package service import ( "context" "errors" "time" "order/dao" "order/model/dto" "order/model/entity" "github.com/gogf/gf/v2/util/gconv" "go.mongodb.org/mongo-driver/v2/bson" ) type paymentConfig struct{} // PaymentConfig 支付配置服务 var PaymentConfig = new(paymentConfig) // CreatePaymentConfig 创建支付配置 func (s *paymentConfig) CreatePaymentConfig(ctx context.Context, req *dto.CreatePaymentConfigReq) (*dto.PaymentConfigResp, error) { // 1. 参数验证 if req.TenantID == "" || req.PayMethod == "" { return nil, errors.New("必填参数不能为空") } // 2. 检查支付方式是否已存在 exist, err := dao.PaymentConfig.GetByTenantAndMethod(ctx, req.TenantID, req.PayMethod) if err != nil { return nil, err } if exist != nil { return nil, errors.New("该支付方式已存在配置") } // 3. 创建配置实体 config := parseConfigMap(req.PayMethod, req.Config) config.TenantId = req.TenantID config.Description = req.Remark config.Enabled = req.IsEnabled // 4. 保存配置 if err := dao.PaymentConfig.Create(ctx, config); err != nil { return nil, err } // 5. 返回结果 resp := &dto.PaymentConfigResp{ ID: config.Id.Hex(), TenantID: gconv.String(config.TenantId), PayMethod: config.PayMethod, Config: buildConfigMap(config), IsEnabled: config.Enabled, Remark: config.Description, CreatedAt: time.Now(), // 暂时使用当前时间 UpdatedAt: time.Now(), } return resp, nil } // UpdatePaymentConfig 更新支付配置 func (s *paymentConfig) UpdatePaymentConfig(ctx context.Context, req *dto.UpdatePaymentConfigReq) (*dto.PaymentConfigResp, error) { // 1. 参数验证 if req.ID == "" || req.TenantID == "" { return nil, errors.New("必填参数不能为空") } // 2. 查询配置 objectID, err := bson.ObjectIDFromHex(req.ID) if err != nil { return nil, errors.New("无效的配置ID") } config, err := dao.PaymentConfig.GetByID(ctx, objectID) if err != nil { return nil, err } if config == nil { return nil, errors.New("支付配置不存在") } // 3. 检查是否是租户自己的配置 if config.TenantId != req.TenantID { return nil, errors.New("无权限操作该配置") } // 4. 更新配置实体 config.ConfigName = req.ConfigName config.Description = req.Remark config.Enabled = req.IsEnabled // 解析配置参数 parseConfigMapToEntity(config.PayMethod, req.Config, config) // 5. 更新配置 if err := dao.PaymentConfig.Update(ctx, config); err != nil { return nil, err } // 6. 返回结果 resp := &dto.PaymentConfigResp{ ID: config.Id.Hex(), TenantID: gconv.String(config.TenantId), PayMethod: config.PayMethod, ConfigName: config.ConfigName, Remark: config.Description, IsEnabled: config.Enabled, Config: convertEntityToConfigMap(config), CreatedAt: time.Unix(0, 0), // 实体中没有时间字段,使用默认值 UpdatedAt: time.Now(), } return resp, nil } // GetPaymentConfig 获取支付配置 func (s *paymentConfig) GetPaymentConfig(ctx context.Context, req *dto.QueryPaymentConfigReq) (*dto.PaymentConfigResp, error) { // 1. 参数验证 if req.TenantID == "" { return nil, errors.New("租户ID不能为空") } var config *entity.PaymentConfig var err error // 2. 查询配置 if req.PayMethod != "" { // 按租户和支付方式查询 config, err = dao.PaymentConfig.GetByTenantAndMethod(ctx, req.TenantID, req.PayMethod) } else { // 只按租户查询(获取所有支付方式配置) configs, err := dao.PaymentConfig.GetByTenantID(ctx, req.TenantID) if err != nil { return nil, err } if len(configs) > 0 { config = &configs[0] // 返回第一个配置作为默认 } } if err != nil { return nil, err } if config == nil { return nil, errors.New("支付配置不存在") } // 3. 返回结果 resp := &dto.PaymentConfigResp{ ID: config.Id.Hex(), TenantID: gconv.String(config.TenantId), PayMethod: config.PayMethod, ConfigName: config.ConfigName, Remark: config.Description, IsEnabled: config.Enabled, Config: convertEntityToConfigMap(config), CreatedAt: time.Unix(0, 0), UpdatedAt: time.Now(), } return resp, nil } // GetPaymentConfigList 获取支付配置列表 func (s *paymentConfig) GetPaymentConfigList(ctx context.Context, tenantID string) ([]dto.PaymentConfigResp, error) { // 1. 参数验证 if tenantID == "" { return nil, errors.New("租户ID不能为空") } // 2. 查询配置列表 configs, err := dao.PaymentConfig.GetByTenantID(ctx, tenantID) if err != nil { return nil, err } // 3. 转换为响应格式 var resp []dto.PaymentConfigResp for _, config := range configs { resp = append(resp, dto.PaymentConfigResp{ ID: config.Id.Hex(), TenantID: gconv.String(config.TenantId), PayMethod: config.PayMethod, ConfigName: config.ConfigName, Remark: config.Description, IsEnabled: config.Enabled, Config: convertEntityToConfigMap(&config), CreatedAt: time.Unix(0, 0), UpdatedAt: time.Now(), }) } return resp, nil } // DeletePaymentConfig 删除支付配置 func (s *paymentConfig) DeletePaymentConfig(ctx context.Context, tenantID, configID string) error { // 1. 参数验证 if tenantID == "" || configID == "" { return errors.New("必填参数不能为空") } // 2. 查询配置 objectID, err := bson.ObjectIDFromHex(configID) if err != nil { return errors.New("无效的配置ID") } config, err := dao.PaymentConfig.GetByID(ctx, objectID) if err != nil { return err } if config == nil { return errors.New("支付配置不存在") } // 3. 检查是否是租户自己的配置 if config.TenantId != tenantID { return errors.New("无权限操作该配置") } // 4. 删除配置 return dao.PaymentConfig.Delete(ctx, objectID) } // EnablePaymentConfig 启用支付配置 func (s *paymentConfig) EnablePaymentConfig(ctx context.Context, tenantID, configID string) error { return s.updateConfigStatus(ctx, tenantID, configID, true) } // DisablePaymentConfig 禁用支付配置 func (s *paymentConfig) DisablePaymentConfig(ctx context.Context, tenantID, configID string) error { return s.updateConfigStatus(ctx, tenantID, configID, false) } // updateConfigStatus 更新配置状态 func (s *paymentConfig) updateConfigStatus(ctx context.Context, tenantID, configID string, enabled bool) error { // 1. 参数验证 if tenantID == "" || configID == "" { return errors.New("必填参数不能为空") } // 2. 查询配置 objectID, err := bson.ObjectIDFromHex(configID) if err != nil { return errors.New("无效的配置ID") } config, err := dao.PaymentConfig.GetByID(ctx, objectID) if err != nil { return err } if config == nil { return errors.New("支付配置不存在") } // 3. 检查是否是租户自己的配置 if config.TenantId != tenantID { return errors.New("无权限操作该配置") } // 4. 更新状态 config.Enabled = enabled return dao.PaymentConfig.Update(ctx, config) } // WechatConfig 微信支付配置服务 var WechatConfig = new(wechatConfig) type wechatConfig struct{} // GetWechatConfig 获取微信支付配置 func (s *wechatConfig) GetWechatConfig(ctx context.Context, tenantID string) (*dto.WechatConfig, error) { // 1. 获取微信支付配置 resp, err := PaymentConfig.GetPaymentConfig(ctx, &dto.QueryPaymentConfigReq{ TenantID: tenantID, PayMethod: "wechat", }) if err != nil { return nil, err } // 2. 转换为微信配置结构体 configMap := resp.Config wechatConfig := &dto.WechatConfig{ ID: resp.ID, TenantID: resp.TenantID, ConfigName: resp.ConfigName, AppID: getString(configMap, "app_id"), MchID: getString(configMap, "mch_id"), APIKey: getString(configMap, "api_key"), NotifyURL: getString(configMap, "notify_url"), ReturnURL: getString(configMap, "return_url"), CertPath: getString(configMap, "cert_path"), KeyPath: getString(configMap, "key_path"), Sandbox: getBool(configMap, "sandbox"), GatewayURL: getString(configMap, "gateway_url"), SupportNative: getBool(configMap, "support_native"), SupportJSAPI: getBool(configMap, "support_jsapi"), SupportAPP: getBool(configMap, "support_app"), SupportH5: getBool(configMap, "support_h5"), } return wechatConfig, nil } // AlipayConfig 支付宝支付配置服务 var AlipayConfig = new(alipayConfig) type alipayConfig struct{} // GetAlipayConfig 获取支付宝支付配置 func (s *alipayConfig) GetAlipayConfig(ctx context.Context, tenantID string) (*dto.AlipayConfig, error) { // 1. 获取支付宝支付配置 resp, err := PaymentConfig.GetPaymentConfig(ctx, &dto.QueryPaymentConfigReq{ TenantID: tenantID, PayMethod: "alipay", }) if err != nil { return nil, err } // 2. 转换为支付宝配置结构体 configMap := resp.Config alipayConfig := &dto.AlipayConfig{ ID: resp.ID, TenantID: resp.TenantID, ConfigName: resp.ConfigName, AppID: getString(configMap, "app_id"), NotifyURL: getString(configMap, "notify_url"), ReturnURL: getString(configMap, "return_url"), AppPrivateKey: getString(configMap, "app_private_key"), AlipayPublicKey: getString(configMap, "alipay_public_key"), Sandbox: getBool(configMap, "sandbox"), GatewayURL: getString(configMap, "gateway_url"), SupportNative: getBool(configMap, "support_native"), SupportJSAPI: getBool(configMap, "support_jsapi"), SupportAPP: getBool(configMap, "support_app"), SupportH5: getBool(configMap, "support_h5"), } return alipayConfig, nil } // getString 从map中获取string值 func getString(m map[string]interface{}, key string) string { if val, ok := m[key]; ok { if str, ok := val.(string); ok { return str } } return "" } // getBool 从map中获取bool值 func getBool(m map[string]interface{}, key string) bool { if val, ok := m[key]; ok { if b, ok := val.(bool); ok { return b } } return false } // buildConfigMap 将PaymentConfig结构体转换为map func buildConfigMap(config *entity.PaymentConfig) map[string]interface{} { result := map[string]interface{}{ "app_id": config.AppID, "mch_id": config.MchID, "api_key": config.APIKey, "notify_url": config.NotifyURL, "return_url": config.ReturnURL, "cert_path": config.CertPath, "key_path": config.KeyPath, "app_private_key": config.AppPrivateKey, "alipay_public_key": config.AlipayPublicKey, "sandbox": config.Sandbox, "gateway_url": config.GatewayURL, "support_native": config.SupportNative, "support_jsapi": config.SupportJSAPI, "support_app": config.SupportAPP, "support_h5": config.SupportH5, } return result } // parseConfigMap 将map转换为PaymentConfig结构体 func parseConfigMap(payMethod string, configMap map[string]interface{}) *entity.PaymentConfig { config := &entity.PaymentConfig{ PayMethod: payMethod, ConfigName: payMethod + "配置", AppID: getString(configMap, "app_id"), MchID: getString(configMap, "mch_id"), APIKey: getString(configMap, "api_key"), NotifyURL: getString(configMap, "notify_url"), ReturnURL: getString(configMap, "return_url"), CertPath: getString(configMap, "cert_path"), KeyPath: getString(configMap, "key_path"), AppPrivateKey: getString(configMap, "app_private_key"), AlipayPublicKey: getString(configMap, "alipay_public_key"), Sandbox: getBool(configMap, "sandbox"), GatewayURL: getString(configMap, "gateway_url"), SupportNative: getBool(configMap, "support_native"), SupportJSAPI: getBool(configMap, "support_jsapi"), SupportAPP: getBool(configMap, "support_app"), SupportH5: getBool(configMap, "support_h5"), } return config } // parseConfigMapToEntity 将map中的配置更新到实体中 func parseConfigMapToEntity(payMethod string, configMap map[string]interface{}, config *entity.PaymentConfig) { config.AppID = getString(configMap, "app_id") config.MchID = getString(configMap, "mch_id") config.APIKey = getString(configMap, "api_key") config.NotifyURL = getString(configMap, "notify_url") config.ReturnURL = getString(configMap, "return_url") config.CertPath = getString(configMap, "cert_path") config.KeyPath = getString(configMap, "key_path") config.AppPrivateKey = getString(configMap, "app_private_key") config.AlipayPublicKey = getString(configMap, "alipay_public_key") config.Sandbox = getBool(configMap, "sandbox") config.GatewayURL = getString(configMap, "gateway_url") config.SupportNative = getBool(configMap, "support_native") config.SupportJSAPI = getBool(configMap, "support_jsapi") config.SupportAPP = getBool(configMap, "support_app") config.SupportH5 = getBool(configMap, "support_h5") } // convertEntityToConfigMap 将实体转换为配置map func convertEntityToConfigMap(config *entity.PaymentConfig) map[string]interface{} { return buildConfigMap(config) }