浏览代码

Merge branch 'v1.0.1_ws' of moapp/jy_docs into feature/v1.0.1

wangshan 1 年之前
父节点
当前提交
27080dcbda
共有 51 个文件被更改,包括 2980 次插入125 次删除
  1. 96 56
      go.mod
  2. 475 49
      go.sum
  3. 5 0
      rpc/partnerlib/README.md
  4. 19 0
      rpc/partnerlib/crontab/crontab.go
  5. 57 0
      rpc/partnerlib/crontab/handle/ticker.go
  6. 31 0
      rpc/partnerlib/crontab/handle/timer.go
  7. 132 0
      rpc/partnerlib/crontab/service/docinInfo.go
  8. 39 0
      rpc/partnerlib/crontab/service/docinUpdate.go
  9. 133 0
      rpc/partnerlib/crontab/service/service.go
  10. 61 0
      rpc/partnerlib/crontab/service/viewsdownloadtimes.go
  11. 22 0
      rpc/partnerlib/entity/entity.go
  12. 20 0
      rpc/partnerlib/etc/crontab.yaml
  13. 23 0
      rpc/partnerlib/etc/interface.yaml
  14. 40 0
      rpc/partnerlib/etc/partnerlib.yaml
  15. 2 0
      rpc/partnerlib/etc/warn.yaml
  16. 二进制
      rpc/partnerlib/file/1.doc
  17. 37 0
      rpc/partnerlib/init/init.go
  18. 20 0
      rpc/partnerlib/internal/config/config.go
  19. 20 0
      rpc/partnerlib/internal/config/crontab.go
  20. 19 0
      rpc/partnerlib/internal/config/interface.go
  21. 5 0
      rpc/partnerlib/internal/config/warn.go
  22. 35 0
      rpc/partnerlib/internal/logic/docdownloadlogic.go
  23. 35 0
      rpc/partnerlib/internal/logic/userbuylogic.go
  24. 33 0
      rpc/partnerlib/internal/server/partnerserver.go
  25. 13 0
      rpc/partnerlib/internal/svc/servicecontext.go
  26. 31 0
      rpc/partnerlib/model/partner.go
  27. 二进制
      rpc/partnerlib/partner.exe
  28. 45 0
      rpc/partnerlib/partner/partner.go
  29. 40 0
      rpc/partnerlib/partnerlib.go
  30. 41 0
      rpc/partnerlib/partnerlib.proto
  31. 68 0
      rpc/partnerlib/service/docDownload.go
  32. 23 0
      rpc/partnerlib/service/ossFileUpload.go
  33. 143 0
      rpc/partnerlib/service/service.go
  34. 71 0
      rpc/partnerlib/service/userBuy.go
  35. 498 0
      rpc/partnerlib/type/partnerlib/partnerlib.pb.go
  36. 141 0
      rpc/partnerlib/type/partnerlib/partnerlib_grpc.pb.go
  37. 23 0
      rpc/partnerlib/util/util.go
  38. 46 0
      rpc/partnerlib/warn/warn.go
  39. 62 0
      services/model/partner.go
  40. 23 19
      services/model/stdlib.go
  41. 12 0
      services/partner/docBuyOrder.go
  42. 13 0
      services/partner/docCheck.go
  43. 112 0
      services/partner/docClass.go
  44. 18 0
      services/partner/docsFind.go
  45. 17 0
      services/partner/docsInsert.go
  46. 16 0
      services/partner/docsStatistics.go
  47. 31 0
      services/partner/docsUpdate.go
  48. 15 0
      services/partner/elastic.go
  49. 13 0
      services/partner/mgo.go
  50. 28 0
      services/partner/redis.go
  51. 78 1
      services/util/baseInit.go

+ 96 - 56
go.mod

@@ -3,98 +3,138 @@ module app.yhyue.com/moapp/jy_docs
 go 1.20
 
 require (
-	app.yhyue.com/moapp/jybase v0.0.0-20210322021809-141cc2c37946
+	app.yhyue.com/moapp/jybase v0.0.0-20240523083821-42a82b37ae20
 	app.yhyue.com/moapp/jyfs v0.0.0-20231024061508-480c270480d4
-	github.com/golang/protobuf v1.5.3
-	github.com/zeromicro/go-zero v1.5.6
-	google.golang.org/grpc v1.59.0
-	google.golang.org/protobuf v1.31.0
+	app.yhyue.com/moapp/jypkg v1.20.1
+	github.com/gogf/gf/v2 v2.7.1
+	github.com/golang/protobuf v1.5.4
+	github.com/zeromicro/go-zero v1.6.4
+	google.golang.org/grpc v1.63.2
+	google.golang.org/protobuf v1.33.0
 	gorm.io/gorm v1.21.3
 )
 
 require (
+	app.yhyue.com/moapp/esv1 v0.0.0-20220414031211-3da4123e648d // indirect
+	app.yhyue.com/moapp/jyMarketing v0.0.2-0.20230304035551-21bb1eedf547 // indirect
+	app.yhyue.com/moapp/jyPoints v1.1.2-0.20231020023521-1a4b1bbf9736 // indirect
+	app.yhyue.com/moapp/message v0.0.0-20231204024949-8c7145bfc161 // indirect
+	bp.jydev.jianyu360.cn/BaseService/entManageApplication v0.0.0-20231226074509-942d80dc34eb // indirect
+	bp.jydev.jianyu360.cn/BaseService/jyMicroservices v0.0.2 // indirect
+	bp.jydev.jianyu360.cn/BaseService/powerCheckCenter v0.0.0-20231222060155-36e225b61353 // indirect
+	bp.jydev.jianyu360.cn/BaseService/resourceCenter v0.1.3 // indirect
+	bp.jydev.jianyu360.cn/BaseService/userCenter v1.2.16 // indirect
+	filippo.io/edwards25519 v1.1.0 // indirect
+	github.com/BurntSushi/toml v1.3.2 // indirect
 	github.com/beorn7/perks v1.0.1 // indirect
-	github.com/cenkalti/backoff/v4 v4.2.0 // indirect
+	github.com/cenkalti/backoff/v4 v4.2.1 // indirect
 	github.com/cespare/xxhash/v2 v2.2.0 // indirect
+	github.com/clbanning/mxj/v2 v2.7.0 // indirect
 	github.com/coreos/go-semver v0.3.1 // indirect
 	github.com/coreos/go-systemd/v22 v22.5.0 // indirect
 	github.com/davecgh/go-spew v1.1.1 // indirect
-	github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f // indirect
 	github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
-	github.com/emicklei/go-restful/v3 v3.9.0 // indirect
-	github.com/fatih/color v1.15.0 // indirect
-	github.com/go-logr/logr v1.2.3 // indirect
+	github.com/emicklei/go-restful/v3 v3.11.0 // indirect
+	github.com/fatih/color v1.16.0 // indirect
+	github.com/fsnotify/fsnotify v1.7.0 // indirect
+	github.com/garyburd/redigo v1.6.2 // indirect
+	github.com/go-logr/logr v1.3.0 // indirect
 	github.com/go-logr/stdr v1.2.2 // indirect
 	github.com/go-openapi/jsonpointer v0.19.6 // indirect
-	github.com/go-openapi/jsonreference v0.20.1 // indirect
-	github.com/go-openapi/swag v0.22.3 // indirect
-	github.com/go-redis/redis/v8 v8.11.5 // indirect
-	github.com/go-sql-driver/mysql v1.7.1 // indirect
+	github.com/go-openapi/jsonreference v0.20.2 // indirect
+	github.com/go-openapi/swag v0.22.4 // indirect
+	github.com/go-sql-driver/mysql v1.8.1 // indirect
 	github.com/gogo/protobuf v1.3.2 // indirect
 	github.com/golang/mock v1.6.0 // indirect
-	github.com/google/gnostic v0.5.7-v3refs // indirect
-	github.com/google/go-cmp v0.5.9 // indirect
+	github.com/golang/snappy v0.0.4 // indirect
+	github.com/gomodule/redigo v2.0.0+incompatible // indirect
+	github.com/google/gnostic-models v0.6.8 // indirect
+	github.com/google/go-cmp v0.6.0 // indirect
 	github.com/google/gofuzz v1.2.0 // indirect
-	github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.0 // indirect
+	github.com/google/uuid v1.6.0 // indirect
+	github.com/gorilla/websocket v1.5.1 // indirect
+	github.com/grokify/html-strip-tags-go v0.1.0 // indirect
+	github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 // indirect
 	github.com/jinzhu/inflection v1.0.0 // indirect
 	github.com/jinzhu/now v1.1.1 // indirect
 	github.com/josharian/intern v1.0.0 // indirect
 	github.com/json-iterator/go v1.1.12 // indirect
+	github.com/klauspost/compress v1.16.7 // indirect
+	github.com/magiconair/properties v1.8.7 // indirect
 	github.com/mailru/easyjson v0.7.7 // indirect
 	github.com/mattn/go-colorable v0.1.13 // indirect
-	github.com/mattn/go-isatty v0.0.17 // indirect
-	github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
+	github.com/mattn/go-isatty v0.0.20 // indirect
+	github.com/mattn/go-runewidth v0.0.15 // indirect
+	github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 	github.com/modern-go/reflect2 v1.0.2 // indirect
+	github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
 	github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
+	github.com/nsqio/go-nsq v1.1.0 // indirect
+	github.com/olekukonko/tablewriter v0.0.5 // indirect
+	github.com/olivere/elastic v6.2.37+incompatible // indirect
 	github.com/olivere/elastic/v7 v7.0.22 // indirect
-	github.com/openzipkin/zipkin-go v0.4.1 // indirect
-	github.com/pelletier/go-toml/v2 v2.1.0 // indirect
+	github.com/openzipkin/zipkin-go v0.4.2 // indirect
+	github.com/pelletier/go-toml/v2 v2.2.0 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
-	github.com/prometheus/client_golang v1.16.0 // indirect
-	github.com/prometheus/client_model v0.4.0 // indirect
-	github.com/prometheus/common v0.42.0 // indirect
-	github.com/prometheus/procfs v0.10.1 // indirect
+	github.com/prometheus/client_golang v1.18.0 // indirect
+	github.com/prometheus/client_model v0.5.0 // indirect
+	github.com/prometheus/common v0.45.0 // indirect
+	github.com/prometheus/procfs v0.12.0 // indirect
+	github.com/redis/go-redis/v9 v9.4.0 // indirect
+	github.com/rivo/uniseg v0.2.0 // indirect
 	github.com/spaolacci/murmur3 v1.1.0 // indirect
-	go.etcd.io/etcd/api/v3 v3.5.9 // indirect
-	go.etcd.io/etcd/client/pkg/v3 v3.5.9 // indirect
-	go.etcd.io/etcd/client/v3 v3.5.9 // indirect
-	go.opentelemetry.io/otel v1.14.0 // indirect
-	go.opentelemetry.io/otel/exporters/jaeger v1.14.0 // indirect
-	go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0 // indirect
-	go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.14.0 // indirect
-	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0 // indirect
-	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.14.0 // indirect
-	go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0 // indirect
-	go.opentelemetry.io/otel/exporters/zipkin v1.14.0 // indirect
-	go.opentelemetry.io/otel/sdk v1.14.0 // indirect
-	go.opentelemetry.io/otel/trace v1.14.0 // indirect
-	go.opentelemetry.io/proto/otlp v0.19.0 // indirect
+	github.com/tealeg/xlsx v1.0.5 // indirect
+	github.com/thinxer/go-word2vec v0.0.0-20150917053916-5c19ec7379ed // indirect
+	github.com/xdg-go/pbkdf2 v1.0.0 // indirect
+	github.com/xdg-go/scram v1.1.2 // indirect
+	github.com/xdg-go/stringprep v1.0.4 // indirect
+	github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect
+	github.com/ziutek/blas v0.0.0-20190227122918-da4ca23e90bb // indirect
+	go.etcd.io/etcd/api/v3 v3.5.13 // indirect
+	go.etcd.io/etcd/client/pkg/v3 v3.5.13 // indirect
+	go.etcd.io/etcd/client/v3 v3.5.13 // indirect
+	go.mongodb.org/mongo-driver v1.14.0 // indirect
+	go.opentelemetry.io/otel v1.19.0 // indirect
+	go.opentelemetry.io/otel/exporters/jaeger v1.17.0 // indirect
+	go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 // indirect
+	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 // indirect
+	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 // indirect
+	go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.19.0 // indirect
+	go.opentelemetry.io/otel/exporters/zipkin v1.19.0 // indirect
+	go.opentelemetry.io/otel/metric v1.19.0 // indirect
+	go.opentelemetry.io/otel/sdk v1.19.0 // indirect
+	go.opentelemetry.io/otel/trace v1.19.0 // indirect
+	go.opentelemetry.io/proto/otlp v1.0.0 // indirect
 	go.uber.org/atomic v1.10.0 // indirect
 	go.uber.org/automaxprocs v1.5.3 // indirect
 	go.uber.org/multierr v1.9.0 // indirect
 	go.uber.org/zap v1.24.0 // indirect
-	golang.org/x/net v0.15.0 // indirect
-	golang.org/x/oauth2 v0.11.0 // indirect
-	golang.org/x/sys v0.12.0 // indirect
-	golang.org/x/term v0.12.0 // indirect
-	golang.org/x/text v0.13.0 // indirect
-	golang.org/x/time v0.3.0 // indirect
-	google.golang.org/appengine v1.6.7 // indirect
-	google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect
-	google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d // indirect
-	google.golang.org/genproto/googleapis/rpc v0.0.0-20230913181813-007df8e322eb // indirect
+	golang.org/x/crypto v0.22.0 // indirect
+	golang.org/x/net v0.24.0 // indirect
+	golang.org/x/oauth2 v0.17.0 // indirect
+	golang.org/x/sync v0.6.0 // indirect
+	golang.org/x/sys v0.19.0 // indirect
+	golang.org/x/term v0.19.0 // indirect
+	golang.org/x/text v0.14.0 // indirect
+	golang.org/x/time v0.5.0 // indirect
+	google.golang.org/appengine v1.6.8 // indirect
+	google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect
+	google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect
+	gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
 	gopkg.in/inf.v0 v0.9.1 // indirect
 	gopkg.in/yaml.v2 v2.4.0 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 	gorm.io/driver/mysql v1.0.5 // indirect
-	k8s.io/api v0.26.3 // indirect
-	k8s.io/apimachinery v0.27.0-alpha.3 // indirect
-	k8s.io/client-go v0.26.3 // indirect
-	k8s.io/klog/v2 v2.90.1 // indirect
-	k8s.io/kube-openapi v0.0.0-20230307230338-69ee2d25a840 // indirect
-	k8s.io/utils v0.0.0-20230209194617-a36077c30491 // indirect
+	jygit.jydev.jianyu360.cn/ApplicationCenter/publicService v0.0.0-20231023011746-38dc3b6aded8 // indirect
+	k8s.io/api v0.29.3 // indirect
+	k8s.io/apimachinery v0.29.3 // indirect
+	k8s.io/client-go v0.29.3 // indirect
+	k8s.io/klog/v2 v2.110.1 // indirect
+	k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect
+	k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect
 	sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
-	sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
+	sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
 	sigs.k8s.io/yaml v1.3.0 // indirect
 )

