Merge branch 'main' of http://1.117.67.95:3000/team/bdqr-server
This commit is contained in:
@@ -121,6 +121,14 @@ type (
|
|||||||
GetInviteLinkResp {
|
GetInviteLinkResp {
|
||||||
InviteLink string `json:"invite_link"` // 邀请链接
|
InviteLink string `json:"invite_link"` // 邀请链接
|
||||||
}
|
}
|
||||||
|
// 生成邀请海报(背景图+二维码,返回 base64)
|
||||||
|
GetInvitePosterReq {
|
||||||
|
InviteLink string `form:"invite_link"` // 邀请链接(短链)
|
||||||
|
Format string `form:"format,optional"` // 返回格式:base64(默认)
|
||||||
|
}
|
||||||
|
GetInvitePosterResp {
|
||||||
|
PosterBase64 string `json:"poster_base64"` // 海报图片 base64(不含 data:image/png;base64, 前缀)
|
||||||
|
}
|
||||||
// 获取代理等级特权信息
|
// 获取代理等级特权信息
|
||||||
GetLevelPrivilegeResp {
|
GetLevelPrivilegeResp {
|
||||||
Levels []LevelPrivilegeItem `json:"levels"`
|
Levels []LevelPrivilegeItem `json:"levels"`
|
||||||
@@ -244,6 +252,10 @@ service main {
|
|||||||
@handler GetInviteLink
|
@handler GetInviteLink
|
||||||
get /invite_link (GetInviteLinkReq) returns (GetInviteLinkResp)
|
get /invite_link (GetInviteLinkReq) returns (GetInviteLinkResp)
|
||||||
|
|
||||||
|
// 生成邀请海报(背景图+邀请链接二维码)
|
||||||
|
@handler GetInvitePoster
|
||||||
|
get /invite/poster (GetInvitePosterReq) returns (GetInvitePosterResp)
|
||||||
|
|
||||||
// 获取代理等级特权信息
|
// 获取代理等级特权信息
|
||||||
@handler GetLevelPrivilege
|
@handler GetLevelPrivilege
|
||||||
get /level/privilege returns (GetLevelPrivilegeResp)
|
get /level/privilege returns (GetLevelPrivilegeResp)
|
||||||
|
|||||||
@@ -58,8 +58,8 @@ WechatH5:
|
|||||||
AppID: "wxb786749edb73eb04"
|
AppID: "wxb786749edb73eb04"
|
||||||
AppSecret: "b2aad5ec8788eb1e74a3c385dd5aa282"
|
AppSecret: "b2aad5ec8788eb1e74a3c385dd5aa282"
|
||||||
WechatMini:
|
WechatMini:
|
||||||
AppID: "xxx" # 小程序的AppID
|
AppID: "wxc17ebfe0d5b832b0" # 小程序的AppID
|
||||||
AppSecret: "xxxx" # 小程序的AppSecret
|
AppSecret: "92100f1fbad05309635cea0671d37995" # 小程序的AppSecret
|
||||||
Query:
|
Query:
|
||||||
ShareLinkExpire: 604800 # 7天 = 7 * 24 * 60 * 60 = 604800秒
|
ShareLinkExpire: 604800 # 7天 = 7 * 24 * 60 * 60 = 604800秒
|
||||||
AdminConfig:
|
AdminConfig:
|
||||||
|
|||||||
@@ -55,8 +55,8 @@ WechatH5:
|
|||||||
AppID: "wxb786749edb73eb04"
|
AppID: "wxb786749edb73eb04"
|
||||||
AppSecret: "b2aad5ec8788eb1e74a3c385dd5aa282"
|
AppSecret: "b2aad5ec8788eb1e74a3c385dd5aa282"
|
||||||
WechatMini:
|
WechatMini:
|
||||||
AppID: "xxx" # 小程序的AppID
|
AppID: "wxc17ebfe0d5b832b0" # 小程序的AppID
|
||||||
AppSecret: "xxxx" # 小程序的AppSecret
|
AppSecret: "92100f1fbad05309635cea0671d37995" # 小程序的AppSecret
|
||||||
Query:
|
Query:
|
||||||
ShareLinkExpire: 604800 # 7天 = 7 * 24 * 60 * 60 = 604800秒
|
ShareLinkExpire: 604800 # 7天 = 7 * 24 * 60 * 60 = 604800秒
|
||||||
AdminConfig:
|
AdminConfig:
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package agent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"bdqr-server/app/main/api/internal/logic/agent"
|
||||||
|
"bdqr-server/app/main/api/internal/svc"
|
||||||
|
"bdqr-server/app/main/api/internal/types"
|
||||||
|
"bdqr-server/common/result"
|
||||||
|
"bdqr-server/pkg/lzkit/validator"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/rest/httpx"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetInvitePosterHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var req types.GetInvitePosterReq
|
||||||
|
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.NewGetInvitePosterLogic(r.Context(), svcCtx)
|
||||||
|
resp, err := l.GetInvitePoster(&req)
|
||||||
|
result.HttpResult(r, w, resp, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -676,6 +676,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
|||||||
Path: "/invite_link",
|
Path: "/invite_link",
|
||||||
Handler: agent.GetInviteLinkHandler(serverCtx),
|
Handler: agent.GetInviteLinkHandler(serverCtx),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Method: http.MethodGet,
|
||||||
|
Path: "/invite/poster",
|
||||||
|
Handler: agent.GetInvitePosterHandler(serverCtx),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Method: http.MethodGet,
|
Method: http.MethodGet,
|
||||||
Path: "/level/privilege",
|
Path: "/level/privilege",
|
||||||
|
|||||||
66
app/main/api/internal/logic/agent/getinviteposterlogic.go
Normal file
66
app/main/api/internal/logic/agent/getinviteposterlogic.go
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
package agent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/base64"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"bdqr-server/app/main/model"
|
||||||
|
"bdqr-server/common/ctxdata"
|
||||||
|
"bdqr-server/common/xerr"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
|
"bdqr-server/app/main/api/internal/svc"
|
||||||
|
"bdqr-server/app/main/api/internal/types"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GetInvitePosterLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGetInvitePosterLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetInvitePosterLogic {
|
||||||
|
return &GetInvitePosterLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *GetInvitePosterLogic) GetInvitePoster(req *types.GetInvitePosterReq) (resp *types.GetInvitePosterResp, err error) {
|
||||||
|
// 1. 需登录且为代理
|
||||||
|
userID, err := ctxdata.GetUidFromCtx(l.ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取用户信息失败, %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, model.ErrNotFound) {
|
||||||
|
return nil, errors.Wrapf(xerr.NewErrMsg("您不是代理"), "")
|
||||||
|
}
|
||||||
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询代理信息失败, %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 邀请链接不能为空
|
||||||
|
inviteLink := strings.TrimSpace(req.InviteLink)
|
||||||
|
if inviteLink == "" {
|
||||||
|
return nil, errors.Wrapf(xerr.NewErrMsg("邀请链接不能为空"), "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 调用 ImageService 生成邀请海报(背景图 + 二维码)
|
||||||
|
imgData, _, err := l.svcCtx.ImageService.ProcessImageWithQRCode("invitation", inviteLink)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成海报失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 返回 base64
|
||||||
|
posterBase64 := base64.StdEncoding.EncodeToString(imgData)
|
||||||
|
return &types.GetInvitePosterResp{
|
||||||
|
PosterBase64: posterBase64,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
@@ -26,13 +26,13 @@ func NewImageService() *ImageService {
|
|||||||
|
|
||||||
// ProcessImageWithQRCode 处理图片,在中间添加二维码
|
// ProcessImageWithQRCode 处理图片,在中间添加二维码
|
||||||
func (s *ImageService) ProcessImageWithQRCode(qrcodeType, qrcodeUrl string) ([]byte, string, error) {
|
func (s *ImageService) ProcessImageWithQRCode(qrcodeType, qrcodeUrl string) ([]byte, string, error) {
|
||||||
// 1. 根据qrcodeType确定使用哪张背景图
|
// 1. 根据qrcodeType确定使用哪张背景图(与 uniapp_ycc/src/static/invitation 下海报一致,需复制到本目录 static/images)
|
||||||
var backgroundImageName string
|
var backgroundImageName string
|
||||||
switch qrcodeType {
|
switch qrcodeType {
|
||||||
case "promote":
|
case "promote":
|
||||||
backgroundImageName = "tg_qrcode_1.png"
|
backgroundImageName = "tg_qrcode_1.png"
|
||||||
case "invitation":
|
case "invitation":
|
||||||
backgroundImageName = "yq_qrcode_1.png"
|
backgroundImageName = "invitation_01.png" // 与 uniapp static/invitation/invitation_01.png 同一张图,部署时拷贝到 static/images
|
||||||
default:
|
default:
|
||||||
backgroundImageName = "tg_qrcode_1.png" // 默认使用第一张图片
|
backgroundImageName = "tg_qrcode_1.png" // 默认使用第一张图片
|
||||||
}
|
}
|
||||||
@@ -79,10 +79,10 @@ func (s *ImageService) ProcessImageWithQRCode(qrcodeType, qrcodeUrl string) ([]b
|
|||||||
|
|
||||||
case "invitation":
|
case "invitation":
|
||||||
// invitation类型:精确设置二维码尺寸
|
// invitation类型:精确设置二维码尺寸
|
||||||
qrSize = 360 // 固定尺寸320px
|
qrSize = 138 // 固定尺寸320px
|
||||||
// 中间偏上位置
|
// 中间偏上位置
|
||||||
qrX = (imgWidth - qrSize) / 2 // 水平居中
|
qrX = (imgWidth - qrSize) / 2 // 水平居中
|
||||||
qrY = 555 // 垂直位置200px
|
qrY = 140 // 垂直位置200px
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// 默认(promote样式)
|
// 默认(promote样式)
|
||||||
@@ -162,7 +162,7 @@ func (s *ImageService) CheckImageExists(qrcodeType string) bool {
|
|||||||
case "promote":
|
case "promote":
|
||||||
backgroundImageName = "tg_qrcode_1.png"
|
backgroundImageName = "tg_qrcode_1.png"
|
||||||
case "invitation":
|
case "invitation":
|
||||||
backgroundImageName = "yq_qrcode_1.png"
|
backgroundImageName = "invitation_01.png"
|
||||||
default:
|
default:
|
||||||
backgroundImageName = "tg_qrcode_1.png"
|
backgroundImageName = "tg_qrcode_1.png"
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
app/main/api/static/images/invitation_01.png
Normal file
BIN
app/main/api/static/images/invitation_01.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 74 KiB |
Reference in New Issue
Block a user