add qygl23t7

This commit is contained in:
2025-07-30 00:51:22 +08:00
parent 83530c0f9b
commit 723c418a1b
38 changed files with 999 additions and 785 deletions

View File

@@ -15,7 +15,7 @@ func TranslateErrorMsg(errorType, errorMsg *string) *string {
"not_subscribed": "未订阅该产品",
"product_not_found": "产品不存在",
"product_disabled": "产品已停用",
"system_error": "系统内部错误",
"system_error": "接口异常",
"datasource_error": "数据源异常",
"invalid_param": "参数校验失败",
"decrypt_fail": "参数解密失败",
@@ -37,4 +37,4 @@ func TranslateErrorMsg(errorType, errorMsg *string) *string {
}
return &translatedMsg
}
}

View File

@@ -117,7 +117,6 @@ func (s *CertificationApplicationServiceImpl) SubmitEnterpriseInfo(
cmd.LegalPersonID,
cmd.LegalPersonPhone,
cmd.EnterpriseAddress,
cmd.EnterpriseEmail,
)
enterpriseInfo := &certification_value_objects.EnterpriseInfo{
CompanyName: cmd.CompanyName,
@@ -126,7 +125,6 @@ func (s *CertificationApplicationServiceImpl) SubmitEnterpriseInfo(
LegalPersonID: cmd.LegalPersonID,
LegalPersonPhone: cmd.LegalPersonPhone,
EnterpriseAddress: cmd.EnterpriseAddress,
EnterpriseEmail: cmd.EnterpriseEmail,
}
err = enterpriseInfo.Validate()
if err != nil {
@@ -432,7 +430,10 @@ func (s *CertificationApplicationServiceImpl) GetCertification(
response := s.convertToResponse(cert)
// 3. 添加状态相关的元数据
meta := cert.GetDataByStatus()
meta, err := s.AddStatusMetadata(ctx, cert)
if err != nil {
return nil, err
}
if meta != nil {
response.Metadata = meta
}
@@ -519,7 +520,6 @@ func (s *CertificationApplicationServiceImpl) HandleEsignCallback(
record.LegalPersonID,
record.LegalPersonPhone,
record.EnterpriseAddress,
record.EnterpriseEmail,
)
if err != nil {
s.logger.Error("同步企业信息到用户域失败", zap.Error(err))
@@ -527,7 +527,7 @@ func (s *CertificationApplicationServiceImpl) HandleEsignCallback(
}
// 生成合同
err = s.generateAndAddContractFile(txCtx, cert, record.CompanyName, record.LegalPersonName, record.UnifiedSocialCode, record.EnterpriseAddress, record.LegalPersonPhone, record.LegalPersonID, record.EnterpriseEmail)
err = s.generateAndAddContractFile(txCtx, cert, record.CompanyName, record.LegalPersonName, record.UnifiedSocialCode, record.EnterpriseAddress, record.LegalPersonPhone, record.LegalPersonID)
if err != nil {
return err
}
@@ -679,7 +679,6 @@ func (s *CertificationApplicationServiceImpl) completeEnterpriseVerification(
record.LegalPersonID,
record.LegalPersonPhone,
record.EnterpriseAddress,
record.EnterpriseEmail,
)
if err != nil {
s.logger.Error("保存企业信息到用户域失败", zap.Error(err))
@@ -689,7 +688,7 @@ func (s *CertificationApplicationServiceImpl) completeEnterpriseVerification(
}
// 生成合同
err = s.generateAndAddContractFile(ctx, cert, record.CompanyName, record.LegalPersonName, record.UnifiedSocialCode, record.EnterpriseAddress, record.LegalPersonPhone, record.LegalPersonID, record.EnterpriseEmail)
err = s.generateAndAddContractFile(ctx, cert, record.CompanyName, record.LegalPersonName, record.UnifiedSocialCode, record.EnterpriseAddress, record.LegalPersonPhone, record.LegalPersonID)
if err != nil {
return err
}
@@ -714,7 +713,6 @@ func (s *CertificationApplicationServiceImpl) generateAndAddContractFile(
enterpriseAddress string,
legalPersonPhone string,
legalPersonID string,
enterpriseEmail string,
) error {
fileComponent := map[string]string{
"YFCompanyName": companyName,
@@ -725,7 +723,6 @@ func (s *CertificationApplicationServiceImpl) generateAndAddContractFile(
"YFEnterpriseAddress": enterpriseAddress,
"YFContactPerson": legalPersonName,
"YFMobile": legalPersonPhone,
"YFEmail": enterpriseEmail,
"SignDate": time.Now().Format("2006年01月02日"),
"SignDate2": time.Now().Format("2006年01月02日"),
"SignDate3": time.Now().Format("2006年01月02日"),
@@ -753,7 +750,7 @@ func (s *CertificationApplicationServiceImpl) updateContractFile(ctx context.Con
}
// 生成合同
err = s.generateAndAddContractFile(ctx, cert, enterpriseInfo.EnterpriseInfo.CompanyName, enterpriseInfo.EnterpriseInfo.LegalPersonName, enterpriseInfo.EnterpriseInfo.UnifiedSocialCode, enterpriseInfo.EnterpriseInfo.EnterpriseAddress, enterpriseInfo.EnterpriseInfo.LegalPersonPhone, enterpriseInfo.EnterpriseInfo.LegalPersonID, enterpriseInfo.EnterpriseInfo.EnterpriseEmail)
err = s.generateAndAddContractFile(ctx, cert, enterpriseInfo.EnterpriseInfo.CompanyName, enterpriseInfo.EnterpriseInfo.LegalPersonName, enterpriseInfo.EnterpriseInfo.UnifiedSocialCode, enterpriseInfo.EnterpriseInfo.EnterpriseAddress, enterpriseInfo.EnterpriseInfo.LegalPersonPhone, enterpriseInfo.EnterpriseInfo.LegalPersonID)
if err != nil {
return err
}
@@ -849,7 +846,7 @@ func (s *CertificationApplicationServiceImpl) checkAndUpdateSignStatus(ctx conte
// handleContractAfterSignComplete 处理签署完成后的合同
func (s *CertificationApplicationServiceImpl) handleContractAfterSignComplete(ctx context.Context, cert *entities.Certification) error {
// 获取用户的企业信息
user, err := s.userAggregateService.LoadUser(ctx, cert.UserID)
user, err := s.userAggregateService.GetUserWithEnterpriseInfo(ctx, cert.UserID)
if err != nil {
return fmt.Errorf("加载用户信息失败: %w", err)
}
@@ -941,3 +938,29 @@ func (s *CertificationApplicationServiceImpl) downloadFileContent(ctx context.Co
}
return io.ReadAll(resp.Body)
}
// 添加状态相关的元数据
func (s *CertificationApplicationServiceImpl) AddStatusMetadata(ctx context.Context, cert *entities.Certification) (map[string]interface{}, error) {
metadata := make(map[string]interface{})
metadata = cert.GetDataByStatus()
switch cert.Status {
case enums.StatusPending, enums.StatusInfoSubmitted, enums.StatusEnterpriseVerified:
record, err := s.enterpriseInfoSubmitRecordRepo.FindLatestByUserID(ctx, cert.UserID)
if err == nil && record != nil {
metadata["company_name"] = record.CompanyName
metadata["legal_person_name"] = record.LegalPersonName
metadata["unified_social_code"] = record.UnifiedSocialCode
metadata["enterprise_address"] = record.EnterpriseAddress
metadata["legal_person_phone"] = record.LegalPersonPhone
metadata["legal_person_id"] = record.LegalPersonID
}
case enums.StatusCompleted:
// 获取最终合同信息
contracts, err := s.contractAggregateService.FindByUserID(ctx, cert.UserID)
if err == nil && len(contracts) > 0 {
metadata["contract_url"] = contracts[0].ContractFileURL
}
}
return metadata, nil
}

View File

@@ -90,6 +90,5 @@ type SubmitEnterpriseInfoCommand struct {
LegalPersonID string `json:"legal_person_id" binding:"required,id_card" comment:"法定代表人身份证号码18位110101199001011234"`
LegalPersonPhone string `json:"legal_person_phone" binding:"required,phone" comment:"法定代表人手机号11位13800138000"`
EnterpriseAddress string `json:"enterprise_address" binding:"required,enterprise_address" comment:"企业地址,如:北京市海淀区"`
EnterpriseEmail string `json:"enterprise_email" binding:"required,enterprise_email" comment:"企业邮箱info@example.com"`
VerificationCode string `json:"verification_code" binding:"required,len=6" comment:"验证码"`
}

View File

@@ -75,3 +75,39 @@ type ProductStatsResponse struct {
VisibleProducts int64 `json:"visible_products" comment:"可见产品数"`
PackageProducts int64 `json:"package_products" comment:"组合包产品数"`
}
// ProductAdminInfoResponse 管理员产品详情响应
type ProductAdminInfoResponse struct {
ID string `json:"id" comment:"产品ID"`
Name string `json:"name" comment:"产品名称"`
Code string `json:"code" comment:"产品编号"`
Description string `json:"description" comment:"产品简介"`
Content string `json:"content" comment:"产品内容"`
CategoryID string `json:"category_id" comment:"产品分类ID"`
Price float64 `json:"price" comment:"产品价格"`
IsEnabled bool `json:"is_enabled" comment:"是否启用"`
IsVisible bool `json:"is_visible" comment:"是否可见"`
IsPackage bool `json:"is_package" comment:"是否组合包"`
// SEO信息
SEOTitle string `json:"seo_title" comment:"SEO标题"`
SEODescription string `json:"seo_description" comment:"SEO描述"`
SEOKeywords string `json:"seo_keywords" comment:"SEO关键词"`
// 关联信息
Category *CategoryInfoResponse `json:"category,omitempty" comment:"分类信息"`
// 组合包信息
PackageItems []*PackageItemResponse `json:"package_items,omitempty" comment:"组合包项目列表"`
CreatedAt time.Time `json:"created_at" comment:"创建时间"`
UpdatedAt time.Time `json:"updated_at" comment:"更新时间"`
}
// ProductAdminListResponse 管理员产品列表响应
type ProductAdminListResponse struct {
Total int64 `json:"total" comment:"总数"`
Page int `json:"page" comment:"页码"`
Size int `json:"size" comment:"每页数量"`
Items []ProductAdminInfoResponse `json:"items" comment:"产品列表"`
}

View File

@@ -20,6 +20,13 @@ type ProductApplicationService interface {
ListProductsWithSubscriptionStatus(ctx context.Context, filters map[string]interface{}, options interfaces.ListOptions) (*responses.ProductListResponse, error)
GetProductsByIDs(ctx context.Context, query *queries.GetProductsByIDsQuery) ([]*responses.ProductInfoResponse, error)
// 管理员专用方法
ListProductsForAdmin(ctx context.Context, filters map[string]interface{}, options interfaces.ListOptions) (*responses.ProductAdminListResponse, error)
GetProductByIDForAdmin(ctx context.Context, query *queries.GetProductQuery) (*responses.ProductAdminInfoResponse, error)
// 用户端专用方法
GetProductByIDForUser(ctx context.Context, query *queries.GetProductQuery) (*responses.ProductInfoResponse, error)
// 业务查询
GetSubscribableProducts(ctx context.Context, query *queries.GetSubscribableProductsQuery) ([]*responses.ProductInfoResponse, error)
GetProductStats(ctx context.Context) (*responses.ProductStatsResponse, error)
@@ -30,6 +37,8 @@ type ProductApplicationService interface {
RemovePackageItem(ctx context.Context, packageID, itemID string) error
ReorderPackageItems(ctx context.Context, packageID string, cmd *commands.ReorderPackageItemsCommand) error
UpdatePackageItems(ctx context.Context, packageID string, cmd *commands.UpdatePackageItemsCommand) error
// 可选子产品查询
GetAvailableProducts(ctx context.Context, query *queries.GetAvailableProductsQuery) (*responses.ProductListResponse, error)
// API配置管理

View File

@@ -344,6 +344,7 @@ func (s *ProductApplicationServiceImpl) UpdatePackageItems(ctx context.Context,
}
// GetAvailableProducts 获取可选子产品列表
// 业务流程1. 获取启用产品 2. 过滤可订阅产品 3. 构建响应数据
func (s *ProductApplicationServiceImpl) GetAvailableProducts(ctx context.Context, query *appQueries.GetAvailableProductsQuery) (*responses.ProductListResponse, error) {
// 构建筛选条件
filters := make(map[string]interface{})
@@ -385,6 +386,56 @@ func (s *ProductApplicationServiceImpl) GetAvailableProducts(ctx context.Context
}, nil
}
// ListProductsForAdmin 获取产品列表(管理员专用)
// 业务流程1. 获取所有产品列表(包括隐藏的) 2. 构建管理员响应数据
func (s *ProductApplicationServiceImpl) ListProductsForAdmin(ctx context.Context, filters map[string]interface{}, options interfaces.ListOptions) (*responses.ProductAdminListResponse, error) {
// 调用领域服务获取产品列表(管理员可以看到所有产品)
products, total, err := s.productManagementService.ListProducts(ctx, filters, options)
if err != nil {
return nil, err
}
// 转换为管理员响应对象
items := make([]responses.ProductAdminInfoResponse, len(products))
for i := range products {
items[i] = *s.convertToProductAdminInfoResponse(products[i])
}
return &responses.ProductAdminListResponse{
Total: total,
Page: options.Page,
Size: options.PageSize,
Items: items,
}, nil
}
// GetProductByIDForAdmin 根据ID获取产品管理员专用
// 业务流程1. 获取产品信息 2. 构建管理员响应数据
func (s *ProductApplicationServiceImpl) GetProductByIDForAdmin(ctx context.Context, query *appQueries.GetProductQuery) (*responses.ProductAdminInfoResponse, error) {
product, err := s.productManagementService.GetProductWithCategory(ctx, query.ID)
if err != nil {
return nil, err
}
return s.convertToProductAdminInfoResponse(product), nil
}
// GetProductByIDForUser 根据ID获取产品用户端专用
// 业务流程1. 获取产品信息 2. 验证产品可见性 3. 构建用户响应数据
func (s *ProductApplicationServiceImpl) GetProductByIDForUser(ctx context.Context, query *appQueries.GetProductQuery) (*responses.ProductInfoResponse, error) {
product, err := s.productManagementService.GetProductWithCategory(ctx, query.ID)
if err != nil {
return nil, err
}
// 用户端只能查看可见的产品
if !product.IsVisible {
return nil, fmt.Errorf("产品不存在或不可见")
}
return s.convertToProductInfoResponse(product), nil
}
// convertToProductInfoResponse 转换为产品信息响应
func (s *ProductApplicationServiceImpl) convertToProductInfoResponse(product *entities.Product) *responses.ProductInfoResponse {
response := &responses.ProductInfoResponse{
@@ -427,6 +478,49 @@ func (s *ProductApplicationServiceImpl) convertToProductInfoResponse(product *en
return response
}
// convertToProductAdminInfoResponse 转换为管理员产品信息响应
func (s *ProductApplicationServiceImpl) convertToProductAdminInfoResponse(product *entities.Product) *responses.ProductAdminInfoResponse {
response := &responses.ProductAdminInfoResponse{
ID: product.ID,
Name: product.Name,
Code: product.Code,
Description: product.Description,
Content: product.Content,
CategoryID: product.CategoryID,
Price: product.Price.InexactFloat64(),
IsEnabled: product.IsEnabled,
IsVisible: product.IsVisible, // 管理员可以看到可见状态
IsPackage: product.IsPackage,
SEOTitle: product.SEOTitle,
SEODescription: product.SEODescription,
SEOKeywords: product.SEOKeywords,
CreatedAt: product.CreatedAt,
UpdatedAt: product.UpdatedAt,
}
// 添加分类信息
if product.Category != nil {
response.Category = s.convertToCategoryInfoResponse(product.Category)
}
// 转换组合包项目信息
if product.IsPackage && len(product.PackageItems) > 0 {
response.PackageItems = make([]*responses.PackageItemResponse, len(product.PackageItems))
for i, item := range product.PackageItems {
response.PackageItems[i] = &responses.PackageItemResponse{
ID: item.ID,
ProductID: item.ProductID,
ProductCode: item.Product.Code,
ProductName: item.Product.Name,
SortOrder: item.SortOrder,
Price: item.Product.Price.InexactFloat64(),
}
}
}
return response
}
// convertToCategoryInfoResponse 转换为分类信息响应
func (s *ProductApplicationServiceImpl) convertToCategoryInfoResponse(category *entities.ProductCategory) *responses.CategoryInfoResponse {
return &responses.CategoryInfoResponse{

View File

@@ -30,7 +30,6 @@ type EnterpriseInfoItem struct {
LegalPersonName string `json:"legal_person_name"`
LegalPersonPhone string `json:"legal_person_phone"`
EnterpriseAddress string `json:"enterprise_address"`
EnterpriseEmail string `json:"enterprise_email"`
CreatedAt time.Time `json:"created_at"`
}

View File

@@ -21,7 +21,6 @@ type EnterpriseInfoResponse struct {
LegalPersonID string `json:"legal_person_id" example:"110101199001011234"`
LegalPersonPhone string `json:"legal_person_phone" example:"13800138000"`
EnterpriseAddress string `json:"enterprise_address" example:"北京市朝阳区xxx街道xxx号"`
EnterpriseEmail string `json:"enterprise_email" example:"contact@example.com"`
CertifiedAt *time.Time `json:"certified_at,omitempty" example:"2024-01-01T00:00:00Z"`
CreatedAt time.Time `json:"created_at" example:"2024-01-01T00:00:00Z"`
UpdatedAt time.Time `json:"updated_at" example:"2024-01-01T00:00:00Z"`

View File

@@ -277,7 +277,6 @@ func (s *UserApplicationServiceImpl) GetUserProfile(ctx context.Context, userID
LegalPersonID: user.EnterpriseInfo.LegalPersonID,
LegalPersonPhone: user.EnterpriseInfo.LegalPersonPhone,
EnterpriseAddress: user.EnterpriseInfo.EnterpriseAddress,
EnterpriseEmail: user.EnterpriseInfo.EnterpriseEmail,
CreatedAt: user.EnterpriseInfo.CreatedAt,
UpdatedAt: user.EnterpriseInfo.UpdatedAt,
}
@@ -341,7 +340,6 @@ func (s *UserApplicationServiceImpl) ListUsers(ctx context.Context, query *queri
LegalPersonName: user.EnterpriseInfo.LegalPersonName,
LegalPersonPhone: user.EnterpriseInfo.LegalPersonPhone,
EnterpriseAddress: user.EnterpriseInfo.EnterpriseAddress,
EnterpriseEmail: user.EnterpriseInfo.EnterpriseEmail,
CreatedAt: user.EnterpriseInfo.CreatedAt,
}
}