文件差异内容过多而无法显示
+ 475 - 49
go.sum


+ 5 - 0
rpc/partnerlib/README.md

@@ -0,0 +1,5 @@
+#### 合作商文档 下载,购买,更新等操作
+
+#### 1:豆丁
+
+#### goctl rpc protoc partnerlib.proto --go_out=./type --go-grpc_out=./type --zrpc_out=.

+ 19 - 0
rpc/partnerlib/crontab/crontab.go

@@ -0,0 +1,19 @@
+package crontab
+
+import (
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/crontab/service"
+	IC "app.yhyue.com/moapp/jy_docs/rpc/partnerlib/init"
+	"github.com/gogf/gf/v2/os/gctx"
+)
+
+func StartTask() {
+	if IC.Cron.IsRun {
+		ctx := gctx.New()
+		//浏览量 下载量更新到检索库
+		//go service.VDTimesUpdate()
+		//获取豆丁docs基本信息
+		go service.GetDocinInfoTask(ctx)
+		//更新豆丁docs基本信息
+		go service.UpdateDocinInfoTask(ctx)
+	}
+}

+ 57 - 0
rpc/partnerlib/crontab/handle/ticker.go

@@ -0,0 +1,57 @@
+package cron
+
+import (
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/entity"
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/internal/config"
+	"app.yhyue.com/moapp/jy_docs/services/partner"
+	"app.yhyue.com/moapp/jybase/date"
+	"context"
+	"fmt"
+	"github.com/gogf/gf/v2/frame/g"
+	"github.com/gogf/gf/v2/os/gcron"
+	"time"
+)
+
+func CrontabByTicker(ctx context.Context, cron config.Cron, f func(cron config.Cron)) {
+	var paramReset = func() {
+		if cron.StartIdKey != "" {
+			if startId := partner.GetDocsStartId(entity.RedisCode, cron.StartIdKey); startId != 0 {
+				cron.StartId = startId
+			}
+		}
+		if cron.StartDateKey != "" {
+			if startDate := partner.GetUpdateTaskInfo(entity.RedisCode, cron.StartDateKey); startDate != "" {
+				cron.StartDate = startDate
+			}
+		}
+		entity.SyncExpectTotal = 0
+		entity.SyncActualTotal = 0
+		entity.UpdateExpectTotal = 0
+		entity.UpdateActualTotal = 0
+	}
+	_, err := gcron.Add(ctx, cron.Time, func(ctx context.Context) {
+		//离线 市场分析报告 处理
+		g.Log().Info(ctx, "----------------------start-------------当前时间:", time.Now().Format(date.Date_Full_Layout))
+		//数据重置处理
+		paramReset()
+		//暂停定时任务  待一轮任务处理完后 再开启
+		go gcron.Stop(cron.Name)
+		f(cron)
+		//开启下一轮定时任务
+		gcron.Start(cron.Name)
+		g.Log().Info(ctx, "----------------------end-------------当前时间:", time.Now().Format(date.Date_Full_Layout))
+	}, cron.Name)
+	if err != nil {
+		g.Log().Info(ctx, fmt.Sprintf("%s定时任务异常", "----"))
+	}
+	//首次运行
+	if cron.First {
+		//数据重置处理
+		paramReset()
+		//暂停定时任务  待一轮任务处理完后 再开启
+		go gcron.Stop(cron.Name)
+		f(cron)
+		//开启下一轮定时任务
+		gcron.Start(cron.Name)
+	}
+}

+ 31 - 0
rpc/partnerlib/crontab/handle/timer.go

@@ -0,0 +1,31 @@
+package cron
+
+import (
+	"app.yhyue.com/moapp/jybase/common"
+	"log"
+	"strings"
+	"time"
+)
+
+func CrontabByTimer(flag bool, c string, f func()) {
+	array := strings.Split(c, ":")
+	if len(array) != 2 {
+		log.Fatalln("定时任务参数错误!", c)
+	}
+	if flag {
+		go f()
+	}
+	now := time.Now()
+	t := time.Date(now.Year(), now.Month(), now.Day(), common.IntAll(array[0]), common.IntAll(array[1]), 0, 0, time.Local)
+	if t.Before(now) {
+		t = t.AddDate(0, 0, 1)
+	}
+	timer := time.NewTimer(t.Sub(now))
+	for {
+		select {
+		case <-timer.C:
+			go f()
+			timer.Reset(24 * time.Hour)
+		}
+	}
+}

+ 132 - 0
rpc/partnerlib/crontab/service/docinInfo.go

@@ -0,0 +1,132 @@
+package service
+
+import (
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/entity"
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/model"
+	sm "app.yhyue.com/moapp/jy_docs/services/model"
+	"app.yhyue.com/moapp/jy_docs/services/partner"
+	"app.yhyue.com/moapp/jybase/date"
+	"crypto/md5"
+	"encoding/hex"
+	"encoding/json"
+	"fmt"
+	"strings"
+	"time"
+)
+
+func InsertDocinInfos(b []byte) (err error, lastId int64, expectTotal, actualTotal int) {
+	var docinInfos model.DocinInfoRes
+	str := string(b)
+	fmt.Println(str, "--------------")
+	err = json.Unmarshal(b, &docinInfos)
+	if err == nil {
+		if expectTotal = len(docinInfos.Data); expectTotal > 0 {
+			//剑鱼doc 一份 || 豆丁备份表一份
+			var (
+				docs           []sm.Docin
+				docsStatistics []sm.DocStatistics
+				docsES         []map[string]interface{}
+			)
+			for _, v := range docinInfos.Data {
+				var (
+					id                = fmt.Sprintf("%s-%d", entity.PartnerName, v.ProductId)
+					md5Id             = GetMD5(id, v.ProductName, v.Desc, v.FilePostfix) //判断数据是否已存在 md5
+					price             = int(v.Price * entity.Multiple)                   //价格转换
+					docTags, docClass = partner.SwitchDocClass(v.PcatName, v.CatName, 1) //标签和分类
+					fileType          = GetDocFileType(v.FilePostfix)
+				)
+				if partner.CheckDocs(id, md5Id) {
+					continue
+				}
+				lastId = v.ProductId
+				//tidb 分类
+				docsStatistics = append(docsStatistics, sm.DocStatistics{
+					AppId:      entity.AppId,
+					DocId:      id,
+					UpdateDate: time.Now(),
+					DownTimes:  v.DownloadCount,
+					ViewTimes:  v.VisitCount,
+				})
+				//tidb 文档
+				docs = append(docs, sm.Docin{
+					Id:              id,
+					UserId:          entity.PartnerName,
+					AppId:           entity.AppId,
+					DocName:         v.ProductName,
+					DocFileType:     fileType,
+					DocFileSuffix:   v.FilePostfix,
+					DocFileSize:     int(v.FileSize),
+					DocPageSize:     v.PageCount,
+					DocTags:         strings.Join(docTags, ","),
+					DocClass:        docClass,
+					UploadDate:      date.NowFormat(date.Date_Full_Layout),
+					IsDelete:        0,
+					OssDocId:        "",
+					Md5:             md5Id, //
+					OssPdfId:        "",
+					OssTxtId:        "",
+					Price:           price,
+					DownOrUp:        0,
+					DocSummary:      v.Desc,
+					PreviewImgId:    "",
+					EncryptionLevel: 0,
+					Source:          2,              //豆丁
+					ProductType:     v.Ifcharge + 1, //Ifcharge:是否付费,0:免费,1:收费;ProductType:商品类型:默认:0:全部;1:会员免费;2:精品(付费)
+					UpdateDate:      date.NowFormat(date.Date_Full_Layout),
+				})
+				//elastic
+				docsES = append(docsES, map[string]interface{}{
+					"_id":          id,
+					"docClass":     docClass,
+					"docFileSize":  int(v.FileSize),
+					"docFileType":  fileType,
+					"docName":      v.ProductName,
+					"docPageSize":  v.PageCount,
+					"docSummary":   v.Desc,
+					"docTags":      strings.Join(docTags, ","),
+					"downTimes":    v.DownloadCount,
+					"previewImgId": v.ProductId,
+					"price":        price,
+					"uploadDate":   date.NowFormat(date.Date_Full_Layout),
+					"viewTimes":    v.VisitCount,
+					"source":       2, //豆丁
+					"productType":  v.Ifcharge + 1,
+				})
+			}
+			if len(docs) > 0 {
+				actualTotal = len(docs)
+				//doc 文库文档数据信息
+				partner.DocsInsert(docs, entity.InBatchesCount)
+				//docsStatistics 文库文档浏览量及下载量信息
+				partner.DocsStatistics(docsStatistics, entity.InBatchesCount)
+				//es sync data
+				partner.SyncDocsToES(docsES)
+			}
+		}
+	}
+	return
+}
+
+func GetMD5(id, productName, desc, FilePostfix string) string {
+	hash := md5.Sum([]byte(fmt.Sprintf("%s#%s#%#s#%s", id, productName, desc, FilePostfix)))
+	return hex.EncodeToString(hash[:])
+}
+
+func GetDocFileType(fileSuffix string) (i int) {
+	//1 doc 2 pdf 3 xls 4 ppt 5 txt 6 其他
+	switch strings.ToLower(fileSuffix) {
+	case "doc":
+		i = 1
+	case "pdf":
+		i = 2
+	case "xls", "xlsx":
+		i = 3
+	case "ppt":
+		i = 4
+	case "txt":
+		i = 5
+	default:
+		i = 6
+	}
+	return
+}

+ 39 - 0
rpc/partnerlib/crontab/service/docinUpdate.go

@@ -0,0 +1,39 @@
+package service
+
+import (
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/entity"
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/model"
+	sm "app.yhyue.com/moapp/jy_docs/services/model"
+	"app.yhyue.com/moapp/jy_docs/services/partner"
+	"app.yhyue.com/moapp/jybase/date"
+	"encoding/json"
+	"fmt"
+	"time"
+)
+
+func UpdateDocinInfos(b []byte) (err error, lastId int64, expectTotal, actualTotal int) {
+	var docinInfos model.DocinInfoRes
+	err = json.Unmarshal(b, &docinInfos)
+	if err == nil {
+		if expectTotal = len(docinInfos.Data); expectTotal > 0 {
+			//更新doc
+			for _, v := range docinInfos.Data {
+				var (
+					id  = fmt.Sprintf("%s-%d", entity.PartnerName, v.ProductId)
+					doc = sm.Doc{}
+				)
+				lastId = v.ProductId
+				doc.Id = id
+				doc.UpdateDate, _ = time.ParseInLocation(date.Date_Full_Layout, v.ModifyDate, time.Local)
+				doc.Price = int(v.Price * entity.Multiple)
+				doc.PriceVip = v.PriceVip
+				doc.ProductType = v.Ifcharge + 1
+				doc.DownOrUp = v.State
+				if err := partner.DocsUpdate(doc); err == nil {
+					actualTotal++
+				}
+			}
+		}
+	}
+	return
+}

+ 133 - 0
rpc/partnerlib/crontab/service/service.go

