Merge remote-tracking branch 'origin/dev' into dev
正在显示
6 个修改的文件
包含
239 行增加
和
13 行删除
@@ -20,11 +20,6 @@ func MiniQrcodeInviteHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { | @@ -20,11 +20,6 @@ func MiniQrcodeInviteHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { | ||
20 | 20 | ||
21 | l := common.NewMiniQrcodeInviteLogic(r.Context(), svcCtx) | 21 | l := common.NewMiniQrcodeInviteLogic(r.Context(), svcCtx) |
22 | resp, err := l.MiniQrcodeInvite(&req) | 22 | resp, err := l.MiniQrcodeInvite(&req) |
23 | - if err != nil { | ||
24 | - result.HttpResult(r, w, resp, err) | ||
25 | - } | ||
26 | - w.Header().Set("Content-Disposition", "attachment; filename="+"qrcode.png") | ||
27 | - w.Header().Set("Content-Type", "application/octet-stream") | ||
28 | - w.Write(resp) | 23 | + result.HttpResult(r, w, resp, err) |
29 | } | 24 | } |
30 | } | 25 | } |
@@ -2,8 +2,12 @@ package common | @@ -2,8 +2,12 @@ package common | ||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "context" | 4 | "context" |
5 | + "encoding/json" | ||
6 | + "fmt" | ||
5 | "github.com/samber/lo" | 7 | "github.com/samber/lo" |
6 | "github.com/silenceper/wechat/v2/miniprogram/qrcode" | 8 | "github.com/silenceper/wechat/v2/miniprogram/qrcode" |
9 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/gateway/openlib" | ||
10 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/tool" | ||
7 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr" | 11 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr" |
8 | 12 | ||
9 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc" | 13 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc" |
@@ -26,8 +30,26 @@ func NewMiniQrcodeInviteLogic(ctx context.Context, svcCtx *svc.ServiceContext) * | @@ -26,8 +30,26 @@ func NewMiniQrcodeInviteLogic(ctx context.Context, svcCtx *svc.ServiceContext) * | ||
26 | } | 30 | } |
27 | } | 31 | } |
28 | 32 | ||
29 | -func (l *MiniQrcodeInviteLogic) MiniQrcodeInvite(req *types.MiniQrCodeRequest) (resp []byte, err error) { | ||
30 | - q := l.svcCtx.MiniProgram.GetQRCode() | 33 | +func (l *MiniQrcodeInviteLogic) MiniQrcodeInvite(req *types.MiniQrCodeRequest) (resp interface{}, err error) { |
34 | + var ( | ||
35 | + q = l.svcCtx.MiniProgram.GetQRCode() | ||
36 | + cacheData = fmt.Sprintf("%s?%s", req.Page, req.Scene) | ||
37 | + cacheKey = fmt.Sprintf("%s:qrcode:%s", l.svcCtx.Config.Name, tool.Md5ByString(cacheData)) | ||
38 | + ok bool | ||
39 | + qrcodeCache QrcodeCache | ||
40 | + ) | ||
41 | + // 从缓存获取 | ||
42 | + if ok, err = l.svcCtx.Redis.ExistsCtx(l.ctx, cacheKey); ok && err == nil { | ||
43 | + tmpCacheData, _ := l.svcCtx.Redis.Get(cacheKey) | ||
44 | + if err = json.Unmarshal([]byte(tmpCacheData), &qrcodeCache); err == nil { | ||
45 | + if qrcodeCache.CacheData == cacheData { | ||
46 | + return MiniQrCodeResponse{ | ||
47 | + Path: qrcodeCache.QrcodeUrl, | ||
48 | + }, nil | ||
49 | + } | ||
50 | + } | ||
51 | + } | ||
52 | + | ||
31 | var data []byte | 53 | var data []byte |
32 | data, err = q.GetWXACodeUnlimit(qrcode.QRCoder{ | 54 | data, err = q.GetWXACodeUnlimit(qrcode.QRCoder{ |
33 | Page: req.Page, | 55 | Page: req.Page, |
@@ -39,5 +61,34 @@ func (l *MiniQrcodeInviteLogic) MiniQrcodeInvite(req *types.MiniQrCodeRequest) ( | @@ -39,5 +61,34 @@ func (l *MiniQrcodeInviteLogic) MiniQrcodeInvite(req *types.MiniQrCodeRequest) ( | ||
39 | if err != nil { | 61 | if err != nil { |
40 | return nil, xerr.NewErr(err) | 62 | return nil, xerr.NewErr(err) |
41 | } | 63 | } |
42 | - return data, nil | 64 | + var result *openlib.DataPutFile |
65 | + result, err = l.svcCtx.OpenApiService.PutFile(l.ctx, openlib.RequestPutFile{ | ||
66 | + File: data, | ||
67 | + }) | ||
68 | + if err != nil { | ||
69 | + return nil, xerr.NewErr(err) | ||
70 | + } | ||
71 | + if result == nil || len(*result) == 0 || (*result)[0].Path == "" { | ||
72 | + return nil, xerr.NewErr(fmt.Errorf("上传失败")) | ||
73 | + } | ||
74 | + | ||
75 | + // 设置缓存 | ||
76 | + jsonData, err := json.Marshal(QrcodeCache{ | ||
77 | + CacheData: cacheData, | ||
78 | + QrcodeUrl: (*result)[0].Path, | ||
79 | + }) | ||
80 | + l.svcCtx.Redis.Set(cacheKey, string(jsonData)) | ||
81 | + | ||
82 | + return MiniQrCodeResponse{ | ||
83 | + Path: (*result)[0].Path, | ||
84 | + }, err | ||
85 | +} | ||
86 | + | ||
87 | +type MiniQrCodeResponse struct { | ||
88 | + Path string `json:"path"` | ||
89 | +} | ||
90 | + | ||
91 | +type QrcodeCache struct { | ||
92 | + CacheData string | ||
93 | + QrcodeUrl string | ||
43 | } | 94 | } |
@@ -14,6 +14,7 @@ import ( | @@ -14,6 +14,7 @@ import ( | ||
14 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain" | 14 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain" |
15 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/gateway" | 15 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/gateway" |
16 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/gateway/authlib" | 16 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/gateway/authlib" |
17 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/gateway/openlib" | ||
17 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/gateway/smslib" | 18 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/gateway/smslib" |
18 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/cache" | 19 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/cache" |
19 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/database" | 20 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/database" |
@@ -47,6 +48,7 @@ type ServiceContext struct { | @@ -47,6 +48,7 @@ type ServiceContext struct { | ||
47 | 48 | ||
48 | ApiAuthService authlib.ApiAuthService | 49 | ApiAuthService authlib.ApiAuthService |
49 | SmsService smslib.SMSService | 50 | SmsService smslib.SMSService |
51 | + OpenApiService openlib.OpenApiService | ||
50 | 52 | ||
51 | MiniProgram *miniprogram.MiniProgram | 53 | MiniProgram *miniprogram.MiniProgram |
52 | 54 | ||
@@ -74,6 +76,7 @@ func NewServiceContext(c config.Config) *ServiceContext { | @@ -74,6 +76,7 @@ func NewServiceContext(c config.Config) *ServiceContext { | ||
74 | Redis: redis, | 76 | Redis: redis, |
75 | ApiAuthService: apiAuth, | 77 | ApiAuthService: apiAuth, |
76 | SmsService: smslib.SMSService{Service: gateway.NewService("短信服务", "https://sms.fjmaimaimai.com:9897", time.Second*5)}, | 78 | SmsService: smslib.SMSService{Service: gateway.NewService("短信服务", "https://sms.fjmaimaimai.com:9897", time.Second*5)}, |
79 | + OpenApiService: openlib.OpenApiService{Service: gateway.NewService("开发接口服务", "https://mmm-open-api-test.fjmaimaimai.com", time.Second*5)}, | ||
77 | LoginStatusCheck: middleware.NewLoginStatusCheckMiddleware(apiAuth).Handle, | 80 | LoginStatusCheck: middleware.NewLoginStatusCheckMiddleware(apiAuth).Handle, |
78 | LogRequest: middleware.NewLogRequestMiddleware(c.LogRequest).Handle, | 81 | LogRequest: middleware.NewLogRequestMiddleware(c.LogRequest).Handle, |
79 | MiniProgram: miniProgram, | 82 | MiniProgram: miniProgram, |
@@ -14,7 +14,7 @@ import ( | @@ -14,7 +14,7 @@ import ( | ||
14 | 14 | ||
15 | type Service struct { | 15 | type Service struct { |
16 | Timeout time.Duration | 16 | Timeout time.Duration |
17 | - host string | 17 | + Host string |
18 | Interceptor func(msg string) | 18 | Interceptor func(msg string) |
19 | ServiceName string | 19 | ServiceName string |
20 | service httpc.Service | 20 | service httpc.Service |
@@ -25,7 +25,7 @@ func NewService(name string, host string, timeout time.Duration, opts ...httpc.O | @@ -25,7 +25,7 @@ func NewService(name string, host string, timeout time.Duration, opts ...httpc.O | ||
25 | //client.Timeout = timeout | 25 | //client.Timeout = timeout |
26 | 26 | ||
27 | service := Service{ | 27 | service := Service{ |
28 | - host: host, | 28 | + Host: host, |
29 | service: httpc.NewServiceWithClient(name, client, opts...), | 29 | service: httpc.NewServiceWithClient(name, client, opts...), |
30 | } | 30 | } |
31 | return service | 31 | return service |
@@ -37,7 +37,7 @@ func (gateway Service) Do(ctx context.Context, url string, method string, val in | @@ -37,7 +37,7 @@ func (gateway Service) Do(ctx context.Context, url string, method string, val in | ||
37 | begin = time.Now() | 37 | begin = time.Now() |
38 | body []byte | 38 | body []byte |
39 | ) | 39 | ) |
40 | - response, err := gateway.service.Do(ctx, method, gateway.host+url, val) | 40 | + response, err := gateway.service.Do(ctx, method, gateway.Host+url, val) |
41 | defer func() { | 41 | defer func() { |
42 | jsonParam, _ := json.Marshal(val) | 42 | jsonParam, _ := json.Marshal(val) |
43 | jsonData, _ := json.Marshal(result) | 43 | jsonData, _ := json.Marshal(result) |
@@ -45,7 +45,7 @@ func (gateway Service) Do(ctx context.Context, url string, method string, val in | @@ -45,7 +45,7 @@ func (gateway Service) Do(ctx context.Context, url string, method string, val in | ||
45 | result = err.Error() | 45 | result = err.Error() |
46 | } | 46 | } |
47 | if gateway.Interceptor != nil { | 47 | if gateway.Interceptor != nil { |
48 | - gateway.Interceptor(fmt.Sprintf("【网关】%v | %v%v | %v : %v \n-->> %v \n<<-- %v", time.Since(begin), gateway.host, url, strings.ToUpper(method), | 48 | + gateway.Interceptor(fmt.Sprintf("【网关】%v | %v%v | %v : %v \n-->> %v \n<<-- %v", time.Since(begin), gateway.Host, url, strings.ToUpper(method), |
49 | result, | 49 | result, |
50 | string(jsonParam), | 50 | string(jsonParam), |
51 | string(jsonData), | 51 | string(jsonData), |
@@ -84,6 +84,62 @@ func (gateway Service) Do(ctx context.Context, url string, method string, val in | @@ -84,6 +84,62 @@ func (gateway Service) Do(ctx context.Context, url string, method string, val in | ||
84 | return nil | 84 | return nil |
85 | } | 85 | } |
86 | 86 | ||
87 | +func (gateway Service) HandlerResponse(ctx context.Context, request *http.Request, response *http.Response, val, result interface{}) error { | ||
88 | + var ( | ||
89 | + baseResponse = Response{} | ||
90 | + begin = time.Now() | ||
91 | + body []byte | ||
92 | + err error | ||
93 | + ) | ||
94 | + defer func() { | ||
95 | + jsonParam, _ := json.Marshal(val) | ||
96 | + jsonData, _ := json.Marshal(result) | ||
97 | + if err != nil { | ||
98 | + result = err.Error() | ||
99 | + } | ||
100 | + if gateway.Interceptor != nil { | ||
101 | + gateway.Interceptor(fmt.Sprintf("【网关】%v | %v%v | %v : %v \n-->> %v \n<<-- %v", time.Since(begin), gateway.Host, request.URL.Path, request.Method, | ||
102 | + result, | ||
103 | + string(jsonParam), | ||
104 | + string(jsonData), | ||
105 | + )) | ||
106 | + } | ||
107 | + }() | ||
108 | + if err != nil { | ||
109 | + return err | ||
110 | + } | ||
111 | + if response.StatusCode != http.StatusOK { | ||
112 | + return HttpError{ | ||
113 | + Base: Response{ | ||
114 | + Code: response.StatusCode, | ||
115 | + Msg: response.Status, | ||
116 | + }, | ||
117 | + } | ||
118 | + } | ||
119 | + body, err = Bytes(response) | ||
120 | + if err != nil { | ||
121 | + return err | ||
122 | + } | ||
123 | + if err = json.Unmarshal(body, &baseResponse); err != nil { | ||
124 | + return err | ||
125 | + } | ||
126 | + if baseResponse.Code != 0 { | ||
127 | + return HttpError{ | ||
128 | + Base: Response{ | ||
129 | + Code: baseResponse.Code, | ||
130 | + Msg: baseResponse.Msg, | ||
131 | + }, | ||
132 | + } | ||
133 | + } | ||
134 | + if err = mapping.UnmarshalJsonBytes(baseResponse.Data, result); err != nil { | ||
135 | + return err | ||
136 | + } | ||
137 | + return nil | ||
138 | +} | ||
139 | + | ||
140 | +func (gateway Service) GetService() httpc.Service { | ||
141 | + return gateway.service | ||
142 | +} | ||
87 | func Bytes(resp *http.Response) ([]byte, error) { | 143 | func Bytes(resp *http.Response) ([]byte, error) { |
88 | var body []byte | 144 | var body []byte |
89 | if resp.Body == nil { | 145 | if resp.Body == nil { |
1 | +package openlib | ||
2 | + | ||
3 | +import ( | ||
4 | + "bytes" | ||
5 | + "context" | ||
6 | + "encoding/json" | ||
7 | + "github.com/zeromicro/go-zero/core/mapping" | ||
8 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/gateway" | ||
9 | + "io" | ||
10 | + "io/ioutil" | ||
11 | + "mime/multipart" | ||
12 | + "net/http" | ||
13 | + "net/url" | ||
14 | +) | ||
15 | + | ||
16 | +type OpenApiService struct { | ||
17 | + gateway.Service | ||
18 | +} | ||
19 | + | ||
20 | +func (svc *OpenApiService) PutFile(ctx context.Context, request RequestPutFile) (*DataPutFile, error) { | ||
21 | + var result DataPutFile | ||
22 | + r, _ := buildRequest(ctx, http.MethodPost, svc.Host+"/v1/vod/putObject", request) | ||
23 | + response, err := svc.GetService().DoRequest(r) | ||
24 | + if err != nil { | ||
25 | + return nil, err | ||
26 | + } | ||
27 | + if err := svc.HandlerResponse(ctx, r, response, nil, &result); err != nil { | ||
28 | + return nil, err | ||
29 | + } | ||
30 | + return &result, nil | ||
31 | +} | ||
32 | + | ||
33 | +func buildRequest(ctx context.Context, method, tmpUrl string, data any) (*http.Request, error) { | ||
34 | + u, err := url.Parse(tmpUrl) | ||
35 | + if err != nil { | ||
36 | + return nil, err | ||
37 | + } | ||
38 | + | ||
39 | + var val map[string]map[string]any | ||
40 | + if data != nil { | ||
41 | + val, err = mapping.Marshal(data) | ||
42 | + if err != nil { | ||
43 | + return nil, err | ||
44 | + } | ||
45 | + } | ||
46 | + | ||
47 | + var reader io.Reader | ||
48 | + jsonVars, hasJsonBody := val["json"] | ||
49 | + if hasJsonBody { | ||
50 | + var buf bytes.Buffer | ||
51 | + enc := json.NewEncoder(&buf) | ||
52 | + if err := enc.Encode(jsonVars); err != nil { | ||
53 | + return nil, err | ||
54 | + } | ||
55 | + | ||
56 | + reader = &buf | ||
57 | + } | ||
58 | + | ||
59 | + req, err := http.NewRequestWithContext(ctx, method, u.String(), reader) | ||
60 | + if err != nil { | ||
61 | + return nil, err | ||
62 | + } | ||
63 | + fileVars, hasFile := val["file"] | ||
64 | + if hasFile { | ||
65 | + if err = fillFile(req, fileVars); err != nil { | ||
66 | + return nil, err | ||
67 | + } | ||
68 | + } | ||
69 | + if hasJsonBody { | ||
70 | + req.Header.Set("Content-Type", "application/json; charset=utf-8") | ||
71 | + } | ||
72 | + | ||
73 | + return req, nil | ||
74 | +} | ||
75 | + | ||
76 | +func fillFile(req *http.Request, val map[string]any) error { | ||
77 | + if len(val) == 0 { | ||
78 | + return nil | ||
79 | + } | ||
80 | + pr, pw := io.Pipe() | ||
81 | + bodyWriter := multipart.NewWriter(pw) | ||
82 | + go func() { | ||
83 | + for k, v := range val { | ||
84 | + fileWriter, err := bodyWriter.CreateFormFile(k, k) | ||
85 | + if err != nil { | ||
86 | + return | ||
87 | + } | ||
88 | + //fh, err := os.Open(v.(string)) | ||
89 | + //if err != nil { | ||
90 | + // return err | ||
91 | + //} | ||
92 | + fh := bytes.NewBuffer(v.([]byte)) | ||
93 | + // iocopy | ||
94 | + _, err = io.Copy(fileWriter, fh) | ||
95 | + if err != nil { | ||
96 | + return | ||
97 | + } | ||
98 | + } | ||
99 | + bodyWriter.Close() | ||
100 | + pw.Close() | ||
101 | + }() | ||
102 | + req.Header.Set("Content-Type", bodyWriter.FormDataContentType()) | ||
103 | + req.Body = ioutil.NopCloser(pr) | ||
104 | + req.Header.Set("Transfer-Encoding", "chunked") | ||
105 | + return nil | ||
106 | +} |
1 | +package openlib | ||
2 | + | ||
3 | +type ( | ||
4 | + RequestPutFile struct { | ||
5 | + File []byte `file:"file.png"` | ||
6 | + } | ||
7 | + DataPutFile []*DataUploadItem | ||
8 | + | ||
9 | + DataUploadItem struct { | ||
10 | + Host string `json:"host"` | ||
11 | + Key string `json:"key"` | ||
12 | + Path string `json:"path"` | ||
13 | + FileName string `json:"fileName"` | ||
14 | + } | ||
15 | +) |
-
请 注册 或 登录 后发表评论