Browse Source

Merge branch 'bzq1/short_url_cf' of eta_server/eta_api into debug

baoziqiang 5 months ago
parent
commit
b66e939930
8 changed files with 203 additions and 5 deletions
  1. 72 1
      controllers/report_v2.go
  2. 2 1
      go.mod
  3. 2 0
      go.sum
  4. 13 0
      models/report.go
  5. 18 0
      routers/commentsRouter.go
  6. 58 2
      services/report_v2.go
  7. 35 0
      utils/common.go
  8. 3 1
      utils/constants.go

+ 72 - 1
controllers/report_v2.go

@@ -12,13 +12,14 @@ import (
 	"eta/eta_api/services/data"
 	"eta/eta_api/utils"
 	"fmt"
-	"github.com/rdlucklib/rdluck_tools/paging"
 	"html"
 	"io"
 	"os"
 	"strconv"
 	"strings"
 	"time"
+
+	"github.com/rdlucklib/rdluck_tools/paging"
 )
 
 // ListReport
@@ -1659,6 +1660,76 @@ func (this *ReportController) CancelApprove() {
 	br.Msg = "操作成功"
 }
 
+// ShareGenerate
+// @Title 获取复制链接
+// @Description 获取复制链接
+// @Param	request	body models.ReportShartLinkReq true "type json string"
+// @Success 200 Ret=200 操作成功
+// @router /share/generate [post]
+func (this *ReportCommonController) ShareGenerate() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	var req models.ReportShartUrlReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数有误"
+		br.ErrMsg = "参数解析失败, Err: " + e.Error()
+		return
+	}
+
+	link, err := services.GetReportShareUrlToken(req)
+	if err != nil {
+		br.Msg = "复制链接失败"
+		br.ErrMsg = "获取复制链接失败, Err: " + err.Error()
+		return
+	}
+
+	resp := new(models.ReportShartUrlResp)
+	resp.UrlToken = link
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// ShareTransform
+// @Title 获取原始链接
+// @Description 获取原始链接
+// @Param	UrlToken   query   string  true    "复制链接的token"
+// @Success 200 Ret=200 操作成功
+// @router /share/transform [get]
+func (this *ReportCommonController) ShareTransform() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	token := this.GetString("UrlToken")
+
+	link, msg, err := services.TransfromToOriginUrl(token)
+	if err != nil {
+		if msg == "" {
+			msg = "获取失败"
+		}
+		br.Msg = msg
+		br.ErrMsg = "获取复制链接失败, Err: " + err.Error()
+		return
+	}
+
+	resp := new(models.ReportShartOriginUrlResp)
+	resp.Url = link
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
 // init
 // @Description: 修复历史报告数据
 // @author: Roc

+ 2 - 1
go.mod

