Quellcode durchsuchen

Merge branch 'feature/v1.2.11' of https://jygit.jydev.jianyu360.cn/jianyu/jy-docs into dev/v1.2.11_wmh

wenmenghao vor 1 Jahr
Ursprung
Commit
4cf509f438

+ 20 - 2
jydocs-back/config.json

@@ -11,7 +11,7 @@
     "stdDoc": {
       "key": "jydocs.stdlib.rpc",
       "address": [
-        "192.168.3.206:2379"
+        "127.0.0.1:2379"
       ]
     },
     "userDoc": {
@@ -41,5 +41,23 @@
     "测试"
   ],
   "searchNumLimit": 200,
-  "shareUrl": "https://web-wky.jydev.jianyu360.com/swordfish/SingleLogin"
+  "shareUrl": "https://web-wky.jydev.jianyu360.com/swordfish/SingleLogin",
+  "doudingImg": "https://img3.douding.cn/%s_90x80.jpg",
+  "price": {
+    "2": {
+      "1": {
+        "rate": 0,
+        "base": 50
+      },
+      "2": {
+        "rate": 100,
+        "base": 100
+      }
+    }
+  },
+  "docMember": {
+    "times": 100,
+    "discount": 8,
+    "source":["pc_Library details_free","app_Library details_free","wx_Library details_free","h5_Library details_free"]
+  }
 }

+ 26 - 0
jydocs-back/config/config.go

@@ -27,8 +27,34 @@ type appConfig struct {
 	IndexSearchTag []string `json:"indexSearchTag"` //首页标签
 	SearchNumLimit int64    `json:"searchNumLimit"` //检索条数限制
 	ShareUrl       string   `json:"shareUrl"`       //分享地址
+	DoudingImg     string   `json:"doudingImg"`     // 豆丁封面图片地址
+	Price          map[int64]map[int64]struct {
+		Rate int64 `json:"rate"` // 价格转换比率
+		Base int64 `json:"base"` // 价格基数
+	} `json:"price"`
+	DocMember struct {
+		Times    int      `json:"times"`    // 会员免费下载次数
+		Discount int64    `json:"discount"` // 会员折扣
+		Source   []string `json:"source"`   // 留资source
+	} `json:"docMember"`
 }
 
