diff --git a/app/main/api/desc/front/agent.api b/app/main/api/desc/front/agent.api index 87585cb..63d04c2 100644 --- a/app/main/api/desc/front/agent.api +++ b/app/main/api/desc/front/agent.api @@ -123,6 +123,14 @@ type ( GetInviteLinkResp { InviteLink string `json:"invite_link"` // 邀请链接 } + // 生成邀请海报请求 + GenerateInvitePosterReq { + InviteLink string `form:"invite_link"` // 邀请链接(用于生成二维码) + } + // 生成邀请海报响应 + GenerateInvitePosterResp { + PosterUrl string `json:"poster_url"` // 海报图片URL(base64编码的data URL) + } // 获取代理等级特权信息 GetLevelPrivilegeResp { Levels []LevelPrivilegeItem `json:"levels"` @@ -250,6 +258,10 @@ service main { @handler GetInviteLink get /invite_link (GetInviteLinkReq) returns (GetInviteLinkResp) + // 生成邀请海报(带二维码的图片) + @handler GenerateInvitePoster + get /invite/poster (GenerateInvitePosterReq) returns (GenerateInvitePosterResp) + // 获取代理等级特权信息 @handler GetLevelPrivilege get /level/privilege returns (GetLevelPrivilegeResp) diff --git a/app/main/api/etc/main.dev.yaml b/app/main/api/etc/main.dev.yaml index bf44f35..46bdd52 100644 --- a/app/main/api/etc/main.dev.yaml +++ b/app/main/api/etc/main.dev.yaml @@ -33,9 +33,9 @@ Alipay: AppID: "2021004165608254" PrivateKey: "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCPsXuwFJeHAL8CwI0QdD9GP7xQ8eejIoQKg6J3/peu26su68JCtGSRhlDm/7vbLHJcFR6h7at+INoz2juc7SqlmNO7i9wKc3+Ua0487y1G2fCsneRNxTTqbceBZwqjj9/AAN0u5/4nSl0bcqTeMddofdpTGOvwGvIJh6CZgCglnhMZnH4D6H6yiIyZf7Q6k2d/qBpVGK8kluYEtSnf/vEQCHhxRx+/DgTL7V1LjbA3BYoPTELZ15JAj0uIzuxextAtxOm4+Huli0RJFAN3q/to2L1Zs8yYY1gKJyTaPWKsJWBx8zI+gZcC/e45k6CZnGgh1Fn3+Xqkf7eGxJGGHs1fAgMBAAECggEAM2rkApbrvdBDiV2TXK7sMVv/K8vUAmkIbKa7zUpZxqUuNSUBp1LbpcM1UeNyujPGXDLmejUMp55j1igiKr4nA4iTQ0oBm+/GWDqpjV5cijzURUBegIGvtK9Bs4lGok6KVy839l/nbvHKLVcxrZySIv7dz9xcGNfbghN5IVRdiU/kOokNbtwQNC837piG5q4PHL6bzwIUGbrLED/RDmw/IwVMMmZovcQQ2JAuWJBo9CS9LB0Nc3I4MOPNx/0Rl+5URSSfmJAriL5ihlWckocQCUHwhRpSGQ6Q4xAXFYvb8OsApAQG3WU9SciBfs2wg/QfGNFzwQgGFofPcTQg3DTeuQKBgQDUHBTsgoe3WXnGo6qZKw1zA4OtF67IJJoltHo5JtkBRKCNVU3BJ+q+6i/fn0MBwScKQ1mhPjWe3h+qTRT207RRxGaxb6ljATOiU+BxmpHvu6jP+DVYtP5F3M7MCAGqpDAEoXgoAWttxmijqk+5YuLOLe0j/btCmpzuH7zwxSnqlQKBgQCtbTvaS/g+Jeu4Ml6iv7xi5//JCjeTn2wUJpXnNmN0jn+riRwEO81z4GWuOI8WukZHHAnufI6qWk2sLH0gcdLQ/STsMnl2L3NbeUyO8o5w2JSAlnZDYfaFfasGqFkGJrBLqG6bh/Bk1DP3/Bl6iMEwDbmu7Ptoy8ihokng9dEPIwKBgBHdi6WgGO5IiwlAH85m4eseEKkzpXUWICWs3d6SdxS0QxGkbbgnNI6ACyg6sdoj+rXSlmoOY1XOP7yIYYuoqTd542xui0XbhA3YIr9u1XvrwnxB27xtAj3AK2rkAb/ttF2ve/9inznPzGB8p9plidTz6VVuuacSfsVPxwpAkRdBAoGAR7c9Ifd6b1DFGkWSBuEc6RWhG6Si+OPbELYoFRXTqNZoiynGsSV9v2ZTBemTmkVrXGqG3N0bLezr47/9+lW3ZP7ZrubsfWf/3xrZAt/g8V9OgaI2w4SWKfuepsElFzsWeiLroltjmH58Axd3/cjhgpqaZ3DOQjbK/7QZsvJUAlsCgYEAqTQVhKLizM7BvXu1N6Z2K8trfJbiN+f90XhZIRPkIIcom0PnOfXhRtT76MCxz9n+lwf+alOKOfbQFy0pZtWG/eaFSYroQlXL+EfmqlFPXZR6D0NQLeygWAKH8161IQUh2VF3Qkhle6g6ZkyJA3Ev4RmqH2BYGv8hcZTTHsZ3Ic4=" AlipayPublicKey: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2CqoCp95w/JV3RT/gzF4/8QmVT1HQNaeW7yUp+mA7x9AbjvlTW/+eRn6oGAL/XhZLjvHD0XjKLVKX0MJVS1aUQHEHEbOJN4Eu8II45OavD4iZISa7Kp9V6AM+i4qTyaeV2wNDnGxHQBaLVUGCfMR+56EK2YpORdE1H9uy72SSQseVb3bmpsV9EW/IJNmcVL/ut3uA1JWAoRmzlQ7ekxg7p8AYXzYPEHQr1tl7W+M4zv9wO9GKZCxIqMA8U3RP5npPfRaCfIRGzXzCqFEEUvWuidOB7frsvN4jiPD07qpL2Bi9LM1X/ee2kC/oM8Uhd7ERZhG8MbZfijZKxgrsDKBcwIDAQAB" - AppCertPath: "app/main/api/etc/merchant/appCertPublicKey_2021004165608254.crt" - AlipayCertPath: "app/main/api/etc/merchant/alipayCertPublicKey_RSA2.crt" - AlipayRootCertPath: "app/main/api/etc/merchant/alipayRootCert.crt" + AppCertPath: "etc/merchant/appCertPublicKey_2021004165608254.crt" + AlipayCertPath: "etc/merchant/alipayCertPublicKey_RSA2.crt" + AlipayRootCertPath: "etc/merchant/alipayRootCert.crt" IsProduction: true NotifyUrl: "https://6m4685017o.goho.co/api/v1/pay/alipay/callback" ReturnURL: "http://localhost:5678/inquire" @@ -45,9 +45,9 @@ Wxpay: MchID: "1687993434" MchCertificateSerialNumber: "241E4BCF5B69AAAC48451DB2C7ED794EF8B3A3D3" MchApiv3Key: "aB3cD5eF7gH9iJ1kL2mN4oP6qR8sT0uV" - MchPrivateKeyPath: "app/main/api/etc/merchant/apiclient_key.pem" + MchPrivateKeyPath: "etc/merchant/apiclient_key.pem" MchPublicKeyID: "PUB_KEY_ID_0116879934342025120200181745004208" - MchPublicKeyPath: "app/main/api/etc/merchant/pub_key.pem" + MchPublicKeyPath: "etc/merchant/pub_key.pem" MchPlatformRAS: "5630D013C88EA348BF66E642B6C39AA0180D4B15" NotifyUrl: "https://6m4685017o.goho.co/api/v1/pay/wechat/callback" RefundNotifyUrl: "https://6m4685017o.goho.co/api/v1/paywechat/refund_callback" @@ -58,7 +58,7 @@ Applepay: BundleID: "com.allinone.check" IssuerID: "bf828d85-5269-4914-9660-c066e09cd6ef" KeyID: "LAY65829DQ" - LoadPrivateKeyPath: "app/main/api/etc/merchant/AuthKey_LAY65829DQ.p8" + LoadPrivateKeyPath: "etc/merchant/AuthKey_LAY65829DQ.p8" Ali: Code: "d55b58829efb41c8aa8e86769cba4844" SystemConfig: diff --git a/app/main/api/internal/handler/agent/generateinviteposterhandler.go b/app/main/api/internal/handler/agent/generateinviteposterhandler.go new file mode 100644 index 0000000..65d8d80 --- /dev/null +++ b/app/main/api/internal/handler/agent/generateinviteposterhandler.go @@ -0,0 +1,33 @@ +// Code scaffolded by goctl. Safe to edit. +// goctl 1.9.2 + +package agent + +import ( + "net/http" + + "qnc-server/app/main/api/internal/logic/agent" + "qnc-server/app/main/api/internal/svc" + "qnc-server/app/main/api/internal/types" + "qnc-server/common/result" + "qnc-server/pkg/lzkit/validator" + + "github.com/zeromicro/go-zero/rest/httpx" +) + +func GenerateInvitePosterHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.GenerateInvitePosterReq + if err := httpx.Parse(r, &req); err != nil { + result.ParamErrorResult(r, w, err) + return + } + if err := validator.Validate(req); err != nil { + result.ParamValidateErrorResult(r, w, err) + return + } + l := agent.NewGenerateInvitePosterLogic(r.Context(), svcCtx) + resp, err := l.GenerateInvitePoster(&req) + result.HttpResult(r, w, resp, err) + } +} diff --git a/app/main/api/internal/handler/routes.go b/app/main/api/internal/handler/routes.go index 59f6328..9885b3e 100644 --- a/app/main/api/internal/handler/routes.go +++ b/app/main/api/internal/handler/routes.go @@ -646,6 +646,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { Path: "/info", Handler: agent.GetAgentInfoHandler(serverCtx), }, + { + Method: http.MethodGet, + Path: "/invite/poster", + Handler: agent.GenerateInvitePosterHandler(serverCtx), + }, { Method: http.MethodPost, Path: "/invite_code/delete", diff --git a/app/main/api/internal/logic/agent/generateinviteposterlogic.go b/app/main/api/internal/logic/agent/generateinviteposterlogic.go new file mode 100644 index 0000000..e7598df --- /dev/null +++ b/app/main/api/internal/logic/agent/generateinviteposterlogic.go @@ -0,0 +1,52 @@ +// Code scaffolded by goctl. Safe to edit. +// goctl 1.9.2 + +package agent + +import ( + "context" + "encoding/base64" + "fmt" + + "qnc-server/app/main/api/internal/svc" + "qnc-server/app/main/api/internal/types" + "qnc-server/common/xerr" + + "github.com/pkg/errors" + "github.com/zeromicro/go-zero/core/logx" +) + +type GenerateInvitePosterLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewGenerateInvitePosterLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GenerateInvitePosterLogic { + return &GenerateInvitePosterLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *GenerateInvitePosterLogic) GenerateInvitePoster(req *types.GenerateInvitePosterReq) (resp *types.GenerateInvitePosterResp, err error) { + if req.InviteLink == "" { + return nil, errors.Wrapf(xerr.NewErrMsg("邀请链接不能为空"), "") + } + + // 调用ImageService生成海报 + imageData, mimeType, err := l.svcCtx.ImageService.ProcessImageWithQRCode("invitation", req.InviteLink) + if err != nil { + l.Errorf("生成邀请海报失败: %v", err) + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成海报失败: %v", err) + } + + // 将图片数据转换为base64编码的data URL + base64Data := base64.StdEncoding.EncodeToString(imageData) + posterUrl := fmt.Sprintf("data:%s;base64,%s", mimeType, base64Data) + + return &types.GenerateInvitePosterResp{ + PosterUrl: posterUrl, + }, nil +} diff --git a/app/main/api/internal/service/alipayService.go b/app/main/api/internal/service/alipayService.go index 92a2e32..531902a 100644 --- a/app/main/api/internal/service/alipayService.go +++ b/app/main/api/internal/service/alipayService.go @@ -6,12 +6,12 @@ import ( "encoding/hex" "fmt" "net/http" - "strconv" - "sync/atomic" - "time" "qnc-server/app/main/api/internal/config" "qnc-server/app/main/model" "qnc-server/pkg/lzkit/lzUtils" + "strconv" + "sync/atomic" + "time" "github.com/smartwalle/alipay/v3" ) diff --git a/app/main/api/internal/types/types.go b/app/main/api/internal/types/types.go index 0e6a4ca..3688580 100644 --- a/app/main/api/internal/types/types.go +++ b/app/main/api/internal/types/types.go @@ -1294,6 +1294,14 @@ type GenerateInviteCodeResp struct { Codes []string `json:"codes"` // 生成的邀请码列表 } +type GenerateInvitePosterReq struct { + InviteLink string `form:"invite_link"` // 邀请链接(用于生成二维码) +} + +type GenerateInvitePosterResp struct { + PosterUrl string `json:"poster_url"` // 海报图片URL(base64编码的data URL) +} + type GetAuthorizationDocumentByOrderReq struct { OrderId string `json:"orderId" validate:"required"` // 订单ID } @@ -1781,6 +1789,7 @@ type PaymentReq struct { Id string `json:"id"` PayMethod string `json:"pay_method"` // 支付方式: wechat, alipay, appleiap, test(仅开发环境), test_empty(仅开发环境-空报告模式) PayType string `json:"pay_type" validate:"required,oneof=query agent_vip agent_upgrade"` + Code string `json:"code,optional"` // 微信小程序/H5授权码,用于自动绑定微信账号(当用户未绑定微信时) } type PaymentResp struct {