@@ -37,11 +37,11 @@ require (
 	github.com/nosixtools/solarlunar v0.0.0-20211112060703-1b6dea7b4a19
 	github.com/olivere/elastic/v7 v7.0.32
 	github.com/pdfcpu/pdfcpu v0.8.0
-	github.com/pingcap/errors v0.11.5-0.20221009092201-b66cddb77c32
 	github.com/qiniu/qmgo v1.1.8
 	github.com/rdlucklib/rdluck_tools v1.0.3
 	github.com/shopspring/decimal v1.4.0
 	github.com/silenceper/wechat/v2 v2.1.6
+	github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72
 	github.com/spf13/viper v1.19.0
 	github.com/tealeg/xlsx v1.0.5
 	github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/asr v1.0.973
@@ -114,6 +114,7 @@ require (
 	github.com/montanaflynn/stats v0.7.1 // indirect
 	github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect
 	github.com/pelletier/go-toml/v2 v2.2.2 // indirect
+	github.com/pingcap/errors v0.11.5-0.20221009092201-b66cddb77c32 // indirect
 	github.com/pingcap/failpoint v0.0.0-20220801062533-2eaa32854a6c // indirect
 	github.com/pingcap/log v1.1.1-0.20230317032135-a0d097d16e22 // indirect
 	github.com/pingcap/tidb/pkg/parser v0.0.0-20231103042308-035ad5ccbe67 // indirect

+ 2 - 0
go.sum

@@ -491,6 +491,8 @@ github.com/smartystreets/assertions v1.1.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYl
 github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
 github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
 github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
+github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ=
+github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
 github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
 github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
 github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=

+ 13 - 0
models/report.go

@@ -1565,3 +1565,16 @@ func FindReportListByCondition(condition string, pars []interface{}) (items []*R
 	}
 	return
 }
+
+type ReportShartUrlReq struct {
+	Url      string `description:"分享链接"`
+	ReportId int    `description:"报告ID"`
+}
+
+type ReportShartUrlResp struct {
+	UrlToken string `description:"分享链接token"`
+}
+
+type ReportShartOriginUrlResp struct {
+	Url string `description:"分享链接token"`
+}

+ 18 - 0
routers/commentsRouter.go

@@ -10618,6 +10618,24 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_api/controllers:ReportCommonController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers:ReportCommonController"],
+        beego.ControllerComments{
+            Method: "ShareGenerate",
+            Router: `/share/generate`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers:ReportCommonController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers:ReportCommonController"],
+        beego.ControllerComments{
+            Method: "ShareTransform",
+            Router: `/share/transform`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_api/controllers:ReportController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers:ReportController"],
         beego.ControllerComments{
             Method: "CheckDayWeekReportChapterVideo",

+ 58 - 2
services/report_v2.go

@@ -10,13 +10,15 @@ import (
 	"eta/eta_api/models/system"
 	"eta/eta_api/utils"
 	"fmt"
-	"github.com/rdlucklib/rdluck_tools/file"
-	"github.com/rdlucklib/rdluck_tools/http"
 	"html"
 	"os"
 	"path"
 	"strconv"
 	"time"
+
+	"github.com/go-redis/redis/v8"
+	"github.com/rdlucklib/rdluck_tools/file"
+	"github.com/rdlucklib/rdluck_tools/http"
 )
 
 // AddReportAndChapter
@@ -1505,3 +1507,57 @@ func GetReportWaterMarkPdf(reportInfo *models.Report, sysUser *system.Admin) {
 	waterMarkStr := fmt.Sprintf("%s - %s", sysUser.RealName, sysUser.Mobile)
 	GeneralWaterMarkPdf(filePath, waterMarkStr)
 }
+
+// GetReportShareUrlToken 获取报告分享链接token
+func GetReportShareUrlToken(req models.ReportShartUrlReq) (linkToken string, err error) {
+	cacheLinkKey := utils.CACHE_REPORT_SHARE_SHORT_Url + strconv.Itoa(req.ReportId)
+	linkToken, _ = utils.Rc.RedisString(cacheLinkKey)
+	if linkToken != "" && utils.Rc.IsExist(utils.CACHE_REPORT_SHARE_ORIGIN_Url+linkToken) {
+		return
+	}
+	var ok bool
+	// 冲突检测
+	for i := 0; i < 3; i++ {
+		linkToken = req.Url
+		if i > 0 {
+			linkToken += "_" + utils.GetRandDigit(3)
+		}
+		hashUrl := utils.MurmurHash64([]byte(linkToken))
+		linkToken = utils.ConvertNumToBase62(hashUrl)
+
+		ok = utils.Rc.IsExist(utils.CACHE_REPORT_SHARE_ORIGIN_Url + linkToken)
+		if !ok {
+			break
+		}
+	}
+	if !ok {
+		after := time.Now().AddDate(0, 0, 7)
+		err = utils.Rc.Put(cacheLinkKey, linkToken, time.Until(after))
+		if err != nil {
+			return
+		}
+		err = utils.Rc.Put(utils.CACHE_REPORT_SHARE_ORIGIN_Url+linkToken, req.Url, time.Until(after))
+		if err != nil {
+			return
+		}
+	}
+	return
+}
+
+func TransfromToOriginUrl(linkToken string) (originLink string, msg string, err error) {
+	cacheLinkKey := utils.CACHE_REPORT_SHARE_ORIGIN_Url + linkToken
+	originLink, err = utils.Rc.RedisString(cacheLinkKey)
+	if err != nil {
+		if err == redis.Nil {
+			msg = "链接已失效, 请重新获取"
+			return
+		}
+		msg = "获取链接失败"
+		return
+	}
+	if originLink == "" {
+		msg = "链接已失效, 请重新获取"
+		return
+	}
+	return
+}

+ 35 - 0
utils/common.go

@@ -34,6 +34,7 @@ import (
 	"github.com/PuerkitoBio/goquery"
 	"github.com/microcosm-cc/bluemonday"
 	"github.com/shopspring/decimal"
+	"github.com/spaolacci/murmur3"
 	xhtml "golang.org/x/net/html"
 )
 
@@ -2791,6 +2792,40 @@ func RoundNumber(num string, decimalPlaces int, hasPercent bool) string {
 	return numStr
 }
 
+// MurmurHash64 计算字符串的64位哈希值
+func MurmurHash64(val []byte) uint64 {
+	hash64 := murmur3.New64()
+	hash64.Write(val)
+	return hash64.Sum64()
+}
+
+const base62Chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+
+type TUint interface {
+	uint64 | uint32 | uint16 | uint8 | uint
+}
+
+// ConvertNumToBase62 转换数字为base62编码
+func ConvertNumToBase62[T TUint](num T) string {
+	if num == 0 {
+		return string(base62Chars[0])
+	}
+
+	var result []byte
+	for num > 0 {
+		remainder := num % 62
+		result = append(result, base62Chars[remainder])
+		num /= 62
+	}
+
+	// 反转结果
+	for i, j := 0, len(result)-1; i < j; i, j = i+1, j-1 {
+		result[i], result[j] = result[j], result[i]
+	}
+
+	return string(result)
+}
+
 // IsAdminRole
 // @Description: 判断是否管理员角色
 // @author: Roc

+ 3 - 1
utils/constants.go

@@ -253,7 +253,9 @@ const (
 	CACHE_CREATE_REPORT_IMGPDF_QUEUE = "eta_report:report_img_pdf_queue" // 生成报告长图PDF队列
 	CACHE_EDB_TERMINAL_CODE_URL      = "edb:terminal_code:edb_code:"     // 指标与终端关系的缓存
 
-	CACHE_KEY_REPLACE_EDB = "eta:replace_edb" //系统用户操作日志队列
+	CACHE_KEY_REPLACE_EDB         = "eta:replace_edb"                 //系统用户操作日志队列
+	CACHE_REPORT_SHARE_SHORT_Url  = "eta:report_share_url:report_id:" //报告短链映射key
+	CACHE_REPORT_SHARE_ORIGIN_Url = "eta:report_share_url:token:"     //短链与原始报告链接的映射key
 )
 
 // 模板消息推送类型