diff --git a/internal/model/dto/wechat_dto.go b/internal/model/dto/wechat_dto.go index 19f41ec..9439595 100644 --- a/internal/model/dto/wechat_dto.go +++ b/internal/model/dto/wechat_dto.go @@ -54,3 +54,17 @@ type WechatPayH5Params struct { ID uint `path:"id" description:"订单ID" required:"true"` WechatPayH5Request } + +// JSSDKConfigRequest 获取 JSSDK 签名配置请求 +type JSSDKConfigRequest struct { + URL string `query:"url" validate:"required" required:"true" description:"当前页面完整 URL(含协议和路径,不含 # 及其后内容)"` +} + +// JSSDKConfigResponse JSSDK 签名配置响应 +// 前端使用这些字段调用 wx.config() 初始化微信 JS-SDK +type JSSDKConfigResponse struct { + AppID string `json:"app_id" description:"公众号 AppID"` + Timestamp int64 `json:"timestamp" description:"时间戳(秒)"` + NonceStr string `json:"nonce_str" description:"随机字符串"` + Signature string `json:"signature" description:"签名(SHA1)"` +} diff --git a/pkg/wechat/official_account.go b/pkg/wechat/official_account.go index ad6ccb5..d7bda14 100644 --- a/pkg/wechat/official_account.go +++ b/pkg/wechat/official_account.go @@ -8,6 +8,37 @@ import ( "go.uber.org/zap" ) +// GetJSSDKConfig 获取 JSSDK 签名配置 +// url 为当前页面完整 URL(含协议和路径,不含 # 及其后内容) +func (s *OfficialAccountService) GetJSSDKConfig(ctx context.Context, url string) (*JSSDKConfig, error) { + if url == "" { + return nil, errors.New(errors.CodeInvalidParam, "页面 URL 不能为空") + } + + signMap, err := s.app.JSSDK.ConfigSignature(ctx, url, "", 0) + if err != nil { + s.logger.Error("获取 JSSDK 签名失败", zap.String("url", url), zap.Error(err)) + return nil, errors.Wrap(errors.CodeInternalError, err, "获取 JSSDK 签名失败") + } + + appID, _ := (*signMap)["appId"].(string) + nonceStr, _ := (*signMap)["nonceStr"].(string) + timestamp, _ := (*signMap)["timestamp"].(int64) + signature, _ := (*signMap)["signature"].(string) + + s.logger.Debug("获取 JSSDK 签名配置成功", + zap.String("app_id", appID), + zap.String("url", url), + ) + + return &JSSDKConfig{ + AppID: appID, + Timestamp: timestamp, + NonceStr: nonceStr, + Signature: signature, + }, nil +} + // OfficialAccountService 微信公众号服务实现 type OfficialAccountService struct { app *officialAccount.OfficialAccount diff --git a/pkg/wechat/wechat.go b/pkg/wechat/wechat.go index 68713cd..4638e2f 100644 --- a/pkg/wechat/wechat.go +++ b/pkg/wechat/wechat.go @@ -10,11 +10,23 @@ type Service interface { GetUserInfo(ctx context.Context, code string) (openID, unionID string, err error) } +// JSSDKConfig JSSDK 签名配置 +// 用于前端调用 wx.config() 初始化微信 JS-SDK +type JSSDKConfig struct { + AppID string // 公众号 AppID + Timestamp int64 // 时间戳(秒) + NonceStr string // 随机字符串 + Signature string // 签名(SHA1) +} + // OfficialAccountServiceInterface 微信公众号服务接口 type OfficialAccountServiceInterface interface { Service GetUserInfoDetailed(ctx context.Context, code string) (*UserInfo, error) GetUserInfoByToken(ctx context.Context, accessToken, openID string) (*UserInfo, error) + // GetJSSDKConfig 获取 JSSDK 签名配置,用于前端调用 wx.config() 初始化 + // url 为当前页面完整 URL(含协议和路径,不含 # 及其后内容) + GetJSSDKConfig(ctx context.Context, url string) (*JSSDKConfig, error) } // PaymentServiceInterface 微信支付服务接口