@@ -0,0 +1,133 @@
+package service
+
+import (
+	cron "app.yhyue.com/moapp/jy_docs/rpc/partnerlib/crontab/handle"
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/entity"
+	. "app.yhyue.com/moapp/jy_docs/rpc/partnerlib/init"
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/internal/config"
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/service"
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/warn"
+	"app.yhyue.com/moapp/jy_docs/services/partner"
+	"app.yhyue.com/moapp/jybase/common"
+	"app.yhyue.com/moapp/jybase/date"
+	"context"
+	"fmt"
+	"github.com/gogf/gf/v2/util/gconv"
+	"log"
+	"time"
+)
+
+// 获取豆丁docs基本信息
+func GetDocinInfoTask(ctx context.Context) {
+	defer common.Catch()
+	cron.CrontabByTicker(ctx, Cron.NewDocsList, SyncDocinInfo)
+}
+
+func SyncDocinInfo(cron config.Cron) {
+	log.Println("sync Docin info task start :", date.NowFormat(date.Date_Full_Layout))
+	var (
+		startId = cron.StartId
+		h       = service.NewHH(I.Docin.Name, I.Docin.Host, I.Docin.DocList.Name, I.Docin.DocList.Pathname, I.Docin.DocList.Method, map[string]interface{}{
+			"startId": startId,
+			"count":   Cron.NewDocsList.Count,
+		})
+		b, err, _ = h.HttpFunc()
+		lastId    = startId
+	)
+	go h.SaveDocinLogger(b, err, "req")
+	if err == nil {
+		if len(b) > 0 {
+			var et, at int
+			//豆丁同步数据到mongo
+			go h.SaveDocinLogger(b, err, "res")
+			err, lastId, et, at = InsertDocinInfos(b)
+			entity.SyncExpectTotal = entity.SyncExpectTotal + et
+			entity.SyncActualTotal = entity.SyncActualTotal + at
+			if err != nil {
+				go warn.SendMsgByWXURL(fmt.Sprintf("同步豆丁数据到tidb失败:%s,当前任务执行参数:%v", err.Error(), cron))
+			} else if lastId > 0 {
+				//周期内数据未同步完成
+				cron.StartId = lastId
+				if cron.Count == et {
+					if st := Cron.NewDocsList.SleepTime; st > 0 {
+						time.Sleep(time.Duration(st) * time.Millisecond)
+					}
+					SyncDocinInfo(cron)
+				}
+			}
+		}
+	} else {
+		go warn.SendMsgByWXURL(fmt.Sprintf("获取豆丁数据列表失败:%s,当前任务执行参数:%v", err.Error(), cron))
+	}
+	//缓存 保存最后一次更新id
+	if b := partner.SetDocsStartId(entity.RedisCode, cron.StartIdKey, cron.StartId, -1); !b {
+		log.Println("同步 Docin 数据 更新最新id缓存异常: ", cron.StartId)
+	} else {
+		log.Println("同步 Docin 数据 更新最新id缓存成功: ", cron.StartId)
+	}
+	log.Println(fmt.Sprintf("sync Docin info task end :%s-当前任务更新 预计数据量:%d 实际数据量:%d", date.NowFormat(date.Date_Full_Layout), entity.SyncExpectTotal, entity.SyncActualTotal))
+}
+
+// 更新豆丁docs基本信息
+func UpdateDocinInfoTask(ctx context.Context) {
+	defer common.Catch()
+	cron.CrontabByTicker(ctx, Cron.UpdateDocsList, UpdateDocinInfo)
+}
+
+func UpdateDocinInfo(cron config.Cron) {
+	var (
+		startId   = cron.StartId
+		count     = cron.Count
+		startDate = cron.StartDate
+		endDate   = cron.EndDate
+	)
+	log.Println("update Docin info task start :", date.NowFormat(date.Date_Full_Layout))
+	if endDate == "" {
+		endDate = date.NowFormat(date.Date_yyyyMMdd)
+	}
+	if startDate == "" || endDate == "" || count == 0 || gconv.Int64(startDate) >= gconv.Int64(endDate) {
+		go warn.SendMsgByWXURL(fmt.Sprintf("timetask 保存 docin 文档失败--参数异常:startId:%d --startDate:%s --endDate:%s--count:%d", startId, startDate, endDate, count))
+		return
+	}
+	h := service.NewHH(I.Docin.Name, I.Docin.Host, I.Docin.UpdateList.Name, I.Docin.UpdateList.Pathname, I.Docin.UpdateList.Method, map[string]interface{}{
+		"startId":   startId,
+		"count":     count,
+		"startDate": startDate,
+		"endDate":   endDate,
+	})
+	b, err, _ := h.HttpFunc()
+	lastId := startId
+	go h.SaveDocinLogger(b, err, "req")
+	if err == nil {
+		if len(b) > 0 {
+			var et, at int
+			//豆丁更新数据到mongo
+			go h.SaveDocinLogger(b, err, "res")
+			err, lastId, et, at = UpdateDocinInfos(b)
+			entity.UpdateExpectTotal = entity.UpdateExpectTotal + et
+			entity.UpdateActualTotal = entity.UpdateActualTotal + at
+			if err != nil {
+				go warn.SendMsgByWXURL(fmt.Sprintf("更新豆丁数据到tidb失败:%s,当前任务执行参数:%v", err.Error(), cron))
+			} else if lastId > 0 {
+				cron.StartId = lastId
+				//周期内数据未同步完成
+				if count == et {
+					if st := Cron.UpdateDocsList.SleepTime; st > 0 {
+						time.Sleep(time.Duration(st) * time.Millisecond)
+					}
+					UpdateDocinInfo(cron)
+				}
+			}
+		}
+	} else {
+		go warn.SendMsgByWXURL(fmt.Sprintf("获取豆丁更新数据失败:%s,当前任务执行参数:%v", err.Error(), cron))
+	}
+	//缓存数据处理
+	partner.SetUpdateTaskInfo(entity.RedisCode, cron.StartDateKey, endDate, -1)
+	partner.DelDocsStartId(entity.RedisCode, cron.StartIdKey)
+	//休眠
+	if st := Cron.UpdateDocsList.SleepTime; st > 0 {
+		time.Sleep(time.Duration(st) * time.Millisecond)
+	}
+	log.Println(fmt.Sprintf("update Docin info task end :%s-当前任务更新 预计数据量:%d 实际数据量:%d", date.NowFormat(date.Date_Full_Layout), entity.UpdateExpectTotal, entity.UpdateActualTotal))
+}

+ 61 - 0
rpc/partnerlib/crontab/service/viewsdownloadtimes.go

@@ -0,0 +1,61 @@
+package service
+
+//
+//import (
+//	"app.yhyue.com/moapp/jy_docs/timetask/config"
+//	"app.yhyue.com/moapp/jy_docs/timetask/cron"
+//	"app.yhyue.com/moapp/jy_docs/timetask/entity"
+//	"app.yhyue.com/moapp/jybase/common"
+//	"app.yhyue.com/moapp/jybase/date"
+//	elastic "app.yhyue.com/moapp/jybase/esv7"
+//	"app.yhyue.com/moapp/jybase/go-logger/logger"
+//	"fmt"
+//	"log"
+//)
+//
+////浏览量和下载量定时更新
+//
+//func VDTimesUpdate() {
+//	defer common.Catch()
+//	cron.CrontabByTicker(config.TimeTask.UpdateViewsDownload.First, config.TimeTask.UpdateDocsDate.Time, func() {
+//		now := date.NowFormat(date.Date_Full_Layout)
+//		log.Println("start update docs views and download times to es:", now)
+//		rows, err := config.Mysql.Raw(`select docId,downTimes,viewTimes from doc_statistics where updateDate>=? and updateDate<?`, config.TimeTask.UpdateViewsDownload.StartTime, now).Rows()
+//		if err != nil {
+//			logger.Error(err)
+//			return
+//		}
+//		if rows != nil {
+//			defer rows.Close()
+//		}
+//		array := [][]string{}
+//		index := 0
+//		for rows.Next() {
+//			var docId string
+//			var downTimes int
+//			var viewTimes int
+//			err = rows.Scan(&docId, &downTimes, &viewTimes)
+//			if err != nil {
+//				logger.Error(err)
+//				continue
+//			}
+//			log.Println("need update to es", "docId", docId, "downTimes", downTimes, "viewTimes", viewTimes)
+//			index++
+//			array = append(array, []string{docId, fmt.Sprintf("ctx._source.downTimes=%d;ctx._source.viewTimes=%d", downTimes, viewTimes)})
+//			if len(array) == config.Config.BlukSize {
+//				logger.Info("update es index", index, elastic.NewBulkUpdate(entity.Es_Jydoc, array...))
+//				array = [][]string{}
+//			}
+//		}
+//		if len(array) > 0 {
+//			logger.Info("update es index", index, elastic.NewBulkUpdate(entity.Es_Jydoc, array...))
+//			array = [][]string{}
+//		}
+//		config.TimeTask.UpdateViewsDownload.StartTime = now
+//		common.WriteSysConfig("./timetask.json", &config.TimeTask)
+//		logger.Info("update to es over", index)
+//	})
+//	//config.TimeTask.Time = now
+//	//logger.Info("update to es over", index)
+//	//time.AfterFunc(time.Duration(config.Config.DurationMinute)*time.Minute, VDTimesUpdate)
+//}

+ 22 - 0
rpc/partnerlib/entity/entity.go

@@ -0,0 +1,22 @@
+package entity
+
+import "sync"
+
+const (
+	DateFormat         = "20060102"
+	RedisCode          = "newother"
+	AppId              = "10000"
+	InBatchesCount     = 20
+	ElasticJYDoc       = "jydoc"
+	Multiple           = 10
+	DocTable           = "doc"
+	DocStatisticsTable = "doc_statistics"
+	DateFullLayout     = "20060102150405"
+	PartnerName        = "docin"
+	DocUserOrderTab    = "doc_user_order"
+)
+
+var (
+	SyncExpectTotal, SyncActualTotal, UpdateExpectTotal, UpdateActualTotal int //批次预计处理数据和实际处理数据
+	DocsLock                                                               = &sync.Mutex{}
+)

+ 20 - 0
rpc/partnerlib/etc/crontab.yaml

@@ -0,0 +1,20 @@
+IsRun: true
+NewDocsList:
+  Name: syncDocs
+  First: true
+  Time: "0 0 0/4 * * ?"
+  StartId: 0
+  StartIdKey: docin_sync_start_id
+  Count: 50
+  SleepTime: 10
+UpdateDocsList:
+  Name: updateDocs
+  First: false
+  Time: "0 0 2 * * 6 ?" # 豆丁文档更新量比较少,每周六早上两点开始
+  StartId: 0 # 首次任务执行:0;以后配置成1
+  StartIdKey: docin_update_start_id
+  Count: 50
+  StartDate: "20230411" # 首次任务执行:20240411
+  StartDateKey: docin_update_start_date
+  EndDate: "" # 默认空
+  SleepTime: 10

+ 23 - 0
rpc/partnerlib/etc/interface.yaml

@@ -0,0 +1,23 @@
+Docin:
+  Name: 豆丁
+  Host: https://t.docin.com
+  AppId: QHXKW0Z4JPM0GZXK
+  AppSecret: tYLwu4fk7BQsS8WgP2g3o1BZv5Mxm2Ta
+  DocList:
+    Name: 文档列表接口
+    Pathname: /api/jianyu/getProducts.do
+    Method: GET
+  UpdateList:
+    Name: 文档更新接口
+    Pathname: /api/jianyu/getModifiedProducts.do
+    Method: GET
+  DocDownload:
+    Name: 文档下载接口
+    Pathname: /api/jianyu/getFile.do
+    Method: GET
+  BuyRecord:
+    Name: 购买会员记录接口
+    Pathname: /api/jianyu/addSaleTransaction.do
+    Method: POST
+
+

+ 40 - 0
rpc/partnerlib/etc/partnerlib.yaml

@@ -0,0 +1,40 @@
+Name: jydocs.partnerlib.rpc
+ListenOn: 127.0.0.1:8082
+WebRpcPort: 8185
+Etcd:
+  Hosts:
+    - 127.0.0.1:2379
+  Key: jydocs.partnerlib.rpc
+JyDocsMysqlDB:
+  DriverName: "mysql"
+  DataSourceName: "root:=PDT49#80Z!RVv52_z@tcp(192.168.3.217:4000)/jydocs?charset=utf8mb4&parseTime=true&loc=Local"
+  MaxOpenConn: 20
+  MaxIdleConn: 10
+  MaxConnLifeTime: 100
+EsConfig:
+  Addr: "http://192.168.3.242:9200"
+  Pool: 30
+  UserName: elastic
+  Password: elastic
+RedisAddr:
+  - other=192.168.3.149:1712
+  - newother=192.168.3.149:1712
+Mongo:
+  Main:
+    Address: 192.168.3.206:27080
+    Size: 5
+    DbName: qfw
+    UserName: ""
+    Password: ""
+  Logger:
+    Address: 192.168.3.206:27090
+    Size: 5
+    DbName: qfw
+    UserName: admin
+    Password: "123456"
+FileSystemConf:
+  Hosts:
+    - 127.0.0.1:2379
+  Key: moapp.filesystem.rpc
+OssInfo:
+  BucketName: jydocs-std #上线前需要配置新bucket

+ 2 - 0
rpc/partnerlib/etc/warn.yaml

@@ -0,0 +1,2 @@
+WebhookURL:
+  - https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=78864582-d770-452f-a55d-e8d17c647f31

二进制
rpc/partnerlib/file/1.doc


+ 37 - 0
rpc/partnerlib/init/init.go