+/*
+例如
+
+	"price": {
+	  "2": {  // 对应文档来源 文档来源:;2:豆丁;
+	    "1": { // 对应商品类型 1:会员免费;2:精品(付费)
+	      "rate": 0, // 比率
+	      "base": 50 // 基数   例如会员免费文档  50+0*price = 50
+	    },
+	    "2": {
+	      "rate": 100, // 例如 精品  100+100*price
+	      "base": 100
+	    }
+	  }
+	}
+*/
 type rpcConfig struct {
 	Key     string   `json:"key"`
 	Address []string `json:"address"` //集群地址

+ 1 - 1
jydocs-back/filter/sessionfilter.go

@@ -19,7 +19,7 @@ func (l *sessionfilter) Do(w http.ResponseWriter, req *http.Request) bool {
 		strings.HasPrefix(rul, "/jydocs/detail") || strings.HasPrefix(rul, "/jydocs/detail/recommend") ||
 		strings.HasPrefix(rul, "/jydocs/topList") || strings.HasPrefix(rul, "/jydocs/activityList") ||
 		strings.HasPrefix(rul, "/jydocs/getAdvertisement") || strings.HasPrefix(rul, "/jydocs/indexTag") ||
-		strings.HasPrefix(rul, "/jydocs/share/img") {
+		strings.HasPrefix(rul, "/jydocs/share/img") || strings.HasPrefix(rul, "/jydocs/user/info") {
 		return true
 	}
 	if session.Get("userId") == nil {

+ 1 - 3
jydocs-back/go.mod

@@ -2,11 +2,9 @@ module jy-docs
 
 go 1.21
 
-toolchain go1.21rc2
-
 require (
 	app.yhyue.com/moapp/jyPoints v1.1.2-0.20231020023521-1a4b1bbf9736
-	app.yhyue.com/moapp/jy_docs v1.1.1
+	app.yhyue.com/moapp/jy_docs v1.1.2
 	app.yhyue.com/moapp/jybase v0.0.0-20240523083821-42a82b37ae20
 	app.yhyue.com/moapp/jyfs v0.0.0-20231024061508-480c270480d4
 	app.yhyue.com/moapp/jypkg v1.20.1

+ 2 - 3
jydocs-back/go.sum

@@ -4,8 +4,9 @@ app.yhyue.com/moapp/jyMarketing v0.0.2-0.20230304035551-21bb1eedf547 h1:cCmWQW8D
 app.yhyue.com/moapp/jyMarketing v0.0.2-0.20230304035551-21bb1eedf547/go.mod h1:JvIs8uKjdT963+7JnZGIEcL4ctBiBjwkoz0kNyigE78=
 app.yhyue.com/moapp/jyPoints v1.1.2-0.20231020023521-1a4b1bbf9736 h1:7Vl3qq1nJZyRQNyMDoCTC14ScKABZqbUmJP0WpOLnIQ=
 app.yhyue.com/moapp/jyPoints v1.1.2-0.20231020023521-1a4b1bbf9736/go.mod h1:NEkVbas7w0Lg4/BPoN4rkl808q4OKv7Bk5lwTXvOThU=
-app.yhyue.com/moapp/jy_docs v1.1.1 h1:eRCDfXuMMVMspB77gL7x8Pc3IU8FzHtTfLD4khu26lM=
 app.yhyue.com/moapp/jy_docs v1.1.1/go.mod h1:54sK98Z5tpMFd2aPLN1IRfEyV3zpFRyFxKj6oi2C5/Q=
+app.yhyue.com/moapp/jy_docs v1.1.2 h1:DFQHKbt/ZH91AHqRFcFKVjK0rSjkoEZlLyGNOgimuT8=
+app.yhyue.com/moapp/jy_docs v1.1.2/go.mod h1:54sK98Z5tpMFd2aPLN1IRfEyV3zpFRyFxKj6oi2C5/Q=
 app.yhyue.com/moapp/jybase v0.0.0-20210322021809-141cc2c37946/go.mod h1:29ShuI8y7qEyg2KviHSx1iamiCioBKdTMm2ndVzWAhk=
 app.yhyue.com/moapp/jybase v0.0.0-20220415064050-37ce64b3e2d4/go.mod h1:qNRA0sHuYqcLoYoP8irpaWnW9YsXixe6obBIkwaXpD0=
 app.yhyue.com/moapp/jybase v0.0.0-20220418104200-46c3fff161c7/go.mod h1:qNRA0sHuYqcLoYoP8irpaWnW9YsXixe6obBIkwaXpD0=
@@ -15,8 +16,6 @@ app.yhyue.com/moapp/jybase v0.0.0-20230117032034-ad7c00ffe11a/go.mod h1:zB47XTeJ
 app.yhyue.com/moapp/jybase v0.0.0-20230419121327-bedf77840ba6/go.mod h1:zB47XTeJvpcbtBRYgkQuxOICWNexiZfbUO+7aUf6mNs=
 app.yhyue.com/moapp/jybase v0.0.0-20230901064756-2fc66b18db40/go.mod h1:Hv9U/7oHRucqH315Tr1+d03NCvS9mOKPfk8pwwlOIwQ=
 app.yhyue.com/moapp/jybase v0.0.0-20231025021840-2f91c944ecdd/go.mod h1:Hv9U/7oHRucqH315Tr1+d03NCvS9mOKPfk8pwwlOIwQ=
-app.yhyue.com/moapp/jybase v0.0.0-20240226084952-7e7b38ef8a66 h1:kCRYqzclN4dtGuGC89ID2w5lGrJgqZC8bNL8mRR+tiU=
-app.yhyue.com/moapp/jybase v0.0.0-20240226084952-7e7b38ef8a66/go.mod h1:XHNATN6tsJKHdCB0DbUtFdPPHXexTUFyB3RlO+lUUoM=
 app.yhyue.com/moapp/jybase v0.0.0-20240523083821-42a82b37ae20 h1:F1ZHkzo7yHp5eNrZDqQxaXMIKFQU72bsI1dMq3ztJLA=
 app.yhyue.com/moapp/jybase v0.0.0-20240523083821-42a82b37ae20/go.mod h1:XHNATN6tsJKHdCB0DbUtFdPPHXexTUFyB3RlO+lUUoM=
 app.yhyue.com/moapp/jyfs v0.0.0-20231024061508-480c270480d4 h1:5oCyV5lZ65iYTx0jts6qsrM8xTc2dbEnVd7qqnUzfy0=

+ 15 - 0
jydocs-back/public/consts.go

@@ -0,0 +1,15 @@
+package public
+
+const (
+	ProductTypeMemberFree = 1 // 商品类型 会员免费
+	ProductTypePremium    = 2 // 商品类型 精品文档
+	ProductTypeFree       = 3 // 商品类型 免费
+	SourceJy              = 1 // 文档来源 剑鱼
+	SourceDd              = 2 // 文档来源 豆丁
+
+	FreeDownloadNoSL           = 0 // 文库没有留资
+	Free_download_NoFreeTimes  = 1 // 已经使用过一次特权下载机会
+	Free_download_HasFreeTimes = 2 // 留过资有一次特权下载机会
+	// 缓存key
+
+)

+ 25 - 8
jydocs-back/rpc/stdDocRpc.go

@@ -2,7 +2,6 @@ package rpc
 
 import (
 	"app.yhyue.com/moapp/jy_docs/rpc/stdlib/stdlib"
-	"app.yhyue.com/moapp/jy_docs/rpc/stdlib/stdlibclient"
 	"context"
 	"fmt"
 	"github.com/zeromicro/go-zero/core/discov"
@@ -12,10 +11,10 @@ import (
 )
 
 // 标准库RPC接口
-var jyStdDocStdlib stdlibclient.Stdlib
+var jyStdDocStdlib stdlib.Stdlib
 
 func init() {
-	jyStdDocStdlib = stdlibclient.NewStdlib(zrpc.MustNewClient(zrpc.RpcClientConf{
+	jyStdDocStdlib = stdlib.NewStdlib(zrpc.MustNewClient(zrpc.RpcClientConf{
 		Etcd: discov.EtcdConf{
 			Key:   config.JyDocsAppConfig.RpcServers.StdDoc.Key,
 			Hosts: config.JyDocsAppConfig.RpcServers.StdDoc.Address,
@@ -36,12 +35,14 @@ param
 	dSort 下载排序
 	vSort 浏览量排序
 */
-func GetDocQuery(userId, keyWord, tag string, pageNum, pageSize int64, sort string) ([]*stdlib.Doc, int64, error) {
+func GetDocQuery(userId, keyWord, tag string, pageNum, pageSize int64, sort string, productType, docFileType int64) ([]*stdlib.Doc, int64, error) {
 	param := &stdlib.DocQueryRequest{
-		AppId:    config.JyDocsAppConfig.AppId,
-		KeyWord:  keyWord,
-		PageSize: pageSize,
-		PageNum:  pageNum,
+		AppId:       config.JyDocsAppConfig.AppId,
+		KeyWord:     keyWord,
+		PageSize:    pageSize,
+		PageNum:     pageNum,
+		ProductType: productType,
+		DocFileType: docFileType,
 	}
 	if tag != "" {
 		param.DocTag = []string{tag}
@@ -156,3 +157,19 @@ func DocStatistics(userId, docId string, sign int32) {
 		log.Printf("%s DocStatistics fail Message %v\n", userId, resp)
 	}
 }
+
+func GetIndexTags() ([]string, error) {
+	resp, err := jyStdDocStdlib.DocIndexTag(context.Background(), &stdlib.DocIndexTagReq{})
+	if err != nil {
+		log.Printf("GetIndexTags call error %v\n", err)
+		return nil, err
+	}
+	if resp.Code != 1 {
+		log.Printf("GetIndexTags fail Message %v\n", resp.Msg)
+		return nil, fmt.Errorf("获取内容失败")
+	}
+	if resp.Tags == nil {
+		return nil, fmt.Errorf("查询异常")
+	}
+	return resp.Tags, nil
+}

+ 68 - 8
jydocs-back/servers/stdDoc.go

@@ -1,6 +1,7 @@
 package servers
 
 import (
+	"app.yhyue.com/moapp/jy_docs/rpc/stdlib/type/stdlib"
 	. "app.yhyue.com/moapp/jybase/api"
 	"app.yhyue.com/moapp/jybase/common"
 	"app.yhyue.com/moapp/jybase/go-xweb/xweb"
@@ -32,23 +33,50 @@ func (stdDoc *StdDoc) Search() {
 		sort := stdDoc.GetString("sort")                          //排序 tSort dSort vSort
 		pageNumReq, _ := stdDoc.GetInt("num")                     //页码 从1开始
 		pageSizeReq, _ := stdDoc.GetInt("size")                   //每页数量
+		productType, _ := stdDoc.GetInt("productType")            //每页数量
+		docFileType, _ := stdDoc.GetInt("docFileType")            //每页数量
 		pageNum, pageSize, err := public.PageNumParse(pageNumReq, pageSizeReq, config.JyDocsAppConfig.SearchNumLimit)
 		if err != nil {
 			return nil, err
 		}
-		if keyWord == "" {
+		if keyWord == "" && tag == "" && productType == 0 {
 			return nil, fmt.Errorf("检索内容不能为空")
 		}
 		if tag == "全部" {
 			tag = ""
 		}
-		list, total, err := rpc.GetDocQuery(userId, keyWord, tag, pageNum, pageSize, sort)
+		if keyWord == "" && (pageNum > 1 || pageSize > 50 || docFileType != 0) { // / 搜索时关键词不能为空 热门推荐 会员免费 精选推荐时关键词可以为空所以再判断一下页数
+			return nil, fmt.Errorf("参数有误")
+		}
+		// 关键词为空说明不是搜索过来的
+		topKey := fmt.Sprintf("jydoc_searchCache_%s_%d_%s_%d_%d", tag, productType, sort, pageNum, pageSize)
+		if keyWord == "" {
+			listCache := redis.Get("other", topKey)
+			if listCache != nil {
+				return listCache, nil
+			}
+		}
+		list, total, err := rpc.GetDocQuery(userId, keyWord, tag, pageNum, pageSize, sort, productType, docFileType)
 		if err != nil {
 			return nil, err
 		}
 		if total > config.JyDocsAppConfig.SearchNumLimit {
 			total = config.JyDocsAppConfig.SearchNumLimit
 		}
+		returnList := []interface{}{}
+		for _, v := range list {
+			//
+			if v.Source == public.SourceDd {
+				v.PreviewImgId = fmt.Sprintf(config.JyDocsAppConfig.DoudingImg, v.DocId)
+			} else {
+				v.PreviewImgId = fmt.Sprintf("https://%s.%s/%s", config.JyDocsAppConfig.OssBucket.Priv, config.JyDocsAppConfig.OssAdmin, v.PreviewImgId)
+			}
+			returnList = append(returnList, v)
+		}
+		// 存缓存
+		if keyWord == "" && len(returnList) > 0 {
+			redis.Put("other", topKey, list, 60*60*2)
+		}
 		return map[string]interface{}{
 			"total": total,
 			"list":  list,
@@ -61,7 +89,14 @@ func (stdDoc *StdDoc) Search() {
 }
 
 func (stdDoc *StdDoc) IndexTag() {
-	stdDoc.ServeJson(NewResult(config.JyDocsAppConfig.IndexSearchTag, nil))
+	tags, err := rpc.GetIndexTags()
+	stdDoc.ServeJson(NewResult(tags, err))
+}
+
+type returnDetail struct {
+	*stdlib.DocInfo
+	DocMemberPrice    int64 `json:"docMemberPrice"`
+	DocMemberDiscount int64 `json:"docMemberDiscount"`
 }
 
 func (stdDoc *StdDoc) Detail() {
@@ -82,12 +117,33 @@ func (stdDoc *StdDoc) Detail() {
 		//ossId清除
 		detail.OssPdfId = ""
 		detail.OssDocId = ""
-		detail.PreviewImgId = fmt.Sprintf("https://%s.%s/%s", config.JyDocsAppConfig.OssBucket.Priv, config.JyDocsAppConfig.OssAdmin, detail.PreviewImgId)
+		if detail.Source == public.SourceDd {
+			priceConfig := config.JyDocsAppConfig.Price[detail.Source][detail.ProductType]
+			// 豆丁的预览图和价格需要重新计算
+			detail.Price = priceConfig.Rate*detail.Price + priceConfig.Base
+			detail.PreviewImgId = fmt.Sprintf(config.JyDocsAppConfig.DoudingImg, detail.DocId)
+		} else {
+			detail.PreviewImgId = fmt.Sprintf("https://%s.%s/%s", config.JyDocsAppConfig.OssBucket.Priv, config.JyDocsAppConfig.OssAdmin, detail.PreviewImgId)
+		}
+		// 计算会员价
+		rs := returnDetail{
+			DocInfo:           detail,
+			DocMemberDiscount: config.JyDocsAppConfig.DocMember.Discount,
+		}
+		// 会员免费
+		if detail.ProductType == public.ProductTypeMemberFree {
+			rs.DocMemberPrice = 0
+		}
+		// 精品 8折
+		if detail.ProductType == public.ProductTypePremium {
+			rs.DocMemberPrice = detail.Price * config.JyDocsAppConfig.DocMember.Discount / 10
+		}
+
 		go rpc.DocStatistics(userId, docId, rpc.View) //统计下载次数
 		return map[string]interface{}{
 			"status":  common.If(isBuy, 1, 0),
 			"collect": common.If(IsCollect, 1, 0),
-			"detail":  detail,
+			"detail":  rs,
 		}, nil
 	}()
 	if errMsg != nil {
@@ -106,7 +162,7 @@ func (stdDoc *StdDoc) Recommend() {
 		if strings.Index(docTag, ",") > -1 {
 			docTag = strings.Split(docTag, ",")[0]
 		}
-		list, _, err := rpc.GetDocQuery(userId, "", docTag, 1, num+1, "dSort")
+		list, _, err := rpc.GetDocQuery(userId, "", docTag, 1, num+1, "dSort", 0, 0)
 		if err != nil {
 			return nil, err
 		}
@@ -116,7 +172,11 @@ func (stdDoc *StdDoc) Recommend() {
 				continue
 			}
 			v.DocSummary = ""
-			v.PreviewImgId = fmt.Sprintf("https://%s.%s/%s", config.JyDocsAppConfig.OssBucket.Priv, config.JyDocsAppConfig.OssAdmin, v.PreviewImgId)
+			if v.Source == public.SourceDd {
+				v.PreviewImgId = fmt.Sprintf(config.JyDocsAppConfig.DoudingImg, v.DocId)
+			} else {
+				v.PreviewImgId = fmt.Sprintf("https://%s.%s/%s", config.JyDocsAppConfig.OssBucket.Priv, config.JyDocsAppConfig.OssAdmin, v.PreviewImgId)
+			}
 			returnList = append(returnList, v)
 		}
 		return returnList, nil
@@ -182,7 +242,7 @@ func (stdDoc *StdDoc) TopList() {
 			return listCache, nil
 		}
 		log.Println("flush", topKey)
-		list, _, err := rpc.GetDocQuery(userId, "", "", 1, num, reqSort)
+		list, _, err := rpc.GetDocQuery(userId, "", "", 1, num, reqSort, 0, 0)
 		if err != nil {
 			return nil, err
 		}

+ 22 - 2
jydocs-back/servers/userDoc.go

@@ -7,6 +7,7 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
+	"jy-docs/config"
 	"jy-docs/public"
 	"jy-docs/rpc"
 	"log"
@@ -19,7 +20,7 @@ type UserDoc struct {
 	collectAdd    xweb.Mapper `xweb:"/user/collect/add"`    //收藏文库
 	collectRemove xweb.Mapper `xweb:"/user/collect/remove"` //取消收藏
 	docBuy        xweb.Mapper `xweb:"/user/buy"`            //文库购买
-	info          xweb.Mapper `xweb:"/user/info"`           //文库购买
+	info          xweb.Mapper `xweb:"/user/info"`           //文库会员信息
 }
 
 // 用户文库列表
@@ -162,13 +163,32 @@ func (userDoc *UserDoc) DocBuy() {
 func (userDoc *UserDoc) Info() {
 	userId := common.ObjToString(userDoc.GetSession("userId"))
 	rData, errMsg := func() (interface{}, error) {
-		mData := public.Compatible.Select(userId, `{"i_doc_status":1,"l_doc_endtime":1,"l_doc_starttime":1}`)
+		if userId == "" {
+			return map[string]interface{}{
+				"docMemberStatus": false,
+				"startTime":       0,
+				"endTime":         0,
+				"free_download":   public.FreeDownloadNoSL,
+			}, nil
+		}
+		mData := public.Compatible.Select(userId, `{"i_doc_status":1,"l_doc_endtime":1,"l_doc_starttime":1,"i_doc_free_download":1}`)
 		if mData != nil && len(*mData) > 0 {
+			free_download := common.IntAll((*mData)["i_doc_free_download"])
+			if (*mData)["i_doc_free_download"] == 0 { // 没有使用过一次免费下载机会
+				// 查留资
+				count := public.MQFW.Count("saleLeads", map[string]interface{}{"userid": userId, "source": map[string]interface{}{"$in": config.JyDocsAppConfig.DocMember.Source}})
+				if count > 0 {
+					free_download = public.Free_download_HasFreeTimes
+				} else {
+					free_download = public.FreeDownloadNoSL
+				}
+			}
 			vipStatus := common.IntAll((*mData)["i_doc_status"])
 			return map[string]interface{}{
 				"docMemberStatus": vipStatus > 0,
 				"startTime":       (*mData)["l_doc_starttime"],
 				"endTime":         (*mData)["l_doc_endtime"],
+				"free_download":   free_download,
 			}, nil
 		}
 		return nil, errors.New("获取文库会员状态失败")

+ 40 - 0
jydocs-back/test/p525.http

@@ -1,3 +1,43 @@
 POST http://127.0.0.1:821/jydocs/user/info
 Content-Type: application/x-www-form-urlencoded
 Cookie: SESSIONID=d6d16e5272466216cb3fb63c80f82cb2938a4e6c;
+
+### 热门文档
+POST http://127.0.0.1:821/jydocs/search
+Content-Type: application/x-www-form-urlencoded
+Cookie: SESSIONID=d6d16e5272466216cb3fb63c80f82cb2938a4e6c;
+
+tag=法律法规&&sort=vSort&num=1&size=10
+
+### 会员免费文档
+POST http://127.0.0.1:821/jydocs/search
+Content-Type: application/x-www-form-urlencoded
+Cookie: SESSIONID=d6d16e5272466216cb3fb63c80f82cb2938a4e6c;
+
+productType=1&&sort=vSort&num=1&size=10
+### 精选文档
+POST http://127.0.0.1:821/jydocs/search
+Content-Type: application/x-www-form-urlencoded
+Cookie: SESSIONID=d6d16e5272466216cb3fb63c80f82cb2938a4e6c;
+
+productType=2&&sort=vSort&num=1&size=10
+
+
+### 精选文档
+POST http://127.0.0.1:821/jydocs/search
+Content-Type: application/x-www-form-urlencoded
+Cookie: SESSIONID=d6d16e5272466216cb3fb63c80f82cb2938a4e6c;
+
+docFileType=2&&sort=vSort&num=1&size=10&keyWord=软件
+
+###
+POST http://127.0.0.1:821/jydocs/indexTag
+Content-Type: application/x-www-form-urlencoded
+Cookie: SESSIONID=d6d16e5272466216cb3fb63c80f82cb2938a4e6c;
+
+###
+POST http://127.0.0.1:821/jydocs/detail
+Content-Type: application/x-www-form-urlencoded
+Cookie: SESSIONID=d6d16e5272466216cb3fb63c80f82cb2938a4e6c;
+
+docId=9d97d240-8dd3-11eb-8419-0050568f1307