package analysisstorelogic import ( "context" "fmt" "strconv" "lone-services/pkg/redis" "lone-services/pkg/utils" "lone-services/pkg/wechat/qrcode" pkgws "lone-services/pkg/ws" analysis "lone-services/rpc/analysis/pb" chore "lone-services/rpc/chore/pb" analysisconfig "lone-services/services/analysis/internal/config" "lone-services/services/analysis/internal/logic/common" "lone-services/services/analysis/internal/svc" "github.com/google/uuid" jsoniter "github.com/json-iterator/go" "github.com/zeromicro/go-zero/core/logx" ) type StoreAuthQrcodeLogic struct { ctx context.Context svcCtx *svc.ServiceContext logx.Logger } func NewStoreAuthQrcodeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *StoreAuthQrcodeLogic { return &StoreAuthQrcodeLogic{ ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx), } } func (l *StoreAuthQrcodeLogic) StoreAuthQrcode(in *analysis.StoreAuthQrcodeReq) (*analysis.Response, error) { storeId, _, fail := common.RequireStoreId(l.ctx) if fail != nil { return fail, nil } wxCfg, err := analysisconfig.LoadWechatConfig() if err != nil { l.Errorf("store auth qrcode wechat config: %v", err) return common.OutResponse(utils.Fail, "微信配置缺失"), nil } sessionID, err := l.createSession() if err != nil { l.Errorf("store auth qrcode session: %v", err) return common.OutResponse(utils.Fail, "create qrcode session failed"), nil } storeKey := pkgws.RedisKeyQRSession + strconv.FormatInt(storeId, utils.NumberTen) if err := redis.Client.Set(l.ctx, storeKey, sessionID, pkgws.SessionTTL).Err(); err != nil { l.Errorf("store auth qrcode store mapping: %v", err) return common.FailResponse(utils.Fail), nil } img, err := wxCfg.NewQrcodeClient().CreateWxaCode(l.ctx, &qrcode.WxaCodeRequest{ Path: qrcode.BuildPath(wxCfg.AuthPage, map[string]string{ "store_id": strconv.FormatInt(storeId, utils.NumberTen), "session_id": sessionID, }), Width: wxCfg.Width, EnvVersion: wxCfg.EnvVersion, AutoColor: false, LineColor: &qrcode.LineColor{R: 255, G: 255, B: 255}, IsHyaline: true, }) if err != nil { l.Errorf("store auth qrcode wechat: %v", err) return common.OutResponse(utils.Fail, err.Error()), nil } qrURL, err := l.uploadQrcode(img) if err != nil { l.Errorf("store auth qrcode upload: %v", err) return common.OutResponse(utils.Fail, "upload qrcode failed"), nil } return common.OkResponse(map[string]string{ "qrcode": qrURL, "session_id": sessionID, }), nil } func (l *StoreAuthQrcodeLogic) createSession() (string, error) { if redis.Client == nil { return "", fmt.Errorf("redis not initialized") } sessionID := uuid.New().String() payload, err := jsoniter.MarshalToString(pkgws.Session{ Status: pkgws.StatusPending, }) if err != nil { return "", err } key := pkgws.RedisKeyQRSession + sessionID if err := redis.Client.Set(l.ctx, key, payload, pkgws.SessionTTL).Err(); err != nil { return "", err } return sessionID, nil } func (l *StoreAuthQrcodeLogic) uploadQrcode(content []byte) (string, error) { if l.svcCtx.ChoreSvcName == utils.StringEmpty { return "", fmt.Errorf("chore service name empty") } cli, err := svc.GetRpcClient(l.svcCtx.ChoreSvcName) if err != nil { return "", err } res, err := chore.NewChoreClient(cli.Conn()).InternalUpload(l.ctx, &chore.InternalUploadReq{ Filename: uuid.New().String() + ".png", Content: content, }) if err != nil { return "", err } if res == nil || res.Url == utils.StringEmpty { return "", fmt.Errorf("chore upload empty url") } return res.Url, nil }