@@ -0,0 +1,37 @@
+package init
+
+import (
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/internal/config"
+	"app.yhyue.com/moapp/jy_docs/services/partner"
+	jyDocsRpcUtil "app.yhyue.com/moapp/jy_docs/services/util"
+	_ "app.yhyue.com/moapp/jypkg/public"
+	"flag"
+	"github.com/zeromicro/go-zero/core/conf"
+)
+
+var (
+	configFile    = flag.String("c", "etc/partnerlib.yaml", "the partnerlib file")
+	interfaceFile = flag.String("i", "etc/interface.yaml", "the interface file")
+	crontabFile   = flag.String("cron", "etc/crontab.yaml", "the crontab file")
+	warnFile      = flag.String("warn", "etc/warn.yaml", "the warn file")
+	C             config.Config
+	I             config.InterfaceInfo
+	Cron          config.CrontabInfo
+	Warn          config.Warn
+)
+
+func init() {
+	conf.MustLoad(*configFile, &C)
+	conf.MustLoad(*interfaceFile, &I)
+	conf.MustLoad(*crontabFile, &Cron)
+	conf.MustLoad(*warnFile, &Warn)
+	if C.JyDocsMysqlDB.DataSourceName != "" && C.EsConfig.Addr != "" {
+		jyDocsRpcUtil.InitDB(C.JyDocsMysqlDB.DataSourceName, C.JyDocsMysqlDB.DriverName, C.JyDocsMysqlDB.MaxOpenConn, C.JyDocsMysqlDB.MaxIdleConn)
+		jyDocsRpcUtil.InitESV7(C.EsConfig.Addr, C.EsConfig.Pool, C.EsConfig.UserName, C.EsConfig.Password)
+		jyDocsRpcUtil.InitRedis(C.RedisAddr)
+		jyDocsRpcUtil.InitMongo(C.Mongo)
+		jyDocsRpcUtil.InitOss(C.FileSystemConf)
+	}
+	//初始化 分类对应关系
+	go partner.InitDocClass()
+}

+ 20 - 0
rpc/partnerlib/internal/config/config.go

@@ -0,0 +1,20 @@
+package config
+
+import (
+	jyDocRpcUtil "app.yhyue.com/moapp/jy_docs/services/util"
+	"github.com/zeromicro/go-zero/core/discov"
+	"github.com/zeromicro/go-zero/zrpc"
+)
+
+type Config struct {
+	zrpc.RpcServerConf
+	WebRpcPort     int64
+	JyDocsMysqlDB  jyDocRpcUtil.MysqlDBConfig
+	EsConfig       jyDocRpcUtil.EsConfig
+	RedisAddr      []string
+	Mongo          jyDocRpcUtil.MongoConfig
+	FileSystemConf discov.EtcdConf
+	OssInfo        struct {
+		BucketName string
+	}
+}

+ 20 - 0
rpc/partnerlib/internal/config/crontab.go

@@ -0,0 +1,20 @@
+package config
+
+type CrontabInfo struct {
+	IsRun          bool
+	NewDocsList    Cron
+	UpdateDocsList Cron
+}
+
+type Cron struct {
+	Name         string
+	First        bool
+	Time         string
+	StartId      int64  `json:",optional"`
+	StartIdKey   string `json:",optional"`
+	Count        int
+	StartDate    string `json:",optional"`
+	StartDateKey string `json:",optional"`
+	EndDate      string `json:",optional"`
+	SleepTime    int    `json:",optional"`
+}

+ 19 - 0
rpc/partnerlib/internal/config/interface.go

@@ -0,0 +1,19 @@
+package config
+
+type InterfaceInfo struct {
+	Docin struct {
+		Name        string
+		Host        string
+		AppId       string
+		AppSecret   string
+		DocList     BaseInfo
+		UpdateList  BaseInfo
+		DocDownload BaseInfo
+		BuyRecord   BaseInfo
+	}
+}
+type BaseInfo struct {
+	Name     string
+	Pathname string
+	Method   string
+}

+ 5 - 0
rpc/partnerlib/internal/config/warn.go

@@ -0,0 +1,5 @@
+package config
+
+type Warn struct {
+	WebhookURL []string
+}

+ 35 - 0
rpc/partnerlib/internal/logic/docdownloadlogic.go

@@ -0,0 +1,35 @@
+package logic
+
+import (
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/service"
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/warn"
+	"context"
+	"fmt"
+
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/internal/svc"
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/type/partnerlib"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type DocDownloadLogic struct {
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+	logx.Logger
+}
+
+func NewDocDownloadLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DocDownloadLogic {
+	return &DocDownloadLogic{
+		ctx:    ctx,
+		svcCtx: svcCtx,
+		Logger: logx.WithContext(ctx),
+	}
+}
+
+func (l *DocDownloadLogic) DocDownload(in *partnerlib.UserDownloadRequest) (*partnerlib.UDRes, error) {
+	res, err := service.DocDownload(in)
+	if err != nil {
+		go warn.SendMsgByWXURL(fmt.Sprintf("文档下载异常:%s,下载参数:%v", err.Error(), in))
+	}
+	return res, err
+}

+ 35 - 0
rpc/partnerlib/internal/logic/userbuylogic.go

@@ -0,0 +1,35 @@
+package logic
+
+import (
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/service"
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/warn"
+	"context"
+	"fmt"
+
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/internal/svc"
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/type/partnerlib"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type UserBuyLogic struct {
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+	logx.Logger
+}
+
+func NewUserBuyLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserBuyLogic {
+	return &UserBuyLogic{
+		ctx:    ctx,
+		svcCtx: svcCtx,
+		Logger: logx.WithContext(ctx),
+	}
+}
+
+func (l *UserBuyLogic) UserBuy(in *partnerlib.UserBuyVipRequest) (*partnerlib.UBVRes, error) {
+	res, err := service.UBHandle(in)
+	if err != nil {
+		go warn.SendMsgByWXURL(fmt.Sprintf("精品文档购买异常:%s,下载参数:%v", err.Error(), in))
+	}
+	return res, err
+}

+ 33 - 0
rpc/partnerlib/internal/server/partnerserver.go

@@ -0,0 +1,33 @@
+// Code generated by goctl. DO NOT EDIT!
+// Source: partnerlib.proto
+
+package server
+
+import (
+	"context"
+
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/internal/logic"
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/internal/svc"
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/type/partnerlib"
+)
+
+type PartnerServer struct {
+	svcCtx *svc.ServiceContext
+	partnerlib.UnimplementedPartnerServer
+}
+
+func NewPartnerServer(svcCtx *svc.ServiceContext) *PartnerServer {
+	return &PartnerServer{
+		svcCtx: svcCtx,
+	}
+}
+
+func (s *PartnerServer) DocDownload(ctx context.Context, in *partnerlib.UserDownloadRequest) (*partnerlib.UDRes, error) {
+	l := logic.NewDocDownloadLogic(ctx, s.svcCtx)
+	return l.DocDownload(in)
+}
+
+func (s *PartnerServer) UserBuy(ctx context.Context, in *partnerlib.UserBuyVipRequest) (*partnerlib.UBVRes, error) {
+	l := logic.NewUserBuyLogic(ctx, s.svcCtx)
+	return l.UserBuy(in)
+}

+ 13 - 0
rpc/partnerlib/internal/svc/servicecontext.go

@@ -0,0 +1,13 @@
+package svc
+
+import "app.yhyue.com/moapp/jy_docs/rpc/partnerlib/internal/config"
+
+type ServiceContext struct {
+	Config config.Config
+}
+
+func NewServiceContext(c config.Config) *ServiceContext {
+	return &ServiceContext{
+		Config: c,
+	}
+}

+ 31 - 0
rpc/partnerlib/model/partner.go

@@ -0,0 +1,31 @@
+package model
+
+type DocinInfoRes struct {
+	Code      int    //状态码
+	Msg       string //状态信息
+	StartId   int64  //起始文档ID
+	Count     int    //请求文档量
+	ListCount int    //列表大小
+	Data      []Docs //列表内容
+	StartDate string //起始修改日期
+	EndDate   string //结束修改日期
+}
+
+type Docs struct {
+	PageCount     int     //文档页数
+	FilePostfix   string  //文档格式
+	ProductId     int64   //文档ID
+	ModifyDate    string  //修改时间
+	PcatName      string  //一级分类
+	Price         float64 //文档价格
+	PriceVip      int     //文档券数
+	ProductName   string  //文档标题
+	VisitCount    int     //浏览量
+	CreatedDate   string  //创建时间
+	FileSize      int64   //文档大小
+	CatName       string  //二级分类
+	DownloadCount int     //下载量
+	Ifcharge      int     //是否付费,0:免费,1:收费
+	Desc          string  //文档详情
+	State         int     //文档状态,0:上架,1:下架
+}

二进制
rpc/partnerlib/partner.exe


+ 45 - 0
rpc/partnerlib/partner/partner.go

@@ -0,0 +1,45 @@
+// Code generated by goctl. DO NOT EDIT!
+// Source: partnerlib.proto
+
+package partner
+
+import (
+	"context"
+
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/type/partnerlib"
+
+	"github.com/zeromicro/go-zero/zrpc"
+	"google.golang.org/grpc"
+)
+
+type (
+	UBVRes              = partnerlib.UBVRes
+	UDRes               = partnerlib.UDRes
+	UserBuyVipRequest   = partnerlib.UserBuyVipRequest
+	UserDownloadRequest = partnerlib.UserDownloadRequest
+
+	Partner interface {
+		DocDownload(ctx context.Context, in *UserDownloadRequest, opts ...grpc.CallOption) (*UDRes, error)
+		UserBuy(ctx context.Context, in *UserBuyVipRequest, opts ...grpc.CallOption) (*UBVRes, error)
+	}
+
+	defaultPartner struct {
+		cli zrpc.Client
+	}
+)
+
+func NewPartner(cli zrpc.Client) Partner {
+	return &defaultPartner{
+		cli: cli,
+	}
+}
+
+func (m *defaultPartner) DocDownload(ctx context.Context, in *UserDownloadRequest, opts ...grpc.CallOption) (*UDRes, error) {
+	client := partnerlib.NewPartnerClient(m.cli.Conn())
+	return client.DocDownload(ctx, in, opts...)
+}
+
+func (m *defaultPartner) UserBuy(ctx context.Context, in *UserBuyVipRequest, opts ...grpc.CallOption) (*UBVRes, error) {
+	client := partnerlib.NewPartnerClient(m.cli.Conn())
+	return client.UserBuy(ctx, in, opts...)
+}

+ 40 - 0
rpc/partnerlib/partnerlib.go

@@ -0,0 +1,40 @@
+package main
+
+import (
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/crontab"
+	IC "app.yhyue.com/moapp/jy_docs/rpc/partnerlib/init"
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/internal/server"
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/internal/svc"
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/type/partnerlib"
+	MC "app.yhyue.com/moapp/jybase/common"
+	"app.yhyue.com/moapp/jybase/endless"
+	"fmt"
+	"github.com/zeromicro/go-zero/core/service"
+	"github.com/zeromicro/go-zero/zrpc"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/reflection"
+	"log"
+)
+
+func main() {
+	go func() {
+		err := endless.ListenAndServe(":"+MC.InterfaceToStr(IC.C.WebRpcPort), nil, func() {})
+		if err != nil {
+			log.Println("ListenAndServe: ", err)
+		}
+	}()
+	ctx := svc.NewServiceContext(IC.C)
+	svr := server.NewPartnerServer(ctx)
+
+	s := zrpc.MustNewServer(IC.C.RpcServerConf, func(grpcServer *grpc.Server) {
+		partnerlib.RegisterPartnerServer(grpcServer, svr)
+
+		if IC.C.Mode == service.DevMode || IC.C.Mode == service.TestMode {
+			reflection.Register(grpcServer)
+		}
+	})
+	defer s.Stop()
+	crontab.StartTask()
+	fmt.Printf("Starting rpc server at %s...\n", IC.C.ListenOn)
+	s.Start()
+}

+ 41 - 0
rpc/partnerlib/partnerlib.proto

@@ -0,0 +1,41 @@
+syntax = "proto3";
+package partnerlib;
+option go_package = "./partnerlib";
+
+//豆丁文档下载
+message UserDownloadRequest {
+  string mgoUserId=1; //用户mongo id
+  string phone=2; //手机号
+  int64 positionId=3;//职位id
+  string appId=4;//剑鱼标识
+  int64 cost=5;//费用
+  string docId = 6;//文档id
+  int64  state = 7;//1:豆丁
+}
+//豆丁会员购买
+message UserBuyVipRequest{
+  string mgoUserId=1; //用户mongo id
+  string phone=2; //手机号
+  int64 positionId=3;//职位id
+  string appId=4;//剑鱼标识
+  string docId=5;//文档id
+  int64 type=6;//购买类型:1 币买文档,2 券买文档,3 月大会员,4 季大会员,5 年大会员
+  int64 state = 7;//1:豆丁
+}
+// 用户下载
+message UDRes{
+  int64 code = 1;
+  string msg = 2;
+  string ossDocId = 3;
+}
+//会员购买返回值
+message UBVRes{
+  int64 code = 1;
+  string msg = 2;
+  string  orderNo = 3;
+}
+
+service  Partner {
+  rpc DocDownload(UserDownloadRequest) returns (UDRes);//文档下载
+  rpc UserBuy(UserBuyVipRequest) returns(UBVRes); //会员购买
+}

+ 68 - 0
rpc/partnerlib/service/docDownload.go

