finclip-app-manager/application/qr_code_info.go

486 lines
15 KiB
Go
Raw Normal View History

2023-10-31 14:07:26 +08:00
package application
import (
"encoding/json"
"finclip-app-manager/domain/entity"
"finclip-app-manager/domain/entity/proto"
"finclip-app-manager/domain/entity/proto/apiproto"
"finclip-app-manager/domain/service"
"finclip-app-manager/infrastructure/config"
"finclip-app-manager/infrastructure/logger"
"finclip-app-manager/infrastructure/utility"
"finclip-app-manager/infrastructure/utils"
"fmt"
"net/http"
"net/url"
"path"
"strconv"
"strings"
"time"
"github.com/gin-gonic/gin"
uuid "github.com/satori/go.uuid"
"gitlab.finogeeks.club/finclip-backend/apm"
)
/**
* @api {POST}
* @apiGroup Finclip App Manager
* @apiParam (RequestBody) {string} appId Id
* @apiParam (RequestBody) {string} sequence
* @apiParam (RequestBody) {string} apiServer apiServer
* @apiParam (RequestBody) {string} type
* @apiParam (RequestBody) {string} codeId id
* @apiParam (RequestBody) {string} startParams
* @apiParamExample {json} Request-Example:
* {
* "appId": "5fd17becec413300012b1911",
* "sequence": 0,
* "apiServer": "https://finchat-mop-b.finogeeks.club",
* "type": "trial",
* "codeId": "c1218720c7a34e5f43b3b6d3",
* "startParams": {
* "path": "",
* "query": ""
* }
* }
* @apiSuccessExample {json} Success Status:
* HTTP/1.1 200 OK
* {
* "data": {
* "url": "https://finchat-mop-b.finogeeks.club/api/v1/mop/runtime/applet/-f-NDhiNThiOGIwYjJlNDdmZg--"
* },
* "errcode": "OK",
* "error": ""
* }
* @apiErrorExample Error Status:
* HTTP/1.1 !=200
*/
func GenQrcodeHand(c *gin.Context) {
traceCtx := apm.ApmClient().TraceContextFromGin(c)
req := proto.GenQrcodeReq{}
if err := c.BindJSON(&req); err != nil {
log.Errorf("GenQrcodeHand bind err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_PARAM_ERR, gin.H{})
return
}
log.Infof("GenQrcodeHand req:%+v", req)
svr := service.NewQrCodeInfoService()
info, err := svr.GenQrcodeInfo(traceCtx, req)
if err != nil {
log.Errorf("GenQrcodeHand GenQrcodeInfo err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{})
return
}
log.Debugf("get qrcode type:%s info:%+v", info.Type, info)
rspInfo := gin.H{}
if info.Type == entity.QrCodeTypeTemporary || info.Type == entity.QrCodeTypeRomoteDebug || info.Type == entity.QrCodeTypeReview {
rspInfo["expireTime"] = info.ExpireTime
}
server, err := parseServer(req.ApiServer)
if err != nil {
log.Errorf("gen url err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_PARAM_ERR, gin.H{})
return
}
var serverUrl string
if req.Limit != "" {
serverUrl = config.GetConfig().QRcodeUriV2
} else {
serverUrl = config.GetConfig().QRcodeUri
}
resultUrl := server + path.Join(serverUrl, req.Limit, "/", info.Uuid)
rspInfo["url"] = resultUrl
log.Debugf("qrcode type:%s result info:%+v", info.Type, rspInfo)
utility.MakeLocRsp(c, http.StatusOK, utility.OK, rspInfo)
return
}
//对原有的二维码逻辑进行重新处理
//文档见https://wiki.finogeeks.club/pages/viewpage.action?pageId=161317118
func joinUrl(server string, uri, uuid string) (string, error) {
u, err := url.Parse(server)
if err != nil {
return "", err
}
u.Path = path.Join(u.Path, uri, uuid)
return u.String(), nil
}
func parseServer(server string) (string, error) {
u, err := url.Parse(server)
if err != nil {
return "", err
}
return u.String(), nil
}
type appQRcodeInfoReq struct {
AppID string `json:"appId"`
Sequence int `json:"sequence"`
ApiServer string `json:"apiServer"`
CodeId string `json:"codeId"`
Type string `json:"type"`
StartParams appQRcodeInfoStartParams `json:"startParams"`
}
type appQRcodeInfoStartParams struct {
Path string `json:"path"`
Query string `json:"query"`
}
type EncryptInfo struct {
AppID string `json:"appId"`
Sequence int `json:"sequence"`
ApiServer string `json:"apiServer"`
CodeId string `json:"codeId"`
Type string `json:"type"`
StartParams appQRcodeInfoStartParams `json:"startParams"`
ExpireTime int64 `json:"expireTime"`
Uuid string `json:"uuid"`
}
type appQRcodeInfoRsp struct {
QRData string `json:"qrData"`
ExpireTime int `json:"expireTime"`
}
/**
* @api {GET}
* @apiGroup Finclip App Manager
* @apiSuccessExample {json} Success Status:
* HTTP/1.1 200 OK
* {
* "errcode": "OK",
* "error": "成功",
* "data":{
*
* }
* }
* @apiErrorExample Error Status:
* HTTP/1.1 !=200
*/
func QRCodeRefresh(c *gin.Context) {
req := appQRcodeInfoReq{}
if err := c.ShouldBindJSON(&req); err != nil {
log.Errorf("appInfo bind err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, nil)
return
}
log.Infof("QRCodeRefresh req:%+v", req)
addSecond, _ := time.ParseDuration(strconv.Itoa(config.GetConfig().QRcodeExpireTime) + "s")
encryptData := EncryptInfo{}
encryptData.AppID = req.AppID
encryptData.Sequence = req.Sequence
encryptData.ApiServer = req.ApiServer
encryptData.CodeId = req.CodeId
encryptData.Type = req.Type
if config.GetConfig().ApiServer != "" {
encryptData.ApiServer = config.GetConfig().ApiServer
}
encryptData.StartParams.Path = req.StartParams.Path
encryptData.StartParams.Query = req.StartParams.Query
//过期时间
encryptData.ExpireTime = -1
encryptData.Uuid = uuid.NewV4().String()
if req.Type == "temporary" {
encryptData.ExpireTime = time.Now().Add(addSecond).UnixNano() / 1e6
}
jsonByte, _ := json.Marshal(encryptData)
logger.GetLogger().Debugf("jsonByte:%s", string(jsonByte))
encodeStr := utils.EncodeAESContent(string(jsonByte))
//if req.Type == "temporary" {
// /*err := cache.NewAppCache(req.AppID).SetAppInfoQRcode(traceCtx, encodeStr, jsonByte, config.Cfg.QRcodeExpireTime)
// if err != nil {
// logger.GetLogger().Errorf("redis set data error:", err.Error())
// MakeRsp(c, http.StatusBadRequest, utility.FS_REDIS_ERR, nil)
// return
// }*/
// encryptData.ExpireTime = time.Now().Add(addSecond).UnixNano() / 1e6
//}
rsp := appQRcodeInfoRsp{}
rsp.QRData = encodeStr
rsp.ExpireTime = config.GetConfig().QRcodeExpireTime
utility.MakeLocRsp(c, http.StatusOK, utility.OK, rsp)
return
}
/**
* @api {GET}
* @apiGroup Finclip App Manager
* @apiSuccessExample {json} Success Status:
* HTTP/1.1 200 OK
* {
* "errcode": "OK",
* "error": "成功",
* "data":{
*
* }
* }
* @apiErrorExample Error Status:
* HTTP/1.1 !=200
*/
func InternalGetQRcodeAppVerInfo(c *gin.Context) {
//traceCtx := apm.ApmClient().TraceContextFromGin(c)
SDKKey := c.GetHeader(entity.SDKKEY_HEADER_KEY)
redisKey := c.GetHeader("redisKey")
log.Infof("InternalGetAppVerInfo req appId:%s,seq:%s,sdk-key:%s,sdk-ver:%s", SDKKey, redisKey)
rspErr := make(map[string]interface{})
if redisKey == "" {
log.Errorf("InternalGetAppVerInfo redisKey empty!!!")
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_LACK_OF_APPID, rspErr)
return
}
if SDKKey == "" {
log.Errorf("InternalGetAppVerInfo sdk-key empty!!!")
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_LACK_OF_SDKKEY, rspErr)
return
}
//sdkKey白名单的校验
if !utils.InArry(SDKKey, config.WhiteSDKArry) {
log.Errorf("RuntimeGetAppVersionInfo sdk not in white sdk arry,sdk-key:%s", SDKKey)
utility.MakeLocRsp(c, http.StatusForbidden, utility.FS_COOPERATION_TERMINATED, rspErr)
return
}
/* appVerSvr := service.NewAppVerService()
data, httpCode, errcode := appVerSvr.OpenApiGetAppVerInfo(traceCtx, appId, sequence, sdkVer)
if data == nil {
MakeRsp(c, httpCode, errcode, rspErr)
return
}
MakeRsp(c, httpCode, errcode, data)*/
rspInfo := InternalGetAppVerInfoRsp{}
// 临时注释
//dataBytes, err := cache.NewQRcodeAppCache().GetQRcodeAppInfo(c, redisKey)
//fmt.Println("dataBytes------------", dataBytes)
//if err != nil {
// if len(dataBytes) == 0 {
// log.Debugln("qrcode is refresh:")
// utility.MakeLocRsp(c, http.StatusOK, utility.FS_QRCODE_HAS_EXPIRE, rspInfo)
// return
// } else {
// log.Errorf("redis error:", err.Error())
// utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_DB_ERR, rspInfo)
// return
// }
//}
//err = json.Unmarshal(dataBytes, &rspInfo)
//if err != nil {
// log.Errorf("json unmarshal error:", err.Error())
// utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, rspInfo)
// return
//}
utility.MakeLocRsp(c, http.StatusOK, utility.OK, rspInfo)
return
}
/**
* @api {GET}
* @apiGroup Finclip App Manager
* @apiSuccessExample {json} Success Status:
* HTTP/1.1 200 OK
* {
* "errcode": "OK",
* "error": "成功",
* "data":{
*
* }
* }
* @apiErrorExample Error Status:
* HTTP/1.1 !=200
*/
func DeleteWechatQrcode(c *gin.Context) {
traceCtx := apm.ApmClient().TraceContextFromGin(c)
req := apiproto.DeleteWechatInfoReq{}
if err := c.ShouldBindJSON(&req); err != nil {
log.Errorf("UpdateWechatInfo err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, nil)
return
}
svr := service.NewQrCodeInfoService()
if err := svr.DeleteWechatQrcode(traceCtx, req); err != nil {
log.Errorf("DeleteWechatQrcode err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_DB_ERR, nil)
return
}
utility.MakeLocRsp(c, http.StatusOK, utility.OK, nil)
return
}
/**
* @api {GET}
* @apiGroup Finclip App Manager
* @apiSuccessExample {json} Success Status:
* HTTP/1.1 200 OK
* {
* "errcode": "OK",
* "error": "成功",
* "data":{
*
* }
* }
* @apiErrorExample Error Status:
* HTTP/1.1 !=200
*/
func GetQrcodeInfo(c *gin.Context) {
traceCtx := apm.ApmClient().TraceContextFromGin(c)
uuid := c.Param("uuid")
log.Infof("GetQrcodeInfo req uuid:%v", uuid)
svr := service.NewQrCodeInfoService()
info, err := svr.GetQrcodeInfo(traceCtx, uuid)
log.Errorf(utility.InterfaceToJsonString(info))
if err != nil {
log.Errorf("GetQrcodeInfo err:%s", err.Error())
if err == entity.NotFoundErr {
utility.MakeLocRsp(c, http.StatusNotFound, utility.FS_NOT_FOUND, gin.H{})
return
}
utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{})
return
}
now := time.Now().UnixNano() / 1e6
if info.Type == entity.QrCodeTypeReview && now >= info.ExpireTime {
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_QR_CODE_EXPIRED, gin.H{})
return
}
//uat多域名兼容
if utils.InArry(info.ApiServer, config.GetConfig().UatDomainList) {
info.ApiServer = "https://api.finclip.com"
}
//if info.ApiServer == "https://www.finclip.com" || info.ApiServer == "https://www.finclip.com/" {
// info.ApiServer = "https://api.finclip.com"
//}
resultInfo := make(map[string]interface{})
resultInfo["apiServer"] = info.ApiServer
resultInfo["type"] = info.Type
switch info.Type {
case entity.QrCodeTypeReview:
resultInfo["appId"] = info.AppId
resultInfo["sequence"] = info.Sequence
resultInfo["expireTime"] = info.ExpireTime
case entity.QrCodeTypeRelease:
resultInfo["appId"] = info.AppId
case entity.APP_BUILD_SOURCE_TRIAL:
resultInfo["codeId"] = info.CodeId
//这里的返回做一个转换
StartParamsMap := map[string]string{
"path": "",
"query": "",
}
paramList := strings.Split(info.StartParams.PathAndQuery, "?")
if len(paramList) > 0 {
StartParamsMap["path"] = paramList[0]
}
if len(paramList) > 1 {
StartParamsMap["query"] = paramList[1]
}
resultInfo["startParams"] = StartParamsMap
case entity.QrCodeTypeTemporary:
resultInfo["appId"] = info.AppId
resultInfo["codeId"] = info.AppId
resultInfo["sequence"] = info.Sequence
resultInfo["expireTime"] = info.ExpireTime
StartParamsMap := map[string]string{
"path": "",
"query": "",
}
paramList := strings.Split(info.StartParams.PathAndQuery, "?")
if len(paramList) > 0 {
StartParamsMap["path"] = paramList[0]
}
if len(paramList) > 1 {
StartParamsMap["query"] = paramList[1]
}
resultInfo["startParams"] = StartParamsMap
case entity.QrCodeTypeRomoteDebug:
resultInfo["appId"] = info.AppId
resultInfo["codeId"] = info.AppId
resultInfo["sequence"] = info.Sequence
resultInfo["expireTime"] = info.ExpireTime
resultInfo["debugInfo"] = info.DebugInfo
}
log.Infof("GetQrcodeInfo rsp:%+v", resultInfo)
infoByte, _ := json.Marshal(resultInfo)
infoStr := utils.EncodeAESContent(string(infoByte))
log.Infof("info.ApiServer:%v", info.ApiServer)
link := info.ApiServer + "/mop/scattered-page/#/sdktip"
resultUrl := fmt.Sprintf("%s?info=%s&type=scanOpen&codeType=%s", link, infoStr, info.Type)
//resultUrl := fmt.Sprintf("%s/mop/scattered-page/#/sdktip?info=%s&type=scanOpen&codeType=%s", info.ApiServer, infoStr, info.Type)
//c.Redirect(http.StatusMovedPermanently, resultUrl)
utility.MakeLocRsp(c, http.StatusOK, utility.OK, gin.H{"url": resultUrl})
return
}
const (
QRCodeMinWidth = 280
QRCodeMaxWidth = 1280
QRCodeDefaultWidth = 430
)
func GetQRCode(c *gin.Context) {
//traceCtx := apm.ApmClient().TraceContextFromGin(c)
//appID := c.Param("path1")
//widthStr := c.Query("width")
//width := QRCodeDefaultWidth
//if widthStr != "" {
// var err error
// width, err = strconv.Atoi(c.Query("width"))
// if err != nil {
// //msg := "Invalid width format: should be integer"
// utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, nil)
// return
// }
//}
//if width < QRCodeMinWidth || width > QRCodeMaxWidth {
// //msg := "Invalid width"
// utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, nil)
// return
//}
//if appID == "" {
// //msg := "Lack of appId"
// utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, nil)
// return
//}
//qr := model.QRCode{}
//if err := qr.GetOne(traceCtx, bson.M{"appId": appID}); err != nil {
// if err.Error() == model.ErrorNotFound {
// msg := fmt.Sprintf("QR Code info with appId %s not found", appID)
// LogAndSetErrResp(c, http.StatusNotFound, FS_NOT_FOUND, nil, msg, nil)
// return
// }
//}
//app := model.App{}
//if err := app.GetOne(traceCtx, bson.M{"appId": appID}); err != nil {
// if err.Error() == model.ErrorNotFound {
// msg := fmt.Sprintf("App with appId %s not found", appID)
// LogAndSetErrResp(c, http.StatusBadRequest, FS_BAD_JSON, nil, msg, nil)
// } else {
// LogAndSetErrResp(c, http.StatusInternalServerError, FS_SYSTEM_CALL, err, "Failed to get app", nil)
// }
// return
//}
////qrCodeStr := fmt.Sprintf("%s://applet/appid/%s?path=%s", qr.Scheme, appID, qr.Path)
//qrCodeStr := fmt.Sprintf("%s://applet/appid/%s", qr.Scheme, appID)
//if qr.Path != "" {
// qrCodeStr = qrCodeStr + "?path=" + qr.Path
//}
//bytes, err := createQRCode(traceCtx, qrCodeStr, app.Logo, width)
//if err != nil {
// LogAndSetErrResp(c, http.StatusInternalServerError, FS_SYSTEM_CALL, err, "Failed create QR Code", nil)
// return
//}
//c.Data(http.StatusOK, "image/png", bytes)
}
func GetQRCodeInfo(c *gin.Context) {
}