@@ -0,0 +1,68 @@
+package service
+
+import (
+	IC "app.yhyue.com/moapp/jy_docs/rpc/partnerlib/init"
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/type/partnerlib"
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/util"
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/warn"
+	"app.yhyue.com/moapp/jy_docs/services/model"
+	"app.yhyue.com/moapp/jy_docs/services/partner"
+	"app.yhyue.com/moapp/jyfs/rpc/filesystem"
+	"encoding/json"
+	"fmt"
+)
+
+type DRes struct {
+	Msg  string
+	Code int64
+}
+
+func DocDownload(in *partnerlib.UserDownloadRequest) (res *partnerlib.UDRes, err error) {
+	res = new(partnerlib.UDRes)
+	var (
+		b      []byte
+		isJson bool
+	)
+	h := NewHH(IC.I.Docin.Name, IC.I.Docin.Host, IC.I.Docin.DocDownload.Name, IC.I.Docin.DocDownload.Pathname, IC.I.Docin.DocDownload.Method, map[string]interface{}{
+		"productId": in.DocId,
+		"userId":    in.PositionId,
+	})
+	b, err, isJson = h.HttpFunc()
+	go h.SaveDocinLogger(b, err, "req")
+	if err == nil {
+		//豆丁同步数据到mongo
+		go h.SaveDocinLogger(b, err, "res")
+		if isJson {
+			err = json.Unmarshal(b, &res)
+		} else {
+			//获取文件信息
+			docInfo := partner.DocsFindOne(in.DocId)
+			//查看oss服务器是否已存在此文档
+			if res.OssDocId = docInfo.OssDocId; res.OssDocId == "" {
+				//获取附件后上传oss
+				if uploadRes := FileUpload(&filesystem.SaveFileReq{
+					Domain: IC.C.OssInfo.BucketName,
+					FileId: fmt.Sprintf("%s.%s", util.GetHashKey(b), docInfo.DocFileSuffix),
+					Meta: map[string]string{
+						"docName":   docInfo.DocName,
+						"docSuffix": docInfo.DocFileSuffix,
+						"docSize":   fmt.Sprintf("%d", docInfo.DocFileSize),
+					},
+					RawFileContent: b,
+				}); uploadRes.OssDocId != "" {
+					//更新doc
+					if err := partner.DocsUpdate(model.Doc{OssDocId: res.OssDocId}); err != nil {
+						warn.SendMsgByWXURL(fmt.Sprintf("文档id:%s,文档名称:%s 上传tidb doc 异常:%s", docInfo.Id, docInfo.DocName, err.Error()))
+					}
+				} else {
+					warn.SendMsgByWXURL(fmt.Sprintf("文档id:%s,文档名称:%s,上传到oss异常:%s", docInfo.Id, docInfo.DocName, res.Msg))
+				}
+
+			}
+		}
+	} else {
+		res.Msg = err.Error()
+		res.Code = -1
+	}
+	return
+}

+ 23 - 0
rpc/partnerlib/service/ossFileUpload.go

@@ -0,0 +1,23 @@
+package service
+
+import (
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/type/partnerlib"
+	jyDocRpcUtil "app.yhyue.com/moapp/jy_docs/services/util"
+	"app.yhyue.com/moapp/jyfs/rpc/filesystem"
+	"fmt"
+	"github.com/gogf/gf/v2/os/gctx"
+)
+
+// 上传文档信息
+func FileUpload(fr *filesystem.SaveFileReq) (res *partnerlib.UDRes) {
+	if fr != nil && len(fr.RawFileContent) > 0 {
+		fRes, err := jyDocRpcUtil.FileSystem.SaveFile(gctx.New(), fr)
+		if err == nil && fRes.State {
+			res.OssDocId = fRes.FileId
+		} else {
+			res.Code = -1
+			res.Msg = fmt.Sprintf("%s上传异常", fr.Meta["docName"])
+		}
+	}
+	return
+}

+ 143 - 0
rpc/partnerlib/service/service.go

@@ -0,0 +1,143 @@
+package service
+
+import (
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/entity"
+	IC "app.yhyue.com/moapp/jy_docs/rpc/partnerlib/init"
+	"app.yhyue.com/moapp/jy_docs/services/partner"
+	"app.yhyue.com/moapp/jybase/common"
+	"app.yhyue.com/moapp/jybase/date"
+	"bytes"
+	"encoding/json"
+	"fmt"
+	"github.com/gogf/gf/v2/crypto/gmd5"
+	"github.com/gogf/gf/v2/crypto/gsha1"
+	"io"
+	"log"
+	"net/http"
+	"net/url"
+	"strings"
+)
+
+type HH struct {
+	Host     string
+	Pathname string
+	Method   string
+	Params   map[string]interface{}
+	Name     string
+	ApiName  string
+}
+
+// new
+func NewHH(name, host, apiName, pathname, method string, params map[string]interface{}) *HH {
+	return &HH{
+		Name:     name,
+		Host:     host,
+		ApiName:  apiName,
+		Pathname: pathname,
+		Method:   method,
+		Params:   params,
+	}
+}
+
+// 豆丁api 请求
+func (h *HH) HttpFunc() (body []byte, err error, isJson bool) {
+	entity.DocsLock.Lock()
+	defer entity.DocsLock.Unlock()
+	if h.Params == nil || len(h.Params) == 0 {
+		err = fmt.Errorf("参数异常")
+		return
+	}
+	var (
+		href string
+		req  *http.Request
+	)
+	switch h.Method {
+	case "POST":
+		var bb *bytes.Buffer
+		href = fmt.Sprintf("%s%s", h.Host, h.Pathname)
+		b, _err := json.Marshal(h.Params)
+		if _err == nil {
+			bb = bytes.NewBuffer(b)
+		}
+		// 创建 请求并添加查询参数
+		req, err = http.NewRequest(h.Method, href, bb)
+	case "GET":
+		params := url.Values{}
+		for k, v := range h.Params {
+			params.Add(k, common.InterfaceToStr(v))
+		}
+		href = fmt.Sprintf("%s%s?%s", h.Host, h.Pathname, params.Encode())
+		// 创建 请求并添加查询参数
+		req, err = http.NewRequest(h.Method, href, nil)
+	}
+	if err != nil {
+		err = fmt.Errorf("error creating GET request:%v", err)
+		return
+	}
+	// 添加请求头
+	req.Header.Add("Content-Type", "application/json")
+	//时间
+	req.Header.Add("Date", h.GetDate())
+	//Content-Md5
+	req.Header.Add("Content-Md5", h.GetContentMd5())
+	//Authorization
+	req.Header.Add("Authorization", h.GetAuthorization())
+	client := &http.Client{}
+	// 使用 Do 方法处理请求
+	resp, _err := client.Do(req)
+	if _err != nil {
+		err = fmt.Errorf("failed to create client:%v", http.StatusInternalServerError)
+		return
+	}
+	defer resp.Body.Close()
+	body, err = io.ReadAll(resp.Body)
+	isJson = strings.Contains(strings.ToLower(resp.Header.Get("Content-Type")), "text/json")
+	if err != nil {
+		log.Println("Failed to read response body", http.StatusInternalServerError)
+		return
+	}
+	return
+}
+
+// 时间
+func (h *HH) GetDate() string {
+	return date.NowFormat(entity.DateFormat)
+
+}
+
+// Content-Md5
+func (h *HH) GetContentMd5() string {
+	//hash := md5.Sum([]byte(h.Pathname))
+	//return strings.ToLower(hex.EncodeToString(hash[:]))
+	m5, _ := gmd5.EncryptString(h.Pathname)
+	return strings.ToLower(m5)
+}
+
+// Authorization
+func (h *HH) GetAuthorization() string {
+	// 计算 SHA1 值
+	//hm := hmac.New(sha1.New, []byte(IC.I.Docin.AppSecret))
+	//hm.Write([]byte(IC.I.Docin.AppSecret + h.GetContentMd5() + h.GetDate()))
+	//return fmt.Sprintf("WPS-2:%s:%s", IC.I.Docin.AppId, strings.ToLower(fmt.Sprintf("%x", hm.Sum(nil))))
+	return fmt.Sprintf("WPS-2:%s:%s", IC.I.Docin.AppId, strings.ToLower(gsha1.Encrypt(fmt.Sprintf("%s%s%s", IC.I.Docin.AppSecret, h.GetContentMd5(), h.GetDate()))))
+}
+
+// 豆丁api请求日志 存mongo
+func (h *HH) SaveDocinLogger(b []byte, err error, mark string) {
+	var body = map[string]interface{}{}
+	if err := json.Unmarshal(b, &body); err != nil {
+		log.Println("json b to body err:", err.Error())
+	}
+	partner.SaveDocinLogger(map[string]interface{}{
+		"name":       h.Name,
+		"host":       h.Host,
+		"apiName":    h.ApiName,
+		"params":     h.Params,
+		"method":     h.Method,
+		"pathname":   h.Pathname,
+		"createDate": date.NowFormat(date.Date_Full_Layout),
+		"content":    body,
+		"ok":         common.If(err == nil, true, false).(bool),
+		"httpType":   mark,
+	})
+}

+ 71 - 0
rpc/partnerlib/service/userBuy.go

@@ -0,0 +1,71 @@
+package service
+
+import (
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/entity"
+	IC "app.yhyue.com/moapp/jy_docs/rpc/partnerlib/init"
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/type/partnerlib"
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/util"
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/warn"
+	"app.yhyue.com/moapp/jy_docs/services/model"
+	"app.yhyue.com/moapp/jy_docs/services/partner"
+	"app.yhyue.com/moapp/jybase/date"
+	"encoding/json"
+	"fmt"
+)
+
+type BRes struct {
+	Msg     string
+	Code    int64
+	OrderNo string
+}
+
+func UBHandle(in *partnerlib.UserBuyVipRequest) (res *partnerlib.UBVRes, err error) {
+	res = new(partnerlib.UBVRes)
+	var (
+		b       []byte
+		docInfo = partner.DocsFindOne(in.DocId)
+	)
+	if docInfo.Id != "" {
+		orderCode := util.GetOrderCode(entity.PartnerName)
+		h := NewHH(IC.I.Docin.Name, IC.I.Docin.Host, IC.I.Docin.BuyRecord.Name, IC.I.Docin.BuyRecord.Pathname, IC.I.Docin.BuyRecord.Method, map[string]interface{}{
+			"orderNo":   orderCode,
+			"productId": in.DocId,
+			"userId":    in.PositionId,
+			"price":     docInfo.Price,
+			"priceVip":  docInfo.PriceVip,
+			"type":      in.Type,
+			"orderTime": date.NowFormat(entity.DateFullLayout),
+		})
+		b, err, _ = h.HttpFunc()
+		go h.SaveDocinLogger(b, err, "req")
+		if err == nil {
+			//豆丁同步数据到mongo
+			go h.SaveDocinLogger(b, err, "res")
+			bRes := &BRes{}
+			if err = json.Unmarshal(b, &bRes); err == nil {
+				//更新文档购买记录
+				if err = partner.InsertBuyDocOrder(&model.DocinUserOrder{
+					PositionId:   in.PositionId,
+					MgoUserId:    in.MgoUserId,
+					Phone:        in.Phone,
+					DocId:        docInfo.Id,
+					OrderCode:    orderCode,
+					Price:        docInfo.Price,
+					PriceVip:     docInfo.PriceVip,
+					PurchaseType: int(in.Type), //购买类型:1 币买文档,2 券买文档,3 月大会员,4 季大会员,5 年大会员
+					State:        1,            //合作商:1:豆丁
+					CreateTime:   date.NowFormat(date.Date_Full_Layout),
+				}); err == nil {
+					warn.SendMsgByWXURL(fmt.Sprintf("%s文档名称: %s,文档id:%s,购买订单编号:%s,请求信息:%v", entity.PartnerName, docInfo.DocName, docInfo.Id, orderCode, in))
+				}
+				res.OrderNo = bRes.OrderNo
+				res.Msg = bRes.Msg
+				res.Code = bRes.Code
+				return
+			}
+		}
+	}
+	res.Msg = err.Error()
+	res.Code = -1
+	return
+}

+ 498 - 0
rpc/partnerlib/type/partnerlib/partnerlib.pb.go

@@ -0,0 +1,498 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.28.0
+// 	protoc        v3.15.5
+// source: partnerlib.proto
+
+package partnerlib
+
+import (
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+//豆丁文档下载
+type UserDownloadRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	MgoUserId  string `protobuf:"bytes,1,opt,name=mgoUserId,proto3" json:"mgoUserId,omitempty"`    //用户mongo id
+	Phone      string `protobuf:"bytes,2,opt,name=phone,proto3" json:"phone,omitempty"`            //手机号
+	PositionId int64  `protobuf:"varint,3,opt,name=positionId,proto3" json:"positionId,omitempty"` //职位id
+	AppId      string `protobuf:"bytes,4,opt,name=appId,proto3" json:"appId,omitempty"`            //剑鱼标识
+	Cost       int64  `protobuf:"varint,5,opt,name=cost,proto3" json:"cost,omitempty"`             //费用
+	DocId      string `protobuf:"bytes,6,opt,name=docId,proto3" json:"docId,omitempty"`            //文档id
+	State      int64  `protobuf:"varint,7,opt,name=state,proto3" json:"state,omitempty"`           //1:豆丁
+}
+
+func (x *UserDownloadRequest) Reset() {
+	*x = UserDownloadRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_partnerlib_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *UserDownloadRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*UserDownloadRequest) ProtoMessage() {}
+
+func (x *UserDownloadRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_partnerlib_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use UserDownloadRequest.ProtoReflect.Descriptor instead.
+func (*UserDownloadRequest) Descriptor() ([]byte, []int) {
+	return file_partnerlib_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *UserDownloadRequest) GetMgoUserId() string {
+	if x != nil {
+		return x.MgoUserId
+	}
+	return ""
+}
+
+func (x *UserDownloadRequest) GetPhone() string {
+	if x != nil {
+		return x.Phone
+	}
+	return ""
+}
+
+func (x *UserDownloadRequest) GetPositionId() int64 {
+	if x != nil {
+		return x.PositionId
+	}
+	return 0
+}
+
+func (x *UserDownloadRequest) GetAppId() string {
+	if x != nil {
+		return x.AppId
+	}
+	return ""
+}
+
+func (x *UserDownloadRequest) GetCost() int64 {
+	if x != nil {
+		return x.Cost
+	}
+	return 0
+}
+
+func (x *UserDownloadRequest) GetDocId() string {
+	if x != nil {
+		return x.DocId
+	}
+	return ""
+}
+
+func (x *UserDownloadRequest) GetState() int64 {
+	if x != nil {
+		return x.State
+	}
+	return 0
+}
+
+//豆丁会员购买
+type UserBuyVipRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	MgoUserId  string `protobuf:"bytes,1,opt,name=mgoUserId,proto3" json:"mgoUserId,omitempty"`    //用户mongo id
+	Phone      string `protobuf:"bytes,2,opt,name=phone,proto3" json:"phone,omitempty"`            //手机号
+	PositionId int64  `protobuf:"varint,3,opt,name=positionId,proto3" json:"positionId,omitempty"` //职位id
+	AppId      string `protobuf:"bytes,4,opt,name=appId,proto3" json:"appId,omitempty"`            //剑鱼标识
+	DocId      string `protobuf:"bytes,5,opt,name=docId,proto3" json:"docId,omitempty"`            //文档id
+	Type       int64  `protobuf:"varint,6,opt,name=type,proto3" json:"type,omitempty"`             //购买类型:1 币买文档,2 券买文档,3 月大会员,4 季大会员,5 年大会员
+	State      int64  `protobuf:"varint,7,opt,name=state,proto3" json:"state,omitempty"`           //1:豆丁
+}
+
+func (x *UserBuyVipRequest) Reset() {
+	*x = UserBuyVipRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_partnerlib_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *UserBuyVipRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*UserBuyVipRequest) ProtoMessage() {}
+
+func (x *UserBuyVipRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_partnerlib_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use UserBuyVipRequest.ProtoReflect.Descriptor instead.
+func (*UserBuyVipRequest) Descriptor() ([]byte, []int) {
+	return file_partnerlib_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *UserBuyVipRequest) GetMgoUserId() string {
+	if x != nil {
+		return x.MgoUserId
+	}
+	return ""
+}
+
+func (x *UserBuyVipRequest) GetPhone() string {
+	if x != nil {
+		return x.Phone
+	}
+	return ""
+}
+
+func (x *UserBuyVipRequest) GetPositionId() int64 {
+	if x != nil {
+		return x.PositionId
+	}
+	return 0
+}
+
+func (x *UserBuyVipRequest) GetAppId() string {
+	if x != nil {
+		return x.AppId
+	}
+	return ""
+}
+
+func (x *UserBuyVipRequest) GetDocId() string {
+	if x != nil {
+		return x.DocId
+	}
+	return ""
+}
+
+func (x *UserBuyVipRequest) GetType() int64 {
+	if x != nil {
+		return x.Type
+	}
+	return 0
+}
+
+func (x *UserBuyVipRequest) GetState() int64 {
+	if x != nil {
+		return x.State
+	}
+	return 0
+}
+
+// 用户下载
+type UDRes struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Code     int64  `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"`
+	Msg      string `protobuf:"bytes,2,opt,name=msg,proto3" json:"msg,omitempty"`
+	OssDocId string `protobuf:"bytes,3,opt,name=ossDocId,proto3" json:"ossDocId,omitempty"`
+}
+
+func (x *UDRes) Reset() {
+	*x = UDRes{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_partnerlib_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *UDRes) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*UDRes) ProtoMessage() {}
+
+func (x *UDRes) ProtoReflect() protoreflect.Message {
+	mi := &file_partnerlib_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use UDRes.ProtoReflect.Descriptor instead.
+func (*UDRes) Descriptor() ([]byte, []int) {
+	return file_partnerlib_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *UDRes) GetCode() int64 {
+	if x != nil {
+		return x.Code
+	}
+	return 0
+}
+
+func (x *UDRes) GetMsg() string {
+	if x != nil {
+		return x.Msg
+	}
+	return ""
+}
+
+func (x *UDRes) GetOssDocId() string {
+	if x != nil {
+		return x.OssDocId
+	}
+	return ""
+}
+
+//会员购买返回值
+type UBVRes struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Code    int64  `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"`
+	Msg     string `protobuf:"bytes,2,opt,name=msg,proto3" json:"msg,omitempty"`
+	OrderNo string `protobuf:"bytes,3,opt,name=orderNo,proto3" json:"orderNo,omitempty"`
+}
+
+func (x *UBVRes) Reset() {
+	*x = UBVRes{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_partnerlib_proto_msgTypes[3]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *UBVRes) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*UBVRes) ProtoMessage() {}
+
+func (x *UBVRes) ProtoReflect() protoreflect.Message {
+	mi := &file_partnerlib_proto_msgTypes[3]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use UBVRes.ProtoReflect.Descriptor instead.
+func (*UBVRes) Descriptor() ([]byte, []int) {
+	return file_partnerlib_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *UBVRes) GetCode() int64 {
+	if x != nil {
+		return x.Code
+	}
+	return 0
+}
+
+func (x *UBVRes) GetMsg() string {
+	if x != nil {
+		return x.Msg
+	}
+	return ""
+}
+
+func (x *UBVRes) GetOrderNo() string {
+	if x != nil {
+		return x.OrderNo
+	}
+	return ""
+}
+
+var File_partnerlib_proto protoreflect.FileDescriptor
+
+var file_partnerlib_proto_rawDesc = []byte{
+	0x0a, 0x10, 0x70, 0x61, 0x72, 0x74, 0x6e, 0x65, 0x72, 0x6c, 0x69, 0x62, 0x2e, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x12, 0x0a, 0x70, 0x61, 0x72, 0x74, 0x6e, 0x65, 0x72, 0x6c, 0x69, 0x62, 0x22, 0xbf,
+	0x01, 0x0a, 0x13, 0x55, 0x73, 0x65, 0x72, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6d, 0x67, 0x6f, 0x55, 0x73, 0x65,
+	0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x67, 0x6f, 0x55, 0x73,
+	0x65, 0x72, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x05, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x6f,
+	0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a,
+	0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x70,
+	0x70, 0x49, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64,
+	0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x73, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04,
+	0x63, 0x6f, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x6f, 0x63, 0x49, 0x64, 0x18, 0x06, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x05, 0x64, 0x6f, 0x63, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74,
+	0x61, 0x74, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65,
+	0x22, 0xbd, 0x01, 0x0a, 0x11, 0x55, 0x73, 0x65, 0x72, 0x42, 0x75, 0x79, 0x56, 0x69, 0x70, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6d, 0x67, 0x6f, 0x55, 0x73, 0x65,
+	0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x67, 0x6f, 0x55, 0x73,
+	0x65, 0x72, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x05, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x6f,
+	0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a,
+	0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x70,
+	0x70, 0x49, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64,
+	0x12, 0x14, 0x0a, 0x05, 0x64, 0x6f, 0x63, 0x49, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x05, 0x64, 0x6f, 0x63, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06,
+	0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74,
+	0x61, 0x74, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65,
+	0x22, 0x49, 0x0a, 0x05, 0x55, 0x44, 0x52, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64,
+	0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a,
+	0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12,
+	0x1a, 0x0a, 0x08, 0x6f, 0x73, 0x73, 0x44, 0x6f, 0x63, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x08, 0x6f, 0x73, 0x73, 0x44, 0x6f, 0x63, 0x49, 0x64, 0x22, 0x48, 0x0a, 0x06, 0x55,
+	0x42, 0x56, 0x52, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x03, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x6f,
+	0x72, 0x64, 0x65, 0x72, 0x4e, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x72,
+	0x64, 0x65, 0x72, 0x4e, 0x6f, 0x32, 0x8a, 0x01, 0x0a, 0x07, 0x50, 0x61, 0x72, 0x74, 0x6e, 0x65,
+	0x72, 0x12, 0x41, 0x0a, 0x0b, 0x44, 0x6f, 0x63, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64,
+	0x12, 0x1f, 0x2e, 0x70, 0x61, 0x72, 0x74, 0x6e, 0x65, 0x72, 0x6c, 0x69, 0x62, 0x2e, 0x55, 0x73,
+	0x65, 0x72, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x1a, 0x11, 0x2e, 0x70, 0x61, 0x72, 0x74, 0x6e, 0x65, 0x72, 0x6c, 0x69, 0x62, 0x2e, 0x55,
+	0x44, 0x52, 0x65, 0x73, 0x12, 0x3c, 0x0a, 0x07, 0x55, 0x73, 0x65, 0x72, 0x42, 0x75, 0x79, 0x12,
+	0x1d, 0x2e, 0x70, 0x61, 0x72, 0x74, 0x6e, 0x65, 0x72, 0x6c, 0x69, 0x62, 0x2e, 0x55, 0x73, 0x65,
+	0x72, 0x42, 0x75, 0x79, 0x56, 0x69, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12,
+	0x2e, 0x70, 0x61, 0x72, 0x74, 0x6e, 0x65, 0x72, 0x6c, 0x69, 0x62, 0x2e, 0x55, 0x42, 0x56, 0x52,
+	0x65, 0x73, 0x42, 0x0e, 0x5a, 0x0c, 0x2e, 0x2f, 0x70, 0x61, 0x72, 0x74, 0x6e, 0x65, 0x72, 0x6c,
+	0x69, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_partnerlib_proto_rawDescOnce sync.Once
+	file_partnerlib_proto_rawDescData = file_partnerlib_proto_rawDesc
+)
+
+func file_partnerlib_proto_rawDescGZIP() []byte {
+	file_partnerlib_proto_rawDescOnce.Do(func() {
+		file_partnerlib_proto_rawDescData = protoimpl.X.CompressGZIP(file_partnerlib_proto_rawDescData)
+	})
+	return file_partnerlib_proto_rawDescData
+}
+
+var file_partnerlib_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
+var file_partnerlib_proto_goTypes = []interface{}{
+	(*UserDownloadRequest)(nil), // 0: partnerlib.UserDownloadRequest
+	(*UserBuyVipRequest)(nil),   // 1: partnerlib.UserBuyVipRequest
+	(*UDRes)(nil),               // 2: partnerlib.UDRes
+	(*UBVRes)(nil),              // 3: partnerlib.UBVRes
+}
+var file_partnerlib_proto_depIdxs = []int32{
+	0, // 0: partnerlib.Partner.DocDownload:input_type -> partnerlib.UserDownloadRequest
+	1, // 1: partnerlib.Partner.UserBuy:input_type -> partnerlib.UserBuyVipRequest
+	2, // 2: partnerlib.Partner.DocDownload:output_type -> partnerlib.UDRes
+	3, // 3: partnerlib.Partner.UserBuy:output_type -> partnerlib.UBVRes
+	2, // [2:4] is the sub-list for method output_type
+	0, // [0:2] is the sub-list for method input_type
+	0, // [0:0] is the sub-list for extension type_name
+	0, // [0:0] is the sub-list for extension extendee
+	0, // [0:0] is the sub-list for field type_name
+}
+
+func init() { file_partnerlib_proto_init() }
+func file_partnerlib_proto_init() {
+	if File_partnerlib_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_partnerlib_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*UserDownloadRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_partnerlib_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*UserBuyVipRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_partnerlib_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*UDRes); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_partnerlib_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*UBVRes); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_partnerlib_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   4,
+			NumExtensions: 0,
+			NumServices:   1,
+		},
+		GoTypes:           file_partnerlib_proto_goTypes,
+		DependencyIndexes: file_partnerlib_proto_depIdxs,
+		MessageInfos:      file_partnerlib_proto_msgTypes,
+	}.Build()
+	File_partnerlib_proto = out.File
+	file_partnerlib_proto_rawDesc = nil
+	file_partnerlib_proto_goTypes = nil
+	file_partnerlib_proto_depIdxs = nil
+}

+ 141 - 0
rpc/partnerlib/type/partnerlib/partnerlib_grpc.pb.go

@@ -0,0 +1,141 @@
+// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+// versions:
+// - protoc-gen-go-grpc v1.2.0
+// - protoc             v3.15.5
+// source: partnerlib.proto
+
+package partnerlib
+
+import (
+	context "context"
+	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
+)
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+// Requires gRPC-Go v1.32.0 or later.
+const _ = grpc.SupportPackageIsVersion7
+
+// PartnerClient is the client API for Partner service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
+type PartnerClient interface {
+	DocDownload(ctx context.Context, in *UserDownloadRequest, opts ...grpc.CallOption) (*UDRes, error)
+	UserBuy(ctx context.Context, in *UserBuyVipRequest, opts ...grpc.CallOption) (*UBVRes, error)
+}
+
+type partnerClient struct {
+	cc grpc.ClientConnInterface
+}
+
+func NewPartnerClient(cc grpc.ClientConnInterface) PartnerClient {
+	return &partnerClient{cc}
+}
+
+func (c *partnerClient) DocDownload(ctx context.Context, in *UserDownloadRequest, opts ...grpc.CallOption) (*UDRes, error) {
+	out := new(UDRes)
+	err := c.cc.Invoke(ctx, "/partnerlib.Partner/DocDownload", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *partnerClient) UserBuy(ctx context.Context, in *UserBuyVipRequest, opts ...grpc.CallOption) (*UBVRes, error) {
+	out := new(UBVRes)
+	err := c.cc.Invoke(ctx, "/partnerlib.Partner/UserBuy", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// PartnerServer is the server API for Partner service.
+// All implementations must embed UnimplementedPartnerServer
+// for forward compatibility
+type PartnerServer interface {
+	DocDownload(context.Context, *UserDownloadRequest) (*UDRes, error)
+	UserBuy(context.Context, *UserBuyVipRequest) (*UBVRes, error)
+	mustEmbedUnimplementedPartnerServer()
+}
+
+// UnimplementedPartnerServer must be embedded to have forward compatible implementations.
+type UnimplementedPartnerServer struct {
+}
+
+func (UnimplementedPartnerServer) DocDownload(context.Context, *UserDownloadRequest) (*UDRes, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method DocDownload not implemented")
+}
+func (UnimplementedPartnerServer) UserBuy(context.Context, *UserBuyVipRequest) (*UBVRes, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method UserBuy not implemented")
+}
+func (UnimplementedPartnerServer) mustEmbedUnimplementedPartnerServer() {}
+
+// UnsafePartnerServer may be embedded to opt out of forward compatibility for this service.
+// Use of this interface is not recommended, as added methods to PartnerServer will
+// result in compilation errors.
+type UnsafePartnerServer interface {
+	mustEmbedUnimplementedPartnerServer()
+}
+
+func RegisterPartnerServer(s grpc.ServiceRegistrar, srv PartnerServer) {
+	s.RegisterService(&Partner_ServiceDesc, srv)
+}
+
+func _Partner_DocDownload_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(UserDownloadRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(PartnerServer).DocDownload(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/partnerlib.Partner/DocDownload",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(PartnerServer).DocDownload(ctx, req.(*UserDownloadRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Partner_UserBuy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(UserBuyVipRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(PartnerServer).UserBuy(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/partnerlib.Partner/UserBuy",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(PartnerServer).UserBuy(ctx, req.(*UserBuyVipRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+// Partner_ServiceDesc is the grpc.ServiceDesc for Partner service.
+// It's only intended for direct use with grpc.RegisterService,
+// and not to be introspected or modified (even as a copy)
+var Partner_ServiceDesc = grpc.ServiceDesc{
+	ServiceName: "partnerlib.Partner",
+	HandlerType: (*PartnerServer)(nil),
+	Methods: []grpc.MethodDesc{
+		{
+			MethodName: "DocDownload",
+			Handler:    _Partner_DocDownload_Handler,
+		},
+		{
+			MethodName: "UserBuy",
+			Handler:    _Partner_UserBuy_Handler,
+		},
+	},
+	Streams:  []grpc.StreamDesc{},
+	Metadata: "partnerlib.proto",
+}

+ 23 - 0
rpc/partnerlib/util/util.go

@@ -0,0 +1,23 @@
+package util
+
+import (
+	"app.yhyue.com/moapp/jybase/common"
+	"app.yhyue.com/moapp/jypkg/public"
+	"crypto/sha256"
+	"fmt"
+)
+
+// sha1 加密
+func GetHashKey(bs []byte) string {
+	defer common.Catch()
+	ha := sha256.New()
+	ha.Write(bs)
+	hbs := ha.Sum(nil)
+	key := fmt.Sprintf("%x", hbs)
+	return key
+}
+
+// 创建订单号
+func GetOrderCode(name string) string {
+	return fmt.Sprintf("%s-%s", name, <-public.VarOrderCode.Pool)
+}

+ 46 - 0
rpc/partnerlib/warn/warn.go

@@ -0,0 +1,46 @@
+package warn
+
+import (
+	IC "app.yhyue.com/moapp/jy_docs/rpc/partnerlib/init"
+	"bytes"
+	"encoding/json"
+	"log"
+	"net/http"
+)
+
+// TODO docin 更新保存异常告警
+func SendMsgByWXURL(msg string) {
+	log.Println("warn msg:", msg)
+	if len(IC.Warn.WebhookURL) > 0 {
+		for _, url := range IC.Warn.WebhookURL {
+			if ok := SendBot(url, msg); !ok {
+				log.Println("数据加载异常 企业微信机器人提醒失败--:", url, msg)
+			}
+		}
+	}
+}
+
+func SendBot(webhookURL, msg string) (b bool) {
+	// 构造请求体
+	payload := map[string]interface{}{
+		"msgtype": "text",
+		"text": map[string]string{
+			"content": msg,
+		},
+	}
+	// 转换为 JSON 字符串
+	payloadBytes, err := json.Marshal(payload)
+	if err != nil {
+		log.Println("Error :", err.Error())
+		return
+	}
+	// 发送 POST 请求
+	resp, err := http.Post(webhookURL, "application/json", bytes.NewReader(payloadBytes))
+	if err != nil {
+		log.Println("Error :", err.Error())
+		return
+	}
+	defer resp.Body.Close()
+	b = true
+	return
+}

+ 62 - 0
services/model/partner.go

@@ -0,0 +1,62 @@
+package model
+
+type Docin struct {
+	Id              string `json:"id" gorm:"column:id"`
+	UserId          string `json:"userId" gorm:"column:userId"`
+	AppId           string `json:"appId" gorm:"column:appId"`
+	DocName         string `json:"docName" gorm:"column:docName"`
+	DocFileType     int    `json:"docFileType" gorm:"column:docFileType"`
+	DocFileSuffix   string `json:"docFileSuffix" gorm:"column:docFileSuffix"`
+	DocFileSize     int    `json:"docFileSize" gorm:"column:docFileSize"`
+	DocPageSize     int    `json:"docPageSize" gorm:"column:docPageSize"`
+	DocTags         string `json:"docTags" gorm:"column:docTags"`
+	DocClass        string `json:"docClass" gorm:"column:docClass"`
+	UploadDate      string `json:"uploadDate" gorm:"column:uploadDate"`
+	IsDelete        int    `json:"isDelete" gorm:"column:isDelete"`
+	OssDocId        string `json:"ossDocId" gorm:"column:ossDocId"`
+	Md5             string `json:"md5" gorm:"column:md5"`
+	OssPdfId        string `json:"ossPdfId" gorm:"column:ossPdfId"`
+	OssTxtId        string `json:"ossTxtId" gorm:"column:ossTxtId"`
+	Price           int    `json:"price" gorm:"column:price"`
+	PriceVip        int    `json:"priceVip" gorm:"column:priceVip"`
+	DownOrUp        int    `json:"downOrUp" gorm:"column:downOrUp"`
+	DocSummary      string `json:"docSummary" gorm:"column:docSummary"`
+	PreviewImgId    string `json:"previewImgId" gorm:"column:previewImgId"`
+	EncryptionLevel int    `json:"encryptionLevel" gorm:"column:encryptionLevel"` //
+	Source          int    `json:"source" gorm:"column:source"`
+	ProductType     int    `json:"productType" gorm:"column:productType"`
+	UpdateDate      string `json:"updateDate" gorm:"column:updateDate"`
+}
+
+func (ud *Docin) TableName() string {
+	return "doc"
+}
+
+// 精品文库订单信息表
+type DocinUserOrder struct {
+	PositionId   int64  `json:"position_id" gorm:"column:position_id"`
+	MgoUserId    string `json:"mgo_user_id" gorm:"column:mgo_user_id"`
+	Phone        string `json:"phone" gorm:"column:phone"`
+	DocId        string `json:"doc_id" gorm:"column:doc_id"`
+	OrderCode    string `json:"order_code" gorm:"column:order_code"`
+	Price        int    `json:"price" gorm:"column:price"`                 //价格
+	PriceVip     int    `json:"price_vip" gorm:"column:price_vip"`         //券
+	PurchaseType int    `json:"purchase_type" gorm:"column:purchase_type"` //购买类型:1 币买文档,2 券买文档,3 月大会员,4 季大会员,5 年大会员
+	State        int    `json:"state" gorm:"column:state"`
+	CreateTime   string `json:"create_time" gorm:"column:create_time"`
+}
+
+func (ud *DocinUserOrder) TableName() string {
+	return "doc_user_order"
+}
+
+type DocClass struct {
+	Name  string
+	Code  string
+	Level int
+	State int
+}
+
+func (dc *DocClass) TableName() string {
+	return "doc_class"
+}

+ 23 - 19
services/model/stdlib.go

@@ -5,7 +5,7 @@ import (
 )
 
 type Doc struct {
-	Id            string    `json:"id" gorm:"id"`
+	Id            string    `json:"id" gorm:"column:id"`
 	UserId        string    `json:"userId" gorm:"column:userId"`
 	AppId         string    `json:"appId" gorm:"column:appId"`
 	DocName       string    `json:"docName" gorm:"column:docName"`
@@ -18,18 +18,22 @@ type Doc struct {
 	UploadDate    time.Time `json:"uploadDate" gorm:"column:uploadDate"`
 	IsDelete      int       `json:"isDelete" gorm:"column:isDelete"`
 	OssDocId      string    `json:"ossDocId" gorm:"column:ossDocId"`
-	OssDocUrl     string    `json:"ossDocUrl" gorm:"column:ossDocUrl"`
-	Md5           string    `json:"md5" gorm:"column:md5"`
-	OssPdfId      string    `json:"ossPdfId" gorm:"column:ossPdfId"`
-	OssPdfUrl     string    `json:"ossPdfUrl" gorm:"column:ossPdfUrl"`
-	OssTxtId      string    `json:"ossTxtId" gorm:"column:ossTxtId"`
-	OssTxtUrl     string    `json:"ossTxtUrl" gorm:"column:ossTxtUrl"`
-	Price         int       `json:"price" gorm:"column:price"`
-	DownOrUp      int       `json:"downOrUp" gorm:"column:downOrUp"`
-	DocSummary    string    `json:"docSummary" gorm:"column:docSummary"`
-	PreviewImgId  string    `json:"preview_img_id" gorm:"column:previewImgId"`
-	Source        int64     `json:"source" gorm:"column:source"`            // '文档来源:默认:0:全部;1:剑鱼;2:豆丁;',
-	ProductType   int64     `json:"product_type" gorm:"column:productType"` //'商品类型:默认:0:全部;1:会员免费;2:精品(付费)'
+	//OssDocUrl       string    `json:"ossDocUrl" gorm:"column:ossDocUrl"`
+	Md5      string `json:"md5" gorm:"column:md5"`
+	OssPdfId string `json:"ossPdfId" gorm:"column:ossPdfId"`
+	//OssPdfUrl       string    `json:"ossPdfUrl" gorm:"column:ossPdfUrl"`
+	OssTxtId string `json:"ossTxtId" gorm:"column:ossTxtId"`
+	//OssTxtUrl       string    `json:"ossTxtUrl" gorm:"column:ossTxtUrl"`
+	Price        int    `json:"price" gorm:"column:price"`
+	PriceVip     int    `json:"priceVip" gorm:"column:priceVip"`
+	DownOrUp     int    `json:"downOrUp" gorm:"column:downOrUp"`
+	DocSummary   string `json:"docSummary" gorm:"column:docSummary"`
+	PreviewImgId string `json:"previewImgId" gorm:"column:previewImgId"`
+	//PreviewImgUrl   string    `json:"preview_img_url" gorm:"column:previewImgUrl"`
+	EncryptionLevel int       `json:"encryptionLevel" gorm:"column:encryptionLevel"` //
+	Source          int       `json:"source" gorm:"column:source"`
+	ProductType     int       `json:"productType" gorm:"column:productType"`
+	UpdateDate      time.Time `json:"updateDate" gorm:"column:updateDate"`
 }
 
 func (ud *Doc) TableName() string {
@@ -102,12 +106,12 @@ func (ud *UserDocData) TableName() string {
 
 type DocStatistics struct {
 	Id         int       `json:"id"`
-	AppId      string    `json:"app_id"  gorm:"column:appId"`
-	DocId      string    `json:"doc_id" gorm:"column:docId"`
-	UpdateDate time.Time `json:"update_date" gorm:"column:updateDate"`
-	score      int       `json:"score" gorm:"column:score"`
-	DownTimes  int       `json:"down_times" gorm:"column:downTimes"`
-	ViewTimes  int       `json:"view_times" gorm:"column:viewTimes"`
+	AppId      string    `json:"appId"  gorm:"column:appId"`
+	DocId      string    `json:"docId" gorm:"column:docId"`
+	UpdateDate time.Time `json:"updateDate" gorm:"column:updateDate"`
+	Score      int       `json:"score" gorm:"column:score"`
+	DownTimes  int       `json:"downTimes" gorm:"column:downTimes"`
+	ViewTimes  int       `json:"viewTimes" gorm:"column:viewTimes"`
 }
 
 func (ud *DocStatistics) TableName() string {

+ 12 - 0
services/partner/docBuyOrder.go

@@ -0,0 +1,12 @@
+package partner
+
+import (
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/entity"
+	"app.yhyue.com/moapp/jy_docs/services/model"
+	jyDocRpcUtil "app.yhyue.com/moapp/jy_docs/services/util"
+)
+
+func InsertBuyDocOrder(orderInfo *model.DocinUserOrder) (err error) {
+	err = jyDocRpcUtil.GetJyDocsDB().Table(entity.DocUserOrderTab).Create(orderInfo).Error
+	return
+}

+ 13 - 0
services/partner/docCheck.go

@@ -0,0 +1,13 @@
+package partner
+
+import (
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/entity"
+	docRpcUtil "app.yhyue.com/moapp/jy_docs/services/util"
+)
+
+func CheckDocs(docId, md5Id string) bool {
+	var count int64
+	//docRpcUtil.GetJyDocsDB().Raw("SELECT COUNT(id) FROM `doc` WHERE id = ? OR md5 = ?", docId, md5Id).Count(&count)
+	docRpcUtil.GetJyDocsDB().Table(entity.DocTable).Where("id = ? OR md5 = ?", docId, md5Id).Count(&count)
+	return count > 0
+}

+ 112 - 0
services/partner/docClass.go

@@ -0,0 +1,112 @@
+package partner
+
+import (
+	"app.yhyue.com/moapp/jy_docs/services/model"
+	docRpcUtil "app.yhyue.com/moapp/jy_docs/services/util"
+	"fmt"
+	"log"
+)
+
+var (
+	DocClassMap = map[string]string{}
+)
+
+// 初始化 文档分类关系
+func InitDocClass() {
+	var dcs = []*model.DocClass{}
+	err := docRpcUtil.GetJyDocsDB().Table("doc_class").Find(&dcs).Error
+	if err == nil && len(dcs) > 0 {
+		var (
+			jyMap  = map[string]string{}
+			tagMap = map[string]string{}
+		)
+		for _, dc := range dcs {
+			switch dc.State {
+			case 0:
+				jyMap[dc.Code] = dc.Name
+			default:
+				switch dc.Level {
+				case 1:
+					var (
+						dcpKey = fmt.Sprintf("p_%s_%d_class", dc.Name, dc.State) //一级class
+						dtpKey = fmt.Sprintf("p_%s_%d_tag", dc.Name, dc.State)   //一级tag
+					)
+					DocClassMap[dcpKey] = dc.Code
+					tagMap[dtpKey] = dc.Code
+				case 2:
+					var (
+						dcKey = fmt.Sprintf("c_%s_%d_class", dc.Name, dc.State) //二级class
+						dtKey = fmt.Sprintf("c_%s_%d_tag", dc.Name, dc.State)   //二级tag
+					)
+					DocClassMap[dcKey] = dc.Code
+					tagMap[dtKey] = dc.Code
+				}
+			}
+		}
+		if tagMap != nil && len(tagMap) > 0 {
+			for k, v := range tagMap {
+				if jyMap[v] != "" {
+					DocClassMap[k] = jyMap[v]
+				}
+			}
+		}
+	}
+}
+
+// 先查内存 再查表数据
+func SwitchDocClass(pName, name string, state int) (docTag []string, docClass string) {
+	var (
+		dcpKey = fmt.Sprintf("p_%s_%d_class", pName, state) //一级class
+		dtpKey = fmt.Sprintf("p_%s_%d_tag", pName, state)   //一级tag
+		dcKey  = fmt.Sprintf("c_%s_%d_class", name, state)  //二级class
+		dtKey  = fmt.Sprintf("c_%s_%d_tag", name, state)    //二级tag
+	)
+	if DocClassMap[dcpKey] != "" && DocClassMap[dtpKey] != "" {
+		docClass = DocClassMap[dcpKey]
+		if DocClassMap[dcKey] != "" {
+			docClass = DocClassMap[dcKey]
+		}
+		docTag = append(docTag, DocClassMap[dtpKey])
+		if DocClassMap[dtKey] != "" {
+			docTag = append(docTag, DocClassMap[dtKey])
+		}
+		return
+	}
+	orm := docRpcUtil.GetJyDocsDB()
+	mdc := model.DocClass{}
+	//合作商文库一级分类
+	err := orm.Where("`name`= ? AND  `level` = 1 AND state = ?", pName, state).First(&mdc).Error
+	if err != nil {
+		log.Println("一级分类转换失败:", err.Error())
+		return
+	}
+	//剑鱼文库一级分类
+	err = orm.Where("`code`= ? AND  `level` = 1 AND state = 0", mdc.Code).First(&mdc).Error
+	if err != nil {
+		log.Println("一级分类转换失败:", err.Error())
+		return
+	}
+	DocClassMap[dcpKey] = mdc.Code
+	DocClassMap[dtpKey] = mdc.Name
+	docTag = append(docTag, mdc.Name)
+	//二级分类
+	if name != "" {
+		//合作商文库二级分类
+		err = orm.Where("`name`= ? AND  `level` = 2 AND state = ?", name, state).First(&mdc).Error
+		if err != nil {
+			log.Println("二级分类转换失败:", err.Error())
+			return
+		}
+		//剑鱼文库二级分类
+		err = orm.Where("`code`= ? AND  `level` = 2 AND state = 0", mdc.Code).First(&mdc).Error
+		if err != nil {
+			log.Println("二级分类转换失败:", err.Error())
+			return
+		}
+		DocClassMap[dcKey] = mdc.Code
+		DocClassMap[dtKey] = mdc.Name
+		docTag = append(docTag, mdc.Name)
+	}
+	docClass = mdc.Code
+	return
+}

+ 18 - 0
services/partner/docsFind.go

@@ -0,0 +1,18 @@
+package partner
+
+import (
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/entity"
+	"app.yhyue.com/moapp/jy_docs/services/model"
+	jyDocRpcUtil "app.yhyue.com/moapp/jy_docs/services/util"
+	"fmt"
+	"log"
+)
+
+func DocsFindOne(docId string) (doc *model.Docin) {
+	doc = &model.Docin{}
+	err := jyDocRpcUtil.GetJyDocsDB().Table(entity.DocTable).Where("id = ?", docId).Find(doc)
+	if err != nil {
+		log.Println(fmt.Sprintf("获取 doc 文档 - %s 异常:%s", docId, err.Error))
+	}
+	return
+}

+ 17 - 0
services/partner/docsInsert.go

@@ -0,0 +1,17 @@
+package partner
+
+import (
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/entity"
+	"app.yhyue.com/moapp/jy_docs/services/model"
+	docRpcUtil "app.yhyue.com/moapp/jy_docs/services/util"
+	"log"
+)
+
+func DocsInsert(docinInfos []model.Docin, count int) {
+	res := docRpcUtil.GetJyDocsDB().Table(entity.DocTable).CreateInBatches(&docinInfos, count)
+	if res.Error != nil {
+		log.Println("error:", res.Error)
+		return
+	}
+	return
+}

+ 16 - 0
services/partner/docsStatistics.go

@@ -0,0 +1,16 @@
+package partner
+
+import (
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/entity"
+	"app.yhyue.com/moapp/jy_docs/services/model"
+	docRpcUtil "app.yhyue.com/moapp/jy_docs/services/util"
+	"log"
+)
+
+func DocsStatistics(docinStatistics []model.DocStatistics, count int) {
+	res := docRpcUtil.GetJyDocsDB().Table(entity.DocStatisticsTable).CreateInBatches(&docinStatistics, count)
+	if res.Error != nil {
+		log.Println("error:", res.Error)
+		return
+	}
+}

+ 31 - 0
services/partner/docsUpdate.go

@@ -0,0 +1,31 @@
+package partner
+
+import (
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/entity"
+	"app.yhyue.com/moapp/jy_docs/services/model"
+	docRpcUtil "app.yhyue.com/moapp/jy_docs/services/util"
+	"app.yhyue.com/moapp/jybase/date"
+	"log"
+)
+
+func DocsUpdate(doc model.Doc) (err error) {
+	updateMap := map[string]interface{}{"updateDate": doc.UpdateDate.Format(date.Date_Full_Layout)}
+	if doc.Price > 0 {
+		updateMap["price"] = doc.Price
+	}
+	if doc.ProductType > 0 {
+		updateMap["productType"] = doc.ProductType
+	}
+	if doc.ProductType > 0 {
+		updateMap["downOrUp"] = doc.DownOrUp
+	}
+	if doc.OssDocId != "" {
+		updateMap["ossDocId"] = doc.OssDocId
+	}
+	err = docRpcUtil.GetJyDocsDB().Table(entity.DocTable).Where("id=?", doc.Id).Updates(updateMap).Error
+	if err.Error != nil {
+		log.Println("error:", err.Error)
+		return
+	}
+	return
+}

+ 15 - 0
services/partner/elastic.go

@@ -0,0 +1,15 @@
+package partner
+
+import (
+	"app.yhyue.com/moapp/jy_docs/rpc/partnerlib/entity"
+	jyDocsRpcUtil "app.yhyue.com/moapp/jy_docs/services/util"
+)
+
+// 同步豆丁文档到es
+func SyncDocsToES(docs []map[string]interface{}) {
+	//jyDocsRpcUtil.GetESV7DB().Save(entity.ElasticJYDoc, entity.ElasticJYDoc, docs[0])
+	if len(docs) > 0 {
+		jyDocsRpcUtil.GetESV7DB().BulkSave(entity.ElasticJYDoc, entity.ElasticJYDoc, &docs, false)
+	}
+	return
+}

+ 13 - 0
services/partner/mgo.go

@@ -0,0 +1,13 @@
+package partner
+
+import docRpcUtil "app.yhyue.com/moapp/jy_docs/services/util"
+
+// 接口请求日志
+func SaveDocinLogger(logMap map[string]interface{}) {
+	docRpcUtil.GetJyMgoLoggerDB().Save("doc_log", logMap)
+}
+
+// 豆丁文档列表mgo 记录
+func SaveDocinList(docs map[string]interface{}) {
+	docRpcUtil.GetJyMgoMainDB().Save("doc_info", docs)
+}

+ 28 - 0
services/partner/redis.go

@@ -0,0 +1,28 @@
+package partner
+
+import "app.yhyue.com/moapp/jybase/redis"
+
+// 存储文档doc 起始-id
+func SetDocsStartId(code, key string, startId int64, expireTime int) bool {
+	return redis.Put(code, key, startId, expireTime)
+}
+
+// 获取文档doc 起始-id
+func GetDocsStartId(code, key string) int64 {
+	return int64(redis.GetInt(code, key))
+}
+
+// 删除文档doc 起始-id
+func DelDocsStartId(code, key string) bool {
+	return redis.Del(code, key)
+}
+
+// 更新文档信息起始时间
+func SetUpdateTaskInfo(code, key, startDate string, expireTime int) bool {
+	return redis.Put(code, key, startDate, expireTime)
+}
+
+// 获取文档信息起始时间
+func GetUpdateTaskInfo(code, key string) string {
+	return redis.GetStr(code, key)
+}

+ 78 - 1
services/util/baseInit.go

@@ -1,13 +1,17 @@
 package util
 
 import (
+	"app.yhyue.com/moapp/jybase/es"
 	elastic "app.yhyue.com/moapp/jybase/esv7"
+	"app.yhyue.com/moapp/jybase/mongodb"
 	"app.yhyue.com/moapp/jybase/mysql"
+	"app.yhyue.com/moapp/jybase/redis"
 	"app.yhyue.com/moapp/jyfs/rpc/filesystemclient"
 	"github.com/zeromicro/go-zero/core/discov"
 	"github.com/zeromicro/go-zero/zrpc"
 	"gorm.io/gorm"
 	"log"
+	"strings"
 )
 
 type MysqlDBConfig struct {
@@ -25,9 +29,25 @@ type EsConfig struct {
 	Password string
 }
 
+type MongoConfig struct {
+	Main   Mongo
+	Logger Mongo
+}
+
+type Mongo struct {
+	Address  string `json:"address"`
+	Size     int    `json:"size"`
+	DbName   string `json:"dbName"`
+	UserName string `json:"userName,optional"`
+	Password string `json:"password,optional"`
+}
+
 var (
 	jyDocsDB   *gorm.DB
 	FileSystem filesystemclient.FileSystem
+	mgoLog     *mongodb.MongodbSim
+	mgoMain    *mongodb.MongodbSim
+	esV7       es.Es
 )
 
 func InitDB(url, driverName string, maxOpenConn, maxIdle int) {
@@ -37,7 +57,6 @@ func InitDB(url, driverName string, maxOpenConn, maxIdle int) {
 	} else {
 		log.Fatalf("----------->【jy_docs】 DB初始化失败<--------------")
 	}
-
 }
 
 func InitEs(addr string, poolSize int, userName, password string) {
@@ -52,6 +71,64 @@ func InitOss(etcd discov.EtcdConf) {
 	FileSystem = filesystemclient.NewFileSystem(client)
 }
 
+func InitRedis(rc []string) {
+	//初始化 redis
+	if len(rc) > 0 {
+		log.Printf("----------->【jy_docs】 redis :[%s] init<--------------", strings.Join(rc, ","))
+		redis.InitRedisBySize(strings.Join(rc, ","), 100, 30, 300)
+	}
+}
+
+func InitMongo(mgo MongoConfig) {
+	if mgo.Main.Address != "" {
+		log.Printf("----------->【jy_docs】 mongodb main:[%s] init<--------------", mgo.Main.Address)
+		mgoMain = &mongodb.MongodbSim{
+			MongodbAddr: mgo.Main.Address,
+			Size:        mgo.Main.Size,
+			DbName:      mgo.Main.DbName,
+			UserName:    mgo.Main.UserName,
+			Password:    mgo.Main.Password,
+		}
+		mgoMain.InitPool()
+	}
+	if mgo.Logger.Address != "" {
+		log.Printf("----------->【jy_docs】 mongodb log:[%s] init<--------------", mgo.Logger.Address)
+		mgoLog = &mongodb.MongodbSim{
+			MongodbAddr: mgo.Logger.Address,
+			Size:        mgo.Logger.Size,
+			DbName:      mgo.Logger.DbName,
+			UserName:    mgo.Logger.UserName,
+			Password:    mgo.Logger.Password,
+		}
+		mgoLog.InitPool()
+	}
+}
+
+// esv7
+func InitESV7(addr string, poolSize int, userName, password string) {
+	if addr != "" {
+		log.Printf("----------->【jy_docs】 elasticSearch :[%s] init<--------------", addr)
+		esV7 = &es.EsV7{
+			Address:  addr,
+			UserName: userName,
+			Password: password,
+			Size:     poolSize,
+		}
+		esV7.Init()
+	}
+}
+func GetJyMgoLoggerDB() *mongodb.MongodbSim {
+	return mgoLog
+}
+
+func GetJyMgoMainDB() *mongodb.MongodbSim {
+	return mgoMain
+}
+
 func GetJyDocsDB() *gorm.DB {
 	return jyDocsDB
 }
+
+func GetESV7DB() es.Es {
+	return esV7
+}

部分文件因为文件数量过多而无法显示