From 812db10a6aea48edb3c849a466c92508ec20374c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=96=87=E6=AD=A6?= <875892894@qq.com>
Date: Thu, 1 Aug 2024 12:48:04 +0800
Subject: [PATCH] init
---
.gitignore | 18 +
Dockerfile | 8 +
Makefile | 67 +
README.md | 3 +-
api/global/dict.go | 40 +
api/global/global.go | 151 +
api/influencer/banner.go | 33 +
api/influencer/chain.go | 36 +
api/influencer/mission.go | 354 +++
api/influencer/order.go | 162 +
api/influencer/tb_goods.go | 29 +
api/influencer/tools.go | 76 +
api/influencer/user.go | 356 +++
api/influencer/wallet.go | 347 +++
api/sys/sys_brochure.go | 42 +
api/sys/sys_user.go | 50 +
api/sys/version.go | 30 +
config-prod.yaml | 122 +
config.yaml | 122 +
config/auto_code.go | 1 +
config/captcha.go | 7 +
config/casbin.go | 5 +
config/config.go | 23 +
config/dysmsapi.go | 11 +
config/email.go | 11 +
config/excel.go | 2 +
config/gorm.go | 21 +
config/gorm_settings.go | 10 +
config/jpush.go | 8 +
config/jwt.go | 7 +
config/minio.go | 2 +
config/oss.go | 31 +
config/paypal.go | 11 +
config/redis.go | 7 +
config/system.go | 9 +
config/timer.go | 13 +
config/tools.go | 5 +
config/zap.go | 13 +
core/server.go | 38 +
core/server_other.go | 17 +
core/server_win.go | 19 +
core/viper.go | 56 +
core/zap.go | 103 +
docs/docs.go | 4378 +++++++++++++++++++++++++++
docs/swagger.json | 4354 ++++++++++++++++++++++++++
docs/swagger.yaml | 2897 ++++++++++++++++++
dto/customer.pb.go | 820 +++++
dto/customer.proto | 60 +
global/global.go | 25 +
global/model.go | 56 +
go.mod | 118 +
go.sum | 781 +++++
initialize/api/email.pb.go | 253 ++
initialize/api/email.proto | 32 +
initialize/api/email_grpc.pb.go | 111 +
initialize/api/greeter.pb.go | 1429 +++++++++
initialize/api/greeter.proto | 126 +
initialize/api/greeter_grpc.pb.go | 432 +++
initialize/api/sms.pb.go | 329 ++
initialize/api/sms.proto | 47 +
initialize/api/sms_grpc.pb.go | 150 +
initialize/gorm.go | 110 +
initialize/grpc.go | 89 +
initialize/internal/gorm.go | 52 +
initialize/internal/logger.go | 33 +
initialize/international.go | 24 +
initialize/redis.go | 44 +
initialize/router.go | 53 +
initialize/timer.go | 23 +
initialize/validator.go | 22 +
main.go | 36 +
middleware/Ijwt.go | 132 +
middleware/cors.go | 26 +
middleware/error.go | 61 +
middleware/jwt.go | 203 ++
middleware/loadtls.go | 26 +
middleware/need_init.go | 23 +
middleware/params.go | 50 +
model/account.go | 29 +
model/address.go | 22 +
model/application.go | 21 +
model/banner.go | 22 +
model/base.go | 9 +
model/bill.go | 51 +
model/bill_fund.go | 22 +
model/collectiom_goods.go | 13 +
model/collection_mission.go | 13 +
model/dict.go | 49 +
model/dt_statistic_order.go | 26 +
model/goods_visit.go | 14 +
model/internationalization.go | 13 +
model/mission.go | 98 +
model/mission_claim.go | 49 +
model/mission_claim_address.go | 12 +
model/mission_claim_order.go | 43 +
model/mission_claim_order_goods.go | 17 +
model/mission_claim_video.go | 37 +
model/mission_claim_works.go | 17 +
model/mission_recommend.go | 27 +
model/notify.go | 16 +
model/order.go | 69 +
model/order_address.go | 12 +
model/order_deliver.go | 27 +
model/order_goods.go | 26 +
model/order_goods_specs.go | 30 +
model/order_post_sale.go | 42 +
model/paypalWebhook.go | 21 +
model/platform_auth.go | 22 +
model/provider.go | 60 +
model/request/account.go | 21 +
model/request/address.go | 7 +
model/request/bill.go | 16 +
model/request/chain.go | 5 +
model/request/collection_mission.go | 9 +
model/request/common.go | 56 +
model/request/dict.go | 5 +
model/request/jwt.go | 19 +
model/request/mission.go | 67 +
model/request/notify.go | 6 +
model/request/order.go | 42 +
model/request/othor.go | 11 +
model/request/sys_brochure.go | 5 +
model/request/tb_goods.go | 15 +
model/request/user.go | 57 +
model/request/wallet.go | 24 +
model/response/banner.go | 16 +
model/response/chain.go | 10 +
model/response/common.go | 19 +
model/response/mission.go | 116 +
model/response/paypalOrder.go | 843 ++++++
model/response/response.go | 86 +
model/response/tripartite.go | 26 +
model/response/user.go | 25 +
model/seller_store.go | 26 +
model/sys_brochure.go | 16 +
model/sys_jwt_blacklist.go | 8 +
model/sys_mission_reward.go | 28 +
model/tag_relation.go | 26 +
model/tags.go | 26 +
model/tb_attribute.go | 41 +
model/tb_attribute_value.go | 25 +
model/tb_category.go | 15 +
model/tb_goods.go | 103 +
model/tb_goods_specs.go | 42 +
model/track.go | 28 +
model/track_webhook.go | 12 +
model/us_citys.go | 12 +
model/us_states.go | 18 +
model/user.go | 64 +
model/version.go | 32 +
model/wallet.go | 18 +
model/webhook.go | 12 +
model/withdrawal.go | 32 +
openapi.yaml | 10 +
packfile/notUsePackFile.go | 3 +
packfile/usePackFile.go | 45 +
resource/gorm_settings.yaml | 25 +
resource/rbac_model.conf | 14 +
router/global/dict.go | 13 +
router/global/global.go | 19 +
router/influencer/base.go | 25 +
router/influencer/goods.go | 13 +
router/influencer/mission.go | 36 +
router/influencer/order.go | 18 +
router/influencer/user.go | 19 +
router/influencer/wallet.go | 28 +
service/address.go | 181 ++
service/banner.go | 41 +
service/bill.go | 157 +
service/chain.go | 28 +
service/collectiom_goods.go | 85 +
service/collection_mission.go | 305 ++
service/dict.go | 56 +
service/jwt_black_list.go | 53 +
service/mission.go | 778 +++++
service/notify.go | 24 +
service/order.go | 459 +++
service/redis_tools.go | 355 +++
service/seller_store.go | 24 +
service/sys_brochure.go | 11 +
service/sys_mission_reward.go | 133 +
service/tags.go | 49 +
service/tb_category.go | 48 +
service/tb_goods.go | 146 +
service/user.go | 868 ++++++
service/version.go | 58 +
service/wallet.go | 281 ++
service/withdrawal.go | 27 +
tests/Makefile | 69 +
tests/api/recommender.proto | 30 +
tests/grpc.go | 1 +
tests/grpc_test.go | 1 +
tests/openapi.yaml | 10 +
utils/array.go | 19 +
utils/breakpoint_continue.go | 102 +
utils/constant.go | 6 +
utils/cors.go | 17 +
utils/db_automation.go | 28 +
utils/directory.go | 46 +
utils/email.go | 78 +
utils/file_operations.go | 63 +
utils/float.go | 28 +
utils/fmt_plus.go | 36 +
utils/injectionCode.go | 142 +
utils/international.go | 32 +
utils/jpush/model.go | 23 +
utils/jpush/push.go | 202 ++
utils/md5.go | 17 +
utils/qiniu/model.go | 83 +
utils/qiniu/video.go | 84 +
utils/redis.go | 321 ++
utils/redis_store.go | 44 +
utils/reload.go | 18 +
utils/rotatelogs_unix.go | 30 +
utils/rotatelogs_windows.go | 26 +
utils/sendSms.go | 109 +
utils/server.go | 113 +
utils/string.go | 69 +
utils/time.go | 13 +
utils/timer/timed_task.go | 109 +
utils/upload/aliyun_oss.go | 75 +
utils/upload/local.go | 79 +
utils/upload/minio.go | 123 +
utils/upload/tencent_cos.go | 60 +
utils/validator.go | 368 +++
utils/verify.go | 27 +
utils/zipfiles.go | 71 +
webhook.json | 546 ++++
228 files changed, 30651 insertions(+), 2 deletions(-)
create mode 100644 .gitignore
create mode 100644 Dockerfile
create mode 100644 Makefile
create mode 100644 api/global/dict.go
create mode 100644 api/global/global.go
create mode 100644 api/influencer/banner.go
create mode 100644 api/influencer/chain.go
create mode 100644 api/influencer/mission.go
create mode 100644 api/influencer/order.go
create mode 100644 api/influencer/tb_goods.go
create mode 100644 api/influencer/tools.go
create mode 100644 api/influencer/user.go
create mode 100644 api/influencer/wallet.go
create mode 100644 api/sys/sys_brochure.go
create mode 100644 api/sys/sys_user.go
create mode 100644 api/sys/version.go
create mode 100644 config-prod.yaml
create mode 100644 config.yaml
create mode 100644 config/auto_code.go
create mode 100644 config/captcha.go
create mode 100644 config/casbin.go
create mode 100644 config/config.go
create mode 100644 config/dysmsapi.go
create mode 100644 config/email.go
create mode 100644 config/excel.go
create mode 100644 config/gorm.go
create mode 100644 config/gorm_settings.go
create mode 100644 config/jpush.go
create mode 100644 config/jwt.go
create mode 100644 config/minio.go
create mode 100644 config/oss.go
create mode 100644 config/paypal.go
create mode 100644 config/redis.go
create mode 100644 config/system.go
create mode 100644 config/timer.go
create mode 100644 config/tools.go
create mode 100644 config/zap.go
create mode 100644 core/server.go
create mode 100644 core/server_other.go
create mode 100644 core/server_win.go
create mode 100644 core/viper.go
create mode 100644 core/zap.go
create mode 100644 docs/docs.go
create mode 100644 docs/swagger.json
create mode 100644 docs/swagger.yaml
create mode 100644 dto/customer.pb.go
create mode 100644 dto/customer.proto
create mode 100644 global/global.go
create mode 100644 global/model.go
create mode 100644 go.mod
create mode 100644 go.sum
create mode 100644 initialize/api/email.pb.go
create mode 100644 initialize/api/email.proto
create mode 100644 initialize/api/email_grpc.pb.go
create mode 100644 initialize/api/greeter.pb.go
create mode 100644 initialize/api/greeter.proto
create mode 100644 initialize/api/greeter_grpc.pb.go
create mode 100644 initialize/api/sms.pb.go
create mode 100644 initialize/api/sms.proto
create mode 100644 initialize/api/sms_grpc.pb.go
create mode 100644 initialize/gorm.go
create mode 100644 initialize/grpc.go
create mode 100644 initialize/internal/gorm.go
create mode 100644 initialize/internal/logger.go
create mode 100644 initialize/international.go
create mode 100644 initialize/redis.go
create mode 100644 initialize/router.go
create mode 100644 initialize/timer.go
create mode 100644 initialize/validator.go
create mode 100644 main.go
create mode 100644 middleware/Ijwt.go
create mode 100644 middleware/cors.go
create mode 100644 middleware/error.go
create mode 100644 middleware/jwt.go
create mode 100644 middleware/loadtls.go
create mode 100644 middleware/need_init.go
create mode 100644 middleware/params.go
create mode 100644 model/account.go
create mode 100644 model/address.go
create mode 100755 model/application.go
create mode 100644 model/banner.go
create mode 100644 model/base.go
create mode 100644 model/bill.go
create mode 100644 model/bill_fund.go
create mode 100644 model/collectiom_goods.go
create mode 100644 model/collection_mission.go
create mode 100644 model/dict.go
create mode 100644 model/dt_statistic_order.go
create mode 100644 model/goods_visit.go
create mode 100644 model/internationalization.go
create mode 100644 model/mission.go
create mode 100644 model/mission_claim.go
create mode 100644 model/mission_claim_address.go
create mode 100644 model/mission_claim_order.go
create mode 100644 model/mission_claim_order_goods.go
create mode 100644 model/mission_claim_video.go
create mode 100644 model/mission_claim_works.go
create mode 100644 model/mission_recommend.go
create mode 100644 model/notify.go
create mode 100644 model/order.go
create mode 100644 model/order_address.go
create mode 100644 model/order_deliver.go
create mode 100644 model/order_goods.go
create mode 100644 model/order_goods_specs.go
create mode 100644 model/order_post_sale.go
create mode 100644 model/paypalWebhook.go
create mode 100644 model/platform_auth.go
create mode 100755 model/provider.go
create mode 100644 model/request/account.go
create mode 100644 model/request/address.go
create mode 100644 model/request/bill.go
create mode 100644 model/request/chain.go
create mode 100644 model/request/collection_mission.go
create mode 100644 model/request/common.go
create mode 100644 model/request/dict.go
create mode 100644 model/request/jwt.go
create mode 100644 model/request/mission.go
create mode 100644 model/request/notify.go
create mode 100644 model/request/order.go
create mode 100644 model/request/othor.go
create mode 100644 model/request/sys_brochure.go
create mode 100644 model/request/tb_goods.go
create mode 100644 model/request/user.go
create mode 100644 model/request/wallet.go
create mode 100644 model/response/banner.go
create mode 100644 model/response/chain.go
create mode 100644 model/response/common.go
create mode 100644 model/response/mission.go
create mode 100644 model/response/paypalOrder.go
create mode 100644 model/response/response.go
create mode 100644 model/response/tripartite.go
create mode 100755 model/response/user.go
create mode 100644 model/seller_store.go
create mode 100644 model/sys_brochure.go
create mode 100755 model/sys_jwt_blacklist.go
create mode 100644 model/sys_mission_reward.go
create mode 100644 model/tag_relation.go
create mode 100644 model/tags.go
create mode 100644 model/tb_attribute.go
create mode 100644 model/tb_attribute_value.go
create mode 100644 model/tb_category.go
create mode 100644 model/tb_goods.go
create mode 100644 model/tb_goods_specs.go
create mode 100644 model/track.go
create mode 100644 model/track_webhook.go
create mode 100644 model/us_citys.go
create mode 100644 model/us_states.go
create mode 100755 model/user.go
create mode 100644 model/version.go
create mode 100644 model/wallet.go
create mode 100644 model/webhook.go
create mode 100644 model/withdrawal.go
create mode 100644 openapi.yaml
create mode 100644 packfile/notUsePackFile.go
create mode 100644 packfile/usePackFile.go
create mode 100644 resource/gorm_settings.yaml
create mode 100644 resource/rbac_model.conf
create mode 100644 router/global/dict.go
create mode 100644 router/global/global.go
create mode 100644 router/influencer/base.go
create mode 100644 router/influencer/goods.go
create mode 100644 router/influencer/mission.go
create mode 100644 router/influencer/order.go
create mode 100644 router/influencer/user.go
create mode 100644 router/influencer/wallet.go
create mode 100644 service/address.go
create mode 100644 service/banner.go
create mode 100644 service/bill.go
create mode 100644 service/chain.go
create mode 100644 service/collectiom_goods.go
create mode 100644 service/collection_mission.go
create mode 100644 service/dict.go
create mode 100755 service/jwt_black_list.go
create mode 100644 service/mission.go
create mode 100644 service/notify.go
create mode 100644 service/order.go
create mode 100644 service/redis_tools.go
create mode 100644 service/seller_store.go
create mode 100644 service/sys_brochure.go
create mode 100644 service/sys_mission_reward.go
create mode 100644 service/tags.go
create mode 100644 service/tb_category.go
create mode 100644 service/tb_goods.go
create mode 100644 service/user.go
create mode 100644 service/version.go
create mode 100644 service/wallet.go
create mode 100644 service/withdrawal.go
create mode 100644 tests/Makefile
create mode 100644 tests/api/recommender.proto
create mode 100644 tests/grpc.go
create mode 100644 tests/grpc_test.go
create mode 100644 tests/openapi.yaml
create mode 100644 utils/array.go
create mode 100644 utils/breakpoint_continue.go
create mode 100644 utils/constant.go
create mode 100644 utils/cors.go
create mode 100644 utils/db_automation.go
create mode 100644 utils/directory.go
create mode 100644 utils/email.go
create mode 100644 utils/file_operations.go
create mode 100644 utils/float.go
create mode 100644 utils/fmt_plus.go
create mode 100644 utils/injectionCode.go
create mode 100644 utils/international.go
create mode 100644 utils/jpush/model.go
create mode 100644 utils/jpush/push.go
create mode 100644 utils/md5.go
create mode 100644 utils/qiniu/model.go
create mode 100644 utils/qiniu/video.go
create mode 100644 utils/redis.go
create mode 100644 utils/redis_store.go
create mode 100644 utils/reload.go
create mode 100644 utils/rotatelogs_unix.go
create mode 100644 utils/rotatelogs_windows.go
create mode 100644 utils/sendSms.go
create mode 100644 utils/server.go
create mode 100644 utils/string.go
create mode 100644 utils/time.go
create mode 100644 utils/timer/timed_task.go
create mode 100644 utils/upload/aliyun_oss.go
create mode 100644 utils/upload/local.go
create mode 100644 utils/upload/minio.go
create mode 100644 utils/upload/tencent_cos.go
create mode 100644 utils/validator.go
create mode 100644 utils/verify.go
create mode 100644 utils/zipfiles.go
create mode 100644 webhook.json
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1e2f0b1
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,18 @@
+# Binaries for programs and plugins
+*.exe
+*.exe~
+*.dll
+*.so
+*.log
+
+# Test binary, build with `go test -c`
+*.test
+
+# Output of the go coverage tool, specifically when used with LiteIDE
+*.out
+.idea/
+
+*.history
+*_debug*
+*.vscode
+cache/
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..4232a79
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,8 @@
+FROM registry.cn-shanghai.aliyuncs.com/lj-go/alpine
+LABEL MAINTAINER="NFT"
+
+WORKDIR /go/src/nft
+COPY . /go/src/nft
+RUN ls
+EXPOSE 8001
+ENTRYPOINT ./server.app
\ No newline at end of file
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..b25a8c2
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,67 @@
+GOHOSTOS:=$(shell go env GOHOSTOS)
+GOPATH:=$(shell go env GOPATH)
+VERSION=$(shell git describe --tags --always)
+
+ifeq ($(GOHOSTOS), windows)
+ #the `find.exe` is different from `find` in bash/shell.
+ #to see https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/find.
+ #changed to use git-bash.exe to run find cli or other cli friendly, caused of every developer has a Git.
+ #Git_Bash= $(subst cmd\,bin\bash.exe,$(dir $(shell where git)))
+ Git_Bash=$(subst \,/,$(subst cmd\,bin\bash.exe,$(dir $(shell where git))))
+ INTERNAL_PROTO_FILES=$(shell $(Git_Bash) -c "find internal -name *.proto")
+ API_PROTO_FILES=$(shell $(Git_Bash) -c "find dto -name *.proto")
+else
+ INTERNAL_PROTO_FILES=$(shell find internal -name *.proto)
+ API_PROTO_FILES=$(shell find dto -name *.proto)
+ SD_PROTO_FILES=$(shell find pkg/stable_diffusion -name *.proto)
+endif
+
+.PHONY: init
+# init env
+init:
+ go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
+ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
+ go install github.com/go-kratos/kratos/cmd/kratos/v2@latest
+ go install github.com/go-kratos/kratos/cmd/protoc-gen-go-http/v2@latest
+ go install github.com/google/gnostic/cmd/protoc-gen-openapi@latest
+ go install github.com/google/wire/cmd/wire@latest
+
+.PHONY: config
+# generate internal proto
+config:
+ protoc --proto_path=./internal \
+ --proto_path=./third_party \
+ --go_out=paths=source_relative:./internal \
+ $(INTERNAL_PROTO_FILES)
+
+.PHONY: api
+# generate api proto
+api:
+ protoc --proto_path=./dto \
+ --go_out=paths=source_relative:./dto \
+ --go-http_out=paths=source_relative:./dto \
+ --go-grpc_out=paths=source_relative:./dto \
+ --openapi_out=fq_schema_naming=true,default_response=false:. \
+ $(API_PROTO_FILES)
+ ls ./dto/*.pb.go | xargs -n1 -IX bash -c 'sed s/,omitempty// X > X.tmp && mv X{.tmp,}'
+
+
+
+# show help
+help:
+ @echo ''
+ @echo 'Usage:'
+ @echo ' make [target]'
+ @echo ''
+ @echo 'Targets:'
+ @awk '/^[a-zA-Z\-\_0-9]+:/ { \
+ helpMessage = match(lastLine, /^# (.*)/); \
+ if (helpMessage) { \
+ helpCommand = substr($$1, 0, index($$1, ":")); \
+ helpMessage = substr(lastLine, RSTART + 2, RLENGTH); \
+ printf "\033[36m%-22s\033[0m %s\n", helpCommand,helpMessage; \
+ } \
+ } \
+ { lastLine = $$0 }' $(MAKEFILE_LIST)
+
+.DEFAULT_GOAL := help
diff --git a/README.md b/README.md
index 704cc64..b74af18 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1 @@
-# app-api
-
+# app-api
\ No newline at end of file
diff --git a/api/global/dict.go b/api/global/dict.go
new file mode 100644
index 0000000..d08c755
--- /dev/null
+++ b/api/global/dict.go
@@ -0,0 +1,40 @@
+package global
+
+import (
+ "pure/model/request"
+ "pure/model/response"
+ "pure/service"
+ "pure/utils"
+
+ "github.com/gin-gonic/gin"
+)
+
+// GetSysDictDataList
+// @Tags dict
+// @Summary 获取数据字典取值列表【v1.0】
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data query request.SearchDictDataParams true "data"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /dict/getDictDataList [get]
+func GetSysDictDataList(c *gin.Context) {
+ var (
+ err error
+ list interface{}
+ params request.SearchDictDataParams
+ )
+ _ = c.ShouldBindQuery(¶ms)
+ if err = utils.Verify(params, utils.DictDataVerity); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ if err, list = service.GetSysDictDataList(params.TypeCode); err != nil {
+ ////global.MG_LOG.Error("获取失败!", zap.Any("err", err))
+ response.FailWithMessage("获取失败", c)
+ } else {
+ response.OkWithDetailed(response.SelectListResult{
+ List: list,
+ }, "获取成功", c)
+ }
+}
diff --git a/api/global/global.go b/api/global/global.go
new file mode 100644
index 0000000..ec237ec
--- /dev/null
+++ b/api/global/global.go
@@ -0,0 +1,151 @@
+package global
+
+import (
+ "github.com/gin-gonic/gin"
+
+ "pure/api/sys"
+ "pure/global"
+ "pure/model"
+ "pure/model/request"
+ "pure/model/response"
+ "pure/service"
+ "pure/utils"
+)
+
+// @Summary 获取用户收货地址列表【v1.0】
+// @Security Bearer
+// @Description
+// @Tags 公用-收货地址
+// @Success 200 {object} []model.Address "{"code": 0, "data": [...]}"
+// @Success 200 {string} string "{"code": 1, "message": ""}"
+// @Router /global/address [get]
+func GetAddressList(c *gin.Context) {
+ var (
+ err error
+ userID string
+ req request.ReqAddress
+ data any
+ )
+ c.ShouldBind(&req)
+ userID = sys.GetUserUuid(c)
+ err, data = service.GetUserAddressList(userID, &req)
+ if err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ response.OkWithData(data, c)
+}
+
+// @Summary 添加收货地址【v1.0】
+// @Security Bearer
+// @Description
+// @Tags 公用-收货地址
+// @Param data body model.Address false "data..."
+// @Success 200 {string} string "{"code": 0, "data": [...]}"
+// @Success 200 {string} string "{"code": 1, "message": ""}"
+// @Router /global/address [post]
+func AddAddress(c *gin.Context) {
+ var (
+ err error
+ userID string
+ data model.Address
+ )
+ c.ShouldBindJSON(&data)
+ userID = sys.GetUserUuid(c)
+ err = service.AddUserAddressList(userID, &data)
+ if err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ response.OkWithMessage("添加成功", c)
+}
+
+// @Summary 修改收货地址【v1.0】
+// @Security Bearer
+// @Description
+// @Tags 公用-收货地址
+// @Param data body model.Address false "data..."
+// @Success 200 {string} string "{"code": 0, "data": [...]}"
+// @Success 200 {string} string "{"code": 1, "message": ""}"
+// @Router /global/address [put]
+func UpdateAddress(c *gin.Context) {
+ var (
+ err error
+ userID string
+ data model.Address
+ )
+ c.ShouldBindJSON(&data)
+ userID = sys.GetUserUuid(c)
+ err = service.UpdateAddress(userID, &data)
+ if err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ response.OkWithMessage("修改成功", c)
+}
+
+// @Summary 删除收货地址【v1.0】
+// @Security Bearer
+// @Description
+// @Tags 公用-收货地址
+// @Param data body global.BASE_ID false "data..."
+// @Success 200 {string} string "{"code": 0, "data": [...]}"
+// @Success 200 {string} string "{"code": 1, "message": ""}"
+// @Router /global/address [delete]
+func DeleteAddress(c *gin.Context) {
+ var (
+ err error
+ userID string
+ data global.BASE_ID
+ )
+ c.ShouldBindJSON(&data)
+ userID = sys.GetUserUuid(c)
+ err = service.DeleteAddress(userID, &data)
+ if err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ response.OkWithMessage("删除成功", c)
+}
+
+// @Summary 美国地区选择器【v1.0】
+// @Security Bearer
+// @Description
+// @Tags 公用-收货地址
+// @Success 200 {object} []model.UsSelect "{"code": 0, "data": [...]}"
+// @Success 200 {string} string "{"code": 1, "message": ""}"
+// @Router /global/usSelect [get]
+func GetUsSelect(c *gin.Context) {
+ var (
+ err error
+ data any
+ )
+ err, data = service.GetUsSelect()
+ if err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ response.OkWithData(data, c)
+}
+
+// @Summary 查询物流信息
+// @Security Bearer
+// @Description
+// @Tags track
+// @Param data query request.IdReq false "params"
+// @Success 200 {string} string "{"code": 1, "message": ""}"
+// @Router /global/track [get]
+func GetTrack(c *gin.Context) {
+ var info request.IdReq
+ _ = c.ShouldBindQuery(&info)
+ if err := utils.Verify(info, utils.IdVerify); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ data, err := service.GetTrack(int64(info.ID))
+ if err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ response.OkWithData(data, c)
+}
diff --git a/api/influencer/banner.go b/api/influencer/banner.go
new file mode 100644
index 0000000..0be5b0c
--- /dev/null
+++ b/api/influencer/banner.go
@@ -0,0 +1,33 @@
+package influencer
+
+import (
+ "github.com/gin-gonic/gin"
+ "pure/model/response"
+ "pure/service"
+)
+
+// GetBannerList
+// @Tags banner
+// @Summary 分页获取banner列表【v1.1.0新增】
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Success 200 {array} response.BannerListResponse "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /influencer/banner/list [get]
+func GetBannerList(c *gin.Context) {
+ var (
+ err error
+ list interface{}
+ total int64
+ )
+
+ if err, list, total = service.GetBannerList(); err != nil {
+ ////global.MG_LOG.Error("获取失败!", zap.Any("err", err))
+ response.FailWithMessage("获取失败", c)
+ } else {
+ response.OkWithDetailed(response.PageResult{
+ List: list,
+ Total: total,
+ }, "获取成功", c)
+ }
+}
diff --git a/api/influencer/chain.go b/api/influencer/chain.go
new file mode 100644
index 0000000..3414350
--- /dev/null
+++ b/api/influencer/chain.go
@@ -0,0 +1,36 @@
+package influencer
+
+import (
+ "github.com/gin-gonic/gin"
+ "pure/model/request"
+ "pure/model/response"
+ "pure/service"
+ "pure/utils"
+)
+
+// GetChainInfo
+// @Summary 获取区块链数据
+// @Description
+// @Tags Chain
+// @Param data query request.ChainParams false "data..."
+// @Success 200 {object} []response.ChainResp "{"code": 0, "data": [...]}"
+// @Success 201 {string} string "{"code": 1, "message": ""}"
+// @Router /influencer/base/chain [get]
+func GetChainInfo(c *gin.Context) {
+ var (
+ err error
+ params request.ChainParams
+ result []response.ChainResp
+ )
+ _ = c.ShouldBindQuery(¶ms)
+ if err = utils.Verify(params, utils.ChainVerify); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ err, result = service.GetChainInfo(params.Hash)
+ if err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ response.OkWithData(result, c)
+}
diff --git a/api/influencer/mission.go b/api/influencer/mission.go
new file mode 100644
index 0000000..7fc426c
--- /dev/null
+++ b/api/influencer/mission.go
@@ -0,0 +1,354 @@
+package influencer
+
+import (
+ "pure/api/sys"
+ "pure/global"
+ "pure/model/request"
+ "pure/model/response"
+ "pure/service"
+ "pure/utils"
+
+ "github.com/gin-gonic/gin"
+ "go.uber.org/zap"
+)
+
+// GetMissionDetail
+// @Summary 获取任务详情【v1.0】
+// @Description
+// @Tags mission
+// @Security ApiKeyAuth
+// @Param data query request.IdReq false "params"
+// @Success 200 {object} model.MissionDetail "{"code": 200, "data": {}}"
+// @Router /influencer/mission/detail [get]
+func GetMissionDetail(c *gin.Context) {
+ var info request.IdReq
+ _ = c.ShouldBindQuery(&info)
+ if err := utils.Verify(info, utils.IdVerify); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ if err, data := service.GetMissionDetail(sys.GetUserUuid(c), info.ID); err != nil {
+ global.MG_LOG.Error("获取失败!", zap.Any("err", err))
+ response.FailWithMessage("获取失败", c)
+ } else {
+ response.OkWithData(data, c)
+ }
+}
+
+// GetMissionList
+// @Summary 获取任务列表【v1.0】
+// @Description
+// @Tags mission
+// @Security ApiKeyAuth
+// @Param data query request.SearchMission false "params"
+// @Success 200 {array} model.MissionDetail "{"code": 200, "data": {}}"
+// @Router /influencer/mission/list [get]
+func GetMissionList(c *gin.Context) {
+ var info request.SearchMission
+ _ = c.ShouldBindQuery(&info)
+ if err := utils.Verify(info.PageInfo, utils.PageInfoVerify); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ if err, list, total := service.GetMissionList(sys.GetUserUuid(c), info); err != nil {
+ global.MG_LOG.Error("获取失败!", zap.Any("err", err))
+ response.FailWithMessage("获取失败", c)
+ } else {
+ response.OkWithDetailed(response.PageResult{
+ List: list,
+ Total: total,
+ Page: info.Page,
+ PageSize: info.PageSize,
+ }, "获取成功", c)
+ }
+}
+
+// GetMissionClaim
+// @Summary 获取我的任务详情【v1.0】
+// @Description
+// @Tags mission
+// @Security ApiKeyAuth
+// @Param data query request.IdReq false "params"
+// @Success 200 {object} model.MissionClaimDetail "{"code": 200, "data": {}}"
+// @Router /influencer/mission/claim [get]
+func GetMissionClaim(c *gin.Context) {
+ var info request.IdReq
+ _ = c.ShouldBindQuery(&info)
+ if err := utils.Verify(info, utils.IdVerify); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ if err, data := service.GetMissionClaim(sys.GetUserUuid(c), info.ID); err != nil {
+ global.MG_LOG.Error("获取失败!", zap.Any("err", err))
+ response.FailWithMessage("获取失败", c)
+ } else {
+ response.OkWithData(data, c)
+ }
+}
+
+// GetMissionClaimList
+// @Summary 获取我的任务列表【v1.0】
+// @Description
+// @Tags mission
+// @Security ApiKeyAuth
+// @Param data query request.SearchMissionClaim false "params"
+// @Success 200 {array} model.MissionClaimDetail "{"code": 200, "data": {}}"
+// @Router /influencer/mission/claim-list [get]
+func GetMissionClaimList(c *gin.Context) {
+ var info request.SearchMissionClaim
+ _ = c.ShouldBindQuery(&info)
+ if err := utils.Verify(info.PageInfo, utils.PageInfoVerify); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ if err, list, total := service.MergeMissionClaimList(sys.GetUserUuid(c), info); err != nil {
+ global.MG_LOG.Error("获取失败!", zap.Any("err", err))
+ response.FailWithMessage("获取失败", c)
+ } else {
+ response.OkWithDetailed(response.PageResult{
+ List: list,
+ Total: total,
+ Page: info.Page,
+ PageSize: info.PageSize,
+ }, "获取成功", c)
+ }
+}
+
+// ClaimMission
+// @Summary 领取任务【v1.0】
+// @Description
+// @Tags mission
+// @Security ApiKeyAuth
+// @Param data body request.ClaimMission false "params"
+// @Success 200 {string} string "{"code": 200, "data": {}}"
+// @Router /influencer/mission/claim [post]
+func ClaimMission(c *gin.Context) {
+ var info request.ClaimMission
+ _ = c.ShouldBindJSON(&info)
+ if err := utils.Verify(info, utils.MissionClaimVerify); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ if err, id := service.ClaimMission(sys.GetUserUuid(c), info); err != nil {
+ global.MG_LOG.Error("领取失败!"+err.Error(), zap.Any("err", err))
+ response.FailWithMessage("领取失败!"+err.Error(), c)
+ } else {
+ response.OkWithDetailed(id, "领取成功", c)
+ }
+}
+
+// CollectMission
+// @Summary 收藏/取消收藏任务【v1.0】
+// @Description
+// @Tags mission
+// @Security ApiKeyAuth
+// @Param data body request.MissionId false "params"
+// @Success 200 {string} string "{"code": 200, "data": {}}"
+// @Router /influencer/mission/collect [post]
+func CollectMission(c *gin.Context) {
+ var info request.MissionId
+ _ = c.ShouldBindJSON(&info)
+ if err := utils.Verify(info, utils.MissionIdVerify); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ if err, id := service.ChangeCollectionMission(sys.GetUserUuid(c), info); err != nil {
+ global.MG_LOG.Error("操作失败!"+err.Error(), zap.Any("err", err))
+ response.FailWithMessage("操作失败!"+err.Error(), c)
+ } else {
+ response.OkWithDetailed(id, "操作成功", c)
+ }
+}
+
+// GetCollectionMissionList
+// @Summary 获取收藏任务列表【v1.0】
+// @Description
+// @Tags mission
+// @Security ApiKeyAuth
+// @Param data query request.SearchCollectionMission false "params"
+// @Success 200 {array} model.MissionDetail "{"code": 200, "data": {}}"
+// @Router /influencer/mission/collect-list [get]
+func GetCollectionMissionList(c *gin.Context) {
+ var info request.SearchCollectionMission
+ _ = c.ShouldBindQuery(&info)
+ if err := utils.Verify(info.PageInfo, utils.PageInfoVerify); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ if err, list, total := service.GetCollectionMissionList(sys.GetUserUuid(c), info); err != nil {
+ global.MG_LOG.Error("获取失败!", zap.Any("err", err))
+ response.FailWithMessage("获取失败", c)
+ } else {
+ response.OkWithDetailed(response.PageResult{
+ List: list,
+ Total: total,
+ Page: info.Page,
+ PageSize: info.PageSize,
+ }, "获取成功", c)
+ }
+}
+
+// SubmitClaimMissionWorks
+// @Summary 领取任务的提交作品【v1.0】
+// @Description
+// @Tags mission
+// @Security ApiKeyAuth
+// @Param data body request.ClaimMissionWorksList false "params"
+// @Success 200 {string} string "{"code": 200, "data": {}}"
+// @Router /influencer/mission/submit-works [post]
+func SubmitClaimMissionWorks(c *gin.Context) {
+ var info request.ClaimMissionWorksList
+ _ = c.ShouldBindJSON(&info)
+ if err := utils.Verify(info, utils.MissionClaimIdVerify); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ if err := service.SubmitClaimMissionWorks(sys.GetUserUuid(c), info); err != nil {
+ global.MG_LOG.Error("提交失败!"+err.Error(), zap.Any("err", err))
+ response.FailWithMessage("提交失败!"+err.Error(), c)
+ } else {
+ response.OkWithMessage("提交成功", c)
+ }
+}
+
+// GetMissionDetail
+// @Summary 获取任务累计奖金
+// @Description
+// @Tags mission
+// @Security ApiKeyAuth
+// @Param data query request.MissionCode false "params"
+// @Success 200 {object} model.MissionBonus "{"code": 200, "data": {}}"
+// @Router /influencer/mission/bonus [get]
+func GetMissionBonus(c *gin.Context) {
+ var info request.MissionCode
+ _ = c.ShouldBindQuery(&info)
+ if err := utils.Verify(info, utils.MissionCodeVerify); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ data := service.GetMissionBonus(info.Code)
+ response.OkWithData(data, c)
+}
+
+// SubmitClaimMissionVideo
+// @Summary 固定费用任务上传视频【v1.0】
+// @Description
+// @Tags mission
+// @Security ApiKeyAuth
+// @Param data body request.ClaimMissionVideo false "params"
+// @Success 200 {string} string "{"code": 200, "data": {}}"
+// @Router /influencer/mission/submit-video [post]
+func SubmitClaimMissionVideo(c *gin.Context) {
+ var info request.ClaimMissionVideo
+ _ = c.ShouldBindJSON(&info)
+ if err := utils.Verify(info, utils.MissionClaimIdVerify); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ if err := service.SubmitClaimMissionVideo(sys.GetUserUuid(c), info); err != nil {
+ global.MG_LOG.Error("提交失败!"+err.Error(), zap.Any("err", err))
+ response.FailWithMessage("提交失败!"+err.Error(), c)
+ } else {
+ response.OkWithMessage("提交成功", c)
+ }
+}
+
+// GetRecommendMissionList
+// @Summary 获取首页任务列表【v1.0】
+// @Description
+// @Tags mission
+// @Security ApiKeyAuth
+// @Param data query request.SearchRecommendMission false "params"
+// @Success 200 {array} response.MissionRecommendResponse "{"code": 200, "data": {}}"
+// @Router /influencer/mission/recommend-list [get]
+func GetRecommendMissionList(c *gin.Context) {
+ var info request.SearchRecommendMission
+ _ = c.ShouldBindQuery(&info)
+ if err := utils.Verify(info.PageInfo, utils.PageInfoVerify); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ if err, list, total := service.GetRecommendMissionList(info); err != nil {
+ global.MG_LOG.Error("获取失败!", zap.Any("err", err))
+ response.FailWithMessage("获取失败", c)
+ } else {
+ response.OkWithDetailed(response.PageResult{
+ List: list,
+ Total: total,
+ Page: info.Page,
+ PageSize: info.PageSize,
+ }, "获取成功", c)
+ }
+}
+
+// GetRecommendMissionDetail
+// @Summary 获取首页任务详情【v1.0】
+// @Description
+// @Tags mission
+// @Security ApiKeyAuth
+// @Param data query request.IdReq false "params"
+// @Success 200 {object} response.MissionRecommendResponse "{"code": 200, "data": {}}"
+// @Router /influencer/mission/recommend-detail [get]
+func GetRecommendMissionDetail(c *gin.Context) {
+ var info request.IdReq
+ _ = c.ShouldBindQuery(&info)
+ if err := utils.Verify(info, utils.IdVerify); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ if err, data := service.GetRecommendMissionDetail(info); err != nil {
+ global.MG_LOG.Error("获取失败!", zap.Any("err", err))
+ response.FailWithMessage("获取失败", c)
+ } else {
+ response.OkWithDetailed(data, "获取成功", c)
+ }
+}
+
+// GetSysRewardList
+// @Summary 获取平台奖励列表【v1.0】
+// @Description
+// @Tags mission
+// @Security ApiKeyAuth
+// @Param data query request.SearchSysReward false "params"
+// @Success 200 {array} model.SysMissionReward "{"code": 200, "data": {}}"
+// @Router /influencer/mission/sys-reward-list [get]
+func GetSysRewardList(c *gin.Context) {
+ var info request.SearchSysReward
+ _ = c.ShouldBindQuery(&info)
+ if err := utils.Verify(info.PageInfo, utils.PageInfoVerify); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ uuid := sys.GetUserUuid(c)
+ if err, list, total := service.GetSysMissionRewardList(info, uuid); err != nil {
+ global.MG_LOG.Error("获取失败!", zap.Any("err", err))
+ response.FailWithMessage("获取失败", c)
+ } else {
+ response.OkWithDetailed(response.PageResult{
+ List: list,
+ Total: total,
+ Page: info.Page,
+ PageSize: info.PageSize,
+ }, "获取成功", c)
+ }
+}
+
+// GetSysRewardSummary
+// @Summary 获取平台奖励汇总【v1.0】
+// @Description
+// @Tags mission
+// @Security ApiKeyAuth
+// @Param data query request.SearchSysRewardSummary false "params"
+// @Success 200 {object} response.SysMissionBonus "{"code": 200, "data": {}}"
+// @Router /influencer/mission/sys-reward-summary [get]
+func GetSysRewardSummary(c *gin.Context) {
+ var info request.SearchSysRewardSummary
+ _ = c.ShouldBindQuery(&info)
+ uuid := sys.GetUserUuid(c)
+ if err, data := service.GetSysRewardSummary(uuid, info); err != nil {
+ global.MG_LOG.Error("获取失败!", zap.Any("err", err))
+ response.FailWithMessage("获取失败", c)
+ } else {
+ response.OkWithDetailed(data, "获取成功", c)
+ }
+}
diff --git a/api/influencer/order.go b/api/influencer/order.go
new file mode 100644
index 0000000..05c66a1
--- /dev/null
+++ b/api/influencer/order.go
@@ -0,0 +1,162 @@
+package influencer
+
+import (
+ "pure/api/sys"
+ "pure/dto"
+ "pure/model"
+ "pure/model/request"
+ "pure/model/response"
+ "pure/service"
+ "pure/utils"
+
+ "github.com/gin-gonic/gin"
+)
+
+// @Summary 获取订单数据
+// @Security Bearer
+// @Description
+// @Tags order
+// @Param data query request.SceneParams false "data..."
+// @Success 200 {object} dto.OrderData "{"code": 0, "data": [...]}"
+// @Success 201 {string} string "{"code": 1, "message": ""}"
+// @Router /influencer/order/data [get]
+func GetOrderData(c *gin.Context) {
+ var (
+ err error
+ params request.SceneParams
+ result dto.OrderData
+ )
+ _ = c.ShouldBindQuery(¶ms)
+ userId := sys.GetUserUuid(c)
+ result, err = service.GetOrderData(userId, ¶ms)
+ if err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ response.OkWithDataMessage(result, "获取成功", c)
+}
+
+// @Summary 获取订单详情
+// @Security Bearer
+// @Description
+// @Tags order
+// @Param data query request.GetOrderParams false "data..."
+// @Success 200 {object} model.OrderDetail "{"code": 0, "data": [...]}"
+// @Success 201 {string} string "{"code": 1, "message": ""}"
+// @Router /influencer/order/detail [get]
+func GetOrderDetail(c *gin.Context) {
+ var (
+ err error
+ params request.GetOrderParams
+ result model.OrderDetail
+ )
+ _ = c.ShouldBindQuery(¶ms)
+ if err = utils.Verify(params, utils.OrderIdVerity); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ userId := sys.GetUserUuid(c)
+ err, result = service.GetOrderDetail(userId, ¶ms)
+ if err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ } else {
+ response.OkWithDataMessage(result, "获取成功", c)
+ return
+ }
+}
+
+// @Summary 获取订单列表
+// @Security Bearer
+// @Description
+// @Tags order
+// @Param data query request.SearchOrderList false "data..."
+// @Success 200 {object} []model.OrderList "{"code": 0, "data": [...]}"
+// @Success 201 {string} string "{"code": 1, "message": ""}"
+// @Router /influencer/order/list [get]
+func GetUserOrderList(c *gin.Context) {
+ var (
+ err error
+ params request.SearchOrderList
+ list interface{}
+ total int64
+ )
+ _ = c.ShouldBindQuery(¶ms)
+ userID := sys.GetUserUuid(c)
+ if err, list, total = service.GetOrderList(userID, ¶ms); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ } else {
+ response.OkWithDetailed(response.PageResult{
+ List: list,
+ Total: total,
+ Page: params.Page,
+ PageSize: params.PageSize,
+ }, "获取成功", c)
+ }
+}
+
+func GetOrderTotalList(c *gin.Context) {
+ var (
+ err error
+ list interface{}
+ data request.SearchOrderList
+ )
+ _ = c.ShouldBindQuery(&data)
+ err, list = service.GetOrderTotalList(&data)
+ if err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ response.OkWithDetailed(list, "获取成功", c)
+}
+
+// @Summary 获取订单商品快照
+// @Security Bearer
+// @Description
+// @Tags order
+// @Param data query request.GetOrderParams false "data..."
+// @Success 200 {object} model.OrderGoodsDetail "{"code": 0, "data": [...]}"
+// @Success 201 {string} string "{"code": 1, "message": ""}"
+// @Router /influencer/order/goods/snapshot [get]
+func GetOrderGoodsInfo(c *gin.Context) {
+ var (
+ err error
+ params request.GetOrderParams
+ result model.OrderGoodsDetail
+ )
+ _ = c.ShouldBindQuery(¶ms)
+ userId := sys.GetUserUuid(c)
+ err, result = service.GetOrderGoods(userId, ¶ms)
+ if err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ } else {
+ response.OkWithDataMessage(result, "获取成功", c)
+ return
+ }
+}
+
+// @Summary 获取任务下订单统计数据
+// @Security Bearer
+// @Description
+// @Tags mission
+// @Param data query request.MissionCode false "data..."
+// @Success 200 {object} dto.MissionOrderStatistic "{"code": 0, "data": [...]}"
+// @Success 201 {string} string "{"code": 1, "message": ""}"
+// @Router /influencer/mission/order-data [get]
+func GetMissionOrderStatistic(c *gin.Context) {
+ var (
+ err error
+ params request.MissionCode
+ result dto.MissionOrderStatistic
+ )
+ _ = c.ShouldBindQuery(¶ms)
+ userId := sys.GetUserUuid(c)
+ result, err = service.GetMissionOrderStatistic(userId, params.Code)
+ if err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ response.OkWithDataMessage(result, "获取成功", c)
+}
diff --git a/api/influencer/tb_goods.go b/api/influencer/tb_goods.go
new file mode 100644
index 0000000..98aa285
--- /dev/null
+++ b/api/influencer/tb_goods.go
@@ -0,0 +1,29 @@
+package influencer
+
+import (
+ "github.com/gin-gonic/gin"
+ "go.uber.org/zap"
+ "pure/global"
+ "pure/model/request"
+ "pure/model/response"
+ "pure/service"
+)
+
+// GetTbGoodsDetail
+// @Summary 获取商品详情
+// @Description
+// @Tags goods
+// @Security ApiKeyAuth
+// @Param data query request.Goods false "params"
+// @Success 200 {object} model.TbGoodsDetail "{"code": 200, "data": {}}"
+//@Router /influencer/goods/detail [get]
+func GetTbGoodsDetail(c *gin.Context) {
+ var info request.Goods
+ _ = c.ShouldBindQuery(&info)
+ if err, data := service.GetTbGoods(info); err != nil {
+ global.MG_LOG.Error("获取失败!", zap.Any("err", err))
+ response.FailWithMessage("获取失败", c)
+ } else {
+ response.OkWithData(data, c)
+ }
+}
diff --git a/api/influencer/tools.go b/api/influencer/tools.go
new file mode 100644
index 0000000..0b8e0e3
--- /dev/null
+++ b/api/influencer/tools.go
@@ -0,0 +1,76 @@
+package influencer
+
+import (
+ "pure/model/request"
+ "pure/model/response"
+ "pure/service"
+ "pure/utils"
+ "regexp"
+ "time"
+
+ "github.com/gin-gonic/gin"
+)
+
+// SendMessage
+// @Tags tools
+// @Summary 发送短信验证码[v1.0.0]
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body request.SendMessage true "phone,type"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /base/sendMessage [post]
+func SendMessage(c *gin.Context) {
+ var (
+ err error
+ params request.SendMessage
+ )
+ _ = c.ShouldBindJSON(¶ms)
+ if err = utils.Verify(params, utils.SendMessageVerity); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ //校验手机号格式
+ if ok, _ := regexp.MatchString(utils.RegPhoneNumber, params.Phone); !ok {
+ response.FailWithMessage("手机号码格式不合法", c)
+ return
+ }
+ if err = utils.SendSms(params.Phone, params.CountryCode, params.Type); err != nil {
+ response.FailWithMessage("发送失败,"+err.Error(), c)
+ return
+ }
+ response.OkWithMessage("发送成功", c)
+}
+
+// SendMessage
+// @Tags tools
+// @Summary 发送邮件验证码[v1.0.0]
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body request.SendEmail true "phone,type"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /base/sendEmail [post]
+func SendEmail(c *gin.Context) {
+ var (
+ err error
+ params request.SendEmail
+ code string
+ )
+ _ = c.ShouldBindJSON(¶ms)
+ if err = utils.Verify(params, utils.SendEmailVerify); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ //校验邮箱格式
+ if ok, _ := regexp.MatchString(utils.RegEmailNumber, params.Email); !ok {
+ response.FailWithMessage("邮箱格式不合法", c)
+ return
+ }
+ if code, err = utils.SendEmail(params.Email, "1"); err != nil {
+ response.FailWithMessage("发送失败,"+err.Error(), c)
+ return
+ }
+ _ = service.RedisSet("email_code:"+params.Email, code, 5*time.Minute)
+ response.OkWithMessage("发送成功", c)
+}
diff --git a/api/influencer/user.go b/api/influencer/user.go
new file mode 100644
index 0000000..f83806a
--- /dev/null
+++ b/api/influencer/user.go
@@ -0,0 +1,356 @@
+package influencer
+
+import (
+ "fmt"
+ "regexp"
+ "time"
+
+ "pure/api/sys"
+ "pure/global"
+ "pure/middleware"
+ "pure/model"
+ "pure/model/request"
+ "pure/model/response"
+ "pure/service"
+
+ "pure/utils"
+
+ "github.com/dgrijalva/jwt-go"
+ "github.com/gin-gonic/gin"
+ "github.com/go-redis/redis"
+ "go.uber.org/zap"
+)
+
+// Login
+// @Summary 登录[v1.0.0]
+// @Security Bearer
+// @Description
+// @Tags auth
+// @Param data body request.UserLogin true "email,password..."
+// @Success 200 {string} string "{"code": 0, "data": [...]}"
+// @Success 200 {string} string "{"code": 1, "message": ""}"
+// @Router /influencer/base/login [post]
+func LoginInfluencer(c *gin.Context) {
+ var (
+ err error
+ l request.UserLogin
+ user *model.User
+ )
+ _ = c.ShouldBindJSON(&l)
+ if err := utils.Verify(l, utils.LoginVerify); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ if l.Type == "1" {
+ if err := utils.Verify(l, utils.LoginPhoneVerify); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ //校验手机号格式
+ if ok, _ := regexp.MatchString(utils.RegPhoneNumber, l.Phone); !ok {
+ response.FailWithMessage("手机号码格式不合法", c)
+ return
+ }
+ if l.CountryCode == "" {
+ l.CountryCode = "86"
+ }
+ } else if l.Type == "2" {
+ if err := utils.Verify(l, utils.LoginEmailVerify); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ //校验邮箱格式
+ if ok, _ := regexp.MatchString(utils.RegEmailNumber, l.Email); !ok {
+ response.FailWithMessage("邮箱格式不合法", c)
+ return
+ }
+ } else {
+ response.FailWithMessage("登录类型不合法", c)
+ return
+ }
+ if err, user = service.UserLogin(&l); err != nil {
+ global.MG_LOG.Error("Login failed! The user name does not exist or the password is wrong!", zap.Any("err", err))
+ fmt.Println(err)
+ response.FailWithMessage("The user name does not exist or the password is wrong", c)
+ return
+ }
+ // if user.IDForbidden {
+ // response.OkWithDetailed(map[string]interface{}{"id_forbidden": user.IDForbidden, "forbidden_time": user.ForbiddenTime.Unix(), "forbidden_reason": user.ForbiddenReason}, "The user forbidden", c)
+ // return
+ // }
+ tokenNext(c, *user)
+}
+
+// Register
+// @Summary 注册[v1.0.0]
+// @Security Bearer
+// @Description
+// @Tags auth
+// @Param data body request.UserRegister true "email,password..."
+// @Success 200 {string} string "{"code": 0, "data": "注册成功"}"
+// @Success 200 {string} string "{"code": 1, "message": ""}"
+// @Router /influencer/base/register [post]
+func Register(c *gin.Context) {
+ var (
+ err error
+ l request.UserRegister
+ user *model.User
+ )
+ _ = c.ShouldBindJSON(&l)
+ if err := utils.Verify(l, utils.RegisterVerify); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ //校验邮箱格式
+ if ok, _ := regexp.MatchString(utils.RegEmailNumber, l.Email); !ok {
+ response.FailWithMessage("邮箱格式不合法", c)
+ return
+ }
+ if l.CountryCode == "" {
+ l.CountryCode = "86"
+ }
+ if err, user = service.UserRegister(&l); err != nil {
+ global.MG_LOG.Error("Register failed!", zap.Any("err", err))
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ tokenNext(c, *user)
+}
+
+// 登录以后签发jwt
+func tokenNext(c *gin.Context, user model.User) {
+ j := &middleware.JWT{SigningKey: []byte(global.MG_CONFIG.JWT.SigningKey)} // 唯一签名
+ claims := request.UserClaims{
+ UUID: user.UUID.String(),
+ NickName: user.NickName,
+ Email: user.Email,
+ Appid: user.Appid,
+ Type: user.Type,
+ IDForbidden: user.IDForbidden,
+ BufferTime: global.MG_CONFIG.JWT.BufferTime, // 缓冲时间1天 缓冲时间内会获得新的token刷新令牌 此时一个用户会存在两个有效令牌 但是前端只留一个 另一个会丢失
+ StandardClaims: jwt.StandardClaims{
+ NotBefore: time.Now().Unix() - 1000, // 签名生效时间
+ ExpiresAt: time.Now().Unix() + global.MG_CONFIG.JWT.ExpiresTime, // 过期时间 7天 配置文件
+ Issuer: "qmPlus", // 签名的发行者
+ },
+ }
+ token, err := j.CreateToken(claims)
+ if err != nil {
+ global.MG_LOG.Error("get token field!", zap.Any("err", err))
+ response.FailWithMessage("get token field", c)
+ return
+ }
+ if global.MG_CONFIG.System.UseMultipoint {
+ err, jwtStr := service.GetRedisJWT(user.Username)
+ if err == redis.Nil {
+ if err := service.SetRedisJWT(token, user.Username); err != nil {
+ global.MG_LOG.Error("set token failed!", zap.Any("err", err))
+ response.FailWithMessage("set token failed", c)
+ return
+ }
+ } else if err != nil {
+ global.MG_LOG.Error("get token failed!", zap.Any("err", err))
+ response.FailWithMessage("get token failed", c)
+ return
+ } else {
+ if err := service.JsonInBlacklist(model.JwtBlacklist{Jwt: jwtStr}); err != nil {
+ global.MG_LOG.Error("jwt作废失败!", zap.Any("err", err))
+ response.FailWithMessage("jwt作废失败", c)
+ return
+ }
+ if err := service.SetRedisJWT(token, user.Username); err != nil {
+ global.MG_LOG.Error("设置登录状态失败!", zap.Any("err", err))
+ response.FailWithMessage("设置登录状态失败", c)
+ return
+ }
+ }
+ }
+ // if !global.MG_CONFIG.System.UseMultipoint {
+ response.OkWithDetailed(response.LoginResponse{
+ User: user,
+ Token: token,
+ ExpiresAt: claims.StandardClaims.ExpiresAt * 1000,
+ }, "success", c)
+}
+
+// @Summary 获取用户基本信息[v1.0.0]
+// @Security Bearer
+// @Description
+// @Tags 网红端-用户
+// @Success 200 {object} model.UserSimple "{"code": 0, "data": [...]}"
+// @Success 200 {string} string "{"code": 1, "message": ""}"
+// @Router /influencer/user/detail [get]
+func GetUserDetail(c *gin.Context) {
+ var (
+ err error
+ userID string
+ data interface{}
+ )
+ userID = sys.GetUserUuid(c)
+ err, data = service.GetUserDetail(userID)
+ if err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ response.OkWithData(data, c)
+}
+
+// @Summary 修改用户基本信息
+// @Security Bearer
+// @Description
+// @Tags 网红端-用户
+// @Param data body request.UserDetail false "data..."
+// @Success 200 {string} string "{"code": 0, "data": [...]}"
+// @Success 200 {string} string "{"code": 1, "message": ""}"
+// @Router /influencer/user/detail [put]
+func UpdateUserDetail(c *gin.Context) {
+ var (
+ err error
+ userID string
+ data request.UserDetail
+ )
+ err = c.ShouldBindJSON(&data)
+ if err != nil {
+ fmt.Println(err)
+ }
+ userID = sys.GetUserUuid(c)
+ err = service.UpdateUserDetail(userID, &data)
+ if err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ response.OkWithMessage("修改成功", c)
+}
+
+// BandPhone
+// @Summary 网红绑定手机[v1.0.0]
+// @Security Bearer
+// @Description
+// @Tags 网红端-用户
+// @Param data body request.UserBandPhone true "email,password..."
+// @Success 200 {string} string "{"code": 0, "data": "绑定成功"}"
+// @Success 200 {string} string "{"code": 1, "message": ""}"
+// @Router /influencer/user/bandPhone [post]
+func BandPhone(c *gin.Context) {
+ var (
+ err error
+ l request.UserBandPhone
+ userID string
+ )
+ _ = c.ShouldBindJSON(&l)
+ if err := utils.Verify(l, utils.BandPhoneVerify); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ userID = sys.GetUserUuid(c)
+ if err = service.UserBandPhone(&l, sys.GetUserAppid(c), userID); err != nil {
+ global.MG_LOG.Error("BandPhone failed!", zap.Any("err", err))
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ response.OkWithMessage("绑定成功", c)
+}
+
+// PlatformAuth
+// @Summary 平台认证[v1.0.0]
+// @Security Bearer
+// @Description
+// @Tags 网红端-用户
+// @Param data body request.UserPlatformAuth true "email,password..."
+// @Success 200 {string} string "{"code": 0, "data": "绑定成功"}"
+// @Success 200 {string} string "{"code": 1, "message": ""}"
+// @Router /influencer/user/platformAuth [post]
+func PlatformAuth(c *gin.Context) {
+ var (
+ err error
+ l request.UserPlatformAuth
+ userID string
+ )
+ err = c.ShouldBindJSON(&l)
+ if err != nil {
+ fmt.Println(err)
+ }
+ if err := utils.Verify(l, utils.PlatformAuthVerify); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ userID = sys.GetUserUuid(c)
+ if err = service.UserPlatformAuth(&l, userID); err != nil {
+ global.MG_LOG.Error("PlatformAuth failed!", zap.Any("err", err))
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ response.OkWithMessage("提交成功", c)
+}
+
+// PlatformAuth
+// @Summary 授权登录[v1.0.0]
+// @Security Bearer
+// @Description
+// @Tags auth
+// @Param data body request.UserAuthorized true "email,password..."
+// @Success 200 {string} string "{"code": 0, "data": "绑定成功"}"
+// @Success 200 {string} string "{"code": 1, "message": ""}"
+// @Router /base/authorized [post]
+func Authorized(c *gin.Context) {
+ var (
+ err error
+ l request.UserAuthorized
+ user model.User
+ )
+ _ = c.ShouldBindJSON(&l)
+ if user, err = service.UserAuthorized(&l); err != nil {
+ global.MG_LOG.Error("Authorized failed!", zap.Any("err", err))
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ tokenNext(c, user)
+}
+
+// @Summary 获取用户统计信息[v1.0.0]
+// @Security Bearer
+// @Description
+// @Tags 网红端-用户
+// @Success 200 {object} response.UserStatistics "{"code": 0, "data": [...]}"
+// @Router /influencer/user/statistics [get]
+func GetUserStatistics(c *gin.Context) {
+ var (
+ err error
+ userID string
+ data interface{}
+ )
+ userID = sys.GetUserUuid(c)
+ err, data = service.GetUserStatistics(userID)
+ if err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ response.OkWithData(data, c)
+}
+
+// @Summary 注销账户[v1.0.1]
+// @Security Bearer
+// @Description
+// @Tags 网红端-用户
+// @Success 200 {string} string "{"code": 0, "data": "注销成功"}"
+// @Router /influencer/user/logoff [post]
+func UserLogOff(c *gin.Context) {
+ var (
+ err error
+ userID string
+ )
+ userID = sys.GetUserUuid(c)
+ err = service.UserLogOff(userID)
+ if err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ //token加入黑名单
+ token := c.Request.Header.Get("x-token")
+ if err := service.JsonInBlacklist(model.JwtBlacklist{Jwt: token}); err != nil {
+ global.MG_LOG.Error("jwt作废失败!", zap.Any("err", err))
+ response.FailWithMessage("jwt作废失败", c)
+ return
+ }
+ response.OkWithMessage("注销成功", c)
+}
diff --git a/api/influencer/wallet.go b/api/influencer/wallet.go
new file mode 100644
index 0000000..515f12d
--- /dev/null
+++ b/api/influencer/wallet.go
@@ -0,0 +1,347 @@
+package influencer
+
+import (
+ "pure/api/sys"
+ "pure/dto"
+ "pure/model"
+ "pure/model/request"
+ "pure/model/response"
+ "pure/service"
+ "pure/utils"
+
+ "github.com/gin-gonic/gin"
+)
+
+// @Summary 钱包基本信息
+// @Security Bearer
+// @Description
+// @Tags 网红端-用户钱包
+// @Success 200 {object} model.Wallet "{"code": 0, "data": [...]}"
+// @Success 201 {string} string "{"code": 1, "message": ""}"
+// @Router /influencer/wallet/detail [get]
+func GetUserWalletDetail(c *gin.Context) {
+ var (
+ err error
+ userID string
+ data interface{}
+ )
+ userID = sys.GetUserUuid(c)
+ err, data = service.GetUserWalletDetail(userID)
+ if err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ response.OkWithData(data, c)
+}
+
+// @Summary 获取账户列表
+// @Security Bearer
+// @Description
+// @Tags 网红端-用户钱包
+// @Success 200 {object} []model.Account "{"code": 0, "data": [...]}"
+// @Success 201 {string} string "{"code": 1, "message": ""}"
+// @Router /influencer/wallet/accountList [get]
+func GetUserAccountList(c *gin.Context) {
+ var (
+ err error
+ userID string
+ result []model.Account
+ )
+ userID = sys.GetUserUuid(c)
+ result, err = service.GetAccountList(userID)
+ if err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ response.OkWithData(result, c)
+}
+
+// @Summary 添加账户
+// @Security Bearer
+// @Description
+// @Tags 网红端-用户钱包
+// @Param data body request.AddAccount false "data..."
+// @Success 200 {string} string "{"code": 0, "data": [...]}"
+// @Success 201 {string} string "{"code": 1, "message": ""}"
+// @Router /influencer/wallet/account [post]
+func AddUserAccount(c *gin.Context) {
+ var (
+ err error
+ userID string
+ params request.AddAccount
+ )
+ _ = c.ShouldBindJSON(¶ms)
+ userID = sys.GetUserUuid(c)
+ if err = service.AddAccount(userID, ¶ms); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ response.OkWithMessage("绑定成功", c)
+}
+
+// @Summary 设置账户默认开关
+// @Security Bearer
+// @Description
+// @Tags 网红端-用户钱包
+// @Param data body request.IdReq false "data..."
+// @Success 200 {string} string "{"code": 0, "data": [...]}"
+// @Success 201 {string} string "{"code": 1, "message": ""}"
+// @Router /influencer/wallet/account/default [put]
+func UpdateAccountIsDefault(c *gin.Context) {
+ var (
+ err error
+ params request.IdReq
+ )
+ _ = c.ShouldBindJSON(¶ms)
+ if err = utils.Verify(params, utils.IdVerify); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ userId := sys.GetUserUuid(c)
+ err = service.UpdateAccountIsDefault(userId, ¶ms)
+ if err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ response.OkWithMessage("设置成功", c)
+}
+
+// @Summary 解绑账户
+// @Security Bearer
+// @Description
+// @Tags 网红端-用户钱包
+// @Param data body request.DeleteAccount false "data..."
+// @Success 200 {string} string "{"code": 0, "data": [...]}"
+// @Success 201 {string} string "{"code": 1, "message": ""}"
+// @Router /influencer/wallet/account [delete]
+func DeleteUserAccount(c *gin.Context) {
+ var (
+ err error
+ userID string
+ params request.DeleteAccount
+ )
+ _ = c.ShouldBindJSON(¶ms)
+ if err = utils.Verify(params, utils.IdVerify); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ userID = sys.GetUserUuid(c)
+ err = service.DeleteAccount(userID, ¶ms)
+ if err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ response.OkWithMessage("解绑成功", c)
+}
+
+func GetUserCommissionList(c *gin.Context) {
+ var (
+ err error
+ userID string
+ list interface{}
+ total int64
+ data request.SearchCommission
+ )
+ c.ShouldBindQuery(&data)
+ userID = sys.GetUserUuid(c)
+ err, list, total = service.GetUserCommissionList(userID, &data)
+ if err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ response.OkWithDetailed(response.PageResult{
+ List: list,
+ Total: total,
+ Page: data.Page,
+ PageSize: data.PageSize,
+ }, "获取成功", c)
+}
+
+func GetUserWithdrawalList(c *gin.Context) {
+ var (
+ err error
+ userID string
+ list interface{}
+ total int64
+ data request.SearchWithdrawal
+ )
+ c.ShouldBindQuery(&data)
+ userID = sys.GetUserUuid(c)
+ err, list, total = service.GetUserWithdrawalList(userID, &data)
+ if err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ response.OkWithDetailed(response.PageResult{
+ List: list,
+ Total: total,
+ Page: data.Page,
+ PageSize: data.PageSize,
+ }, "获取成功", c)
+}
+
+// @Summary 提现
+// @Security Bearer
+// @Description
+// @Tags 网红端-用户钱包
+// @Param data body request.WithdrawalParams false "data..."
+// @Success 200 {object} model.WithdrawalView "{"code": 0, "data": [...]}"
+// @Success 200 {string} string "{"code": 1, "message": ""}"
+// @Router /influencer/wallet/withdrawal [post]
+func UserWithdrawal(c *gin.Context) {
+ var (
+ err error
+ params request.WithdrawalParams
+ resp model.WithdrawalView
+ )
+ _ = c.ShouldBindJSON(¶ms)
+ if err = utils.Verify(params, utils.WithdrawalVerity); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ userId := sys.GetUserUuid(c)
+ err, resp = service.Withdrawal(userId, ¶ms)
+ if err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ response.OkWithDataMessage(resp, "提现成功", c)
+}
+
+// @Summary 获取对账中心数据
+// @Security Bearer
+// @Description
+// @Tags 对账中心
+// @Param data query request.GetBillDataParams false "data..."
+// @Success 200 {object} dto.BillData "{"code": 0, "data": [...]}"
+// @Success 201 {string} string "{"code": 1, "message": ""}"
+// @Router /influencer/wallet/bill/data [get]
+func GetUserBillData(c *gin.Context) {
+ var (
+ err error
+ params request.GetBillDataParams
+ result dto.BillData
+ )
+ _ = c.ShouldBindQuery(¶ms)
+ userId := sys.GetUserUuid(c)
+ result, err = service.GetBillData(userId, ¶ms)
+ if err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ response.OkWithDataMessage(result, "获取成功", c)
+}
+
+// @Summary 获取资金流水记录
+// @Security Bearer
+// @Description
+// @Tags 对账中心
+// @Param data query request.SearchBillParams false "data..."
+// @Success 200 {object} []model.Bill "{"code": 0, "data": [...]}"
+// @Success 201 {string} string "{"code": 1, "message": ""}"
+// @Router /influencer/wallet/bill-list [get]
+func GetBillList(c *gin.Context) {
+ var (
+ err error
+ params request.SearchBillParams
+ result []model.Bill
+ )
+ _ = c.ShouldBindQuery(¶ms)
+ if err = utils.Verify(params, utils.BillListVerity); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ userId := sys.GetUserUuid(c)
+ if result, err = service.GetBillList(userId, ¶ms); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ response.OkWithDetailed(response.PageResult{
+ List: result,
+ Page: params.Page,
+ PageSize: params.PageSize,
+ }, "获取成功", c)
+}
+
+// @Summary 获取账单通知列表
+// @Security Bearer
+// @Description
+// @Tags 对账中心
+// @Success 200 {object} []model.BillNotify "{"code": 0, "data": [...]}"
+// @Success 201 {string} string "{"code": 1, "message": ""}"
+// @Router /influencer/wallet/bill-notify [get]
+func GetBillNotifyList(c *gin.Context) {
+ var (
+ err error
+ params request.SearchNotify
+ result []model.Notify
+ )
+ userId := sys.GetUserUuid(c)
+ params.Page = 1
+ params.PageSize = 5
+ params.RelationType = "1"
+ if result, _, err = service.GetNotifyList(userId, ¶ms); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ response.OkWithDataMessage(result, "获取成功", c)
+}
+
+// @Summary 获取提现详情
+// @Security Bearer
+// @Description
+// @Tags 对账中心
+// @Param data query request.FlowNoParam false "data..."
+// @Success 200 {object} model.Withdrawal "{"code": 0, "data": [...]}"
+// @Success 201 {string} string "{"code": 1, "message": ""}"
+// @Router /influencer/wallet/withdrawal [get]
+func GetWithdrawal(c *gin.Context) {
+ var (
+ err error
+ params request.FlowNoParam
+ result model.Withdrawal
+ )
+ _ = c.ShouldBindQuery(¶ms)
+ if err = utils.Verify(params, utils.FlowNoVerity); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ userId := sys.GetUserUuid(c)
+ err, result = service.GetWithdrawal(userId, ¶ms)
+ if err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ response.OkWithData(result, c)
+}
+
+// @Summary 获取提现记录
+// @Security Bearer
+// @Description
+// @Tags 对账中心
+// @Param data query request.PageInfo false "data..."
+// @Success 200 {object} []model.Withdrawal "{"code": 0, "data": [...]}"
+// @Success 201 {string} string "{"code": 1, "message": ""}"
+// @Router /influencer/wallet/withdrawal-list [get]
+func GetWithdrawalList(c *gin.Context) {
+ var (
+ err error
+ params request.PageInfo
+ result []model.Withdrawal
+ )
+ _ = c.ShouldBindQuery(¶ms)
+ if err = utils.Verify(params, utils.PageInfoVerify); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ userId := sys.GetUserUuid(c)
+ if err, result = service.GetWithdrawalList(userId, ¶ms); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ response.OkWithDetailed(response.PageResult{
+ List: result,
+ Page: params.Page,
+ PageSize: params.PageSize,
+ }, "获取成功", c)
+}
diff --git a/api/sys/sys_brochure.go b/api/sys/sys_brochure.go
new file mode 100644
index 0000000..67771fd
--- /dev/null
+++ b/api/sys/sys_brochure.go
@@ -0,0 +1,42 @@
+package sys
+
+import (
+ "github.com/gin-gonic/gin"
+ "go.uber.org/zap"
+ "pure/global"
+ "pure/model/request"
+ "pure/model/response"
+ "pure/service"
+ "pure/utils"
+)
+
+// GetSysBrochure
+// @Summary 隐私协议单页
+// @Tags tools
+// @Param data query request.SysBrochureType false "params"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":""}"
+// @Router /customer/base/brochure [get]
+func GetSysBrochure(c *gin.Context) {
+ var info request.SysBrochureType
+ _ = c.ShouldBindQuery(&info)
+ if err := utils.Verify(info, utils.TypeVerify); err != nil {
+ response.FailWithMessage(err.Error(), c)
+ return
+ }
+ if err, data := service.GetSysBrochure(info.Type); err != nil {
+ global.MG_LOG.Error("获取失败!", zap.Any("err", err))
+ response.FailWithMessage("获取失败", c)
+ } else {
+ response.OkWithDetailed(data.Content, "获取成功", c)
+ }
+}
+
+// GetSysBrochure2
+// @Summary 隐私协议单页
+// @Tags tools
+// @Param data query request.SysBrochureType false "params"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":""}"
+// @Router /influencer/base/brochure [get]
+func GetSysBrochure2(c *gin.Context) {
+
+}
diff --git a/api/sys/sys_user.go b/api/sys/sys_user.go
new file mode 100644
index 0000000..4ce80fe
--- /dev/null
+++ b/api/sys/sys_user.go
@@ -0,0 +1,50 @@
+package sys
+
+import (
+ "pure/global"
+ "pure/model/request"
+
+ "github.com/gin-gonic/gin"
+)
+
+// 从Gin的Context中获取从jwt解析出来的用户UUID
+func GetUserUuid(c *gin.Context) string {
+ if claims, exists := c.Get("claims"); !exists {
+ global.MG_LOG.Error("从Gin的Context中获取从jwt解析出来的用户UUID失败, 请检查路由是否使用jwt中间件!")
+ return ""
+ } else {
+ waitUse := claims.(*request.UserClaims)
+ return waitUse.UUID
+ }
+}
+
+// 从Gin的Context中获取从jwt解析出来的用户账号
+func GetUserName(c *gin.Context) string {
+ if claims, exists := c.Get("claims"); !exists {
+ global.MG_LOG.Error("从Gin的Context中获取从jwt解析出来的用户UUID失败, 请检查路由是否使用jwt中间件!")
+ return ""
+ } else {
+ waitUse := claims.(*request.UserClaims)
+ return waitUse.Username
+ }
+}
+
+func GetUserAppid(c *gin.Context) string {
+ if claims, exists := c.Get("claims"); !exists {
+ global.MG_LOG.Error("从Gin的Context中获取从jwt解析出来的用户UUID失败, 请检查路由是否使用jwt中间件!")
+ return ""
+ } else {
+ waitUse := claims.(*request.UserClaims)
+ return waitUse.Appid
+ }
+}
+
+func getUserInfo(c *gin.Context) *request.UserClaims {
+ if claims, exists := c.Get("claims"); !exists {
+ global.MG_LOG.Error("从Gin的Context中获取从jwt解析出来的用户UUID失败, 请检查路由是否使用jwt中间件!")
+ return nil
+ } else {
+ waitUse := claims.(*request.UserClaims)
+ return waitUse
+ }
+}
diff --git a/api/sys/version.go b/api/sys/version.go
new file mode 100644
index 0000000..f5baf77
--- /dev/null
+++ b/api/sys/version.go
@@ -0,0 +1,30 @@
+package sys
+
+import (
+ "github.com/gin-gonic/gin"
+ "pure/model"
+ "pure/model/response"
+ "pure/service"
+)
+
+// @Summary 获取版本信息
+// @Security Bearer
+// @Description
+// @Tags version
+// @Success 200 {string} string "{"code": 0, "data": [...]}"
+// @Success 201 {string} string "{"code": 1, "message": ""}"
+// @Router /influencer/base/version [get]
+func GetVersion(c *gin.Context) {
+ var (
+ err error
+ result model.VersionV
+ )
+ platform := c.GetString("platform")
+ version := c.GetString("version")
+ result, err = service.CheckVersion(platform, version)
+ if err != nil {
+ response.FailWithMessage(err.Error(), c)
+ } else {
+ response.OkWithData(result, c)
+ }
+}
diff --git a/config-prod.yaml b/config-prod.yaml
new file mode 100644
index 0000000..a470538
--- /dev/null
+++ b/config-prod.yaml
@@ -0,0 +1,122 @@
+
+autocode:
+ transfer-restart: true
+ root: /Users/holi/Downloads/go-workspace/nft-admin
+ server: /server
+ server-api: /api/sys
+ server-initialize: /initialize
+ server-model: /model
+ server-request: /model/request/
+ server-router: /router
+ server-service: /service
+ web: /web/src
+ web-api: /api
+ web-form: /view
+ web-table: /view
+ web-flow: /view
+captcha:
+ key-long: 6
+ img-width: 240
+ img-height: 80
+casbin:
+ model-path: ./resource/rbac_model.conf
+email:
+ to: xxx@qq.com
+ port: 465
+ from: xxx@163.com
+ host: smtp.163.com
+ is-ssl: true
+ secret: xxx
+ nickname: test
+excel:
+ dir: ./resource/excel/
+jwt:
+ signing-key: wqrefsad
+ expires-time: 604800
+ buffer-time: 86400
+local:
+ path: uploads/file
+mysql:
+ path: 172.16.0.26:3306
+ config: charset=utf8mb4&parseTime=True&loc=Local
+ db-name: bkb-prod
+ username: bkbrd
+ password: yJGQ3hlV#*4nTJrn
+ max-idle-conns: 10
+ max-open-conns: 100
+ log-mode: info
+ log-zap: ""
+minio:
+ endpoint: file.mangguonews.com
+ access-key-id: minio
+ secret-access-key: minio123
+ use-ssl: false
+redis:
+ db: 2
+# addr: 172.16.0.239:6379
+# password: bkbrd:!Fgcye*HGs*Z&q0p
+ addr: redis-6715eafa-8e3f-4014-9659-ac647bd1ef46.cn-north-4.dcs.myhuaweicloud.com:6379
+ password: rMof*kkr!mfO7MHW
+
+system:
+ env: prod
+ addr: 8001
+ db-type: mysql
+ oss-type: local
+ use-multipoint: false
+
+timer:
+ start: true
+ spec: '@daily'
+ detail:
+ - tableName: sys_operation_records
+ compareField: created_at
+ interval: 2160h
+zap:
+ level: warn
+ format: console
+ prefix: '[NFT-ADMIN]'
+ director: log
+ link-name: nft.log
+ showLine: true
+ encode-level: LowercaseColorLevelEncoder
+ stacktrace-key: stacktrace
+ log-in-console: true
+
+jpush:
+ appkey: d7e557b47f34c5214e70b02f
+ secret: 036c179ba0f7c43c1e199c91
+ all-user-sign: fm_all_users
+ android-intent: intent:#Intent;component=com.mg.news.dev/com.mango.hnxwlb.ui930.Main930Activity;S.extras=%v;end
+
+# qiniu configuration (请自行七牛申请对应的 公钥 私钥 bucket 和 域名地址)
+qiniu:
+ zone: 'ZoneHuabei'
+ bucket: ff-file-test
+ img-path: http://qny-ff-file-test.mangguonews.com
+ use-https: false
+ access-key: Maeg1k1PuMo2wJSidAJ-6sSPZquxEbGQuRJvl_Vr
+ secret-key: gEwHt01k5Pnsk75ad8w4OFZr2kYC6YmoWNITIB1_
+ use-cdn-domains: true
+
+paypal:
+ env: SandBox
+ client-id: Af7cbDvcc0qBEZDWgGU3ATZFJePJnFl-UH6foaGzmOu6w_8l1ewZRv88CO39HA0X_ATSR-TP_ZvM_t55
+ secret: EFsM94NOvKscr6J-U18rtVp0AIZXlrqWwjXP-vqnNXQ8s2c9TpLQo2hFuf0gYUJg4pjPonqCD4T7nrdW
+ return-url:
+ cancel-url:
+ order-back: 15
+ order-confirm: 1
+
+tools:
+# customer-url: http://120.55.164.69:30204
+ customer-url: https://h5-dev.bkbackground.com
+
+dysmsapi:
+ accessSecret: ZAnicsJ4biuCbgpNnqQbYU34FhTmn3&
+ accessKeyID: LTAI5tLzNwMrdZUhdKpm9wor
+ signName: 一个地球
+ templateCode1: SMS_257761932
+ templateCode2: SMS_257742075
+ templateCode3: SMS_257742078
+ templateCode4: SMS_257767780
\ No newline at end of file
diff --git a/config.yaml b/config.yaml
new file mode 100644
index 0000000..9ec157f
--- /dev/null
+++ b/config.yaml
@@ -0,0 +1,122 @@
+
+autocode:
+ transfer-restart: true
+ root: /Users/holi/Downloads/go-workspace/nft-admin
+ server: /server
+ server-api: /api/sys
+ server-initialize: /initialize
+ server-model: /model
+ server-request: /model/request/
+ server-router: /router
+ server-service: /service
+ web: /web/src
+ web-api: /api
+ web-form: /view
+ web-table: /view
+ web-flow: /view
+captcha:
+ key-long: 6
+ img-width: 240
+ img-height: 80
+casbin:
+ model-path: ./resource/rbac_model.conf
+email:
+ to: xxx@qq.com
+ port: 465
+ from: xxx@163.com
+ host: smtp.163.com
+ is-ssl: true
+ secret: xxx
+ nickname: test
+excel:
+ dir: ./resource/excel/
+jwt:
+ signing-key: wqrefsad
+ expires-time: 604800
+ buffer-time: 86400
+local:
+ path: uploads/file
+mysql:
+ path: 172.16.0.26:3306
+ config: charset=utf8mb4&parseTime=True&loc=Local
+ db-name: bkb
+ username: bkbrd
+ password: yJGQ3hlV#*4nTJrn
+ max-idle-conns: 10
+ max-open-conns: 100
+ log-mode: info
+ log-zap: ""
+minio:
+ endpoint: file.mangguonews.com
+ access-key-id: minio
+ secret-access-key: minio123
+ use-ssl: false
+redis:
+ db: 1
+# addr: 172.16.0.239:6379
+# password: bkbrd:!Fgcye*HGs*Z&q0p
+ addr: redis-6715eafa-8e3f-4014-9659-ac647bd1ef46.cn-north-4.dcs.myhuaweicloud.com:6379
+ password: rMof*kkr!mfO7MHW
+
+system:
+ env: develop
+ addr: 8001
+ db-type: mysql
+ oss-type: local
+ use-multipoint: false
+
+timer:
+ start: true
+ spec: '@daily'
+ detail:
+ - tableName: sys_operation_records
+ compareField: created_at
+ interval: 2160h
+zap:
+ level: warn
+ format: console
+ prefix: '[NFT-ADMIN]'
+ director: log
+ link-name: nft.log
+ showLine: true
+ encode-level: LowercaseColorLevelEncoder
+ stacktrace-key: stacktrace
+ log-in-console: true
+
+jpush:
+ appkey: d7e557b47f34c5214e70b02f
+ secret: 036c179ba0f7c43c1e199c91
+ all-user-sign: fm_all_users
+ android-intent: intent:#Intent;component=com.mg.news.dev/com.mango.hnxwlb.ui930.Main930Activity;S.extras=%v;end
+
+# qiniu configuration (请自行七牛申请对应的 公钥 私钥 bucket 和 域名地址)
+qiniu:
+ zone: 'ZoneHuabei'
+ bucket: ff-file-test
+ img-path: http://qny-ff-file-test.mangguonews.com
+ use-https: false
+ access-key: Maeg1k1PuMo2wJSidAJ-6sSPZquxEbGQuRJvl_Vr
+ secret-key: gEwHt01k5Pnsk75ad8w4OFZr2kYC6YmoWNITIB1_
+ use-cdn-domains: true
+
+paypal:
+ env: SandBox
+ client-id: Af7cbDvcc0qBEZDWgGU3ATZFJePJnFl-UH6foaGzmOu6w_8l1ewZRv88CO39HA0X_ATSR-TP_ZvM_t55
+ secret: EFsM94NOvKscr6J-U18rtVp0AIZXlrqWwjXP-vqnNXQ8s2c9TpLQo2hFuf0gYUJg4pjPonqCD4T7nrdW
+ return-url:
+ cancel-url:
+ order-back: 15
+ order-confirm: 1
+
+tools:
+# customer-url: http://120.55.164.69:30204
+ customer-url: https://h5-dev.bkbackground.com
+
+dysmsapi:
+ accessSecret: ZAnicsJ4biuCbgpNnqQbYU34FhTmn3&
+ accessKeyID: LTAI5tLzNwMrdZUhdKpm9wor
+ signName: 一个地球
+ templateCode1: SMS_257761932
+ templateCode2: SMS_257742075
+ templateCode3: SMS_257742078
+ templateCode4: SMS_257767780
\ No newline at end of file
diff --git a/config/auto_code.go b/config/auto_code.go
new file mode 100644
index 0000000..d912156
--- /dev/null
+++ b/config/auto_code.go
@@ -0,0 +1 @@
+package config
diff --git a/config/captcha.go b/config/captcha.go
new file mode 100644
index 0000000..af329bf
--- /dev/null
+++ b/config/captcha.go
@@ -0,0 +1,7 @@
+package config
+
+type Captcha struct {
+ KeyLong int `mapstructure:"key-long" json:"keyLong" yaml:"key-long"` // 验证码长度
+ ImgWidth int `mapstructure:"img-width" json:"imgWidth" yaml:"img-width"` // 验证码宽度
+ ImgHeight int `mapstructure:"img-height" json:"imgHeight" yaml:"img-height"` // 验证码高度
+}
diff --git a/config/casbin.go b/config/casbin.go
new file mode 100644
index 0000000..1b32f2b
--- /dev/null
+++ b/config/casbin.go
@@ -0,0 +1,5 @@
+package config
+
+type Casbin struct {
+ ModelPath string `mapstructure:"model-path" json:"modelPath" yaml:"model-path"` // 存放casbin模型的相对路径
+}
diff --git a/config/config.go b/config/config.go
new file mode 100644
index 0000000..5e977bf
--- /dev/null
+++ b/config/config.go
@@ -0,0 +1,23 @@
+package config
+
+type Server struct {
+ JWT JWT `mapstructure:"jwt" json:"jwt" yaml:"jwt"`
+ Zap Zap `mapstructure:"zap" json:"zap" yaml:"zap"`
+ Redis Redis `mapstructure:"redis" json:"redis" yaml:"redis"`
+ Email Email `mapstructure:"email" json:"email" yaml:"email"`
+ Casbin Casbin `mapstructure:"casbin" json:"casbin" yaml:"casbin"`
+ System System `mapstructure:"system" json:"system" yaml:"system"`
+ // gorm
+ Mysql Mysql `mapstructure:"mysql" json:"mysql" yaml:"mysql"`
+ GormSettings GormSettings `mapstructure:"gorm-settings" json:"gormSettings" yaml:"gorm-settings"`
+ // oss
+ Local Local `mapstructure:"local" json:"local" yaml:"local"`
+ Qiniu Qiniu `mapstructure:"qiniu" json:"qiniu" yaml:"qiniu"`
+ AliyunOSS AliyunOSS `mapstructure:"aliyun-oss" json:"aliyunOSS" yaml:"aliyun-oss"`
+ TencentCOS TencentCOS `mapstructure:"tencent-cos" json:"tencentCOS" yaml:"tencent-cos"`
+ Timer Timer `mapstructure:"timer" json:"timer" yaml:"timer"`
+ JPush JPush `mapstructure:"jpush" json:"jpush" yaml:"jpush"`
+ Paypal Paypal `mapstructure:"paypal" json:"paypal" yaml:"paypal"`
+ Tools Tools `mapstructure:"tools" json:"tools" yaml:"tools"`
+ Dysmsapi Dysmsapi `mapstructure:"dysmsapi" json:"dysmsapi" yaml:"dysmsapi"`
+}
diff --git a/config/dysmsapi.go b/config/dysmsapi.go
new file mode 100644
index 0000000..e27449a
--- /dev/null
+++ b/config/dysmsapi.go
@@ -0,0 +1,11 @@
+package config
+
+type Dysmsapi struct {
+ AccessSecret string `mapstructure:"accessSecret" json:"accessSecret" yaml:"accessSecret"` //买家端h5域名地址
+ AccessKeyID string `mapstructure:"accessKeyID" json:"accessKeyID" yaml:"accessKeyID"` //买家端h5域名地址
+ SignName string `mapstructure:"signName" json:"signName" yaml:"signName"` //买家端h5域名地址
+ TemplateCode1 string `mapstructure:"templateCode1" json:"templateCode1" yaml:"templateCode1"` //买家端h5域名地址
+ TemplateCode2 string `mapstructure:"templateCode2" json:"templateCode2" yaml:"templateCode2"` //买家端h5域名地址
+ TemplateCode3 string `mapstructure:"templateCode3" json:"templateCode3" yaml:"templateCode3"` //买家端h5域名地址
+ TemplateCode4 string `mapstructure:"templateCode4" json:"templateCode4" yaml:"templateCode4"` //买家端h5域名地址
+}
diff --git a/config/email.go b/config/email.go
new file mode 100644
index 0000000..7a8676d
--- /dev/null
+++ b/config/email.go
@@ -0,0 +1,11 @@
+package config
+
+type Email struct {
+ To string `mapstructure:"to" json:"to" yaml:"to"` // 收件人:多个以英文逗号分隔
+ Port int `mapstructure:"port" json:"port" yaml:"port"` // 端口
+ From string `mapstructure:"from" json:"from" yaml:"from"` // 收件人
+ Host string `mapstructure:"host" json:"host" yaml:"host"` // 服务器地址
+ IsSSL bool `mapstructure:"is-ssl" json:"isSSL" yaml:"is-ssl"` // 是否SSL
+ Secret string `mapstructure:"secret" json:"secret" yaml:"secret"` // 密钥
+ Nickname string `mapstructure:"nickname" json:"nickname" yaml:"nickname"` // 昵称
+}
diff --git a/config/excel.go b/config/excel.go
new file mode 100644
index 0000000..f3921b0
--- /dev/null
+++ b/config/excel.go
@@ -0,0 +1,2 @@
+package config
+
diff --git a/config/gorm.go b/config/gorm.go
new file mode 100644
index 0000000..9466414
--- /dev/null
+++ b/config/gorm.go
@@ -0,0 +1,21 @@
+package config
+
+type Mysql struct {
+ Path string `mapstructure:"path" json:"path" yaml:"path"` // 服务器地址:端口
+ Config string `mapstructure:"config" json:"config" yaml:"config"` // 高级配置
+ Dbname string `mapstructure:"db-name" json:"dbname" yaml:"db-name"` // 数据库名
+ Username string `mapstructure:"username" json:"username" yaml:"username"` // 数据库用户名
+ Password string `mapstructure:"password" json:"password" yaml:"password"` // 数据库密码
+ MaxIdleConns int `mapstructure:"max-idle-conns" json:"maxIdleConns" yaml:"max-idle-conns"` // 空闲中的最大连接数
+ MaxOpenConns int `mapstructure:"max-open-conns" json:"maxOpenConns" yaml:"max-open-conns"` // 打开到数据库的最大连接数
+ LogMode string `mapstructure:"log-mode" json:"logMode" yaml:"log-mode"` // 是否开启Gorm全局日志
+ LogZap bool `mapstructure:"log-zap" json:"logZap" yaml:"log-zap"` // 是否通过zap写入日志文件
+}
+
+func (m *Mysql) Dsn() string {
+ return m.Username + ":" + m.Password + "@tcp(" + m.Path + ")/" + m.Dbname + "?" + m.Config
+}
+
+func (m *Mysql) GetLogMode() string {
+ return m.LogMode
+}
diff --git a/config/gorm_settings.go b/config/gorm_settings.go
new file mode 100644
index 0000000..c01a311
--- /dev/null
+++ b/config/gorm_settings.go
@@ -0,0 +1,10 @@
+package config
+
+type GormSettings struct {
+ Settings []Settings `mapstructure:"settings" json:"settings" yaml:"settings"`
+}
+
+type Settings struct {
+ DsnName string `mapstructure:"dsn-name" json:"dsnName" yaml:"dsn-name"`
+ BindTables []interface{} `mapstructure:"bind-tables" json:"bindTables" yaml:"bind-tables"`
+}
diff --git a/config/jpush.go b/config/jpush.go
new file mode 100644
index 0000000..54c4366
--- /dev/null
+++ b/config/jpush.go
@@ -0,0 +1,8 @@
+package config
+
+type JPush struct {
+ Appkey string `mapstructure:"appkey" json:"appkey" yaml:"appkey"` //appkey
+ Secret string `mapstructure:"secret" json:"secret" yaml:"secret"` //密钥
+ AllUserSign string `mapstructure:"all-user-sign" json:"allUserSign" yaml:"all-user-sign"` //所有用户标签
+ AndroidIntent string `mapstructure:"android-intent" json:"androidIntent" yaml:"android-intent"` //安卓厂商通道包名
+}
diff --git a/config/jwt.go b/config/jwt.go
new file mode 100644
index 0000000..08b81f9
--- /dev/null
+++ b/config/jwt.go
@@ -0,0 +1,7 @@
+package config
+
+type JWT struct {
+ SigningKey string `mapstructure:"signing-key" json:"SigningKey" yaml:"signing-key"` // jwt签名
+ ExpiresTime int64 `mapstructure:"expires-time" json:"expiresTime" yaml:"expires-time"` // 过期时间
+ BufferTime int64 `mapstructure:"buffer-time" json:"bufferTime" yaml:"buffer-time"` // 缓冲时间
+}
diff --git a/config/minio.go b/config/minio.go
new file mode 100644
index 0000000..f3921b0
--- /dev/null
+++ b/config/minio.go
@@ -0,0 +1,2 @@
+package config
+
diff --git a/config/oss.go b/config/oss.go
new file mode 100644
index 0000000..a78420a
--- /dev/null
+++ b/config/oss.go
@@ -0,0 +1,31 @@
+package config
+
+type Local struct {
+ Path string `mapstructure:"path" json:"path" yaml:"path"` // 本地文件路径
+}
+
+type Qiniu struct {
+ Zone string `mapstructure:"zone" json:"zone" yaml:"zone"` // 存储区域
+ Bucket string `mapstructure:"bucket" json:"bucket" yaml:"bucket"` // 空间名称
+ ImgPath string `mapstructure:"img-path" json:"imgPath" yaml:"img-path"` // CDN加速域名
+ UseHTTPS bool `mapstructure:"use-https" json:"useHttps" yaml:"use-https"` // 是否使用https
+ AccessKey string `mapstructure:"access-key" json:"accessKey" yaml:"access-key"` // 秘钥AK
+ SecretKey string `mapstructure:"secret-key" json:"secretKey" yaml:"secret-key"` // 秘钥SK
+ UseCdnDomains bool `mapstructure:"use-cdn-domains" json:"useCdnDomains" yaml:"use-cdn-domains"` // 上传是否使用CDN上传加速
+}
+
+type AliyunOSS struct {
+ Endpoint string `mapstructure:"endpoint" json:"endpoint" yaml:"endpoint"`
+ AccessKeyId string `mapstructure:"access-key-id" json:"accessKeyId" yaml:"access-key-id"`
+ AccessKeySecret string `mapstructure:"access-key-secret" json:"accessKeySecret" yaml:"access-key-secret"`
+ BucketName string `mapstructure:"bucket-name" json:"bucketName" yaml:"bucket-name"`
+ BucketUrl string `mapstructure:"bucket-url" json:"bucketUrl" yaml:"bucket-url"`
+}
+type TencentCOS struct {
+ Bucket string `mapstructure:"bucket" json:"bucket" yaml:"bucket"`
+ Region string `mapstructure:"region" json:"region" yaml:"region"`
+ SecretID string `mapstructure:"secret-id" json:"secretID" yaml:"secret-id"`
+ SecretKey string `mapstructure:"secret-key" json:"secretKey" yaml:"secret-key"`
+ BaseURL string `mapstructure:"base-url" json:"baseURL" yaml:"base-url"`
+ PathPrefix string `mapstructure:"path-prefix" json:"pathPrefix" yaml:"path-prefix"`
+}
diff --git a/config/paypal.go b/config/paypal.go
new file mode 100644
index 0000000..1f4d95e
--- /dev/null
+++ b/config/paypal.go
@@ -0,0 +1,11 @@
+package config
+
+type Paypal struct {
+ Env string `mapstructure:"env" json:"env" yaml:"env"` //端点
+ ClientID string `mapstructure:"client-id" json:"client-id" yaml:"client-id"` //用户ID
+ Secret string `mapstructure:"secret" json:"secret" yaml:"secret"` //密钥
+ ReturnUrl string `mapstructure:"return-url" json:"return-url" yaml:"return-url"` //支付完成跳转
+ CancelUrl string `mapstructure:"cancel-url" json:"cancel-url" yaml:"cancel-url"` //取消支付跳转
+ OrderBack int `mapstructure:"order-back" json:"order-back" yaml:"order-back"` //订单取消时间(分钟)
+ OrderConfirm int `mapstructure:"order-confirm" json:"order-confirm" yaml:"order-confirm"` //订单确认时间(天)
+}
diff --git a/config/redis.go b/config/redis.go
new file mode 100644
index 0000000..1a25178
--- /dev/null
+++ b/config/redis.go
@@ -0,0 +1,7 @@
+package config
+
+type Redis struct {
+ DB int `mapstructure:"db" json:"db" yaml:"db"` // redis的哪个数据库
+ Addr string `mapstructure:"addr" json:"addr" yaml:"addr"` // 服务器地址:端口
+ Password string `mapstructure:"password" json:"password" yaml:"password"` // 密码
+}
diff --git a/config/system.go b/config/system.go
new file mode 100644
index 0000000..768788a
--- /dev/null
+++ b/config/system.go
@@ -0,0 +1,9 @@
+package config
+
+type System struct {
+ Env string `mapstructure:"env" json:"env" yaml:"env"` // 环境值
+ Addr int `mapstructure:"addr" json:"addr" yaml:"addr"` // 端口值
+ DbType string `mapstructure:"db-type" json:"dbType" yaml:"db-type"` // 数据库类型:mysql(默认)|sqlite|sqlserver|postgresql
+ OssType string `mapstructure:"oss-type" json:"ossType" yaml:"oss-type"` // Oss类型
+ UseMultipoint bool `mapstructure:"use-multipoint" json:"useMultipoint" yaml:"use-multipoint"` // 多点登录拦截
+}
diff --git a/config/timer.go b/config/timer.go
new file mode 100644
index 0000000..1ece2bc
--- /dev/null
+++ b/config/timer.go
@@ -0,0 +1,13 @@
+package config
+
+type Timer struct {
+ Start bool `mapstructure:"start" json:"start" yaml:"start"` // 是否启用
+ Spec string `mapstructure:"spec" json:"spec" yaml:"spec"` // CRON表达式
+ Detail []Detail `mapstructure:"detail" json:"detail" yaml:"detail"`
+}
+
+type Detail struct {
+ TableName string `mapstructure:"tableName" json:"tableName" yaml:"tableName"` // 需要清理的表名
+ CompareField string `mapstructure:"compareField" json:"compareField" yaml:"compareField"` // 需要比较时间的字段
+ Interval string `mapstructure:"interval" json:"interval" yaml:"interval"` // 时间间隔
+}
diff --git a/config/tools.go b/config/tools.go
new file mode 100644
index 0000000..6e6d18b
--- /dev/null
+++ b/config/tools.go
@@ -0,0 +1,5 @@
+package config
+
+type Tools struct {
+ CustomerUrl string `mapstructure:"customer-url" json:"customer-url" yaml:"customer-url"` //买家端h5域名地址
+}
diff --git a/config/zap.go b/config/zap.go
new file mode 100644
index 0000000..f681ca8
--- /dev/null
+++ b/config/zap.go
@@ -0,0 +1,13 @@
+package config
+
+type Zap struct {
+ Level string `mapstructure:"level" json:"level" yaml:"level"` // 级别
+ Format string `mapstructure:"format" json:"format" yaml:"format"` // 输出
+ Prefix string `mapstructure:"prefix" json:"prefix" yaml:"prefix"` // 日志前缀
+ Director string `mapstructure:"director" json:"director" yaml:"director"` // 日志文件夹
+ LinkName string `mapstructure:"link-name" json:"linkName" yaml:"link-name"` // 软链接名称
+ ShowLine bool `mapstructure:"show-line" json:"showLine" yaml:"showLine"` // 显示行
+ EncodeLevel string `mapstructure:"encode-level" json:"encodeLevel" yaml:"encode-level"` // 编码级
+ StacktraceKey string `mapstructure:"stacktrace-key" json:"stacktraceKey" yaml:"stacktrace-key"` // 栈名
+ LogInConsole bool `mapstructure:"log-in-console" json:"logInConsole" yaml:"log-in-console"` // 输出控制台
+}
diff --git a/core/server.go b/core/server.go
new file mode 100644
index 0000000..85aa2fd
--- /dev/null
+++ b/core/server.go
@@ -0,0 +1,38 @@
+package core
+
+import (
+ "fmt"
+ "pure/global"
+ "pure/initialize"
+ "time"
+
+ "go.uber.org/zap"
+)
+
+type server interface {
+ ListenAndServe() error
+}
+
+func RunWindowsServer() {
+ // 初始化redis服务
+ initialize.Redis()
+ //NewRedisEventSink(global.MG_CONFIG.Redis.DB, "expired")
+
+ Router := initialize.Routers()
+ Router.Static("/form-generator", "./resource/page")
+
+ address := fmt.Sprintf(":%d", global.MG_CONFIG.System.Addr)
+ s := initServer(address, Router)
+ // 保证文本顺序输出
+ // In order to ensure that the text order output can be deleted
+ time.Sleep(10 * time.Microsecond)
+ global.MG_LOG.Info("server run success on ", zap.String("address", address))
+
+ fmt.Printf(`
+ 欢迎使用 MangGuoNews-Admin
+ 当前版本:V2.4.2
+ 默认自动化文档地址:http://127.0.0.1%s/swagger/index.html
+ 默认前端文件运行地址:http://127.0.0.1%s
+`, address, address)
+ global.MG_LOG.Error(s.ListenAndServe().Error())
+}
diff --git a/core/server_other.go b/core/server_other.go
new file mode 100644
index 0000000..baa7222
--- /dev/null
+++ b/core/server_other.go
@@ -0,0 +1,17 @@
+// +build !windows
+
+package core
+
+import (
+ "github.com/fvbock/endless"
+ "github.com/gin-gonic/gin"
+ "time"
+)
+
+func initServer(address string, router *gin.Engine) server {
+ s := endless.NewServer(address, router)
+ s.ReadHeaderTimeout = 10 * time.Millisecond
+ s.WriteTimeout = 10 * time.Second
+ s.MaxHeaderBytes = 1 << 20
+ return s
+}
diff --git a/core/server_win.go b/core/server_win.go
new file mode 100644
index 0000000..ada3c4b
--- /dev/null
+++ b/core/server_win.go
@@ -0,0 +1,19 @@
+// +build windows
+
+package core
+
+import (
+ "github.com/gin-gonic/gin"
+ "net/http"
+ "time"
+)
+
+func initServer(address string, router *gin.Engine) server {
+ return &http.Server{
+ Addr: address,
+ Handler: router,
+ ReadTimeout: 10 * time.Second,
+ WriteTimeout: 10 * time.Second,
+ MaxHeaderBytes: 1 << 20,
+ }
+}
diff --git a/core/viper.go b/core/viper.go
new file mode 100644
index 0000000..58ccb4f
--- /dev/null
+++ b/core/viper.go
@@ -0,0 +1,56 @@
+package core
+
+import (
+ "flag"
+ "fmt"
+ "os"
+
+ "pure/global"
+ _ "pure/packfile"
+ "pure/utils"
+
+ "github.com/fsnotify/fsnotify"
+ "github.com/spf13/viper"
+)
+
+func Viper(path ...string) *viper.Viper {
+ var config string
+ if len(path) == 0 {
+ flag.StringVar(&config, "c", "", "choose config file.")
+ flag.Parse()
+ if config == "" { // 优先级: 命令行 > 环境变量 > 默认值
+ if configEnv := os.Getenv(utils.ConfigEnv); configEnv == "" {
+ config = utils.ConfigFile
+ fmt.Printf("您正在使用config的默认值,config的路径为%v\n", utils.ConfigFile)
+ } else {
+ config = configEnv
+ fmt.Printf("您正在使用MG_CONFIG环境变量,config的路径为%v\n", config)
+ }
+ } else {
+ fmt.Printf("您正在使用命令行的-c参数传递的值,config的路径为%v\n", config)
+ }
+ } else {
+ config = path[0]
+ fmt.Printf("您正在使用func Viper()传递的值,config的路径为%v\n", config)
+ }
+
+ v := viper.New()
+ v.SetConfigFile(config)
+ v.SetConfigType("yaml")
+ err := v.ReadInConfig()
+ if err != nil {
+ panic(fmt.Errorf("Fatal error config file: %s \n", err))
+ }
+ v.WatchConfig()
+
+ v.OnConfigChange(func(e fsnotify.Event) {
+ fmt.Println("config file changed:", e.Name)
+ if err := v.Unmarshal(&global.MG_CONFIG); err != nil {
+ fmt.Println(err)
+ }
+ })
+ if err := v.Unmarshal(&global.MG_CONFIG); err != nil {
+ fmt.Println(err)
+ }
+ return v
+}
diff --git a/core/zap.go b/core/zap.go
new file mode 100644
index 0000000..b261cb0
--- /dev/null
+++ b/core/zap.go
@@ -0,0 +1,103 @@
+package core
+
+import (
+ "fmt"
+ "os"
+ "pure/global"
+ "pure/utils"
+ "time"
+
+ "go.uber.org/zap"
+ "go.uber.org/zap/zapcore"
+)
+
+var level zapcore.Level
+
+func Zap() (logger *zap.Logger) {
+ if ok, _ := utils.PathExists(global.MG_CONFIG.Zap.Director); !ok { // 判断是否有Director文件夹
+ fmt.Printf("create %v directory\n", global.MG_CONFIG.Zap.Director)
+ _ = os.Mkdir(global.MG_CONFIG.Zap.Director, os.ModePerm)
+ }
+
+ switch global.MG_CONFIG.Zap.Level { // 初始化配置文件的Level
+ case "debug":
+ level = zap.DebugLevel
+ case "info":
+ level = zap.InfoLevel
+ case "warn":
+ level = zap.WarnLevel
+ case "error":
+ level = zap.ErrorLevel
+ case "dpanic":
+ level = zap.DPanicLevel
+ case "panic":
+ level = zap.PanicLevel
+ case "fatal":
+ level = zap.FatalLevel
+ default:
+ level = zap.InfoLevel
+ }
+
+ if level == zap.DebugLevel || level == zap.ErrorLevel {
+ logger = zap.New(getEncoderCore(), zap.AddStacktrace(level))
+ } else {
+ logger = zap.New(getEncoderCore())
+ }
+ if global.MG_CONFIG.Zap.ShowLine {
+ logger = logger.WithOptions(zap.AddCaller())
+ }
+ return logger
+}
+
+// getEncoderConfig 获取zapcore.EncoderConfig
+func getEncoderConfig() (config zapcore.EncoderConfig) {
+ config = zapcore.EncoderConfig{
+ MessageKey: "message",
+ LevelKey: "level",
+ TimeKey: "time",
+ NameKey: "logger",
+ CallerKey: "caller",
+ StacktraceKey: global.MG_CONFIG.Zap.StacktraceKey,
+ LineEnding: zapcore.DefaultLineEnding,
+ EncodeLevel: zapcore.LowercaseLevelEncoder,
+ EncodeTime: CustomTimeEncoder,
+ EncodeDuration: zapcore.SecondsDurationEncoder,
+ EncodeCaller: zapcore.FullCallerEncoder,
+ }
+ switch {
+ case global.MG_CONFIG.Zap.EncodeLevel == "LowercaseLevelEncoder": // 小写编码器(默认)
+ config.EncodeLevel = zapcore.LowercaseLevelEncoder
+ case global.MG_CONFIG.Zap.EncodeLevel == "LowercaseColorLevelEncoder": // 小写编码器带颜色
+ config.EncodeLevel = zapcore.LowercaseColorLevelEncoder
+ case global.MG_CONFIG.Zap.EncodeLevel == "CapitalLevelEncoder": // 大写编码器
+ config.EncodeLevel = zapcore.CapitalLevelEncoder
+ case global.MG_CONFIG.Zap.EncodeLevel == "CapitalColorLevelEncoder": // 大写编码器带颜色
+ config.EncodeLevel = zapcore.CapitalColorLevelEncoder
+ default:
+ config.EncodeLevel = zapcore.LowercaseLevelEncoder
+ }
+ return config
+}
+
+// getEncoder 获取zapcore.Encoder
+func getEncoder() zapcore.Encoder {
+ if global.MG_CONFIG.Zap.Format == "json" {
+ return zapcore.NewJSONEncoder(getEncoderConfig())
+ }
+ return zapcore.NewConsoleEncoder(getEncoderConfig())
+}
+
+// getEncoderCore 获取Encoder的zapcore.Core
+func getEncoderCore() (core zapcore.Core) {
+ writer, err := utils.GetWriteSyncer() // 使用file-rotatelogs进行日志分割
+ if err != nil {
+ fmt.Printf("Get Write Syncer Failed err:%v", err.Error())
+ return
+ }
+ return zapcore.NewCore(getEncoder(), writer, level)
+}
+
+// 自定义日志输出时间格式
+func CustomTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
+ enc.AppendString(t.Format(global.MG_CONFIG.Zap.Prefix + "2006/01/02 - 15:04:05.000"))
+}
diff --git a/docs/docs.go b/docs/docs.go
new file mode 100644
index 0000000..50f27bd
--- /dev/null
+++ b/docs/docs.go
@@ -0,0 +1,4378 @@
+// Code generated by swaggo/swag. DO NOT EDIT
+package docs
+
+import "github.com/swaggo/swag"
+
+const docTemplate = `{
+ "schemes": {{ marshal .Schemes }},
+ "swagger": "2.0",
+ "info": {
+ "description": "{{escape .Description}}",
+ "title": "{{.Title}}",
+ "contact": {},
+ "version": "{{.Version}}"
+ },
+ "host": "{{.Host}}",
+ "basePath": "{{.BasePath}}",
+ "paths": {
+ "/base/authorized": {
+ "post": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "auth"
+ ],
+ "summary": "授权登录[v1.0.0]",
+ "parameters": [
+ {
+ "description": "email,password...",
+ "name": "data",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/request.UserAuthorized"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/base/sendEmail": {
+ "post": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "tags": [
+ "tools"
+ ],
+ "summary": "发送邮件验证码[v1.0.0]",
+ "parameters": [
+ {
+ "description": "phone,type",
+ "name": "data",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/request.SendEmail"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"success\":true,\"data\":{},\"msg\":\"获取成功\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/base/sendMessage": {
+ "post": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "tags": [
+ "tools"
+ ],
+ "summary": "发送短信验证码[v1.0.0]",
+ "parameters": [
+ {
+ "description": "phone,type",
+ "name": "data",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/request.SendMessage"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"success\":true,\"data\":{},\"msg\":\"获取成功\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/customer/base/brochure": {
+ "get": {
+ "tags": [
+ "tools"
+ ],
+ "summary": "隐私协议单页",
+ "parameters": [
+ {
+ "type": "string",
+ "name": "type",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"success\":true,\"data\":{},\"msg\":\"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/dict/getDictDataList": {
+ "get": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "tags": [
+ "dict"
+ ],
+ "summary": "获取数据字典取值列表【v1.0】",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "取值 release_country=发布国家 release_channel=发布渠道 tag_type=标签类型",
+ "name": "typeCode",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"success\":true,\"data\":{},\"msg\":\"获取成功\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/global/address": {
+ "get": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "公用-收货地址"
+ ],
+ "summary": "获取用户收货地址列表【v1.0】",
+ "responses": {
+ "200": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "put": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "公用-收货地址"
+ ],
+ "summary": "修改收货地址【v1.0】",
+ "parameters": [
+ {
+ "description": "data...",
+ "name": "data",
+ "in": "body",
+ "schema": {
+ "$ref": "#/definitions/model.Address"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "post": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "公用-收货地址"
+ ],
+ "summary": "添加收货地址【v1.0】",
+ "parameters": [
+ {
+ "description": "data...",
+ "name": "data",
+ "in": "body",
+ "schema": {
+ "$ref": "#/definitions/model.Address"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "delete": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "公用-收货地址"
+ ],
+ "summary": "删除收货地址【v1.0】",
+ "parameters": [
+ {
+ "description": "data...",
+ "name": "data",
+ "in": "body",
+ "schema": {
+ "$ref": "#/definitions/global.BASE_ID"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/global/track": {
+ "get": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "track"
+ ],
+ "summary": "查询物流信息",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "id",
+ "name": "id",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/global/usSelect": {
+ "get": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "公用-收货地址"
+ ],
+ "summary": "美国地区选择器【v1.0】",
+ "responses": {
+ "200": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/banner/list": {
+ "get": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "tags": [
+ "banner"
+ ],
+ "summary": "分页获取banner列表【v1.1.0新增】",
+ "responses": {
+ "200": {
+ "description": "{\"success\":true,\"data\":{},\"msg\":\"获取成功\"}",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/response.BannerListResponse"
+ }
+ }
+ }
+ }
+ }
+ },
+ "/influencer/base/brochure": {
+ "get": {
+ "tags": [
+ "tools"
+ ],
+ "summary": "隐私协议单页",
+ "parameters": [
+ {
+ "type": "string",
+ "name": "type",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"success\":true,\"data\":{},\"msg\":\"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/base/chain": {
+ "get": {
+ "tags": [
+ "Chain"
+ ],
+ "summary": "获取区块链数据",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "区块/合约hash",
+ "name": "hash",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": [...]}",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/response.ChainResp"
+ }
+ }
+ },
+ "201": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/base/login": {
+ "post": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "auth"
+ ],
+ "summary": "登录[v1.0.0]",
+ "parameters": [
+ {
+ "description": "email,password...",
+ "name": "data",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/request.UserLogin"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/base/register": {
+ "post": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "auth"
+ ],
+ "summary": "注册[v1.0.0]",
+ "parameters": [
+ {
+ "description": "email,password...",
+ "name": "data",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/request.UserRegister"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/base/version": {
+ "get": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "version"
+ ],
+ "summary": "获取版本信息",
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": [...]}",
+ "schema": {
+ "type": "string"
+ }
+ },
+ "201": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/goods/detail": {
+ "get": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "tags": [
+ "goods"
+ ],
+ "summary": "获取商品详情",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "领取任务id",
+ "name": "claim_no",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "商品id",
+ "name": "id",
+ "in": "query"
+ },
+ {
+ "type": "string",
+ "description": "sku_no",
+ "name": "sku_no",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 200, \"data\": {}}",
+ "schema": {
+ "$ref": "#/definitions/model.TbGoodsDetail"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/mission/bonus": {
+ "get": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "tags": [
+ "mission"
+ ],
+ "summary": "获取任务累计奖金",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "任务编码",
+ "name": "code",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 200, \"data\": {}}",
+ "schema": {
+ "$ref": "#/definitions/model.MissionBonus"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/mission/claim": {
+ "get": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "tags": [
+ "mission"
+ ],
+ "summary": "获取我的任务详情【v1.0】",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "id",
+ "name": "id",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 200, \"data\": {}}",
+ "schema": {
+ "$ref": "#/definitions/model.MissionClaimDetail"
+ }
+ }
+ }
+ },
+ "post": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "tags": [
+ "mission"
+ ],
+ "summary": "领取任务【v1.0】",
+ "parameters": [
+ {
+ "description": "params",
+ "name": "data",
+ "in": "body",
+ "schema": {
+ "$ref": "#/definitions/request.ClaimMission"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 200, \"data\": {}}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/mission/claim-list": {
+ "get": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "tags": [
+ "mission"
+ ],
+ "summary": "获取我的任务列表【v1.0】",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "佣金类型 1:固定佣金 2:比例抽成",
+ "name": "hire_type",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "页码",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "每页大小",
+ "name": "pageSize",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "是否筛选上传视频 1是",
+ "name": "video_upload",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 200, \"data\": {}}",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.MissionClaimDetail"
+ }
+ }
+ }
+ }
+ }
+ },
+ "/influencer/mission/collect": {
+ "post": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "tags": [
+ "mission"
+ ],
+ "summary": "收藏/取消收藏任务【v1.0】",
+ "parameters": [
+ {
+ "description": "params",
+ "name": "data",
+ "in": "body",
+ "schema": {
+ "$ref": "#/definitions/request.MissionId"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 200, \"data\": {}}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/mission/collect-list": {
+ "get": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "tags": [
+ "mission"
+ ],
+ "summary": "获取收藏任务列表【v1.0】",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "页码",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "每页大小",
+ "name": "pageSize",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 200, \"data\": {}}",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.MissionDetail"
+ }
+ }
+ }
+ }
+ }
+ },
+ "/influencer/mission/detail": {
+ "get": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "tags": [
+ "mission"
+ ],
+ "summary": "获取任务详情【v1.0】",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "id",
+ "name": "id",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 200, \"data\": {}}",
+ "schema": {
+ "$ref": "#/definitions/model.MissionDetail"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/mission/list": {
+ "get": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "tags": [
+ "mission"
+ ],
+ "summary": "获取任务列表【v1.0】",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "页码",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "每页大小",
+ "name": "pageSize",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 200, \"data\": {}}",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.MissionDetail"
+ }
+ }
+ }
+ }
+ }
+ },
+ "/influencer/mission/order-data": {
+ "get": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "mission"
+ ],
+ "summary": "获取任务下订单统计数据",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "任务编码",
+ "name": "code",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": [...]}",
+ "schema": {
+ "$ref": "#/definitions/dto.MissionOrderStatistic"
+ }
+ },
+ "201": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/mission/recommend-detail": {
+ "get": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "tags": [
+ "mission"
+ ],
+ "summary": "获取首页任务详情【v1.0】",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "id",
+ "name": "id",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 200, \"data\": {}}",
+ "schema": {
+ "$ref": "#/definitions/response.MissionRecommendResponse"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/mission/recommend-list": {
+ "get": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "tags": [
+ "mission"
+ ],
+ "summary": "获取首页任务列表【v1.0】",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "页码",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "每页大小",
+ "name": "pageSize",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 200, \"data\": {}}",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/response.MissionRecommendResponse"
+ }
+ }
+ }
+ }
+ }
+ },
+ "/influencer/mission/submit-video": {
+ "post": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "tags": [
+ "mission"
+ ],
+ "summary": "固定费用任务上传视频【v1.0】",
+ "parameters": [
+ {
+ "description": "params",
+ "name": "data",
+ "in": "body",
+ "schema": {
+ "$ref": "#/definitions/request.ClaimMissionVideo"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 200, \"data\": {}}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/mission/submit-works": {
+ "post": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "tags": [
+ "mission"
+ ],
+ "summary": "领取任务的提交作品【v1.0】",
+ "parameters": [
+ {
+ "description": "params",
+ "name": "data",
+ "in": "body",
+ "schema": {
+ "$ref": "#/definitions/request.ClaimMissionWorksList"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 200, \"data\": {}}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/mission/sys-reward-list": {
+ "get": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "tags": [
+ "mission"
+ ],
+ "summary": "获取平台奖励列表【v1.0】",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "页码",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "每页大小",
+ "name": "pageSize",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "状态 1待发放 2已发放 3已领取",
+ "name": "status",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 200, \"data\": {}}",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.SysMissionReward"
+ }
+ }
+ }
+ }
+ }
+ },
+ "/influencer/mission/sys-reward-summary": {
+ "get": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "tags": [
+ "mission"
+ ],
+ "summary": "获取平台奖励汇总【v1.0】",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "状态 1待发放 2已发放 3已领取",
+ "name": "status",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 200, \"data\": {}}",
+ "schema": {
+ "$ref": "#/definitions/response.SysMissionBonus"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/order/data": {
+ "get": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "order"
+ ],
+ "summary": "获取订单数据",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "场景 my:我的 order-list:订单列表",
+ "name": "scene",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": [...]}",
+ "schema": {
+ "$ref": "#/definitions/dto.OrderData"
+ }
+ },
+ "201": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/order/detail": {
+ "get": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "order"
+ ],
+ "summary": "获取订单详情",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "订单号",
+ "name": "orderID",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": [...]}",
+ "schema": {
+ "$ref": "#/definitions/model.OrderDetail"
+ }
+ },
+ "201": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/order/goods/snapshot": {
+ "get": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "order"
+ ],
+ "summary": "获取订单商品快照",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "订单号",
+ "name": "orderID",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": [...]}",
+ "schema": {
+ "$ref": "#/definitions/model.OrderGoodsDetail"
+ }
+ },
+ "201": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/order/list": {
+ "get": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "order"
+ ],
+ "summary": "获取订单列表",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "网红码?",
+ "name": "code",
+ "in": "query"
+ },
+ {
+ "type": "string",
+ "description": "数据库分组",
+ "name": "group",
+ "in": "query"
+ },
+ {
+ "type": "string",
+ "description": "订单号",
+ "name": "orderID",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "页码",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "每页大小",
+ "name": "pageSize",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "订单状态 //订单状态 1-待付款 2-待发货 3-已发货 4-已完成 5-已取消",
+ "name": "status",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": [...]}",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.OrderList"
+ }
+ }
+ },
+ "201": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/user/bandPhone": {
+ "post": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "网红端-用户"
+ ],
+ "summary": "网红绑定手机[v1.0.0]",
+ "parameters": [
+ {
+ "description": "email,password...",
+ "name": "data",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/request.UserBandPhone"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/user/detail": {
+ "get": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "网红端-用户"
+ ],
+ "summary": "获取用户基本信息[v1.0.0]",
+ "responses": {
+ "200": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "put": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "网红端-用户"
+ ],
+ "summary": "修改用户基本信息",
+ "parameters": [
+ {
+ "description": "data...",
+ "name": "data",
+ "in": "body",
+ "schema": {
+ "$ref": "#/definitions/request.UserDetail"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/user/logoff": {
+ "post": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "网红端-用户"
+ ],
+ "summary": "注销账户[v1.0.1]",
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": \"注销成功\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/user/platformAuth": {
+ "post": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "网红端-用户"
+ ],
+ "summary": "平台认证[v1.0.0]",
+ "parameters": [
+ {
+ "description": "email,password...",
+ "name": "data",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/request.UserPlatformAuth"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/user/statistics": {
+ "get": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "网红端-用户"
+ ],
+ "summary": "获取用户统计信息[v1.0.0]",
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": [...]}",
+ "schema": {
+ "$ref": "#/definitions/response.UserStatistics"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/wallet/account": {
+ "post": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "网红端-用户钱包"
+ ],
+ "summary": "添加账户",
+ "parameters": [
+ {
+ "description": "data...",
+ "name": "data",
+ "in": "body",
+ "schema": {
+ "$ref": "#/definitions/request.AddAccount"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": [...]}",
+ "schema": {
+ "type": "string"
+ }
+ },
+ "201": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "delete": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "网红端-用户钱包"
+ ],
+ "summary": "解绑账户",
+ "parameters": [
+ {
+ "description": "data...",
+ "name": "data",
+ "in": "body",
+ "schema": {
+ "$ref": "#/definitions/request.DeleteAccount"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": [...]}",
+ "schema": {
+ "type": "string"
+ }
+ },
+ "201": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/wallet/account/default": {
+ "put": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "网红端-用户钱包"
+ ],
+ "summary": "设置账户默认开关",
+ "parameters": [
+ {
+ "description": "data...",
+ "name": "data",
+ "in": "body",
+ "schema": {
+ "$ref": "#/definitions/request.IdReq"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": [...]}",
+ "schema": {
+ "type": "string"
+ }
+ },
+ "201": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/wallet/accountList": {
+ "get": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "网红端-用户钱包"
+ ],
+ "summary": "获取账户列表",
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": [...]}",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.Account"
+ }
+ }
+ },
+ "201": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/wallet/bill-list": {
+ "get": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "对账中心"
+ ],
+ "summary": "获取资金流水记录",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "页码",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "每页大小",
+ "name": "pageSize",
+ "in": "query"
+ },
+ {
+ "type": "string",
+ "description": "空:默认 1:bill-center",
+ "name": "scene",
+ "in": "query"
+ },
+ {
+ "type": "string",
+ "description": "空:全部 1-支出 2-收入",
+ "name": "status",
+ "in": "query"
+ },
+ {
+ "type": "string",
+ "description": "1:全部 2:昨天 3:近30天",
+ "name": "uint",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": [...]}",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.Bill"
+ }
+ }
+ },
+ "201": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/wallet/bill-notify": {
+ "get": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "对账中心"
+ ],
+ "summary": "获取账单通知列表",
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": [...]}",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.BillNotify"
+ }
+ }
+ },
+ "201": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/wallet/bill/data": {
+ "get": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "对账中心"
+ ],
+ "summary": "获取对账中心数据",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "1:全部 2:昨天 3:近30天",
+ "name": "uint",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": [...]}",
+ "schema": {
+ "$ref": "#/definitions/dto.BillData"
+ }
+ },
+ "201": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/wallet/detail": {
+ "get": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "网红端-用户钱包"
+ ],
+ "summary": "钱包基本信息",
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": [...]}",
+ "schema": {
+ "$ref": "#/definitions/model.Wallet"
+ }
+ },
+ "201": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/wallet/withdrawal": {
+ "get": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "对账中心"
+ ],
+ "summary": "获取提现详情",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "流水号",
+ "name": "flow_no",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": [...]}",
+ "schema": {
+ "$ref": "#/definitions/model.Withdrawal"
+ }
+ },
+ "201": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "post": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "网红端-用户钱包"
+ ],
+ "summary": "提现",
+ "parameters": [
+ {
+ "description": "data...",
+ "name": "data",
+ "in": "body",
+ "schema": {
+ "$ref": "#/definitions/request.WithdrawalParams"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/wallet/withdrawal-list": {
+ "get": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "对账中心"
+ ],
+ "summary": "获取提现记录",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "页码",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "每页大小",
+ "name": "pageSize",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": [...]}",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.Withdrawal"
+ }
+ }
+ },
+ "201": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "definitions": {
+ "dto.BillData": {
+ "type": "object",
+ "properties": {
+ "cancelOrderMoney": {
+ "description": "退款订单总额",
+ "type": "number"
+ },
+ "cancelOrderNum": {
+ "description": "退款订单数",
+ "type": "integer"
+ },
+ "flowExpend": {
+ "description": "出账",
+ "type": "number"
+ },
+ "flowIncome": {
+ "description": "进账",
+ "type": "number"
+ },
+ "income": {
+ "description": "收入总额",
+ "type": "number"
+ },
+ "orderMoney": {
+ "description": "订单总额",
+ "type": "number"
+ },
+ "orderNum": {
+ "description": "订单数",
+ "type": "integer"
+ },
+ "rewardUnfinished": {
+ "description": "在途佣金",
+ "type": "number"
+ }
+ }
+ },
+ "dto.MissionOrderStatistic": {
+ "type": "object",
+ "properties": {
+ "OrderMoney": {
+ "description": "订单金额",
+ "type": "number"
+ },
+ "OrderUserNum": {
+ "description": "下单人数",
+ "type": "integer"
+ },
+ "RewardRatio": {
+ "description": "佣金比例",
+ "type": "number"
+ },
+ "SellNum": {
+ "description": "销售数量",
+ "type": "integer"
+ },
+ "SettleReward": {
+ "description": "结算佣金",
+ "type": "number"
+ },
+ "TransitReward": {
+ "description": "在途佣金",
+ "type": "number"
+ },
+ "Uv": {
+ "description": "浏览人数",
+ "type": "integer"
+ },
+ "orderDoneNum": {
+ "description": "完成订单总数",
+ "type": "integer"
+ },
+ "orderNum": {
+ "description": "订单总数",
+ "type": "integer"
+ }
+ }
+ },
+ "dto.OrderData": {
+ "type": "object",
+ "properties": {
+ "all": {
+ "description": "全部",
+ "type": "integer"
+ },
+ "cancel": {
+ "description": "已取消",
+ "type": "integer"
+ },
+ "finished": {
+ "description": "已完成",
+ "type": "integer"
+ },
+ "shipped": {
+ "description": "已发货",
+ "type": "integer"
+ },
+ "unship": {
+ "description": "待发货",
+ "type": "integer"
+ }
+ }
+ },
+ "global.BASE_ID": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "description": "主键",
+ "type": "integer"
+ }
+ }
+ },
+ "model.Account": {
+ "type": "object",
+ "properties": {
+ "account_name": {
+ "description": "户名",
+ "type": "string"
+ },
+ "address": {
+ "description": "收款人地址",
+ "type": "string"
+ },
+ "bank_code": {
+ "description": "收款行",
+ "type": "string"
+ },
+ "card_number": {
+ "description": "银行卡号",
+ "type": "string"
+ },
+ "country": {
+ "description": "国家/地区",
+ "type": "string"
+ },
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "currency": {
+ "description": "币种 USD:美元",
+ "type": "string"
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "idCard": {
+ "type": "string"
+ },
+ "is_default": {
+ "description": "是否为默认 0:非默认 1:默认",
+ "type": "boolean"
+ },
+ "phone": {
+ "type": "string"
+ },
+ "platform": {
+ "description": "平台 saller(买家端) / customer(客户端) / influencer(网红端)",
+ "type": "string"
+ },
+ "sort": {
+ "description": "排序值",
+ "type": "integer"
+ },
+ "swift_code": {
+ "description": "银行国际代码",
+ "type": "string"
+ },
+ "type": {
+ "description": "类型 1:paypal 2:银行卡",
+ "type": "integer"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ },
+ "userID": {
+ "description": "用户id",
+ "type": "string"
+ }
+ }
+ },
+ "model.Address": {
+ "type": "object",
+ "properties": {
+ "bldg": {
+ "description": "apt,ste,bldg",
+ "type": "string"
+ },
+ "city": {
+ "description": "city",
+ "type": "string"
+ },
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "default": {
+ "description": "是否默认地址 1-是 2-否",
+ "type": "integer"
+ },
+ "firstName": {
+ "description": "first name",
+ "type": "string"
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "lastName": {
+ "description": "last name",
+ "type": "string"
+ },
+ "phone": {
+ "description": "手机号",
+ "type": "string"
+ },
+ "platform": {
+ "description": "平台 saller(买家端) / customer(客户端) / influencer(网红端)",
+ "type": "string"
+ },
+ "state": {
+ "description": "state",
+ "type": "string"
+ },
+ "street": {
+ "description": "street",
+ "type": "string"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ },
+ "userId": {
+ "type": "string"
+ },
+ "zipCode": {
+ "description": "zip code",
+ "type": "string"
+ }
+ }
+ },
+ "model.Bill": {
+ "type": "object",
+ "properties": {
+ "account": {
+ "description": "收款账户(提现)",
+ "type": "string"
+ },
+ "amount": {
+ "description": "数量",
+ "type": "integer"
+ },
+ "balance": {
+ "description": "余额",
+ "type": "number"
+ },
+ "check_status": {
+ "description": "审核状态 0:待审核 1:审核通过 2:审核未通过",
+ "type": "string"
+ },
+ "claim_no": {
+ "description": "领取任务编号",
+ "type": "string"
+ },
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "order_id": {
+ "description": "关联订单id",
+ "type": "string"
+ },
+ "platform": {
+ "description": "平台 seller(买家端) / customer(客户端) / influencer(网红端)",
+ "type": "string"
+ },
+ "price": {
+ "description": "金额",
+ "type": "number"
+ },
+ "receipt": {
+ "description": "是否已到账 1-是 2-否 3-已取消付款",
+ "type": "integer"
+ },
+ "remark": {
+ "description": "备注",
+ "type": "string"
+ },
+ "status": {
+ "description": "类型 1-支出 2-收入",
+ "type": "integer"
+ },
+ "title": {
+ "description": "账单标题",
+ "type": "string"
+ },
+ "transaction_id": {
+ "description": "交易编号",
+ "type": "string"
+ },
+ "type": {
+ "description": "类型 1-佣金 2-订单 3-提现 4-平台奖励",
+ "type": "string"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ },
+ "userID": {
+ "description": "用户id",
+ "type": "string"
+ },
+ "withd_id": {
+ "description": "提现id",
+ "type": "string"
+ },
+ "withdrawalStatus": {
+ "description": "提现状态 0-提现中 1-提现完成 2-提现失败",
+ "type": "integer"
+ }
+ }
+ },
+ "model.BillNotify": {
+ "type": "object",
+ "properties": {
+ "relation_id": {
+ "description": "关联id",
+ "type": "string"
+ },
+ "relation_type": {
+ "description": "关联类型",
+ "type": "string"
+ },
+ "title": {
+ "description": "标题",
+ "type": "string"
+ }
+ }
+ },
+ "model.BillView": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "description": "id",
+ "type": "integer"
+ },
+ "order_id": {
+ "description": "订单编号",
+ "type": "string"
+ },
+ "transaction_id": {
+ "description": "交易编号",
+ "type": "string"
+ }
+ }
+ },
+ "model.Breadcrumb": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "integer"
+ },
+ "is_leaf": {
+ "description": "是否叶子分类",
+ "type": "boolean"
+ },
+ "name": {
+ "type": "string"
+ },
+ "pid": {
+ "description": "父id",
+ "type": "integer"
+ }
+ }
+ },
+ "model.Chain": {
+ "type": "object",
+ "properties": {
+ "address": {
+ "description": "合约地址",
+ "type": "string"
+ }
+ }
+ },
+ "model.MissionBonus": {
+ "type": "object",
+ "properties": {
+ "total": {
+ "type": "number"
+ },
+ "user_total": {
+ "type": "number"
+ }
+ }
+ },
+ "model.MissionClaimDetail": {
+ "type": "object",
+ "properties": {
+ "achieve_num": {
+ "description": "已完成商品数量",
+ "type": "integer"
+ },
+ "claim_no": {
+ "description": "领取任务编号",
+ "type": "string"
+ },
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "email": {
+ "description": "发送邮箱",
+ "type": "string"
+ },
+ "expire_at": {
+ "description": "任务推广过期时间",
+ "type": "string"
+ },
+ "finished": {
+ "description": "任务完成状态 0:未完成 1:已完成",
+ "type": "integer"
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "mission": {
+ "description": "关联任务",
+ "allOf": [
+ {
+ "$ref": "#/definitions/model.MissionDetail"
+ }
+ ]
+ },
+ "mission_id": {
+ "description": "任务id",
+ "type": "integer"
+ },
+ "order": {
+ "description": "任务订单",
+ "allOf": [
+ {
+ "$ref": "#/definitions/model.MissionClaimOrderInfo"
+ }
+ ]
+ },
+ "spread_url": {
+ "description": "推广链接",
+ "type": "string"
+ },
+ "status": {
+ "description": "状态 1:已领取待发货 2:已发货 3:已收货推广中",
+ "type": "integer"
+ },
+ "status_except": {
+ "description": "状态描述",
+ "type": "string"
+ },
+ "total_bonus": {
+ "description": "累计佣金",
+ "type": "integer"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ },
+ "video": {
+ "description": "上传视频",
+ "allOf": [
+ {
+ "$ref": "#/definitions/model.MissionClaimVideo"
+ }
+ ]
+ },
+ "works": {
+ "description": "发布作品",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.MissionClaimWorks"
+ }
+ }
+ }
+ },
+ "model.MissionClaimOrderGoods": {
+ "type": "object",
+ "properties": {
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "image": {
+ "description": "规格图片url",
+ "type": "string"
+ },
+ "order_id": {
+ "description": "订单号",
+ "type": "string"
+ },
+ "price": {
+ "description": "价格",
+ "type": "number"
+ },
+ "sku_no": {
+ "description": "sku编号",
+ "type": "string"
+ },
+ "specs": {
+ "description": "规格",
+ "type": "string"
+ },
+ "title": {
+ "description": "名称",
+ "type": "string"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ }
+ }
+ },
+ "model.MissionClaimOrderInfo": {
+ "type": "object",
+ "properties": {
+ "courier": {
+ "description": "快递公司",
+ "type": "string"
+ },
+ "courier_number": {
+ "description": "快递单号",
+ "type": "string"
+ },
+ "courier_url": {
+ "description": "快递查询地址",
+ "type": "string"
+ },
+ "deliver": {
+ "description": "发货信息",
+ "allOf": [
+ {
+ "$ref": "#/definitions/model.OrderDeliver"
+ }
+ ]
+ },
+ "mission_claim_id": {
+ "description": "领取任务id",
+ "type": "integer"
+ },
+ "order_goods": {
+ "description": "订单商品信息",
+ "allOf": [
+ {
+ "$ref": "#/definitions/model.MissionClaimOrderGoods"
+ }
+ ]
+ },
+ "order_id": {
+ "description": "订单号",
+ "type": "string"
+ },
+ "send_time": {
+ "description": "发货时间",
+ "type": "string"
+ },
+ "status": {
+ "description": "订单状态 2:待发货 3:已发货",
+ "type": "integer"
+ }
+ }
+ },
+ "model.MissionClaimVideo": {
+ "type": "object",
+ "properties": {
+ "cover": {
+ "description": "视频封面",
+ "type": "string"
+ },
+ "create_by": {
+ "description": "创建人",
+ "type": "string"
+ },
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "height": {
+ "description": "高度",
+ "type": "integer"
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "mission_claim_id": {
+ "description": "领取任务id",
+ "type": "integer"
+ },
+ "mission_id": {
+ "description": "任务ID",
+ "type": "integer"
+ },
+ "remark": {
+ "type": "string"
+ },
+ "reward_status": {
+ "description": "奖励发放状态 1:未发放 2:已发放",
+ "type": "integer"
+ },
+ "source_type": {
+ "description": "类型:1:固定费用上传 2:奖励任务上传 3:后台上传",
+ "type": "integer"
+ },
+ "status": {
+ "description": "状态 1:待审核 2:审核通过 3:审核不通过",
+ "type": "integer"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ },
+ "video_url": {
+ "description": "视频上传地址",
+ "type": "string"
+ },
+ "width": {
+ "description": "宽度",
+ "type": "integer"
+ }
+ }
+ },
+ "model.MissionClaimWorks": {
+ "type": "object",
+ "properties": {
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "homepage": {
+ "description": "作品主页地址",
+ "type": "string"
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "image": {
+ "description": "作品凭证截图",
+ "type": "string"
+ },
+ "mission_claim_id": {
+ "description": "领取任务id",
+ "type": "integer"
+ },
+ "type": {
+ "description": "平台 1:ins 2:YouTube 3:tiktok 4:Facebook 5:Twitter",
+ "type": "integer"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ },
+ "video_url": {
+ "description": "视频上传地址",
+ "type": "string"
+ }
+ }
+ },
+ "model.MissionDetail": {
+ "type": "object",
+ "properties": {
+ "claim_days": {
+ "description": "任务完成天数",
+ "type": "integer"
+ },
+ "claim_demands": {
+ "description": "任务拍摄要求",
+ "type": "string"
+ },
+ "claim_num": {
+ "description": "接任务人数",
+ "type": "integer"
+ },
+ "claim_status_except": {
+ "description": "可接任务状态描述",
+ "type": "string"
+ },
+ "claim_status_except_eng": {
+ "description": "英文版状态描述",
+ "type": "string"
+ },
+ "claim_stock": {
+ "description": "可接任务库存",
+ "type": "integer"
+ },
+ "collect_status": {
+ "description": "收藏状态 true:已收藏 false:未收藏",
+ "type": "boolean"
+ },
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "description": {
+ "description": "描述/卖点",
+ "type": "string"
+ },
+ "end_time": {
+ "description": "任务结束时间",
+ "type": "string"
+ },
+ "goods": {
+ "description": "商品信息",
+ "allOf": [
+ {
+ "$ref": "#/definitions/model.TbGoodsSpecsView"
+ }
+ ]
+ },
+ "goods_status": {
+ "description": "关联商品状态 1:正常 2:已下架",
+ "type": "integer"
+ },
+ "goods_url": {
+ "description": "商品链接",
+ "type": "string"
+ },
+ "has_sample": {
+ "description": "是否有样品 0:没有 1:有",
+ "type": "integer"
+ },
+ "has_video": {
+ "description": "是否有视频素材 0:没有 1:有",
+ "type": "integer"
+ },
+ "hire_money": {
+ "description": "hire_type==1 佣金金额",
+ "type": "number"
+ },
+ "hire_money_expect": {
+ "description": "预计佣金描述",
+ "type": "string"
+ },
+ "hire_ratio": {
+ "description": "hire_type==2 抽成比例",
+ "type": "number"
+ },
+ "hire_type": {
+ "description": "佣金类型 1:固定佣金 2:比例抽成",
+ "type": "integer"
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "num": {
+ "description": "商品数量",
+ "type": "integer"
+ },
+ "release_channels": {
+ "description": "发布渠道",
+ "type": "string"
+ },
+ "release_country": {
+ "description": "发布国家",
+ "type": "string"
+ },
+ "sample_num": {
+ "description": "样品数量",
+ "type": "integer"
+ },
+ "start_time": {
+ "description": "任务起始时间",
+ "type": "string"
+ },
+ "status": {
+ "description": "状态 1:未开始 2:进行中 3:已结束",
+ "type": "integer"
+ },
+ "store": {
+ "description": "商家信息",
+ "allOf": [
+ {
+ "$ref": "#/definitions/model.SellerStoreInfo"
+ }
+ ]
+ },
+ "title": {
+ "description": "标题",
+ "type": "string"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ },
+ "video_channel_ids": {
+ "description": "视频发布渠道,多个渠道英文逗号连接",
+ "type": "string"
+ },
+ "video_country_id": {
+ "description": "视频发布国家",
+ "type": "string"
+ },
+ "video_url": {
+ "type": "string"
+ }
+ }
+ },
+ "model.OrderAddress": {
+ "type": "object",
+ "properties": {
+ "bldg": {
+ "description": "apt,ste,bldg",
+ "type": "string"
+ },
+ "city": {
+ "description": "city",
+ "type": "string"
+ },
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "default": {
+ "description": "是否默认地址 1-是 2-否",
+ "type": "integer"
+ },
+ "firstName": {
+ "description": "first name",
+ "type": "string"
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "lastName": {
+ "description": "last name",
+ "type": "string"
+ },
+ "orderID": {
+ "type": "string"
+ },
+ "phone": {
+ "description": "手机号",
+ "type": "string"
+ },
+ "platform": {
+ "description": "平台 saller(买家端) / customer(客户端) / influencer(网红端)",
+ "type": "string"
+ },
+ "state": {
+ "description": "state",
+ "type": "string"
+ },
+ "street": {
+ "description": "street",
+ "type": "string"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ },
+ "userId": {
+ "type": "string"
+ },
+ "zipCode": {
+ "description": "zip code",
+ "type": "string"
+ }
+ }
+ },
+ "model.OrderDeliver": {
+ "type": "object",
+ "properties": {
+ "courier": {
+ "description": "快递公司",
+ "type": "string"
+ },
+ "courierLink": {
+ "description": "快递链接",
+ "type": "string"
+ },
+ "courierNumber": {
+ "description": "快递单号",
+ "type": "string"
+ },
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "orderID": {
+ "description": "订单号",
+ "type": "string"
+ },
+ "track_id": {
+ "description": "track表id",
+ "type": "integer"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ }
+ }
+ },
+ "model.OrderDetail": {
+ "type": "object",
+ "properties": {
+ "IAmount": {
+ "description": "网红佣金",
+ "type": "string"
+ },
+ "address": {
+ "description": "地址",
+ "allOf": [
+ {
+ "$ref": "#/definitions/model.OrderAddress"
+ }
+ ]
+ },
+ "bill": {
+ "description": "交易信息",
+ "allOf": [
+ {
+ "$ref": "#/definitions/model.BillView"
+ }
+ ]
+ },
+ "captureID": {
+ "description": "paypal收款确认id",
+ "type": "string"
+ },
+ "chain": {
+ "description": "区块链",
+ "allOf": [
+ {
+ "$ref": "#/definitions/model.Chain"
+ }
+ ]
+ },
+ "code": {
+ "description": "网红码?",
+ "type": "string"
+ },
+ "commodID": {
+ "description": "商品id",
+ "type": "integer"
+ },
+ "confirmTime": {
+ "description": "收货时间",
+ "type": "string"
+ },
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "deliver": {
+ "description": "发货信息",
+ "allOf": [
+ {
+ "$ref": "#/definitions/model.OrderDeliver"
+ }
+ ]
+ },
+ "goods": {
+ "description": "商品信息",
+ "allOf": [
+ {
+ "$ref": "#/definitions/model.OrderGoodsDetail"
+ }
+ ]
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "number": {
+ "description": "数量",
+ "type": "integer"
+ },
+ "orderID": {
+ "description": "订单号",
+ "type": "string"
+ },
+ "paidPrice": {
+ "description": "实付价格",
+ "type": "number"
+ },
+ "payTime": {
+ "description": "付款时间",
+ "type": "string"
+ },
+ "paypalID": {
+ "description": "paypal订单号",
+ "type": "string"
+ },
+ "platform": {
+ "description": "购买平台",
+ "type": "string"
+ },
+ "postSale": {
+ "description": "售后信息",
+ "allOf": [
+ {
+ "$ref": "#/definitions/model.PostSale"
+ }
+ ]
+ },
+ "price": {
+ "description": "商品价格",
+ "type": "number"
+ },
+ "sendTime": {
+ "description": "发货时间",
+ "type": "string"
+ },
+ "sku_id": {
+ "description": "商品规格编号",
+ "type": "integer"
+ },
+ "sku_no": {
+ "description": "商品规格编号",
+ "type": "string"
+ },
+ "status": {
+ "description": "订单状态 //订单状态 1-待付款 2-待发货 3-已发货 4-已完成 5-已取消",
+ "type": "integer"
+ },
+ "store": {
+ "description": "店铺信息",
+ "allOf": [
+ {
+ "$ref": "#/definitions/model.SellerStoreInfo"
+ }
+ ]
+ },
+ "store_no": {
+ "description": "店铺编号",
+ "type": "string"
+ },
+ "type": {
+ "description": "类型 1-普通订单 2-预售订单",
+ "type": "integer"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ },
+ "userID": {
+ "description": "用户id",
+ "type": "string"
+ }
+ }
+ },
+ "model.OrderGoodsDetail": {
+ "type": "object",
+ "properties": {
+ "attributes": {
+ "description": "规格详情",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.TbAttributeWithValues"
+ }
+ },
+ "content": {
+ "description": "详情",
+ "type": "string"
+ },
+ "content_text": {
+ "description": "详情-文字",
+ "type": "string"
+ },
+ "cover": {
+ "description": "封面图",
+ "type": "string"
+ },
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "goods_specs": {
+ "description": "规格",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.TbOrderGoodsSpecsDetail"
+ }
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "images": {
+ "description": "图片",
+ "type": "string"
+ },
+ "orderID": {
+ "description": "订单id",
+ "type": "string"
+ },
+ "price_max": {
+ "description": "最高规格价格",
+ "type": "number"
+ },
+ "price_min": {
+ "description": "最低规格价格",
+ "type": "number"
+ },
+ "retail_price": {
+ "description": "吊牌价(零售指导价)",
+ "type": "number"
+ },
+ "sku_no": {
+ "description": "商品规格编号",
+ "type": "string"
+ },
+ "specs": {
+ "description": "规格",
+ "type": "string"
+ },
+ "spu_no": {
+ "description": "编号",
+ "type": "string"
+ },
+ "store_no": {
+ "description": "店铺编号",
+ "type": "string"
+ },
+ "title": {
+ "description": "名称",
+ "type": "string"
+ },
+ "title_eng": {
+ "description": "英文名称",
+ "type": "string"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ }
+ }
+ },
+ "model.OrderList": {
+ "type": "object",
+ "properties": {
+ "IAmount": {
+ "description": "网红佣金",
+ "type": "string"
+ },
+ "captureID": {
+ "description": "paypal收款确认id",
+ "type": "string"
+ },
+ "code": {
+ "description": "网红码?",
+ "type": "string"
+ },
+ "commodID": {
+ "description": "商品id",
+ "type": "integer"
+ },
+ "confirmTime": {
+ "description": "收货时间",
+ "type": "string"
+ },
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "goods": {
+ "description": "商品信息",
+ "allOf": [
+ {
+ "$ref": "#/definitions/model.OrderGoodsDetail"
+ }
+ ]
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "number": {
+ "description": "数量",
+ "type": "integer"
+ },
+ "orderID": {
+ "description": "订单号",
+ "type": "string"
+ },
+ "paidPrice": {
+ "description": "实付价格",
+ "type": "number"
+ },
+ "payTime": {
+ "description": "付款时间",
+ "type": "string"
+ },
+ "paypalID": {
+ "description": "paypal订单号",
+ "type": "string"
+ },
+ "platform": {
+ "description": "购买平台",
+ "type": "string"
+ },
+ "price": {
+ "description": "商品价格",
+ "type": "number"
+ },
+ "sendTime": {
+ "description": "发货时间",
+ "type": "string"
+ },
+ "sku_id": {
+ "description": "商品规格编号",
+ "type": "integer"
+ },
+ "sku_no": {
+ "description": "商品规格编号",
+ "type": "string"
+ },
+ "status": {
+ "description": "订单状态 //订单状态 1-待付款 2-待发货 3-已发货 4-已完成 5-已取消",
+ "type": "integer"
+ },
+ "store_no": {
+ "description": "店铺编号",
+ "type": "string"
+ },
+ "type": {
+ "description": "类型 1-普通订单 2-预售订单",
+ "type": "integer"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ },
+ "user": {
+ "description": "买家信息",
+ "allOf": [
+ {
+ "$ref": "#/definitions/model.UserSimple"
+ }
+ ]
+ },
+ "userID": {
+ "description": "用户id",
+ "type": "string"
+ }
+ }
+ },
+ "model.PostSale": {
+ "type": "object",
+ "properties": {
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "examine_time": {
+ "description": "审核时间",
+ "type": "string"
+ },
+ "id": {
+ "description": "id",
+ "type": "integer"
+ },
+ "orderId": {
+ "description": "订单id",
+ "type": "string"
+ },
+ "refundStatus": {
+ "description": "退款状态 1:退款中 2:退款成功 3:退款失败",
+ "type": "integer"
+ },
+ "refund_time": {
+ "description": "退款时间",
+ "type": "string"
+ },
+ "remark": {
+ "description": "审核原因",
+ "type": "string"
+ },
+ "status": {
+ "description": "处理状态 1:已提交 2:已处理 3:已拒绝 4:已撤回",
+ "type": "integer"
+ }
+ }
+ },
+ "model.SellerStoreInfo": {
+ "type": "object",
+ "properties": {
+ "email": {
+ "description": "店铺联系email(注册账号email)",
+ "type": "string"
+ },
+ "store_no": {
+ "description": "店铺编号",
+ "type": "string"
+ },
+ "type": {
+ "description": "1:个人店铺",
+ "type": "integer"
+ }
+ }
+ },
+ "model.SysMissionReward": {
+ "type": "object",
+ "properties": {
+ "achieve_num": {
+ "description": "已完成任务次数",
+ "type": "integer"
+ },
+ "audit_by": {
+ "description": "审核人",
+ "type": "string"
+ },
+ "bonus": {
+ "description": "奖励金额",
+ "type": "number"
+ },
+ "create_by": {
+ "description": "创建人",
+ "type": "string"
+ },
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "relationId": {
+ "description": "关联项目id",
+ "type": "string"
+ },
+ "status": {
+ "description": "状态 1待发放 2已发放 3已领取",
+ "type": "integer"
+ },
+ "title": {
+ "description": "标题",
+ "type": "string"
+ },
+ "type": {
+ "description": "奖励类型 1.视频上传 2.信息完善 3.商家任务",
+ "type": "integer"
+ },
+ "update_by": {
+ "description": "更新人",
+ "type": "string"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ }
+ }
+ },
+ "model.TbAttributeDetail": {
+ "type": "object",
+ "properties": {
+ "attribute_id": {
+ "description": "规格属性id",
+ "type": "integer"
+ },
+ "value": {
+ "type": "string"
+ },
+ "value_id": {
+ "type": "integer"
+ }
+ }
+ },
+ "model.TbAttributeValueItem": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "integer"
+ },
+ "image": {
+ "description": "图片",
+ "type": "string"
+ },
+ "name": {
+ "description": "规格属性值",
+ "type": "string"
+ }
+ }
+ },
+ "model.TbAttributeWithValues": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "integer"
+ },
+ "name": {
+ "type": "string"
+ },
+ "values": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.TbAttributeValueItem"
+ }
+ }
+ }
+ },
+ "model.TbGoodsDetail": {
+ "type": "object",
+ "properties": {
+ "attributes": {
+ "description": "规格详情",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.TbAttributeWithValues"
+ }
+ },
+ "breadcrumb": {
+ "description": "分类面包屑",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.Breadcrumb"
+ }
+ },
+ "category_id": {
+ "description": "分类id",
+ "type": "integer"
+ },
+ "collect_status": {
+ "description": "收藏状态 true:已收藏 false:未收藏",
+ "type": "boolean"
+ },
+ "content": {
+ "description": "商品详情",
+ "type": "string"
+ },
+ "content_text": {
+ "description": "详情-文字",
+ "type": "string"
+ },
+ "cover": {
+ "type": "string"
+ },
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "images": {
+ "description": "图片",
+ "type": "string"
+ },
+ "list_price": {
+ "description": "列表价格",
+ "type": "number"
+ },
+ "online": {
+ "description": "上下架状态 on/off",
+ "type": "string"
+ },
+ "price_max": {
+ "description": "最高规格价格",
+ "type": "number"
+ },
+ "price_min": {
+ "description": "最低规格价格",
+ "type": "number"
+ },
+ "retail_price": {
+ "description": "吊牌价(零售指导价)",
+ "type": "number"
+ },
+ "specs": {
+ "description": "规格",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.TbGoodsSpecsDetail"
+ }
+ },
+ "spu_no": {
+ "description": "编号",
+ "type": "string"
+ },
+ "tags": {
+ "description": "标签",
+ "type": "string"
+ },
+ "title": {
+ "description": "标题",
+ "type": "string"
+ },
+ "title_eng": {
+ "description": "英文标题",
+ "type": "string"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ }
+ }
+ },
+ "model.TbGoodsSpecsDetail": {
+ "type": "object",
+ "properties": {
+ "attributes": {
+ "description": "规格详情",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.TbAttributeDetail"
+ }
+ },
+ "code": {
+ "type": "string"
+ },
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "goods_id": {
+ "type": "integer"
+ },
+ "goods_no": {
+ "description": "商品编号",
+ "type": "string"
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "image": {
+ "description": "规格图片url",
+ "type": "string"
+ },
+ "price": {
+ "description": "价格",
+ "type": "number"
+ },
+ "sku_no": {
+ "description": "商品编码",
+ "type": "string"
+ },
+ "specs": {
+ "description": "规格",
+ "type": "string"
+ },
+ "stock": {
+ "description": "库存",
+ "type": "integer"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ }
+ }
+ },
+ "model.TbGoodsSpecsView": {
+ "type": "object",
+ "properties": {
+ "attributes": {
+ "description": "规格详情",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.TbAttributeWithValues"
+ }
+ },
+ "cover": {
+ "type": "string"
+ },
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "images": {
+ "description": "图片",
+ "type": "string"
+ },
+ "price_max": {
+ "description": "最高规格价格",
+ "type": "number"
+ },
+ "price_min": {
+ "description": "最低规格价格",
+ "type": "number"
+ },
+ "retail_price": {
+ "description": "吊牌价(零售指导价)",
+ "type": "number"
+ },
+ "sales": {
+ "description": "总销售量",
+ "type": "integer"
+ },
+ "specs": {
+ "description": "规格",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.TbGoodsSpecsDetail"
+ }
+ },
+ "spu_no": {
+ "description": "编号",
+ "type": "string"
+ },
+ "stock": {
+ "description": "总库存",
+ "type": "integer"
+ },
+ "tags": {
+ "description": "标签",
+ "type": "string"
+ },
+ "title": {
+ "description": "标题",
+ "type": "string"
+ },
+ "title_eng": {
+ "description": "英文标题",
+ "type": "string"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ }
+ }
+ },
+ "model.TbOrderGoodsSpecsDetail": {
+ "type": "object",
+ "properties": {
+ "code": {
+ "description": "attribute定位标识",
+ "type": "string"
+ },
+ "goods_id": {
+ "type": "integer"
+ },
+ "goods_no": {
+ "description": "商品编号",
+ "type": "string"
+ },
+ "image": {
+ "description": "规格图片url",
+ "type": "string"
+ },
+ "orderGoodsId": {
+ "type": "integer"
+ },
+ "price": {
+ "description": "价格",
+ "type": "number"
+ },
+ "sku_no": {
+ "description": "Attributes []TbAttributeDetail ` + "`" + `gorm:\"-\" json:\"-\"` + "`" + ` // 规格详情",
+ "type": "string"
+ },
+ "specs": {
+ "description": "规格",
+ "type": "string"
+ }
+ }
+ },
+ "model.UsCitys": {
+ "type": "object",
+ "properties": {
+ "city": {
+ "type": "string"
+ },
+ "county": {
+ "type": "string"
+ },
+ "id": {
+ "type": "integer"
+ },
+ "idState": {
+ "type": "integer"
+ }
+ }
+ },
+ "model.UsSelect": {
+ "type": "object",
+ "properties": {
+ "children": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.UsCitys"
+ }
+ },
+ "id": {
+ "type": "integer"
+ },
+ "stateCode": {
+ "type": "string"
+ },
+ "stateName": {
+ "type": "string"
+ }
+ }
+ },
+ "model.UserSimple": {
+ "type": "object",
+ "properties": {
+ "avatar": {
+ "description": "头像",
+ "type": "string"
+ },
+ "email": {
+ "description": "用户邮箱",
+ "type": "string"
+ },
+ "nick_name": {
+ "description": "昵称",
+ "type": "string"
+ },
+ "phone": {
+ "description": "手机号",
+ "type": "string"
+ },
+ "platform": {
+ "description": "平台",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/request.Platform"
+ }
+ },
+ "tags": {
+ "description": "个人标签",
+ "type": "string"
+ },
+ "uuid": {
+ "description": "用户uuid编码",
+ "type": "string"
+ }
+ }
+ },
+ "model.Wallet": {
+ "type": "object",
+ "properties": {
+ "balance": {
+ "description": "可用余额",
+ "type": "number"
+ },
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "platform": {
+ "description": "平台 saller(买家端) / customer(客户端) / influencer(网红端)",
+ "type": "string"
+ },
+ "state": {
+ "description": "状态 0:正常 1:限制提现 2:禁止提现",
+ "type": "integer"
+ },
+ "transitBalance": {
+ "description": "在途余额",
+ "type": "number"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ },
+ "userId": {
+ "type": "string"
+ }
+ }
+ },
+ "model.Withdrawal": {
+ "type": "object",
+ "properties": {
+ "account_name": {
+ "description": "户名",
+ "type": "string"
+ },
+ "account_type": {
+ "description": "账户类型 1:paypal 2:银行卡",
+ "type": "integer"
+ },
+ "address": {
+ "description": "收款人地址",
+ "type": "string"
+ },
+ "amount": {
+ "description": "金额",
+ "type": "number"
+ },
+ "bank_code": {
+ "description": "收款行",
+ "type": "string"
+ },
+ "bill_no": {
+ "description": "账单号",
+ "type": "string"
+ },
+ "card_number": {
+ "description": "银行卡号",
+ "type": "string"
+ },
+ "check_status": {
+ "description": "审核状态 0:待审核 1:审核通过 2:审核未通过",
+ "type": "string"
+ },
+ "check_time": {
+ "description": "审核时间",
+ "type": "string"
+ },
+ "country": {
+ "description": "国家/地区",
+ "type": "string"
+ },
+ "create_by": {
+ "description": "创建人/店铺",
+ "type": "string"
+ },
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "currency": {
+ "description": "币种 USD:美元",
+ "type": "string"
+ },
+ "flow_no": {
+ "description": "流水号",
+ "type": "string"
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "pay_id": {
+ "description": "支付id",
+ "type": "string"
+ },
+ "platform": {
+ "description": "平台 1:网红 2:商家",
+ "type": "string"
+ },
+ "remark": {
+ "description": "备注",
+ "type": "string"
+ },
+ "status": {
+ "description": "提现状态 0:进行中 1:成功 2:失败",
+ "type": "string"
+ },
+ "swift_code": {
+ "description": "银行国际代码",
+ "type": "string"
+ },
+ "title": {
+ "description": "标题",
+ "type": "string"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ },
+ "wallet_type": {
+ "description": "钱包类型 1:余额钱包 2:营销账户钱包",
+ "type": "integer"
+ }
+ }
+ },
+ "model.WithdrawalView": {
+ "type": "object",
+ "properties": {
+ "flow_no": {
+ "description": "流水号",
+ "type": "string"
+ }
+ }
+ },
+ "request.AddAccount": {
+ "type": "object",
+ "properties": {
+ "account_name": {
+ "description": "户名",
+ "type": "string"
+ },
+ "address": {
+ "description": "收款人地址",
+ "type": "string"
+ },
+ "bank_card": {
+ "description": "银行卡号",
+ "type": "string"
+ },
+ "bank_code": {
+ "description": "银行编码",
+ "type": "string"
+ },
+ "country": {
+ "description": "国家/地区",
+ "type": "string"
+ },
+ "currency": {
+ "description": "币种 USD: 美元",
+ "type": "string"
+ },
+ "is_default": {
+ "description": "是否默认",
+ "type": "boolean"
+ },
+ "swift_code": {
+ "description": "swift编码",
+ "type": "string"
+ }
+ }
+ },
+ "request.ClaimMission": {
+ "type": "object",
+ "properties": {
+ "address_id": {
+ "description": "收货地址id",
+ "type": "integer"
+ },
+ "email": {
+ "description": "邮箱地址",
+ "type": "string"
+ },
+ "mission_id": {
+ "description": "任务id",
+ "type": "integer"
+ },
+ "sku_no": {
+ "description": "商品sku_no",
+ "type": "string"
+ },
+ "spu_no": {
+ "description": "商品spu_no",
+ "type": "string"
+ }
+ }
+ },
+ "request.ClaimMissionVideo": {
+ "type": "object",
+ "properties": {
+ "cover": {
+ "type": "string"
+ },
+ "height": {
+ "description": "高度",
+ "type": "integer"
+ },
+ "mission_claim_id": {
+ "description": "领取任务id",
+ "type": "integer"
+ },
+ "source_type": {
+ "description": "类型:1:固定费用上传 2:奖励任务上传 3:后台上传",
+ "type": "integer"
+ },
+ "video_url": {
+ "description": "视频上传地址",
+ "type": "string"
+ },
+ "width": {
+ "description": "宽度",
+ "type": "integer"
+ }
+ }
+ },
+ "request.ClaimMissionWorks": {
+ "type": "object",
+ "properties": {
+ "homepage": {
+ "description": "作品主页地址",
+ "type": "string"
+ },
+ "id": {
+ "description": "id",
+ "type": "integer"
+ },
+ "image": {
+ "description": "作品凭证截图",
+ "type": "string"
+ },
+ "type": {
+ "description": "平台 1:ins 2:Pinterest 3:tk 4:Twitter 5:Facebook 6:Reddit",
+ "type": "integer"
+ },
+ "video_url": {
+ "description": "视频上传地址",
+ "type": "string"
+ }
+ }
+ },
+ "request.ClaimMissionWorksList": {
+ "type": "object",
+ "properties": {
+ "mission_claim_id": {
+ "description": "领取任务id",
+ "type": "integer"
+ },
+ "works": {
+ "description": "作品列表",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/request.ClaimMissionWorks"
+ }
+ }
+ }
+ },
+ "request.DeleteAccount": {
+ "type": "object",
+ "properties": {
+ "code": {
+ "description": "验证码",
+ "type": "string"
+ },
+ "id": {
+ "description": "主键",
+ "type": "integer"
+ },
+ "phone": {
+ "description": "手机号",
+ "type": "string"
+ }
+ }
+ },
+ "request.IdReq": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "description": "id",
+ "type": "integer"
+ }
+ }
+ },
+ "request.MissionId": {
+ "type": "object",
+ "properties": {
+ "mission_id": {
+ "description": "任务",
+ "type": "integer"
+ }
+ }
+ },
+ "request.Platform": {
+ "type": "object",
+ "properties": {
+ "image": {
+ "description": "图片",
+ "type": "string"
+ },
+ "is_auth": {
+ "description": "是否认证",
+ "type": "boolean"
+ },
+ "label": {
+ "type": "string"
+ },
+ "platform": {
+ "description": "平台 字典表获取",
+ "type": "string"
+ },
+ "url": {
+ "description": "主页地址",
+ "type": "string"
+ }
+ }
+ },
+ "request.SendEmail": {
+ "type": "object",
+ "properties": {
+ "email": {
+ "type": "string"
+ }
+ }
+ },
+ "request.SendMessage": {
+ "type": "object",
+ "properties": {
+ "country_code": {
+ "description": "用户手机号国家代码 国际区号 86 中国 1美国",
+ "type": "string"
+ },
+ "phone": {
+ "type": "string"
+ },
+ "type": {
+ "description": "1:登录验证码 2-解绑 3-绑定 4-提现",
+ "type": "integer"
+ }
+ }
+ },
+ "request.UserAuthorized": {
+ "type": "object",
+ "properties": {
+ "appid": {
+ "description": "应用id",
+ "type": "string"
+ },
+ "client": {
+ "description": "客户端 ios android web",
+ "type": "string"
+ },
+ "code": {
+ "description": "授权码",
+ "type": "string"
+ },
+ "platform": {
+ "description": "平台 google facebook twitter tiktok",
+ "type": "string"
+ },
+ "token": {
+ "description": "token",
+ "type": "string"
+ },
+ "uuid": {
+ "description": "设备唯一标识",
+ "type": "string"
+ }
+ }
+ },
+ "request.UserBandPhone": {
+ "type": "object",
+ "properties": {
+ "code": {
+ "description": "验证码",
+ "type": "string"
+ },
+ "phone": {
+ "description": "手机号",
+ "type": "string"
+ }
+ }
+ },
+ "request.UserDetail": {
+ "type": "object",
+ "properties": {
+ "platform": {
+ "description": "平台及地址逗号隔开 eg:(ins:https://baidu.com/user/1,qq:12345678)",
+ "type": "string"
+ },
+ "tags": {
+ "description": "个人标签",
+ "type": "string"
+ },
+ "type": {
+ "description": "修改字段 platform-平台 tags-个人标签",
+ "type": "string"
+ }
+ }
+ },
+ "request.UserLogin": {
+ "type": "object",
+ "properties": {
+ "appid": {
+ "description": "应用id",
+ "type": "string"
+ },
+ "code": {
+ "description": "验证码",
+ "type": "string"
+ },
+ "country_code": {
+ "description": "用户手机号国家代码 国际区号 86 中国 1美国",
+ "type": "string"
+ },
+ "email": {
+ "description": "邮箱",
+ "type": "string"
+ },
+ "password": {
+ "description": "密码",
+ "type": "string"
+ },
+ "phone": {
+ "description": "手机号",
+ "type": "string"
+ },
+ "type": {
+ "description": "1-手机号 2-邮箱",
+ "type": "string"
+ }
+ }
+ },
+ "request.UserPlatformAuth": {
+ "type": "object",
+ "properties": {
+ "platform": {
+ "description": "平台",
+ "allOf": [
+ {
+ "$ref": "#/definitions/request.Platform"
+ }
+ ]
+ },
+ "tags": {
+ "description": "个人标签",
+ "type": "string"
+ }
+ }
+ },
+ "request.UserRegister": {
+ "type": "object",
+ "properties": {
+ "appid": {
+ "description": "应用id",
+ "type": "string"
+ },
+ "avatar": {
+ "description": "头像",
+ "type": "string"
+ },
+ "code": {
+ "description": "验证码",
+ "type": "string"
+ },
+ "country_code": {
+ "description": "用户手机号国家代码 国际区号 86 中国 1美国",
+ "type": "string"
+ },
+ "email": {
+ "description": "邮箱",
+ "type": "string"
+ },
+ "nickname": {
+ "description": "昵称",
+ "type": "string"
+ }
+ }
+ },
+ "request.WithdrawalParams": {
+ "type": "object",
+ "properties": {
+ "accountID": {
+ "description": "提现账户id",
+ "type": "integer"
+ },
+ "amount": {
+ "description": "Code string ` + "`" + `json:\"code\"` + "`" + ` // 验证码",
+ "type": "number"
+ }
+ }
+ },
+ "response.BannerListResponse": {
+ "type": "object",
+ "properties": {
+ "coverUrl": {
+ "description": "封面图",
+ "type": "string"
+ },
+ "id": {
+ "description": "主键",
+ "type": "integer"
+ },
+ "link": {
+ "description": "链接地址",
+ "type": "string"
+ },
+ "linkType": {
+ "description": "链接类型 0:内链 1:外链",
+ "type": "string"
+ },
+ "relationId": {
+ "description": "关联项目id",
+ "type": "string"
+ },
+ "relationType": {
+ "description": "关联类型 01-任务",
+ "type": "string"
+ },
+ "sort_index": {
+ "description": "序号索引",
+ "type": "integer"
+ },
+ "status": {
+ "description": "状态 0=下架 1=上架",
+ "type": "string"
+ },
+ "title": {
+ "description": "标题",
+ "type": "string"
+ },
+ "type": {
+ "description": "任务-0101 平台奖励页-0102",
+ "type": "string"
+ }
+ }
+ },
+ "response.ChainResp": {
+ "type": "object",
+ "properties": {
+ "block_adress": {
+ "description": "所在区块",
+ "type": "string"
+ },
+ "block_height": {
+ "description": "块高度",
+ "type": "integer"
+ },
+ "hash": {
+ "description": "交易哈希",
+ "type": "string"
+ },
+ "time": {
+ "description": "上链时间",
+ "type": "string"
+ }
+ }
+ },
+ "response.MissionRecommendResponse": {
+ "type": "object",
+ "properties": {
+ "achieve_num": {
+ "description": "已完成商品数量",
+ "type": "integer"
+ },
+ "bought_num": {
+ "description": "购买人数",
+ "type": "number"
+ },
+ "claim_num": {
+ "description": "任务领取人数",
+ "type": "integer"
+ },
+ "cover": {
+ "description": "封面",
+ "type": "string"
+ },
+ "create_by": {
+ "description": "创建人",
+ "type": "string"
+ },
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "end_time": {
+ "description": "任务结束时间",
+ "type": "string"
+ },
+ "goods_title": {
+ "description": "商品标题",
+ "type": "string"
+ },
+ "goods_title_eng": {
+ "description": "商品英文标题",
+ "type": "string"
+ },
+ "height": {
+ "description": "高度",
+ "type": "integer"
+ },
+ "hire_money": {
+ "description": "hire_type==1 佣金金额",
+ "type": "number"
+ },
+ "hire_money_expect": {
+ "description": "预计佣金描述",
+ "type": "string"
+ },
+ "hire_ratio": {
+ "description": "hire_type==2 抽成比例",
+ "type": "number"
+ },
+ "hire_type": {
+ "description": "佣金类型 1:固定佣金 2:比例抽成",
+ "type": "integer"
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "influencer": {
+ "$ref": "#/definitions/model.UserSimple"
+ },
+ "mission_id": {
+ "description": "任务ID",
+ "type": "integer"
+ },
+ "mission_status": {
+ "description": "任务状态",
+ "type": "integer"
+ },
+ "relation_id": {
+ "description": "关联ID,任务视频ID",
+ "type": "integer"
+ },
+ "release_channels": {
+ "description": "发布渠道",
+ "type": "string"
+ },
+ "release_country": {
+ "description": "发布国家",
+ "type": "string"
+ },
+ "sort": {
+ "description": "倒序 //排序",
+ "type": "integer"
+ },
+ "start_time": {
+ "description": "任务起始时间",
+ "type": "string"
+ },
+ "status": {
+ "description": "状态 1:上架 2:下架",
+ "type": "integer"
+ },
+ "tag": {
+ "description": "todo 标签系统",
+ "type": "string"
+ },
+ "title": {
+ "description": "任务标题",
+ "type": "string"
+ },
+ "total_bonus": {
+ "description": "累计奖励",
+ "type": "number"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ },
+ "video_url": {
+ "description": "视频地址",
+ "type": "string"
+ },
+ "width": {
+ "description": "宽度",
+ "type": "integer"
+ }
+ }
+ },
+ "response.SysBonusDetail": {
+ "type": "object",
+ "properties": {
+ "achieve_max": {
+ "description": "最大完成次数",
+ "type": "integer"
+ },
+ "achieve_num": {
+ "description": "已完成任务次数",
+ "type": "integer"
+ },
+ "bonus": {
+ "description": "奖金",
+ "type": "number"
+ },
+ "mission_list": {
+ "description": "任务列表",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/response.SysMissionDesc"
+ }
+ },
+ "title": {
+ "description": "标题",
+ "type": "string"
+ },
+ "total": {
+ "description": "奖励次数",
+ "type": "integer"
+ },
+ "type": {
+ "description": "奖励类型 1.视频上传 2.信息完善 3.商家任务",
+ "type": "integer"
+ }
+ }
+ },
+ "response.SysMissionBonus": {
+ "type": "object",
+ "properties": {
+ "total": {
+ "description": "奖励总笔数",
+ "type": "integer"
+ },
+ "total_bonus": {
+ "description": "奖励汇总金额",
+ "type": "number"
+ },
+ "video_bonus": {
+ "description": "视频上传",
+ "allOf": [
+ {
+ "$ref": "#/definitions/response.SysBonusDetail"
+ }
+ ]
+ }
+ }
+ },
+ "response.SysMissionDesc": {
+ "type": "object",
+ "properties": {
+ "achieve_num": {
+ "type": "integer"
+ },
+ "bonus": {
+ "description": "奖励金额",
+ "type": "number"
+ },
+ "description": {
+ "description": "描述",
+ "type": "string"
+ },
+ "description_eng": {
+ "description": "描述英文",
+ "type": "string"
+ },
+ "status": {
+ "description": "状态 1待发放 2已发放 3已领取 0未完成",
+ "type": "integer"
+ },
+ "title": {
+ "description": "任务标题",
+ "type": "string"
+ },
+ "title_eng": {
+ "description": "任务标题英文",
+ "type": "string"
+ }
+ }
+ },
+ "response.UserStatistics": {
+ "type": "object",
+ "properties": {
+ "claim_mission_num": {
+ "description": "领取任务数量",
+ "type": "integer"
+ },
+ "collection_mission_num": {
+ "description": "收藏任务数量",
+ "type": "integer"
+ },
+ "platform_num": {
+ "description": "认证平台数量",
+ "type": "integer"
+ }
+ }
+ }
+ },
+ "securityDefinitions": {
+ "ApiKeyAuth": {
+ "type": "apiKey",
+ "name": "x-token",
+ "in": "header"
+ }
+ }
+}`
+
+// SwaggerInfo holds exported Swagger Info so clients can modify it
+var SwaggerInfo = &swag.Spec{
+ Version: "0.0.1",
+ Host: "",
+ BasePath: "",
+ Schemes: []string{},
+ Title: "Swagger Example API",
+ Description: "接口文档",
+ InfoInstanceName: "swagger",
+ SwaggerTemplate: docTemplate,
+}
+
+func init() {
+ swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo)
+}
diff --git a/docs/swagger.json b/docs/swagger.json
new file mode 100644
index 0000000..1b2ac21
--- /dev/null
+++ b/docs/swagger.json
@@ -0,0 +1,4354 @@
+{
+ "swagger": "2.0",
+ "info": {
+ "description": "接口文档",
+ "title": "Swagger Example API",
+ "contact": {},
+ "version": "0.0.1"
+ },
+ "paths": {
+ "/base/authorized": {
+ "post": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "auth"
+ ],
+ "summary": "授权登录[v1.0.0]",
+ "parameters": [
+ {
+ "description": "email,password...",
+ "name": "data",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/request.UserAuthorized"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/base/sendEmail": {
+ "post": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "tags": [
+ "tools"
+ ],
+ "summary": "发送邮件验证码[v1.0.0]",
+ "parameters": [
+ {
+ "description": "phone,type",
+ "name": "data",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/request.SendEmail"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"success\":true,\"data\":{},\"msg\":\"获取成功\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/base/sendMessage": {
+ "post": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "tags": [
+ "tools"
+ ],
+ "summary": "发送短信验证码[v1.0.0]",
+ "parameters": [
+ {
+ "description": "phone,type",
+ "name": "data",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/request.SendMessage"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"success\":true,\"data\":{},\"msg\":\"获取成功\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/customer/base/brochure": {
+ "get": {
+ "tags": [
+ "tools"
+ ],
+ "summary": "隐私协议单页",
+ "parameters": [
+ {
+ "type": "string",
+ "name": "type",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"success\":true,\"data\":{},\"msg\":\"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/dict/getDictDataList": {
+ "get": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "tags": [
+ "dict"
+ ],
+ "summary": "获取数据字典取值列表【v1.0】",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "取值 release_country=发布国家 release_channel=发布渠道 tag_type=标签类型",
+ "name": "typeCode",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"success\":true,\"data\":{},\"msg\":\"获取成功\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/global/address": {
+ "get": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "公用-收货地址"
+ ],
+ "summary": "获取用户收货地址列表【v1.0】",
+ "responses": {
+ "200": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "put": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "公用-收货地址"
+ ],
+ "summary": "修改收货地址【v1.0】",
+ "parameters": [
+ {
+ "description": "data...",
+ "name": "data",
+ "in": "body",
+ "schema": {
+ "$ref": "#/definitions/model.Address"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "post": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "公用-收货地址"
+ ],
+ "summary": "添加收货地址【v1.0】",
+ "parameters": [
+ {
+ "description": "data...",
+ "name": "data",
+ "in": "body",
+ "schema": {
+ "$ref": "#/definitions/model.Address"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "delete": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "公用-收货地址"
+ ],
+ "summary": "删除收货地址【v1.0】",
+ "parameters": [
+ {
+ "description": "data...",
+ "name": "data",
+ "in": "body",
+ "schema": {
+ "$ref": "#/definitions/global.BASE_ID"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/global/track": {
+ "get": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "track"
+ ],
+ "summary": "查询物流信息",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "id",
+ "name": "id",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/global/usSelect": {
+ "get": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "公用-收货地址"
+ ],
+ "summary": "美国地区选择器【v1.0】",
+ "responses": {
+ "200": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/banner/list": {
+ "get": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "tags": [
+ "banner"
+ ],
+ "summary": "分页获取banner列表【v1.1.0新增】",
+ "responses": {
+ "200": {
+ "description": "{\"success\":true,\"data\":{},\"msg\":\"获取成功\"}",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/response.BannerListResponse"
+ }
+ }
+ }
+ }
+ }
+ },
+ "/influencer/base/brochure": {
+ "get": {
+ "tags": [
+ "tools"
+ ],
+ "summary": "隐私协议单页",
+ "parameters": [
+ {
+ "type": "string",
+ "name": "type",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"success\":true,\"data\":{},\"msg\":\"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/base/chain": {
+ "get": {
+ "tags": [
+ "Chain"
+ ],
+ "summary": "获取区块链数据",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "区块/合约hash",
+ "name": "hash",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": [...]}",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/response.ChainResp"
+ }
+ }
+ },
+ "201": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/base/login": {
+ "post": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "auth"
+ ],
+ "summary": "登录[v1.0.0]",
+ "parameters": [
+ {
+ "description": "email,password...",
+ "name": "data",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/request.UserLogin"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/base/register": {
+ "post": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "auth"
+ ],
+ "summary": "注册[v1.0.0]",
+ "parameters": [
+ {
+ "description": "email,password...",
+ "name": "data",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/request.UserRegister"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/base/version": {
+ "get": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "version"
+ ],
+ "summary": "获取版本信息",
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": [...]}",
+ "schema": {
+ "type": "string"
+ }
+ },
+ "201": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/goods/detail": {
+ "get": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "tags": [
+ "goods"
+ ],
+ "summary": "获取商品详情",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "领取任务id",
+ "name": "claim_no",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "商品id",
+ "name": "id",
+ "in": "query"
+ },
+ {
+ "type": "string",
+ "description": "sku_no",
+ "name": "sku_no",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 200, \"data\": {}}",
+ "schema": {
+ "$ref": "#/definitions/model.TbGoodsDetail"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/mission/bonus": {
+ "get": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "tags": [
+ "mission"
+ ],
+ "summary": "获取任务累计奖金",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "任务编码",
+ "name": "code",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 200, \"data\": {}}",
+ "schema": {
+ "$ref": "#/definitions/model.MissionBonus"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/mission/claim": {
+ "get": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "tags": [
+ "mission"
+ ],
+ "summary": "获取我的任务详情【v1.0】",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "id",
+ "name": "id",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 200, \"data\": {}}",
+ "schema": {
+ "$ref": "#/definitions/model.MissionClaimDetail"
+ }
+ }
+ }
+ },
+ "post": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "tags": [
+ "mission"
+ ],
+ "summary": "领取任务【v1.0】",
+ "parameters": [
+ {
+ "description": "params",
+ "name": "data",
+ "in": "body",
+ "schema": {
+ "$ref": "#/definitions/request.ClaimMission"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 200, \"data\": {}}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/mission/claim-list": {
+ "get": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "tags": [
+ "mission"
+ ],
+ "summary": "获取我的任务列表【v1.0】",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "佣金类型 1:固定佣金 2:比例抽成",
+ "name": "hire_type",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "页码",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "每页大小",
+ "name": "pageSize",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "是否筛选上传视频 1是",
+ "name": "video_upload",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 200, \"data\": {}}",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.MissionClaimDetail"
+ }
+ }
+ }
+ }
+ }
+ },
+ "/influencer/mission/collect": {
+ "post": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "tags": [
+ "mission"
+ ],
+ "summary": "收藏/取消收藏任务【v1.0】",
+ "parameters": [
+ {
+ "description": "params",
+ "name": "data",
+ "in": "body",
+ "schema": {
+ "$ref": "#/definitions/request.MissionId"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 200, \"data\": {}}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/mission/collect-list": {
+ "get": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "tags": [
+ "mission"
+ ],
+ "summary": "获取收藏任务列表【v1.0】",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "页码",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "每页大小",
+ "name": "pageSize",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 200, \"data\": {}}",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.MissionDetail"
+ }
+ }
+ }
+ }
+ }
+ },
+ "/influencer/mission/detail": {
+ "get": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "tags": [
+ "mission"
+ ],
+ "summary": "获取任务详情【v1.0】",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "id",
+ "name": "id",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 200, \"data\": {}}",
+ "schema": {
+ "$ref": "#/definitions/model.MissionDetail"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/mission/list": {
+ "get": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "tags": [
+ "mission"
+ ],
+ "summary": "获取任务列表【v1.0】",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "页码",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "每页大小",
+ "name": "pageSize",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 200, \"data\": {}}",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.MissionDetail"
+ }
+ }
+ }
+ }
+ }
+ },
+ "/influencer/mission/order-data": {
+ "get": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "mission"
+ ],
+ "summary": "获取任务下订单统计数据",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "任务编码",
+ "name": "code",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": [...]}",
+ "schema": {
+ "$ref": "#/definitions/dto.MissionOrderStatistic"
+ }
+ },
+ "201": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/mission/recommend-detail": {
+ "get": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "tags": [
+ "mission"
+ ],
+ "summary": "获取首页任务详情【v1.0】",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "id",
+ "name": "id",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 200, \"data\": {}}",
+ "schema": {
+ "$ref": "#/definitions/response.MissionRecommendResponse"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/mission/recommend-list": {
+ "get": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "tags": [
+ "mission"
+ ],
+ "summary": "获取首页任务列表【v1.0】",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "页码",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "每页大小",
+ "name": "pageSize",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 200, \"data\": {}}",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/response.MissionRecommendResponse"
+ }
+ }
+ }
+ }
+ }
+ },
+ "/influencer/mission/submit-video": {
+ "post": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "tags": [
+ "mission"
+ ],
+ "summary": "固定费用任务上传视频【v1.0】",
+ "parameters": [
+ {
+ "description": "params",
+ "name": "data",
+ "in": "body",
+ "schema": {
+ "$ref": "#/definitions/request.ClaimMissionVideo"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 200, \"data\": {}}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/mission/submit-works": {
+ "post": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "tags": [
+ "mission"
+ ],
+ "summary": "领取任务的提交作品【v1.0】",
+ "parameters": [
+ {
+ "description": "params",
+ "name": "data",
+ "in": "body",
+ "schema": {
+ "$ref": "#/definitions/request.ClaimMissionWorksList"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 200, \"data\": {}}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/mission/sys-reward-list": {
+ "get": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "tags": [
+ "mission"
+ ],
+ "summary": "获取平台奖励列表【v1.0】",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "页码",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "每页大小",
+ "name": "pageSize",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "状态 1待发放 2已发放 3已领取",
+ "name": "status",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 200, \"data\": {}}",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.SysMissionReward"
+ }
+ }
+ }
+ }
+ }
+ },
+ "/influencer/mission/sys-reward-summary": {
+ "get": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "tags": [
+ "mission"
+ ],
+ "summary": "获取平台奖励汇总【v1.0】",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "状态 1待发放 2已发放 3已领取",
+ "name": "status",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 200, \"data\": {}}",
+ "schema": {
+ "$ref": "#/definitions/response.SysMissionBonus"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/order/data": {
+ "get": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "order"
+ ],
+ "summary": "获取订单数据",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "场景 my:我的 order-list:订单列表",
+ "name": "scene",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": [...]}",
+ "schema": {
+ "$ref": "#/definitions/dto.OrderData"
+ }
+ },
+ "201": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/order/detail": {
+ "get": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "order"
+ ],
+ "summary": "获取订单详情",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "订单号",
+ "name": "orderID",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": [...]}",
+ "schema": {
+ "$ref": "#/definitions/model.OrderDetail"
+ }
+ },
+ "201": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/order/goods/snapshot": {
+ "get": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "order"
+ ],
+ "summary": "获取订单商品快照",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "订单号",
+ "name": "orderID",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": [...]}",
+ "schema": {
+ "$ref": "#/definitions/model.OrderGoodsDetail"
+ }
+ },
+ "201": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/order/list": {
+ "get": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "order"
+ ],
+ "summary": "获取订单列表",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "网红码?",
+ "name": "code",
+ "in": "query"
+ },
+ {
+ "type": "string",
+ "description": "数据库分组",
+ "name": "group",
+ "in": "query"
+ },
+ {
+ "type": "string",
+ "description": "订单号",
+ "name": "orderID",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "页码",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "每页大小",
+ "name": "pageSize",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "订单状态 //订单状态 1-待付款 2-待发货 3-已发货 4-已完成 5-已取消",
+ "name": "status",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": [...]}",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.OrderList"
+ }
+ }
+ },
+ "201": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/user/bandPhone": {
+ "post": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "网红端-用户"
+ ],
+ "summary": "网红绑定手机[v1.0.0]",
+ "parameters": [
+ {
+ "description": "email,password...",
+ "name": "data",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/request.UserBandPhone"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/user/detail": {
+ "get": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "网红端-用户"
+ ],
+ "summary": "获取用户基本信息[v1.0.0]",
+ "responses": {
+ "200": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "put": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "网红端-用户"
+ ],
+ "summary": "修改用户基本信息",
+ "parameters": [
+ {
+ "description": "data...",
+ "name": "data",
+ "in": "body",
+ "schema": {
+ "$ref": "#/definitions/request.UserDetail"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/user/logoff": {
+ "post": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "网红端-用户"
+ ],
+ "summary": "注销账户[v1.0.1]",
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": \"注销成功\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/user/platformAuth": {
+ "post": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "网红端-用户"
+ ],
+ "summary": "平台认证[v1.0.0]",
+ "parameters": [
+ {
+ "description": "email,password...",
+ "name": "data",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/request.UserPlatformAuth"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/user/statistics": {
+ "get": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "网红端-用户"
+ ],
+ "summary": "获取用户统计信息[v1.0.0]",
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": [...]}",
+ "schema": {
+ "$ref": "#/definitions/response.UserStatistics"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/wallet/account": {
+ "post": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "网红端-用户钱包"
+ ],
+ "summary": "添加账户",
+ "parameters": [
+ {
+ "description": "data...",
+ "name": "data",
+ "in": "body",
+ "schema": {
+ "$ref": "#/definitions/request.AddAccount"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": [...]}",
+ "schema": {
+ "type": "string"
+ }
+ },
+ "201": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "delete": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "网红端-用户钱包"
+ ],
+ "summary": "解绑账户",
+ "parameters": [
+ {
+ "description": "data...",
+ "name": "data",
+ "in": "body",
+ "schema": {
+ "$ref": "#/definitions/request.DeleteAccount"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": [...]}",
+ "schema": {
+ "type": "string"
+ }
+ },
+ "201": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/wallet/account/default": {
+ "put": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "网红端-用户钱包"
+ ],
+ "summary": "设置账户默认开关",
+ "parameters": [
+ {
+ "description": "data...",
+ "name": "data",
+ "in": "body",
+ "schema": {
+ "$ref": "#/definitions/request.IdReq"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": [...]}",
+ "schema": {
+ "type": "string"
+ }
+ },
+ "201": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/wallet/accountList": {
+ "get": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "网红端-用户钱包"
+ ],
+ "summary": "获取账户列表",
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": [...]}",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.Account"
+ }
+ }
+ },
+ "201": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/wallet/bill-list": {
+ "get": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "对账中心"
+ ],
+ "summary": "获取资金流水记录",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "页码",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "每页大小",
+ "name": "pageSize",
+ "in": "query"
+ },
+ {
+ "type": "string",
+ "description": "空:默认 1:bill-center",
+ "name": "scene",
+ "in": "query"
+ },
+ {
+ "type": "string",
+ "description": "空:全部 1-支出 2-收入",
+ "name": "status",
+ "in": "query"
+ },
+ {
+ "type": "string",
+ "description": "1:全部 2:昨天 3:近30天",
+ "name": "uint",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": [...]}",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.Bill"
+ }
+ }
+ },
+ "201": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/wallet/bill-notify": {
+ "get": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "对账中心"
+ ],
+ "summary": "获取账单通知列表",
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": [...]}",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.BillNotify"
+ }
+ }
+ },
+ "201": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/wallet/bill/data": {
+ "get": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "对账中心"
+ ],
+ "summary": "获取对账中心数据",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "1:全部 2:昨天 3:近30天",
+ "name": "uint",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": [...]}",
+ "schema": {
+ "$ref": "#/definitions/dto.BillData"
+ }
+ },
+ "201": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/wallet/detail": {
+ "get": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "网红端-用户钱包"
+ ],
+ "summary": "钱包基本信息",
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": [...]}",
+ "schema": {
+ "$ref": "#/definitions/model.Wallet"
+ }
+ },
+ "201": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/wallet/withdrawal": {
+ "get": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "对账中心"
+ ],
+ "summary": "获取提现详情",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "流水号",
+ "name": "flow_no",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": [...]}",
+ "schema": {
+ "$ref": "#/definitions/model.Withdrawal"
+ }
+ },
+ "201": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "post": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "网红端-用户钱包"
+ ],
+ "summary": "提现",
+ "parameters": [
+ {
+ "description": "data...",
+ "name": "data",
+ "in": "body",
+ "schema": {
+ "$ref": "#/definitions/request.WithdrawalParams"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "/influencer/wallet/withdrawal-list": {
+ "get": {
+ "security": [
+ {
+ "Bearer": []
+ }
+ ],
+ "tags": [
+ "对账中心"
+ ],
+ "summary": "获取提现记录",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "页码",
+ "name": "page",
+ "in": "query"
+ },
+ {
+ "type": "integer",
+ "description": "每页大小",
+ "name": "pageSize",
+ "in": "query"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{\"code\": 0, \"data\": [...]}",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.Withdrawal"
+ }
+ }
+ },
+ "201": {
+ "description": "{\"code\": 1, \"message\": \"\"}",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "definitions": {
+ "dto.BillData": {
+ "type": "object",
+ "properties": {
+ "cancelOrderMoney": {
+ "description": "退款订单总额",
+ "type": "number"
+ },
+ "cancelOrderNum": {
+ "description": "退款订单数",
+ "type": "integer"
+ },
+ "flowExpend": {
+ "description": "出账",
+ "type": "number"
+ },
+ "flowIncome": {
+ "description": "进账",
+ "type": "number"
+ },
+ "income": {
+ "description": "收入总额",
+ "type": "number"
+ },
+ "orderMoney": {
+ "description": "订单总额",
+ "type": "number"
+ },
+ "orderNum": {
+ "description": "订单数",
+ "type": "integer"
+ },
+ "rewardUnfinished": {
+ "description": "在途佣金",
+ "type": "number"
+ }
+ }
+ },
+ "dto.MissionOrderStatistic": {
+ "type": "object",
+ "properties": {
+ "OrderMoney": {
+ "description": "订单金额",
+ "type": "number"
+ },
+ "OrderUserNum": {
+ "description": "下单人数",
+ "type": "integer"
+ },
+ "RewardRatio": {
+ "description": "佣金比例",
+ "type": "number"
+ },
+ "SellNum": {
+ "description": "销售数量",
+ "type": "integer"
+ },
+ "SettleReward": {
+ "description": "结算佣金",
+ "type": "number"
+ },
+ "TransitReward": {
+ "description": "在途佣金",
+ "type": "number"
+ },
+ "Uv": {
+ "description": "浏览人数",
+ "type": "integer"
+ },
+ "orderDoneNum": {
+ "description": "完成订单总数",
+ "type": "integer"
+ },
+ "orderNum": {
+ "description": "订单总数",
+ "type": "integer"
+ }
+ }
+ },
+ "dto.OrderData": {
+ "type": "object",
+ "properties": {
+ "all": {
+ "description": "全部",
+ "type": "integer"
+ },
+ "cancel": {
+ "description": "已取消",
+ "type": "integer"
+ },
+ "finished": {
+ "description": "已完成",
+ "type": "integer"
+ },
+ "shipped": {
+ "description": "已发货",
+ "type": "integer"
+ },
+ "unship": {
+ "description": "待发货",
+ "type": "integer"
+ }
+ }
+ },
+ "global.BASE_ID": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "description": "主键",
+ "type": "integer"
+ }
+ }
+ },
+ "model.Account": {
+ "type": "object",
+ "properties": {
+ "account_name": {
+ "description": "户名",
+ "type": "string"
+ },
+ "address": {
+ "description": "收款人地址",
+ "type": "string"
+ },
+ "bank_code": {
+ "description": "收款行",
+ "type": "string"
+ },
+ "card_number": {
+ "description": "银行卡号",
+ "type": "string"
+ },
+ "country": {
+ "description": "国家/地区",
+ "type": "string"
+ },
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "currency": {
+ "description": "币种 USD:美元",
+ "type": "string"
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "idCard": {
+ "type": "string"
+ },
+ "is_default": {
+ "description": "是否为默认 0:非默认 1:默认",
+ "type": "boolean"
+ },
+ "phone": {
+ "type": "string"
+ },
+ "platform": {
+ "description": "平台 saller(买家端) / customer(客户端) / influencer(网红端)",
+ "type": "string"
+ },
+ "sort": {
+ "description": "排序值",
+ "type": "integer"
+ },
+ "swift_code": {
+ "description": "银行国际代码",
+ "type": "string"
+ },
+ "type": {
+ "description": "类型 1:paypal 2:银行卡",
+ "type": "integer"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ },
+ "userID": {
+ "description": "用户id",
+ "type": "string"
+ }
+ }
+ },
+ "model.Address": {
+ "type": "object",
+ "properties": {
+ "bldg": {
+ "description": "apt,ste,bldg",
+ "type": "string"
+ },
+ "city": {
+ "description": "city",
+ "type": "string"
+ },
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "default": {
+ "description": "是否默认地址 1-是 2-否",
+ "type": "integer"
+ },
+ "firstName": {
+ "description": "first name",
+ "type": "string"
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "lastName": {
+ "description": "last name",
+ "type": "string"
+ },
+ "phone": {
+ "description": "手机号",
+ "type": "string"
+ },
+ "platform": {
+ "description": "平台 saller(买家端) / customer(客户端) / influencer(网红端)",
+ "type": "string"
+ },
+ "state": {
+ "description": "state",
+ "type": "string"
+ },
+ "street": {
+ "description": "street",
+ "type": "string"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ },
+ "userId": {
+ "type": "string"
+ },
+ "zipCode": {
+ "description": "zip code",
+ "type": "string"
+ }
+ }
+ },
+ "model.Bill": {
+ "type": "object",
+ "properties": {
+ "account": {
+ "description": "收款账户(提现)",
+ "type": "string"
+ },
+ "amount": {
+ "description": "数量",
+ "type": "integer"
+ },
+ "balance": {
+ "description": "余额",
+ "type": "number"
+ },
+ "check_status": {
+ "description": "审核状态 0:待审核 1:审核通过 2:审核未通过",
+ "type": "string"
+ },
+ "claim_no": {
+ "description": "领取任务编号",
+ "type": "string"
+ },
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "order_id": {
+ "description": "关联订单id",
+ "type": "string"
+ },
+ "platform": {
+ "description": "平台 seller(买家端) / customer(客户端) / influencer(网红端)",
+ "type": "string"
+ },
+ "price": {
+ "description": "金额",
+ "type": "number"
+ },
+ "receipt": {
+ "description": "是否已到账 1-是 2-否 3-已取消付款",
+ "type": "integer"
+ },
+ "remark": {
+ "description": "备注",
+ "type": "string"
+ },
+ "status": {
+ "description": "类型 1-支出 2-收入",
+ "type": "integer"
+ },
+ "title": {
+ "description": "账单标题",
+ "type": "string"
+ },
+ "transaction_id": {
+ "description": "交易编号",
+ "type": "string"
+ },
+ "type": {
+ "description": "类型 1-佣金 2-订单 3-提现 4-平台奖励",
+ "type": "string"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ },
+ "userID": {
+ "description": "用户id",
+ "type": "string"
+ },
+ "withd_id": {
+ "description": "提现id",
+ "type": "string"
+ },
+ "withdrawalStatus": {
+ "description": "提现状态 0-提现中 1-提现完成 2-提现失败",
+ "type": "integer"
+ }
+ }
+ },
+ "model.BillNotify": {
+ "type": "object",
+ "properties": {
+ "relation_id": {
+ "description": "关联id",
+ "type": "string"
+ },
+ "relation_type": {
+ "description": "关联类型",
+ "type": "string"
+ },
+ "title": {
+ "description": "标题",
+ "type": "string"
+ }
+ }
+ },
+ "model.BillView": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "description": "id",
+ "type": "integer"
+ },
+ "order_id": {
+ "description": "订单编号",
+ "type": "string"
+ },
+ "transaction_id": {
+ "description": "交易编号",
+ "type": "string"
+ }
+ }
+ },
+ "model.Breadcrumb": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "integer"
+ },
+ "is_leaf": {
+ "description": "是否叶子分类",
+ "type": "boolean"
+ },
+ "name": {
+ "type": "string"
+ },
+ "pid": {
+ "description": "父id",
+ "type": "integer"
+ }
+ }
+ },
+ "model.Chain": {
+ "type": "object",
+ "properties": {
+ "address": {
+ "description": "合约地址",
+ "type": "string"
+ }
+ }
+ },
+ "model.MissionBonus": {
+ "type": "object",
+ "properties": {
+ "total": {
+ "type": "number"
+ },
+ "user_total": {
+ "type": "number"
+ }
+ }
+ },
+ "model.MissionClaimDetail": {
+ "type": "object",
+ "properties": {
+ "achieve_num": {
+ "description": "已完成商品数量",
+ "type": "integer"
+ },
+ "claim_no": {
+ "description": "领取任务编号",
+ "type": "string"
+ },
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "email": {
+ "description": "发送邮箱",
+ "type": "string"
+ },
+ "expire_at": {
+ "description": "任务推广过期时间",
+ "type": "string"
+ },
+ "finished": {
+ "description": "任务完成状态 0:未完成 1:已完成",
+ "type": "integer"
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "mission": {
+ "description": "关联任务",
+ "allOf": [
+ {
+ "$ref": "#/definitions/model.MissionDetail"
+ }
+ ]
+ },
+ "mission_id": {
+ "description": "任务id",
+ "type": "integer"
+ },
+ "order": {
+ "description": "任务订单",
+ "allOf": [
+ {
+ "$ref": "#/definitions/model.MissionClaimOrderInfo"
+ }
+ ]
+ },
+ "spread_url": {
+ "description": "推广链接",
+ "type": "string"
+ },
+ "status": {
+ "description": "状态 1:已领取待发货 2:已发货 3:已收货推广中",
+ "type": "integer"
+ },
+ "status_except": {
+ "description": "状态描述",
+ "type": "string"
+ },
+ "total_bonus": {
+ "description": "累计佣金",
+ "type": "integer"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ },
+ "video": {
+ "description": "上传视频",
+ "allOf": [
+ {
+ "$ref": "#/definitions/model.MissionClaimVideo"
+ }
+ ]
+ },
+ "works": {
+ "description": "发布作品",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.MissionClaimWorks"
+ }
+ }
+ }
+ },
+ "model.MissionClaimOrderGoods": {
+ "type": "object",
+ "properties": {
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "image": {
+ "description": "规格图片url",
+ "type": "string"
+ },
+ "order_id": {
+ "description": "订单号",
+ "type": "string"
+ },
+ "price": {
+ "description": "价格",
+ "type": "number"
+ },
+ "sku_no": {
+ "description": "sku编号",
+ "type": "string"
+ },
+ "specs": {
+ "description": "规格",
+ "type": "string"
+ },
+ "title": {
+ "description": "名称",
+ "type": "string"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ }
+ }
+ },
+ "model.MissionClaimOrderInfo": {
+ "type": "object",
+ "properties": {
+ "courier": {
+ "description": "快递公司",
+ "type": "string"
+ },
+ "courier_number": {
+ "description": "快递单号",
+ "type": "string"
+ },
+ "courier_url": {
+ "description": "快递查询地址",
+ "type": "string"
+ },
+ "deliver": {
+ "description": "发货信息",
+ "allOf": [
+ {
+ "$ref": "#/definitions/model.OrderDeliver"
+ }
+ ]
+ },
+ "mission_claim_id": {
+ "description": "领取任务id",
+ "type": "integer"
+ },
+ "order_goods": {
+ "description": "订单商品信息",
+ "allOf": [
+ {
+ "$ref": "#/definitions/model.MissionClaimOrderGoods"
+ }
+ ]
+ },
+ "order_id": {
+ "description": "订单号",
+ "type": "string"
+ },
+ "send_time": {
+ "description": "发货时间",
+ "type": "string"
+ },
+ "status": {
+ "description": "订单状态 2:待发货 3:已发货",
+ "type": "integer"
+ }
+ }
+ },
+ "model.MissionClaimVideo": {
+ "type": "object",
+ "properties": {
+ "cover": {
+ "description": "视频封面",
+ "type": "string"
+ },
+ "create_by": {
+ "description": "创建人",
+ "type": "string"
+ },
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "height": {
+ "description": "高度",
+ "type": "integer"
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "mission_claim_id": {
+ "description": "领取任务id",
+ "type": "integer"
+ },
+ "mission_id": {
+ "description": "任务ID",
+ "type": "integer"
+ },
+ "remark": {
+ "type": "string"
+ },
+ "reward_status": {
+ "description": "奖励发放状态 1:未发放 2:已发放",
+ "type": "integer"
+ },
+ "source_type": {
+ "description": "类型:1:固定费用上传 2:奖励任务上传 3:后台上传",
+ "type": "integer"
+ },
+ "status": {
+ "description": "状态 1:待审核 2:审核通过 3:审核不通过",
+ "type": "integer"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ },
+ "video_url": {
+ "description": "视频上传地址",
+ "type": "string"
+ },
+ "width": {
+ "description": "宽度",
+ "type": "integer"
+ }
+ }
+ },
+ "model.MissionClaimWorks": {
+ "type": "object",
+ "properties": {
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "homepage": {
+ "description": "作品主页地址",
+ "type": "string"
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "image": {
+ "description": "作品凭证截图",
+ "type": "string"
+ },
+ "mission_claim_id": {
+ "description": "领取任务id",
+ "type": "integer"
+ },
+ "type": {
+ "description": "平台 1:ins 2:YouTube 3:tiktok 4:Facebook 5:Twitter",
+ "type": "integer"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ },
+ "video_url": {
+ "description": "视频上传地址",
+ "type": "string"
+ }
+ }
+ },
+ "model.MissionDetail": {
+ "type": "object",
+ "properties": {
+ "claim_days": {
+ "description": "任务完成天数",
+ "type": "integer"
+ },
+ "claim_demands": {
+ "description": "任务拍摄要求",
+ "type": "string"
+ },
+ "claim_num": {
+ "description": "接任务人数",
+ "type": "integer"
+ },
+ "claim_status_except": {
+ "description": "可接任务状态描述",
+ "type": "string"
+ },
+ "claim_status_except_eng": {
+ "description": "英文版状态描述",
+ "type": "string"
+ },
+ "claim_stock": {
+ "description": "可接任务库存",
+ "type": "integer"
+ },
+ "collect_status": {
+ "description": "收藏状态 true:已收藏 false:未收藏",
+ "type": "boolean"
+ },
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "description": {
+ "description": "描述/卖点",
+ "type": "string"
+ },
+ "end_time": {
+ "description": "任务结束时间",
+ "type": "string"
+ },
+ "goods": {
+ "description": "商品信息",
+ "allOf": [
+ {
+ "$ref": "#/definitions/model.TbGoodsSpecsView"
+ }
+ ]
+ },
+ "goods_status": {
+ "description": "关联商品状态 1:正常 2:已下架",
+ "type": "integer"
+ },
+ "goods_url": {
+ "description": "商品链接",
+ "type": "string"
+ },
+ "has_sample": {
+ "description": "是否有样品 0:没有 1:有",
+ "type": "integer"
+ },
+ "has_video": {
+ "description": "是否有视频素材 0:没有 1:有",
+ "type": "integer"
+ },
+ "hire_money": {
+ "description": "hire_type==1 佣金金额",
+ "type": "number"
+ },
+ "hire_money_expect": {
+ "description": "预计佣金描述",
+ "type": "string"
+ },
+ "hire_ratio": {
+ "description": "hire_type==2 抽成比例",
+ "type": "number"
+ },
+ "hire_type": {
+ "description": "佣金类型 1:固定佣金 2:比例抽成",
+ "type": "integer"
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "num": {
+ "description": "商品数量",
+ "type": "integer"
+ },
+ "release_channels": {
+ "description": "发布渠道",
+ "type": "string"
+ },
+ "release_country": {
+ "description": "发布国家",
+ "type": "string"
+ },
+ "sample_num": {
+ "description": "样品数量",
+ "type": "integer"
+ },
+ "start_time": {
+ "description": "任务起始时间",
+ "type": "string"
+ },
+ "status": {
+ "description": "状态 1:未开始 2:进行中 3:已结束",
+ "type": "integer"
+ },
+ "store": {
+ "description": "商家信息",
+ "allOf": [
+ {
+ "$ref": "#/definitions/model.SellerStoreInfo"
+ }
+ ]
+ },
+ "title": {
+ "description": "标题",
+ "type": "string"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ },
+ "video_channel_ids": {
+ "description": "视频发布渠道,多个渠道英文逗号连接",
+ "type": "string"
+ },
+ "video_country_id": {
+ "description": "视频发布国家",
+ "type": "string"
+ },
+ "video_url": {
+ "type": "string"
+ }
+ }
+ },
+ "model.OrderAddress": {
+ "type": "object",
+ "properties": {
+ "bldg": {
+ "description": "apt,ste,bldg",
+ "type": "string"
+ },
+ "city": {
+ "description": "city",
+ "type": "string"
+ },
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "default": {
+ "description": "是否默认地址 1-是 2-否",
+ "type": "integer"
+ },
+ "firstName": {
+ "description": "first name",
+ "type": "string"
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "lastName": {
+ "description": "last name",
+ "type": "string"
+ },
+ "orderID": {
+ "type": "string"
+ },
+ "phone": {
+ "description": "手机号",
+ "type": "string"
+ },
+ "platform": {
+ "description": "平台 saller(买家端) / customer(客户端) / influencer(网红端)",
+ "type": "string"
+ },
+ "state": {
+ "description": "state",
+ "type": "string"
+ },
+ "street": {
+ "description": "street",
+ "type": "string"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ },
+ "userId": {
+ "type": "string"
+ },
+ "zipCode": {
+ "description": "zip code",
+ "type": "string"
+ }
+ }
+ },
+ "model.OrderDeliver": {
+ "type": "object",
+ "properties": {
+ "courier": {
+ "description": "快递公司",
+ "type": "string"
+ },
+ "courierLink": {
+ "description": "快递链接",
+ "type": "string"
+ },
+ "courierNumber": {
+ "description": "快递单号",
+ "type": "string"
+ },
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "orderID": {
+ "description": "订单号",
+ "type": "string"
+ },
+ "track_id": {
+ "description": "track表id",
+ "type": "integer"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ }
+ }
+ },
+ "model.OrderDetail": {
+ "type": "object",
+ "properties": {
+ "IAmount": {
+ "description": "网红佣金",
+ "type": "string"
+ },
+ "address": {
+ "description": "地址",
+ "allOf": [
+ {
+ "$ref": "#/definitions/model.OrderAddress"
+ }
+ ]
+ },
+ "bill": {
+ "description": "交易信息",
+ "allOf": [
+ {
+ "$ref": "#/definitions/model.BillView"
+ }
+ ]
+ },
+ "captureID": {
+ "description": "paypal收款确认id",
+ "type": "string"
+ },
+ "chain": {
+ "description": "区块链",
+ "allOf": [
+ {
+ "$ref": "#/definitions/model.Chain"
+ }
+ ]
+ },
+ "code": {
+ "description": "网红码?",
+ "type": "string"
+ },
+ "commodID": {
+ "description": "商品id",
+ "type": "integer"
+ },
+ "confirmTime": {
+ "description": "收货时间",
+ "type": "string"
+ },
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "deliver": {
+ "description": "发货信息",
+ "allOf": [
+ {
+ "$ref": "#/definitions/model.OrderDeliver"
+ }
+ ]
+ },
+ "goods": {
+ "description": "商品信息",
+ "allOf": [
+ {
+ "$ref": "#/definitions/model.OrderGoodsDetail"
+ }
+ ]
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "number": {
+ "description": "数量",
+ "type": "integer"
+ },
+ "orderID": {
+ "description": "订单号",
+ "type": "string"
+ },
+ "paidPrice": {
+ "description": "实付价格",
+ "type": "number"
+ },
+ "payTime": {
+ "description": "付款时间",
+ "type": "string"
+ },
+ "paypalID": {
+ "description": "paypal订单号",
+ "type": "string"
+ },
+ "platform": {
+ "description": "购买平台",
+ "type": "string"
+ },
+ "postSale": {
+ "description": "售后信息",
+ "allOf": [
+ {
+ "$ref": "#/definitions/model.PostSale"
+ }
+ ]
+ },
+ "price": {
+ "description": "商品价格",
+ "type": "number"
+ },
+ "sendTime": {
+ "description": "发货时间",
+ "type": "string"
+ },
+ "sku_id": {
+ "description": "商品规格编号",
+ "type": "integer"
+ },
+ "sku_no": {
+ "description": "商品规格编号",
+ "type": "string"
+ },
+ "status": {
+ "description": "订单状态 //订单状态 1-待付款 2-待发货 3-已发货 4-已完成 5-已取消",
+ "type": "integer"
+ },
+ "store": {
+ "description": "店铺信息",
+ "allOf": [
+ {
+ "$ref": "#/definitions/model.SellerStoreInfo"
+ }
+ ]
+ },
+ "store_no": {
+ "description": "店铺编号",
+ "type": "string"
+ },
+ "type": {
+ "description": "类型 1-普通订单 2-预售订单",
+ "type": "integer"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ },
+ "userID": {
+ "description": "用户id",
+ "type": "string"
+ }
+ }
+ },
+ "model.OrderGoodsDetail": {
+ "type": "object",
+ "properties": {
+ "attributes": {
+ "description": "规格详情",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.TbAttributeWithValues"
+ }
+ },
+ "content": {
+ "description": "详情",
+ "type": "string"
+ },
+ "content_text": {
+ "description": "详情-文字",
+ "type": "string"
+ },
+ "cover": {
+ "description": "封面图",
+ "type": "string"
+ },
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "goods_specs": {
+ "description": "规格",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.TbOrderGoodsSpecsDetail"
+ }
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "images": {
+ "description": "图片",
+ "type": "string"
+ },
+ "orderID": {
+ "description": "订单id",
+ "type": "string"
+ },
+ "price_max": {
+ "description": "最高规格价格",
+ "type": "number"
+ },
+ "price_min": {
+ "description": "最低规格价格",
+ "type": "number"
+ },
+ "retail_price": {
+ "description": "吊牌价(零售指导价)",
+ "type": "number"
+ },
+ "sku_no": {
+ "description": "商品规格编号",
+ "type": "string"
+ },
+ "specs": {
+ "description": "规格",
+ "type": "string"
+ },
+ "spu_no": {
+ "description": "编号",
+ "type": "string"
+ },
+ "store_no": {
+ "description": "店铺编号",
+ "type": "string"
+ },
+ "title": {
+ "description": "名称",
+ "type": "string"
+ },
+ "title_eng": {
+ "description": "英文名称",
+ "type": "string"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ }
+ }
+ },
+ "model.OrderList": {
+ "type": "object",
+ "properties": {
+ "IAmount": {
+ "description": "网红佣金",
+ "type": "string"
+ },
+ "captureID": {
+ "description": "paypal收款确认id",
+ "type": "string"
+ },
+ "code": {
+ "description": "网红码?",
+ "type": "string"
+ },
+ "commodID": {
+ "description": "商品id",
+ "type": "integer"
+ },
+ "confirmTime": {
+ "description": "收货时间",
+ "type": "string"
+ },
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "goods": {
+ "description": "商品信息",
+ "allOf": [
+ {
+ "$ref": "#/definitions/model.OrderGoodsDetail"
+ }
+ ]
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "number": {
+ "description": "数量",
+ "type": "integer"
+ },
+ "orderID": {
+ "description": "订单号",
+ "type": "string"
+ },
+ "paidPrice": {
+ "description": "实付价格",
+ "type": "number"
+ },
+ "payTime": {
+ "description": "付款时间",
+ "type": "string"
+ },
+ "paypalID": {
+ "description": "paypal订单号",
+ "type": "string"
+ },
+ "platform": {
+ "description": "购买平台",
+ "type": "string"
+ },
+ "price": {
+ "description": "商品价格",
+ "type": "number"
+ },
+ "sendTime": {
+ "description": "发货时间",
+ "type": "string"
+ },
+ "sku_id": {
+ "description": "商品规格编号",
+ "type": "integer"
+ },
+ "sku_no": {
+ "description": "商品规格编号",
+ "type": "string"
+ },
+ "status": {
+ "description": "订单状态 //订单状态 1-待付款 2-待发货 3-已发货 4-已完成 5-已取消",
+ "type": "integer"
+ },
+ "store_no": {
+ "description": "店铺编号",
+ "type": "string"
+ },
+ "type": {
+ "description": "类型 1-普通订单 2-预售订单",
+ "type": "integer"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ },
+ "user": {
+ "description": "买家信息",
+ "allOf": [
+ {
+ "$ref": "#/definitions/model.UserSimple"
+ }
+ ]
+ },
+ "userID": {
+ "description": "用户id",
+ "type": "string"
+ }
+ }
+ },
+ "model.PostSale": {
+ "type": "object",
+ "properties": {
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "examine_time": {
+ "description": "审核时间",
+ "type": "string"
+ },
+ "id": {
+ "description": "id",
+ "type": "integer"
+ },
+ "orderId": {
+ "description": "订单id",
+ "type": "string"
+ },
+ "refundStatus": {
+ "description": "退款状态 1:退款中 2:退款成功 3:退款失败",
+ "type": "integer"
+ },
+ "refund_time": {
+ "description": "退款时间",
+ "type": "string"
+ },
+ "remark": {
+ "description": "审核原因",
+ "type": "string"
+ },
+ "status": {
+ "description": "处理状态 1:已提交 2:已处理 3:已拒绝 4:已撤回",
+ "type": "integer"
+ }
+ }
+ },
+ "model.SellerStoreInfo": {
+ "type": "object",
+ "properties": {
+ "email": {
+ "description": "店铺联系email(注册账号email)",
+ "type": "string"
+ },
+ "store_no": {
+ "description": "店铺编号",
+ "type": "string"
+ },
+ "type": {
+ "description": "1:个人店铺",
+ "type": "integer"
+ }
+ }
+ },
+ "model.SysMissionReward": {
+ "type": "object",
+ "properties": {
+ "achieve_num": {
+ "description": "已完成任务次数",
+ "type": "integer"
+ },
+ "audit_by": {
+ "description": "审核人",
+ "type": "string"
+ },
+ "bonus": {
+ "description": "奖励金额",
+ "type": "number"
+ },
+ "create_by": {
+ "description": "创建人",
+ "type": "string"
+ },
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "relationId": {
+ "description": "关联项目id",
+ "type": "string"
+ },
+ "status": {
+ "description": "状态 1待发放 2已发放 3已领取",
+ "type": "integer"
+ },
+ "title": {
+ "description": "标题",
+ "type": "string"
+ },
+ "type": {
+ "description": "奖励类型 1.视频上传 2.信息完善 3.商家任务",
+ "type": "integer"
+ },
+ "update_by": {
+ "description": "更新人",
+ "type": "string"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ }
+ }
+ },
+ "model.TbAttributeDetail": {
+ "type": "object",
+ "properties": {
+ "attribute_id": {
+ "description": "规格属性id",
+ "type": "integer"
+ },
+ "value": {
+ "type": "string"
+ },
+ "value_id": {
+ "type": "integer"
+ }
+ }
+ },
+ "model.TbAttributeValueItem": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "integer"
+ },
+ "image": {
+ "description": "图片",
+ "type": "string"
+ },
+ "name": {
+ "description": "规格属性值",
+ "type": "string"
+ }
+ }
+ },
+ "model.TbAttributeWithValues": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "integer"
+ },
+ "name": {
+ "type": "string"
+ },
+ "values": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.TbAttributeValueItem"
+ }
+ }
+ }
+ },
+ "model.TbGoodsDetail": {
+ "type": "object",
+ "properties": {
+ "attributes": {
+ "description": "规格详情",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.TbAttributeWithValues"
+ }
+ },
+ "breadcrumb": {
+ "description": "分类面包屑",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.Breadcrumb"
+ }
+ },
+ "category_id": {
+ "description": "分类id",
+ "type": "integer"
+ },
+ "collect_status": {
+ "description": "收藏状态 true:已收藏 false:未收藏",
+ "type": "boolean"
+ },
+ "content": {
+ "description": "商品详情",
+ "type": "string"
+ },
+ "content_text": {
+ "description": "详情-文字",
+ "type": "string"
+ },
+ "cover": {
+ "type": "string"
+ },
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "images": {
+ "description": "图片",
+ "type": "string"
+ },
+ "list_price": {
+ "description": "列表价格",
+ "type": "number"
+ },
+ "online": {
+ "description": "上下架状态 on/off",
+ "type": "string"
+ },
+ "price_max": {
+ "description": "最高规格价格",
+ "type": "number"
+ },
+ "price_min": {
+ "description": "最低规格价格",
+ "type": "number"
+ },
+ "retail_price": {
+ "description": "吊牌价(零售指导价)",
+ "type": "number"
+ },
+ "specs": {
+ "description": "规格",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.TbGoodsSpecsDetail"
+ }
+ },
+ "spu_no": {
+ "description": "编号",
+ "type": "string"
+ },
+ "tags": {
+ "description": "标签",
+ "type": "string"
+ },
+ "title": {
+ "description": "标题",
+ "type": "string"
+ },
+ "title_eng": {
+ "description": "英文标题",
+ "type": "string"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ }
+ }
+ },
+ "model.TbGoodsSpecsDetail": {
+ "type": "object",
+ "properties": {
+ "attributes": {
+ "description": "规格详情",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.TbAttributeDetail"
+ }
+ },
+ "code": {
+ "type": "string"
+ },
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "goods_id": {
+ "type": "integer"
+ },
+ "goods_no": {
+ "description": "商品编号",
+ "type": "string"
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "image": {
+ "description": "规格图片url",
+ "type": "string"
+ },
+ "price": {
+ "description": "价格",
+ "type": "number"
+ },
+ "sku_no": {
+ "description": "商品编码",
+ "type": "string"
+ },
+ "specs": {
+ "description": "规格",
+ "type": "string"
+ },
+ "stock": {
+ "description": "库存",
+ "type": "integer"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ }
+ }
+ },
+ "model.TbGoodsSpecsView": {
+ "type": "object",
+ "properties": {
+ "attributes": {
+ "description": "规格详情",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.TbAttributeWithValues"
+ }
+ },
+ "cover": {
+ "type": "string"
+ },
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "images": {
+ "description": "图片",
+ "type": "string"
+ },
+ "price_max": {
+ "description": "最高规格价格",
+ "type": "number"
+ },
+ "price_min": {
+ "description": "最低规格价格",
+ "type": "number"
+ },
+ "retail_price": {
+ "description": "吊牌价(零售指导价)",
+ "type": "number"
+ },
+ "sales": {
+ "description": "总销售量",
+ "type": "integer"
+ },
+ "specs": {
+ "description": "规格",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.TbGoodsSpecsDetail"
+ }
+ },
+ "spu_no": {
+ "description": "编号",
+ "type": "string"
+ },
+ "stock": {
+ "description": "总库存",
+ "type": "integer"
+ },
+ "tags": {
+ "description": "标签",
+ "type": "string"
+ },
+ "title": {
+ "description": "标题",
+ "type": "string"
+ },
+ "title_eng": {
+ "description": "英文标题",
+ "type": "string"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ }
+ }
+ },
+ "model.TbOrderGoodsSpecsDetail": {
+ "type": "object",
+ "properties": {
+ "code": {
+ "description": "attribute定位标识",
+ "type": "string"
+ },
+ "goods_id": {
+ "type": "integer"
+ },
+ "goods_no": {
+ "description": "商品编号",
+ "type": "string"
+ },
+ "image": {
+ "description": "规格图片url",
+ "type": "string"
+ },
+ "orderGoodsId": {
+ "type": "integer"
+ },
+ "price": {
+ "description": "价格",
+ "type": "number"
+ },
+ "sku_no": {
+ "description": "Attributes []TbAttributeDetail `gorm:\"-\" json:\"-\"` // 规格详情",
+ "type": "string"
+ },
+ "specs": {
+ "description": "规格",
+ "type": "string"
+ }
+ }
+ },
+ "model.UsCitys": {
+ "type": "object",
+ "properties": {
+ "city": {
+ "type": "string"
+ },
+ "county": {
+ "type": "string"
+ },
+ "id": {
+ "type": "integer"
+ },
+ "idState": {
+ "type": "integer"
+ }
+ }
+ },
+ "model.UsSelect": {
+ "type": "object",
+ "properties": {
+ "children": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.UsCitys"
+ }
+ },
+ "id": {
+ "type": "integer"
+ },
+ "stateCode": {
+ "type": "string"
+ },
+ "stateName": {
+ "type": "string"
+ }
+ }
+ },
+ "model.UserSimple": {
+ "type": "object",
+ "properties": {
+ "avatar": {
+ "description": "头像",
+ "type": "string"
+ },
+ "email": {
+ "description": "用户邮箱",
+ "type": "string"
+ },
+ "nick_name": {
+ "description": "昵称",
+ "type": "string"
+ },
+ "phone": {
+ "description": "手机号",
+ "type": "string"
+ },
+ "platform": {
+ "description": "平台",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/request.Platform"
+ }
+ },
+ "tags": {
+ "description": "个人标签",
+ "type": "string"
+ },
+ "uuid": {
+ "description": "用户uuid编码",
+ "type": "string"
+ }
+ }
+ },
+ "model.Wallet": {
+ "type": "object",
+ "properties": {
+ "balance": {
+ "description": "可用余额",
+ "type": "number"
+ },
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "platform": {
+ "description": "平台 saller(买家端) / customer(客户端) / influencer(网红端)",
+ "type": "string"
+ },
+ "state": {
+ "description": "状态 0:正常 1:限制提现 2:禁止提现",
+ "type": "integer"
+ },
+ "transitBalance": {
+ "description": "在途余额",
+ "type": "number"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ },
+ "userId": {
+ "type": "string"
+ }
+ }
+ },
+ "model.Withdrawal": {
+ "type": "object",
+ "properties": {
+ "account_name": {
+ "description": "户名",
+ "type": "string"
+ },
+ "account_type": {
+ "description": "账户类型 1:paypal 2:银行卡",
+ "type": "integer"
+ },
+ "address": {
+ "description": "收款人地址",
+ "type": "string"
+ },
+ "amount": {
+ "description": "金额",
+ "type": "number"
+ },
+ "bank_code": {
+ "description": "收款行",
+ "type": "string"
+ },
+ "bill_no": {
+ "description": "账单号",
+ "type": "string"
+ },
+ "card_number": {
+ "description": "银行卡号",
+ "type": "string"
+ },
+ "check_status": {
+ "description": "审核状态 0:待审核 1:审核通过 2:审核未通过",
+ "type": "string"
+ },
+ "check_time": {
+ "description": "审核时间",
+ "type": "string"
+ },
+ "country": {
+ "description": "国家/地区",
+ "type": "string"
+ },
+ "create_by": {
+ "description": "创建人/店铺",
+ "type": "string"
+ },
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "currency": {
+ "description": "币种 USD:美元",
+ "type": "string"
+ },
+ "flow_no": {
+ "description": "流水号",
+ "type": "string"
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "pay_id": {
+ "description": "支付id",
+ "type": "string"
+ },
+ "platform": {
+ "description": "平台 1:网红 2:商家",
+ "type": "string"
+ },
+ "remark": {
+ "description": "备注",
+ "type": "string"
+ },
+ "status": {
+ "description": "提现状态 0:进行中 1:成功 2:失败",
+ "type": "string"
+ },
+ "swift_code": {
+ "description": "银行国际代码",
+ "type": "string"
+ },
+ "title": {
+ "description": "标题",
+ "type": "string"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ },
+ "wallet_type": {
+ "description": "钱包类型 1:余额钱包 2:营销账户钱包",
+ "type": "integer"
+ }
+ }
+ },
+ "model.WithdrawalView": {
+ "type": "object",
+ "properties": {
+ "flow_no": {
+ "description": "流水号",
+ "type": "string"
+ }
+ }
+ },
+ "request.AddAccount": {
+ "type": "object",
+ "properties": {
+ "account_name": {
+ "description": "户名",
+ "type": "string"
+ },
+ "address": {
+ "description": "收款人地址",
+ "type": "string"
+ },
+ "bank_card": {
+ "description": "银行卡号",
+ "type": "string"
+ },
+ "bank_code": {
+ "description": "银行编码",
+ "type": "string"
+ },
+ "country": {
+ "description": "国家/地区",
+ "type": "string"
+ },
+ "currency": {
+ "description": "币种 USD: 美元",
+ "type": "string"
+ },
+ "is_default": {
+ "description": "是否默认",
+ "type": "boolean"
+ },
+ "swift_code": {
+ "description": "swift编码",
+ "type": "string"
+ }
+ }
+ },
+ "request.ClaimMission": {
+ "type": "object",
+ "properties": {
+ "address_id": {
+ "description": "收货地址id",
+ "type": "integer"
+ },
+ "email": {
+ "description": "邮箱地址",
+ "type": "string"
+ },
+ "mission_id": {
+ "description": "任务id",
+ "type": "integer"
+ },
+ "sku_no": {
+ "description": "商品sku_no",
+ "type": "string"
+ },
+ "spu_no": {
+ "description": "商品spu_no",
+ "type": "string"
+ }
+ }
+ },
+ "request.ClaimMissionVideo": {
+ "type": "object",
+ "properties": {
+ "cover": {
+ "type": "string"
+ },
+ "height": {
+ "description": "高度",
+ "type": "integer"
+ },
+ "mission_claim_id": {
+ "description": "领取任务id",
+ "type": "integer"
+ },
+ "source_type": {
+ "description": "类型:1:固定费用上传 2:奖励任务上传 3:后台上传",
+ "type": "integer"
+ },
+ "video_url": {
+ "description": "视频上传地址",
+ "type": "string"
+ },
+ "width": {
+ "description": "宽度",
+ "type": "integer"
+ }
+ }
+ },
+ "request.ClaimMissionWorks": {
+ "type": "object",
+ "properties": {
+ "homepage": {
+ "description": "作品主页地址",
+ "type": "string"
+ },
+ "id": {
+ "description": "id",
+ "type": "integer"
+ },
+ "image": {
+ "description": "作品凭证截图",
+ "type": "string"
+ },
+ "type": {
+ "description": "平台 1:ins 2:Pinterest 3:tk 4:Twitter 5:Facebook 6:Reddit",
+ "type": "integer"
+ },
+ "video_url": {
+ "description": "视频上传地址",
+ "type": "string"
+ }
+ }
+ },
+ "request.ClaimMissionWorksList": {
+ "type": "object",
+ "properties": {
+ "mission_claim_id": {
+ "description": "领取任务id",
+ "type": "integer"
+ },
+ "works": {
+ "description": "作品列表",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/request.ClaimMissionWorks"
+ }
+ }
+ }
+ },
+ "request.DeleteAccount": {
+ "type": "object",
+ "properties": {
+ "code": {
+ "description": "验证码",
+ "type": "string"
+ },
+ "id": {
+ "description": "主键",
+ "type": "integer"
+ },
+ "phone": {
+ "description": "手机号",
+ "type": "string"
+ }
+ }
+ },
+ "request.IdReq": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "description": "id",
+ "type": "integer"
+ }
+ }
+ },
+ "request.MissionId": {
+ "type": "object",
+ "properties": {
+ "mission_id": {
+ "description": "任务",
+ "type": "integer"
+ }
+ }
+ },
+ "request.Platform": {
+ "type": "object",
+ "properties": {
+ "image": {
+ "description": "图片",
+ "type": "string"
+ },
+ "is_auth": {
+ "description": "是否认证",
+ "type": "boolean"
+ },
+ "label": {
+ "type": "string"
+ },
+ "platform": {
+ "description": "平台 字典表获取",
+ "type": "string"
+ },
+ "url": {
+ "description": "主页地址",
+ "type": "string"
+ }
+ }
+ },
+ "request.SendEmail": {
+ "type": "object",
+ "properties": {
+ "email": {
+ "type": "string"
+ }
+ }
+ },
+ "request.SendMessage": {
+ "type": "object",
+ "properties": {
+ "country_code": {
+ "description": "用户手机号国家代码 国际区号 86 中国 1美国",
+ "type": "string"
+ },
+ "phone": {
+ "type": "string"
+ },
+ "type": {
+ "description": "1:登录验证码 2-解绑 3-绑定 4-提现",
+ "type": "integer"
+ }
+ }
+ },
+ "request.UserAuthorized": {
+ "type": "object",
+ "properties": {
+ "appid": {
+ "description": "应用id",
+ "type": "string"
+ },
+ "client": {
+ "description": "客户端 ios android web",
+ "type": "string"
+ },
+ "code": {
+ "description": "授权码",
+ "type": "string"
+ },
+ "platform": {
+ "description": "平台 google facebook twitter tiktok",
+ "type": "string"
+ },
+ "token": {
+ "description": "token",
+ "type": "string"
+ },
+ "uuid": {
+ "description": "设备唯一标识",
+ "type": "string"
+ }
+ }
+ },
+ "request.UserBandPhone": {
+ "type": "object",
+ "properties": {
+ "code": {
+ "description": "验证码",
+ "type": "string"
+ },
+ "phone": {
+ "description": "手机号",
+ "type": "string"
+ }
+ }
+ },
+ "request.UserDetail": {
+ "type": "object",
+ "properties": {
+ "platform": {
+ "description": "平台及地址逗号隔开 eg:(ins:https://baidu.com/user/1,qq:12345678)",
+ "type": "string"
+ },
+ "tags": {
+ "description": "个人标签",
+ "type": "string"
+ },
+ "type": {
+ "description": "修改字段 platform-平台 tags-个人标签",
+ "type": "string"
+ }
+ }
+ },
+ "request.UserLogin": {
+ "type": "object",
+ "properties": {
+ "appid": {
+ "description": "应用id",
+ "type": "string"
+ },
+ "code": {
+ "description": "验证码",
+ "type": "string"
+ },
+ "country_code": {
+ "description": "用户手机号国家代码 国际区号 86 中国 1美国",
+ "type": "string"
+ },
+ "email": {
+ "description": "邮箱",
+ "type": "string"
+ },
+ "password": {
+ "description": "密码",
+ "type": "string"
+ },
+ "phone": {
+ "description": "手机号",
+ "type": "string"
+ },
+ "type": {
+ "description": "1-手机号 2-邮箱",
+ "type": "string"
+ }
+ }
+ },
+ "request.UserPlatformAuth": {
+ "type": "object",
+ "properties": {
+ "platform": {
+ "description": "平台",
+ "allOf": [
+ {
+ "$ref": "#/definitions/request.Platform"
+ }
+ ]
+ },
+ "tags": {
+ "description": "个人标签",
+ "type": "string"
+ }
+ }
+ },
+ "request.UserRegister": {
+ "type": "object",
+ "properties": {
+ "appid": {
+ "description": "应用id",
+ "type": "string"
+ },
+ "avatar": {
+ "description": "头像",
+ "type": "string"
+ },
+ "code": {
+ "description": "验证码",
+ "type": "string"
+ },
+ "country_code": {
+ "description": "用户手机号国家代码 国际区号 86 中国 1美国",
+ "type": "string"
+ },
+ "email": {
+ "description": "邮箱",
+ "type": "string"
+ },
+ "nickname": {
+ "description": "昵称",
+ "type": "string"
+ }
+ }
+ },
+ "request.WithdrawalParams": {
+ "type": "object",
+ "properties": {
+ "accountID": {
+ "description": "提现账户id",
+ "type": "integer"
+ },
+ "amount": {
+ "description": "Code string `json:\"code\"` // 验证码",
+ "type": "number"
+ }
+ }
+ },
+ "response.BannerListResponse": {
+ "type": "object",
+ "properties": {
+ "coverUrl": {
+ "description": "封面图",
+ "type": "string"
+ },
+ "id": {
+ "description": "主键",
+ "type": "integer"
+ },
+ "link": {
+ "description": "链接地址",
+ "type": "string"
+ },
+ "linkType": {
+ "description": "链接类型 0:内链 1:外链",
+ "type": "string"
+ },
+ "relationId": {
+ "description": "关联项目id",
+ "type": "string"
+ },
+ "relationType": {
+ "description": "关联类型 01-任务",
+ "type": "string"
+ },
+ "sort_index": {
+ "description": "序号索引",
+ "type": "integer"
+ },
+ "status": {
+ "description": "状态 0=下架 1=上架",
+ "type": "string"
+ },
+ "title": {
+ "description": "标题",
+ "type": "string"
+ },
+ "type": {
+ "description": "任务-0101 平台奖励页-0102",
+ "type": "string"
+ }
+ }
+ },
+ "response.ChainResp": {
+ "type": "object",
+ "properties": {
+ "block_adress": {
+ "description": "所在区块",
+ "type": "string"
+ },
+ "block_height": {
+ "description": "块高度",
+ "type": "integer"
+ },
+ "hash": {
+ "description": "交易哈希",
+ "type": "string"
+ },
+ "time": {
+ "description": "上链时间",
+ "type": "string"
+ }
+ }
+ },
+ "response.MissionRecommendResponse": {
+ "type": "object",
+ "properties": {
+ "achieve_num": {
+ "description": "已完成商品数量",
+ "type": "integer"
+ },
+ "bought_num": {
+ "description": "购买人数",
+ "type": "number"
+ },
+ "claim_num": {
+ "description": "任务领取人数",
+ "type": "integer"
+ },
+ "cover": {
+ "description": "封面",
+ "type": "string"
+ },
+ "create_by": {
+ "description": "创建人",
+ "type": "string"
+ },
+ "created_at": {
+ "description": "创建时间",
+ "type": "string"
+ },
+ "end_time": {
+ "description": "任务结束时间",
+ "type": "string"
+ },
+ "goods_title": {
+ "description": "商品标题",
+ "type": "string"
+ },
+ "goods_title_eng": {
+ "description": "商品英文标题",
+ "type": "string"
+ },
+ "height": {
+ "description": "高度",
+ "type": "integer"
+ },
+ "hire_money": {
+ "description": "hire_type==1 佣金金额",
+ "type": "number"
+ },
+ "hire_money_expect": {
+ "description": "预计佣金描述",
+ "type": "string"
+ },
+ "hire_ratio": {
+ "description": "hire_type==2 抽成比例",
+ "type": "number"
+ },
+ "hire_type": {
+ "description": "佣金类型 1:固定佣金 2:比例抽成",
+ "type": "integer"
+ },
+ "id": {
+ "description": "主键ID",
+ "type": "integer"
+ },
+ "influencer": {
+ "$ref": "#/definitions/model.UserSimple"
+ },
+ "mission_id": {
+ "description": "任务ID",
+ "type": "integer"
+ },
+ "mission_status": {
+ "description": "任务状态",
+ "type": "integer"
+ },
+ "relation_id": {
+ "description": "关联ID,任务视频ID",
+ "type": "integer"
+ },
+ "release_channels": {
+ "description": "发布渠道",
+ "type": "string"
+ },
+ "release_country": {
+ "description": "发布国家",
+ "type": "string"
+ },
+ "sort": {
+ "description": "倒序 //排序",
+ "type": "integer"
+ },
+ "start_time": {
+ "description": "任务起始时间",
+ "type": "string"
+ },
+ "status": {
+ "description": "状态 1:上架 2:下架",
+ "type": "integer"
+ },
+ "tag": {
+ "description": "todo 标签系统",
+ "type": "string"
+ },
+ "title": {
+ "description": "任务标题",
+ "type": "string"
+ },
+ "total_bonus": {
+ "description": "累计奖励",
+ "type": "number"
+ },
+ "updated_at": {
+ "description": "更新时间",
+ "type": "string"
+ },
+ "video_url": {
+ "description": "视频地址",
+ "type": "string"
+ },
+ "width": {
+ "description": "宽度",
+ "type": "integer"
+ }
+ }
+ },
+ "response.SysBonusDetail": {
+ "type": "object",
+ "properties": {
+ "achieve_max": {
+ "description": "最大完成次数",
+ "type": "integer"
+ },
+ "achieve_num": {
+ "description": "已完成任务次数",
+ "type": "integer"
+ },
+ "bonus": {
+ "description": "奖金",
+ "type": "number"
+ },
+ "mission_list": {
+ "description": "任务列表",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/response.SysMissionDesc"
+ }
+ },
+ "title": {
+ "description": "标题",
+ "type": "string"
+ },
+ "total": {
+ "description": "奖励次数",
+ "type": "integer"
+ },
+ "type": {
+ "description": "奖励类型 1.视频上传 2.信息完善 3.商家任务",
+ "type": "integer"
+ }
+ }
+ },
+ "response.SysMissionBonus": {
+ "type": "object",
+ "properties": {
+ "total": {
+ "description": "奖励总笔数",
+ "type": "integer"
+ },
+ "total_bonus": {
+ "description": "奖励汇总金额",
+ "type": "number"
+ },
+ "video_bonus": {
+ "description": "视频上传",
+ "allOf": [
+ {
+ "$ref": "#/definitions/response.SysBonusDetail"
+ }
+ ]
+ }
+ }
+ },
+ "response.SysMissionDesc": {
+ "type": "object",
+ "properties": {
+ "achieve_num": {
+ "type": "integer"
+ },
+ "bonus": {
+ "description": "奖励金额",
+ "type": "number"
+ },
+ "description": {
+ "description": "描述",
+ "type": "string"
+ },
+ "description_eng": {
+ "description": "描述英文",
+ "type": "string"
+ },
+ "status": {
+ "description": "状态 1待发放 2已发放 3已领取 0未完成",
+ "type": "integer"
+ },
+ "title": {
+ "description": "任务标题",
+ "type": "string"
+ },
+ "title_eng": {
+ "description": "任务标题英文",
+ "type": "string"
+ }
+ }
+ },
+ "response.UserStatistics": {
+ "type": "object",
+ "properties": {
+ "claim_mission_num": {
+ "description": "领取任务数量",
+ "type": "integer"
+ },
+ "collection_mission_num": {
+ "description": "收藏任务数量",
+ "type": "integer"
+ },
+ "platform_num": {
+ "description": "认证平台数量",
+ "type": "integer"
+ }
+ }
+ }
+ },
+ "securityDefinitions": {
+ "ApiKeyAuth": {
+ "type": "apiKey",
+ "name": "x-token",
+ "in": "header"
+ }
+ }
+}
\ No newline at end of file
diff --git a/docs/swagger.yaml b/docs/swagger.yaml
new file mode 100644
index 0000000..4187061
--- /dev/null
+++ b/docs/swagger.yaml
@@ -0,0 +1,2897 @@
+definitions:
+ dto.BillData:
+ properties:
+ cancelOrderMoney:
+ description: 退款订单总额
+ type: number
+ cancelOrderNum:
+ description: 退款订单数
+ type: integer
+ flowExpend:
+ description: 出账
+ type: number
+ flowIncome:
+ description: 进账
+ type: number
+ income:
+ description: 收入总额
+ type: number
+ orderMoney:
+ description: 订单总额
+ type: number
+ orderNum:
+ description: 订单数
+ type: integer
+ rewardUnfinished:
+ description: 在途佣金
+ type: number
+ type: object
+ dto.MissionOrderStatistic:
+ properties:
+ OrderMoney:
+ description: 订单金额
+ type: number
+ OrderUserNum:
+ description: 下单人数
+ type: integer
+ RewardRatio:
+ description: 佣金比例
+ type: number
+ SellNum:
+ description: 销售数量
+ type: integer
+ SettleReward:
+ description: 结算佣金
+ type: number
+ TransitReward:
+ description: 在途佣金
+ type: number
+ Uv:
+ description: 浏览人数
+ type: integer
+ orderDoneNum:
+ description: 完成订单总数
+ type: integer
+ orderNum:
+ description: 订单总数
+ type: integer
+ type: object
+ dto.OrderData:
+ properties:
+ all:
+ description: 全部
+ type: integer
+ cancel:
+ description: 已取消
+ type: integer
+ finished:
+ description: 已完成
+ type: integer
+ shipped:
+ description: 已发货
+ type: integer
+ unship:
+ description: 待发货
+ type: integer
+ type: object
+ global.BASE_ID:
+ properties:
+ id:
+ description: 主键
+ type: integer
+ type: object
+ model.Account:
+ properties:
+ account_name:
+ description: 户名
+ type: string
+ address:
+ description: 收款人地址
+ type: string
+ bank_code:
+ description: 收款行
+ type: string
+ card_number:
+ description: 银行卡号
+ type: string
+ country:
+ description: 国家/地区
+ type: string
+ created_at:
+ description: 创建时间
+ type: string
+ currency:
+ description: 币种 USD:美元
+ type: string
+ id:
+ description: 主键ID
+ type: integer
+ idCard:
+ type: string
+ is_default:
+ description: 是否为默认 0:非默认 1:默认
+ type: boolean
+ phone:
+ type: string
+ platform:
+ description: 平台 saller(买家端) / customer(客户端) / influencer(网红端)
+ type: string
+ sort:
+ description: 排序值
+ type: integer
+ swift_code:
+ description: 银行国际代码
+ type: string
+ type:
+ description: 类型 1:paypal 2:银行卡
+ type: integer
+ updated_at:
+ description: 更新时间
+ type: string
+ userID:
+ description: 用户id
+ type: string
+ type: object
+ model.Address:
+ properties:
+ bldg:
+ description: apt,ste,bldg
+ type: string
+ city:
+ description: city
+ type: string
+ created_at:
+ description: 创建时间
+ type: string
+ default:
+ description: 是否默认地址 1-是 2-否
+ type: integer
+ firstName:
+ description: first name
+ type: string
+ id:
+ description: 主键ID
+ type: integer
+ lastName:
+ description: last name
+ type: string
+ phone:
+ description: 手机号
+ type: string
+ platform:
+ description: 平台 saller(买家端) / customer(客户端) / influencer(网红端)
+ type: string
+ state:
+ description: state
+ type: string
+ street:
+ description: street
+ type: string
+ updated_at:
+ description: 更新时间
+ type: string
+ userId:
+ type: string
+ zipCode:
+ description: zip code
+ type: string
+ type: object
+ model.Bill:
+ properties:
+ account:
+ description: 收款账户(提现)
+ type: string
+ amount:
+ description: 数量
+ type: integer
+ balance:
+ description: 余额
+ type: number
+ check_status:
+ description: 审核状态 0:待审核 1:审核通过 2:审核未通过
+ type: string
+ claim_no:
+ description: 领取任务编号
+ type: string
+ created_at:
+ description: 创建时间
+ type: string
+ id:
+ description: 主键ID
+ type: integer
+ order_id:
+ description: 关联订单id
+ type: string
+ platform:
+ description: 平台 seller(买家端) / customer(客户端) / influencer(网红端)
+ type: string
+ price:
+ description: 金额
+ type: number
+ receipt:
+ description: 是否已到账 1-是 2-否 3-已取消付款
+ type: integer
+ remark:
+ description: 备注
+ type: string
+ status:
+ description: 类型 1-支出 2-收入
+ type: integer
+ title:
+ description: 账单标题
+ type: string
+ transaction_id:
+ description: 交易编号
+ type: string
+ type:
+ description: 类型 1-佣金 2-订单 3-提现 4-平台奖励
+ type: string
+ updated_at:
+ description: 更新时间
+ type: string
+ userID:
+ description: 用户id
+ type: string
+ withd_id:
+ description: 提现id
+ type: string
+ withdrawalStatus:
+ description: 提现状态 0-提现中 1-提现完成 2-提现失败
+ type: integer
+ type: object
+ model.BillNotify:
+ properties:
+ relation_id:
+ description: 关联id
+ type: string
+ relation_type:
+ description: 关联类型
+ type: string
+ title:
+ description: 标题
+ type: string
+ type: object
+ model.BillView:
+ properties:
+ id:
+ description: id
+ type: integer
+ order_id:
+ description: 订单编号
+ type: string
+ transaction_id:
+ description: 交易编号
+ type: string
+ type: object
+ model.Breadcrumb:
+ properties:
+ id:
+ type: integer
+ is_leaf:
+ description: 是否叶子分类
+ type: boolean
+ name:
+ type: string
+ pid:
+ description: 父id
+ type: integer
+ type: object
+ model.Chain:
+ properties:
+ address:
+ description: 合约地址
+ type: string
+ type: object
+ model.MissionBonus:
+ properties:
+ total:
+ type: number
+ user_total:
+ type: number
+ type: object
+ model.MissionClaimDetail:
+ properties:
+ achieve_num:
+ description: 已完成商品数量
+ type: integer
+ claim_no:
+ description: 领取任务编号
+ type: string
+ created_at:
+ description: 创建时间
+ type: string
+ email:
+ description: 发送邮箱
+ type: string
+ expire_at:
+ description: 任务推广过期时间
+ type: string
+ finished:
+ description: 任务完成状态 0:未完成 1:已完成
+ type: integer
+ id:
+ description: 主键ID
+ type: integer
+ mission:
+ allOf:
+ - $ref: '#/definitions/model.MissionDetail'
+ description: 关联任务
+ mission_id:
+ description: 任务id
+ type: integer
+ order:
+ allOf:
+ - $ref: '#/definitions/model.MissionClaimOrderInfo'
+ description: 任务订单
+ spread_url:
+ description: 推广链接
+ type: string
+ status:
+ description: 状态 1:已领取待发货 2:已发货 3:已收货推广中
+ type: integer
+ status_except:
+ description: 状态描述
+ type: string
+ total_bonus:
+ description: 累计佣金
+ type: integer
+ updated_at:
+ description: 更新时间
+ type: string
+ video:
+ allOf:
+ - $ref: '#/definitions/model.MissionClaimVideo'
+ description: 上传视频
+ works:
+ description: 发布作品
+ items:
+ $ref: '#/definitions/model.MissionClaimWorks'
+ type: array
+ type: object
+ model.MissionClaimOrderGoods:
+ properties:
+ created_at:
+ description: 创建时间
+ type: string
+ id:
+ description: 主键ID
+ type: integer
+ image:
+ description: 规格图片url
+ type: string
+ order_id:
+ description: 订单号
+ type: string
+ price:
+ description: 价格
+ type: number
+ sku_no:
+ description: sku编号
+ type: string
+ specs:
+ description: 规格
+ type: string
+ title:
+ description: 名称
+ type: string
+ updated_at:
+ description: 更新时间
+ type: string
+ type: object
+ model.MissionClaimOrderInfo:
+ properties:
+ courier:
+ description: 快递公司
+ type: string
+ courier_number:
+ description: 快递单号
+ type: string
+ courier_url:
+ description: 快递查询地址
+ type: string
+ deliver:
+ allOf:
+ - $ref: '#/definitions/model.OrderDeliver'
+ description: 发货信息
+ mission_claim_id:
+ description: 领取任务id
+ type: integer
+ order_goods:
+ allOf:
+ - $ref: '#/definitions/model.MissionClaimOrderGoods'
+ description: 订单商品信息
+ order_id:
+ description: 订单号
+ type: string
+ send_time:
+ description: 发货时间
+ type: string
+ status:
+ description: 订单状态 2:待发货 3:已发货
+ type: integer
+ type: object
+ model.MissionClaimVideo:
+ properties:
+ cover:
+ description: 视频封面
+ type: string
+ create_by:
+ description: 创建人
+ type: string
+ created_at:
+ description: 创建时间
+ type: string
+ height:
+ description: 高度
+ type: integer
+ id:
+ description: 主键ID
+ type: integer
+ mission_claim_id:
+ description: 领取任务id
+ type: integer
+ mission_id:
+ description: 任务ID
+ type: integer
+ remark:
+ type: string
+ reward_status:
+ description: 奖励发放状态 1:未发放 2:已发放
+ type: integer
+ source_type:
+ description: 类型:1:固定费用上传 2:奖励任务上传 3:后台上传
+ type: integer
+ status:
+ description: 状态 1:待审核 2:审核通过 3:审核不通过
+ type: integer
+ updated_at:
+ description: 更新时间
+ type: string
+ video_url:
+ description: 视频上传地址
+ type: string
+ width:
+ description: 宽度
+ type: integer
+ type: object
+ model.MissionClaimWorks:
+ properties:
+ created_at:
+ description: 创建时间
+ type: string
+ homepage:
+ description: 作品主页地址
+ type: string
+ id:
+ description: 主键ID
+ type: integer
+ image:
+ description: 作品凭证截图
+ type: string
+ mission_claim_id:
+ description: 领取任务id
+ type: integer
+ type:
+ description: 平台 1:ins 2:YouTube 3:tiktok 4:Facebook 5:Twitter
+ type: integer
+ updated_at:
+ description: 更新时间
+ type: string
+ video_url:
+ description: 视频上传地址
+ type: string
+ type: object
+ model.MissionDetail:
+ properties:
+ claim_days:
+ description: 任务完成天数
+ type: integer
+ claim_demands:
+ description: 任务拍摄要求
+ type: string
+ claim_num:
+ description: 接任务人数
+ type: integer
+ claim_status_except:
+ description: 可接任务状态描述
+ type: string
+ claim_status_except_eng:
+ description: 英文版状态描述
+ type: string
+ claim_stock:
+ description: 可接任务库存
+ type: integer
+ collect_status:
+ description: 收藏状态 true:已收藏 false:未收藏
+ type: boolean
+ created_at:
+ description: 创建时间
+ type: string
+ description:
+ description: 描述/卖点
+ type: string
+ end_time:
+ description: 任务结束时间
+ type: string
+ goods:
+ allOf:
+ - $ref: '#/definitions/model.TbGoodsSpecsView'
+ description: 商品信息
+ goods_status:
+ description: 关联商品状态 1:正常 2:已下架
+ type: integer
+ goods_url:
+ description: 商品链接
+ type: string
+ has_sample:
+ description: 是否有样品 0:没有 1:有
+ type: integer
+ has_video:
+ description: 是否有视频素材 0:没有 1:有
+ type: integer
+ hire_money:
+ description: hire_type==1 佣金金额
+ type: number
+ hire_money_expect:
+ description: 预计佣金描述
+ type: string
+ hire_ratio:
+ description: hire_type==2 抽成比例
+ type: number
+ hire_type:
+ description: 佣金类型 1:固定佣金 2:比例抽成
+ type: integer
+ id:
+ description: 主键ID
+ type: integer
+ num:
+ description: 商品数量
+ type: integer
+ release_channels:
+ description: 发布渠道
+ type: string
+ release_country:
+ description: 发布国家
+ type: string
+ sample_num:
+ description: 样品数量
+ type: integer
+ start_time:
+ description: 任务起始时间
+ type: string
+ status:
+ description: 状态 1:未开始 2:进行中 3:已结束
+ type: integer
+ store:
+ allOf:
+ - $ref: '#/definitions/model.SellerStoreInfo'
+ description: 商家信息
+ title:
+ description: 标题
+ type: string
+ updated_at:
+ description: 更新时间
+ type: string
+ video_channel_ids:
+ description: 视频发布渠道,多个渠道英文逗号连接
+ type: string
+ video_country_id:
+ description: 视频发布国家
+ type: string
+ video_url:
+ type: string
+ type: object
+ model.OrderAddress:
+ properties:
+ bldg:
+ description: apt,ste,bldg
+ type: string
+ city:
+ description: city
+ type: string
+ created_at:
+ description: 创建时间
+ type: string
+ default:
+ description: 是否默认地址 1-是 2-否
+ type: integer
+ firstName:
+ description: first name
+ type: string
+ id:
+ description: 主键ID
+ type: integer
+ lastName:
+ description: last name
+ type: string
+ orderID:
+ type: string
+ phone:
+ description: 手机号
+ type: string
+ platform:
+ description: 平台 saller(买家端) / customer(客户端) / influencer(网红端)
+ type: string
+ state:
+ description: state
+ type: string
+ street:
+ description: street
+ type: string
+ updated_at:
+ description: 更新时间
+ type: string
+ userId:
+ type: string
+ zipCode:
+ description: zip code
+ type: string
+ type: object
+ model.OrderDeliver:
+ properties:
+ courier:
+ description: 快递公司
+ type: string
+ courierLink:
+ description: 快递链接
+ type: string
+ courierNumber:
+ description: 快递单号
+ type: string
+ created_at:
+ description: 创建时间
+ type: string
+ id:
+ description: 主键ID
+ type: integer
+ orderID:
+ description: 订单号
+ type: string
+ track_id:
+ description: track表id
+ type: integer
+ updated_at:
+ description: 更新时间
+ type: string
+ type: object
+ model.OrderDetail:
+ properties:
+ IAmount:
+ description: 网红佣金
+ type: string
+ address:
+ allOf:
+ - $ref: '#/definitions/model.OrderAddress'
+ description: 地址
+ bill:
+ allOf:
+ - $ref: '#/definitions/model.BillView'
+ description: 交易信息
+ captureID:
+ description: paypal收款确认id
+ type: string
+ chain:
+ allOf:
+ - $ref: '#/definitions/model.Chain'
+ description: 区块链
+ code:
+ description: 网红码?
+ type: string
+ commodID:
+ description: 商品id
+ type: integer
+ confirmTime:
+ description: 收货时间
+ type: string
+ created_at:
+ description: 创建时间
+ type: string
+ deliver:
+ allOf:
+ - $ref: '#/definitions/model.OrderDeliver'
+ description: 发货信息
+ goods:
+ allOf:
+ - $ref: '#/definitions/model.OrderGoodsDetail'
+ description: 商品信息
+ id:
+ description: 主键ID
+ type: integer
+ number:
+ description: 数量
+ type: integer
+ orderID:
+ description: 订单号
+ type: string
+ paidPrice:
+ description: 实付价格
+ type: number
+ payTime:
+ description: 付款时间
+ type: string
+ paypalID:
+ description: paypal订单号
+ type: string
+ platform:
+ description: 购买平台
+ type: string
+ postSale:
+ allOf:
+ - $ref: '#/definitions/model.PostSale'
+ description: 售后信息
+ price:
+ description: 商品价格
+ type: number
+ sendTime:
+ description: 发货时间
+ type: string
+ sku_id:
+ description: 商品规格编号
+ type: integer
+ sku_no:
+ description: 商品规格编号
+ type: string
+ status:
+ description: 订单状态 //订单状态 1-待付款 2-待发货 3-已发货 4-已完成 5-已取消
+ type: integer
+ store:
+ allOf:
+ - $ref: '#/definitions/model.SellerStoreInfo'
+ description: 店铺信息
+ store_no:
+ description: 店铺编号
+ type: string
+ type:
+ description: 类型 1-普通订单 2-预售订单
+ type: integer
+ updated_at:
+ description: 更新时间
+ type: string
+ userID:
+ description: 用户id
+ type: string
+ type: object
+ model.OrderGoodsDetail:
+ properties:
+ attributes:
+ description: 规格详情
+ items:
+ $ref: '#/definitions/model.TbAttributeWithValues'
+ type: array
+ content:
+ description: 详情
+ type: string
+ content_text:
+ description: 详情-文字
+ type: string
+ cover:
+ description: 封面图
+ type: string
+ created_at:
+ description: 创建时间
+ type: string
+ goods_specs:
+ description: 规格
+ items:
+ $ref: '#/definitions/model.TbOrderGoodsSpecsDetail'
+ type: array
+ id:
+ description: 主键ID
+ type: integer
+ images:
+ description: 图片
+ type: string
+ orderID:
+ description: 订单id
+ type: string
+ price_max:
+ description: 最高规格价格
+ type: number
+ price_min:
+ description: 最低规格价格
+ type: number
+ retail_price:
+ description: 吊牌价(零售指导价)
+ type: number
+ sku_no:
+ description: 商品规格编号
+ type: string
+ specs:
+ description: 规格
+ type: string
+ spu_no:
+ description: 编号
+ type: string
+ store_no:
+ description: 店铺编号
+ type: string
+ title:
+ description: 名称
+ type: string
+ title_eng:
+ description: 英文名称
+ type: string
+ updated_at:
+ description: 更新时间
+ type: string
+ type: object
+ model.OrderList:
+ properties:
+ IAmount:
+ description: 网红佣金
+ type: string
+ captureID:
+ description: paypal收款确认id
+ type: string
+ code:
+ description: 网红码?
+ type: string
+ commodID:
+ description: 商品id
+ type: integer
+ confirmTime:
+ description: 收货时间
+ type: string
+ created_at:
+ description: 创建时间
+ type: string
+ goods:
+ allOf:
+ - $ref: '#/definitions/model.OrderGoodsDetail'
+ description: 商品信息
+ id:
+ description: 主键ID
+ type: integer
+ number:
+ description: 数量
+ type: integer
+ orderID:
+ description: 订单号
+ type: string
+ paidPrice:
+ description: 实付价格
+ type: number
+ payTime:
+ description: 付款时间
+ type: string
+ paypalID:
+ description: paypal订单号
+ type: string
+ platform:
+ description: 购买平台
+ type: string
+ price:
+ description: 商品价格
+ type: number
+ sendTime:
+ description: 发货时间
+ type: string
+ sku_id:
+ description: 商品规格编号
+ type: integer
+ sku_no:
+ description: 商品规格编号
+ type: string
+ status:
+ description: 订单状态 //订单状态 1-待付款 2-待发货 3-已发货 4-已完成 5-已取消
+ type: integer
+ store_no:
+ description: 店铺编号
+ type: string
+ type:
+ description: 类型 1-普通订单 2-预售订单
+ type: integer
+ updated_at:
+ description: 更新时间
+ type: string
+ user:
+ allOf:
+ - $ref: '#/definitions/model.UserSimple'
+ description: 买家信息
+ userID:
+ description: 用户id
+ type: string
+ type: object
+ model.PostSale:
+ properties:
+ created_at:
+ description: 创建时间
+ type: string
+ examine_time:
+ description: 审核时间
+ type: string
+ id:
+ description: id
+ type: integer
+ orderId:
+ description: 订单id
+ type: string
+ refund_time:
+ description: 退款时间
+ type: string
+ refundStatus:
+ description: 退款状态 1:退款中 2:退款成功 3:退款失败
+ type: integer
+ remark:
+ description: 审核原因
+ type: string
+ status:
+ description: 处理状态 1:已提交 2:已处理 3:已拒绝 4:已撤回
+ type: integer
+ type: object
+ model.SellerStoreInfo:
+ properties:
+ email:
+ description: 店铺联系email(注册账号email)
+ type: string
+ store_no:
+ description: 店铺编号
+ type: string
+ type:
+ description: 1:个人店铺
+ type: integer
+ type: object
+ model.SysMissionReward:
+ properties:
+ achieve_num:
+ description: 已完成任务次数
+ type: integer
+ audit_by:
+ description: 审核人
+ type: string
+ bonus:
+ description: 奖励金额
+ type: number
+ create_by:
+ description: 创建人
+ type: string
+ created_at:
+ description: 创建时间
+ type: string
+ id:
+ description: 主键ID
+ type: integer
+ relationId:
+ description: 关联项目id
+ type: string
+ status:
+ description: 状态 1待发放 2已发放 3已领取
+ type: integer
+ title:
+ description: 标题
+ type: string
+ type:
+ description: 奖励类型 1.视频上传 2.信息完善 3.商家任务
+ type: integer
+ update_by:
+ description: 更新人
+ type: string
+ updated_at:
+ description: 更新时间
+ type: string
+ type: object
+ model.TbAttributeDetail:
+ properties:
+ attribute_id:
+ description: 规格属性id
+ type: integer
+ value:
+ type: string
+ value_id:
+ type: integer
+ type: object
+ model.TbAttributeValueItem:
+ properties:
+ id:
+ type: integer
+ image:
+ description: 图片
+ type: string
+ name:
+ description: 规格属性值
+ type: string
+ type: object
+ model.TbAttributeWithValues:
+ properties:
+ id:
+ type: integer
+ name:
+ type: string
+ values:
+ items:
+ $ref: '#/definitions/model.TbAttributeValueItem'
+ type: array
+ type: object
+ model.TbGoodsDetail:
+ properties:
+ attributes:
+ description: 规格详情
+ items:
+ $ref: '#/definitions/model.TbAttributeWithValues'
+ type: array
+ breadcrumb:
+ description: 分类面包屑
+ items:
+ $ref: '#/definitions/model.Breadcrumb'
+ type: array
+ category_id:
+ description: 分类id
+ type: integer
+ collect_status:
+ description: 收藏状态 true:已收藏 false:未收藏
+ type: boolean
+ content:
+ description: 商品详情
+ type: string
+ content_text:
+ description: 详情-文字
+ type: string
+ cover:
+ type: string
+ created_at:
+ description: 创建时间
+ type: string
+ id:
+ description: 主键ID
+ type: integer
+ images:
+ description: 图片
+ type: string
+ list_price:
+ description: 列表价格
+ type: number
+ online:
+ description: 上下架状态 on/off
+ type: string
+ price_max:
+ description: 最高规格价格
+ type: number
+ price_min:
+ description: 最低规格价格
+ type: number
+ retail_price:
+ description: 吊牌价(零售指导价)
+ type: number
+ specs:
+ description: 规格
+ items:
+ $ref: '#/definitions/model.TbGoodsSpecsDetail'
+ type: array
+ spu_no:
+ description: 编号
+ type: string
+ tags:
+ description: 标签
+ type: string
+ title:
+ description: 标题
+ type: string
+ title_eng:
+ description: 英文标题
+ type: string
+ updated_at:
+ description: 更新时间
+ type: string
+ type: object
+ model.TbGoodsSpecsDetail:
+ properties:
+ attributes:
+ description: 规格详情
+ items:
+ $ref: '#/definitions/model.TbAttributeDetail'
+ type: array
+ code:
+ type: string
+ created_at:
+ description: 创建时间
+ type: string
+ goods_id:
+ type: integer
+ goods_no:
+ description: 商品编号
+ type: string
+ id:
+ description: 主键ID
+ type: integer
+ image:
+ description: 规格图片url
+ type: string
+ price:
+ description: 价格
+ type: number
+ sku_no:
+ description: 商品编码
+ type: string
+ specs:
+ description: 规格
+ type: string
+ stock:
+ description: 库存
+ type: integer
+ updated_at:
+ description: 更新时间
+ type: string
+ type: object
+ model.TbGoodsSpecsView:
+ properties:
+ attributes:
+ description: 规格详情
+ items:
+ $ref: '#/definitions/model.TbAttributeWithValues'
+ type: array
+ cover:
+ type: string
+ created_at:
+ description: 创建时间
+ type: string
+ id:
+ description: 主键ID
+ type: integer
+ images:
+ description: 图片
+ type: string
+ price_max:
+ description: 最高规格价格
+ type: number
+ price_min:
+ description: 最低规格价格
+ type: number
+ retail_price:
+ description: 吊牌价(零售指导价)
+ type: number
+ sales:
+ description: 总销售量
+ type: integer
+ specs:
+ description: 规格
+ items:
+ $ref: '#/definitions/model.TbGoodsSpecsDetail'
+ type: array
+ spu_no:
+ description: 编号
+ type: string
+ stock:
+ description: 总库存
+ type: integer
+ tags:
+ description: 标签
+ type: string
+ title:
+ description: 标题
+ type: string
+ title_eng:
+ description: 英文标题
+ type: string
+ updated_at:
+ description: 更新时间
+ type: string
+ type: object
+ model.TbOrderGoodsSpecsDetail:
+ properties:
+ code:
+ description: attribute定位标识
+ type: string
+ goods_id:
+ type: integer
+ goods_no:
+ description: 商品编号
+ type: string
+ image:
+ description: 规格图片url
+ type: string
+ orderGoodsId:
+ type: integer
+ price:
+ description: 价格
+ type: number
+ sku_no:
+ description: Attributes []TbAttributeDetail `gorm:"-" json:"-"` // 规格详情
+ type: string
+ specs:
+ description: 规格
+ type: string
+ type: object
+ model.UsCitys:
+ properties:
+ city:
+ type: string
+ county:
+ type: string
+ id:
+ type: integer
+ idState:
+ type: integer
+ type: object
+ model.UsSelect:
+ properties:
+ children:
+ items:
+ $ref: '#/definitions/model.UsCitys'
+ type: array
+ id:
+ type: integer
+ stateCode:
+ type: string
+ stateName:
+ type: string
+ type: object
+ model.UserSimple:
+ properties:
+ avatar:
+ description: 头像
+ type: string
+ email:
+ description: 用户邮箱
+ type: string
+ nick_name:
+ description: 昵称
+ type: string
+ phone:
+ description: 手机号
+ type: string
+ platform:
+ description: 平台
+ items:
+ $ref: '#/definitions/request.Platform'
+ type: array
+ tags:
+ description: 个人标签
+ type: string
+ uuid:
+ description: 用户uuid编码
+ type: string
+ type: object
+ model.Wallet:
+ properties:
+ balance:
+ description: 可用余额
+ type: number
+ created_at:
+ description: 创建时间
+ type: string
+ id:
+ description: 主键ID
+ type: integer
+ platform:
+ description: 平台 saller(买家端) / customer(客户端) / influencer(网红端)
+ type: string
+ state:
+ description: 状态 0:正常 1:限制提现 2:禁止提现
+ type: integer
+ transitBalance:
+ description: 在途余额
+ type: number
+ updated_at:
+ description: 更新时间
+ type: string
+ userId:
+ type: string
+ type: object
+ model.Withdrawal:
+ properties:
+ account_name:
+ description: 户名
+ type: string
+ account_type:
+ description: 账户类型 1:paypal 2:银行卡
+ type: integer
+ address:
+ description: 收款人地址
+ type: string
+ amount:
+ description: 金额
+ type: number
+ bank_code:
+ description: 收款行
+ type: string
+ bill_no:
+ description: 账单号
+ type: string
+ card_number:
+ description: 银行卡号
+ type: string
+ check_status:
+ description: 审核状态 0:待审核 1:审核通过 2:审核未通过
+ type: string
+ check_time:
+ description: 审核时间
+ type: string
+ country:
+ description: 国家/地区
+ type: string
+ create_by:
+ description: 创建人/店铺
+ type: string
+ created_at:
+ description: 创建时间
+ type: string
+ currency:
+ description: 币种 USD:美元
+ type: string
+ flow_no:
+ description: 流水号
+ type: string
+ id:
+ description: 主键ID
+ type: integer
+ pay_id:
+ description: 支付id
+ type: string
+ platform:
+ description: 平台 1:网红 2:商家
+ type: string
+ remark:
+ description: 备注
+ type: string
+ status:
+ description: 提现状态 0:进行中 1:成功 2:失败
+ type: string
+ swift_code:
+ description: 银行国际代码
+ type: string
+ title:
+ description: 标题
+ type: string
+ updated_at:
+ description: 更新时间
+ type: string
+ wallet_type:
+ description: 钱包类型 1:余额钱包 2:营销账户钱包
+ type: integer
+ type: object
+ model.WithdrawalView:
+ properties:
+ flow_no:
+ description: 流水号
+ type: string
+ type: object
+ request.AddAccount:
+ properties:
+ account_name:
+ description: 户名
+ type: string
+ address:
+ description: 收款人地址
+ type: string
+ bank_card:
+ description: 银行卡号
+ type: string
+ bank_code:
+ description: 银行编码
+ type: string
+ country:
+ description: 国家/地区
+ type: string
+ currency:
+ description: '币种 USD: 美元'
+ type: string
+ is_default:
+ description: 是否默认
+ type: boolean
+ swift_code:
+ description: swift编码
+ type: string
+ type: object
+ request.ClaimMission:
+ properties:
+ address_id:
+ description: 收货地址id
+ type: integer
+ email:
+ description: 邮箱地址
+ type: string
+ mission_id:
+ description: 任务id
+ type: integer
+ sku_no:
+ description: 商品sku_no
+ type: string
+ spu_no:
+ description: 商品spu_no
+ type: string
+ type: object
+ request.ClaimMissionVideo:
+ properties:
+ cover:
+ type: string
+ height:
+ description: 高度
+ type: integer
+ mission_claim_id:
+ description: 领取任务id
+ type: integer
+ source_type:
+ description: 类型:1:固定费用上传 2:奖励任务上传 3:后台上传
+ type: integer
+ video_url:
+ description: 视频上传地址
+ type: string
+ width:
+ description: 宽度
+ type: integer
+ type: object
+ request.ClaimMissionWorks:
+ properties:
+ homepage:
+ description: 作品主页地址
+ type: string
+ id:
+ description: id
+ type: integer
+ image:
+ description: 作品凭证截图
+ type: string
+ type:
+ description: 平台 1:ins 2:Pinterest 3:tk 4:Twitter 5:Facebook 6:Reddit
+ type: integer
+ video_url:
+ description: 视频上传地址
+ type: string
+ type: object
+ request.ClaimMissionWorksList:
+ properties:
+ mission_claim_id:
+ description: 领取任务id
+ type: integer
+ works:
+ description: 作品列表
+ items:
+ $ref: '#/definitions/request.ClaimMissionWorks'
+ type: array
+ type: object
+ request.DeleteAccount:
+ properties:
+ code:
+ description: 验证码
+ type: string
+ id:
+ description: 主键
+ type: integer
+ phone:
+ description: 手机号
+ type: string
+ type: object
+ request.IdReq:
+ properties:
+ id:
+ description: id
+ type: integer
+ type: object
+ request.MissionId:
+ properties:
+ mission_id:
+ description: 任务
+ type: integer
+ type: object
+ request.Platform:
+ properties:
+ image:
+ description: 图片
+ type: string
+ is_auth:
+ description: 是否认证
+ type: boolean
+ label:
+ type: string
+ platform:
+ description: 平台 字典表获取
+ type: string
+ url:
+ description: 主页地址
+ type: string
+ type: object
+ request.SendEmail:
+ properties:
+ email:
+ type: string
+ type: object
+ request.SendMessage:
+ properties:
+ country_code:
+ description: 用户手机号国家代码 国际区号 86 中国 1美国
+ type: string
+ phone:
+ type: string
+ type:
+ description: 1:登录验证码 2-解绑 3-绑定 4-提现
+ type: integer
+ type: object
+ request.UserAuthorized:
+ properties:
+ appid:
+ description: 应用id
+ type: string
+ client:
+ description: 客户端 ios android web
+ type: string
+ code:
+ description: 授权码
+ type: string
+ platform:
+ description: 平台 google facebook twitter tiktok
+ type: string
+ token:
+ description: token
+ type: string
+ uuid:
+ description: 设备唯一标识
+ type: string
+ type: object
+ request.UserBandPhone:
+ properties:
+ code:
+ description: 验证码
+ type: string
+ phone:
+ description: 手机号
+ type: string
+ type: object
+ request.UserDetail:
+ properties:
+ platform:
+ description: 平台及地址逗号隔开 eg:(ins:https://baidu.com/user/1,qq:12345678)
+ type: string
+ tags:
+ description: 个人标签
+ type: string
+ type:
+ description: 修改字段 platform-平台 tags-个人标签
+ type: string
+ type: object
+ request.UserLogin:
+ properties:
+ appid:
+ description: 应用id
+ type: string
+ code:
+ description: 验证码
+ type: string
+ country_code:
+ description: 用户手机号国家代码 国际区号 86 中国 1美国
+ type: string
+ email:
+ description: 邮箱
+ type: string
+ password:
+ description: 密码
+ type: string
+ phone:
+ description: 手机号
+ type: string
+ type:
+ description: 1-手机号 2-邮箱
+ type: string
+ type: object
+ request.UserPlatformAuth:
+ properties:
+ platform:
+ allOf:
+ - $ref: '#/definitions/request.Platform'
+ description: 平台
+ tags:
+ description: 个人标签
+ type: string
+ type: object
+ request.UserRegister:
+ properties:
+ appid:
+ description: 应用id
+ type: string
+ avatar:
+ description: 头像
+ type: string
+ code:
+ description: 验证码
+ type: string
+ country_code:
+ description: 用户手机号国家代码 国际区号 86 中国 1美国
+ type: string
+ email:
+ description: 邮箱
+ type: string
+ nickname:
+ description: 昵称
+ type: string
+ type: object
+ request.WithdrawalParams:
+ properties:
+ accountID:
+ description: 提现账户id
+ type: integer
+ amount:
+ description: Code string `json:"code"` // 验证码
+ type: number
+ type: object
+ response.BannerListResponse:
+ properties:
+ coverUrl:
+ description: 封面图
+ type: string
+ id:
+ description: 主键
+ type: integer
+ link:
+ description: 链接地址
+ type: string
+ linkType:
+ description: 链接类型 0:内链 1:外链
+ type: string
+ relationId:
+ description: 关联项目id
+ type: string
+ relationType:
+ description: 关联类型 01-任务
+ type: string
+ sort_index:
+ description: 序号索引
+ type: integer
+ status:
+ description: 状态 0=下架 1=上架
+ type: string
+ title:
+ description: 标题
+ type: string
+ type:
+ description: 任务-0101 平台奖励页-0102
+ type: string
+ type: object
+ response.ChainResp:
+ properties:
+ block_adress:
+ description: 所在区块
+ type: string
+ block_height:
+ description: 块高度
+ type: integer
+ hash:
+ description: 交易哈希
+ type: string
+ time:
+ description: 上链时间
+ type: string
+ type: object
+ response.MissionRecommendResponse:
+ properties:
+ achieve_num:
+ description: 已完成商品数量
+ type: integer
+ bought_num:
+ description: 购买人数
+ type: number
+ claim_num:
+ description: 任务领取人数
+ type: integer
+ cover:
+ description: 封面
+ type: string
+ create_by:
+ description: 创建人
+ type: string
+ created_at:
+ description: 创建时间
+ type: string
+ end_time:
+ description: 任务结束时间
+ type: string
+ goods_title:
+ description: 商品标题
+ type: string
+ goods_title_eng:
+ description: 商品英文标题
+ type: string
+ height:
+ description: 高度
+ type: integer
+ hire_money:
+ description: hire_type==1 佣金金额
+ type: number
+ hire_money_expect:
+ description: 预计佣金描述
+ type: string
+ hire_ratio:
+ description: hire_type==2 抽成比例
+ type: number
+ hire_type:
+ description: 佣金类型 1:固定佣金 2:比例抽成
+ type: integer
+ id:
+ description: 主键ID
+ type: integer
+ influencer:
+ $ref: '#/definitions/model.UserSimple'
+ mission_id:
+ description: 任务ID
+ type: integer
+ mission_status:
+ description: 任务状态
+ type: integer
+ relation_id:
+ description: 关联ID,任务视频ID
+ type: integer
+ release_channels:
+ description: 发布渠道
+ type: string
+ release_country:
+ description: 发布国家
+ type: string
+ sort:
+ description: 倒序 //排序
+ type: integer
+ start_time:
+ description: 任务起始时间
+ type: string
+ status:
+ description: 状态 1:上架 2:下架
+ type: integer
+ tag:
+ description: todo 标签系统
+ type: string
+ title:
+ description: 任务标题
+ type: string
+ total_bonus:
+ description: 累计奖励
+ type: number
+ updated_at:
+ description: 更新时间
+ type: string
+ video_url:
+ description: 视频地址
+ type: string
+ width:
+ description: 宽度
+ type: integer
+ type: object
+ response.SysBonusDetail:
+ properties:
+ achieve_max:
+ description: 最大完成次数
+ type: integer
+ achieve_num:
+ description: 已完成任务次数
+ type: integer
+ bonus:
+ description: 奖金
+ type: number
+ mission_list:
+ description: 任务列表
+ items:
+ $ref: '#/definitions/response.SysMissionDesc'
+ type: array
+ title:
+ description: 标题
+ type: string
+ total:
+ description: 奖励次数
+ type: integer
+ type:
+ description: 奖励类型 1.视频上传 2.信息完善 3.商家任务
+ type: integer
+ type: object
+ response.SysMissionBonus:
+ properties:
+ total:
+ description: 奖励总笔数
+ type: integer
+ total_bonus:
+ description: 奖励汇总金额
+ type: number
+ video_bonus:
+ allOf:
+ - $ref: '#/definitions/response.SysBonusDetail'
+ description: 视频上传
+ type: object
+ response.SysMissionDesc:
+ properties:
+ achieve_num:
+ type: integer
+ bonus:
+ description: 奖励金额
+ type: number
+ description:
+ description: 描述
+ type: string
+ description_eng:
+ description: 描述英文
+ type: string
+ status:
+ description: 状态 1待发放 2已发放 3已领取 0未完成
+ type: integer
+ title:
+ description: 任务标题
+ type: string
+ title_eng:
+ description: 任务标题英文
+ type: string
+ type: object
+ response.UserStatistics:
+ properties:
+ claim_mission_num:
+ description: 领取任务数量
+ type: integer
+ collection_mission_num:
+ description: 收藏任务数量
+ type: integer
+ platform_num:
+ description: 认证平台数量
+ type: integer
+ type: object
+info:
+ contact: {}
+ description: 接口文档
+ title: Swagger Example API
+ version: 0.0.1
+paths:
+ /base/authorized:
+ post:
+ parameters:
+ - description: email,password...
+ in: body
+ name: data
+ required: true
+ schema:
+ $ref: '#/definitions/request.UserAuthorized'
+ responses:
+ "200":
+ description: '{"code": 1, "message": ""}'
+ schema:
+ type: string
+ security:
+ - Bearer: []
+ summary: 授权登录[v1.0.0]
+ tags:
+ - auth
+ /base/sendEmail:
+ post:
+ consumes:
+ - application/json
+ parameters:
+ - description: phone,type
+ in: body
+ name: data
+ required: true
+ schema:
+ $ref: '#/definitions/request.SendEmail'
+ produces:
+ - application/json
+ responses:
+ "200":
+ description: '{"success":true,"data":{},"msg":"获取成功"}'
+ schema:
+ type: string
+ security:
+ - ApiKeyAuth: []
+ summary: 发送邮件验证码[v1.0.0]
+ tags:
+ - tools
+ /base/sendMessage:
+ post:
+ consumes:
+ - application/json
+ parameters:
+ - description: phone,type
+ in: body
+ name: data
+ required: true
+ schema:
+ $ref: '#/definitions/request.SendMessage'
+ produces:
+ - application/json
+ responses:
+ "200":
+ description: '{"success":true,"data":{},"msg":"获取成功"}'
+ schema:
+ type: string
+ security:
+ - ApiKeyAuth: []
+ summary: 发送短信验证码[v1.0.0]
+ tags:
+ - tools
+ /customer/base/brochure:
+ get:
+ parameters:
+ - in: query
+ name: type
+ type: string
+ responses:
+ "200":
+ description: '{"success":true,"data":{},"msg":""}'
+ schema:
+ type: string
+ summary: 隐私协议单页
+ tags:
+ - tools
+ /dict/getDictDataList:
+ get:
+ consumes:
+ - application/json
+ parameters:
+ - description: 取值 release_country=发布国家 release_channel=发布渠道 tag_type=标签类型
+ in: query
+ name: typeCode
+ type: string
+ produces:
+ - application/json
+ responses:
+ "200":
+ description: '{"success":true,"data":{},"msg":"获取成功"}'
+ schema:
+ type: string
+ security:
+ - ApiKeyAuth: []
+ summary: 获取数据字典取值列表【v1.0】
+ tags:
+ - dict
+ /global/address:
+ delete:
+ parameters:
+ - description: data...
+ in: body
+ name: data
+ schema:
+ $ref: '#/definitions/global.BASE_ID'
+ responses:
+ "200":
+ description: '{"code": 1, "message": ""}'
+ schema:
+ type: string
+ security:
+ - Bearer: []
+ summary: 删除收货地址【v1.0】
+ tags:
+ - 公用-收货地址
+ get:
+ responses:
+ "200":
+ description: '{"code": 1, "message": ""}'
+ schema:
+ type: string
+ security:
+ - Bearer: []
+ summary: 获取用户收货地址列表【v1.0】
+ tags:
+ - 公用-收货地址
+ post:
+ parameters:
+ - description: data...
+ in: body
+ name: data
+ schema:
+ $ref: '#/definitions/model.Address'
+ responses:
+ "200":
+ description: '{"code": 1, "message": ""}'
+ schema:
+ type: string
+ security:
+ - Bearer: []
+ summary: 添加收货地址【v1.0】
+ tags:
+ - 公用-收货地址
+ put:
+ parameters:
+ - description: data...
+ in: body
+ name: data
+ schema:
+ $ref: '#/definitions/model.Address'
+ responses:
+ "200":
+ description: '{"code": 1, "message": ""}'
+ schema:
+ type: string
+ security:
+ - Bearer: []
+ summary: 修改收货地址【v1.0】
+ tags:
+ - 公用-收货地址
+ /global/track:
+ get:
+ parameters:
+ - description: id
+ in: query
+ name: id
+ type: integer
+ responses:
+ "200":
+ description: '{"code": 1, "message": ""}'
+ schema:
+ type: string
+ security:
+ - Bearer: []
+ summary: 查询物流信息
+ tags:
+ - track
+ /global/usSelect:
+ get:
+ responses:
+ "200":
+ description: '{"code": 1, "message": ""}'
+ schema:
+ type: string
+ security:
+ - Bearer: []
+ summary: 美国地区选择器【v1.0】
+ tags:
+ - 公用-收货地址
+ /influencer/banner/list:
+ get:
+ consumes:
+ - application/json
+ produces:
+ - application/json
+ responses:
+ "200":
+ description: '{"success":true,"data":{},"msg":"获取成功"}'
+ schema:
+ items:
+ $ref: '#/definitions/response.BannerListResponse'
+ type: array
+ security:
+ - ApiKeyAuth: []
+ summary: 分页获取banner列表【v1.1.0新增】
+ tags:
+ - banner
+ /influencer/base/brochure:
+ get:
+ parameters:
+ - in: query
+ name: type
+ type: string
+ responses:
+ "200":
+ description: '{"success":true,"data":{},"msg":""}'
+ schema:
+ type: string
+ summary: 隐私协议单页
+ tags:
+ - tools
+ /influencer/base/chain:
+ get:
+ parameters:
+ - description: 区块/合约hash
+ in: query
+ name: hash
+ type: string
+ responses:
+ "200":
+ description: '{"code": 0, "data": [...]}'
+ schema:
+ items:
+ $ref: '#/definitions/response.ChainResp'
+ type: array
+ "201":
+ description: '{"code": 1, "message": ""}'
+ schema:
+ type: string
+ summary: 获取区块链数据
+ tags:
+ - Chain
+ /influencer/base/login:
+ post:
+ parameters:
+ - description: email,password...
+ in: body
+ name: data
+ required: true
+ schema:
+ $ref: '#/definitions/request.UserLogin'
+ responses:
+ "200":
+ description: '{"code": 1, "message": ""}'
+ schema:
+ type: string
+ security:
+ - Bearer: []
+ summary: 登录[v1.0.0]
+ tags:
+ - auth
+ /influencer/base/register:
+ post:
+ parameters:
+ - description: email,password...
+ in: body
+ name: data
+ required: true
+ schema:
+ $ref: '#/definitions/request.UserRegister'
+ responses:
+ "200":
+ description: '{"code": 1, "message": ""}'
+ schema:
+ type: string
+ security:
+ - Bearer: []
+ summary: 注册[v1.0.0]
+ tags:
+ - auth
+ /influencer/base/version:
+ get:
+ responses:
+ "200":
+ description: '{"code": 0, "data": [...]}'
+ schema:
+ type: string
+ "201":
+ description: '{"code": 1, "message": ""}'
+ schema:
+ type: string
+ security:
+ - Bearer: []
+ summary: 获取版本信息
+ tags:
+ - version
+ /influencer/goods/detail:
+ get:
+ parameters:
+ - description: 领取任务id
+ in: query
+ name: claim_no
+ type: string
+ - description: 商品id
+ in: query
+ name: id
+ type: integer
+ - description: sku_no
+ in: query
+ name: sku_no
+ type: string
+ responses:
+ "200":
+ description: '{"code": 200, "data": {}}'
+ schema:
+ $ref: '#/definitions/model.TbGoodsDetail'
+ security:
+ - ApiKeyAuth: []
+ summary: 获取商品详情
+ tags:
+ - goods
+ /influencer/mission/bonus:
+ get:
+ parameters:
+ - description: 任务编码
+ in: query
+ name: code
+ type: string
+ responses:
+ "200":
+ description: '{"code": 200, "data": {}}'
+ schema:
+ $ref: '#/definitions/model.MissionBonus'
+ security:
+ - ApiKeyAuth: []
+ summary: 获取任务累计奖金
+ tags:
+ - mission
+ /influencer/mission/claim:
+ get:
+ parameters:
+ - description: id
+ in: query
+ name: id
+ type: integer
+ responses:
+ "200":
+ description: '{"code": 200, "data": {}}'
+ schema:
+ $ref: '#/definitions/model.MissionClaimDetail'
+ security:
+ - ApiKeyAuth: []
+ summary: 获取我的任务详情【v1.0】
+ tags:
+ - mission
+ post:
+ parameters:
+ - description: params
+ in: body
+ name: data
+ schema:
+ $ref: '#/definitions/request.ClaimMission'
+ responses:
+ "200":
+ description: '{"code": 200, "data": {}}'
+ schema:
+ type: string
+ security:
+ - ApiKeyAuth: []
+ summary: 领取任务【v1.0】
+ tags:
+ - mission
+ /influencer/mission/claim-list:
+ get:
+ parameters:
+ - description: 佣金类型 1:固定佣金 2:比例抽成
+ in: query
+ name: hire_type
+ type: integer
+ - description: 页码
+ in: query
+ name: page
+ type: integer
+ - description: 每页大小
+ in: query
+ name: pageSize
+ type: integer
+ - description: 是否筛选上传视频 1是
+ in: query
+ name: video_upload
+ type: integer
+ responses:
+ "200":
+ description: '{"code": 200, "data": {}}'
+ schema:
+ items:
+ $ref: '#/definitions/model.MissionClaimDetail'
+ type: array
+ security:
+ - ApiKeyAuth: []
+ summary: 获取我的任务列表【v1.0】
+ tags:
+ - mission
+ /influencer/mission/collect:
+ post:
+ parameters:
+ - description: params
+ in: body
+ name: data
+ schema:
+ $ref: '#/definitions/request.MissionId'
+ responses:
+ "200":
+ description: '{"code": 200, "data": {}}'
+ schema:
+ type: string
+ security:
+ - ApiKeyAuth: []
+ summary: 收藏/取消收藏任务【v1.0】
+ tags:
+ - mission
+ /influencer/mission/collect-list:
+ get:
+ parameters:
+ - description: 页码
+ in: query
+ name: page
+ type: integer
+ - description: 每页大小
+ in: query
+ name: pageSize
+ type: integer
+ responses:
+ "200":
+ description: '{"code": 200, "data": {}}'
+ schema:
+ items:
+ $ref: '#/definitions/model.MissionDetail'
+ type: array
+ security:
+ - ApiKeyAuth: []
+ summary: 获取收藏任务列表【v1.0】
+ tags:
+ - mission
+ /influencer/mission/detail:
+ get:
+ parameters:
+ - description: id
+ in: query
+ name: id
+ type: integer
+ responses:
+ "200":
+ description: '{"code": 200, "data": {}}'
+ schema:
+ $ref: '#/definitions/model.MissionDetail'
+ security:
+ - ApiKeyAuth: []
+ summary: 获取任务详情【v1.0】
+ tags:
+ - mission
+ /influencer/mission/list:
+ get:
+ parameters:
+ - description: 页码
+ in: query
+ name: page
+ type: integer
+ - description: 每页大小
+ in: query
+ name: pageSize
+ type: integer
+ responses:
+ "200":
+ description: '{"code": 200, "data": {}}'
+ schema:
+ items:
+ $ref: '#/definitions/model.MissionDetail'
+ type: array
+ security:
+ - ApiKeyAuth: []
+ summary: 获取任务列表【v1.0】
+ tags:
+ - mission
+ /influencer/mission/order-data:
+ get:
+ parameters:
+ - description: 任务编码
+ in: query
+ name: code
+ type: string
+ responses:
+ "200":
+ description: '{"code": 0, "data": [...]}'
+ schema:
+ $ref: '#/definitions/dto.MissionOrderStatistic'
+ "201":
+ description: '{"code": 1, "message": ""}'
+ schema:
+ type: string
+ security:
+ - Bearer: []
+ summary: 获取任务下订单统计数据
+ tags:
+ - mission
+ /influencer/mission/recommend-detail:
+ get:
+ parameters:
+ - description: id
+ in: query
+ name: id
+ type: integer
+ responses:
+ "200":
+ description: '{"code": 200, "data": {}}'
+ schema:
+ $ref: '#/definitions/response.MissionRecommendResponse'
+ security:
+ - ApiKeyAuth: []
+ summary: 获取首页任务详情【v1.0】
+ tags:
+ - mission
+ /influencer/mission/recommend-list:
+ get:
+ parameters:
+ - description: 页码
+ in: query
+ name: page
+ type: integer
+ - description: 每页大小
+ in: query
+ name: pageSize
+ type: integer
+ responses:
+ "200":
+ description: '{"code": 200, "data": {}}'
+ schema:
+ items:
+ $ref: '#/definitions/response.MissionRecommendResponse'
+ type: array
+ security:
+ - ApiKeyAuth: []
+ summary: 获取首页任务列表【v1.0】
+ tags:
+ - mission
+ /influencer/mission/submit-video:
+ post:
+ parameters:
+ - description: params
+ in: body
+ name: data
+ schema:
+ $ref: '#/definitions/request.ClaimMissionVideo'
+ responses:
+ "200":
+ description: '{"code": 200, "data": {}}'
+ schema:
+ type: string
+ security:
+ - ApiKeyAuth: []
+ summary: 固定费用任务上传视频【v1.0】
+ tags:
+ - mission
+ /influencer/mission/submit-works:
+ post:
+ parameters:
+ - description: params
+ in: body
+ name: data
+ schema:
+ $ref: '#/definitions/request.ClaimMissionWorksList'
+ responses:
+ "200":
+ description: '{"code": 200, "data": {}}'
+ schema:
+ type: string
+ security:
+ - ApiKeyAuth: []
+ summary: 领取任务的提交作品【v1.0】
+ tags:
+ - mission
+ /influencer/mission/sys-reward-list:
+ get:
+ parameters:
+ - description: 页码
+ in: query
+ name: page
+ type: integer
+ - description: 每页大小
+ in: query
+ name: pageSize
+ type: integer
+ - description: 状态 1待发放 2已发放 3已领取
+ in: query
+ name: status
+ type: integer
+ responses:
+ "200":
+ description: '{"code": 200, "data": {}}'
+ schema:
+ items:
+ $ref: '#/definitions/model.SysMissionReward'
+ type: array
+ security:
+ - ApiKeyAuth: []
+ summary: 获取平台奖励列表【v1.0】
+ tags:
+ - mission
+ /influencer/mission/sys-reward-summary:
+ get:
+ parameters:
+ - description: 状态 1待发放 2已发放 3已领取
+ in: query
+ name: status
+ type: integer
+ responses:
+ "200":
+ description: '{"code": 200, "data": {}}'
+ schema:
+ $ref: '#/definitions/response.SysMissionBonus'
+ security:
+ - ApiKeyAuth: []
+ summary: 获取平台奖励汇总【v1.0】
+ tags:
+ - mission
+ /influencer/order/data:
+ get:
+ parameters:
+ - description: 场景 my:我的 order-list:订单列表
+ in: query
+ name: scene
+ type: string
+ responses:
+ "200":
+ description: '{"code": 0, "data": [...]}'
+ schema:
+ $ref: '#/definitions/dto.OrderData'
+ "201":
+ description: '{"code": 1, "message": ""}'
+ schema:
+ type: string
+ security:
+ - Bearer: []
+ summary: 获取订单数据
+ tags:
+ - order
+ /influencer/order/detail:
+ get:
+ parameters:
+ - description: 订单号
+ in: query
+ name: orderID
+ type: string
+ responses:
+ "200":
+ description: '{"code": 0, "data": [...]}'
+ schema:
+ $ref: '#/definitions/model.OrderDetail'
+ "201":
+ description: '{"code": 1, "message": ""}'
+ schema:
+ type: string
+ security:
+ - Bearer: []
+ summary: 获取订单详情
+ tags:
+ - order
+ /influencer/order/goods/snapshot:
+ get:
+ parameters:
+ - description: 订单号
+ in: query
+ name: orderID
+ type: string
+ responses:
+ "200":
+ description: '{"code": 0, "data": [...]}'
+ schema:
+ $ref: '#/definitions/model.OrderGoodsDetail'
+ "201":
+ description: '{"code": 1, "message": ""}'
+ schema:
+ type: string
+ security:
+ - Bearer: []
+ summary: 获取订单商品快照
+ tags:
+ - order
+ /influencer/order/list:
+ get:
+ parameters:
+ - description: 网红码?
+ in: query
+ name: code
+ type: string
+ - description: 数据库分组
+ in: query
+ name: group
+ type: string
+ - description: 订单号
+ in: query
+ name: orderID
+ type: string
+ - description: 页码
+ in: query
+ name: page
+ type: integer
+ - description: 每页大小
+ in: query
+ name: pageSize
+ type: integer
+ - description: 订单状态 //订单状态 1-待付款 2-待发货 3-已发货 4-已完成 5-已取消
+ in: query
+ name: status
+ type: integer
+ responses:
+ "200":
+ description: '{"code": 0, "data": [...]}'
+ schema:
+ items:
+ $ref: '#/definitions/model.OrderList'
+ type: array
+ "201":
+ description: '{"code": 1, "message": ""}'
+ schema:
+ type: string
+ security:
+ - Bearer: []
+ summary: 获取订单列表
+ tags:
+ - order
+ /influencer/user/bandPhone:
+ post:
+ parameters:
+ - description: email,password...
+ in: body
+ name: data
+ required: true
+ schema:
+ $ref: '#/definitions/request.UserBandPhone'
+ responses:
+ "200":
+ description: '{"code": 1, "message": ""}'
+ schema:
+ type: string
+ security:
+ - Bearer: []
+ summary: 网红绑定手机[v1.0.0]
+ tags:
+ - 网红端-用户
+ /influencer/user/detail:
+ get:
+ responses:
+ "200":
+ description: '{"code": 1, "message": ""}'
+ schema:
+ type: string
+ security:
+ - Bearer: []
+ summary: 获取用户基本信息[v1.0.0]
+ tags:
+ - 网红端-用户
+ put:
+ parameters:
+ - description: data...
+ in: body
+ name: data
+ schema:
+ $ref: '#/definitions/request.UserDetail'
+ responses:
+ "200":
+ description: '{"code": 1, "message": ""}'
+ schema:
+ type: string
+ security:
+ - Bearer: []
+ summary: 修改用户基本信息
+ tags:
+ - 网红端-用户
+ /influencer/user/logoff:
+ post:
+ responses:
+ "200":
+ description: '{"code": 0, "data": "注销成功"}'
+ schema:
+ type: string
+ security:
+ - Bearer: []
+ summary: 注销账户[v1.0.1]
+ tags:
+ - 网红端-用户
+ /influencer/user/platformAuth:
+ post:
+ parameters:
+ - description: email,password...
+ in: body
+ name: data
+ required: true
+ schema:
+ $ref: '#/definitions/request.UserPlatformAuth'
+ responses:
+ "200":
+ description: '{"code": 1, "message": ""}'
+ schema:
+ type: string
+ security:
+ - Bearer: []
+ summary: 平台认证[v1.0.0]
+ tags:
+ - 网红端-用户
+ /influencer/user/statistics:
+ get:
+ responses:
+ "200":
+ description: '{"code": 0, "data": [...]}'
+ schema:
+ $ref: '#/definitions/response.UserStatistics'
+ security:
+ - Bearer: []
+ summary: 获取用户统计信息[v1.0.0]
+ tags:
+ - 网红端-用户
+ /influencer/wallet/account:
+ delete:
+ parameters:
+ - description: data...
+ in: body
+ name: data
+ schema:
+ $ref: '#/definitions/request.DeleteAccount'
+ responses:
+ "200":
+ description: '{"code": 0, "data": [...]}'
+ schema:
+ type: string
+ "201":
+ description: '{"code": 1, "message": ""}'
+ schema:
+ type: string
+ security:
+ - Bearer: []
+ summary: 解绑账户
+ tags:
+ - 网红端-用户钱包
+ post:
+ parameters:
+ - description: data...
+ in: body
+ name: data
+ schema:
+ $ref: '#/definitions/request.AddAccount'
+ responses:
+ "200":
+ description: '{"code": 0, "data": [...]}'
+ schema:
+ type: string
+ "201":
+ description: '{"code": 1, "message": ""}'
+ schema:
+ type: string
+ security:
+ - Bearer: []
+ summary: 添加账户
+ tags:
+ - 网红端-用户钱包
+ /influencer/wallet/account/default:
+ put:
+ parameters:
+ - description: data...
+ in: body
+ name: data
+ schema:
+ $ref: '#/definitions/request.IdReq'
+ responses:
+ "200":
+ description: '{"code": 0, "data": [...]}'
+ schema:
+ type: string
+ "201":
+ description: '{"code": 1, "message": ""}'
+ schema:
+ type: string
+ security:
+ - Bearer: []
+ summary: 设置账户默认开关
+ tags:
+ - 网红端-用户钱包
+ /influencer/wallet/accountList:
+ get:
+ responses:
+ "200":
+ description: '{"code": 0, "data": [...]}'
+ schema:
+ items:
+ $ref: '#/definitions/model.Account'
+ type: array
+ "201":
+ description: '{"code": 1, "message": ""}'
+ schema:
+ type: string
+ security:
+ - Bearer: []
+ summary: 获取账户列表
+ tags:
+ - 网红端-用户钱包
+ /influencer/wallet/bill-list:
+ get:
+ parameters:
+ - description: 页码
+ in: query
+ name: page
+ type: integer
+ - description: 每页大小
+ in: query
+ name: pageSize
+ type: integer
+ - description: 空:默认 1:bill-center
+ in: query
+ name: scene
+ type: string
+ - description: 空:全部 1-支出 2-收入
+ in: query
+ name: status
+ type: string
+ - description: 1:全部 2:昨天 3:近30天
+ in: query
+ name: uint
+ type: string
+ responses:
+ "200":
+ description: '{"code": 0, "data": [...]}'
+ schema:
+ items:
+ $ref: '#/definitions/model.Bill'
+ type: array
+ "201":
+ description: '{"code": 1, "message": ""}'
+ schema:
+ type: string
+ security:
+ - Bearer: []
+ summary: 获取资金流水记录
+ tags:
+ - 对账中心
+ /influencer/wallet/bill-notify:
+ get:
+ responses:
+ "200":
+ description: '{"code": 0, "data": [...]}'
+ schema:
+ items:
+ $ref: '#/definitions/model.BillNotify'
+ type: array
+ "201":
+ description: '{"code": 1, "message": ""}'
+ schema:
+ type: string
+ security:
+ - Bearer: []
+ summary: 获取账单通知列表
+ tags:
+ - 对账中心
+ /influencer/wallet/bill/data:
+ get:
+ parameters:
+ - description: 1:全部 2:昨天 3:近30天
+ in: query
+ name: uint
+ type: string
+ responses:
+ "200":
+ description: '{"code": 0, "data": [...]}'
+ schema:
+ $ref: '#/definitions/dto.BillData'
+ "201":
+ description: '{"code": 1, "message": ""}'
+ schema:
+ type: string
+ security:
+ - Bearer: []
+ summary: 获取对账中心数据
+ tags:
+ - 对账中心
+ /influencer/wallet/detail:
+ get:
+ responses:
+ "200":
+ description: '{"code": 0, "data": [...]}'
+ schema:
+ $ref: '#/definitions/model.Wallet'
+ "201":
+ description: '{"code": 1, "message": ""}'
+ schema:
+ type: string
+ security:
+ - Bearer: []
+ summary: 钱包基本信息
+ tags:
+ - 网红端-用户钱包
+ /influencer/wallet/withdrawal:
+ get:
+ parameters:
+ - description: 流水号
+ in: query
+ name: flow_no
+ type: string
+ responses:
+ "200":
+ description: '{"code": 0, "data": [...]}'
+ schema:
+ $ref: '#/definitions/model.Withdrawal'
+ "201":
+ description: '{"code": 1, "message": ""}'
+ schema:
+ type: string
+ security:
+ - Bearer: []
+ summary: 获取提现详情
+ tags:
+ - 对账中心
+ post:
+ parameters:
+ - description: data...
+ in: body
+ name: data
+ schema:
+ $ref: '#/definitions/request.WithdrawalParams'
+ responses:
+ "200":
+ description: '{"code": 1, "message": ""}'
+ schema:
+ type: string
+ security:
+ - Bearer: []
+ summary: 提现
+ tags:
+ - 网红端-用户钱包
+ /influencer/wallet/withdrawal-list:
+ get:
+ parameters:
+ - description: 页码
+ in: query
+ name: page
+ type: integer
+ - description: 每页大小
+ in: query
+ name: pageSize
+ type: integer
+ responses:
+ "200":
+ description: '{"code": 0, "data": [...]}'
+ schema:
+ items:
+ $ref: '#/definitions/model.Withdrawal'
+ type: array
+ "201":
+ description: '{"code": 1, "message": ""}'
+ schema:
+ type: string
+ security:
+ - Bearer: []
+ summary: 获取提现记录
+ tags:
+ - 对账中心
+securityDefinitions:
+ ApiKeyAuth:
+ in: header
+ name: x-token
+ type: apiKey
+swagger: "2.0"
diff --git a/dto/customer.pb.go b/dto/customer.pb.go
new file mode 100644
index 0000000..2b30d0e
--- /dev/null
+++ b/dto/customer.pb.go
@@ -0,0 +1,820 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.31.0
+// protoc v3.21.12
+// source: customer.proto
+
+package dto
+
+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 LoginRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email"`
+ Phone string `protobuf:"bytes,2,opt,name=phone,proto3" json:"phone"`
+ Code string `protobuf:"bytes,3,opt,name=code,proto3" json:"code"`
+ Password string `protobuf:"bytes,4,opt,name=password,proto3" json:"password"`
+ Type string `protobuf:"bytes,5,opt,name=type,proto3" json:"type"`
+ Appid string `protobuf:"bytes,6,opt,name=appid,proto3" json:"appid"`
+}
+
+func (x *LoginRequest) Reset() {
+ *x = LoginRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_customer_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *LoginRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*LoginRequest) ProtoMessage() {}
+
+func (x *LoginRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_customer_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 LoginRequest.ProtoReflect.Descriptor instead.
+func (*LoginRequest) Descriptor() ([]byte, []int) {
+ return file_customer_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *LoginRequest) GetEmail() string {
+ if x != nil {
+ return x.Email
+ }
+ return ""
+}
+
+func (x *LoginRequest) GetPhone() string {
+ if x != nil {
+ return x.Phone
+ }
+ return ""
+}
+
+func (x *LoginRequest) GetCode() string {
+ if x != nil {
+ return x.Code
+ }
+ return ""
+}
+
+func (x *LoginRequest) GetPassword() string {
+ if x != nil {
+ return x.Password
+ }
+ return ""
+}
+
+func (x *LoginRequest) GetType() string {
+ if x != nil {
+ return x.Type
+ }
+ return ""
+}
+
+func (x *LoginRequest) GetAppid() string {
+ if x != nil {
+ return x.Appid
+ }
+ return ""
+}
+
+type RegisterRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email"`
+ Code string `protobuf:"bytes,2,opt,name=code,proto3" json:"code"`
+ Nickname string `protobuf:"bytes,3,opt,name=nickname,proto3" json:"nickname"`
+ Avatar string `protobuf:"bytes,4,opt,name=avatar,proto3" json:"avatar"`
+ Appid string `protobuf:"bytes,5,opt,name=appid,proto3" json:"appid"`
+}
+
+func (x *RegisterRequest) Reset() {
+ *x = RegisterRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_customer_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *RegisterRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RegisterRequest) ProtoMessage() {}
+
+func (x *RegisterRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_customer_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 RegisterRequest.ProtoReflect.Descriptor instead.
+func (*RegisterRequest) Descriptor() ([]byte, []int) {
+ return file_customer_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *RegisterRequest) GetEmail() string {
+ if x != nil {
+ return x.Email
+ }
+ return ""
+}
+
+func (x *RegisterRequest) GetCode() string {
+ if x != nil {
+ return x.Code
+ }
+ return ""
+}
+
+func (x *RegisterRequest) GetNickname() string {
+ if x != nil {
+ return x.Nickname
+ }
+ return ""
+}
+
+func (x *RegisterRequest) GetAvatar() string {
+ if x != nil {
+ return x.Avatar
+ }
+ return ""
+}
+
+func (x *RegisterRequest) GetAppid() string {
+ if x != nil {
+ return x.Appid
+ }
+ return ""
+}
+
+type SmsRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Phone string `protobuf:"bytes,1,opt,name=phone,proto3" json:"phone"`
+}
+
+func (x *SmsRequest) Reset() {
+ *x = SmsRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_customer_proto_msgTypes[2]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *SmsRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SmsRequest) ProtoMessage() {}
+
+func (x *SmsRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_customer_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 SmsRequest.ProtoReflect.Descriptor instead.
+func (*SmsRequest) Descriptor() ([]byte, []int) {
+ return file_customer_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *SmsRequest) GetPhone() string {
+ if x != nil {
+ return x.Phone
+ }
+ return ""
+}
+
+type WithdrawRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Phone string `protobuf:"bytes,1,opt,name=phone,proto3" json:"phone"` //账户绑定手机号
+ Code string `protobuf:"bytes,2,opt,name=code,proto3" json:"code"` //验证码
+ Amount float64 `protobuf:"fixed64,3,opt,name=amount,proto3" json:"amount"` //提现金额
+ AccountID int32 `protobuf:"varint,4,opt,name=accountID,proto3" json:"accountID"` //账户id
+}
+
+func (x *WithdrawRequest) Reset() {
+ *x = WithdrawRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_customer_proto_msgTypes[3]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *WithdrawRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*WithdrawRequest) ProtoMessage() {}
+
+func (x *WithdrawRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_customer_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 WithdrawRequest.ProtoReflect.Descriptor instead.
+func (*WithdrawRequest) Descriptor() ([]byte, []int) {
+ return file_customer_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *WithdrawRequest) GetPhone() string {
+ if x != nil {
+ return x.Phone
+ }
+ return ""
+}
+
+func (x *WithdrawRequest) GetCode() string {
+ if x != nil {
+ return x.Code
+ }
+ return ""
+}
+
+func (x *WithdrawRequest) GetAmount() float64 {
+ if x != nil {
+ return x.Amount
+ }
+ return 0
+}
+
+func (x *WithdrawRequest) GetAccountID() int32 {
+ if x != nil {
+ return x.AccountID
+ }
+ return 0
+}
+
+type OrderData struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ All int64 `protobuf:"varint,1,opt,name=all,proto3" json:"all"` // 全部
+ Unship int64 `protobuf:"varint,2,opt,name=unship,proto3" json:"unship"` // 待发货
+ Shipped int64 `protobuf:"varint,3,opt,name=shipped,proto3" json:"shipped"` // 已发货
+ Finished int64 `protobuf:"varint,4,opt,name=finished,proto3" json:"finished"` // 已完成
+ Cancel int64 `protobuf:"varint,5,opt,name=cancel,proto3" json:"cancel"` // 已取消
+}
+
+func (x *OrderData) Reset() {
+ *x = OrderData{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_customer_proto_msgTypes[4]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *OrderData) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*OrderData) ProtoMessage() {}
+
+func (x *OrderData) ProtoReflect() protoreflect.Message {
+ mi := &file_customer_proto_msgTypes[4]
+ 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 OrderData.ProtoReflect.Descriptor instead.
+func (*OrderData) Descriptor() ([]byte, []int) {
+ return file_customer_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *OrderData) GetAll() int64 {
+ if x != nil {
+ return x.All
+ }
+ return 0
+}
+
+func (x *OrderData) GetUnship() int64 {
+ if x != nil {
+ return x.Unship
+ }
+ return 0
+}
+
+func (x *OrderData) GetShipped() int64 {
+ if x != nil {
+ return x.Shipped
+ }
+ return 0
+}
+
+func (x *OrderData) GetFinished() int64 {
+ if x != nil {
+ return x.Finished
+ }
+ return 0
+}
+
+func (x *OrderData) GetCancel() int64 {
+ if x != nil {
+ return x.Cancel
+ }
+ return 0
+}
+
+type BillData struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Income float64 `protobuf:"fixed64,1,opt,name=income,proto3" json:"income"` // 收入总额
+ RewardUnfinished float64 `protobuf:"fixed64,2,opt,name=rewardUnfinished,proto3" json:"rewardUnfinished"` // 在途佣金
+ OrderMoney float64 `protobuf:"fixed64,3,opt,name=orderMoney,proto3" json:"orderMoney"` // 订单总额
+ OrderNum int64 `protobuf:"varint,4,opt,name=orderNum,proto3" json:"orderNum"` // 订单数
+ CancelOrderNum int64 `protobuf:"varint,5,opt,name=cancelOrderNum,proto3" json:"cancelOrderNum"` // 退款订单数
+ CancelOrderMoney float64 `protobuf:"fixed64,6,opt,name=cancelOrderMoney,proto3" json:"cancelOrderMoney"` // 退款订单总额
+ FlowIncome float64 `protobuf:"fixed64,7,opt,name=flowIncome,proto3" json:"flowIncome"` // 进账
+ FlowExpend float64 `protobuf:"fixed64,8,opt,name=flowExpend,proto3" json:"flowExpend"` // 出账
+}
+
+func (x *BillData) Reset() {
+ *x = BillData{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_customer_proto_msgTypes[5]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *BillData) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*BillData) ProtoMessage() {}
+
+func (x *BillData) ProtoReflect() protoreflect.Message {
+ mi := &file_customer_proto_msgTypes[5]
+ 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 BillData.ProtoReflect.Descriptor instead.
+func (*BillData) Descriptor() ([]byte, []int) {
+ return file_customer_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *BillData) GetIncome() float64 {
+ if x != nil {
+ return x.Income
+ }
+ return 0
+}
+
+func (x *BillData) GetRewardUnfinished() float64 {
+ if x != nil {
+ return x.RewardUnfinished
+ }
+ return 0
+}
+
+func (x *BillData) GetOrderMoney() float64 {
+ if x != nil {
+ return x.OrderMoney
+ }
+ return 0
+}
+
+func (x *BillData) GetOrderNum() int64 {
+ if x != nil {
+ return x.OrderNum
+ }
+ return 0
+}
+
+func (x *BillData) GetCancelOrderNum() int64 {
+ if x != nil {
+ return x.CancelOrderNum
+ }
+ return 0
+}
+
+func (x *BillData) GetCancelOrderMoney() float64 {
+ if x != nil {
+ return x.CancelOrderMoney
+ }
+ return 0
+}
+
+func (x *BillData) GetFlowIncome() float64 {
+ if x != nil {
+ return x.FlowIncome
+ }
+ return 0
+}
+
+func (x *BillData) GetFlowExpend() float64 {
+ if x != nil {
+ return x.FlowExpend
+ }
+ return 0
+}
+
+type MissionOrderStatistic struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ OrderNum int64 `protobuf:"varint,1,opt,name=orderNum,proto3" json:"orderNum"` // 订单总数
+ OrderDoneNum int64 `protobuf:"varint,2,opt,name=orderDoneNum,proto3" json:"orderDoneNum"` // 完成订单总数
+ OrderMoney float64 `protobuf:"fixed64,3,opt,name=OrderMoney,proto3" json:"OrderMoney"` // 订单金额
+ SettleReward float64 `protobuf:"fixed64,4,opt,name=SettleReward,proto3" json:"SettleReward"` // 结算佣金
+ TransitReward float64 `protobuf:"fixed64,5,opt,name=TransitReward,proto3" json:"TransitReward"` // 在途佣金
+ RewardRatio float64 `protobuf:"fixed64,6,opt,name=RewardRatio,proto3" json:"RewardRatio"` // 佣金比例
+ Uv int64 `protobuf:"varint,7,opt,name=Uv,proto3" json:"Uv"` // 浏览人数
+ OrderUserNum int64 `protobuf:"varint,8,opt,name=OrderUserNum,proto3" json:"OrderUserNum"` // 下单人数
+ SellNum int64 `protobuf:"varint,9,opt,name=SellNum,proto3" json:"SellNum"` // 销售数量
+}
+
+func (x *MissionOrderStatistic) Reset() {
+ *x = MissionOrderStatistic{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_customer_proto_msgTypes[6]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *MissionOrderStatistic) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MissionOrderStatistic) ProtoMessage() {}
+
+func (x *MissionOrderStatistic) ProtoReflect() protoreflect.Message {
+ mi := &file_customer_proto_msgTypes[6]
+ 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 MissionOrderStatistic.ProtoReflect.Descriptor instead.
+func (*MissionOrderStatistic) Descriptor() ([]byte, []int) {
+ return file_customer_proto_rawDescGZIP(), []int{6}
+}
+
+func (x *MissionOrderStatistic) GetOrderNum() int64 {
+ if x != nil {
+ return x.OrderNum
+ }
+ return 0
+}
+
+func (x *MissionOrderStatistic) GetOrderDoneNum() int64 {
+ if x != nil {
+ return x.OrderDoneNum
+ }
+ return 0
+}
+
+func (x *MissionOrderStatistic) GetOrderMoney() float64 {
+ if x != nil {
+ return x.OrderMoney
+ }
+ return 0
+}
+
+func (x *MissionOrderStatistic) GetSettleReward() float64 {
+ if x != nil {
+ return x.SettleReward
+ }
+ return 0
+}
+
+func (x *MissionOrderStatistic) GetTransitReward() float64 {
+ if x != nil {
+ return x.TransitReward
+ }
+ return 0
+}
+
+func (x *MissionOrderStatistic) GetRewardRatio() float64 {
+ if x != nil {
+ return x.RewardRatio
+ }
+ return 0
+}
+
+func (x *MissionOrderStatistic) GetUv() int64 {
+ if x != nil {
+ return x.Uv
+ }
+ return 0
+}
+
+func (x *MissionOrderStatistic) GetOrderUserNum() int64 {
+ if x != nil {
+ return x.OrderUserNum
+ }
+ return 0
+}
+
+func (x *MissionOrderStatistic) GetSellNum() int64 {
+ if x != nil {
+ return x.SellNum
+ }
+ return 0
+}
+
+var File_customer_proto protoreflect.FileDescriptor
+
+var file_customer_proto_rawDesc = []byte{
+ 0x0a, 0x0e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x12, 0x03, 0x61, 0x70, 0x69, 0x22, 0x94, 0x01, 0x0a, 0x0c, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52,
+ 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x14, 0x0a, 0x05,
+ 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x70, 0x68, 0x6f,
+ 0x6e, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f,
+ 0x72, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f,
+ 0x72, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x70, 0x70, 0x69, 0x64, 0x18,
+ 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x70, 0x70, 0x69, 0x64, 0x22, 0x85, 0x01, 0x0a,
+ 0x0f, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+ 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6e, 0x69,
+ 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x69,
+ 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72,
+ 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x12, 0x14,
+ 0x0a, 0x05, 0x61, 0x70, 0x70, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61,
+ 0x70, 0x70, 0x69, 0x64, 0x22, 0x22, 0x0a, 0x0a, 0x53, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
+ 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x05, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x22, 0x71, 0x0a, 0x0f, 0x57, 0x69, 0x74, 0x68,
+ 0x64, 0x72, 0x61, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x70,
+ 0x68, 0x6f, 0x6e, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x70, 0x68, 0x6f, 0x6e,
+ 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18,
+ 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1c, 0x0a,
+ 0x09, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x44, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05,
+ 0x52, 0x09, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x44, 0x22, 0x83, 0x01, 0x0a, 0x09,
+ 0x4f, 0x72, 0x64, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x6c, 0x6c,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x61, 0x6c, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x75,
+ 0x6e, 0x73, 0x68, 0x69, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x75, 0x6e, 0x73,
+ 0x68, 0x69, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x68, 0x69, 0x70, 0x70, 0x65, 0x64, 0x18, 0x03,
+ 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x73, 0x68, 0x69, 0x70, 0x70, 0x65, 0x64, 0x12, 0x1a, 0x0a,
+ 0x08, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52,
+ 0x08, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x61, 0x6e,
+ 0x63, 0x65, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x63, 0x61, 0x6e, 0x63, 0x65,
+ 0x6c, 0x22, 0x9e, 0x02, 0x0a, 0x08, 0x42, 0x69, 0x6c, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x12, 0x16,
+ 0x0a, 0x06, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x06,
+ 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x10, 0x72, 0x65, 0x77, 0x61, 0x72, 0x64,
+ 0x55, 0x6e, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01,
+ 0x52, 0x10, 0x72, 0x65, 0x77, 0x61, 0x72, 0x64, 0x55, 0x6e, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68,
+ 0x65, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x4d, 0x6f, 0x6e, 0x65, 0x79,
+ 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0a, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x4d, 0x6f, 0x6e,
+ 0x65, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x4e, 0x75, 0x6d, 0x18, 0x04,
+ 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x4e, 0x75, 0x6d, 0x12, 0x26,
+ 0x0a, 0x0e, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x4e, 0x75, 0x6d,
+ 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x4f, 0x72,
+ 0x64, 0x65, 0x72, 0x4e, 0x75, 0x6d, 0x12, 0x2a, 0x0a, 0x10, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c,
+ 0x4f, 0x72, 0x64, 0x65, 0x72, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x01,
+ 0x52, 0x10, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x4d, 0x6f, 0x6e,
+ 0x65, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x66, 0x6c, 0x6f, 0x77, 0x49, 0x6e, 0x63, 0x6f, 0x6d, 0x65,
+ 0x18, 0x07, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0a, 0x66, 0x6c, 0x6f, 0x77, 0x49, 0x6e, 0x63, 0x6f,
+ 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x66, 0x6c, 0x6f, 0x77, 0x45, 0x78, 0x70, 0x65, 0x6e, 0x64,
+ 0x18, 0x08, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0a, 0x66, 0x6c, 0x6f, 0x77, 0x45, 0x78, 0x70, 0x65,
+ 0x6e, 0x64, 0x22, 0xb1, 0x02, 0x0a, 0x15, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4f, 0x72,
+ 0x64, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x12, 0x1a, 0x0a, 0x08,
+ 0x6f, 0x72, 0x64, 0x65, 0x72, 0x4e, 0x75, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08,
+ 0x6f, 0x72, 0x64, 0x65, 0x72, 0x4e, 0x75, 0x6d, 0x12, 0x22, 0x0a, 0x0c, 0x6f, 0x72, 0x64, 0x65,
+ 0x72, 0x44, 0x6f, 0x6e, 0x65, 0x4e, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c,
+ 0x6f, 0x72, 0x64, 0x65, 0x72, 0x44, 0x6f, 0x6e, 0x65, 0x4e, 0x75, 0x6d, 0x12, 0x1e, 0x0a, 0x0a,
+ 0x4f, 0x72, 0x64, 0x65, 0x72, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01,
+ 0x52, 0x0a, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x12, 0x22, 0x0a, 0x0c,
+ 0x53, 0x65, 0x74, 0x74, 0x6c, 0x65, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x18, 0x04, 0x20, 0x01,
+ 0x28, 0x01, 0x52, 0x0c, 0x53, 0x65, 0x74, 0x74, 0x6c, 0x65, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64,
+ 0x12, 0x24, 0x0a, 0x0d, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x52, 0x65, 0x77, 0x61, 0x72,
+ 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0d, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74,
+ 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64,
+ 0x52, 0x61, 0x74, 0x69, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0b, 0x52, 0x65, 0x77,
+ 0x61, 0x72, 0x64, 0x52, 0x61, 0x74, 0x69, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x55, 0x76, 0x18, 0x07,
+ 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x55, 0x76, 0x12, 0x22, 0x0a, 0x0c, 0x4f, 0x72, 0x64, 0x65,
+ 0x72, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x75, 0x6d, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c,
+ 0x4f, 0x72, 0x64, 0x65, 0x72, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x75, 0x6d, 0x12, 0x18, 0x0a, 0x07,
+ 0x53, 0x65, 0x6c, 0x6c, 0x4e, 0x75, 0x6d, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x53,
+ 0x65, 0x6c, 0x6c, 0x4e, 0x75, 0x6d, 0x42, 0x0a, 0x5a, 0x08, 0x70, 0x75, 0x72, 0x65, 0x2f, 0x64,
+ 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+ file_customer_proto_rawDescOnce sync.Once
+ file_customer_proto_rawDescData = file_customer_proto_rawDesc
+)
+
+func file_customer_proto_rawDescGZIP() []byte {
+ file_customer_proto_rawDescOnce.Do(func() {
+ file_customer_proto_rawDescData = protoimpl.X.CompressGZIP(file_customer_proto_rawDescData)
+ })
+ return file_customer_proto_rawDescData
+}
+
+var file_customer_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
+var file_customer_proto_goTypes = []interface{}{
+ (*LoginRequest)(nil), // 0: api.LoginRequest
+ (*RegisterRequest)(nil), // 1: api.RegisterRequest
+ (*SmsRequest)(nil), // 2: api.SmsRequest
+ (*WithdrawRequest)(nil), // 3: api.WithdrawRequest
+ (*OrderData)(nil), // 4: api.OrderData
+ (*BillData)(nil), // 5: api.BillData
+ (*MissionOrderStatistic)(nil), // 6: api.MissionOrderStatistic
+}
+var file_customer_proto_depIdxs = []int32{
+ 0, // [0:0] is the sub-list for method output_type
+ 0, // [0:0] 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_customer_proto_init() }
+func file_customer_proto_init() {
+ if File_customer_proto != nil {
+ return
+ }
+ if !protoimpl.UnsafeEnabled {
+ file_customer_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*LoginRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_customer_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*RegisterRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_customer_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*SmsRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_customer_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*WithdrawRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_customer_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*OrderData); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_customer_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*BillData); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_customer_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MissionOrderStatistic); 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_customer_proto_rawDesc,
+ NumEnums: 0,
+ NumMessages: 7,
+ NumExtensions: 0,
+ NumServices: 0,
+ },
+ GoTypes: file_customer_proto_goTypes,
+ DependencyIndexes: file_customer_proto_depIdxs,
+ MessageInfos: file_customer_proto_msgTypes,
+ }.Build()
+ File_customer_proto = out.File
+ file_customer_proto_rawDesc = nil
+ file_customer_proto_goTypes = nil
+ file_customer_proto_depIdxs = nil
+}
diff --git a/dto/customer.proto b/dto/customer.proto
new file mode 100644
index 0000000..25a422e
--- /dev/null
+++ b/dto/customer.proto
@@ -0,0 +1,60 @@
+syntax = "proto3";
+
+package api;
+
+option go_package = "pure/dto";
+
+message LoginRequest{
+ string email = 1;
+ string phone = 2;
+ string code = 3;
+ string password = 4;
+ string type = 5;
+ string appid = 6;
+}
+
+message RegisterRequest{
+ string email = 1;
+ string code = 2;
+ string nickname = 3;
+ string avatar = 4;
+ string appid = 5;
+}
+
+message SmsRequest {
+ string phone = 1;
+}
+message WithdrawRequest {
+ string phone = 1;//账户绑定手机号
+ string code = 2; //验证码
+ double amount = 3;//提现金额
+ int32 accountID = 4;//账户id
+}
+message OrderData{
+ int64 all = 1;// 全部
+ int64 unship = 2;// 待发货
+ int64 shipped = 3;// 已发货
+ int64 finished = 4;// 已完成
+ int64 cancel = 5;// 已取消
+}
+message BillData{
+ double income = 1;// 收入总额
+ double rewardUnfinished = 2;// 在途佣金
+ double orderMoney = 3;// 订单总额
+ int64 orderNum = 4;// 订单数
+ int64 cancelOrderNum = 5;// 退款订单数
+ double cancelOrderMoney = 6;// 退款订单总额
+ double flowIncome = 7;// 进账
+ double flowExpend = 8;// 出账
+}
+message MissionOrderStatistic{
+ int64 orderNum = 1;// 订单总数
+ int64 orderDoneNum = 2;// 完成订单总数
+ double OrderMoney = 3;// 订单金额
+ double SettleReward = 4;// 结算佣金
+ double TransitReward = 5;// 在途佣金
+ double RewardRatio = 6; // 佣金比例
+ int64 Uv = 7;// 浏览人数
+ int64 OrderUserNum = 8;// 下单人数
+ int64 SellNum = 9;// 销售数量
+}
\ No newline at end of file
diff --git a/global/global.go b/global/global.go
new file mode 100644
index 0000000..ebbdf2e
--- /dev/null
+++ b/global/global.go
@@ -0,0 +1,25 @@
+package global
+
+import (
+ "pure/config"
+ "pure/initialize/api"
+ "pure/utils/timer"
+
+ "github.com/go-redis/redis"
+ "github.com/spf13/viper"
+ "go.uber.org/zap"
+ "gorm.io/gorm"
+)
+
+var (
+ MG_DB *gorm.DB
+ MG_REDIS *redis.Client
+ MG_CONFIG config.Server
+ MG_VP *viper.Viper
+ MG_LOG *zap.Logger
+ PAY_CLIENT api.GreeterClient
+ SMS_CLIENT api.SmsClient
+ EMAIL_CLIENT api.EmailClient
+ MG_Language interface{}
+ MG_Timer timer.Timer = timer.NewTimerTask()
+)
diff --git a/global/model.go b/global/model.go
new file mode 100644
index 0000000..1e7b3c1
--- /dev/null
+++ b/global/model.go
@@ -0,0 +1,56 @@
+package global
+
+import (
+ "time"
+
+ "gorm.io/gorm"
+)
+
+type MG_MODEL struct {
+ ID uint `gorm:"AUTO_INCREMENT;PRIMARY_KEY;" json:"id"` // 主键ID
+ CreatedAt time.Time `json:"created_at"` // 创建时间
+ UpdatedAt time.Time `json:"updated_at"` // 更新时间
+ DeletedAt gorm.DeletedAt `json:"-"` // 删除时间
+}
+type Pure_MODEL struct {
+ ID uint `gorm:"AUTO_INCREMENT;PRIMARY_KEY;" json:"id"` // 主键ID
+ CreatedAt time.Time `json:"created_at"` // 创建时间
+ UpdatedAt time.Time `json:"updated_at"` // 更新时间
+}
+
+type TIME_MODEL struct {
+ CreatedAt time.Time `json:"-"`
+ UpdatedAt time.Time `json:"-"`
+ DeletedAt gorm.DeletedAt `json:"-"`
+}
+
+type ID_BACKUP_STR struct {
+ ID string `gorm:"primary_key;size:50" json:"id" form:"id"` //主键
+ // Kid int `json:"kid" form:"kid"`
+ Backup int `json:"backup" form:"backup"`
+ Check int `json:"check" form:"check"`
+ CurrentCheck string `json:"currentCheck" form:"currentCheck"`
+}
+
+type BASE_ID struct {
+ ID uint `gorm:"AUTO_INCREMENT;primary_key;" json:"id" form:"id"` //主键
+}
+
+type ID_SORT struct {
+ ID string `json:"id"`
+ Sort int `json:"sort"`
+}
+
+type ID_COUNT struct {
+ ID string `json:"id"`
+ Count int `json:"count"`
+}
+
+type RedisValueScore struct {
+ Value string `json:"value"`
+ Score float64 `json:"score"`
+}
+
+type BASE_ID_STR struct {
+ ID string `gorm:"primary_key;size:50" json:"id" form:"id"` //主键
+}
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..d55e886
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,118 @@
+module pure
+
+go 1.20
+
+require (
+ github.com/aliyun/aliyun-oss-go-sdk v2.2.9+incompatible
+ github.com/dgrijalva/jwt-go v3.2.0+incompatible
+ github.com/fsnotify/fsnotify v1.6.0
+ github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6
+ github.com/gin-gonic/gin v1.9.0
+ github.com/go-kratos/kratos/contrib/registry/nacos/v2 v2.0.0-20230830131453-6c026bce56a9
+ github.com/go-kratos/kratos/v2 v2.7.0
+ github.com/go-redis/redis v6.15.9+incompatible
+ github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible
+ github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible
+ github.com/nacos-group/nacos-sdk-go v1.1.4
+ github.com/pili-engineering/pili-sdk-go.v2 v0.0.0-20200608105005-bb506e708987
+ github.com/plutov/paypal v2.0.5+incompatible
+ github.com/robfig/cron/v3 v3.0.1
+ github.com/satori/go.uuid v1.2.0
+ github.com/shirou/gopsutil v2.21.11+incompatible
+ github.com/spf13/cast v1.5.1
+ github.com/spf13/viper v1.16.0
+ github.com/swaggo/files v1.0.1
+ github.com/swaggo/gin-swagger v1.6.0
+ github.com/swaggo/swag v1.8.12
+ github.com/taskcluster/slugid-go v1.1.0
+ github.com/tencentyun/cos-go-sdk-v5 v0.7.42
+ github.com/unrolled/secure v1.13.0
+ github.com/w3liu/go-common v0.0.0-20210108072342-826b2f3582be
+ go.uber.org/zap v1.25.0
+ google.golang.org/grpc v1.56.1
+ google.golang.org/protobuf v1.31.0
+ gorm.io/driver/mysql v1.5.1
+ gorm.io/gorm v1.25.4
+)
+
+require (
+ cloud.google.com/go/compute v1.20.1 // indirect
+ cloud.google.com/go/compute/metadata v0.2.3 // indirect
+ github.com/google/uuid v1.3.0 // indirect
+ google.golang.org/appengine v1.6.8 // indirect
+)
+
+require (
+ github.com/KyleBanks/depth v1.2.1 // indirect
+ github.com/PuerkitoBio/purell v1.1.1 // indirect
+ github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
+ github.com/aliyun/alibaba-cloud-sdk-go v1.61.18 // indirect
+ github.com/buger/jsonparser v1.1.1 // indirect
+ github.com/bytedance/sonic v1.8.0 // indirect
+ github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
+ github.com/clbanning/mxj v1.8.4 // indirect
+ github.com/gin-contrib/sse v0.1.0 // indirect
+ github.com/go-errors/errors v1.0.1 // indirect
+ github.com/go-kratos/aegis v0.2.0 // indirect
+ github.com/go-ole/go-ole v1.2.6 // indirect
+ github.com/go-openapi/jsonpointer v0.19.5 // indirect
+ github.com/go-openapi/jsonreference v0.19.6 // indirect
+ github.com/go-openapi/spec v0.20.4 // indirect
+ github.com/go-openapi/swag v0.19.15 // indirect
+ github.com/go-playground/form/v4 v4.2.0 // indirect
+ github.com/go-playground/locales v0.14.1 // indirect
+ github.com/go-playground/universal-translator v0.18.1 // indirect
+ github.com/go-playground/validator/v10 v10.11.2 // indirect
+ github.com/go-sql-driver/mysql v1.7.0 // indirect
+ github.com/goccy/go-json v0.10.0 // indirect
+ github.com/golang/protobuf v1.5.3 // indirect
+ github.com/google/go-querystring v1.0.0 // indirect
+ github.com/gorilla/mux v1.8.0 // indirect
+ github.com/hashicorp/hcl v1.0.0 // indirect
+ github.com/jinzhu/inflection v1.0.0 // indirect
+ github.com/jinzhu/now v1.1.5 // indirect
+ github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af // indirect
+ github.com/jonboulle/clockwork v0.4.0 // indirect
+ github.com/josharian/intern v1.0.0 // indirect
+ github.com/json-iterator/go v1.1.12 // indirect
+ github.com/klauspost/cpuid/v2 v2.0.9 // indirect
+ github.com/leodido/go-urn v1.2.1 // indirect
+ github.com/lestrrat-go/strftime v1.0.6 // indirect
+ github.com/magiconair/properties v1.8.7 // indirect
+ github.com/mailru/easyjson v0.7.6 // indirect
+ github.com/mattn/go-isatty v0.0.17 // indirect
+ github.com/mitchellh/mapstructure v1.5.0 // indirect
+ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
+ github.com/modern-go/reflect2 v1.0.2 // indirect
+ github.com/mozillazg/go-httpheader v0.2.1 // indirect
+ github.com/pborman/uuid v1.2.0 // indirect
+ github.com/pelletier/go-toml/v2 v2.0.8 // indirect
+ github.com/pkg/errors v0.9.1 // indirect
+ github.com/qiniu/x v1.10.5 // indirect
+ github.com/spf13/afero v1.9.5 // indirect
+ github.com/spf13/jwalterweatherman v1.1.0 // indirect
+ github.com/spf13/pflag v1.0.5 // indirect
+ github.com/subosito/gotenv v1.4.2 // indirect
+ github.com/tklauser/go-sysconf v0.3.12 // indirect
+ github.com/tklauser/numcpus v0.6.1 // indirect
+ github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
+ github.com/ugorji/go/codec v1.2.9 // indirect
+ github.com/yusufpapurcu/wmi v1.2.3 // indirect
+ go.uber.org/multierr v1.10.0 // indirect
+ golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect
+ golang.org/x/crypto v0.14.0 // indirect
+ golang.org/x/net v0.17.0 // indirect
+ golang.org/x/oauth2 v0.13.0
+ golang.org/x/sync v0.3.0 // indirect
+ golang.org/x/sys v0.13.0 // indirect
+ golang.org/x/text v0.13.0 // indirect
+ golang.org/x/time v0.1.0 // indirect
+ golang.org/x/tools v0.7.0 // indirect
+ google.golang.org/genproto v0.0.0-20230629202037-9506855d4529 // indirect
+ google.golang.org/genproto/googleapis/api v0.0.0-20230629202037-9506855d4529
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20230629202037-9506855d4529 // indirect
+ gopkg.in/ini.v1 v1.67.0 // indirect
+ gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
+ gopkg.in/yaml.v2 v2.4.0 // indirect
+ gopkg.in/yaml.v3 v3.0.1 // indirect
+)
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..2237152
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,781 @@
+cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
+cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
+cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
+cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
+cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
+cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
+cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
+cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
+cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
+cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
+cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
+cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
+cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
+cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
+cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
+cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
+cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY=
+cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
+cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
+cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
+cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
+cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
+cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
+cloud.google.com/go/compute v1.20.1 h1:6aKEtlUiwEpJzM001l0yFkpXmUVXaN8W+fbkb2AZNbg=
+cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM=
+cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
+cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
+cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
+cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
+cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
+cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
+cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
+cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
+cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
+cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
+cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
+cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
+cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
+cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
+dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
+gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
+github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
+github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
+github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
+github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
+github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
+github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
+github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
+github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
+github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
+github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM=
+github.com/aliyun/alibaba-cloud-sdk-go v1.61.18 h1:zOVTBdCKFd9JbCKz9/nt+FovbjPFmb7mUnp8nH9fQBA=
+github.com/aliyun/alibaba-cloud-sdk-go v1.61.18/go.mod h1:v8ESoHo4SyHmuB4b1tJqDHxfTGEciD+yhvOU/5s1Rfk=
+github.com/aliyun/aliyun-oss-go-sdk v2.2.9+incompatible h1:Sg/2xHwDrioHpxTN6WMiwbXTpUEinBpHsN7mG21Rc2k=
+github.com/aliyun/aliyun-oss-go-sdk v2.2.9+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
+github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
+github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
+github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
+github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
+github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
+github.com/bytedance/sonic v1.8.0 h1:ea0Xadu+sHlu7x5O3gKhRpQ1IKiMrSiHttPF0ybECuA=
+github.com/bytedance/sonic v1.8.0/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
+github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
+github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g=
+github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
+github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
+github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
+github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
+github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
+github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
+github.com/clbanning/mxj v1.8.4 h1:HuhwZtbyvyOw+3Z1AowPkU87JkJUSv751ELWaiTpj8I=
+github.com/clbanning/mxj v1.8.4/go.mod h1:BVjHeAH+rl9rs6f+QIpeRl0tfu10SXn1pUSa5PVGJng=
+github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
+github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
+github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
+github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k=
+github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
+github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
+github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
+github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
+github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
+github.com/envoyproxy/go-control-plane v0.11.2-0.20230627204322-7d0032219fcb h1:kxNVXsNro/lpR5WD+P1FI/yUHn2G03Glber3k8cQL2Y=
+github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
+github.com/envoyproxy/protoc-gen-validate v0.10.1 h1:c0g45+xCJhdgFGw7a5QAfdS4byAbud7miNWJ1WwEVf8=
+github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
+github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
+github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6 h1:6VSn3hB5U5GeA6kQw4TwWIWbOhtvR2hmbBJnTOtqTWc=
+github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6/go.mod h1:YxOVT5+yHzKvwhsiSIWmbAYM3Dr9AEEbER2dVayfBkg=
+github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4=
+github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
+github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
+github.com/gin-gonic/gin v1.9.0 h1:OjyFBKICoexlu99ctXNR2gg+c5pKrKMuyjgARg9qeY8=
+github.com/gin-gonic/gin v1.9.0/go.mod h1:W1Me9+hsUSyj3CePGrd1/QrKJMSJ1Tu/0hFEH89961k=
+github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
+github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
+github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
+github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
+github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
+github.com/go-kratos/aegis v0.2.0 h1:dObzCDWn3XVjUkgxyBp6ZeWtx/do0DPZ7LY3yNSJLUQ=
+github.com/go-kratos/aegis v0.2.0/go.mod h1:v0R2m73WgEEYB3XYu6aE2WcMwsZkJ/Rzuf5eVccm7bI=
+github.com/go-kratos/kratos/contrib/registry/nacos/v2 v2.0.0-20230830131453-6c026bce56a9 h1:m6eNghBfLhxZbOJR5yUFSZ4KswrxTlU2oK6lQWROXtI=
+github.com/go-kratos/kratos/contrib/registry/nacos/v2 v2.0.0-20230830131453-6c026bce56a9/go.mod h1:6xVbnCGYP1wqhz+nu9ct2K6K+mZkCqm/R6zlMRY7Sug=
+github.com/go-kratos/kratos/v2 v2.7.0 h1:9DaVgU9YoHPb/BxDVqeVlVCMduRhiSewG3xE+e9ZAZ8=
+github.com/go-kratos/kratos/v2 v2.7.0/go.mod h1:CPn82O93OLHjtnbuyOKhAG5TkSvw+mFnL32c4lZFDwU=
+github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
+github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
+github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
+github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
+github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
+github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs=
+github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns=
+github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M=
+github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I=
+github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
+github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=
+github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
+github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
+github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
+github.com/go-playground/form/v4 v4.2.0 h1:N1wh+Goz61e6w66vo8vJkQt+uwZSoLz50kZPJWR8eic=
+github.com/go-playground/form/v4 v4.2.0/go.mod h1:q1a2BY+AQUUzhl6xA/6hBetay6dEIhMHjgvJiGo6K7U=
+github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
+github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
+github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
+github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
+github.com/go-playground/validator/v10 v10.11.2 h1:q3SHpufmypg+erIExEKUmsgmhDTyhcJ38oeKGACXohU=
+github.com/go-playground/validator/v10 v10.11.2/go.mod h1:NieE624vt4SCTJtD87arVLvdmjPAeV8BQlHtMnw9D7s=
+github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg=
+github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
+github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
+github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
+github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
+github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/goccy/go-json v0.10.0 h1:mXKd9Qw4NuzShiRlOXKews24ufknHO7gx30lsDyokKA=
+github.com/goccy/go-json v0.10.0/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
+github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A=
+github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
+github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
+github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
+github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
+github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc=
+github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
+github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
+github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
+github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
+github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
+github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
+github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
+github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
+github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
+github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
+github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
+github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
+github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
+github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
+github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
+github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
+github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
+github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
+github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
+github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
+github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
+github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
+github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
+github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
+github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
+github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
+github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
+github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
+github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
+github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
+github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
+github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
+github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
+github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
+github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
+github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
+github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4=
+github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc=
+github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible h1:jdpOPRN1zP63Td1hDQbZW73xKmzDvZHzVdNYxhnTMDA=
+github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible/go.mod h1:1c7szIrayyPPB/987hsnvNzLushdWf4o/79s3P08L8A=
+github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
+github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
+github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
+github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
+github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
+github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
+github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
+github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
+github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4=
+github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
+github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
+github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
+github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc h1:RKf14vYWi2ttpEmkA4aQ3j4u9dStX2t4M8UM6qqNsG8=
+github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is=
+github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible h1:Y6sqxHMyB1D2YSzWkLibYKgg+SwmyFU9dF2hn6MdTj4=
+github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible/go.mod h1:ZQnN8lSECaebrkQytbHj4xNgtg8CR7RYXnPok8e0EHA=
+github.com/lestrrat-go/strftime v1.0.6 h1:CFGsDEt1pOpFNU+TJB0nhz9jl+K0hZSLE205AhTIGQQ=
+github.com/lestrrat-go/strftime v1.0.6/go.mod h1:f7jQKgV5nnJpYgdEasS+/y7EsTb8ykN2z68n3TtcTaw=
+github.com/lib/pq v1.7.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
+github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
+github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
+github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
+github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
+github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
+github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
+github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
+github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
+github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
+github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
+github.com/mozillazg/go-httpheader v0.2.1 h1:geV7TrjbL8KXSyvghnFm+NyTux/hxwueTSrwhe88TQQ=
+github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISeBAdw6E61aqQma60=
+github.com/nacos-group/nacos-sdk-go v1.1.4 h1:qyrZ7HTWM4aeymFfqnbgNRERh7TWuER10pCB7ddRcTY=
+github.com/nacos-group/nacos-sdk-go v1.1.4/go.mod h1:cBv9wy5iObs7khOqov1ERFQrCuTR4ILpgaiaVMxEmGI=
+github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
+github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
+github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
+github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=
+github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
+github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
+github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
+github.com/pili-engineering/pili-sdk-go.v2 v0.0.0-20200608105005-bb506e708987 h1:PIPYQRZ0S1yjLPO05uNtYz5fcsiJ5Xo/vdQCrwde0fM=
+github.com/pili-engineering/pili-sdk-go.v2 v0.0.0-20200608105005-bb506e708987/go.mod h1:nd8f4Fi29T7yRtBjAZwPOvsRurUzq7Jja5vWUB+aprk=
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
+github.com/plutov/paypal v2.0.5+incompatible h1:i5ma4HiHO0MUvJGHaKkL2aqOj0B19q8WoJm1jgzQjlM=
+github.com/plutov/paypal v2.0.5+incompatible/go.mod h1:jOStyiXeDrJ9dHA/yVUB2ahyYPjd5rMXUZ4N7XM37nQ=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/qiniu/x v1.10.5 h1:7V/CYWEmo9axJULvrJN6sMYh2FdY+esN5h8jwDkA4b0=
+github.com/qiniu/x v1.10.5/go.mod h1:03Ni9tj+N2h2aKnAz+6N0Xfl8FwMEDRC2PAlxekASDs=
+github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
+github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
+github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
+github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
+github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
+github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
+github.com/shirou/gopsutil v2.21.11+incompatible h1:lOGOyCG67a5dv2hq5Z1BLDUqqKp3HkbjPcz5j6XMS0U=
+github.com/shirou/gopsutil v2.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM=
+github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
+github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA=
+github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48=
+github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
+github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
+github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
+github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/spf13/viper v1.16.0 h1:rGGH0XDZhdUOryiDWjmIvUSWpbNqisK8Wk0Vyefw8hc=
+github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
+github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY=
+github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
+github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
+github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE=
+github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg=
+github.com/swaggo/gin-swagger v1.6.0 h1:y8sxvQ3E20/RCyrXeFfg60r6H0Z+SwpTjMYsMm+zy8M=
+github.com/swaggo/gin-swagger v1.6.0/go.mod h1:BG00cCEy294xtVpyIAHG6+e2Qzj/xKlRdOqDkvq0uzo=
+github.com/swaggo/swag v1.8.12 h1:pctzkNPu0AlQP2royqX3apjKCQonAnf7KGoxeO4y64w=
+github.com/swaggo/swag v1.8.12/go.mod h1:lNfm6Gg+oAq3zRJQNEMBE66LIJKM44mxFqhEEgy2its=
+github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
+github.com/taskcluster/slugid-go v1.1.0 h1:SWsUplliyamdYzOKVM4+lDohZKuL63fKreGkvIKJ9aI=
+github.com/taskcluster/slugid-go v1.1.0/go.mod h1:5sOAcPHjqso1UkKxSl77CkKgOwha0D9X0msBKBj0AOg=
+github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.563/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y=
+github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/kms v1.0.563/go.mod h1:uom4Nvi9W+Qkom0exYiJ9VWJjXwyxtPYTkKkaLMlfE0=
+github.com/tencentyun/cos-go-sdk-v5 v0.7.42 h1:Up1704BJjI5orycXKjpVpvuOInt9GC5pqY4knyE9Uds=
+github.com/tencentyun/cos-go-sdk-v5 v0.7.42/go.mod h1:LUFnaqRmGk6pEHOaRmdn2dCZR2j0cSsM5xowWFPTPao=
+github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
+github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
+github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
+github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
+github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
+github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
+github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
+github.com/ugorji/go/codec v1.2.9 h1:rmenucSohSTiyL09Y+l2OCk+FrMxGMzho2+tjr5ticU=
+github.com/ugorji/go/codec v1.2.9/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
+github.com/unrolled/secure v1.13.0 h1:sdr3Phw2+f8Px8HE5sd1EHdj1aV3yUwed/uZXChLFsk=
+github.com/unrolled/secure v1.13.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40=
+github.com/w3liu/go-common v0.0.0-20210108072342-826b2f3582be h1:NW489IqqgOz/+fV4oDC2NJqQFH+gYYQt8WRLj4v94Ok=
+github.com/w3liu/go-common v0.0.0-20210108072342-826b2f3582be/go.mod h1:yHAS/DWXivtrBrO4K45DpIFjQ6LgOi4bUBz7A1iClsE=
+github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
+github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
+github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
+github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
+github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
+go.mongodb.org/mongo-driver v1.2.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
+go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
+go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
+go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
+go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
+go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
+go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
+go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
+go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
+go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
+go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc=
+go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ=
+go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c=
+go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk=
+golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU=
+golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
+golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
+golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
+golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
+golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
+golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
+golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
+golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
+golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
+golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
+golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
+golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
+golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
+golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
+golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
+golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
+golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
+golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
+golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
+golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
+golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs=
+golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
+golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY=
+golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
+golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
+golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
+golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
+golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA=
+golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
+golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
+golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
+golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
+golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
+golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
+google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
+google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
+google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
+google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
+google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
+google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
+google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
+google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
+google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
+google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
+google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
+google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
+google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
+google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
+google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
+google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
+google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
+google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
+google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
+google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
+google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
+google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
+google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
+google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20230629202037-9506855d4529 h1:9JucMWR7sPvCxUFd6UsOUNmA5kCcWOfORaT3tpAsKQs=
+google.golang.org/genproto v0.0.0-20230629202037-9506855d4529/go.mod h1:xZnkP7mREFX5MORlOPEzLMr+90PPZQ2QWzrVTWfAq64=
+google.golang.org/genproto/googleapis/api v0.0.0-20230629202037-9506855d4529 h1:s5YSX+ZH5b5vS9rnpGymvIyMpLRJizowqDlOuyjXnTk=
+google.golang.org/genproto/googleapis/api v0.0.0-20230629202037-9506855d4529/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20230629202037-9506855d4529 h1:DEH99RbiLZhMxrpEJCZ0A+wdTe0EOgou/poSLx9vWf4=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20230629202037-9506855d4529/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA=
+google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
+google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
+google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
+google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
+google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
+google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
+google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
+google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
+google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
+google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
+google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
+google.golang.org/grpc v1.56.1 h1:z0dNfjIl0VpaZ9iSVjA6daGatAYwPGstTjt5vkRMFkQ=
+google.golang.org/grpc v1.56.1/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=
+google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
+google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
+google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
+google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
+google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
+google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
+google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
+google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
+google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
+google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
+gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
+gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
+gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
+gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gorm.io/driver/mysql v1.5.1 h1:WUEH5VF9obL/lTtzjmML/5e6VfFR/788coz2uaVCAZw=
+gorm.io/driver/mysql v1.5.1/go.mod h1:Jo3Xu7mMhCyj8dlrb3WoCaRd1FhsVh+yMXb1jUInf5o=
+gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
+gorm.io/gorm v1.25.4 h1:iyNd8fNAe8W9dvtlgeRI5zSVZPsq3OpcTu37cYcpCmw=
+gorm.io/gorm v1.25.4/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
+honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
+honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
+honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
+rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
+rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
+rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
+rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
+xorm.io/builder v0.3.7/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
+xorm.io/xorm v1.0.6/go.mod h1:uF9EtbhODq5kNWxMbnBEj8hRRZnlcNSz2t2N7HW/+A4=
diff --git a/initialize/api/email.pb.go b/initialize/api/email.pb.go
new file mode 100644
index 0000000..df90a58
--- /dev/null
+++ b/initialize/api/email.pb.go
@@ -0,0 +1,253 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.31.0
+// protoc v3.21.12
+// source: initialize/api/email.proto
+
+package api
+
+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 SendRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // 收件人 必填参数
+ To []string `protobuf:"bytes,1,rep,name=to,proto3" json:"to,omitempty"`
+ // 邮件主题,必填参数
+ Subject string `protobuf:"bytes,2,opt,name=subject,proto3" json:"subject,omitempty"`
+ // 消息体,支持富文本
+ Body string `protobuf:"bytes,3,opt,name=body,proto3" json:"body,omitempty"`
+ // 附件地址
+ Files []string `protobuf:"bytes,4,rep,name=files,proto3" json:"files,omitempty"`
+}
+
+func (x *SendRequest) Reset() {
+ *x = SendRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_initialize_api_email_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *SendRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SendRequest) ProtoMessage() {}
+
+func (x *SendRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_initialize_api_email_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 SendRequest.ProtoReflect.Descriptor instead.
+func (*SendRequest) Descriptor() ([]byte, []int) {
+ return file_initialize_api_email_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *SendRequest) GetTo() []string {
+ if x != nil {
+ return x.To
+ }
+ return nil
+}
+
+func (x *SendRequest) GetSubject() string {
+ if x != nil {
+ return x.Subject
+ }
+ return ""
+}
+
+func (x *SendRequest) GetBody() string {
+ if x != nil {
+ return x.Body
+ }
+ return ""
+}
+
+func (x *SendRequest) GetFiles() []string {
+ if x != nil {
+ return x.Files
+ }
+ return nil
+}
+
+// The response message containing the greetings
+type SendEmailReply struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Code int32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"`
+ Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"`
+}
+
+func (x *SendEmailReply) Reset() {
+ *x = SendEmailReply{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_initialize_api_email_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *SendEmailReply) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SendEmailReply) ProtoMessage() {}
+
+func (x *SendEmailReply) ProtoReflect() protoreflect.Message {
+ mi := &file_initialize_api_email_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 SendEmailReply.ProtoReflect.Descriptor instead.
+func (*SendEmailReply) Descriptor() ([]byte, []int) {
+ return file_initialize_api_email_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *SendEmailReply) GetCode() int32 {
+ if x != nil {
+ return x.Code
+ }
+ return 0
+}
+
+func (x *SendEmailReply) GetMessage() string {
+ if x != nil {
+ return x.Message
+ }
+ return ""
+}
+
+var File_initialize_api_email_proto protoreflect.FileDescriptor
+
+var file_initialize_api_email_proto_rawDesc = []byte{
+ 0x0a, 0x1a, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x2f, 0x61, 0x70, 0x69,
+ 0x2f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x03, 0x61, 0x70,
+ 0x69, 0x22, 0x61, 0x0a, 0x0b, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+ 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x02, 0x74, 0x6f,
+ 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f,
+ 0x64, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x14,
+ 0x0a, 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x66,
+ 0x69, 0x6c, 0x65, 0x73, 0x22, 0x3e, 0x0a, 0x0e, 0x53, 0x65, 0x6e, 0x64, 0x45, 0x6d, 0x61, 0x69,
+ 0x6c, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65,
+ 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73,
+ 0x73, 0x61, 0x67, 0x65, 0x32, 0x3d, 0x0a, 0x05, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x34, 0x0a,
+ 0x09, 0x53, 0x65, 0x6e, 0x64, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x10, 0x2e, 0x61, 0x70, 0x69,
+ 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x61,
+ 0x70, 0x69, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x70, 0x6c,
+ 0x79, 0x22, 0x00, 0x42, 0x10, 0x5a, 0x0e, 0x62, 0x6b, 0x62, 0x2d, 0x6e, 0x6f, 0x74, 0x69, 0x66,
+ 0x79, 0x2f, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+ file_initialize_api_email_proto_rawDescOnce sync.Once
+ file_initialize_api_email_proto_rawDescData = file_initialize_api_email_proto_rawDesc
+)
+
+func file_initialize_api_email_proto_rawDescGZIP() []byte {
+ file_initialize_api_email_proto_rawDescOnce.Do(func() {
+ file_initialize_api_email_proto_rawDescData = protoimpl.X.CompressGZIP(file_initialize_api_email_proto_rawDescData)
+ })
+ return file_initialize_api_email_proto_rawDescData
+}
+
+var file_initialize_api_email_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
+var file_initialize_api_email_proto_goTypes = []interface{}{
+ (*SendRequest)(nil), // 0: api.SendRequest
+ (*SendEmailReply)(nil), // 1: api.SendEmailReply
+}
+var file_initialize_api_email_proto_depIdxs = []int32{
+ 0, // 0: api.Email.SendEmail:input_type -> api.SendRequest
+ 1, // 1: api.Email.SendEmail:output_type -> api.SendEmailReply
+ 1, // [1:2] is the sub-list for method output_type
+ 0, // [0:1] 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_initialize_api_email_proto_init() }
+func file_initialize_api_email_proto_init() {
+ if File_initialize_api_email_proto != nil {
+ return
+ }
+ if !protoimpl.UnsafeEnabled {
+ file_initialize_api_email_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*SendRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_initialize_api_email_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*SendEmailReply); 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_initialize_api_email_proto_rawDesc,
+ NumEnums: 0,
+ NumMessages: 2,
+ NumExtensions: 0,
+ NumServices: 1,
+ },
+ GoTypes: file_initialize_api_email_proto_goTypes,
+ DependencyIndexes: file_initialize_api_email_proto_depIdxs,
+ MessageInfos: file_initialize_api_email_proto_msgTypes,
+ }.Build()
+ File_initialize_api_email_proto = out.File
+ file_initialize_api_email_proto_rawDesc = nil
+ file_initialize_api_email_proto_goTypes = nil
+ file_initialize_api_email_proto_depIdxs = nil
+}
diff --git a/initialize/api/email.proto b/initialize/api/email.proto
new file mode 100644
index 0000000..1832d7d
--- /dev/null
+++ b/initialize/api/email.proto
@@ -0,0 +1,32 @@
+syntax = "proto3";
+
+package api;
+
+
+option go_package = "bkb-notify/api";
+
+
+// The Email service definition.
+service Email {
+ // 发送一个邮件
+ rpc SendEmail (SendRequest) returns (SendEmailReply) {
+
+ }
+}
+
+message SendRequest {
+ //收件人 必填参数
+ repeated string to=1;
+ //邮件主题,必填参数
+ string subject=2;
+ //消息体,支持富文本
+ string body=3;
+ //附件地址
+ repeated string files=4;
+}
+
+// The response message containing the greetings
+message SendEmailReply {
+ int32 code = 1;
+ string message = 2;
+}
diff --git a/initialize/api/email_grpc.pb.go b/initialize/api/email_grpc.pb.go
new file mode 100644
index 0000000..bb6edd9
--- /dev/null
+++ b/initialize/api/email_grpc.pb.go
@@ -0,0 +1,111 @@
+// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+// versions:
+// - protoc-gen-go-grpc v1.3.0
+// - protoc v3.21.12
+// source: initialize/api/email.proto
+
+package api
+
+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
+
+const (
+ Email_SendEmail_FullMethodName = "/api.Email/SendEmail"
+)
+
+// EmailClient is the client API for Email 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 EmailClient interface {
+ // 发送一个邮件
+ SendEmail(ctx context.Context, in *SendRequest, opts ...grpc.CallOption) (*SendEmailReply, error)
+}
+
+type emailClient struct {
+ cc grpc.ClientConnInterface
+}
+
+func NewEmailClient(cc grpc.ClientConnInterface) EmailClient {
+ return &emailClient{cc}
+}
+
+func (c *emailClient) SendEmail(ctx context.Context, in *SendRequest, opts ...grpc.CallOption) (*SendEmailReply, error) {
+ out := new(SendEmailReply)
+ err := c.cc.Invoke(ctx, Email_SendEmail_FullMethodName, in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+// EmailServer is the server API for Email service.
+// All implementations must embed UnimplementedEmailServer
+// for forward compatibility
+type EmailServer interface {
+ // 发送一个邮件
+ SendEmail(context.Context, *SendRequest) (*SendEmailReply, error)
+ mustEmbedUnimplementedEmailServer()
+}
+
+// UnimplementedEmailServer must be embedded to have forward compatible implementations.
+type UnimplementedEmailServer struct {
+}
+
+func (UnimplementedEmailServer) SendEmail(context.Context, *SendRequest) (*SendEmailReply, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method SendEmail not implemented")
+}
+func (UnimplementedEmailServer) mustEmbedUnimplementedEmailServer() {}
+
+// UnsafeEmailServer may be embedded to opt out of forward compatibility for this service.
+// Use of this interface is not recommended, as added methods to EmailServer will
+// result in compilation errors.
+type UnsafeEmailServer interface {
+ mustEmbedUnimplementedEmailServer()
+}
+
+func RegisterEmailServer(s grpc.ServiceRegistrar, srv EmailServer) {
+ s.RegisterService(&Email_ServiceDesc, srv)
+}
+
+func _Email_SendEmail_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(SendRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(EmailServer).SendEmail(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: Email_SendEmail_FullMethodName,
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(EmailServer).SendEmail(ctx, req.(*SendRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+// Email_ServiceDesc is the grpc.ServiceDesc for Email service.
+// It's only intended for direct use with grpc.RegisterService,
+// and not to be introspected or modified (even as a copy)
+var Email_ServiceDesc = grpc.ServiceDesc{
+ ServiceName: "api.Email",
+ HandlerType: (*EmailServer)(nil),
+ Methods: []grpc.MethodDesc{
+ {
+ MethodName: "SendEmail",
+ Handler: _Email_SendEmail_Handler,
+ },
+ },
+ Streams: []grpc.StreamDesc{},
+ Metadata: "initialize/api/email.proto",
+}
diff --git a/initialize/api/greeter.pb.go b/initialize/api/greeter.pb.go
new file mode 100644
index 0000000..9e2c7de
--- /dev/null
+++ b/initialize/api/greeter.pb.go
@@ -0,0 +1,1429 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.28.0
+// protoc v4.23.4
+// source: greeter.proto
+
+package api
+
+import (
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ emptypb "google.golang.org/protobuf/types/known/emptypb"
+ 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)
+)
+
+// The response message containing the greetings
+type PingReply struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
+}
+
+func (x *PingReply) Reset() {
+ *x = PingReply{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_greeter_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *PingReply) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*PingReply) ProtoMessage() {}
+
+func (x *PingReply) ProtoReflect() protoreflect.Message {
+ mi := &file_greeter_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 PingReply.ProtoReflect.Descriptor instead.
+func (*PingReply) Descriptor() ([]byte, []int) {
+ return file_greeter_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *PingReply) GetMessage() string {
+ if x != nil {
+ return x.Message
+ }
+ return ""
+}
+
+type Country struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
+ Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
+}
+
+func (x *Country) Reset() {
+ *x = Country{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_greeter_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Country) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Country) ProtoMessage() {}
+
+func (x *Country) ProtoReflect() protoreflect.Message {
+ mi := &file_greeter_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 Country.ProtoReflect.Descriptor instead.
+func (*Country) Descriptor() ([]byte, []int) {
+ return file_greeter_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *Country) GetId() int32 {
+ if x != nil {
+ return x.Id
+ }
+ return 0
+}
+
+func (x *Country) GetName() string {
+ if x != nil {
+ return x.Name
+ }
+ return ""
+}
+
+type CountryReply struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ List []*Country `protobuf:"bytes,1,rep,name=list,proto3" json:"list,omitempty"`
+}
+
+func (x *CountryReply) Reset() {
+ *x = CountryReply{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_greeter_proto_msgTypes[2]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *CountryReply) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CountryReply) ProtoMessage() {}
+
+func (x *CountryReply) ProtoReflect() protoreflect.Message {
+ mi := &file_greeter_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 CountryReply.ProtoReflect.Descriptor instead.
+func (*CountryReply) Descriptor() ([]byte, []int) {
+ return file_greeter_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *CountryReply) GetList() []*Country {
+ if x != nil {
+ return x.List
+ }
+ return nil
+}
+
+type DistrictRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Country int32 `protobuf:"varint,1,opt,name=country,proto3" json:"country,omitempty"`
+}
+
+func (x *DistrictRequest) Reset() {
+ *x = DistrictRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_greeter_proto_msgTypes[3]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *DistrictRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*DistrictRequest) ProtoMessage() {}
+
+func (x *DistrictRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_greeter_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 DistrictRequest.ProtoReflect.Descriptor instead.
+func (*DistrictRequest) Descriptor() ([]byte, []int) {
+ return file_greeter_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *DistrictRequest) GetCountry() int32 {
+ if x != nil {
+ return x.Country
+ }
+ return 0
+}
+
+type District struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Label string `protobuf:"bytes,1,opt,name=label,proto3" json:"label,omitempty"`
+ Adcode string `protobuf:"bytes,2,opt,name=adcode,proto3" json:"adcode,omitempty"`
+ ParentId int32 `protobuf:"varint,3,opt,name=parentId,proto3" json:"parentId,omitempty"`
+ Children []*District `protobuf:"bytes,4,rep,name=children,proto3" json:"children,omitempty"`
+}
+
+func (x *District) Reset() {
+ *x = District{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_greeter_proto_msgTypes[4]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *District) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*District) ProtoMessage() {}
+
+func (x *District) ProtoReflect() protoreflect.Message {
+ mi := &file_greeter_proto_msgTypes[4]
+ 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 District.ProtoReflect.Descriptor instead.
+func (*District) Descriptor() ([]byte, []int) {
+ return file_greeter_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *District) GetLabel() string {
+ if x != nil {
+ return x.Label
+ }
+ return ""
+}
+
+func (x *District) GetAdcode() string {
+ if x != nil {
+ return x.Adcode
+ }
+ return ""
+}
+
+func (x *District) GetParentId() int32 {
+ if x != nil {
+ return x.ParentId
+ }
+ return 0
+}
+
+func (x *District) GetChildren() []*District {
+ if x != nil {
+ return x.Children
+ }
+ return nil
+}
+
+type DistrictReply struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ List []*District `protobuf:"bytes,1,rep,name=list,proto3" json:"list,omitempty"`
+}
+
+func (x *DistrictReply) Reset() {
+ *x = DistrictReply{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_greeter_proto_msgTypes[5]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *DistrictReply) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*DistrictReply) ProtoMessage() {}
+
+func (x *DistrictReply) ProtoReflect() protoreflect.Message {
+ mi := &file_greeter_proto_msgTypes[5]
+ 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 DistrictReply.ProtoReflect.Descriptor instead.
+func (*DistrictReply) Descriptor() ([]byte, []int) {
+ return file_greeter_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *DistrictReply) GetList() []*District {
+ if x != nil {
+ return x.List
+ }
+ return nil
+}
+
+type PayTransRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Appid string `protobuf:"bytes,1,opt,name=appid,proto3" json:"appid,omitempty"`
+ Mchid string `protobuf:"bytes,2,opt,name=mchid,proto3" json:"mchid,omitempty"`
+ OutTradeNo string `protobuf:"bytes,3,opt,name=out_trade_no,json=outTradeNo,proto3" json:"out_trade_no,omitempty"`
+ Attach string `protobuf:"bytes,4,opt,name=attach,proto3" json:"attach,omitempty"`
+ NotifyUrl string `protobuf:"bytes,5,opt,name=notify_url,json=notifyUrl,proto3" json:"notify_url,omitempty"`
+ Amount float64 `protobuf:"fixed64,6,opt,name=amount,proto3" json:"amount,omitempty"`
+ Currency string `protobuf:"bytes,7,opt,name=currency,proto3" json:"currency,omitempty"`
+ PayChannel string `protobuf:"bytes,8,opt,name=pay_channel,json=payChannel,proto3" json:"pay_channel,omitempty"`
+ ReturnUrl string `protobuf:"bytes,9,opt,name=return_url,json=returnUrl,proto3" json:"return_url,omitempty"`
+ CancelUrl string `protobuf:"bytes,10,opt,name=cancel_url,json=cancelUrl,proto3" json:"cancel_url,omitempty"`
+}
+
+func (x *PayTransRequest) Reset() {
+ *x = PayTransRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_greeter_proto_msgTypes[6]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *PayTransRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*PayTransRequest) ProtoMessage() {}
+
+func (x *PayTransRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_greeter_proto_msgTypes[6]
+ 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 PayTransRequest.ProtoReflect.Descriptor instead.
+func (*PayTransRequest) Descriptor() ([]byte, []int) {
+ return file_greeter_proto_rawDescGZIP(), []int{6}
+}
+
+func (x *PayTransRequest) GetAppid() string {
+ if x != nil {
+ return x.Appid
+ }
+ return ""
+}
+
+func (x *PayTransRequest) GetMchid() string {
+ if x != nil {
+ return x.Mchid
+ }
+ return ""
+}
+
+func (x *PayTransRequest) GetOutTradeNo() string {
+ if x != nil {
+ return x.OutTradeNo
+ }
+ return ""
+}
+
+func (x *PayTransRequest) GetAttach() string {
+ if x != nil {
+ return x.Attach
+ }
+ return ""
+}
+
+func (x *PayTransRequest) GetNotifyUrl() string {
+ if x != nil {
+ return x.NotifyUrl
+ }
+ return ""
+}
+
+func (x *PayTransRequest) GetAmount() float64 {
+ if x != nil {
+ return x.Amount
+ }
+ return 0
+}
+
+func (x *PayTransRequest) GetCurrency() string {
+ if x != nil {
+ return x.Currency
+ }
+ return ""
+}
+
+func (x *PayTransRequest) GetPayChannel() string {
+ if x != nil {
+ return x.PayChannel
+ }
+ return ""
+}
+
+func (x *PayTransRequest) GetReturnUrl() string {
+ if x != nil {
+ return x.ReturnUrl
+ }
+ return ""
+}
+
+func (x *PayTransRequest) GetCancelUrl() string {
+ if x != nil {
+ return x.CancelUrl
+ }
+ return ""
+}
+
+type PayTransResponse struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ TransactionId string `protobuf:"bytes,1,opt,name=transaction_id,json=transactionId,proto3" json:"transaction_id,omitempty"`
+ Status string `protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"`
+ Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
+}
+
+func (x *PayTransResponse) Reset() {
+ *x = PayTransResponse{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_greeter_proto_msgTypes[7]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *PayTransResponse) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*PayTransResponse) ProtoMessage() {}
+
+func (x *PayTransResponse) ProtoReflect() protoreflect.Message {
+ mi := &file_greeter_proto_msgTypes[7]
+ 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 PayTransResponse.ProtoReflect.Descriptor instead.
+func (*PayTransResponse) Descriptor() ([]byte, []int) {
+ return file_greeter_proto_rawDescGZIP(), []int{7}
+}
+
+func (x *PayTransResponse) GetTransactionId() string {
+ if x != nil {
+ return x.TransactionId
+ }
+ return ""
+}
+
+func (x *PayTransResponse) GetStatus() string {
+ if x != nil {
+ return x.Status
+ }
+ return ""
+}
+
+func (x *PayTransResponse) GetMessage() string {
+ if x != nil {
+ return x.Message
+ }
+ return ""
+}
+
+type PayUrlRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Mchid string `protobuf:"bytes,1,opt,name=mchid,proto3" json:"mchid,omitempty"`
+ PayChannel string `protobuf:"bytes,2,opt,name=pay_channel,json=payChannel,proto3" json:"pay_channel,omitempty"`
+ TransactionId string `protobuf:"bytes,3,opt,name=transaction_id,json=transactionId,proto3" json:"transaction_id,omitempty"`
+}
+
+func (x *PayUrlRequest) Reset() {
+ *x = PayUrlRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_greeter_proto_msgTypes[8]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *PayUrlRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*PayUrlRequest) ProtoMessage() {}
+
+func (x *PayUrlRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_greeter_proto_msgTypes[8]
+ 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 PayUrlRequest.ProtoReflect.Descriptor instead.
+func (*PayUrlRequest) Descriptor() ([]byte, []int) {
+ return file_greeter_proto_rawDescGZIP(), []int{8}
+}
+
+func (x *PayUrlRequest) GetMchid() string {
+ if x != nil {
+ return x.Mchid
+ }
+ return ""
+}
+
+func (x *PayUrlRequest) GetPayChannel() string {
+ if x != nil {
+ return x.PayChannel
+ }
+ return ""
+}
+
+func (x *PayUrlRequest) GetTransactionId() string {
+ if x != nil {
+ return x.TransactionId
+ }
+ return ""
+}
+
+type PayUrlResponse struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ PayChannel string `protobuf:"bytes,1,opt,name=pay_channel,json=payChannel,proto3" json:"pay_channel,omitempty"`
+ PayId string `protobuf:"bytes,2,opt,name=pay_id,json=payId,proto3" json:"pay_id,omitempty"`
+ PayReturn string `protobuf:"bytes,3,opt,name=pay_return,json=payReturn,proto3" json:"pay_return,omitempty"`
+ PayStatus string `protobuf:"bytes,4,opt,name=pay_status,json=payStatus,proto3" json:"pay_status,omitempty"`
+}
+
+func (x *PayUrlResponse) Reset() {
+ *x = PayUrlResponse{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_greeter_proto_msgTypes[9]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *PayUrlResponse) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*PayUrlResponse) ProtoMessage() {}
+
+func (x *PayUrlResponse) ProtoReflect() protoreflect.Message {
+ mi := &file_greeter_proto_msgTypes[9]
+ 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 PayUrlResponse.ProtoReflect.Descriptor instead.
+func (*PayUrlResponse) Descriptor() ([]byte, []int) {
+ return file_greeter_proto_rawDescGZIP(), []int{9}
+}
+
+func (x *PayUrlResponse) GetPayChannel() string {
+ if x != nil {
+ return x.PayChannel
+ }
+ return ""
+}
+
+func (x *PayUrlResponse) GetPayId() string {
+ if x != nil {
+ return x.PayId
+ }
+ return ""
+}
+
+func (x *PayUrlResponse) GetPayReturn() string {
+ if x != nil {
+ return x.PayReturn
+ }
+ return ""
+}
+
+func (x *PayUrlResponse) GetPayStatus() string {
+ if x != nil {
+ return x.PayStatus
+ }
+ return ""
+}
+
+type PaybackRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Mchid string `protobuf:"bytes,1,opt,name=mchid,proto3" json:"mchid,omitempty"`
+ PayChannel string `protobuf:"bytes,2,opt,name=pay_channel,json=payChannel,proto3" json:"pay_channel,omitempty"`
+ PayId string `protobuf:"bytes,3,opt,name=pay_id,json=payId,proto3" json:"pay_id,omitempty"`
+ EventType string `protobuf:"bytes,4,opt,name=event_type,json=eventType,proto3" json:"event_type,omitempty"`
+}
+
+func (x *PaybackRequest) Reset() {
+ *x = PaybackRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_greeter_proto_msgTypes[10]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *PaybackRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*PaybackRequest) ProtoMessage() {}
+
+func (x *PaybackRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_greeter_proto_msgTypes[10]
+ 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 PaybackRequest.ProtoReflect.Descriptor instead.
+func (*PaybackRequest) Descriptor() ([]byte, []int) {
+ return file_greeter_proto_rawDescGZIP(), []int{10}
+}
+
+func (x *PaybackRequest) GetMchid() string {
+ if x != nil {
+ return x.Mchid
+ }
+ return ""
+}
+
+func (x *PaybackRequest) GetPayChannel() string {
+ if x != nil {
+ return x.PayChannel
+ }
+ return ""
+}
+
+func (x *PaybackRequest) GetPayId() string {
+ if x != nil {
+ return x.PayId
+ }
+ return ""
+}
+
+func (x *PaybackRequest) GetEventType() string {
+ if x != nil {
+ return x.EventType
+ }
+ return ""
+}
+
+type PaybackResp struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ OutTradeNo string `protobuf:"bytes,1,opt,name=out_trade_no,json=outTradeNo,proto3" json:"out_trade_no,omitempty"`
+ TradeState string `protobuf:"bytes,2,opt,name=trade_state,json=tradeState,proto3" json:"trade_state,omitempty"`
+ Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
+}
+
+func (x *PaybackResp) Reset() {
+ *x = PaybackResp{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_greeter_proto_msgTypes[11]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *PaybackResp) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*PaybackResp) ProtoMessage() {}
+
+func (x *PaybackResp) ProtoReflect() protoreflect.Message {
+ mi := &file_greeter_proto_msgTypes[11]
+ 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 PaybackResp.ProtoReflect.Descriptor instead.
+func (*PaybackResp) Descriptor() ([]byte, []int) {
+ return file_greeter_proto_rawDescGZIP(), []int{11}
+}
+
+func (x *PaybackResp) GetOutTradeNo() string {
+ if x != nil {
+ return x.OutTradeNo
+ }
+ return ""
+}
+
+func (x *PaybackResp) GetTradeState() string {
+ if x != nil {
+ return x.TradeState
+ }
+ return ""
+}
+
+func (x *PaybackResp) GetMessage() string {
+ if x != nil {
+ return x.Message
+ }
+ return ""
+}
+
+type GetPayTransOutTradeNoRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Appid string `protobuf:"bytes,1,opt,name=appid,proto3" json:"appid,omitempty"`
+ Mchid string `protobuf:"bytes,2,opt,name=mchid,proto3" json:"mchid,omitempty"`
+ OutTradeNo string `protobuf:"bytes,3,opt,name=out_trade_no,json=outTradeNo,proto3" json:"out_trade_no,omitempty"`
+}
+
+func (x *GetPayTransOutTradeNoRequest) Reset() {
+ *x = GetPayTransOutTradeNoRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_greeter_proto_msgTypes[12]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *GetPayTransOutTradeNoRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetPayTransOutTradeNoRequest) ProtoMessage() {}
+
+func (x *GetPayTransOutTradeNoRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_greeter_proto_msgTypes[12]
+ 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 GetPayTransOutTradeNoRequest.ProtoReflect.Descriptor instead.
+func (*GetPayTransOutTradeNoRequest) Descriptor() ([]byte, []int) {
+ return file_greeter_proto_rawDescGZIP(), []int{12}
+}
+
+func (x *GetPayTransOutTradeNoRequest) GetAppid() string {
+ if x != nil {
+ return x.Appid
+ }
+ return ""
+}
+
+func (x *GetPayTransOutTradeNoRequest) GetMchid() string {
+ if x != nil {
+ return x.Mchid
+ }
+ return ""
+}
+
+func (x *GetPayTransOutTradeNoRequest) GetOutTradeNo() string {
+ if x != nil {
+ return x.OutTradeNo
+ }
+ return ""
+}
+
+type GetPayTransactionResp struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Data *GetPayTransaction `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"`
+}
+
+func (x *GetPayTransactionResp) Reset() {
+ *x = GetPayTransactionResp{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_greeter_proto_msgTypes[13]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *GetPayTransactionResp) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetPayTransactionResp) ProtoMessage() {}
+
+func (x *GetPayTransactionResp) ProtoReflect() protoreflect.Message {
+ mi := &file_greeter_proto_msgTypes[13]
+ 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 GetPayTransactionResp.ProtoReflect.Descriptor instead.
+func (*GetPayTransactionResp) Descriptor() ([]byte, []int) {
+ return file_greeter_proto_rawDescGZIP(), []int{13}
+}
+
+func (x *GetPayTransactionResp) GetData() *GetPayTransaction {
+ if x != nil {
+ return x.Data
+ }
+ return nil
+}
+
+type GetPayTransaction struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Appid string `protobuf:"bytes,1,opt,name=appid,proto3" json:"appid,omitempty"`
+ Mchid string `protobuf:"bytes,2,opt,name=mchid,proto3" json:"mchid,omitempty"`
+}
+
+func (x *GetPayTransaction) Reset() {
+ *x = GetPayTransaction{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_greeter_proto_msgTypes[14]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *GetPayTransaction) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetPayTransaction) ProtoMessage() {}
+
+func (x *GetPayTransaction) ProtoReflect() protoreflect.Message {
+ mi := &file_greeter_proto_msgTypes[14]
+ 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 GetPayTransaction.ProtoReflect.Descriptor instead.
+func (*GetPayTransaction) Descriptor() ([]byte, []int) {
+ return file_greeter_proto_rawDescGZIP(), []int{14}
+}
+
+func (x *GetPayTransaction) GetAppid() string {
+ if x != nil {
+ return x.Appid
+ }
+ return ""
+}
+
+func (x *GetPayTransaction) GetMchid() string {
+ if x != nil {
+ return x.Mchid
+ }
+ return ""
+}
+
+type CloseBillRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ TransactionId string `protobuf:"bytes,1,opt,name=transaction_id,json=transactionId,proto3" json:"transaction_id,omitempty"`
+}
+
+func (x *CloseBillRequest) Reset() {
+ *x = CloseBillRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_greeter_proto_msgTypes[15]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *CloseBillRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CloseBillRequest) ProtoMessage() {}
+
+func (x *CloseBillRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_greeter_proto_msgTypes[15]
+ 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 CloseBillRequest.ProtoReflect.Descriptor instead.
+func (*CloseBillRequest) Descriptor() ([]byte, []int) {
+ return file_greeter_proto_rawDescGZIP(), []int{15}
+}
+
+func (x *CloseBillRequest) GetTransactionId() string {
+ if x != nil {
+ return x.TransactionId
+ }
+ return ""
+}
+
+var File_greeter_proto protoreflect.FileDescriptor
+
+var file_greeter_proto_rawDesc = []byte{
+ 0x0a, 0x0d, 0x67, 0x72, 0x65, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
+ 0x03, 0x61, 0x70, 0x69, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x22, 0x25, 0x0a, 0x09, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x18,
+ 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x2d, 0x0a, 0x07, 0x43, 0x6f, 0x75, 0x6e,
+ 0x74, 0x72, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52,
+ 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x30, 0x0a, 0x0c, 0x43, 0x6f, 0x75, 0x6e, 0x74,
+ 0x72, 0x79, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x20, 0x0a, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x18,
+ 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6f, 0x75, 0x6e,
+ 0x74, 0x72, 0x79, 0x52, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x22, 0x2b, 0x0a, 0x0f, 0x44, 0x69, 0x73,
+ 0x74, 0x72, 0x69, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07,
+ 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x63,
+ 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x22, 0x7f, 0x0a, 0x08, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69,
+ 0x63, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x64, 0x63, 0x6f,
+ 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x64, 0x63, 0x6f, 0x64, 0x65,
+ 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01,
+ 0x28, 0x05, 0x52, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x29, 0x0a, 0x08,
+ 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d,
+ 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x52, 0x08, 0x63,
+ 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x22, 0x32, 0x0a, 0x0d, 0x44, 0x69, 0x73, 0x74, 0x72,
+ 0x69, 0x63, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x21, 0x0a, 0x04, 0x6c, 0x69, 0x73, 0x74,
+ 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x69, 0x73,
+ 0x74, 0x72, 0x69, 0x63, 0x74, 0x52, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x22, 0xa9, 0x02, 0x0a, 0x0f,
+ 0x50, 0x61, 0x79, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
+ 0x14, 0x0a, 0x05, 0x61, 0x70, 0x70, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
+ 0x61, 0x70, 0x70, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x63, 0x68, 0x69, 0x64, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x63, 0x68, 0x69, 0x64, 0x12, 0x20, 0x0a, 0x0c, 0x6f,
+ 0x75, 0x74, 0x5f, 0x74, 0x72, 0x61, 0x64, 0x65, 0x5f, 0x6e, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x0a, 0x6f, 0x75, 0x74, 0x54, 0x72, 0x61, 0x64, 0x65, 0x4e, 0x6f, 0x12, 0x16, 0x0a,
+ 0x06, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61,
+ 0x74, 0x74, 0x61, 0x63, 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x5f,
+ 0x75, 0x72, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x6f, 0x74, 0x69, 0x66,
+ 0x79, 0x55, 0x72, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06,
+ 0x20, 0x01, 0x28, 0x01, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08,
+ 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
+ 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x79, 0x5f,
+ 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70,
+ 0x61, 0x79, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x74,
+ 0x75, 0x72, 0x6e, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72,
+ 0x65, 0x74, 0x75, 0x72, 0x6e, 0x55, 0x72, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x61, 0x6e, 0x63,
+ 0x65, 0x6c, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x61,
+ 0x6e, 0x63, 0x65, 0x6c, 0x55, 0x72, 0x6c, 0x22, 0x6b, 0x0a, 0x10, 0x50, 0x61, 0x79, 0x54, 0x72,
+ 0x61, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x74,
+ 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e,
+ 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65,
+ 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73,
+ 0x73, 0x61, 0x67, 0x65, 0x22, 0x6d, 0x0a, 0x0d, 0x50, 0x61, 0x79, 0x55, 0x72, 0x6c, 0x52, 0x65,
+ 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x63, 0x68, 0x69, 0x64, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x63, 0x68, 0x69, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x70,
+ 0x61, 0x79, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x0a, 0x70, 0x61, 0x79, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x25, 0x0a, 0x0e,
+ 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f,
+ 0x6e, 0x49, 0x64, 0x22, 0x86, 0x01, 0x0a, 0x0e, 0x50, 0x61, 0x79, 0x55, 0x72, 0x6c, 0x52, 0x65,
+ 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x79, 0x5f, 0x63, 0x68,
+ 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x61, 0x79,
+ 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x15, 0x0a, 0x06, 0x70, 0x61, 0x79, 0x5f, 0x69,
+ 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x70, 0x61, 0x79, 0x49, 0x64, 0x12, 0x1d,
+ 0x0a, 0x0a, 0x70, 0x61, 0x79, 0x5f, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x18, 0x03, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x79, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x12, 0x1d, 0x0a,
+ 0x0a, 0x70, 0x61, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x09, 0x70, 0x61, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x7d, 0x0a, 0x0e,
+ 0x50, 0x61, 0x79, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14,
+ 0x0a, 0x05, 0x6d, 0x63, 0x68, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d,
+ 0x63, 0x68, 0x69, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x79, 0x5f, 0x63, 0x68, 0x61, 0x6e,
+ 0x6e, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x61, 0x79, 0x43, 0x68,
+ 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x15, 0x0a, 0x06, 0x70, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x18,
+ 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x70, 0x61, 0x79, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a,
+ 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x09, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x22, 0x6a, 0x0a, 0x0b, 0x50,
+ 0x61, 0x79, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x12, 0x20, 0x0a, 0x0c, 0x6f, 0x75,
+ 0x74, 0x5f, 0x74, 0x72, 0x61, 0x64, 0x65, 0x5f, 0x6e, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x0a, 0x6f, 0x75, 0x74, 0x54, 0x72, 0x61, 0x64, 0x65, 0x4e, 0x6f, 0x12, 0x1f, 0x0a, 0x0b,
+ 0x74, 0x72, 0x61, 0x64, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x0a, 0x74, 0x72, 0x61, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a,
+ 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
+ 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x6c, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x50, 0x61,
+ 0x79, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x54, 0x72, 0x61, 0x64, 0x65, 0x4e, 0x6f,
+ 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x70, 0x70, 0x69, 0x64,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x70, 0x70, 0x69, 0x64, 0x12, 0x14, 0x0a,
+ 0x05, 0x6d, 0x63, 0x68, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x63,
+ 0x68, 0x69, 0x64, 0x12, 0x20, 0x0a, 0x0c, 0x6f, 0x75, 0x74, 0x5f, 0x74, 0x72, 0x61, 0x64, 0x65,
+ 0x5f, 0x6e, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x75, 0x74, 0x54, 0x72,
+ 0x61, 0x64, 0x65, 0x4e, 0x6f, 0x22, 0x43, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x50, 0x61, 0x79, 0x54,
+ 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x12, 0x2a,
+ 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x61,
+ 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61, 0x79, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63,
+ 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x3f, 0x0a, 0x11, 0x47, 0x65,
+ 0x74, 0x50, 0x61, 0x79, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12,
+ 0x14, 0x0a, 0x05, 0x61, 0x70, 0x70, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
+ 0x61, 0x70, 0x70, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x63, 0x68, 0x69, 0x64, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x63, 0x68, 0x69, 0x64, 0x22, 0x39, 0x0a, 0x10, 0x43,
+ 0x6c, 0x6f, 0x73, 0x65, 0x42, 0x69, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
+ 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69,
+ 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63,
+ 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x32, 0xf1, 0x04, 0x0a, 0x07, 0x47, 0x72, 0x65, 0x65, 0x74,
+ 0x65, 0x72, 0x12, 0x30, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f,
+ 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70,
+ 0x74, 0x79, 0x1a, 0x0e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x70,
+ 0x6c, 0x79, 0x22, 0x00, 0x12, 0x3a, 0x0a, 0x0b, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x4c,
+ 0x69, 0x73, 0x74, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x11, 0x2e, 0x61, 0x70,
+ 0x69, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00,
+ 0x12, 0x3d, 0x0a, 0x0f, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x43, 0x61, 0x73, 0x63,
+ 0x61, 0x64, 0x65, 0x12, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69,
+ 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x61, 0x70, 0x69, 0x2e,
+ 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12,
+ 0x42, 0x0a, 0x11, 0x50, 0x61, 0x79, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f,
+ 0x6e, 0x41, 0x70, 0x70, 0x12, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x50, 0x61, 0x79, 0x54, 0x72,
+ 0x61, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x61, 0x70, 0x69,
+ 0x2e, 0x50, 0x61, 0x79, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+ 0x65, 0x22, 0x00, 0x12, 0x3a, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e,
+ 0x74, 0x55, 0x72, 0x6c, 0x12, 0x12, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x50, 0x61, 0x79, 0x55, 0x72,
+ 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x50,
+ 0x61, 0x79, 0x55, 0x72, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
+ 0x43, 0x0a, 0x14, 0x50, 0x61, 0x79, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f,
+ 0x6e, 0x41, 0x70, 0x70, 0x55, 0x72, 0x6c, 0x12, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x50, 0x61,
+ 0x79, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e,
+ 0x61, 0x70, 0x69, 0x2e, 0x50, 0x61, 0x79, 0x55, 0x72, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+ 0x73, 0x65, 0x22, 0x00, 0x12, 0x39, 0x0a, 0x0e, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x50,
+ 0x61, 0x79, 0x62, 0x61, 0x63, 0x6b, 0x12, 0x13, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x50, 0x61, 0x79,
+ 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x61, 0x70,
+ 0x69, 0x2e, 0x50, 0x61, 0x79, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12,
+ 0x38, 0x0a, 0x0d, 0x50, 0x61, 0x79, 0x70, 0x61, 0x6c, 0x50, 0x61, 0x79, 0x62, 0x61, 0x63, 0x6b,
+ 0x12, 0x13, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x50, 0x61, 0x79, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65,
+ 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x50, 0x61, 0x79, 0x62,
+ 0x61, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x49, 0x0a, 0x11, 0x47, 0x65, 0x74,
+ 0x50, 0x61, 0x79, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16,
+ 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
+ 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74,
+ 0x50, 0x61, 0x79, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65,
+ 0x73, 0x70, 0x22, 0x00, 0x12, 0x34, 0x0a, 0x09, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x42, 0x69, 0x6c,
+ 0x6c, 0x12, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x42, 0x69, 0x6c,
+ 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x50,
+ 0x69, 0x6e, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x42, 0x11, 0x5a, 0x0f, 0x62, 0x6b,
+ 0x62, 0x2d, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+ file_greeter_proto_rawDescOnce sync.Once
+ file_greeter_proto_rawDescData = file_greeter_proto_rawDesc
+)
+
+func file_greeter_proto_rawDescGZIP() []byte {
+ file_greeter_proto_rawDescOnce.Do(func() {
+ file_greeter_proto_rawDescData = protoimpl.X.CompressGZIP(file_greeter_proto_rawDescData)
+ })
+ return file_greeter_proto_rawDescData
+}
+
+var file_greeter_proto_msgTypes = make([]protoimpl.MessageInfo, 16)
+var file_greeter_proto_goTypes = []interface{}{
+ (*PingReply)(nil), // 0: api.PingReply
+ (*Country)(nil), // 1: api.Country
+ (*CountryReply)(nil), // 2: api.CountryReply
+ (*DistrictRequest)(nil), // 3: api.DistrictRequest
+ (*District)(nil), // 4: api.District
+ (*DistrictReply)(nil), // 5: api.DistrictReply
+ (*PayTransRequest)(nil), // 6: api.PayTransRequest
+ (*PayTransResponse)(nil), // 7: api.PayTransResponse
+ (*PayUrlRequest)(nil), // 8: api.PayUrlRequest
+ (*PayUrlResponse)(nil), // 9: api.PayUrlResponse
+ (*PaybackRequest)(nil), // 10: api.PaybackRequest
+ (*PaybackResp)(nil), // 11: api.PaybackResp
+ (*GetPayTransOutTradeNoRequest)(nil), // 12: api.GetPayTransOutTradeNoRequest
+ (*GetPayTransactionResp)(nil), // 13: api.GetPayTransactionResp
+ (*GetPayTransaction)(nil), // 14: api.GetPayTransaction
+ (*CloseBillRequest)(nil), // 15: api.CloseBillRequest
+ (*emptypb.Empty)(nil), // 16: google.protobuf.Empty
+}
+var file_greeter_proto_depIdxs = []int32{
+ 1, // 0: api.CountryReply.list:type_name -> api.Country
+ 4, // 1: api.District.children:type_name -> api.District
+ 4, // 2: api.DistrictReply.list:type_name -> api.District
+ 14, // 3: api.GetPayTransactionResp.data:type_name -> api.GetPayTransaction
+ 16, // 4: api.Greeter.Ping:input_type -> google.protobuf.Empty
+ 16, // 5: api.Greeter.CountryList:input_type -> google.protobuf.Empty
+ 3, // 6: api.Greeter.DistrictCascade:input_type -> api.DistrictRequest
+ 6, // 7: api.Greeter.PayTransactionApp:input_type -> api.PayTransRequest
+ 8, // 8: api.Greeter.GetPaymentUrl:input_type -> api.PayUrlRequest
+ 6, // 9: api.Greeter.PayTransactionAppUrl:input_type -> api.PayTransRequest
+ 10, // 10: api.Greeter.SuccessPayback:input_type -> api.PaybackRequest
+ 10, // 11: api.Greeter.PaypalPayback:input_type -> api.PaybackRequest
+ 16, // 12: api.Greeter.GetPayTransaction:input_type -> google.protobuf.Empty
+ 15, // 13: api.Greeter.CloseBill:input_type -> api.CloseBillRequest
+ 0, // 14: api.Greeter.Ping:output_type -> api.PingReply
+ 2, // 15: api.Greeter.CountryList:output_type -> api.CountryReply
+ 5, // 16: api.Greeter.DistrictCascade:output_type -> api.DistrictReply
+ 7, // 17: api.Greeter.PayTransactionApp:output_type -> api.PayTransResponse
+ 9, // 18: api.Greeter.GetPaymentUrl:output_type -> api.PayUrlResponse
+ 9, // 19: api.Greeter.PayTransactionAppUrl:output_type -> api.PayUrlResponse
+ 11, // 20: api.Greeter.SuccessPayback:output_type -> api.PaybackResp
+ 11, // 21: api.Greeter.PaypalPayback:output_type -> api.PaybackResp
+ 13, // 22: api.Greeter.GetPayTransaction:output_type -> api.GetPayTransactionResp
+ 0, // 23: api.Greeter.CloseBill:output_type -> api.PingReply
+ 14, // [14:24] is the sub-list for method output_type
+ 4, // [4:14] is the sub-list for method input_type
+ 4, // [4:4] is the sub-list for extension type_name
+ 4, // [4:4] is the sub-list for extension extendee
+ 0, // [0:4] is the sub-list for field type_name
+}
+
+func init() { file_greeter_proto_init() }
+func file_greeter_proto_init() {
+ if File_greeter_proto != nil {
+ return
+ }
+ if !protoimpl.UnsafeEnabled {
+ file_greeter_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*PingReply); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_greeter_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Country); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_greeter_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*CountryReply); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_greeter_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*DistrictRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_greeter_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*District); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_greeter_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*DistrictReply); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_greeter_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*PayTransRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_greeter_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*PayTransResponse); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_greeter_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*PayUrlRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_greeter_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*PayUrlResponse); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_greeter_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*PaybackRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_greeter_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*PaybackResp); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_greeter_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*GetPayTransOutTradeNoRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_greeter_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*GetPayTransactionResp); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_greeter_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*GetPayTransaction); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_greeter_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*CloseBillRequest); 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_greeter_proto_rawDesc,
+ NumEnums: 0,
+ NumMessages: 16,
+ NumExtensions: 0,
+ NumServices: 1,
+ },
+ GoTypes: file_greeter_proto_goTypes,
+ DependencyIndexes: file_greeter_proto_depIdxs,
+ MessageInfos: file_greeter_proto_msgTypes,
+ }.Build()
+ File_greeter_proto = out.File
+ file_greeter_proto_rawDesc = nil
+ file_greeter_proto_goTypes = nil
+ file_greeter_proto_depIdxs = nil
+}
diff --git a/initialize/api/greeter.proto b/initialize/api/greeter.proto
new file mode 100644
index 0000000..d69ca0b
--- /dev/null
+++ b/initialize/api/greeter.proto
@@ -0,0 +1,126 @@
+syntax = "proto3";
+
+package api;
+
+import "google/protobuf/empty.proto";
+//import "common.proto";
+option go_package = "bkb-payment/api";
+
+
+// The greeting service definition.
+service Greeter {
+ // Sends a greeting
+ rpc Ping (google.protobuf.Empty) returns (PingReply) {
+
+ }
+ rpc CountryList (google.protobuf.Empty) returns (CountryReply) {
+
+ }
+ rpc DistrictCascade (DistrictRequest) returns (DistrictReply) {
+
+ }
+ rpc PayTransactionApp(PayTransRequest) returns (PayTransResponse) {
+
+ }
+ rpc GetPaymentUrl(PayUrlRequest) returns (PayUrlResponse) {
+
+ }
+ rpc PayTransactionAppUrl(PayTransRequest) returns (PayUrlResponse) {
+
+ }
+ rpc SuccessPayback(PaybackRequest) returns (PaybackResp) {
+
+ }
+ rpc PaypalPayback(PaybackRequest) returns (PaybackResp) {
+
+ }
+ rpc GetPayTransaction(google.protobuf.Empty) returns (GetPayTransactionResp) {
+
+ }
+ rpc CloseBill(CloseBillRequest) returns (PingReply) {
+
+ }
+ // rpc ClosePayTransaction(google.protobuf.Empty) returns (PingReply) {
+ // option (google.api.http) = {
+ // post: "/pay/transaction/outTradeNo/close"
+ // };
+ // }
+}
+
+// The response message containing the greetings
+message PingReply {
+ string message = 1;
+}
+message Country{
+ int32 id = 1;
+ string name = 2;
+}
+message CountryReply{
+ repeated Country list = 1;
+}
+message DistrictRequest {
+ int32 country = 1;
+}
+message District {
+ string label = 1;
+ string adcode = 2;
+ int32 parentId = 3;
+ repeated District children = 4;
+}
+message DistrictReply{
+ repeated District list = 1;
+}
+message PayTransRequest{
+ string appid = 1;
+ string mchid = 2;
+ string out_trade_no = 3;
+ string attach = 4;
+ string notify_url = 5;
+ double amount = 6;
+ string currency = 7;
+ string pay_channel = 8;
+ string return_url = 9;
+ string cancel_url = 10;
+}
+message PayTransResponse{
+ string transaction_id = 1;
+ string status = 2;
+ string message = 3;
+}
+message PayUrlRequest{
+ string mchid = 1;
+ string pay_channel = 2;
+ string transaction_id = 3;
+}
+message PayUrlResponse{
+ string pay_channel = 1;
+ string pay_id = 2;
+ string pay_return = 3;
+ string pay_status = 4;
+}
+message PaybackRequest{
+ string mchid = 1;
+ string pay_channel = 2;
+ string pay_id = 3;
+ string event_type = 4;
+}
+message PaybackResp{
+ string out_trade_no = 1;
+ string trade_state = 2;
+ string message = 3;
+}
+message GetPayTransOutTradeNoRequest{
+ string appid = 1;
+ string mchid = 2;
+ string out_trade_no = 3;
+}
+message GetPayTransactionResp{
+ GetPayTransaction data = 1;
+}
+message GetPayTransaction{
+ string appid = 1;
+ string mchid = 2;
+}
+message CloseBillRequest{
+ string transaction_id = 1;
+}
\ No newline at end of file
diff --git a/initialize/api/greeter_grpc.pb.go b/initialize/api/greeter_grpc.pb.go
new file mode 100644
index 0000000..8dd7faa
--- /dev/null
+++ b/initialize/api/greeter_grpc.pb.go
@@ -0,0 +1,432 @@
+// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+// versions:
+// - protoc-gen-go-grpc v1.2.0
+// - protoc v4.23.4
+// source: greeter.proto
+
+package api
+
+import (
+ context "context"
+ grpc "google.golang.org/grpc"
+ codes "google.golang.org/grpc/codes"
+ status "google.golang.org/grpc/status"
+ emptypb "google.golang.org/protobuf/types/known/emptypb"
+)
+
+// 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
+
+// GreeterClient is the client API for Greeter 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 GreeterClient interface {
+ // Sends a greeting
+ Ping(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*PingReply, error)
+ CountryList(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*CountryReply, error)
+ DistrictCascade(ctx context.Context, in *DistrictRequest, opts ...grpc.CallOption) (*DistrictReply, error)
+ PayTransactionApp(ctx context.Context, in *PayTransRequest, opts ...grpc.CallOption) (*PayTransResponse, error)
+ GetPaymentUrl(ctx context.Context, in *PayUrlRequest, opts ...grpc.CallOption) (*PayUrlResponse, error)
+ PayTransactionAppUrl(ctx context.Context, in *PayTransRequest, opts ...grpc.CallOption) (*PayUrlResponse, error)
+ SuccessPayback(ctx context.Context, in *PaybackRequest, opts ...grpc.CallOption) (*PaybackResp, error)
+ PaypalPayback(ctx context.Context, in *PaybackRequest, opts ...grpc.CallOption) (*PaybackResp, error)
+ GetPayTransaction(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*GetPayTransactionResp, error)
+ CloseBill(ctx context.Context, in *CloseBillRequest, opts ...grpc.CallOption) (*PingReply, error)
+}
+
+type greeterClient struct {
+ cc grpc.ClientConnInterface
+}
+
+func NewGreeterClient(cc grpc.ClientConnInterface) GreeterClient {
+ return &greeterClient{cc}
+}
+
+func (c *greeterClient) Ping(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*PingReply, error) {
+ out := new(PingReply)
+ err := c.cc.Invoke(ctx, "/api.Greeter/Ping", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *greeterClient) CountryList(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*CountryReply, error) {
+ out := new(CountryReply)
+ err := c.cc.Invoke(ctx, "/api.Greeter/CountryList", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *greeterClient) DistrictCascade(ctx context.Context, in *DistrictRequest, opts ...grpc.CallOption) (*DistrictReply, error) {
+ out := new(DistrictReply)
+ err := c.cc.Invoke(ctx, "/api.Greeter/DistrictCascade", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *greeterClient) PayTransactionApp(ctx context.Context, in *PayTransRequest, opts ...grpc.CallOption) (*PayTransResponse, error) {
+ out := new(PayTransResponse)
+ err := c.cc.Invoke(ctx, "/api.Greeter/PayTransactionApp", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *greeterClient) GetPaymentUrl(ctx context.Context, in *PayUrlRequest, opts ...grpc.CallOption) (*PayUrlResponse, error) {
+ out := new(PayUrlResponse)
+ err := c.cc.Invoke(ctx, "/api.Greeter/GetPaymentUrl", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *greeterClient) PayTransactionAppUrl(ctx context.Context, in *PayTransRequest, opts ...grpc.CallOption) (*PayUrlResponse, error) {
+ out := new(PayUrlResponse)
+ err := c.cc.Invoke(ctx, "/api.Greeter/PayTransactionAppUrl", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *greeterClient) SuccessPayback(ctx context.Context, in *PaybackRequest, opts ...grpc.CallOption) (*PaybackResp, error) {
+ out := new(PaybackResp)
+ err := c.cc.Invoke(ctx, "/api.Greeter/SuccessPayback", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *greeterClient) PaypalPayback(ctx context.Context, in *PaybackRequest, opts ...grpc.CallOption) (*PaybackResp, error) {
+ out := new(PaybackResp)
+ err := c.cc.Invoke(ctx, "/api.Greeter/PaypalPayback", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *greeterClient) GetPayTransaction(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*GetPayTransactionResp, error) {
+ out := new(GetPayTransactionResp)
+ err := c.cc.Invoke(ctx, "/api.Greeter/GetPayTransaction", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *greeterClient) CloseBill(ctx context.Context, in *CloseBillRequest, opts ...grpc.CallOption) (*PingReply, error) {
+ out := new(PingReply)
+ err := c.cc.Invoke(ctx, "/api.Greeter/CloseBill", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+// GreeterServer is the server API for Greeter service.
+// All implementations must embed UnimplementedGreeterServer
+// for forward compatibility
+type GreeterServer interface {
+ // Sends a greeting
+ Ping(context.Context, *emptypb.Empty) (*PingReply, error)
+ CountryList(context.Context, *emptypb.Empty) (*CountryReply, error)
+ DistrictCascade(context.Context, *DistrictRequest) (*DistrictReply, error)
+ PayTransactionApp(context.Context, *PayTransRequest) (*PayTransResponse, error)
+ GetPaymentUrl(context.Context, *PayUrlRequest) (*PayUrlResponse, error)
+ PayTransactionAppUrl(context.Context, *PayTransRequest) (*PayUrlResponse, error)
+ SuccessPayback(context.Context, *PaybackRequest) (*PaybackResp, error)
+ PaypalPayback(context.Context, *PaybackRequest) (*PaybackResp, error)
+ GetPayTransaction(context.Context, *emptypb.Empty) (*GetPayTransactionResp, error)
+ CloseBill(context.Context, *CloseBillRequest) (*PingReply, error)
+ mustEmbedUnimplementedGreeterServer()
+}
+
+// UnimplementedGreeterServer must be embedded to have forward compatible implementations.
+type UnimplementedGreeterServer struct {
+}
+
+func (UnimplementedGreeterServer) Ping(context.Context, *emptypb.Empty) (*PingReply, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method Ping not implemented")
+}
+func (UnimplementedGreeterServer) CountryList(context.Context, *emptypb.Empty) (*CountryReply, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method CountryList not implemented")
+}
+func (UnimplementedGreeterServer) DistrictCascade(context.Context, *DistrictRequest) (*DistrictReply, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method DistrictCascade not implemented")
+}
+func (UnimplementedGreeterServer) PayTransactionApp(context.Context, *PayTransRequest) (*PayTransResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method PayTransactionApp not implemented")
+}
+func (UnimplementedGreeterServer) GetPaymentUrl(context.Context, *PayUrlRequest) (*PayUrlResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method GetPaymentUrl not implemented")
+}
+func (UnimplementedGreeterServer) PayTransactionAppUrl(context.Context, *PayTransRequest) (*PayUrlResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method PayTransactionAppUrl not implemented")
+}
+func (UnimplementedGreeterServer) SuccessPayback(context.Context, *PaybackRequest) (*PaybackResp, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method SuccessPayback not implemented")
+}
+func (UnimplementedGreeterServer) PaypalPayback(context.Context, *PaybackRequest) (*PaybackResp, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method PaypalPayback not implemented")
+}
+func (UnimplementedGreeterServer) GetPayTransaction(context.Context, *emptypb.Empty) (*GetPayTransactionResp, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method GetPayTransaction not implemented")
+}
+func (UnimplementedGreeterServer) CloseBill(context.Context, *CloseBillRequest) (*PingReply, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method CloseBill not implemented")
+}
+func (UnimplementedGreeterServer) mustEmbedUnimplementedGreeterServer() {}
+
+// UnsafeGreeterServer may be embedded to opt out of forward compatibility for this service.
+// Use of this interface is not recommended, as added methods to GreeterServer will
+// result in compilation errors.
+type UnsafeGreeterServer interface {
+ mustEmbedUnimplementedGreeterServer()
+}
+
+func RegisterGreeterServer(s grpc.ServiceRegistrar, srv GreeterServer) {
+ s.RegisterService(&Greeter_ServiceDesc, srv)
+}
+
+func _Greeter_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(emptypb.Empty)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(GreeterServer).Ping(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/api.Greeter/Ping",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(GreeterServer).Ping(ctx, req.(*emptypb.Empty))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Greeter_CountryList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(emptypb.Empty)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(GreeterServer).CountryList(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/api.Greeter/CountryList",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(GreeterServer).CountryList(ctx, req.(*emptypb.Empty))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Greeter_DistrictCascade_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(DistrictRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(GreeterServer).DistrictCascade(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/api.Greeter/DistrictCascade",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(GreeterServer).DistrictCascade(ctx, req.(*DistrictRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Greeter_PayTransactionApp_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(PayTransRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(GreeterServer).PayTransactionApp(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/api.Greeter/PayTransactionApp",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(GreeterServer).PayTransactionApp(ctx, req.(*PayTransRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Greeter_GetPaymentUrl_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(PayUrlRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(GreeterServer).GetPaymentUrl(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/api.Greeter/GetPaymentUrl",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(GreeterServer).GetPaymentUrl(ctx, req.(*PayUrlRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Greeter_PayTransactionAppUrl_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(PayTransRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(GreeterServer).PayTransactionAppUrl(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/api.Greeter/PayTransactionAppUrl",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(GreeterServer).PayTransactionAppUrl(ctx, req.(*PayTransRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Greeter_SuccessPayback_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(PaybackRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(GreeterServer).SuccessPayback(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/api.Greeter/SuccessPayback",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(GreeterServer).SuccessPayback(ctx, req.(*PaybackRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Greeter_PaypalPayback_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(PaybackRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(GreeterServer).PaypalPayback(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/api.Greeter/PaypalPayback",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(GreeterServer).PaypalPayback(ctx, req.(*PaybackRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Greeter_GetPayTransaction_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(emptypb.Empty)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(GreeterServer).GetPayTransaction(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/api.Greeter/GetPayTransaction",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(GreeterServer).GetPayTransaction(ctx, req.(*emptypb.Empty))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Greeter_CloseBill_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(CloseBillRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(GreeterServer).CloseBill(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/api.Greeter/CloseBill",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(GreeterServer).CloseBill(ctx, req.(*CloseBillRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+// Greeter_ServiceDesc is the grpc.ServiceDesc for Greeter service.
+// It's only intended for direct use with grpc.RegisterService,
+// and not to be introspected or modified (even as a copy)
+var Greeter_ServiceDesc = grpc.ServiceDesc{
+ ServiceName: "api.Greeter",
+ HandlerType: (*GreeterServer)(nil),
+ Methods: []grpc.MethodDesc{
+ {
+ MethodName: "Ping",
+ Handler: _Greeter_Ping_Handler,
+ },
+ {
+ MethodName: "CountryList",
+ Handler: _Greeter_CountryList_Handler,
+ },
+ {
+ MethodName: "DistrictCascade",
+ Handler: _Greeter_DistrictCascade_Handler,
+ },
+ {
+ MethodName: "PayTransactionApp",
+ Handler: _Greeter_PayTransactionApp_Handler,
+ },
+ {
+ MethodName: "GetPaymentUrl",
+ Handler: _Greeter_GetPaymentUrl_Handler,
+ },
+ {
+ MethodName: "PayTransactionAppUrl",
+ Handler: _Greeter_PayTransactionAppUrl_Handler,
+ },
+ {
+ MethodName: "SuccessPayback",
+ Handler: _Greeter_SuccessPayback_Handler,
+ },
+ {
+ MethodName: "PaypalPayback",
+ Handler: _Greeter_PaypalPayback_Handler,
+ },
+ {
+ MethodName: "GetPayTransaction",
+ Handler: _Greeter_GetPayTransaction_Handler,
+ },
+ {
+ MethodName: "CloseBill",
+ Handler: _Greeter_CloseBill_Handler,
+ },
+ },
+ Streams: []grpc.StreamDesc{},
+ Metadata: "greeter.proto",
+}
diff --git a/initialize/api/sms.pb.go b/initialize/api/sms.pb.go
new file mode 100644
index 0000000..ec1a800
--- /dev/null
+++ b/initialize/api/sms.pb.go
@@ -0,0 +1,329 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.31.0
+// protoc v3.21.12
+// source: sms.proto
+
+package api
+
+import (
+ _ "google.golang.org/genproto/googleapis/api/annotations"
+ 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 SendSmsRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // 手机号码,必填
+ Phone string `protobuf:"bytes,1,opt,name=phone,proto3" json:"phone,omitempty"`
+ // 短信场景值 1,2,3,4
+ SmsType int32 `protobuf:"varint,2,opt,name=smsType,proto3" json:"smsType,omitempty"`
+ // 国际区号 86 中国 1美国
+ AreaCode string `protobuf:"bytes,3,opt,name=areaCode,proto3" json:"areaCode,omitempty"`
+}
+
+func (x *SendSmsRequest) Reset() {
+ *x = SendSmsRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_sms_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *SendSmsRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SendSmsRequest) ProtoMessage() {}
+
+func (x *SendSmsRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_sms_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 SendSmsRequest.ProtoReflect.Descriptor instead.
+func (*SendSmsRequest) Descriptor() ([]byte, []int) {
+ return file_sms_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *SendSmsRequest) GetPhone() string {
+ if x != nil {
+ return x.Phone
+ }
+ return ""
+}
+
+func (x *SendSmsRequest) GetSmsType() int32 {
+ if x != nil {
+ return x.SmsType
+ }
+ return 0
+}
+
+func (x *SendSmsRequest) GetAreaCode() string {
+ if x != nil {
+ return x.AreaCode
+ }
+ return ""
+}
+
+// 短信发送回复
+type SendSmsReply struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Code int32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"`
+ Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"`
+}
+
+func (x *SendSmsReply) Reset() {
+ *x = SendSmsReply{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_sms_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *SendSmsReply) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SendSmsReply) ProtoMessage() {}
+
+func (x *SendSmsReply) ProtoReflect() protoreflect.Message {
+ mi := &file_sms_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 SendSmsReply.ProtoReflect.Descriptor instead.
+func (*SendSmsReply) Descriptor() ([]byte, []int) {
+ return file_sms_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *SendSmsReply) GetCode() int32 {
+ if x != nil {
+ return x.Code
+ }
+ return 0
+}
+
+func (x *SendSmsReply) GetMessage() string {
+ if x != nil {
+ return x.Message
+ }
+ return ""
+}
+
+type SmsCodeVerifyRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // 手机号码,必填
+ Phone string `protobuf:"bytes,1,opt,name=phone,proto3" json:"phone,omitempty"`
+ // 短信验证码
+ Code string `protobuf:"bytes,2,opt,name=code,proto3" json:"code,omitempty"`
+}
+
+func (x *SmsCodeVerifyRequest) Reset() {
+ *x = SmsCodeVerifyRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_sms_proto_msgTypes[2]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *SmsCodeVerifyRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SmsCodeVerifyRequest) ProtoMessage() {}
+
+func (x *SmsCodeVerifyRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_sms_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 SmsCodeVerifyRequest.ProtoReflect.Descriptor instead.
+func (*SmsCodeVerifyRequest) Descriptor() ([]byte, []int) {
+ return file_sms_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *SmsCodeVerifyRequest) GetPhone() string {
+ if x != nil {
+ return x.Phone
+ }
+ return ""
+}
+
+func (x *SmsCodeVerifyRequest) GetCode() string {
+ if x != nil {
+ return x.Code
+ }
+ return ""
+}
+
+var File_sms_proto protoreflect.FileDescriptor
+
+var file_sms_proto_rawDesc = []byte{
+ 0x0a, 0x09, 0x73, 0x6d, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x03, 0x61, 0x70, 0x69,
+ 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e,
+ 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x5c,
+ 0x0a, 0x0e, 0x53, 0x65, 0x6e, 0x64, 0x53, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+ 0x12, 0x14, 0x0a, 0x05, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x05, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x6d, 0x73, 0x54, 0x79, 0x70,
+ 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x73, 0x6d, 0x73, 0x54, 0x79, 0x70, 0x65,
+ 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x72, 0x65, 0x61, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x08, 0x61, 0x72, 0x65, 0x61, 0x43, 0x6f, 0x64, 0x65, 0x22, 0x3c, 0x0a, 0x0c,
+ 0x53, 0x65, 0x6e, 0x64, 0x53, 0x6d, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x12, 0x0a, 0x04,
+ 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65,
+ 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x40, 0x0a, 0x14, 0x53, 0x6d,
+ 0x73, 0x43, 0x6f, 0x64, 0x65, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65,
+ 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x05, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x32, 0xa9, 0x01, 0x0a,
+ 0x03, 0x53, 0x6d, 0x73, 0x12, 0x4a, 0x0a, 0x0b, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x73,
+ 0x61, 0x67, 0x65, 0x12, 0x13, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x53, 0x6d,
+ 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53,
+ 0x65, 0x6e, 0x64, 0x53, 0x6d, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x13, 0x82, 0xd3, 0xe4,
+ 0x93, 0x02, 0x0d, 0x3a, 0x01, 0x2a, 0x22, 0x08, 0x73, 0x6d, 0x73, 0x2f, 0x73, 0x65, 0x6e, 0x64,
+ 0x12, 0x56, 0x0a, 0x0a, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x19,
+ 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x6d, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x56, 0x65, 0x72, 0x69,
+ 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x2e,
+ 0x53, 0x65, 0x6e, 0x64, 0x53, 0x6d, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1a, 0x82, 0xd3,
+ 0xe4, 0x93, 0x02, 0x14, 0x3a, 0x01, 0x2a, 0x22, 0x0f, 0x73, 0x6d, 0x73, 0x2f, 0x63, 0x6f, 0x64,
+ 0x65, 0x2d, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x42, 0x10, 0x5a, 0x0e, 0x62, 0x6b, 0x62, 0x2d,
+ 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x2f, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x33,
+}
+
+var (
+ file_sms_proto_rawDescOnce sync.Once
+ file_sms_proto_rawDescData = file_sms_proto_rawDesc
+)
+
+func file_sms_proto_rawDescGZIP() []byte {
+ file_sms_proto_rawDescOnce.Do(func() {
+ file_sms_proto_rawDescData = protoimpl.X.CompressGZIP(file_sms_proto_rawDescData)
+ })
+ return file_sms_proto_rawDescData
+}
+
+var file_sms_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
+var file_sms_proto_goTypes = []interface{}{
+ (*SendSmsRequest)(nil), // 0: api.SendSmsRequest
+ (*SendSmsReply)(nil), // 1: api.SendSmsReply
+ (*SmsCodeVerifyRequest)(nil), // 2: api.SmsCodeVerifyRequest
+}
+var file_sms_proto_depIdxs = []int32{
+ 0, // 0: api.Sms.SendMessage:input_type -> api.SendSmsRequest
+ 2, // 1: api.Sms.VerifyCode:input_type -> api.SmsCodeVerifyRequest
+ 1, // 2: api.Sms.SendMessage:output_type -> api.SendSmsReply
+ 1, // 3: api.Sms.VerifyCode:output_type -> api.SendSmsReply
+ 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_sms_proto_init() }
+func file_sms_proto_init() {
+ if File_sms_proto != nil {
+ return
+ }
+ if !protoimpl.UnsafeEnabled {
+ file_sms_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*SendSmsRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_sms_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*SendSmsReply); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_sms_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*SmsCodeVerifyRequest); 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_sms_proto_rawDesc,
+ NumEnums: 0,
+ NumMessages: 3,
+ NumExtensions: 0,
+ NumServices: 1,
+ },
+ GoTypes: file_sms_proto_goTypes,
+ DependencyIndexes: file_sms_proto_depIdxs,
+ MessageInfos: file_sms_proto_msgTypes,
+ }.Build()
+ File_sms_proto = out.File
+ file_sms_proto_rawDesc = nil
+ file_sms_proto_goTypes = nil
+ file_sms_proto_depIdxs = nil
+}
diff --git a/initialize/api/sms.proto b/initialize/api/sms.proto
new file mode 100644
index 0000000..7313b96
--- /dev/null
+++ b/initialize/api/sms.proto
@@ -0,0 +1,47 @@
+syntax = "proto3";
+
+package api;
+
+import "google/api/annotations.proto";
+option go_package = "bkb-notify/api";
+
+
+// The Email service definition.
+service Sms {
+ // 发送一条短信
+ rpc SendMessage (SendSmsRequest) returns (SendSmsReply) {
+ option (google.api.http) = {
+ post: "sms/send"
+ body: "*"
+ };
+ }
+ // 校验短信code
+ rpc VerifyCode (SmsCodeVerifyRequest) returns (SendSmsReply) {
+ option (google.api.http) = {
+ post: "sms/code-verify"
+ body: "*"
+ };
+ }
+}
+
+message SendSmsRequest {
+ //手机号码,必填
+ string phone=1;
+ //短信场景值 1,2,3,4
+ int32 smsType=2;
+ //国际区号 86 中国 1美国
+ string areaCode = 3;
+}
+
+// 短信发送回复
+message SendSmsReply {
+ int32 code = 1;
+ string message = 2;
+}
+
+message SmsCodeVerifyRequest {
+ //手机号码,必填
+ string phone=1;
+ //短信验证码
+ string code=2;
+}
\ No newline at end of file
diff --git a/initialize/api/sms_grpc.pb.go b/initialize/api/sms_grpc.pb.go
new file mode 100644
index 0000000..680ccba
--- /dev/null
+++ b/initialize/api/sms_grpc.pb.go
@@ -0,0 +1,150 @@
+// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+// versions:
+// - protoc-gen-go-grpc v1.3.0
+// - protoc v3.21.12
+// source: sms.proto
+
+package api
+
+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
+
+const (
+ Sms_SendMessage_FullMethodName = "/api.Sms/SendMessage"
+ Sms_VerifyCode_FullMethodName = "/api.Sms/VerifyCode"
+)
+
+// SmsClient is the client API for Sms 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 SmsClient interface {
+ // 发送一条短信
+ SendMessage(ctx context.Context, in *SendSmsRequest, opts ...grpc.CallOption) (*SendSmsReply, error)
+ // 校验短信code
+ VerifyCode(ctx context.Context, in *SmsCodeVerifyRequest, opts ...grpc.CallOption) (*SendSmsReply, error)
+}
+
+type smsClient struct {
+ cc grpc.ClientConnInterface
+}
+
+func NewSmsClient(cc grpc.ClientConnInterface) SmsClient {
+ return &smsClient{cc}
+}
+
+func (c *smsClient) SendMessage(ctx context.Context, in *SendSmsRequest, opts ...grpc.CallOption) (*SendSmsReply, error) {
+ out := new(SendSmsReply)
+ err := c.cc.Invoke(ctx, Sms_SendMessage_FullMethodName, in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *smsClient) VerifyCode(ctx context.Context, in *SmsCodeVerifyRequest, opts ...grpc.CallOption) (*SendSmsReply, error) {
+ out := new(SendSmsReply)
+ err := c.cc.Invoke(ctx, Sms_VerifyCode_FullMethodName, in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+// SmsServer is the server API for Sms service.
+// All implementations must embed UnimplementedSmsServer
+// for forward compatibility
+type SmsServer interface {
+ // 发送一条短信
+ SendMessage(context.Context, *SendSmsRequest) (*SendSmsReply, error)
+ // 校验短信code
+ VerifyCode(context.Context, *SmsCodeVerifyRequest) (*SendSmsReply, error)
+ mustEmbedUnimplementedSmsServer()
+}
+
+// UnimplementedSmsServer must be embedded to have forward compatible implementations.
+type UnimplementedSmsServer struct {
+}
+
+func (UnimplementedSmsServer) SendMessage(context.Context, *SendSmsRequest) (*SendSmsReply, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method SendMessage not implemented")
+}
+func (UnimplementedSmsServer) VerifyCode(context.Context, *SmsCodeVerifyRequest) (*SendSmsReply, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method VerifyCode not implemented")
+}
+func (UnimplementedSmsServer) mustEmbedUnimplementedSmsServer() {}
+
+// UnsafeSmsServer may be embedded to opt out of forward compatibility for this service.
+// Use of this interface is not recommended, as added methods to SmsServer will
+// result in compilation errors.
+type UnsafeSmsServer interface {
+ mustEmbedUnimplementedSmsServer()
+}
+
+func RegisterSmsServer(s grpc.ServiceRegistrar, srv SmsServer) {
+ s.RegisterService(&Sms_ServiceDesc, srv)
+}
+
+func _Sms_SendMessage_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(SendSmsRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(SmsServer).SendMessage(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: Sms_SendMessage_FullMethodName,
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(SmsServer).SendMessage(ctx, req.(*SendSmsRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _Sms_VerifyCode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(SmsCodeVerifyRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(SmsServer).VerifyCode(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: Sms_VerifyCode_FullMethodName,
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(SmsServer).VerifyCode(ctx, req.(*SmsCodeVerifyRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+// Sms_ServiceDesc is the grpc.ServiceDesc for Sms service.
+// It's only intended for direct use with grpc.RegisterService,
+// and not to be introspected or modified (even as a copy)
+var Sms_ServiceDesc = grpc.ServiceDesc{
+ ServiceName: "api.Sms",
+ HandlerType: (*SmsServer)(nil),
+ Methods: []grpc.MethodDesc{
+ {
+ MethodName: "SendMessage",
+ Handler: _Sms_SendMessage_Handler,
+ },
+ {
+ MethodName: "VerifyCode",
+ Handler: _Sms_VerifyCode_Handler,
+ },
+ },
+ Streams: []grpc.StreamDesc{},
+ Metadata: "sms.proto",
+}
diff --git a/initialize/gorm.go b/initialize/gorm.go
new file mode 100644
index 0000000..923c5e7
--- /dev/null
+++ b/initialize/gorm.go
@@ -0,0 +1,110 @@
+package initialize
+
+import (
+ "fmt"
+ "os"
+ "pure/global"
+ "pure/initialize/internal"
+ "pure/model"
+
+ "go.uber.org/zap"
+ "gorm.io/driver/mysql"
+ "gorm.io/gorm"
+)
+
+//@function: Gorm
+//@description: 初始化数据库并产生数据库全局变量
+//@return: *gorm.DB
+
+func Gorm() *gorm.DB {
+ switch global.MG_CONFIG.System.DbType {
+ case "mysql":
+ return GormMysql()
+ default:
+ return GormMysql()
+ }
+}
+
+// MysqlTables
+//@function: MysqlTables
+//@description: 注册数据库表专用
+//@param: db *gorm.DB
+
+func MysqlTables(db *gorm.DB) {
+ err := db.AutoMigrate(
+ model.Account{},
+ model.Address{},
+ model.Bill{},
+ model.Order{},
+ model.OrderAddress{},
+ model.TbGoods{},
+ model.TbGoodsSpecs{},
+ model.Wallet{},
+ model.JwtBlacklist{},
+ //model.SysDictionary{},
+ //model.SysDictionaryDetail{},
+ //model.ExaFileUploadAndDownload{},
+ //model.ExaFile{},
+ //model.ExaFileChunk{},
+ //model.ExaCustomer{},
+ //model.ExaSimpleUploader{},
+
+ // Code generated by pure Begin; DO NOT EDIT.
+ // Code generated by pure End; DO NOT EDIT.
+ model.Mission{},
+ model.MissionClaimAddress{},
+ model.CollectionMission{},
+ model.CollectionGoods{},
+ model.PaypalWebhook{},
+ model.MissionClaimWorks{},
+ model.MissionClaimOrder{},
+ model.MissionClaimOrderGoods{},
+ model.Internationalization{},
+ model.MissionClaim{},
+ model.MissionClaimVideo{},
+ model.PlatformAuth{},
+ model.SysMissionReward{}, //平台任务奖励
+ model.DtStatisticOrder{},
+ model.Withdrawal{}, // 提现
+ model.User{},
+ model.Notify{},
+ model.Version{},
+ )
+ if err != nil {
+ global.MG_LOG.Error("register table failed", zap.Any("err", err))
+ os.Exit(0)
+ }
+
+ global.MG_LOG.Info("register table success")
+}
+
+// @function: GormMysql
+// @description: 初始化Mysql数据库
+// @return: *gorm.DB
+func GormMysql() *gorm.DB {
+ m := global.MG_CONFIG.Mysql
+ if m.Dbname == "" {
+ return nil
+ }
+ dsn := m.Username + ":" + m.Password + "@tcp(" + m.Path + ")/" + m.Dbname + "?" + m.Config
+ mysqlConfig := mysql.Config{
+ DSN: dsn, // DSN data source name
+ DefaultStringSize: 191, // string 类型字段的默认长度
+ DisableDatetimePrecision: true, // 禁用 datetime 精度,MySQL 5.6 之前的数据库不支持
+ DontSupportRenameIndex: true, // 重命名索引时采用删除并新建的方式,MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引
+ DontSupportRenameColumn: true, // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列
+ SkipInitializeWithVersion: false, // 根据版本自动配置
+ }
+ fmt.Println(m.LogMode)
+ if db, err := gorm.Open(mysql.New(mysqlConfig), internal.Gorm.Config()); err != nil {
+ //global.GVA_LOG.Error("MySQL启动异常", zap.Any("err", err))
+ //os.Exit(0)
+ //return nil
+ return nil
+ } else {
+ sqlDB, _ := db.DB()
+ sqlDB.SetMaxIdleConns(m.MaxIdleConns)
+ sqlDB.SetMaxOpenConns(m.MaxOpenConns)
+ return db
+ }
+}
diff --git a/initialize/grpc.go b/initialize/grpc.go
new file mode 100644
index 0000000..6764cbc
--- /dev/null
+++ b/initialize/grpc.go
@@ -0,0 +1,89 @@
+package initialize
+
+import (
+ "context"
+ "fmt"
+ "pure/global"
+ "pure/initialize/api"
+ "time"
+
+ "github.com/go-kratos/kratos/contrib/registry/nacos/v2"
+ "github.com/go-kratos/kratos/v2/middleware/recovery"
+ "github.com/go-kratos/kratos/v2/transport/grpc"
+ "github.com/nacos-group/nacos-sdk-go/clients"
+ "github.com/nacos-group/nacos-sdk-go/common/constant"
+ "github.com/nacos-group/nacos-sdk-go/vo"
+)
+
+func PaymentClient() api.GreeterClient {
+ sc := []constant.ServerConfig{
+ *constant.NewServerConfig("72535c70-8d6d-400f-9893-4bb3e634f682.nacos.cn-north-4.cse.myhuaweicloud.com", 8848),
+ }
+ cc := constant.ClientConfig{
+ NamespaceId: "dev",
+ TimeoutMs: 5000,
+ Username: "nacos",
+ Password: "nacos",
+ }
+ client, err := clients.NewNamingClient(
+ vo.NacosClientParam{
+ ServerConfigs: sc,
+ ClientConfig: &cc,
+ },
+ )
+ if err != nil {
+ fmt.Println(err)
+ panic(err)
+ }
+
+ r := nacos.New(client)
+ conn, err := grpc.DialInsecure(
+ context.Background(),
+ grpc.WithEndpoint("discovery:///bkb.payment.grpc"),
+ grpc.WithDiscovery(r),
+ grpc.WithMiddleware(
+ recovery.Recovery()))
+ if err != nil {
+ panic(err)
+ }
+ return api.NewGreeterClient(conn)
+}
+
+func InitNacosClient() {
+ sc := []constant.ServerConfig{
+ *constant.NewServerConfig("72535c70-8d6d-400f-9893-4bb3e634f682.nacos.cn-north-4.cse.myhuaweicloud.com", 8848),
+ }
+ cc := constant.ClientConfig{
+ NamespaceId: "dev",
+ TimeoutMs: 5000,
+ Username: "nacos",
+ Password: "nacos",
+ }
+ func() {
+ client, err := clients.NewNamingClient(
+ vo.NacosClientParam{
+ ServerConfigs: sc,
+ ClientConfig: &cc,
+ },
+ )
+ if err != nil {
+ fmt.Println(err)
+ panic(err)
+ }
+ r := nacos.New(client)
+ ctx, cel := context.WithTimeout(context.Background(), time.Second*5)
+ defer cel()
+ conn, err := grpc.DialInsecure(
+ ctx,
+ grpc.WithEndpoint("discovery:///bkb.notify.grpc"),
+ grpc.WithDiscovery(r),
+ grpc.WithMiddleware(
+ recovery.Recovery()))
+ if err != nil {
+ panic(err)
+ }
+ global.EMAIL_CLIENT = api.NewEmailClient(conn)
+ global.SMS_CLIENT = api.NewSmsClient(conn)
+ }()
+
+}
diff --git a/initialize/internal/gorm.go b/initialize/internal/gorm.go
new file mode 100644
index 0000000..4941696
--- /dev/null
+++ b/initialize/internal/gorm.go
@@ -0,0 +1,52 @@
+package internal
+
+import (
+ "log"
+ "os"
+ "pure/global"
+ "time"
+
+ "gorm.io/gorm"
+ "gorm.io/gorm/logger"
+)
+
+type DBBASE interface {
+ GetLogMode() string
+}
+
+var Gorm = new(_gorm)
+
+type _gorm struct{}
+
+// Config gorm 自定义配置
+// Author [SliverHorn](https://github.com/SliverHorn)
+func (g *_gorm) Config() *gorm.Config {
+ config := &gorm.Config{DisableForeignKeyConstraintWhenMigrating: true}
+ _default := logger.New(NewWriter(log.New(os.Stdout, "\r\n", log.LstdFlags)), logger.Config{
+ SlowThreshold: 200 * time.Millisecond,
+ LogLevel: logger.Warn,
+ Colorful: true,
+ })
+ var logMode DBBASE
+ switch global.MG_CONFIG.System.DbType {
+ case "mysql":
+ logMode = &global.MG_CONFIG.Mysql
+ break
+ default:
+ logMode = &global.MG_CONFIG.Mysql
+ }
+
+ switch logMode.GetLogMode() {
+ case "silent", "Silent":
+ config.Logger = _default.LogMode(logger.Silent)
+ case "error", "Error":
+ config.Logger = _default.LogMode(logger.Error)
+ case "warn", "Warn":
+ config.Logger = _default.LogMode(logger.Warn)
+ case "info", "Info":
+ config.Logger = _default.LogMode(logger.Info)
+ default:
+ config.Logger = _default.LogMode(logger.Info)
+ }
+ return config
+}
diff --git a/initialize/internal/logger.go b/initialize/internal/logger.go
new file mode 100644
index 0000000..0fc8723
--- /dev/null
+++ b/initialize/internal/logger.go
@@ -0,0 +1,33 @@
+package internal
+
+import (
+ "fmt"
+ "pure/global"
+
+ "gorm.io/gorm/logger"
+)
+
+type writer struct {
+ logger.Writer
+}
+
+// NewWriter writer 构造函数
+// Author [SliverHorn](https://github.com/SliverHorn)
+func NewWriter(w logger.Writer) *writer {
+ return &writer{Writer: w}
+}
+
+// Printf 格式化打印日志
+// Author [SliverHorn](https://github.com/SliverHorn)
+func (w *writer) Printf(message string, data ...interface{}) {
+ var logZap bool
+ switch global.MG_CONFIG.System.DbType {
+ case "mysql":
+ logZap = global.MG_CONFIG.Mysql.LogZap
+ }
+ if logZap {
+ global.MG_LOG.Info(fmt.Sprintf(message+"\n", data...))
+ } else {
+ w.Writer.Printf(message, data...)
+ }
+}
diff --git a/initialize/international.go b/initialize/international.go
new file mode 100644
index 0000000..5774797
--- /dev/null
+++ b/initialize/international.go
@@ -0,0 +1,24 @@
+package initialize
+
+import (
+ "fmt"
+ "pure/global"
+ "pure/model"
+)
+
+func InternationalizationInit() interface{} {
+ var (
+ err error
+ data []model.Internationalization
+ language = make(map[string]model.Internationalization)
+ )
+ err = global.MG_DB.Model(&model.Internationalization{}).Find(&data).Error
+ if err != nil {
+ fmt.Println("多语言模块加载失败")
+ return nil
+ }
+ for v := range data {
+ language[data[v].Ch] = data[v]
+ }
+ return language
+}
diff --git a/initialize/redis.go b/initialize/redis.go
new file mode 100644
index 0000000..6aa44df
--- /dev/null
+++ b/initialize/redis.go
@@ -0,0 +1,44 @@
+package initialize
+
+import (
+ "github.com/go-redis/redis"
+ "go.uber.org/zap"
+ "pure/global"
+ "strconv"
+ "strings"
+)
+
+func Redis() {
+ redisCfg := global.MG_CONFIG.Redis
+ client := redis.NewClient(&redis.Options{
+ Addr: redisCfg.Addr,
+ Password: redisCfg.Password, // no password set
+ DB: redisCfg.DB, // use default DB
+ })
+ pong, err := client.Ping().Result()
+ if err != nil {
+ global.MG_LOG.Error("redis connect ping failed, err:", zap.Any("err", err))
+ } else {
+ global.MG_LOG.Info("redis connect ping response:", zap.String("pong", pong))
+ global.MG_REDIS = client
+ }
+ //开启过期消息订阅
+ go PubsunChannel(client)
+}
+
+func PubsunChannel(client *redis.Client) {
+ pubsub := client.Subscribe("__keyevent@" + strconv.Itoa(global.MG_CONFIG.Redis.DB) + "__:expired")
+ //fmt.Println("__keyevent@" + strconv.Itoa(global.MG_CONFIG.Redis.DB) + "__:expired")
+ defer pubsub.Close()
+ for msg := range pubsub.Channel() {
+ key := strings.Split(msg.Payload, "-")
+ if len(key) > 1 {
+ switch key[0] {
+ case "test":
+ println(msg.Payload)
+ default:
+ //默认处理
+ }
+ }
+ }
+}
diff --git a/initialize/router.go b/initialize/router.go
new file mode 100644
index 0000000..16f146e
--- /dev/null
+++ b/initialize/router.go
@@ -0,0 +1,53 @@
+package initialize
+
+import (
+ "net/http"
+
+ _ "pure/docs"
+ "pure/global"
+ "pure/middleware"
+ globalr "pure/router/global"
+ "pure/router/influencer"
+
+ "github.com/gin-gonic/gin"
+ swaggerFiles "github.com/swaggo/files"
+ ginSwagger "github.com/swaggo/gin-swagger"
+ //"github.com/swaggo/gin-swagger/swaggerFiles"
+)
+
+// 初始化总路由
+
+func Routers() *gin.Engine {
+ Router := gin.Default()
+ Router.StaticFS(global.MG_CONFIG.Local.Path, http.Dir(global.MG_CONFIG.Local.Path)) // 为用户头像和文件提供静态地址
+ // Router.Use(middleware.LoadTls()) // 打开就能玩https了
+ // 跨域
+ Router.Use(middleware.Cors()) // 如需跨域可以打开
+ Router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
+
+ Router.Use(middleware.ParamsMiddleware())
+ //网红端
+ PrivateGroup2 := Router.Group("influencer")
+ PrivateGroup4 := Router.Group("")
+ {
+ influencer.InitInfluencerOtherRouter(PrivateGroup2) // 基础路由
+ }
+ PrivateGroup2.Use(middleware.JWTAuth())
+ //PrivateGroup4.Use(middleware.JWTAuth())
+ {
+ influencer.InitInfluencerUserRouter(PrivateGroup2) // 用户
+ influencer.InitInfluencerWalletRouter(PrivateGroup2) // 钱包
+ influencer.InitInfluencerMissionRouter(PrivateGroup2) // 任务
+ influencer.InitInfluencerGoodsRouter(PrivateGroup2) // 商品
+ influencer.InitInfluencerOrderRouter(PrivateGroup2) // 订单
+ globalr.InitGlobalRouter(PrivateGroup2) // 地址
+ globalr.InitDictRouter(PrivateGroup4) // 字典
+ influencer.InitBanner(PrivateGroup2) //banner
+ }
+ PrivateGroup3 := Router.Group("")
+ PrivateGroup3.Use(middleware.JWTAuth2())
+ {
+ globalr.InitGlobalRouter(PrivateGroup3) // 用户
+ }
+ return Router
+}
diff --git a/initialize/timer.go b/initialize/timer.go
new file mode 100644
index 0000000..4b99ff2
--- /dev/null
+++ b/initialize/timer.go
@@ -0,0 +1,23 @@
+package initialize
+
+import (
+ "fmt"
+ "pure/config"
+ "pure/global"
+ "pure/utils"
+)
+
+func Timer() {
+ if global.MG_CONFIG.Timer.Start {
+ for _, detail := range global.MG_CONFIG.Timer.Detail {
+ go func(detail config.Detail) {
+ global.MG_Timer.AddTaskByFunc("ClearDB", global.MG_CONFIG.Timer.Spec, func() {
+ err := utils.ClearTable(global.MG_DB, detail.TableName, detail.CompareField, detail.Interval)
+ if err != nil {
+ fmt.Println("timer error:", err)
+ }
+ })
+ }(detail)
+ }
+ }
+}
diff --git a/initialize/validator.go b/initialize/validator.go
new file mode 100644
index 0000000..d9f80d9
--- /dev/null
+++ b/initialize/validator.go
@@ -0,0 +1,22 @@
+package initialize
+
+import "pure/utils"
+
+func init() {
+ _ = utils.RegisterRule("PageVerify",
+ utils.Rules{
+ "Page": {utils.NotEmpty()},
+ "PageSize": {utils.NotEmpty()},
+ },
+ )
+ _ = utils.RegisterRule("IdVerify",
+ utils.Rules{
+ "Id": {utils.NotEmpty()},
+ },
+ )
+ _ = utils.RegisterRule("AuthorityIdVerify",
+ utils.Rules{
+ "AuthorityId": {utils.NotEmpty()},
+ },
+ )
+}
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..c7a25c5
--- /dev/null
+++ b/main.go
@@ -0,0 +1,36 @@
+package main
+
+import (
+ "pure/core"
+ "pure/global"
+ "pure/initialize"
+)
+
+//go:generate go env -w GO111MODULE=on
+//go:generate go env -w GOPROXY=https://goproxy.cn,direct
+//go:generate go mod tidy
+//go:generate go mod download
+
+// @title Swagger Example API
+// @version 0.0.1
+// @description 接口文档
+// @securityDefinitions.apikey ApiKeyAuth
+// @in header
+// @name x-token
+// @BasePath /
+func main() {
+ global.MG_VP = core.Viper() // 初始化Viper
+ global.MG_LOG = core.Zap() // 初始化zap日志库
+ global.MG_DB = initialize.Gorm() // gorm连接数据库
+ // initialize.Minio()
+ initialize.InitNacosClient() //初始化微服务连接
+ initialize.Timer()
+ global.MG_Language = initialize.InternationalizationInit()
+ if global.MG_DB != nil {
+ initialize.MysqlTables(global.MG_DB) //初始化表
+ // 程序结束前关闭数据库链接
+ db, _ := global.MG_DB.DB()
+ defer db.Close()
+ }
+ core.RunWindowsServer()
+}
diff --git a/middleware/Ijwt.go b/middleware/Ijwt.go
new file mode 100644
index 0000000..70d4eb6
--- /dev/null
+++ b/middleware/Ijwt.go
@@ -0,0 +1,132 @@
+package middleware
+
+import (
+ "strconv"
+ "time"
+
+ "pure/global"
+ "pure/model"
+ "pure/model/request"
+ "pure/model/response"
+ "pure/service"
+
+ "github.com/dgrijalva/jwt-go"
+ "github.com/gin-gonic/gin"
+ "go.uber.org/zap"
+)
+
+func InfluencerJWTAuth() gin.HandlerFunc {
+ return func(c *gin.Context) {
+ // 我们这里jwt鉴权取头部信息 x-token 登录时回返回token信息 这里前端需要把token存储到cookie或者本地localStorage中 不过需要跟后端协商过期时间 可以约定刷新令牌或者重新登录
+
+ token := c.Request.Header.Get("x-token")
+ if token == "" {
+ response.FailWithDetailed(gin.H{"reload": true}, "未登录或非法访问", c)
+ c.Abort()
+ return
+ }
+ if service.IsBlacklist(token) {
+ response.FailWithDetailed(gin.H{"reload": true}, "您的帐户异地登陆或令牌失效", c)
+ c.Abort()
+ return
+ }
+ j := NewInfluencerJWT()
+ // parseToken 解析token包含的信息
+ claims, err := j.ParseInfluencerToken(token)
+ if err != nil {
+ if err == TokenExpired {
+ response.FailWithDetailed(gin.H{"reload": true}, "授权已过期", c)
+ c.Abort()
+ return
+ }
+ response.FailWithDetailed(gin.H{"reload": true}, err.Error(), c)
+ c.Abort()
+ return
+ }
+ // if err, _ = service.FindUserByUuid(claims.UUID.String()); err != nil {
+ // _ = service.JsonInBlacklist(model.JwtBlacklist{Jwt: token})
+ // response.FailWithDetailed(gin.H{"reload": true}, err.Error(), c)
+ // c.Abort()
+ // }
+ if claims.ExpiresAt-time.Now().Unix() < claims.BufferTime {
+ claims.ExpiresAt = time.Now().Unix() + global.MG_CONFIG.JWT.ExpiresTime
+ newToken, _ := j.CreateInfluencerToken(*claims)
+ newClaims, _ := j.ParseInfluencerToken(newToken)
+ c.Header("new-token", newToken)
+ c.Header("new-expires-at", strconv.FormatInt(newClaims.ExpiresAt, 10))
+ if global.MG_CONFIG.System.UseMultipoint {
+ err, RedisJwtToken := service.GetRedisJWT(newClaims.Username)
+ if err != nil {
+ global.MG_LOG.Error("get redis jwt failed", zap.Any("err", err))
+ } else { // 当之前的取成功时才进行拉黑操作
+ _ = service.JsonInBlacklist(model.JwtBlacklist{Jwt: RedisJwtToken})
+ }
+ // 无论如何都要记录当前的活跃状态
+ _ = service.SetRedisJWT(newToken, newClaims.Username)
+ }
+ }
+ c.Set("claims", claims)
+ c.Next()
+ }
+}
+
+func NewInfluencerJWT() *JWT {
+ return &JWT{
+ []byte(global.MG_CONFIG.JWT.SigningKey),
+ }
+}
+
+// 创建一个token
+func (j *JWT) CreateInfluencerToken(claims request.UserClaims) (string, error) {
+ token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
+ return token.SignedString(j.SigningKey)
+}
+
+// 解析 token
+func (j *JWT) ParseInfluencerToken(tokenString string) (*request.UserClaims, error) {
+ token, err := jwt.ParseWithClaims(tokenString, &request.UserClaims{}, func(token *jwt.Token) (i interface{}, e error) {
+ return j.SigningKey, nil
+ })
+ if err != nil {
+ if ve, ok := err.(*jwt.ValidationError); ok {
+ if ve.Errors&jwt.ValidationErrorMalformed != 0 {
+ return nil, TokenMalformed
+ } else if ve.Errors&jwt.ValidationErrorExpired != 0 {
+ // Token is expired
+ return nil, TokenExpired
+ } else if ve.Errors&jwt.ValidationErrorNotValidYet != 0 {
+ return nil, TokenNotValidYet
+ } else {
+ return nil, TokenInvalid
+ }
+ }
+ }
+ if token != nil {
+ if claims, ok := token.Claims.(*request.UserClaims); ok && token.Valid {
+ return claims, nil
+ }
+ return nil, TokenInvalid
+
+ } else {
+ return nil, TokenInvalid
+ }
+}
+
+// 更新token
+//func (j *JWT) RefreshToken(tokenString string) (string, error) {
+// jwt.TimeFunc = func() time.Time {
+// return time.Unix(0, 0)
+// }
+// token, err := jwt.ParseWithClaims(tokenString, &request.CustomClaims{}, func(token *jwt.Token) (interface{}, error) {
+// return j.SigningKey, nil
+// })
+// if err != nil {
+// return "", err
+// }
+// if claims, ok := token.Claims.(*request.CustomClaims); ok && token.Valid {
+// jwt.TimeFunc = time.Now
+// claims.StandardClaims.ExpiresAt = time.Now().Unix() + 60*60*24*7
+// return j.CreateToken(*claims)
+// }
+// return "", TokenInvalid
+//}
diff --git a/middleware/cors.go b/middleware/cors.go
new file mode 100644
index 0000000..4f262bc
--- /dev/null
+++ b/middleware/cors.go
@@ -0,0 +1,26 @@
+package middleware
+
+import (
+ "github.com/gin-gonic/gin"
+ "net/http"
+)
+
+// 处理跨域请求,支持options访问
+func Cors() gin.HandlerFunc {
+ return func(c *gin.Context) {
+ method := c.Request.Method
+ origin := c.Request.Header.Get("Origin")
+ c.Header("Access-Control-Allow-Origin", origin)
+ c.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization, Token,X-Token,X-User-Id,X-Requested-With,X_Requested_With")
+ c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS,DELETE,PUT")
+ c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type")
+ c.Header("Access-Control-Allow-Credentials", "true")
+
+ // 放行所有OPTIONS方法
+ if method == "OPTIONS" {
+ c.AbortWithStatus(http.StatusNoContent)
+ }
+ // 处理请求
+ c.Next()
+ }
+}
diff --git a/middleware/error.go b/middleware/error.go
new file mode 100644
index 0000000..31feb1f
--- /dev/null
+++ b/middleware/error.go
@@ -0,0 +1,61 @@
+package middleware
+
+import (
+ "net"
+ "net/http"
+ "net/http/httputil"
+ "os"
+ "pure/global"
+ "runtime/debug"
+ "strings"
+
+ "github.com/gin-gonic/gin"
+ "go.uber.org/zap"
+)
+
+// GinRecovery recover掉项目可能出现的panic,并使用zap记录相关日志
+func GinRecovery(stack bool) gin.HandlerFunc {
+ return func(c *gin.Context) {
+ defer func() {
+ if err := recover(); err != nil {
+ // Check for a broken connection, as it is not really a
+ // condition that warrants a panic stack trace.
+ var brokenPipe bool
+ if ne, ok := err.(*net.OpError); ok {
+ if se, ok := ne.Err.(*os.SyscallError); ok {
+ if strings.Contains(strings.ToLower(se.Error()), "broken pipe") || strings.Contains(strings.ToLower(se.Error()), "connection reset by peer") {
+ brokenPipe = true
+ }
+ }
+ }
+
+ httpRequest, _ := httputil.DumpRequest(c.Request, false)
+ if brokenPipe {
+ global.MG_LOG.Error(c.Request.URL.Path,
+ zap.Any("error", err),
+ zap.String("request", string(httpRequest)),
+ )
+ // If the connection is dead, we can't write a status to it.
+ _ = c.Error(err.(error)) // nolint: errcheck
+ c.Abort()
+ return
+ }
+
+ if stack {
+ global.MG_LOG.Error("[Recovery from panic]",
+ zap.Any("error", err),
+ zap.String("request", string(httpRequest)),
+ zap.String("stack", string(debug.Stack())),
+ )
+ } else {
+ global.MG_LOG.Error("[Recovery from panic]",
+ zap.Any("error", err),
+ zap.String("request", string(httpRequest)),
+ )
+ }
+ c.AbortWithStatus(http.StatusInternalServerError)
+ }
+ }()
+ c.Next()
+ }
+}
diff --git a/middleware/jwt.go b/middleware/jwt.go
new file mode 100644
index 0000000..9319a69
--- /dev/null
+++ b/middleware/jwt.go
@@ -0,0 +1,203 @@
+package middleware
+
+import (
+ "errors"
+ "pure/global"
+ "pure/model"
+ "pure/model/request"
+ "pure/model/response"
+ "pure/service"
+ "strconv"
+ "time"
+
+ "github.com/dgrijalva/jwt-go"
+ "github.com/gin-gonic/gin"
+ "go.uber.org/zap"
+)
+
+func JWTAuth() gin.HandlerFunc {
+ return func(c *gin.Context) {
+ // 我们这里jwt鉴权取头部信息 x-token 登录时回返回token信息 这里前端需要把token存储到cookie或者本地localStorage中 不过需要跟后端协商过期时间 可以约定刷新令牌或者重新登录
+ token := c.Request.Header.Get("x-token")
+ if token == "" {
+ response.FailWithDetailed(gin.H{"reload": true}, "未登录或非法访问", c)
+ c.Abort()
+ return
+ }
+ if service.IsBlacklist(token) {
+ response.FailWithDetailed(gin.H{"reload": true}, "您的帐户异地登陆或令牌失效", c)
+ c.Abort()
+ return
+ }
+ j := NewJWT()
+ // parseToken 解析token包含的信息
+ claims, err := j.ParseToken(token)
+ if err != nil {
+ if err == TokenExpired {
+ response.FailWithDetailed(gin.H{"reload": true}, "授权已过期", c)
+ c.Abort()
+ return
+ }
+ response.FailWithDetailed(gin.H{"reload": true}, err.Error(), c)
+ c.Abort()
+ return
+ }
+ // if err, _ = service.FindUserByUuid(claims.UUID.String()); err != nil {
+ // _ = service.JsonInBlacklist(model.JwtBlacklist{Jwt: token})
+ // response.FailWithDetailed(gin.H{"reload": true}, err.Error(), c)
+ // c.Abort()
+ // }
+ if claims.ExpiresAt-time.Now().Unix() < claims.BufferTime {
+ claims.ExpiresAt = time.Now().Unix() + global.MG_CONFIG.JWT.ExpiresTime
+ newToken, _ := j.CreateToken(*claims)
+ newClaims, _ := j.ParseToken(newToken)
+ c.Header("new-token", newToken)
+ c.Header("new-expires-at", strconv.FormatInt(newClaims.ExpiresAt, 10))
+ if global.MG_CONFIG.System.UseMultipoint {
+ err, RedisJwtToken := service.GetRedisJWT(newClaims.Username)
+ if err != nil {
+ global.MG_LOG.Error("get redis jwt failed", zap.Any("err", err))
+ } else { // 当之前的取成功时才进行拉黑操作
+ _ = service.JsonInBlacklist(model.JwtBlacklist{Jwt: RedisJwtToken})
+ }
+ // 无论如何都要记录当前的活跃状态
+ _ = service.SetRedisJWT(newToken, newClaims.Username)
+ }
+ }
+ c.Set("claims", claims)
+ c.Next()
+ }
+}
+
+func JWTAuth2() gin.HandlerFunc {
+ return func(c *gin.Context) {
+ // 我们这里jwt鉴权取头部信息 x-token 登录时回返回token信息 这里前端需要把token存储到cookie或者本地localStorage中 不过需要跟后端协商过期时间 可以约定刷新令牌或者重新登录
+ token := c.Request.Header.Get("x-token")
+ if token == "" {
+ response.FailWithDetailed(gin.H{"reload": true}, "未登录或非法访问", c)
+ c.Abort()
+ return
+ }
+ if service.IsBlacklist(token) {
+ response.FailWithDetailed(gin.H{"reload": true}, "您的帐户异地登陆或令牌失效", c)
+ c.Abort()
+ return
+ }
+
+ j := NewJWT()
+ // parseToken 解析token包含的信息
+ claims, err := j.ParseToken(token)
+ if err != nil {
+ j = NewInfluencerJWT()
+ claims, err = j.ParseInfluencerToken(token)
+ if err != nil {
+ if err == TokenExpired {
+ response.FailWithDetailed(gin.H{"reload": true}, "授权已过期", c)
+ c.Abort()
+ return
+ }
+ response.FailWithDetailed(gin.H{"reload": true}, err.Error(), c)
+ c.Abort()
+ return
+ }
+ }
+ // if err, _ = service.FindUserByUuid(claims.UUID.String()); err != nil {
+ // _ = service.JsonInBlacklist(model.JwtBlacklist{Jwt: token})
+ // response.FailWithDetailed(gin.H{"reload": true}, err.Error(), c)
+ // c.Abort()
+ // }
+ if claims.ExpiresAt-time.Now().Unix() < claims.BufferTime {
+ claims.ExpiresAt = time.Now().Unix() + global.MG_CONFIG.JWT.ExpiresTime
+ newToken, _ := j.CreateToken(*claims)
+ newClaims, _ := j.ParseToken(newToken)
+ c.Header("new-token", newToken)
+ c.Header("new-expires-at", strconv.FormatInt(newClaims.ExpiresAt, 10))
+ if global.MG_CONFIG.System.UseMultipoint {
+ err, RedisJwtToken := service.GetRedisJWT(newClaims.Username)
+ if err != nil {
+ global.MG_LOG.Error("get redis jwt failed", zap.Any("err", err))
+ } else { // 当之前的取成功时才进行拉黑操作
+ _ = service.JsonInBlacklist(model.JwtBlacklist{Jwt: RedisJwtToken})
+ }
+ // 无论如何都要记录当前的活跃状态
+ _ = service.SetRedisJWT(newToken, newClaims.Username)
+ }
+ }
+ c.Set("claims", claims)
+ c.Next()
+ }
+}
+
+type JWT struct {
+ SigningKey []byte
+}
+
+var (
+ TokenExpired = errors.New("Token is expired")
+ TokenNotValidYet = errors.New("Token not active yet")
+ TokenMalformed = errors.New("That's not even a token")
+ TokenInvalid = errors.New("Couldn't handle this token:")
+)
+
+func NewJWT() *JWT {
+ return &JWT{
+ []byte(global.MG_CONFIG.JWT.SigningKey),
+ }
+}
+
+// 创建一个token
+func (j *JWT) CreateToken(claims request.UserClaims) (string, error) {
+ token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
+ return token.SignedString(j.SigningKey)
+}
+
+// 解析 token
+func (j *JWT) ParseToken(tokenString string) (*request.UserClaims, error) {
+ token, err := jwt.ParseWithClaims(tokenString, &request.UserClaims{}, func(token *jwt.Token) (i interface{}, e error) {
+ return j.SigningKey, nil
+ })
+ if err != nil {
+ if ve, ok := err.(*jwt.ValidationError); ok {
+ if ve.Errors&jwt.ValidationErrorMalformed != 0 {
+ return nil, TokenMalformed
+ } else if ve.Errors&jwt.ValidationErrorExpired != 0 {
+ // Token is expired
+ return nil, TokenExpired
+ } else if ve.Errors&jwt.ValidationErrorNotValidYet != 0 {
+ return nil, TokenNotValidYet
+ } else {
+ return nil, TokenInvalid
+ }
+ }
+ }
+ if token != nil {
+ if claims, ok := token.Claims.(*request.UserClaims); ok && token.Valid {
+ return claims, nil
+ }
+ return nil, TokenInvalid
+
+ } else {
+ return nil, TokenInvalid
+
+ }
+
+}
+
+// 更新token
+//func (j *JWT) RefreshToken(tokenString string) (string, error) {
+// jwt.TimeFunc = func() time.Time {
+// return time.Unix(0, 0)
+// }
+// token, err := jwt.ParseWithClaims(tokenString, &request.CustomClaims{}, func(token *jwt.Token) (interface{}, error) {
+// return j.SigningKey, nil
+// })
+// if err != nil {
+// return "", err
+// }
+// if claims, ok := token.Claims.(*request.CustomClaims); ok && token.Valid {
+// jwt.TimeFunc = time.Now
+// claims.StandardClaims.ExpiresAt = time.Now().Unix() + 60*60*24*7
+// return j.CreateToken(*claims)
+// }
+// return "", TokenInvalid
+//}
diff --git a/middleware/loadtls.go b/middleware/loadtls.go
new file mode 100644
index 0000000..69efe95
--- /dev/null
+++ b/middleware/loadtls.go
@@ -0,0 +1,26 @@
+package middleware
+
+import (
+ "fmt"
+ "github.com/gin-gonic/gin"
+ "github.com/unrolled/secure"
+)
+
+// 用https把这个中间件在router里面use一下就好
+
+func LoadTls() gin.HandlerFunc {
+ return func(c *gin.Context) {
+ middleware := secure.New(secure.Options{
+ SSLRedirect: true,
+ SSLHost: "localhost:443",
+ })
+ err := middleware.Process(c.Writer, c.Request)
+ if err != nil {
+ // 如果出现错误,请不要继续
+ fmt.Println(err)
+ return
+ }
+ // 继续往下处理
+ c.Next()
+ }
+}
diff --git a/middleware/need_init.go b/middleware/need_init.go
new file mode 100644
index 0000000..74da6e5
--- /dev/null
+++ b/middleware/need_init.go
@@ -0,0 +1,23 @@
+package middleware
+
+import (
+ "pure/global"
+ "pure/model/response"
+
+ "github.com/gin-gonic/gin"
+)
+
+// 处理跨域请求,支持options访问
+func NeedInit() gin.HandlerFunc {
+ return func(c *gin.Context) {
+ if global.MG_DB == nil {
+ response.OkWithDetailed(gin.H{
+ "needInit": true,
+ }, "前往初始化数据库", c)
+ c.Abort()
+ } else {
+ c.Next()
+ }
+ // 处理请求
+ }
+}
diff --git a/middleware/params.go b/middleware/params.go
new file mode 100644
index 0000000..4402c0c
--- /dev/null
+++ b/middleware/params.go
@@ -0,0 +1,50 @@
+package middleware
+
+import (
+ "github.com/gin-gonic/gin"
+ "pure/model"
+ "pure/model/response"
+ "pure/service"
+ "strings"
+)
+
+func ParamsMiddleware() gin.HandlerFunc {
+ return func(c *gin.Context) {
+ var err error
+ defer func() {
+ if err != nil {
+ c.Abort()
+ } else {
+ c.Next()
+ }
+ }()
+ type params struct {
+ Version string `json:"version"`
+ }
+ var p params
+ if err = c.ShouldBindHeader(&p); err != nil {
+ response.FailWithMessage("缺少必要参数", c)
+ return
+ }
+ var platform string
+ tmp := strings.ToUpper(c.Request.UserAgent())
+ if strings.Contains(tmp, "IPHONE") || strings.Contains(tmp, "IOS") { //
+ platform = "2"
+ } else {
+ platform = "1"
+ }
+ c.Set("platform", platform)
+ if p.Version != "" {
+ //校验版本号可用性
+ var version model.VersionV
+ version, err = service.GetVersion(platform, p.Version)
+ if err != nil {
+ response.FailWithMessage("版本号不可取", c)
+ return
+ } else {
+ c.Set("version", version.Version)
+ c.Set("version_status", version.Status)
+ }
+ }
+ }
+}
diff --git a/model/account.go b/model/account.go
new file mode 100644
index 0000000..522b661
--- /dev/null
+++ b/model/account.go
@@ -0,0 +1,29 @@
+package model
+
+import "pure/global"
+
+type BankCard struct {
+ AccountName string `gorm:"size:50" json:"account_name"` // 户名
+ BankCode string `gorm:"size:50" json:"bank_code"` // 收款行
+ SwiftCode string `gorm:"size:20" json:"swift_code"` // 银行国际代码
+ CardNumber string `gorm:"size:50" json:"card_number"` // 银行卡号
+ Address string `gorm:"size:255" json:"address"` // 收款人地址
+ Country string `gorm:"size:255" json:"country"` // 国家/地区
+ Currency string `gorm:"size:10" json:"currency"` // 币种 USD:美元
+}
+
+type Account struct {
+ global.MG_MODEL
+ Platform string `gorm:"size:50" json:"platform"` //平台 saller(买家端) / customer(客户端) / influencer(网红端)
+ UserID string `gorm:"size:50;index" json:"userID"` //用户id
+ Type int `gorm:"type:int(1)" json:"type"` // 类型 1:paypal 2:银行卡
+ BankCard //
+ IDCard string `gorm:"size:30" json:"idCard"` //
+ Phone string `gorm:"size:20" json:"phone"` //
+ Sort int `gorm:"type:int" json:"sort"` // 排序值
+ IsDefault bool `gorm:"type:tinyint" json:"is_default"` // 是否为默认 0:非默认 1:默认
+}
+
+func (Account) TableName() string {
+ return "account"
+}
diff --git a/model/address.go b/model/address.go
new file mode 100644
index 0000000..8db6a5e
--- /dev/null
+++ b/model/address.go
@@ -0,0 +1,22 @@
+package model
+
+import "pure/global"
+
+type Address struct {
+ global.MG_MODEL
+ UserID string `gorm:"size:255" json:"userId"`
+ FirstName string `gorm:"size:255" json:"firstName"` //first name
+ LastName string `gorm:"size:255" json:"lastName"` //last name
+ Street string `gorm:"size:255" json:"street"` //street
+ Phone string `gorm:"size:20" json:"phone"` //手机号
+ Bldg string `gorm:"size:255" json:"bldg"` //apt,ste,bldg
+ City string `gorm:"size:255" json:"city"` //city
+ State string `gorm:"size:255" json:"state"` //state
+ ZipCode string `gorm:"size:255" json:"zipCode"` //zip code
+ Default int `gorm:"tinyint(1)" json:"default"` //是否默认地址 1-是 2-否
+ Platform string `gorm:"size:50" json:"platform"` //平台 saller(买家端) / customer(客户端) / influencer(网红端)
+}
+
+func (Address) TableName() string {
+ return "address"
+}
diff --git a/model/application.go b/model/application.go
new file mode 100755
index 0000000..b110946
--- /dev/null
+++ b/model/application.go
@@ -0,0 +1,21 @@
+// 自动生成模板Application
+package model
+
+import "pure/global"
+
+// 如果含有time.Time 请自行import time包
+type Application struct {
+ global.MG_MODEL
+ Owner string `gorm:"size:50;comment:用户所属" json:"owner" ` // 用户所属
+ Name string `gorm:"size:50;comment:应用名称" json:"name" ` // 应用名称
+ Appid string `gorm:"size:50;comment:应用ID" json:"appid" ` // 应用ID
+ Logo string `gorm:"size:255;comment:应用logo" json:"logo" ` // 应用logo
+ Organization string `gorm:"size:50;comment:组织" json:"organization" ` // 组织
+ Provider string `gorm:"type:text;comment:提供者" json:"provider" ` // 提供者
+ ClientID string `gorm:"size:50;comment:客户端ID" json:"clientID" ` // 客户端ID
+ ClientSecret string `gorm:"size:50;comment:客户端密钥" json:"clientSecret" ` // 客户端密钥
+}
+
+func (Application) TableName() string {
+ return "application"
+}
diff --git a/model/banner.go b/model/banner.go
new file mode 100644
index 0000000..1573f27
--- /dev/null
+++ b/model/banner.go
@@ -0,0 +1,22 @@
+package model
+
+import "pure/global"
+
+type Banner struct {
+ RelationId string `gorm:"size:50" json:"relationId"` //关联项目id
+ RelationType string `gorm:"size:4" json:"relationType"` //关联类型 01-任务
+ Title string `gorm:"size:80" json:"title"` //标题
+ CoverUrl string `gorm:"size:500" json:"coverUrl"` //封面图
+ LinkType string `gorm:"size:2" json:"linkType" form:"linkType"` //链接类型 0:内链 1:外链
+ Link string `gorm:"size:500" json:"link"` //链接地址
+ Type string `gorm:"size:4" json:"type"` //任务-0101 平台奖励页-0102
+ Sort int `gorm:"" json:"sort"` //排序
+ Status string `gorm:"size:4" json:"status"` //状态 0=下架 1=上架
+ CreateBy string `gorm:"size:64" json:"createBy"` //创建人
+ UpdateBy string `gorm:"size:64" json:"updateBy"` //更新人
+ global.MG_MODEL
+}
+
+func (Banner) TableName() string {
+ return "banner"
+}
diff --git a/model/base.go b/model/base.go
new file mode 100644
index 0000000..ceaff03
--- /dev/null
+++ b/model/base.go
@@ -0,0 +1,9 @@
+package model
+
+type Breadcrumb struct { //面包屑
+ ID uint `json:"id"`
+ Name string `json:"name"`
+ Pid uint `json:"pid"` //父id
+ IsLeaf bool `json:"is_leaf"` //是否叶子分类
+ Parent *Breadcrumb `gorm:"-" json:"-"` //上级/下级
+}
diff --git a/model/bill.go b/model/bill.go
new file mode 100644
index 0000000..58333d4
--- /dev/null
+++ b/model/bill.go
@@ -0,0 +1,51 @@
+package model
+
+import (
+ "pure/global"
+)
+
+type Bill struct {
+ global.MG_MODEL
+ UserID string `gorm:"size:50;index" json:"userID"` //用户id
+ Type string `gorm:"size:1;default:1" json:"type"` //类型 1-佣金 2-订单 3-提现 4-平台奖励
+ Title string `gorm:"size:255" json:"title"` // 账单标题
+ ClaimNo string `json:"claim_no"` //领取任务编号
+ Account string `gorm:"size:50" json:"account"` //收款账户(提现)
+ OrderID string `gorm:"size:50" json:"order_id"` //关联订单id
+ WithdID string `gorm:"size:50" json:"withd_id"` //提现id
+ Price float64 `gorm:"type:decimal(10,2)" json:"price"` //金额
+ Balance float64 `gorm:"type:decimal(10,2)" json:"balance"` //余额
+ Amount int `gorm:"type:int(2);default:1" json:"amount"` //数量
+ Status int `gorm:"type:int(1);default:0" json:"status"` //类型 1-支出 2-收入
+ Receipt int `gorm:"type:tinyint(1)" json:"receipt"` //是否已到账 1-是 2-否 3-已取消付款
+ WithdrawalStatus int `gorm:"type:tinyint(1)" json:"withdrawalStatus"` //提现状态 0-提现中 1-提现完成 2-提现失败
+ CheckStatus string `gorm:"size:1" json:"check_status"` // 审核状态 0:待审核 1:审核通过 2:审核未通过
+ Remark string `gorm:"size:50" json:"remark"` //备注
+ Platform string `gorm:"size:50" json:"platform"` //平台 seller(买家端) / customer(客户端) / influencer(网红端)
+ TransactionId string `gorm:"size:50" json:"transaction_id"` // 交易编号
+}
+
+type BillView struct {
+ ID uint `json:"id"` // id
+ OrderID string `json:"order_id"` // 订单编号
+ TransactionId string `json:"transaction_id"` // 交易编号
+}
+
+type BillNotify struct {
+ Title string `json:"title"` // 标题
+ RelationType string `json:"relation_type"` // 关联类型
+ RelationId string `json:"relation_id"` // 关联id
+}
+
+type BillFlowData struct {
+ Status int `json:"status"`
+ Price float64 `json:"price"`
+}
+
+func (Bill) TableName() string {
+ return "bill"
+}
+
+func (BillView) TableName() string {
+ return "bill"
+}
diff --git a/model/bill_fund.go b/model/bill_fund.go
new file mode 100644
index 0000000..012718a
--- /dev/null
+++ b/model/bill_fund.go
@@ -0,0 +1,22 @@
+package model
+
+import "pure/global"
+
+type BillFund struct { // 账户
+ global.MG_MODEL
+ UserID string `gorm:"size:50;index" json:"userID"` // 用户id
+ TransactionType int `gorm:"type:int(1);default:1" json:"transaction_type"` // 类型 1-支出 2-收入
+ TransactionId string `gorm:"size:50;unique" json:"transaction_id"` // 交易编号
+ Title string `gorm:"size:255" json:"title"` // 账单标题
+ Price float64 `gorm:"type:decimal(10,2)" json:"price"` // 价格
+ Balance float64 `gorm:"type:decimal(10,2)" json:"balance"` // 余额
+ Platform string `gorm:"size:20" json:"platform"` // 平台 seller
+ Remark string `gorm:"size:50" json:"remark"` // 备注
+ RelatedId string `gorm:"size:50" json:"related_id"` // 关联id 任务id
+ PayId string `gorm:"size:50" json:"pay_id"` // 支付id
+ Status int `gorm:"size:1" json:"status"` // 状态 1:进行中 2:已完成 3:已失败
+}
+
+func (BillFund) TableName() string {
+ return "bill_fund"
+}
diff --git a/model/collectiom_goods.go b/model/collectiom_goods.go
new file mode 100644
index 0000000..635efe2
--- /dev/null
+++ b/model/collectiom_goods.go
@@ -0,0 +1,13 @@
+package model
+
+import "pure/global"
+
+type CollectionGoods struct { //买家端收藏商品
+ SpuNo string `gorm:"size:60" json:"spu_no"` //spu_no
+ CreateBy string `gorm:"size:64" json:"create_by"` //创建人
+ global.MG_MODEL
+}
+
+func (CollectionGoods) TableName() string {
+ return "collection_goods"
+}
diff --git a/model/collection_mission.go b/model/collection_mission.go
new file mode 100644
index 0000000..7129ca6
--- /dev/null
+++ b/model/collection_mission.go
@@ -0,0 +1,13 @@
+package model
+
+import "pure/global"
+
+type CollectionMission struct { //网红端收藏任务
+ MissionId uint `gorm:"type:int(11)" json:"mission_id"` //任务id
+ CreateBy string `gorm:"size:64" json:"create_by"` //创建人
+ global.MG_MODEL
+}
+
+func (CollectionMission) TableName() string {
+ return "collection_mission"
+}
diff --git a/model/dict.go b/model/dict.go
new file mode 100644
index 0000000..4211a33
--- /dev/null
+++ b/model/dict.go
@@ -0,0 +1,49 @@
+package model
+
+import "pure/global"
+
+const (
+ ReleaseCountryCode = "release_country"
+ ReleaseChannelCode = "release_channel"
+)
+
+type SysDictType struct { //数据字典分类
+ global.BASE_ID
+ PID int `gorm:"" json:"pid"` //父ID
+ Code string `gorm:"UNIQUE;size:20" json:"code"` //编码
+ Name string `gorm:"size:20" json:"name"` //名称
+ Type string `gorm:"size:10" json:"type"` //类型
+ Status string `gorm:"size:1" json:"status"` //可用状态 1正常 0删除
+ Desc string `gorm:"size:30" json:"desc"` //描述
+ IsFixed int `gorm:"type:tinyint(1)" json:"isFixed"` //0默认为不固定 1固定
+ //DynamicField string `gorm:"type:varchar(255)" json:"dynamic_field"` //动态字段编码
+
+ global.TIME_MODEL
+}
+
+type SysDictData struct { //数据字典取值
+ global.BASE_ID
+ TypeCode string `gorm:"size:20" json:"typeCode"` //编码
+ Sort int `gorm:"" json:"sort"` //排序
+ Label string `gorm:"size:30" json:"label"` //标签
+ Value string `gorm:"size:10" json:"value"` //值
+ IsDefault int `gorm:"type:tinyint(1)" json:"isDefault"` //是否为默认值 1是 0否
+ Desc string `gorm:"size:50" json:"desc"` //描述
+ Status string `gorm:"size:1" json:"status"` //可用状态 1正常 0删除
+
+ global.TIME_MODEL
+}
+
+type SysDictDataView struct {
+ Label string `json:"label"` //标签
+ Value string `json:"value"` //值
+ IsDefault int `json:"isDefault"` //是否为默认值 1是 0否
+}
+
+func (SysDictType) TableName() string {
+ return "sys_dict_type"
+}
+
+func (SysDictData) TableName() string {
+ return "sys_dict_data"
+}
diff --git a/model/dt_statistic_order.go b/model/dt_statistic_order.go
new file mode 100644
index 0000000..104d468
--- /dev/null
+++ b/model/dt_statistic_order.go
@@ -0,0 +1,26 @@
+package model
+
+import "pure/global"
+
+type DtStatisticOrder struct { // 数据统计-订单
+ global.MG_MODEL
+ Value string `gorm:"size:20" json:"value"` // 统计对象 eg:20231020(按天统计)
+ Unit string `gorm:"size:10" json:"unit"` // 单位 hour/day/month/all
+ Type int `gorm:"type:tinyint(1)" json:"type"` // 关联类型 0:无 1:用户 2:任务领取id 3:店铺id 4:spu_no
+ RelationId string `gorm:"size:60" json:"relation_id"` // 关联id 用户id/任务领取id/店铺id
+ NewOrderNum int64 `gorm:"type:int" json:"new_order_num"` // 创建订单数
+ NewOrderMoney float64 `gorm:"type:decimal(10,2)" json:"new_order_money"` // 创建订单金额
+ OrderNum int64 `gorm:"type:int" json:"order_num"` // 订单数
+ OrderMoney float64 `gorm:"type:decimal(10,2)" json:"order_money"` // 订单金额
+ OrderDoneNum int64 `gorm:"type:int" json:"order_done_num"` // 订单完成数
+ SaleVolume int64 `gorm:"type:int" json:"sale_volume"` // 销售量
+ SettleReward float64 `gorm:"type:decimal(10,2)" json:"settle_reward"` // 结算佣金
+ TransitReward float64 `gorm:"type:decimal(10,2)" json:"transit_reward"` // 在途佣金
+ OrderCancelNum int64 `gorm:"type:int" json:"order_cancel_num"` // 订单取消数
+ OrderCancelMoney float64 `gorm:"type:decimal(10,2)" json:"order_cancel_money"` // 订单取消金额
+ //Income float64 `gorm:"type:decimal(10,2)" json:"income"` // 收入
+}
+
+func (DtStatisticOrder) TableName() string {
+ return "dt_statistic_order"
+}
diff --git a/model/goods_visit.go b/model/goods_visit.go
new file mode 100644
index 0000000..72cf97f
--- /dev/null
+++ b/model/goods_visit.go
@@ -0,0 +1,14 @@
+package model
+
+import "pure/global"
+
+type GoodsVisit struct {
+ global.MG_MODEL
+ UserID string `gorm:"size:50;index" json:"user_id"` // 用户id
+ GoodsID uint `gorm:"size:50" json:"goods_id"`
+ ClaimNo string `json:"claim_no"` // 领取任务id
+}
+
+func (GoodsVisit) TableName() string {
+ return "goods_visit"
+}
diff --git a/model/internationalization.go b/model/internationalization.go
new file mode 100644
index 0000000..bd943b3
--- /dev/null
+++ b/model/internationalization.go
@@ -0,0 +1,13 @@
+package model
+
+import "pure/global"
+
+type Internationalization struct {
+ global.MG_MODEL
+ Ch string `gorm:"size:200" json:"ch"`
+ En string `gorm:"size:200" json:"en"`
+}
+
+func (Internationalization) TableName() string {
+ return "internationalization"
+}
diff --git a/model/mission.go b/model/mission.go
new file mode 100644
index 0000000..b8d77a8
--- /dev/null
+++ b/model/mission.go
@@ -0,0 +1,98 @@
+package model
+
+import (
+ "time"
+
+ "pure/global"
+)
+
+type Mission struct { // 任务
+ Title string `gorm:"type:mediumtext" json:"title"` // 标题
+ GoodsId uint `gorm:"type:int(11)" json:"goods_id"` // 关联商品
+ GoodsStatus int `gorm:"type:tinyint(1);" json:"goods_status"` // 关联商品状态 1:正常 2:已下架
+ Num int64 `gorm:"type:int(11)" json:"num"` // 商品数量
+ HireType int `gorm:"type:tinyint(1)" json:"hire_type"` // 佣金类型 1:固定佣金 2:比例抽成
+ HireMoney float64 `gorm:"type:decimal(10,2);" json:"hire_money"` // hire_type==1 佣金金额
+ HireRatio float64 `gorm:"type:decimal(10,2);" json:"hire_ratio"` // hire_type==2 抽成比例
+ StartTime *time.Time `gorm:"column:start_time" json:"start_time"` // 任务起始时间
+ EndTime *time.Time `gorm:"column:end_time" json:"end_time"` // 任务结束时间
+ ClaimNum int64 `gorm:"type:int(11)" json:"claim_num"` // 接任务人数
+ CollectionNum int64 `gorm:"type:int(11)" json:"collection_num"` // 收藏人数
+ CreateBy string `gorm:"size:64" json:"create_by"` // 创建人
+ Status int `gorm:"type:tinyint(1);" json:"status"` // 状态 1:未开始 2:进行中 3:已结束
+ ClaimStock int64 `json:"claim_stock"` // 可接任务库存
+ Sample
+ VideoMaterial
+ ClaimDays int `gorm:"type:tinyint(11)" json:"claim_days"` // 任务完成天数
+ ClaimDemands string `gorm:"type:varchar(500);" json:"claim_demands"` // 任务拍摄要求
+ Description string `gorm:"type:varchar(2000);" json:"description"` // 描述/卖点
+
+ global.MG_MODEL
+}
+
+type MissionDetail struct {
+ Title string `json:"title"` // 标题
+ GoodsId uint `json:"-"`
+ GoodsStatus int `json:"goods_status"` // 关联商品状态 1:正常 2:已下架
+ Goods TbGoodsSpecsView `gorm:"ForeignKey:GoodsId;AssociationForeignKey:ID" json:"goods"` // 商品信息
+ Num int64 `json:"num"` // 商品数量
+ HireType int `json:"hire_type"` // 佣金类型 1:固定佣金 2:比例抽成
+ HireMoney float64 `json:"hire_money"` // hire_type==1 佣金金额
+ HireRatio float64 `json:"hire_ratio"` // hire_type==2 抽成比例
+ HireMoneyExpect string `json:"hire_money_expect"` // 预计佣金描述
+ StartTime *time.Time `json:"start_time"` // 任务起始时间
+ EndTime *time.Time `json:"end_time"` // 任务结束时间
+ ClaimNum int64 `gorm:"type:int(11)" json:"claim_num"` // 接任务人数
+ CreateBy string `json:"-"` //
+ CollectStatus bool `gorm:"-" json:"collect_status"` // 收藏状态 true:已收藏 false:未收藏
+ Store SellerStoreInfo `gorm:"-" json:"store"` // 商家信息
+ Status int `json:"status"` // 状态 1:未开始 2:进行中 3:已结束
+
+ // OrderNum int64 `gorm:"-" json:"order_num"` //订单数
+ Sample
+
+ VideoMaterial
+ ClaimStock int64 `json:"claim_stock"` // 可接任务库存
+ ClaimDays int `gorm:"type:tinyint(11)" json:"claim_days"` // 任务完成天数
+ ClaimDemands string `gorm:"type:varchar(500);" json:"claim_demands"` // 任务拍摄要求
+ Description string `gorm:"type:varchar(2000);" json:"description"` // 描述/卖点
+ ReleaseChannels string `gorm:"-" json:"release_channels"` // 发布渠道
+ ReleaseCountry string `gorm:"-" json:"release_country"` // 发布国家
+ ClaimStatusExcept string `json:"claim_status_except"` // 可接任务状态描述
+ ClaimStatusExceptEng string `json:"claim_status_except_eng"` // 英文版状态描述
+ GoodsUrl string `json:"goods_url"` // 商品链接
+ global.MG_MODEL
+}
+
+type Sample struct {
+ HasSample int `gorm:"type:tinyint(1);default:0" json:"has_sample"` // 是否有样品 0:没有 1:有
+ SampleNum int `gorm:"type:tinyint(11);" json:"sample_num"` // 样品数量
+}
+
+type VideoMaterial struct {
+ HasVideo int `gorm:"type:tinyint(1);default:0" json:"has_video"` // 是否有视频素材 0:没有 1:有
+ VideoUrl string `json:"video_url"`
+ VideoChannelIds string `json:"video_channel_ids"` // 视频发布渠道,多个渠道英文逗号连接
+ VideoCountryId string `json:"video_country_id"` // 视频发布国家
+}
+
+type MissionClaimInfo struct {
+ MissionId uint `json:"mission_id"` // 任务id
+ ClaimNo string `json:"claim_no"` // 领取任务编号
+ HireType int `gorm:"type:tinyint(1)" json:"hire_type"` // 佣金类型 1:固定佣金 2:比例抽成
+ HireMoney float64 `gorm:"type:decimal(10,2);" json:"hire_money"` // hire_type==1 佣金金额
+ HireRatio float64 `gorm:"type:decimal(10,2);" json:"hire_ratio"` // hire_type==2 抽成比例
+}
+
+type MissionBonus struct {
+ Total float64 `json:"total"`
+ UserTotal float64 `json:"user_total"`
+}
+
+func (Mission) TableName() string {
+ return "mission"
+}
+
+func (MissionDetail) TableName() string {
+ return "mission"
+}
diff --git a/model/mission_claim.go b/model/mission_claim.go
new file mode 100644
index 0000000..5ce741c
--- /dev/null
+++ b/model/mission_claim.go
@@ -0,0 +1,49 @@
+package model
+
+import (
+ "pure/global"
+ "time"
+)
+
+type MissionClaim struct { //领取任务记录
+ MissionId uint `gorm:"type:int(11)" json:"mission_id"` //任务id
+ ClaimNo string `gorm:"unique;type:varchar(60);" json:"claim_no"` //领取任务编号
+ AchieveNum int64 `gorm:"type:int(11)" json:"achieve_num"` //已完成商品数量
+ CreateBy string `gorm:"size:64" json:"create_by"` //创建人
+ Status int `gorm:"type:tinyint(1);" json:"status"` //状态 1:已领取待发货 2:已发货 3:已收货推广中
+ ExpireAt time.Time `json:"expire_at"` //任务推广过期时间
+ Finished int `gorm:"type:tinyint(1);" json:"finished"` // 任务完成状态 0:未完成 1:已完成
+ OrderNum int64 `gorm:"type:int" json:"orderNum"` // 订单数
+ OrderMoney float64 `gorm:"type:decimal(10,2)" json:"orderMoney"` // 订单金额
+ RewardFinished float64 `gorm:"type:decimal(10,2)" json:"rewardFinished"` // 佣金结算
+ RewardUnfinished float64 `gorm:"type:decimal(10,2)" json:"rewardUnfinished"` // 在途佣金
+ Email string `gorm:"size:255" json:"email"` //发送邮箱
+ SendFinished int `gorm:"type:tinyint(1);" json:"send_finished"` //状态 1:已发送 2:发送失败
+ global.MG_MODEL
+}
+
+type MissionClaimDetail struct {
+ global.MG_MODEL
+ ClaimNo string `json:"claim_no"` //领取任务编号
+ MissionId uint `json:"mission_id"` //任务id
+ AchieveNum int64 `json:"achieve_num"` //已完成商品数量
+ Status int `json:"status"` //状态 1:已领取待发货 2:已发货 3:已收货推广中
+ SpreadUrl string `json:"spread_url"` //推广链接
+ TotalBonus int64 `json:"total_bonus"` //累计佣金
+ StatusExcept string `json:"status_except" gorm:"-"` //状态描述
+ ExpireAt time.Time `json:"expire_at"` //任务推广过期时间
+ Email string `json:"email"` //发送邮箱
+ Finished int `json:"finished"` // 任务完成状态 0:未完成 1:已完成
+ Order MissionClaimOrderInfo `gorm:"ForeignKey:MissionClaimId;AssociationForeignKey:ID" json:"order"` //任务订单
+ Mission MissionDetail `gorm:"ForeignKey:MissionId;AssociationForeignKey:ID" json:"mission"` //关联任务
+ Works []MissionClaimWorks `gorm:"ForeignKey:MissionClaimId;AssociationForeignKey:ID" json:"works"` //发布作品
+ Video MissionClaimVideo `gorm:"ForeignKey:MissionClaimId;AssociationForeignKey:ID" json:"video"` //上传视频
+}
+
+func (MissionClaim) TableName() string {
+ return "mission_claim"
+}
+
+func (MissionClaimDetail) TableName() string {
+ return "mission_claim"
+}
diff --git a/model/mission_claim_address.go b/model/mission_claim_address.go
new file mode 100644
index 0000000..a406497
--- /dev/null
+++ b/model/mission_claim_address.go
@@ -0,0 +1,12 @@
+package model
+
+type MissionClaimAddress struct { //领取任务地址
+ Address
+ AddressId uint `gorm:"type:int(11)" json:"address_id"` //地址id
+ MissionClaimId uint `gorm:"type:int(11)" json:"mission_claim_id"` //领取任务id
+ OrderID string `gorm:"size:50;index" json:"order_id"` //订单号
+}
+
+func (MissionClaimAddress) TableName() string {
+ return "mission_claim_address"
+}
diff --git a/model/mission_claim_order.go b/model/mission_claim_order.go
new file mode 100644
index 0000000..700a229
--- /dev/null
+++ b/model/mission_claim_order.go
@@ -0,0 +1,43 @@
+package model
+
+import (
+ "pure/global"
+ "time"
+)
+
+type MissionClaimOrder struct { //任务领取sku订单
+ global.MG_MODEL
+ OrderID string `gorm:"size:50;index" json:"order_id"` //订单号
+ MissionClaimId uint `gorm:"type:int(11)" json:"mission_claim_id"` //领取任务id
+ SpuNo string `gorm:"type:varchar(60);" json:"spu_no"` //spu编号
+ SkuNo string `gorm:"type:varchar(60);" json:"sku_no"` //sku编号
+ Number int `gorm:"type:int(10)" json:"number"` //数量
+ CreateBy string `gorm:"size:64" json:"create_by"` //创建人
+ Status int `gorm:"type:int(1)" json:"status"` //订单状态 2:待发货 3:已发货
+ SendTime *time.Time `gorm:"send_time" json:"sendTime"` //发货时间
+ Courier string `gorm:"size:50" json:"courier"` //快递公司
+ CourierUrl string `gorm:"size:255" json:"courier_url"` //快递查询地址
+ CourierNumber string `gorm:"size:50" json:"courierNumber"` //快递单号
+ TrackId uint `json:"track_id"` // track表id
+ ConfirmTime *time.Time `gorm:"" json:"confirmTime"` //收货时间
+}
+
+type MissionClaimOrderInfo struct {
+ OrderID string `json:"order_id"` //订单号
+ MissionClaimId uint `json:"mission_claim_id"` //领取任务id
+ Status int `json:"status"` //订单状态 2:待发货 3:已发货
+ Courier string `json:"courier"` //快递公司
+ CourierUrl string `json:"courier_url"` //快递查询地址
+ CourierNumber string `json:"courier_number"` //快递单号
+ SendTime *time.Time `gorm:"send_time" json:"send_time"` //发货时间
+ OrderGoods MissionClaimOrderGoods `gorm:"ForeignKey:OrderID;references:OrderID;" json:"order_goods"` //订单商品信息
+ Deliver OrderDeliver `gorm:"-" json:"deliver"` //发货信息
+}
+
+func (MissionClaimOrder) TableName() string {
+ return "mission_claim_order"
+}
+
+func (MissionClaimOrderInfo) TableName() string {
+ return "mission_claim_order"
+}
diff --git a/model/mission_claim_order_goods.go b/model/mission_claim_order_goods.go
new file mode 100644
index 0000000..19273d6
--- /dev/null
+++ b/model/mission_claim_order_goods.go
@@ -0,0 +1,17 @@
+package model
+
+import "pure/global"
+
+type MissionClaimOrderGoods struct { //任务订单关联商品
+ global.MG_MODEL
+ OrderID string `gorm:"size:50;index" json:"order_id"` //订单号
+ SkuNo string `gorm:"type:varchar(60);" json:"sku_no"` //sku编号
+ Title string `gorm:"type:varchar(255);" json:"title"` //名称
+ Image string `gorm:"size:255" json:"image"` //规格图片url
+ Specs string `gorm:"type:text;" json:"specs"` //规格
+ Price float64 `gorm:"type:decimal(10,2);" json:"price"` //价格
+}
+
+func (MissionClaimOrderGoods) TableName() string {
+ return "mission_claim_order_goods"
+}
diff --git a/model/mission_claim_video.go b/model/mission_claim_video.go
new file mode 100644
index 0000000..f17230e
--- /dev/null
+++ b/model/mission_claim_video.go
@@ -0,0 +1,37 @@
+package model
+
+import (
+ "pure/global"
+ "time"
+)
+
+type MissionClaimVideo struct { //固定费用上传视频
+ global.MG_MODEL
+ MissionClaimId uint `gorm:"type:int(11)" json:"mission_claim_id"` //领取任务id
+ VideoUrl string `gorm:"size:255" json:"video_url"` //视频上传地址
+ Cover string `json:"cover" gorm:"size:255"` //视频封面
+ Remark string `json:"remark"`
+ Status int `json:"status"` //状态 1:待审核 2:审核通过 3:审核不通过
+ RewardStatus int `gorm:"type:tinyint(1)" json:"reward_status"` // 奖励发放状态 1:未发放 2:已发放
+ SourceType int `json:"source_type" gorm:"type:tinyint(1);default:1"` //类型:1:固定费用上传 2:奖励任务上传 3:后台上传
+ MissionId uint `json:"mission_id"` //任务ID
+ CreateBy string `gorm:"size:64" json:"create_by"` //创建人
+ CreateTime time.Time `gorm:"-" json:"created_at"` // 创建时间
+ Width int `json:"width"` //宽度
+ Height int `json:"height"` //高度
+
+}
+
+type MissionClaimVideoDetail struct {
+ MissionClaimVideo
+ Mission MissionDetail `gorm:"ForeignKey:ID;References:MissionId" json:"mission"` //任务信息
+ Influencer UserSimple `gorm:"ForeignKey:UUID;References:CreateBy" json:"influencer"` //网红信息
+}
+
+func (MissionClaimVideo) TableName() string {
+ return "mission_claim_video"
+}
+
+func (MissionClaimVideoDetail) TableName() string {
+ return "mission_claim_video"
+}
diff --git a/model/mission_claim_works.go b/model/mission_claim_works.go
new file mode 100644
index 0000000..e1d6ce2
--- /dev/null
+++ b/model/mission_claim_works.go
@@ -0,0 +1,17 @@
+package model
+
+import "pure/global"
+
+type MissionClaimWorks struct { //领取任务发布的作品
+ global.MG_MODEL
+ MissionClaimId uint `gorm:"type:int(11)" json:"mission_claim_id"` //领取任务id
+ Type int `gorm:"type:tinyint(1)" json:"type"` //平台 1:ins 2:YouTube 3:tiktok 4:Facebook 5:Twitter
+ Homepage string `gorm:"size:255" json:"homepage"` //作品主页地址
+ Image string `json:"image"` //作品凭证截图
+ VideoUrl string `gorm:"size:255" json:"video_url"` //视频上传地址
+
+}
+
+func (MissionClaimWorks) TableName() string {
+ return "mission_claim_works"
+}
diff --git a/model/mission_recommend.go b/model/mission_recommend.go
new file mode 100644
index 0000000..3b47da1
--- /dev/null
+++ b/model/mission_recommend.go
@@ -0,0 +1,27 @@
+package model
+
+import (
+ "pure/global"
+)
+
+type MissionRecommend struct { //任务推荐
+ RelationId uint `gorm:"type:int(11);" json:"relation_id"` //关联ID,任务视频ID
+ CreateBy string `gorm:"size:64" json:"create_by"` //创建人
+ Status int `gorm:"type:tinyint(1);" json:"status"` //状态 1:上架 2:下架
+ Sort int `gorm:"type:tinyint(2)" json:"sort"` //倒序 //排序
+ UpdateBy string `gorm:"size:64" json:"-"` //更新人
+ global.MG_MODEL
+}
+
+type MissionRecommendDetail struct { //任务推荐
+ MissionRecommend //更新人
+ MissionVideo MissionClaimVideoDetail `gorm:"ForeignKey:ID;References:RelationId" json:"mission_video"` //任务视频信息
+}
+
+func (MissionRecommend) TableName() string {
+ return "mission_recommend"
+}
+
+func (MissionRecommendDetail) TableName() string {
+ return "mission_recommend"
+}
diff --git a/model/notify.go b/model/notify.go
new file mode 100644
index 0000000..405aa97
--- /dev/null
+++ b/model/notify.go
@@ -0,0 +1,16 @@
+package model
+
+import "pure/global"
+
+type Notify struct { // 通知
+ global.MG_MODEL
+ UserId string `gorm:"size:64" json:"userId"` // 用户id
+ RelationType string `gorm:"size:1" json:"relation_type"` // 关联类型 1-提现
+ RelationId string `gorm:"size:64" json:"relation_id"` // 关联id
+ Title string `gorm:"size:255" json:"title"` // 通知标题
+ Content string `gorm:"size:255" json:"content"` // 通知内容
+}
+
+func (Notify) TableName() string {
+ return "notify"
+}
diff --git a/model/order.go b/model/order.go
new file mode 100644
index 0000000..ffa6a0c
--- /dev/null
+++ b/model/order.go
@@ -0,0 +1,69 @@
+package model
+
+import (
+ "pure/global"
+ "time"
+)
+
+type Order struct {
+ global.MG_MODEL
+ Platform string `gorm:"size:10" json:"platform"` // 购买平台
+ StoreNo string `gorm:"size:60" json:"store_no"` // 店铺编号
+ OrderID string `gorm:"size:50;index" json:"orderID"` //订单号
+ PaypalID string `gorm:"size:50" json:"paypalID"` //paypal订单号
+ CaptureID string `gorm:"size:50" json:"captureID"` //paypal收款确认id
+ Code string `gorm:"size:20" json:"code"` //网红码?
+ UserID string `gorm:"size:50;index" json:"userID"` //用户id
+ CommodID uint `gorm:"size:50;index" json:"commodID"` //商品id
+ SkuNo string `gorm:"type:varchar(60);" json:"sku_no"` //商品规格编号
+ SkuID int `gorm:"type:int(10);" json:"sku_id"` //商品规格编号
+ Type int `gorm:"type:int(1);default:1" json:"type"` //类型 1-普通订单 2-预售订单
+ Price float64 `gorm:"type:decimal(10,2)" json:"price"` //商品价格
+ Number int `gorm:"type:int(10)" json:"number"` //数量
+ PaidPrice float64 `gorm:"type:decimal(10,2)" json:"paidPrice"` //实付价格
+ Status int `gorm:"type:int(1)" json:"status"` //订单状态 //订单状态 1-待付款 2-待发货 3-已发货 4-已完成 5-已取消
+ PayTime *time.Time `gorm:"" json:"payTime"` //付款时间
+ SendTime *time.Time `gorm:"" json:"sendTime"` //发货时间
+ ConfirmTime *time.Time `gorm:"" json:"confirmTime"` //收货时间
+}
+
+type OrderList struct {
+ Order
+ Goods OrderGoodsDetail `json:"goods"` // 商品信息
+ User UserSimple `gorm:"-" json:"user"` //买家信息
+ InfluencerAmount string `gorm:"-" json:"IAmount"` //网红佣金
+}
+
+type OrderDetail struct {
+ Order
+ Goods OrderGoodsDetail `gorm:"-" json:"goods"` // 商品信息
+ Address OrderAddress `gorm:"-" json:"address"` //地址
+ Deliver OrderDeliver `gorm:"-" json:"deliver"` //发货信息
+ Store SellerStoreInfo `gorm:"-" json:"store"` // 店铺信息
+ PostSale PostSale `gorm:"-" json:"postSale"` // 售后信息
+ Bill BillView `gorm:"-" json:"bill"` // 交易信息
+ Chain Chain `gorm:"-" json:"chain"` // 区块链
+ InfluencerAmount string `gorm:"-" json:"IAmount"` //网红佣金
+}
+
+type OrderTotal struct {
+ Status2 int `json:"status2"` //待发货
+ Status3 int `json:"status3"` //已发货
+ Status4 int `json:"status4"` //已收货
+}
+
+type Chain struct {
+ Address string `json:"address"` // 合约地址
+}
+
+func (Order) TableName() string {
+ return "order"
+}
+
+func (OrderList) TableName() string {
+ return "order"
+}
+
+func (OrderDetail) TableName() string {
+ return "order"
+}
diff --git a/model/order_address.go b/model/order_address.go
new file mode 100644
index 0000000..9c24918
--- /dev/null
+++ b/model/order_address.go
@@ -0,0 +1,12 @@
+package model
+
+//记录订单中的收货地址
+type OrderAddress struct {
+ Address
+ OrderID string `gorm:"size:50" json:"orderID"`
+ Platform string `gorm:"size:50" json:"platform"` //平台 saller(买家端) / customer(客户端) / influencer(网红端)
+}
+
+func (OrderAddress) TableName() string {
+ return "order_address"
+}
diff --git a/model/order_deliver.go b/model/order_deliver.go
new file mode 100644
index 0000000..b936b11
--- /dev/null
+++ b/model/order_deliver.go
@@ -0,0 +1,27 @@
+package model
+
+import "pure/global"
+
+type OrderDeliver struct {
+ global.MG_MODEL
+ OrderID string `gorm:"size:50" json:"orderID"` //订单号
+ CourierNumber string `gorm:"size:50" json:"courierNumber"` //快递单号
+ Courier string `gorm:"size:50" json:"courier"` //快递公司
+ CourierLink string `gorm:"size:255" json:"courierLink"` //快递链接
+ TrackId uint `json:"track_id"` // track表id
+}
+
+type OrderDeliverDesc struct {
+ OrderID string `gorm:"size:50" json:"orderID"` //订单号
+ CourierNumber string `gorm:"size:50" json:"courierNumber"` //快递单号
+ Courier string `gorm:"size:50" json:"courier"` //快递公司
+ CourierLink string `gorm:"size:255" json:"courierLink"` //快递链接
+}
+
+type PutDeliver struct {
+ Data []OrderDeliverDesc `json:"data"`
+}
+
+func (OrderDeliver) TableName() string {
+ return "order_deliver"
+}
diff --git a/model/order_goods.go b/model/order_goods.go
new file mode 100644
index 0000000..c8c4544
--- /dev/null
+++ b/model/order_goods.go
@@ -0,0 +1,26 @@
+package model
+
+import "pure/global"
+
+type OrderGoods struct {
+ global.MG_MODEL
+ OrderID string `gorm:"size:50" json:"orderID"` // 订单id
+ SpuNo string `gorm:"type:varchar(60);" json:"spu_no"` // 商品编号
+ SkuNo string `gorm:"type:varchar(60);" json:"sku_no"` // 商品规格编号
+ Specs string `gorm:"type:text;" json:"specs"` // 规格
+ TbGoodsBase
+}
+
+type OrderGoodsDetail struct {
+ OrderGoods
+ Attributes []TbAttributeWithValues `gorm:"-" json:"attributes"` // 规格详情
+ GoodsSpecs []TbOrderGoodsSpecsDetail `gorm:"-" json:"goods_specs"` // 规格
+}
+
+func (OrderGoods) TableName() string {
+ return "order_goods"
+}
+
+func (OrderGoodsDetail) TableName() string {
+ return "order_goods"
+}
diff --git a/model/order_goods_specs.go b/model/order_goods_specs.go
new file mode 100644
index 0000000..5282abd
--- /dev/null
+++ b/model/order_goods_specs.go
@@ -0,0 +1,30 @@
+package model
+
+import "pure/global"
+
+type OrderGoodsSpecs struct {
+ global.MG_MODEL
+ TbGoodsSpecsBase
+ OrderID string `gorm:"size:50" json:"orderID"` // 订单id
+ OrderGoodsId uint `json:"orderGoodsId"` //
+}
+
+type TbOrderGoodsSpecsDetail struct {
+ GoodsId uint `json:"goods_id"`
+ Specs string `json:"specs"` // 规格
+ //Attributes []TbAttributeDetail `gorm:"-" json:"-"` // 规格详情
+ SkuNo string `json:"sku_no"` // 商品编码
+ Price float64 `json:"price"` // 价格
+ Image string `json:"image"` // 规格图片url
+ GoodsNo string `json:"goods_no"` // 商品编号
+ Code string `json:"code"` // attribute定位标识
+ OrderGoodsId uint `json:"orderGoodsId"` //
+}
+
+func (OrderGoodsSpecs) TableName() string {
+ return "order_goods_specs"
+}
+
+func (TbOrderGoodsSpecsDetail) TableName() string {
+ return "order_goods_specs"
+}
diff --git a/model/order_post_sale.go b/model/order_post_sale.go
new file mode 100644
index 0000000..ccbaa17
--- /dev/null
+++ b/model/order_post_sale.go
@@ -0,0 +1,42 @@
+package model
+
+import (
+ "pure/global"
+ "time"
+)
+
+type OrderPostSale struct { // 订单售后记录
+ global.MG_MODEL
+ Type int `gorm:"type:tinyint(1)" json:"type"` // 售后类型 1:仅退款
+ OrderID string `gorm:"size:50" json:"orderId"` // 订单号
+ StoreNo string `gorm:"size:60" json:"store_no"` // 店铺编号
+ UserID string `gorm:"size:50" json:"userId"` // 用户id
+ Amount float64 `gorm:"type:decimal(10,2)" json:"amount"` // 退款金额
+ Reason string `gorm:"size:1" json:"reason"` // 退款原因
+ Images string `gorm:"size:255" json:"images"` // 图片
+ Videos string `gorm:"size:255" json:"videos"` // 视频
+ Status int `gorm:"type:tinyint(1)" json:"status"` // 处理状态 1:已提交 2:已处理 3:已拒绝 4:已撤回
+ Remark string `gorm:"size:255" json:"remark"` // 原因
+ ExamineTime *time.Time `gorm:"" json:"examine_time"` // 审核时间
+ RefundStatus int `gorm:"type:tinyint(1)" json:"refundStatus"` // 退款状态 1:退款中 2:退款成功 3:退款失败
+ RefundTime *time.Time `gorm:"" json:"refund_time"` // 退款时间
+}
+
+type PostSale struct {
+ ID uint `json:"id"` // id
+ OrderID string `json:"orderId"` // 订单id
+ Status int `json:"status"` // 处理状态 1:已提交 2:已处理 3:已拒绝 4:已撤回
+ Remark string `json:"remark"` // 审核原因
+ ExamineTime *time.Time `json:"examine_time"` // 审核时间
+ RefundStatus int `json:"refundStatus"` // 退款状态 1:退款中 2:退款成功 3:退款失败
+ RefundTime *time.Time `json:"refund_time"` // 退款时间
+ CreatedAt *time.Time `json:"created_at"` // 创建时间
+}
+
+func (OrderPostSale) TableName() string {
+ return "order_post_sale"
+}
+
+func (PostSale) TableName() string {
+ return "order_post_sale"
+}
diff --git a/model/paypalWebhook.go b/model/paypalWebhook.go
new file mode 100644
index 0000000..2fbd41d
--- /dev/null
+++ b/model/paypalWebhook.go
@@ -0,0 +1,21 @@
+package model
+
+type PaypalWebhookDetail struct {
+ ID string `json:"id"`
+ EventVersion string `json:"event_version"`
+ CreateTime string `json:"create_time"`
+ ResourceType string `json:"resource_type"` //checkout-order-订单付款 capture-付款确认 payouts-提现 refund-退款
+ EventType string `json:"event_type"`
+ Summary string `json:"summary"`
+ Resource struct {
+ BatchHeader struct {
+ BatchStatus string `json:"batch_status"` //SUCCESS-成功 DENIED-拒绝 FAILED-失败
+ SenderBatchHeader struct {
+ SenderBatchID string `json:"sender_batch_id"`
+ } `json:"sender_batch_header"`
+ } `json:"batch_header"`
+ CreateTime string `json:"create_time"`
+ ID string `json:"id"`
+ Status string `json:"status"` //COMPLETED-完成 APPROVED-用户已付款? PENDING-等待
+ } `json:"resource"`
+}
diff --git a/model/platform_auth.go b/model/platform_auth.go
new file mode 100644
index 0000000..152497f
--- /dev/null
+++ b/model/platform_auth.go
@@ -0,0 +1,22 @@
+package model
+
+import (
+ "pure/global"
+ "pure/model/request"
+)
+
+type PlatformAuth struct {
+ global.MG_MODEL
+ UserID string `json:"user_id" gorm:"type:varchar(60);comment:用户ID"`
+ request.Platform
+ Status string `json:"status" gorm:"size:1;comment:认证状态 0:未认证 1:已认证 2:认证失败"` //认证状态 0:未认证 1:已认证 2:认证失败
+}
+
+type PlatformAuthSimple struct {
+ PlatformAuth
+ User UserSimple `json:"user"`
+}
+
+func (PlatformAuth) TableName() string {
+ return "platform_auth"
+}
diff --git a/model/provider.go b/model/provider.go
new file mode 100755
index 0000000..32f97f8
--- /dev/null
+++ b/model/provider.go
@@ -0,0 +1,60 @@
+// 自动生成模板Provider
+package model
+
+import "pure/global"
+
+// 如果含有time.Time 请自行import time包
+type Provider struct {
+ global.MG_MODEL
+ Owner string `gorm:"size:50;comment:用户所属" json:"owner" ` // 用户所属
+ Name string `gorm:"size:50;comment:提供者名称" json:"name" ` // 提供者名称
+ Category string `gorm:"size:50;comment:提供者分类" json:"category" ` // 提供者分类 1-社交 2-支付 3-媒体 4-其他
+ Code string `gorm:"size:50;comment:提供者代码" json:"code" ` // 提供者代码 google facebook twitter tiktok
+ ClientID string `gorm:"size:50;comment:客户端ID" json:"client_id" ` // 客户端ID
+ ClientSecret string `gorm:"size:50;comment:客户端密钥" json:"client_secret" ` // 客户端密钥
+ Scope string `gorm:"size:50;comment:作用域" json:"scope" ` // 作用域
+ TokenType string `gorm:"size:50;comment:令牌类型" json:"token_type" ` // 令牌类型 Bearer urlencoded
+ RedirectURI string `gorm:"size:50;comment:重定向URI" json:"redirect_uri" ` // 重定向URI
+ RedirectURIByAnd string `gorm:"size:50;comment:重定向URI" json:"redirect_uri_by_and" ` // 重定向URI(安卓)
+ RedirectURIByIos string `gorm:"size:50;comment:重定向URI" json:"redirect_uri_by_ios" ` // 重定向URI(IOS)
+ AuthURI string `gorm:"size:50;comment:认证URI" json:"auth_uri" ` // 认证URI
+ TokenURI string `gorm:"size:50;comment:令牌URI" json:"token_uri" ` // 令牌URI
+ TokenCheckURI string `gorm:"size:50;comment:令牌校验URI" json:"token_check_uri" ` // 令牌校验URI
+ UserInfoURI string `gorm:"size:50;comment:用户信息URI" json:"user_info_uri" ` // 用户信息URI
+}
+
+type ClentProvider struct {
+ Web []Provider `json:"web"`
+ Android []Provider `json:"android"`
+ Ios []Provider `json:"ios"`
+}
+
+type ProviderUser struct {
+ UserID string `gorm:"size:50;comment:用户ID" json:"user_id" ` // 用户ID
+ NickName string `gorm:"size:50;comment:昵称" json:"nick_name" ` // 昵称
+ Avatar string `gorm:"size:50;comment:头像" json:"avatar" ` // 头像
+ Email string `gorm:"size:50;comment:邮箱" json:"email" ` // 邮箱
+ Phone string `gorm:"size:50;comment:手机号" json:"phone" ` // 手机号
+}
+
+type FacebookUserInfo struct {
+ UnionId string `json:"id"`
+ UserName string `json:"name"`
+ Email string `json:"email"`
+ Picture struct {
+ Data struct {
+ URL string `json:"url"`
+ } `json:"data"`
+ } `json:"picture"`
+}
+
+type TiktokUser struct {
+ OpenID string `json:"open_id"`
+ UnionID string `json:"union_id"`
+ AvatarURL string `json:"avatar_url"`
+ DisplayName string `json:"display_name"`
+}
+
+func (Provider) TableName() string {
+ return "provider"
+}
diff --git a/model/request/account.go b/model/request/account.go
new file mode 100644
index 0000000..56d856d
--- /dev/null
+++ b/model/request/account.go
@@ -0,0 +1,21 @@
+package request
+
+type AddAccount0 struct {
+ UserID string `gorm:"size:50;index" json:"userID"` //用户id
+ AccountName string `gorm:"size:50" json:"accountName"` //户名
+ IDCard string `gorm:"size:30" json:"idCard"` //身份证
+ Phone string `gorm:"size:20" json:"phone"` //手机号
+ PayPalName string `gorm:"size:50" json:"payPalName"` //paypal账号
+ Code string `json:"code"`
+ Platform string `gorm:"size:50" json:"platform"` //平台 saller(买家端) / customer(客户端) / influencer(网红端)
+}
+
+type SearchCommission struct {
+ Receipt int `json:"receipt" form:"receipt"` //是否已到账 1-是 2-否
+ PageInfo
+}
+
+type SearchWithdrawal struct {
+ Status int `json:"status"` //类型 1-支出 2-收入
+ PageInfo
+}
diff --git a/model/request/address.go b/model/request/address.go
new file mode 100644
index 0000000..f5a405b
--- /dev/null
+++ b/model/request/address.go
@@ -0,0 +1,7 @@
+package request
+
+import "pure/global"
+
+type ReqAddress struct {
+ global.BASE_ID
+}
diff --git a/model/request/bill.go b/model/request/bill.go
new file mode 100644
index 0000000..064bfe3
--- /dev/null
+++ b/model/request/bill.go
@@ -0,0 +1,16 @@
+package request
+
+type GetBillDataParams struct {
+ Uint string `json:"uint" form:"uint"` // 1:全部 2:昨天 3:近30天
+}
+
+type SearchBillParams struct {
+ Uint string `json:"uint" form:"uint"` // 1:全部 2:昨天 3:近30天
+ Status string `json:"status" form:"status"` // 空:全部 1-支出 2-收入
+ Scene string `json:"scene" form:"scene"` // 空:默认 1:bill-center
+ PageInfo
+}
+
+type FlowNoParam struct {
+ FlowNo string `json:"flow_no" form:"flow_no"` // 流水号
+}
diff --git a/model/request/chain.go b/model/request/chain.go
new file mode 100644
index 0000000..f4d4718
--- /dev/null
+++ b/model/request/chain.go
@@ -0,0 +1,5 @@
+package request
+
+type ChainParams struct {
+ Hash string `json:"hash" form:"hash"` // 区块/合约hash
+}
diff --git a/model/request/collection_mission.go b/model/request/collection_mission.go
new file mode 100644
index 0000000..d506091
--- /dev/null
+++ b/model/request/collection_mission.go
@@ -0,0 +1,9 @@
+package request
+
+type SearchCollectionMission struct {
+ PageInfo
+}
+
+type SearchRecommendMission struct {
+ PageInfo
+}
diff --git a/model/request/common.go b/model/request/common.go
new file mode 100644
index 0000000..ecf5d7e
--- /dev/null
+++ b/model/request/common.go
@@ -0,0 +1,56 @@
+package request
+
+// Paging common input parameter structure
+type PageInfo struct {
+ Page int `json:"page" form:"page"` // 页码
+ PageSize int `json:"pageSize" form:"pageSize"` // 每页大小
+}
+
+// Find by id structure
+type GetById struct {
+ ID float64 `json:"id" form:"id"` // 主键ID
+}
+
+type IdsReq struct {
+ Ids []int `json:"ids" form:"ids"`
+}
+
+type IdsStrReq struct {
+ Ids []string `json:"ids" form:"ids"`
+}
+
+type IdReq struct {
+ ID uint `json:"id" form:"id"` //id
+}
+
+type IdStrReq struct {
+ ID string `json:"id" form:"id"`
+}
+
+type StatusParam struct {
+ Status string `json:"status" form:"id"`
+ ID string `json:"id" form:"id"`
+}
+
+type StatusParams struct {
+ Status string `json:"status"`
+ IdsStrReq
+}
+
+type StatusParamsInt struct {
+ Status int `json:"status"`
+ IdsStrReq
+}
+
+type ChannelId struct {
+ ChannelId string `json:"channelId" form:"channelId"`
+}
+
+type StructParams map[string]interface{}
+
+// Get role by id structure
+type GetAuthorityId struct {
+ AuthorityId string // 角色ID
+}
+
+type Empty struct{}
diff --git a/model/request/dict.go b/model/request/dict.go
new file mode 100644
index 0000000..3950b1d
--- /dev/null
+++ b/model/request/dict.go
@@ -0,0 +1,5 @@
+package request
+
+type SearchDictDataParams struct {
+ TypeCode string `json:"typeCode" form:"typeCode"` //取值 release_country=发布国家 release_channel=发布渠道 tag_type=标签类型
+}
diff --git a/model/request/jwt.go b/model/request/jwt.go
new file mode 100644
index 0000000..b876f9f
--- /dev/null
+++ b/model/request/jwt.go
@@ -0,0 +1,19 @@
+package request
+
+import (
+ "github.com/dgrijalva/jwt-go"
+)
+
+// Custom claims structure
+type UserClaims struct {
+ UUID string
+ ID uint
+ Username string
+ NickName string
+ Email string
+ Appid string
+ Type string
+ IDForbidden bool
+ BufferTime int64
+ jwt.StandardClaims
+}
diff --git a/model/request/mission.go b/model/request/mission.go
new file mode 100644
index 0000000..6e0c1e9
--- /dev/null
+++ b/model/request/mission.go
@@ -0,0 +1,67 @@
+package request
+
+type SearchMission struct {
+ PageInfo
+}
+
+type SearchMissionClaim struct {
+ MissionStatus int `json:"-"`
+ HireType int `json:"hire_type" form:"hire_type"` // 佣金类型 1:固定佣金 2:比例抽成
+ VideoUpload int `json:"video_upload" form:"video_upload"` //是否筛选上传视频 1是
+ ExcludeIds []uint `json:"-"` //排除ID
+ PageInfo
+}
+
+type ClaimMission struct {
+ MissionId uint `json:"mission_id"` //任务id
+ AddressId uint `json:"address_id"` //收货地址id
+ SpuNo string `json:"spu_no"` //商品spu_no
+ SkuNo string `json:"sku_no"` //商品sku_no
+ Email string `json:"email"` //邮箱地址
+}
+
+type MissionId struct {
+ MissionId uint `json:"mission_id"` //任务
+}
+
+type MissionCode struct {
+ Code string `json:"code" form:"code"` //任务编码
+}
+
+type ClaimMissionWorks struct {
+ ID uint `json:"id"` //id
+ Type int `json:"type"` //平台 1:ins 2:Pinterest 3:tk 4:Twitter 5:Facebook 6:Reddit
+ Homepage string `json:"homepage"` //作品主页地址
+ Image string `json:"image"` //作品凭证截图
+ VideoUrl string `json:"video_url"` //视频上传地址
+}
+
+type ClaimMissionWorksList struct {
+ MissionClaimId uint `json:"mission_claim_id"` //领取任务id
+ Works []ClaimMissionWorks `json:"works"` //作品列表
+}
+
+type ClaimMissionVideo struct {
+ MissionClaimId uint `json:"mission_claim_id"` //领取任务id
+ VideoUrl string `json:"video_url"` //视频上传地址
+ Cover string `json:"cover"`
+ SourceType int `json:"source_type"` //类型:1:固定费用上传 2:奖励任务上传 3:后台上传
+ Width int `json:"width"` //宽度
+ Height int `json:"height"` //高度
+}
+
+type AddSysMissionReward struct {
+ Type int `json:"type"` //奖励类型 1.视频上传 2.信息完善 3.商家任务
+ RelationId string `json:"relationId"` //关联项目id
+ AchieveNum int64 `json:"achieve_num"` //已完成任务次数
+ CreateBy string `json:"create_by"` //创建人
+}
+
+type SearchSysReward struct {
+ Status int `form:"status" json:"status"` //状态 1待发放 2已发放 3已领取
+ PageInfo
+}
+
+type SearchSysRewardSummary struct {
+ Status int `form:"status" json:"status"` //状态 1待发放 2已发放 3已领取
+}
diff --git a/model/request/notify.go b/model/request/notify.go
new file mode 100644
index 0000000..08d55a5
--- /dev/null
+++ b/model/request/notify.go
@@ -0,0 +1,6 @@
+package request
+
+type SearchNotify struct {
+ PageInfo
+ RelationType string `json:"relation_type" form:"relation_type"`
+}
diff --git a/model/request/order.go b/model/request/order.go
new file mode 100644
index 0000000..ac58f6a
--- /dev/null
+++ b/model/request/order.go
@@ -0,0 +1,42 @@
+package request
+
+type SearchOrderList struct {
+ OrderID string `json:"orderID" form:"orderID"` //订单号
+ Code string `json:"code" form:"code"` //网红码?
+ Status int `json:"status" form:"status"` //订单状态 //订单状态 1-待付款 2-待发货 3-已发货 4-已完成 5-已取消
+ Group string // 数据库分组
+ PageInfo
+}
+
+type GetOrderParams struct {
+ OrderID string `json:"orderID" form:"orderID"` //订单号
+}
+
+type SceneParams struct {
+ Scene string `json:"scene" form:"scene"` // 场景 my:我的 order-list:订单列表
+}
+
+type AddOrder struct {
+ Code string `json:"code"` //网红码?
+ SkuID int `json:"skuID"` //商品规格id
+ Number int `json:"number"` //数量
+ AddressID int `json:"addressID"` //收货地址id
+ PayMode int `json:"payMode"` //支付方式 1-paypal
+}
+
+type UpdateUserOrderStatus struct {
+ OrderID string `json:"orderID"` //订单号
+ Status int `json:"status"` //订单状态 4-已完成 5-已取消
+}
+
+type CheckOrderParams struct {
+ Token string `json:"token" form:"token"`
+}
+
+type DeleteUserORder struct {
+ OrderID string `json:"orderID"` //订单号
+}
+
+type OrderMessage struct {
+ OrderID string `json:"orderID"` //订单号
+}
diff --git a/model/request/othor.go b/model/request/othor.go
new file mode 100644
index 0000000..96d3e03
--- /dev/null
+++ b/model/request/othor.go
@@ -0,0 +1,11 @@
+package request
+
+type SendMessage struct {
+ Phone string `form:"phone"`
+ Type int `form:"type"` //1:登录验证码 2-解绑 3-绑定 4-提现
+ CountryCode string `json:"country_code" form:"country_code" gorm:"size:255"` //用户手机号国家代码 国际区号 86 中国 1美国
+}
+
+type SendEmail struct {
+ Email string `form:"email"`
+}
diff --git a/model/request/sys_brochure.go b/model/request/sys_brochure.go
new file mode 100644
index 0000000..cad7675
--- /dev/null
+++ b/model/request/sys_brochure.go
@@ -0,0 +1,5 @@
+package request
+
+type SysBrochureType struct {
+ Type string `json:"type" form:"type"`
+}
diff --git a/model/request/tb_goods.go b/model/request/tb_goods.go
new file mode 100644
index 0000000..5be0274
--- /dev/null
+++ b/model/request/tb_goods.go
@@ -0,0 +1,15 @@
+package request
+
+type Goods struct {
+ ID uint `json:"id" form:"id"` //商品id
+ SkuNo string `json:"sku_no" form:"sku_no"` //sku_no
+ ClaimNo string `json:"claim_no" form:"claim_no"` //领取任务id
+}
+
+type SpuNo struct {
+ SpuNo string `json:"spu_no"` //spu_no
+}
+
+type SearchCollectionGoods struct {
+ PageInfo
+}
diff --git a/model/request/user.go b/model/request/user.go
new file mode 100644
index 0000000..4ffea59
--- /dev/null
+++ b/model/request/user.go
@@ -0,0 +1,57 @@
+package request
+
+import "time"
+
+// User login structure
+type UserDetail struct {
+ Type string `json:"type"` // 修改字段 platform-平台 tags-个人标签
+ Platform string `json:"platform"` // 平台及地址逗号隔开 eg:(ins:https://baidu.com/user/1,qq:12345678)
+ Tags string `json:"tags"` // 个人标签
+}
+
+type UserLogin struct {
+ Email string `json:"email"` //邮箱
+ Phone string `json:"phone"` //手机号
+ Code string `json:"code"` //验证码
+ Password string `json:"password"` //密码
+ Type string `json:"type"` // 1-手机号 2-邮箱
+ Appid string `json:"appid"` //应用id
+ CountryCode string `json:"country_code" form:"country_code" gorm:"size:255"` //用户手机号国家代码 国际区号 86 中国 1美国
+}
+
+type UserRegister struct {
+ Email string `json:"email"` // 邮箱
+ Code string `json:"code"` // 验证码
+ Nickname string `json:"nickname"` //昵称
+ Avatar string `json:"avatar"` //头像
+ Appid string `json:"appid"` //应用id
+ CountryCode string `json:"country_code" form:"country_code" gorm:"size:255"` //用户手机号国家代码 国际区号 86 中国 1美国
+}
+
+type UserBandPhone struct {
+ Phone string `json:"phone"` //手机号
+ Code string `json:"code"` //验证码
+}
+
+type UserPlatformAuth struct {
+ Platform Platform `json:"platform"` //平台
+ Tags string `json:"tags"` //个人标签
+}
+
+type Platform struct {
+ Platform string `json:"platform"` //平台 字典表获取
+ Label string `gorm:"-" json:"label"`
+ Url string `json:"url"` //主页地址
+ Image string `json:"image"` //图片
+ IsAuth bool `json:"is_auth"` //是否认证
+ CreatedAt *time.Time `json:"-" gorm:"-"` //创建时间
+}
+
+type UserAuthorized struct {
+ Appid string `json:"appid"` //应用id
+ Client string `json:"client"` //客户端 ios android web
+ Platform string `json:"platform"` //平台 google facebook twitter tiktok
+ Code string `json:"code"` //授权码
+ Token string `json:"token"` //token
+ Uuid string `json:"uuid"` //设备唯一标识
+}
diff --git a/model/request/wallet.go b/model/request/wallet.go
new file mode 100644
index 0000000..558d5fa
--- /dev/null
+++ b/model/request/wallet.go
@@ -0,0 +1,24 @@
+package request
+
+type AddAccount struct {
+ AccountName string `json:"account_name"` // 户名
+ BankCode string `json:"bank_code"` // 银行编码
+ SwiftCode string `json:"swift_code"` // swift编码
+ BankCard string `json:"bank_card"` // 银行卡号
+ Address string `json:"address"` // 收款人地址
+ Country string `json:"country"` // 国家/地区
+ Currency string `json:"currency"` // 币种 USD: 美元
+ IsDefault bool `json:"is_default"` // 是否默认
+}
+
+type DeleteAccount struct {
+ ID uint `json:"id"` //主键
+ Phone string `json:"phone"` //手机号
+ Code string `json:"code"` //验证码
+}
+
+type WithdrawalParams struct {
+ //Code string `json:"code"` // 验证码
+ Amount float64 `json:"amount"` // 提现金额
+ AccountID int `json:"accountID"` // 提现账户id
+}
diff --git a/model/response/banner.go b/model/response/banner.go
new file mode 100644
index 0000000..ed0180d
--- /dev/null
+++ b/model/response/banner.go
@@ -0,0 +1,16 @@
+package response
+
+import "pure/global"
+
+type BannerListResponse struct {
+ global.BASE_ID
+ RelationId string `json:"relationId"` //关联项目id
+ RelationType string `json:"relationType"` //关联类型 01-任务
+ Title string `json:"title"` //标题
+ CoverUrl string `json:"coverUrl"` //封面图
+ LinkType string `json:"linkType"` //链接类型 0:内链 1:外链
+ Link string `json:"link"` //链接地址
+ Type string `json:"type"` //任务-0101 平台奖励页-0102
+ Status string ` json:"status"` //状态 0=下架 1=上架
+ SortIndex int `json:"sort_index"` //序号索引
+}
diff --git a/model/response/chain.go b/model/response/chain.go
new file mode 100644
index 0000000..488a138
--- /dev/null
+++ b/model/response/chain.go
@@ -0,0 +1,10 @@
+package response
+
+import "time"
+
+type ChainResp struct {
+ Time *time.Time `json:"time"` // 上链时间
+ BlockHeight int64 `json:"block_height"` // 块高度
+ BlockAddress string `json:"block_adress"` // 所在区块
+ Hash string `json:"hash"` // 交易哈希
+}
diff --git a/model/response/common.go b/model/response/common.go
new file mode 100644
index 0000000..f6550c5
--- /dev/null
+++ b/model/response/common.go
@@ -0,0 +1,19 @@
+package response
+
+type PageResult struct {
+ List any `json:"list"`
+ Total int64 `json:"total"`
+ Page int `json:"page"`
+ PageSize int `json:"pageSize"`
+}
+
+type SelectListResult struct {
+ List any `json:"list"`
+}
+
+type TrackItem struct {
+ CheckpointDate string `json:"checkpoint_date"`
+ TrackingDetail string `json:"tracking_detail"`
+ DeliveryStatus string `json:"delivery_status"`
+ DeliveryStatusCn string `json:"delivery_status_cn"`
+}
diff --git a/model/response/mission.go b/model/response/mission.go
new file mode 100644
index 0000000..2c31118
--- /dev/null
+++ b/model/response/mission.go
@@ -0,0 +1,116 @@
+package response
+
+import (
+ "pure/model"
+ "time"
+)
+
+type MissionClaimView struct {
+ ID uint `json:"id"` //ID
+ ClaimNo string `json:"claim_no"` //领取任务编号
+ MissionId uint `json:"mission_id"` //任务id
+ AchieveNum int64 `json:"achieve_num"` //已完成商品数量
+ Status int `json:"status"` //状态 1:已领取待发货 2:已发货 3:已收货推广中
+ SpreadUrl string `json:"spread_url"` //推广链接
+ HireType int `json:"hire_type"` //佣金类型 1:固定佣金 2:比例抽成
+ HireMoneyExpect string `json:"hire_money_expect"` //预计佣金描述
+ EndTime *time.Time `json:"end_time"` //任务结束时间
+ ExpireAt time.Time `json:"expire_at"` //任务推广过期时间
+ CollectStatus bool `gorm:"-" json:"collect_status"` //收藏状态 true:已收藏 false:未收藏
+ Goods MissionGoodsView `json:"goods"`
+}
+
+type MissionCollectView struct {
+ ID uint `json:"id"` //ID
+ MissionId uint `json:"mission_id"` //任务id
+ AchieveNum int64 `json:"achieve_num"` //已完成商品数量
+ TotalBonus float64 `json:"total_bonus"`
+ Status int `json:"status"`
+ HireType int `json:"hire_type"` //佣金类型 1:固定佣金 2:比例抽成
+ HireMoneyExpect string `json:"hire_money_expect"` //预计佣金描述
+ Goods MissionGoodsView `json:"goods"`
+}
+
+type MissionGoodsView struct {
+ GoodsId uint `json:"goods_id"`
+ SpuNo string `json:"spu_no"` //编号
+ Title string `json:"title"` //标题
+ TitleEng string `json:"title_eng"` //英文标题
+ Images string `json:"images"` //图片
+ Price float64 `gorm:"type:decimal(10,2);" json:"price_min"` //最低规格价格
+ SkuNo string `json:"sku_no"` //sku编号
+
+}
+
+type MissionRecommendView struct {
+ ID uint `json:"id"` //ID
+ MissionId uint `json:"mission_id"` //任务id
+ AchieveNum int64 `json:"achieve_num"` //已完成商品数量
+ TotalBonus float64 `json:"total_bonus"`
+ Status int `json:"status"`
+ HireType int `json:"hire_type"` //佣金类型 1:固定佣金 2:比例抽成
+ HireMoneyExpect string `json:"hire_money_expect"` //预计佣金描述
+ Goods MissionGoodsView `json:"goods"`
+ Tags string `json:"tags"`
+}
+
+type MissionRecommendResponse struct {
+ model.MissionRecommend
+ MissionVideoCommonData
+}
+
+type MissionVideoResponse struct {
+ ID uint `json:"id"`
+ MissionVideoCommonData
+}
+
+type MissionVideoCommonData struct {
+ MissionId uint `json:"mission_id"` //任务ID
+ VideoUrl string `json:"video_url"` //视频地址
+ Cover string `json:"cover"` //封面
+ Title string `json:"title"` //任务标题
+ GoodsTitle string `json:"goods_title"` //商品标题
+ GoodsTitleEng string `json:"goods_title_eng"` //商品英文标题
+ Influencer model.UserSimple `json:"influencer"`
+ //todo 标签系统
+ Tag string `json:"tag"`
+ MissionStatus int `json:"mission_status"` //任务状态
+ StartTime *time.Time `json:"start_time"` //任务起始时间
+ EndTime *time.Time `json:"end_time"` //任务结束时间
+ HireType int `json:"hire_type"` //佣金类型 1:固定佣金 2:比例抽成
+ HireMoney float64 `json:"hire_money"` //hire_type==1 佣金金额
+ HireRatio float64 `json:"hire_ratio"` //hire_type==2 抽成比例
+ HireMoneyExpect string `gorm:"-" json:"hire_money_expect"` //预计佣金描述
+ ReleaseCountry string `gorm:"-" json:"release_country"` //发布国家
+ ReleaseChannels string `gorm:"-" json:"release_channels"` //发布渠道
+ AchieveNum int64 `json:"achieve_num"` //已完成商品数量
+ TotalBonus float64 `json:"total_bonus"` //累计奖励
+ BoughtNum float64 `json:"bought_num"` //购买人数
+ Width int `json:"width"` //宽度
+ Height int `json:"height"` //高度
+ ClaimNum int64 `json:"claim_num"` //任务领取人数
+}
+
+type SysMissionBonus struct {
+ VideoBonus SysBonusDetail `json:"video_bonus"` //视频上传
+ TotalBonus float64 `json:"total_bonus"` //奖励汇总金额
+ Total int64 `json:"total"` //奖励总笔数
+}
+
+type SysBonusDetail struct {
+ model.SysMissionBonus
+ Title string `json:"title"` //标题
+ AchieveMax int64 `json:"achieve_max"` //最大完成次数
+ MissionList []SysMissionDesc `json:"mission_list"` //任务列表
+}
+
+type SysMissionDesc struct {
+ Title string `json:"title"` //任务标题
+ Bonus float64 `json:"bonus"` //奖励金额
+ Description string `json:"description"` //描述
+ AchieveNum int `json:"achieve_num"`
+ Status int `json:"status"` //状态 1待发放 2已发放 3已领取 0未完成
+ TitleEng string `json:"title_eng"` //任务标题英文
+ DescriptionEng string `json:"description_eng"` //描述英文
+
+}
diff --git a/model/response/paypalOrder.go b/model/response/paypalOrder.go
new file mode 100644
index 0000000..17bc99f
--- /dev/null
+++ b/model/response/paypalOrder.go
@@ -0,0 +1,843 @@
+package response
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+ "sync"
+ "time"
+)
+
+const (
+ // APIBaseSandBox points to the sandbox (for testing) version of the API
+ APIBaseSandBox = "https://api.sandbox.paypal.com"
+
+ // APIBaseLive points to the live version of the API
+ APIBaseLive = "https://api.paypal.com"
+
+ // RequestNewTokenBeforeExpiresIn is used by SendWithAuth and try to get new Token when it's about to expire
+ RequestNewTokenBeforeExpiresIn = time.Duration(60) * time.Second
+)
+
+// Possible values for `no_shipping` in InputFields
+//
+// https://developer.paypal.com/docs/api/payment-experience/#definition-input_fields
+const (
+ NoShippingDisplay uint = 0
+ NoShippingHide uint = 1
+ NoShippingBuyerAccount uint = 2
+)
+
+// Possible values for `address_override` in InputFields
+//
+// https://developer.paypal.com/docs/api/payment-experience/#definition-input_fields
+const (
+ AddrOverrideFromFile uint = 0
+ AddrOverrideFromCall uint = 1
+)
+
+// Possible values for `landing_page_type` in FlowConfig
+//
+// https://developer.paypal.com/docs/api/payment-experience/#definition-flow_config
+const (
+ LandingPageTypeBilling string = "Billing"
+ LandingPageTypeLogin string = "Login"
+)
+
+// Possible value for `allowed_payment_method` in PaymentOptions
+//
+// https://developer.paypal.com/docs/api/payments/#definition-payment_options
+const (
+ AllowedPaymentUnrestricted string = "UNRESTRICTED"
+ AllowedPaymentInstantFundingSource string = "INSTANT_FUNDING_SOURCE"
+ AllowedPaymentImmediatePay string = "IMMEDIATE_PAY"
+)
+
+// Possible value for `intent` in CreateOrder
+//
+// https://developer.paypal.com/docs/api/orders/v2/#orders_create
+const (
+ OrderIntentCapture string = "CAPTURE"
+ OrderIntentAuthorize string = "AUTHORIZE"
+)
+
+// Possible values for `category` in Item
+//
+// https://developer.paypal.com/docs/api/orders/v2/#definition-item
+const (
+ ItemCategoryDigitalGood string = "DIGITAL_GOODS"
+ ItemCategoryPhysicalGood string = "PHYSICAL_GOODS"
+)
+
+// Possible values for `shipping_preference` in ApplicationContext
+//
+// https://developer.paypal.com/docs/api/orders/v2/#definition-application_context
+const (
+ ShippingPreferenceGetFromFile string = "GET_FROM_FILE"
+ ShippingPreferenceNoShipping string = "NO_SHIPPING"
+ ShippingPreferenceSetProvidedAddress string = "SET_PROVIDED_ADDRESS"
+)
+
+type (
+ // JSONTime overrides MarshalJson method to format in ISO8601
+ JSONTime time.Time
+
+ // Address struct
+ Address struct {
+ Line1 string `json:"line1"`
+ Line2 string `json:"line2,omitempty"`
+ City string `json:"city"`
+ CountryCode string `json:"country_code"`
+ PostalCode string `json:"postal_code,omitempty"`
+ State string `json:"state,omitempty"`
+ Phone string `json:"phone,omitempty"`
+ }
+
+ // AgreementDetails struct
+ AgreementDetails struct {
+ OutstandingBalance AmountPayout `json:"outstanding_balance"`
+ CyclesRemaining int `json:"cycles_remaining,string"`
+ CyclesCompleted int `json:"cycles_completed,string"`
+ NextBillingDate time.Time `json:"next_billing_date"`
+ LastPaymentDate time.Time `json:"last_payment_date"`
+ LastPaymentAmount AmountPayout `json:"last_payment_amount"`
+ FinalPaymentDate time.Time `json:"final_payment_date"`
+ FailedPaymentCount int `json:"failed_payment_count,string"`
+ }
+
+ // Amount struct
+ Amount struct {
+ Currency string `json:"currency"`
+ Total string `json:"total"`
+ Details Details `json:"details,omitempty"`
+ }
+
+ // AmountPayout struct
+ AmountPayout struct {
+ Currency string `json:"currency"`
+ Value string `json:"value"`
+ }
+
+ // ApplicationContext struct
+ ApplicationContext struct {
+ BrandName string `json:"brand_name,omitempty"`
+ Locale string `json:"locale,omitempty"`
+ LandingPage string `json:"landing_page,omitempty"`
+ ShippingPreference string `json:"shipping_preference,omitempty"`
+ UserAction string `json:"user_action,omitempty"`
+ ReturnURL string `json:"return_url,omitempty"`
+ CancelURL string `json:"cancel_url,omitempty"`
+ }
+
+ // Authorization struct
+ Authorization struct {
+ Amount *Amount `json:"amount,omitempty"`
+ CreateTime *time.Time `json:"create_time,omitempty"`
+ UpdateTime *time.Time `json:"update_time,omitempty"`
+ State string `json:"state,omitempty"`
+ ParentPayment string `json:"parent_payment,omitempty"`
+ ID string `json:"id,omitempty"`
+ ValidUntil *time.Time `json:"valid_until,omitempty"`
+ Links []Link `json:"links,omitempty"`
+ ClearingTime string `json:"clearing_time,omitempty"`
+ ProtectionEligibility string `json:"protection_eligibility,omitempty"`
+ ProtectionEligibilityType string `json:"protection_eligibility_type,omitempty"`
+ }
+
+ // AuthorizeOrderResponse .
+ AuthorizeOrderResponse struct {
+ CreateTime *time.Time `json:"create_time,omitempty"`
+ UpdateTime *time.Time `json:"update_time,omitempty"`
+ ID string `json:"id,omitempty"`
+ Status string `json:"status,omitempty"`
+ Intent string `json:"intent,omitempty"`
+ PurchaseUnits []PurchaseUnitRequest `json:"purchase_units,omitempty"`
+ Payer *PayerWithNameAndPhone `json:"payer,omitempty"`
+ }
+
+ // AuthorizeOrderRequest - https://developer.paypal.com/docs/api/orders/v2/#orders_authorize
+ AuthorizeOrderRequest struct {
+ PaymentSource *PaymentSource `json:"payment_source,omitempty"`
+ ApplicationContext ApplicationContext `json:"application_context,omitempty"`
+ }
+
+ // CaptureOrderRequest - https://developer.paypal.com/docs/api/orders/v2/#orders_capture
+ CaptureOrderRequest struct {
+ PaymentSource *PaymentSource `json:"payment_source"`
+ }
+
+ // BatchHeader struct
+ BatchHeader struct {
+ Amount *AmountPayout `json:"amount,omitempty"`
+ Fees *AmountPayout `json:"fees,omitempty"`
+ PayoutBatchID string `json:"payout_batch_id,omitempty"`
+ BatchStatus string `json:"batch_status,omitempty"`
+ TimeCreated *time.Time `json:"time_created,omitempty"`
+ TimeCompleted *time.Time `json:"time_completed,omitempty"`
+ SenderBatchHeader *SenderBatchHeader `json:"sender_batch_header,omitempty"`
+ }
+
+ // BillingAgreement struct
+ BillingAgreement struct {
+ Name string `json:"name,omitempty"`
+ Description string `json:"description,omitempty"`
+ StartDate JSONTime `json:"start_date,omitempty"`
+ Plan BillingPlan `json:"plan,omitempty"`
+ Payer Payer `json:"payer,omitempty"`
+ ShippingAddress *ShippingAddress `json:"shipping_address,omitempty"`
+ OverrideMerchantPreferences *MerchantPreferences `json:"override_merchant_preferences,omitempty"`
+ }
+
+ // BillingPlan struct
+ BillingPlan struct {
+ ID string `json:"id,omitempty"`
+ Name string `json:"name,omitempty"`
+ Description string `json:"description,omitempty"`
+ Type string `json:"type,omitempty"`
+ PaymentDefinitions []PaymentDefinition `json:"payment_definitions,omitempty"`
+ MerchantPreferences *MerchantPreferences `json:"merchant_preferences,omitempty"`
+ }
+
+ // Capture struct
+ Capture struct {
+ Amount *Amount `json:"amount,omitempty"`
+ IsFinalCapture bool `json:"is_final_capture"`
+ CreateTime *time.Time `json:"create_time,omitempty"`
+ UpdateTime *time.Time `json:"update_time,omitempty"`
+ State string `json:"state,omitempty"`
+ ParentPayment string `json:"parent_payment,omitempty"`
+ ID string `json:"id,omitempty"`
+ Links []Link `json:"links,omitempty"`
+ }
+
+ // ChargeModel struct
+ ChargeModel struct {
+ Type string `json:"type,omitempty"`
+ Amount AmountPayout `json:"amount,omitempty"`
+ }
+
+ // Client represents a Paypal REST API Client
+ Client struct {
+ sync.Mutex
+ Client *http.Client
+ ClientID string
+ Secret string
+ APIBase string
+ Log io.Writer // If user set log file name all requests will be logged there
+ Token *TokenResponse
+ tokenExpiresAt time.Time
+ }
+
+ // CreditCard struct
+ CreditCard struct {
+ ID string `json:"id,omitempty"`
+ PayerID string `json:"payer_id,omitempty"`
+ ExternalCustomerID string `json:"external_customer_id,omitempty"`
+ Number string `json:"number"`
+ Type string `json:"type"`
+ ExpireMonth string `json:"expire_month"`
+ ExpireYear string `json:"expire_year"`
+ CVV2 string `json:"cvv2,omitempty"`
+ FirstName string `json:"first_name,omitempty"`
+ LastName string `json:"last_name,omitempty"`
+ BillingAddress *Address `json:"billing_address,omitempty"`
+ State string `json:"state,omitempty"`
+ ValidUntil string `json:"valid_until,omitempty"`
+ }
+
+ // CreditCards GET /v1/vault/credit-cards
+ CreditCards struct {
+ Items []CreditCard `json:"items"`
+ Links []Link `json:"links"`
+ TotalItems int `json:"total_items"`
+ TotalPages int `json:"total_pages"`
+ }
+
+ // CreditCardToken struct
+ CreditCardToken struct {
+ CreditCardID string `json:"credit_card_id"`
+ PayerID string `json:"payer_id,omitempty"`
+ Last4 string `json:"last4,omitempty"`
+ ExpireYear string `json:"expire_year,omitempty"`
+ ExpireMonth string `json:"expire_month,omitempty"`
+ }
+
+ // CreditCardsFilter struct
+ CreditCardsFilter struct {
+ PageSize int
+ Page int
+ }
+
+ // CreditCardField PATCH /v1/vault/credit-cards/credit_card_id
+ CreditCardField struct {
+ Operation string `json:"op"`
+ Path string `json:"path"`
+ Value string `json:"value"`
+ }
+
+ // Currency struct
+ Currency struct {
+ Currency string `json:"currency,omitempty"`
+ Value string `json:"value,omitempty"`
+ }
+
+ // Details structure used in Amount structures as optional value
+ Details struct {
+ Subtotal string `json:"subtotal,omitempty"`
+ Shipping string `json:"shipping,omitempty"`
+ Tax string `json:"tax,omitempty"`
+ HandlingFee string `json:"handling_fee,omitempty"`
+ ShippingDiscount string `json:"shipping_discount,omitempty"`
+ Insurance string `json:"insurance,omitempty"`
+ GiftWrap string `json:"gift_wrap,omitempty"`
+ }
+
+ // ErrorResponseDetail struct
+ ErrorResponseDetail struct {
+ Field string `json:"field"`
+ Issue string `json:"issue"`
+ Links []Link `json:"link"`
+ }
+
+ // ErrorResponse https://developer.paypal.com/docs/api/errors/
+ ErrorResponse struct {
+ Response *http.Response `json:"-"`
+ Name string `json:"name"`
+ DebugID string `json:"debug_id"`
+ Message string `json:"message"`
+ InformationLink string `json:"information_link"`
+ Details []ErrorResponseDetail `json:"details"`
+ }
+
+ // ExecuteAgreementResponse struct
+ ExecuteAgreementResponse struct {
+ ID string `json:"id"`
+ State string `json:"state"`
+ Description string `json:"description,omitempty"`
+ Payer Payer `json:"payer"`
+ Plan BillingPlan `json:"plan"`
+ StartDate time.Time `json:"start_date"`
+ ShippingAddress ShippingAddress `json:"shipping_address"`
+ AgreementDetails AgreementDetails `json:"agreement_details"`
+ Links []Link `json:"links"`
+ }
+
+ // ExecuteResponse struct
+ ExecuteResponse struct {
+ ID string `json:"id"`
+ Links []Link `json:"links"`
+ State string `json:"state"`
+ Payer PaymentPayer `json:"payer"`
+ Transactions []Transaction `json:"transactions,omitempty"`
+ }
+
+ // FundingInstrument struct
+ FundingInstrument struct {
+ CreditCard *CreditCard `json:"credit_card,omitempty"`
+ CreditCardToken *CreditCardToken `json:"credit_card_token,omitempty"`
+ }
+
+ // Item struct
+ Item struct {
+ Quantity uint32 `json:"quantity"`
+ Name string `json:"name"`
+ Price string `json:"price"`
+ Currency string `json:"currency"`
+ SKU string `json:"sku,omitempty"`
+ Description string `json:"description,omitempty"`
+ Tax string `json:"tax,omitempty"`
+ UnitAmount *Money `json:"unit_amount,omitempty"`
+ Category string `json:"category,omitempty"`
+ }
+
+ // ItemList struct
+ ItemList struct {
+ Items []Item `json:"items,omitempty"`
+ ShippingAddress *ShippingAddress `json:"shipping_address,omitempty"`
+ }
+
+ // Link struct
+ Link struct {
+ Href string `json:"href"`
+ Rel string `json:"rel,omitempty"`
+ Method string `json:"method,omitempty"`
+ Enctype string `json:"enctype,omitempty"`
+ }
+
+ // PurchaseUnitAmount struct
+ PurchaseUnitAmount struct {
+ Currency string `json:"currency_code"`
+ Value string `json:"value"`
+ Breakdown *PurchaseUnitAmountBreakdown `json:"breakdown,omitempty"`
+ }
+
+ // PurchaseUnitAmountBreakdown struct
+ PurchaseUnitAmountBreakdown struct {
+ ItemTotal *Money `json:"item_total,omitempty"`
+ Shipping *Money `json:"shipping,omitempty"`
+ Handling *Money `json:"handling,omitempty"`
+ TaxTotal *Money `json:"tax_total,omitempty"`
+ Insurance *Money `json:"insurance,omitempty"`
+ ShippingDiscount *Money `json:"shipping_discount,omitempty"`
+ Discount *Money `json:"discount,omitempty"`
+ }
+
+ // Money struct
+ //
+ // https://developer.paypal.com/docs/api/orders/v2/#definition-money
+ Money struct {
+ Currency string `json:"currency_code"`
+ Value string `json:"value"`
+ }
+
+ // PurchaseUnit struct
+ PurchaseUnit struct {
+ ReferenceID string `json:"reference_id"`
+ Amount *PurchaseUnitAmount `json:"amount,omitempty"`
+ }
+
+ // TaxInfo used for orders.
+ TaxInfo struct {
+ TaxID string `json:"tax_id,omitempty"`
+ TaxIDType string `json:"tax_id_type,omitempty"`
+ }
+
+ // PhoneWithTypeNumber struct for PhoneWithType
+ PhoneWithTypeNumber struct {
+ NationalNumber string `json:"national_number,omitempty"`
+ }
+
+ // PhoneWithType struct used for orders
+ PhoneWithType struct {
+ PhoneType string `json:"phone_type,omitempty"`
+ PhoneNumber *PhoneWithTypeNumber `json:"phone_number,omitempty"`
+ }
+
+ // CreateOrderPayerName create order payer name
+ CreateOrderPayerName struct {
+ GivenName string `json:"given_name,omitempty"`
+ Surname string `json:"surname,omitempty"`
+ }
+
+ // CreateOrderPayer used with create order requests
+ CreateOrderPayer struct {
+ Name *CreateOrderPayerName `json:"name,omitempty"`
+ EmailAddress string `json:"email_address,omitempty"`
+ PayerID string `json:"payer_id,omitempty"`
+ Phone *PhoneWithType `json:"phone,omitempty"`
+ BirthDate string `json:"birth_date,omitempty"`
+ TaxInfo *TaxInfo `json:"tax_info,omitempty"`
+ Address *ShippingDetailAddressPortable `json:"address,omitempty"`
+ }
+
+ // PurchaseUnitRequest struct
+ PurchaseUnitRequest struct {
+ ReferenceID string `json:"reference_id,omitempty"`
+ Amount *PurchaseUnitAmount `json:"amount"`
+ Payee *PayeeForOrders `json:"payee,omitempty"`
+ Description string `json:"description,omitempty"`
+ CustomID string `json:"custom_id,omitempty"`
+ InvoiceID string `json:"invoice_id,omitempty"`
+ SoftDescriptor string `json:"soft_descriptor,omitempty"`
+ Items []Item `json:"items,omitempty"`
+ Shipping *ShippingDetail `json:"shipping,omitempty"`
+ }
+
+ // MerchantPreferences struct
+ MerchantPreferences struct {
+ SetupFee *AmountPayout `json:"setup_fee,omitempty"`
+ ReturnURL string `json:"return_url,omitempty"`
+ CancelURL string `json:"cancel_url,omitempty"`
+ AutoBillAmount string `json:"auto_bill_amount,omitempty"`
+ InitialFailAmountAction string `json:"initial_fail_amount_action,omitempty"`
+ MaxFailAttempts string `json:"max_fail_attempts,omitempty"`
+ }
+
+ // Order struct
+ Order struct {
+ ID string `json:"id,omitempty"`
+ Status string `json:"status,omitempty"`
+ Intent string `json:"intent,omitempty"`
+ PurchaseUnits []PurchaseUnit `json:"purchase_units,omitempty"`
+ Links []Link `json:"links,omitempty"`
+ CreateTime *time.Time `json:"create_time,omitempty"`
+ UpdateTime *time.Time `json:"update_time,omitempty"`
+ }
+
+ // CaptureAmount struct
+ CaptureAmount struct {
+ ID string `json:"id,omitempty"`
+ Amount *PurchaseUnitAmount `json:"amount,omitempty"`
+ }
+
+ // CapturedPayments has the amounts for a captured order
+ CapturedPayments struct {
+ Captures []CaptureAmount `json:"captures,omitempty"`
+ }
+
+ // CapturedPurchaseUnit are purchase units for a captured order
+ CapturedPurchaseUnit struct {
+ Payments *CapturedPayments `json:"payments,omitempty"`
+ }
+
+ // PayerWithNameAndPhone struct
+ PayerWithNameAndPhone struct {
+ Name *CreateOrderPayerName `json:"name,omitempty"`
+ EmailAddress string `json:"email_address,omitempty"`
+ Phone *PhoneWithType `json:"phone,omitempty"`
+ PayerID string `json:"payer_id,omitempty"`
+ }
+
+ // CaptureOrderResponse is the response for capture order
+ CaptureOrderResponse struct {
+ ID string `json:"id,omitempty"`
+ Status string `json:"status,omitempty"`
+ Payer *PayerWithNameAndPhone `json:"payer,omitempty"`
+ PurchaseUnits []CapturedPurchaseUnit `json:"purchase_units,omitempty"`
+ }
+
+ // Payer struct
+ Payer struct {
+ PaymentMethod string `json:"payment_method"`
+ FundingInstruments []FundingInstrument `json:"funding_instruments,omitempty"`
+ PayerInfo *PayerInfo `json:"payer_info,omitempty"`
+ Status string `json:"payer_status,omitempty"`
+ }
+
+ // PayerInfo struct
+ PayerInfo struct {
+ Email string `json:"email,omitempty"`
+ FirstName string `json:"first_name,omitempty"`
+ LastName string `json:"last_name,omitempty"`
+ PayerID string `json:"payer_id,omitempty"`
+ Phone string `json:"phone,omitempty"`
+ ShippingAddress *ShippingAddress `json:"shipping_address,omitempty"`
+ TaxIDType string `json:"tax_id_type,omitempty"`
+ TaxID string `json:"tax_id,omitempty"`
+ CountryCode string `json:"country_code"`
+ }
+
+ // PaymentDefinition struct
+ PaymentDefinition struct {
+ ID string `json:"id,omitempty"`
+ Name string `json:"name,omitempty"`
+ Type string `json:"type,omitempty"`
+ Frequency string `json:"frequency,omitempty"`
+ FrequencyInterval string `json:"frequency_interval,omitempty"`
+ Amount AmountPayout `json:"amount,omitempty"`
+ Cycles string `json:"cycles,omitempty"`
+ ChargeModels []ChargeModel `json:"charge_models,omitempty"`
+ }
+
+ // PaymentOptions struct
+ PaymentOptions struct {
+ AllowedPaymentMethod string `json:"allowed_payment_method,omitempty"`
+ }
+
+ // PaymentPatch PATCH /v2/payments/payment/{payment_id)
+ PaymentPatch struct {
+ Operation string `json:"op"`
+ Path string `json:"path"`
+ Value interface{} `json:"value"`
+ }
+
+ // PaymentPayer struct
+ PaymentPayer struct {
+ PaymentMethod string `json:"payment_method"`
+ Status string `json:"status,omitempty"`
+ PayerInfo *PayerInfo `json:"payer_info,omitempty"`
+ }
+
+ // PaymentResponse structure
+ PaymentResponse struct {
+ ID string `json:"id"`
+ State string `json:"state"`
+ Intent string `json:"intent"`
+ Payer Payer `json:"payer"`
+ Transactions []Transaction `json:"transactions"`
+ Links []Link `json:"links"`
+ }
+
+ // PaymentSource structure
+ PaymentSource struct {
+ Card *PaymentSourceCard `json:"card"`
+ Token *PaymentSourceToken `json:"token"`
+ }
+
+ // PaymentSourceCard structure
+ PaymentSourceCard struct {
+ ID string `json:"id"`
+ Name string `json:"name"`
+ Number string `json:"number"`
+ Expiry string `json:"expiry"`
+ SecurityCode string `json:"security_code"`
+ LastDigits string `json:"last_digits"`
+ CardType string `json:"card_type"`
+ BillingAddress *CardBillingAddress `json:"billing_address"`
+ }
+
+ // CardBillingAddress structure
+ CardBillingAddress struct {
+ AddressLine1 string `json:"address_line_1"`
+ AddressLine2 string `json:"address_line_2"`
+ AdminArea2 string `json:"admin_area_2"`
+ AdminArea1 string `json:"admin_area_1"`
+ PostalCode string `json:"postal_code"`
+ CountryCode string `json:"country_code"`
+ }
+
+ // PaymentSourceToken structure
+ PaymentSourceToken struct {
+ ID string `json:"id"`
+ Type string `json:"type"`
+ }
+
+ // Payout struct
+ Payout struct {
+ SenderBatchHeader *SenderBatchHeader `json:"sender_batch_header"`
+ Items []PayoutItem `json:"items"`
+ }
+
+ // PayoutItem struct
+ PayoutItem struct {
+ RecipientType string `json:"recipient_type"`
+ Receiver string `json:"receiver"`
+ Amount *AmountPayout `json:"amount"`
+ Note string `json:"note,omitempty"`
+ SenderItemID string `json:"sender_item_id,omitempty"`
+ }
+
+ // PayoutItemResponse struct
+ PayoutItemResponse struct {
+ PayoutItemID string `json:"payout_item_id"`
+ TransactionID string `json:"transaction_id"`
+ TransactionStatus string `json:"transaction_status"`
+ PayoutBatchID string `json:"payout_batch_id,omitempty"`
+ PayoutItemFee *AmountPayout `json:"payout_item_fee,omitempty"`
+ PayoutItem *PayoutItem `json:"payout_item"`
+ TimeProcessed *time.Time `json:"time_processed,omitempty"`
+ Links []Link `json:"links"`
+ Error ErrorResponse `json:"errors,omitempty"`
+ }
+
+ // PayoutResponse struct
+ PayoutResponse struct {
+ BatchHeader *BatchHeader `json:"batch_header"`
+ Items []PayoutItemResponse `json:"items"`
+ Links []Link `json:"links"`
+ }
+
+ // RedirectURLs struct
+ RedirectURLs struct {
+ ReturnURL string `json:"return_url,omitempty"`
+ CancelURL string `json:"cancel_url,omitempty"`
+ }
+
+ // Refund struct
+ Refund struct {
+ ID string `json:"id,omitempty"`
+ Amount *Amount `json:"amount,omitempty"`
+ CreateTime *time.Time `json:"create_time,omitempty"`
+ State string `json:"state,omitempty"`
+ CaptureID string `json:"capture_id,omitempty"`
+ ParentPayment string `json:"parent_payment,omitempty"`
+ UpdateTime *time.Time `json:"update_time,omitempty"`
+ }
+
+ // RefundResponse .
+ RefundResponse struct {
+ ID string `json:"id,omitempty"`
+ Amount *PurchaseUnitAmount `json:"amount,omitempty"`
+ Status string `json:"status,omitempty"`
+ }
+
+ // Related struct
+ Related struct {
+ Sale *Sale `json:"sale,omitempty"`
+ Authorization *Authorization `json:"authorization,omitempty"`
+ Order *Order `json:"order,omitempty"`
+ Capture *Capture `json:"capture,omitempty"`
+ Refund *Refund `json:"refund,omitempty"`
+ }
+
+ // Sale struct
+ Sale struct {
+ ID string `json:"id,omitempty"`
+ Amount *Amount `json:"amount,omitempty"`
+ TransactionFee *Currency `json:"transaction_fee,omitempty"`
+ Description string `json:"description,omitempty"`
+ CreateTime *time.Time `json:"create_time,omitempty"`
+ State string `json:"state,omitempty"`
+ ParentPayment string `json:"parent_payment,omitempty"`
+ UpdateTime *time.Time `json:"update_time,omitempty"`
+ PaymentMode string `json:"payment_mode,omitempty"`
+ PendingReason string `json:"pending_reason,omitempty"`
+ ReasonCode string `json:"reason_code,omitempty"`
+ ClearingTime string `json:"clearing_time,omitempty"`
+ ProtectionEligibility string `json:"protection_eligibility,omitempty"`
+ ProtectionEligibilityType string `json:"protection_eligibility_type,omitempty"`
+ Links []Link `json:"links,omitempty"`
+ }
+
+ // SenderBatchHeader struct
+ SenderBatchHeader struct {
+ EmailSubject string `json:"email_subject"`
+ SenderBatchID string `json:"sender_batch_id,omitempty"`
+ }
+
+ // ShippingAddress struct
+ ShippingAddress struct {
+ RecipientName string `json:"recipient_name,omitempty"`
+ Type string `json:"type,omitempty"`
+ Line1 string `json:"line1"`
+ Line2 string `json:"line2,omitempty"`
+ City string `json:"city"`
+ CountryCode string `json:"country_code"`
+ PostalCode string `json:"postal_code,omitempty"`
+ State string `json:"state,omitempty"`
+ Phone string `json:"phone,omitempty"`
+ }
+
+ // ShippingDetailAddressPortable used with create orders
+ ShippingDetailAddressPortable struct {
+ AddressLine1 string `json:"address_line_1,omitempty"`
+ AddressLine2 string `json:"address_line_2,omitempty"`
+ AdminArea1 string `json:"admin_area_1,omitempty"`
+ AdminArea2 string `json:"admin_area_2,omitempty"`
+ PostalCode string `json:"postal_code,omitempty"`
+ CountryCode string `json:"country_code,omitempty"`
+ }
+
+ // Name struct
+ Name struct {
+ FullName string `json:"full_name,omitempty"`
+ }
+
+ // ShippingDetail struct
+ ShippingDetail struct {
+ Name *Name `json:"name,omitempty"`
+ Address *ShippingDetailAddressPortable `json:"address,omitempty"`
+ }
+
+ expirationTime int64
+
+ // TokenResponse is for API response for the /oauth2/token endpoint
+ TokenResponse struct {
+ RefreshToken string `json:"refresh_token"`
+ Token string `json:"access_token"`
+ Type string `json:"token_type"`
+ ExpiresIn expirationTime `json:"expires_in"`
+ }
+
+ // Transaction struct
+ Transaction struct {
+ Amount *Amount `json:"amount"`
+ Description string `json:"description,omitempty"`
+ ItemList *ItemList `json:"item_list,omitempty"`
+ InvoiceNumber string `json:"invoice_number,omitempty"`
+ Custom string `json:"custom,omitempty"`
+ SoftDescriptor string `json:"soft_descriptor,omitempty"`
+ RelatedResources []Related `json:"related_resources,omitempty"`
+ PaymentOptions *PaymentOptions `json:"payment_options,omitempty"`
+ NotifyURL string `json:"notify_url,omitempty"`
+ OrderURL string `json:"order_url,omitempty"`
+ Payee *Payee `json:"payee,omitempty"`
+ }
+
+ //Payee struct
+ Payee struct {
+ Email string `json:"email"`
+ }
+
+ // PayeeForOrders struct
+ PayeeForOrders struct {
+ EmailAddress string `json:"email_address,omitempty"`
+ MerchantID string `json:"merchant_id,omitempty"`
+ }
+
+ // UserInfo struct
+ UserInfo struct {
+ ID string `json:"user_id"`
+ Name string `json:"name"`
+ GivenName string `json:"given_name"`
+ FamilyName string `json:"family_name"`
+ Email string `json:"email"`
+ Verified bool `json:"verified,omitempty,string"`
+ Gender string `json:"gender,omitempty"`
+ BirthDate string `json:"birthdate,omitempty"`
+ ZoneInfo string `json:"zoneinfo,omitempty"`
+ Locale string `json:"locale,omitempty"`
+ Phone string `json:"phone_number,omitempty"`
+ Address *Address `json:"address,omitempty"`
+ VerifiedAccount bool `json:"verified_account,omitempty,string"`
+ AccountType string `json:"account_type,omitempty"`
+ AgeRange string `json:"age_range,omitempty"`
+ PayerID string `json:"payer_id,omitempty"`
+ }
+
+ // WebProfile represents the configuration of the payment web payment experience
+ //
+ // https://developer.paypal.com/docs/api/payment-experience/
+ WebProfile struct {
+ ID string `json:"id,omitempty"`
+ Name string `json:"name"`
+ Presentation Presentation `json:"presentation,omitempty"`
+ InputFields InputFields `json:"input_fields,omitempty"`
+ FlowConfig FlowConfig `json:"flow_config,omitempty"`
+ }
+
+ // Presentation represents the branding and locale that a customer sees on
+ // redirect payments
+ //
+ // https://developer.paypal.com/docs/api/payment-experience/#definition-presentation
+ Presentation struct {
+ BrandName string `json:"brand_name,omitempty"`
+ LogoImage string `json:"logo_image,omitempty"`
+ LocaleCode string `json:"locale_code,omitempty"`
+ }
+
+ // InputFields represents the fields that are displayed to a customer on
+ // redirect payments
+ //
+ // https://developer.paypal.com/docs/api/payment-experience/#definition-input_fields
+ InputFields struct {
+ AllowNote bool `json:"allow_note,omitempty"`
+ NoShipping uint `json:"no_shipping,omitempty"`
+ AddressOverride uint `json:"address_override,omitempty"`
+ }
+
+ // FlowConfig represents the general behaviour of redirect payment pages
+ //
+ // https://developer.paypal.com/docs/api/payment-experience/#definition-flow_config
+ FlowConfig struct {
+ LandingPageType string `json:"landing_page_type,omitempty"`
+ BankTXNPendingURL string `json:"bank_txn_pending_url,omitempty"`
+ UserAction string `json:"user_action,omitempty"`
+ }
+)
+
+// Error method implementation for ErrorResponse struct
+func (r *ErrorResponse) Error() string {
+ return fmt.Sprintf("%v %v: %d %s", r.Response.Request.Method, r.Response.Request.URL, r.Response.StatusCode, r.Message)
+}
+
+// MarshalJSON for JSONTime
+func (t JSONTime) MarshalJSON() ([]byte, error) {
+ stamp := fmt.Sprintf(`"%s"`, time.Time(t).UTC().Format(time.RFC3339))
+ return []byte(stamp), nil
+}
+
+func (e *expirationTime) UnmarshalJSON(b []byte) error {
+ var n json.Number
+ err := json.Unmarshal(b, &n)
+ if err != nil {
+ return err
+ }
+ i, err := n.Int64()
+ if err != nil {
+ return err
+ }
+ *e = expirationTime(i)
+ return nil
+}
diff --git a/model/response/response.go b/model/response/response.go
new file mode 100644
index 0000000..bd4d43d
--- /dev/null
+++ b/model/response/response.go
@@ -0,0 +1,86 @@
+package response
+
+import (
+ "net/http"
+ "pure/utils"
+
+ "github.com/gin-gonic/gin"
+)
+
+type Response struct {
+ Code int `json:"code"`
+ Data interface{} `json:"data"`
+ Msg string `json:"msg"`
+}
+
+const (
+ ERROR = 7 //token过期
+ API_ERROR = 1 //接口返回错误
+ SUCCESS = 0
+)
+
+func Result(code int, data interface{}, msg string, c *gin.Context) {
+ // 开始时间
+ c.JSON(http.StatusOK, Response{
+ code,
+ data,
+ msg,
+ })
+}
+
+func Ok(c *gin.Context) {
+ Result(SUCCESS, map[string]interface{}{}, "操作成功", c)
+}
+
+func OkWithMessage(message string, c *gin.Context) {
+ trs := utils.InterTranslate(message, "zh", "en")
+ if trs != "" {
+ message = trs
+ }
+ Result(SUCCESS, map[string]interface{}{}, message, c)
+}
+
+func OkWithDataMessage(data interface{}, message string, c *gin.Context) {
+ trs := utils.InterTranslate(message, "zh", "en")
+ if trs != "" {
+ message = trs
+ }
+ Result(SUCCESS, data, message, c)
+}
+
+func OkWithData(data interface{}, c *gin.Context) {
+ message := "操作成功"
+ trs := utils.InterTranslate(message, "zh", "en")
+ if trs != "" {
+ message = trs
+ }
+ Result(SUCCESS, data, message, c)
+}
+
+func OkWithDetailed(data interface{}, message string, c *gin.Context) {
+ trs := utils.InterTranslate(message, "zh", "en")
+ if trs != "" {
+ message = trs
+ }
+ Result(SUCCESS, data, message, c)
+}
+
+func Fail(c *gin.Context) {
+ Result(ERROR, map[string]interface{}{}, "操作失败", c)
+}
+
+func FailWithMessage(message string, c *gin.Context) {
+ trs := utils.InterTranslate(message, "zh", "en")
+ if trs != "" {
+ message = trs
+ }
+ Result(API_ERROR, map[string]interface{}{}, message, c)
+}
+
+func FailWithDetailed(data interface{}, message string, c *gin.Context) {
+ trs := utils.InterTranslate(message, "zh", "en")
+ if trs != "" {
+ message = trs
+ }
+ Result(ERROR, data, message, c)
+}
diff --git a/model/response/tripartite.go b/model/response/tripartite.go
new file mode 100644
index 0000000..92f02d9
--- /dev/null
+++ b/model/response/tripartite.go
@@ -0,0 +1,26 @@
+package response
+
+type TripartiteGoogle struct {
+ ID string `json:"id"`
+ Sub string `json:"sub"`
+ Email string `json:"email"`
+ VerifiedEmail bool `json:"verified_email"`
+ Name string `json:"name"`
+ GivenName string `json:"given_name"`
+ FamilyName string `json:"family_name"`
+ Picture string `json:"picture"`
+ Locale string `json:"locale"`
+}
+
+type TripartiteTwitter struct {
+ Data struct {
+ ID string `json:"id"`
+ Name string `json:"name"`
+ UserName string `json:"username"`
+ } `json:"data"`
+}
+
+type TripartiteInstagram struct {
+ ID string `json:"id"`
+ Username string `json:"username"`
+}
diff --git a/model/response/user.go b/model/response/user.go
new file mode 100755
index 0000000..16fec0e
--- /dev/null
+++ b/model/response/user.go
@@ -0,0 +1,25 @@
+package response
+
+import "pure/model"
+
+type LoginResponse struct {
+ User model.User `json:"user"`
+ Token string `json:"token"`
+ ExpiresAt int64 `json:"expiresAt"`
+}
+
+type TiktokResponse struct {
+ Data struct {
+ User model.TiktokUser `json:"user"`
+ } `json:"data"`
+ Error struct {
+ Code string `json:"code"`
+ Message string `json:"message"`
+ } `json:"error"`
+}
+
+type UserStatistics struct {
+ CollectionMissionNum int64 `json:"collection_mission_num"` //收藏任务数量
+ ClaimMissionNum int64 `json:"claim_mission_num"` //领取任务数量
+ PlatformNum int64 `json:"platform_num"` //认证平台数量
+}
diff --git a/model/seller_store.go b/model/seller_store.go
new file mode 100644
index 0000000..d8e4e39
--- /dev/null
+++ b/model/seller_store.go
@@ -0,0 +1,26 @@
+package model
+
+import "pure/global"
+
+type SellerStore struct { //店铺
+ StoreNo string `gorm:"unique;type:varchar(60);" json:"store_no"` //店铺编号
+ Type int `gorm:"type:tinyint(1)" json:"type"` //1:个人店铺
+ CreateBy string `gorm:"type:varchar(60);" json:"create_by"` //创建人
+ Email string `gorm:"type:varchar(100);" json:"email"` //店铺联系email(注册账号email)
+ global.MG_MODEL
+}
+
+type SellerStoreInfo struct {
+ StoreNo string `json:"store_no"` //店铺编号
+ Type int `json:"type"` //1:个人店铺
+ CreateBy string `json:"-"` //
+ Email string `json:"email"` //店铺联系email(注册账号email)
+}
+
+func (SellerStore) TableName() string {
+ return "seller_store"
+}
+
+func (SellerStoreInfo) TableName() string {
+ return "seller_store"
+}
diff --git a/model/sys_brochure.go b/model/sys_brochure.go
new file mode 100644
index 0000000..2aa0021
--- /dev/null
+++ b/model/sys_brochure.go
@@ -0,0 +1,16 @@
+package model
+
+import "pure/global"
+
+type SysBrochure struct { //单页 协议、条款等
+ global.BASE_ID
+ Title string `gorm:"size:10" json:"title"` //标题
+ Type string `gorm:"size:30" json:"type"` //类型
+ Content string `gorm:"type:mediumtext" json:"content"` //内容
+ Src string `gorm:"size:500" json:"src"` //静态页面html
+ global.TIME_MODEL
+}
+
+func (SysBrochure) TableName() string {
+ return "sys_brochure"
+}
diff --git a/model/sys_jwt_blacklist.go b/model/sys_jwt_blacklist.go
new file mode 100755
index 0000000..a9391c6
--- /dev/null
+++ b/model/sys_jwt_blacklist.go
@@ -0,0 +1,8 @@
+package model
+
+import "pure/global"
+
+type JwtBlacklist struct {
+ Jwt string `gorm:"type:text;comment:jwt"`
+ global.MG_MODEL
+}
diff --git a/model/sys_mission_reward.go b/model/sys_mission_reward.go
new file mode 100644
index 0000000..25da40f
--- /dev/null
+++ b/model/sys_mission_reward.go
@@ -0,0 +1,28 @@
+package model
+
+import "pure/global"
+
+// 平台任务奖励
+type SysMissionReward struct {
+ global.MG_MODEL
+ Title string `json:"title" gorm:"size:255"` //标题
+ Type int `json:"type" gorm:"tinyint(1) comment:奖励类型 1.视频上传 2.信息完善 3.商家任务"` //奖励类型 1.视频上传 2.信息完善 3.商家任务
+ RelationId string `gorm:"size:64" json:"relationId"` //关联项目id
+ Bonus float64 `json:"bonus" gorm:"type:decimal(10,2)"` //奖励金额
+ Status int `gorm:"type:int(1)" json:"status"` //状态 1待发放 2已发放 3已领取
+ AchieveNum int64 `gorm:"type:int(11)" json:"achieve_num"` //已完成任务次数
+ CreateBy string `gorm:"size:64" json:"create_by"` //创建人
+ UpdateBy string `gorm:"size:64" json:"update_by"` //更新人
+ AuditBy string `gorm:"size:64" json:"audit_by"` //审核人
+}
+
+type SysMissionBonus struct {
+ Total int64 `json:"total"` //奖励次数
+ Bonus float64 `json:"bonus"` //奖金
+ Type int `json:"type"` //奖励类型 1.视频上传 2.信息完善 3.商家任务
+ AchieveNum int64 `json:"achieve_num"` //已完成任务次数
+}
+
+func (SysMissionReward) TableName() string {
+ return "sys_mission_reward"
+}
diff --git a/model/tag_relation.go b/model/tag_relation.go
new file mode 100644
index 0000000..344615a
--- /dev/null
+++ b/model/tag_relation.go
@@ -0,0 +1,26 @@
+package model
+
+import "pure/global"
+
+// 组件内容
+type TagRelation struct {
+ global.MG_MODEL
+ TagId uint `json:"tagId"` //组件id
+ RelationId string `gorm:"size:50" json:"relationId"` //关联项目id
+ RelationType string `gorm:"size:4" json:"relationType"` //项目类型 01-任务 02-任务视频 03-网红
+ CreateBy string `gorm:"size:64" json:"createBy"` //创建人
+ UpdateBy string `gorm:"size:64" json:"updateBy"` //更新人
+}
+
+type TagRelationDesc struct {
+ global.BASE_ID_STR
+ Name string `gorm:"size:20" json:"name"` //标签名称
+}
+
+func (TagRelation) TableName() string {
+ return "tag_relation"
+}
+
+func (TagRelationDesc) TableName() string {
+ return "tag_relation"
+}
diff --git a/model/tags.go b/model/tags.go
new file mode 100644
index 0000000..41beb98
--- /dev/null
+++ b/model/tags.go
@@ -0,0 +1,26 @@
+package model
+
+import (
+ "pure/global"
+)
+
+type Tags struct { //标签
+ Value string `gorm:"size:100" json:"value"` //值
+ CreateBy string `gorm:"size:64" json:"createBy"` //创建人
+ UpdateBy string `gorm:"size:64" json:"updateBy"` //修改人
+ Type string `gorm:"size:10; comment:类型" json:"type"` //标签类型 01-任务 02-任务视频 03-网红
+ global.MG_MODEL
+}
+
+type TagsDesc struct {
+ global.BASE_ID
+ Value string `gorm:"size:100" json:"value"` //值
+}
+
+func (Tags) TableName() string {
+ return "tags"
+}
+
+func (TagsDesc) TableName() string {
+ return "tags"
+}
diff --git a/model/tb_attribute.go b/model/tb_attribute.go
new file mode 100644
index 0000000..858e40c
--- /dev/null
+++ b/model/tb_attribute.go
@@ -0,0 +1,41 @@
+package model
+
+import "pure/global"
+
+type TbAttribute struct { //属性表
+ Name string `gorm:"type:varchar(255);not null;" json:"name"` //规格名称
+ Status int `gorm:"type:tinyint(1);not null;comment:状态 1:正常" json:"status"`
+ global.MG_MODEL
+}
+
+type TbAttributeView struct {
+ ID uint `json:"id"`
+ Name string `json:"name"`
+}
+
+type TbAttributeDetail struct {
+ AttributeId uint `json:"attribute_id"` //规格属性id
+ Value string `json:"value"` //
+ ValueId uint `json:"value_id"` //
+}
+
+type TbAttributeWithValues struct {
+ TbAttributeView
+ Values []TbAttributeValueItem `gorm:"-" json:"values"`
+}
+
+func (TbAttribute) TableName() string {
+ return "tb_attribute"
+}
+
+func (TbAttributeView) TableName() string {
+ return "tb_attribute"
+}
+
+func (TbAttributeWithValues) TableName() string {
+ return "tb_attribute"
+}
+
+func (TbAttributeDetail) TableName() string {
+ return "tb_attribute"
+}
diff --git a/model/tb_attribute_value.go b/model/tb_attribute_value.go
new file mode 100644
index 0000000..96e8fa5
--- /dev/null
+++ b/model/tb_attribute_value.go
@@ -0,0 +1,25 @@
+package model
+
+import "pure/global"
+
+type TbAttributeValue struct { //规格属性取值
+ AttributeId uint `gorm:"type:int(11);not null;" json:"attribute_id"` //attribute_id
+ Name string `gorm:"type:varchar(255);not null;" json:"name"` //属性取值
+ Status int `gorm:"type:tinyint(1);comment:状态 1:正常" json:"status"`
+ global.MG_MODEL
+}
+
+type TbAttributeValueItem struct {
+ Id uint `json:"id"`
+ Name string `json:"name"` //规格属性值
+ Image string `json:"image"` //图片
+}
+
+type TbAttributeValueJson struct {
+ Str string `json:"str"`
+ Items []TbAttributeValueItem `json:"names"`
+}
+
+func (TbAttributeValue) TableName() string {
+ return "tb_attribute_value"
+}
diff --git a/model/tb_category.go b/model/tb_category.go
new file mode 100644
index 0000000..b34bb4c
--- /dev/null
+++ b/model/tb_category.go
@@ -0,0 +1,15 @@
+package model
+
+import "pure/global"
+
+type TbCategory struct { //商品分类
+ Name string `gorm:"type:varchar(100);not null;comment:商品分类名称" json:"name"`
+ Pid uint `gorm:"type:int(11);comment:父id" json:"pid"` //父id
+ IsLeaf bool `gorm:"type:tinyint(1)" json:"is_leaf"` //是否叶子分类
+ Status int `gorm:"type:tinyint(1);comment:状态 1:正常" json:"status"`
+ global.MG_MODEL
+}
+
+func (TbCategory) TableName() string {
+ return "tb_category"
+}
diff --git a/model/tb_goods.go b/model/tb_goods.go
new file mode 100644
index 0000000..bb55984
--- /dev/null
+++ b/model/tb_goods.go
@@ -0,0 +1,103 @@
+package model
+
+import "pure/global"
+
+type TbGoodsBase struct {
+ SpuNo string `gorm:"unique;type:varchar(60);" json:"spu_no"` // 编号
+ Title string `gorm:"type:mediumtext" json:"title"` // 名称
+ TitleEng string `gorm:"type:mediumtext" json:"title_eng"` // 英文名称
+ Cover string `gorm:"type:varchar(255);" json:"cover"` // 封面图
+ Images string `gorm:"type:mediumtext;" json:"images"` // 图片
+ Content string `gorm:"type:mediumtext;" json:"content"` // 详情
+ ContentText string `gorm:"type:mediumtext;" json:"content_text"` // 详情-文字
+ RetailPrice float64 `gorm:"type:decimal(10,2);" json:"retail_price"` // 吊牌价(零售指导价)
+ PriceMin float64 `gorm:"type:decimal(10,2);" json:"price_min"` // 最低规格价格
+ PriceMax float64 `gorm:"type:decimal(10,2);" json:"price_max"` // 最高规格价格
+ StoreNo string `gorm:"type:varchar(60);" json:"store_no"` // 店铺编号
+}
+
+type TbGoods struct { // spu
+ TbGoodsBase
+ CategoryId uint `gorm:"type:int(11);not null;" json:"category_id"` // 分类id
+ ListPrice float64 `gorm:"type:decimal(10,2);" json:"list_price"` // 列表价格
+ AttributeList string `gorm:"type:text;" json:"attribute_list"` // 规格列表
+ Stock int64 `gorm:"type:int(11);comment:总库存" json:"stock"` // 总库存
+ Sales int64 `gorm:"type:int(11);comment:总销售量" json:"sales"` // 总销售量
+ Views int64 `gorm:"size:11;comment:商品浏览量" json:"views"` // 商品浏览量
+ Favourites int64 `gorm:"size:11;comment:商品喜欢量" json:"favourites"` // 商品喜欢量
+ CollectionNum int64 `gorm:"type:int(11)" json:"collection_num"` // 收藏人数
+ Tags string `gorm:"type:varchar(255);" json:"tags"` // 标签
+ Online string `gorm:"type:ENUM('on','off');comment:商品上下架状态" json:"online" form:"online"` // 上下架状态 on/off
+ CreateBy string `gorm:"size:64" json:"create_by"` // 创建人
+ // SaleStatus int `gorm:"type:tinyint(1);" json:"sale_status"` //销售状态 1:正常 2:已售罄
+ global.MG_MODEL
+}
+
+type TbGoodsView struct {
+ SpuNo string `json:"spu_no"` // 编号
+ Title string `json:"title"` // 标题
+ TitleEng string `json:"title_eng"` // 英文标题
+ Cover string `json:"cover"` //
+ Images string `json:"images"` // 图片
+ RetailPrice float64 `json:"retail_price"` // 吊牌价(零售指导价)
+ Tags string `json:"tags"` // 标签
+ PriceMin float64 `json:"price_min"` // 最低规格价格
+ PriceMax float64 `json:"price_max"` // 最高规格价格
+ global.MG_MODEL
+}
+
+type TbGoodsSpecsView struct {
+ SpuNo string `json:"spu_no"` // 编号
+ Title string `json:"title"` // 标题
+ TitleEng string `json:"title_eng"` // 英文标题
+ Cover string `json:"cover"` //
+ Images string `json:"images"` // 图片
+ RetailPrice float64 `json:"retail_price"` // 吊牌价(零售指导价)
+ Tags string `json:"tags"` // 标签
+ PriceMin float64 `json:"price_min"` // 最低规格价格
+ PriceMax float64 `json:"price_max"` // 最高规格价格
+ Specs []TbGoodsSpecsDetail `gorm:"ForeignKey:GoodsId;AssociationForeignKey:ID" json:"specs"` // 规格
+ Attributes []TbAttributeWithValues `gorm:"-" json:"attributes"` // 规格详情
+ Stock int64 `gorm:"type:int(11);comment:总库存" json:"stock"` // 总库存
+ Sales int64 `gorm:"type:int(11);comment:总销售量" json:"sales"` // 总销售量
+ global.MG_MODEL
+}
+
+type TbGoodsDetail struct {
+ CategoryId uint `json:"category_id"` // 分类id
+ SpuNo string `json:"spu_no"` // 编号
+ Title string `json:"title"` // 标题
+ TitleEng string `json:"title_eng"` // 英文标题
+ Cover string `json:"cover"` //
+ Images string `json:"images"` // 图片
+ Content string `json:"content"` // 商品详情
+ ContentText string `json:"content_text"` // 详情-文字
+ ListPrice float64 `json:"list_price"` // 列表价格
+ RetailPrice float64 `json:"retail_price"` // 吊牌价(零售指导价)
+ PriceMin float64 `json:"price_min"` // 最低规格价格
+ PriceMax float64 `json:"price_max"` // 最高规格价格
+ Tags string `json:"tags"` // 标签
+ Online string `json:"online"` // 上下架状态 on/off
+ Attributes []TbAttributeWithValues `gorm:"-" json:"attributes"` // 规格详情
+ Specs []TbGoodsSpecsDetail `gorm:"ForeignKey:GoodsId;AssociationForeignKey:ID" json:"specs"` // 规格
+ CollectStatus bool `gorm:"-" json:"collect_status"` // 收藏状态 true:已收藏 false:未收藏
+ Breadcrumb []Breadcrumb `gorm:"-" json:"breadcrumb"` // 分类面包屑
+
+ global.MG_MODEL
+}
+
+func (TbGoods) TableName() string {
+ return "tb_goods"
+}
+
+func (TbGoodsView) TableName() string {
+ return "tb_goods"
+}
+
+func (TbGoodsDetail) TableName() string {
+ return "tb_goods"
+}
+
+func (TbGoodsSpecsView) TableName() string {
+ return "tb_goods"
+}
diff --git a/model/tb_goods_specs.go b/model/tb_goods_specs.go
new file mode 100644
index 0000000..940d232
--- /dev/null
+++ b/model/tb_goods_specs.go
@@ -0,0 +1,42 @@
+package model
+
+import "pure/global"
+
+type TbGoodsSpecsBase struct {
+ GoodsId uint `gorm:"type:int(11)" json:"goods_id"` // spu id
+ SpuNo string `gorm:"type:varchar(60);" json:"spu_no"` // 商品编号
+ SkuNo string `gorm:"type:varchar(60);" json:"sku_no"` // 商品规格编号
+ Specs string `gorm:"type:text;" json:"specs"` // 规格
+ Price float64 `gorm:"type:decimal(10,2);" json:"price"` // 价格
+ Image string `gorm:"size:255" json:"image"` // 规格图片url
+ GoodsNo string `gorm:"size:255" json:"goods_no"` // 商品编号
+ Code string `gorm:"size:100" json:"code"` // 商品规格属性值定位码
+}
+
+type TbGoodsSpecs struct { // sku
+ global.MG_MODEL
+ TbGoodsSpecsBase
+ Stock int64 `gorm:"type:int(11);" json:"stock"` // 库存
+ Status int `gorm:"type:tinyint(1);comment:状态 1:正常" json:"status"` // 状态
+}
+
+type TbGoodsSpecsDetail struct {
+ global.MG_MODEL
+ GoodsId uint `json:"goods_id"`
+ Specs string `json:"specs"` // 规格
+ Attributes []TbAttributeDetail `gorm:"-" json:"attributes"` // 规格详情
+ SkuNo string `json:"sku_no"` // 商品编码
+ Stock int64 `json:"stock"` // 库存
+ Price float64 `json:"price"` // 价格
+ Image string `json:"image"` // 规格图片url
+ GoodsNo string `json:"goods_no"` // 商品编号
+ Code string `json:"code"` //
+}
+
+func (TbGoodsSpecs) TableName() string {
+ return "tb_goods_specs"
+}
+
+func (TbGoodsSpecsDetail) TableName() string {
+ return "tb_goods_specs"
+}
diff --git a/model/track.go b/model/track.go
new file mode 100644
index 0000000..74376dc
--- /dev/null
+++ b/model/track.go
@@ -0,0 +1,28 @@
+package model
+
+import (
+ "encoding/json"
+ "pure/global"
+)
+
+type Track struct {
+ global.Pure_MODEL
+ Value json.RawMessage `gorm:"type:json" json:"value"`
+ TrackingNumber string `gorm:"type:varchar(100)" json:"tracking_number"`
+ CourierCode string `gorm:"type:varchar(50)" json:"courier_code"`
+ RelationId string `gorm:"type:varchar(100)" json:"relation_id"`
+}
+
+func (Track) TableName() string {
+ return "track"
+}
+
+type TrackValue struct {
+
+ CheckpointDate string `json:"checkpoint_date,omitempty"`
+ TrackingDetail string `json:"tracking_detail,omitempty"`
+ CheckpointDeliveryStatus string `json:"checkpoint_delivery_status"`
+ CheckpointDeliveryStatusV2 string `json:"checkpoint_delivery_status_v2,omitempty"`
+ CheckpointDeliverySubstatus string `json:"checkpoint_delivery_substatus"`
+ CheckpointDeliverySubstatusV2 string `json:"checkpoint_delivery_substatus_v2,omitempty"`
+}
diff --git a/model/track_webhook.go b/model/track_webhook.go
new file mode 100644
index 0000000..6bdb9af
--- /dev/null
+++ b/model/track_webhook.go
@@ -0,0 +1,12 @@
+package model
+
+import "pure/global"
+
+type TrackWebhook struct {
+ global.MG_MODEL
+ Value string `gorm:"type:text" json:"value"`
+}
+
+func (TrackWebhook) TableName() string {
+ return "track_webhook"
+}
diff --git a/model/us_citys.go b/model/us_citys.go
new file mode 100644
index 0000000..a6ad48a
--- /dev/null
+++ b/model/us_citys.go
@@ -0,0 +1,12 @@
+package model
+
+type UsCitys struct {
+ ID int `json:"id"`
+ IDState int `json:"idState"`
+ City string `json:"city"`
+ County string `json:"county"`
+}
+
+func (UsCitys) TableName() string {
+ return "us_citys"
+}
diff --git a/model/us_states.go b/model/us_states.go
new file mode 100644
index 0000000..1fb68a5
--- /dev/null
+++ b/model/us_states.go
@@ -0,0 +1,18 @@
+package model
+
+type UsStates struct {
+ ID int `json:"id"`
+ StateCode string `json:"stateCode"`
+ StateName string `json:"stateName"`
+}
+
+type UsSelect struct {
+ ID int `json:"id"`
+ StateCode string `json:"stateCode"`
+ StateName string `json:"stateName"`
+ Child []UsCitys `gorm:"-" json:"children"`
+}
+
+func (UsStates) TableName() string {
+ return "us_states"
+}
diff --git a/model/user.go b/model/user.go
new file mode 100755
index 0000000..fee0974
--- /dev/null
+++ b/model/user.go
@@ -0,0 +1,64 @@
+// 自动生成模板User
+package model
+
+import (
+ "pure/global"
+ "pure/model/request"
+ "time"
+
+ uuid "github.com/satori/go.uuid"
+)
+
+// 如果含有time.Time 请自行import time包
+type User struct {
+ global.MG_MODEL
+ UUID uuid.UUID `gorm:"unique;size:64" json:"uuid"` //用户uuid编码
+ Username string `gorm:"size:128" json:"username"` //用户登录名
+ NickName string `gorm:"size:20" json:"nick_name"` //昵称
+ Avatar string `gorm:"size:255" json:"avatar"` //头像
+ Platform string `gorm:"type:text" json:"platform"` //json格式的平台信息
+ Appid string `json:"appid" form:"appid" gorm:"size:255"` //用户所属应用
+ Organization string `json:"organization" form:"organization" gorm:"size:255"` //用户所属组织
+ Type string `json:"type" form:"type" gorm:"size:255"` //用户类型(随用户所属而定)
+ Phone string `json:"phone" form:"phone" gorm:"size:255"` //用户手机号
+ CountryCode string `json:"country_code" form:"country_code" gorm:"size:255"` //用户手机号国家代码
+ Email string `json:"email" form:"email" gorm:"size:255"` //用户邮箱
+ Password string `json:"password" form:"password" gorm:"size:255"` //用户密码
+ PasswordSalt string `json:"password_salt" form:"password_salt" gorm:"size:255"` //用户密码盐
+ Tags string `gorm:"type:text" json:"tags"` //个人标签
+ Facebook string `gorm:"size:255" json:"facebook"` //facebook
+ Douyin string `gorm:"size:255" json:"douyin"` //抖音
+ Tiktok string `gorm:"size:255" json:"tiktok"` //tiktok
+ Instagram string `gorm:"size:255" json:"instagram"` //instagram
+ Twitter string `gorm:"size:255" json:"twitter"` //twitter
+ Google string `gorm:"size:255" json:"google"` //google
+ Youtube string `gorm:"size:255" json:"youtube"` //youtube
+ Ios string `gorm:"size:255" json:"ios"` //ios
+ IsAuth bool `gorm:"default:0" json:"is_auth"` //是否认证 0未认证 1已认证
+ IDForbidden bool `json:"id_forbidden"` //是否禁用
+ ForbiddenTime *time.Time `json:"forbidden_time"` //禁用时间
+ ForbiddenReason string `json:"forbidden_reason"` //禁用原因
+ ForbiddenOperation string `json:"forbidden_operation"` //禁用操作人
+ Jwt string `gorm:"type:text" json:"jwt"` //最后登录jwt
+ Source string `json:"source" gorm:"size:255"` //用户来源
+ LogOffTime *time.Time `json:"log_off_time"` //注销时间
+}
+
+type UserSimple struct {
+ UUID uuid.UUID `json:"uuid"` //用户uuid编码
+ NickName string `json:"nick_name"` //昵称
+ Avatar string `json:"avatar"` //头像
+ Phone string `json:"phone"` // 手机号
+ Platform string `json:"-"` //json格式的平台信息
+ Tags string `json:"tags"` //个人标签
+ Email string `json:"email"` //用户邮箱
+ Platforms []request.Platform `gorm:"-" json:"platform"` //平台
+}
+
+func (User) TableName() string {
+ return "user"
+}
+
+func (UserSimple) TableName() string {
+ return "user"
+}
diff --git a/model/version.go b/model/version.go
new file mode 100644
index 0000000..6a86faa
--- /dev/null
+++ b/model/version.go
@@ -0,0 +1,32 @@
+package model
+
+import "pure/global"
+
+type Version struct { // 版本号
+ global.MG_MODEL
+ Version string `gorm:"size:20" json:"version"` // 版本号 1.0.0.11
+ Code int64 `gorm:"type:int(11)" json:"code"` // 版本编号
+ Type int `gorm:"type:int(1)" json:"type"` // 1:ios 2:android 3:h5
+ Info string `gorm:"type:text" json:"info"` // 版本更新描述
+ IsForce bool `gorm:"type:tinyint(1)" json:"is_force"` // 是否强制更新 true:是
+ Tip bool `gorm:"type:tinyint(1);default:1" json:"tip"` // 是否提示升级 true=是
+ Url string `gorm:"size:255" json:"url"` // 下载地址
+ MD5 string `gorm:"size:64" json:"md5"` // 文件md5
+ Status int `gorm:"type:int(1)" json:"status"` // 状态 0:未上线 1:已上线 2:审核中
+}
+
+type VersionV struct {
+ Version string `json:"version"` // 版本号
+ Code int64 `json:"code"` // 版本编号
+ Info string `json:"info"` // 版本更新描述
+ IsForce bool `json:"is_force"` // 是否强制更新 true:是
+ Url string `json:"url"` // apk下载地址
+ MD5 string `json:"md5"` // apk文件md5
+ Tip bool `json:"tip"` // 是否提示升级 true=是
+ Status int `json:"-"` // 1:已上线 2:审核中
+ HideAndSeek bool `json:"hide_and_seek"` //
+}
+
+func (Version) TableName() string {
+ return "version"
+}
diff --git a/model/wallet.go b/model/wallet.go
new file mode 100644
index 0000000..19ab6d9
--- /dev/null
+++ b/model/wallet.go
@@ -0,0 +1,18 @@
+package model
+
+import "pure/global"
+
+type Wallet struct {
+ global.MG_MODEL
+ UserID string `gorm:"size:50" json:"userId"`
+ Balance float64 `gorm:"type:decimal(10,2)" json:"balance"` //可用余额
+ TransitBalance float64 `gorm:"type:decimal(10,2)" json:"transitBalance"` //在途余额
+ Fund float64 `gorm:"type:decimal(10,2)" json:"-"` // 营销账户
+ FundLock float64 `gorm:"type:decimal(10,2)" json:"-"` // 营销账户-锁定金额
+ Platform string `gorm:"size:50" json:"platform"` //平台 saller(买家端) / customer(客户端) / influencer(网红端)
+ State int `gorm:"type:tinyint(1)" json:"state"` // 状态 0:正常 1:限制提现 2:禁止提现
+}
+
+func (Wallet) TableName() string {
+ return "wallet"
+}
diff --git a/model/webhook.go b/model/webhook.go
new file mode 100644
index 0000000..97f5b97
--- /dev/null
+++ b/model/webhook.go
@@ -0,0 +1,12 @@
+package model
+
+import "pure/global"
+
+type PaypalWebhook struct {
+ global.MG_MODEL
+ Value string `gorm:"type:text" json:"value"`
+}
+
+func (PaypalWebhook) TableName() string {
+ return "paypal_webhook"
+}
diff --git a/model/withdrawal.go b/model/withdrawal.go
new file mode 100644
index 0000000..138b918
--- /dev/null
+++ b/model/withdrawal.go
@@ -0,0 +1,32 @@
+package model
+
+import (
+ "pure/global"
+ "time"
+)
+
+type Withdrawal struct { // 提现记录
+ global.MG_MODEL
+ Platform string `gorm:"size:10" json:"platform"` // 平台 1:网红 2:商家
+ WalletType int `gorm:"type:tinyint(1)" json:"wallet_type"` // 钱包类型 1:余额钱包 2:营销账户钱包
+ FlowNo string `gorm:"size:50;unique" json:"flow_no"` // 流水号
+ BillNo string `gorm:"size:50" json:"bill_no"` // 账单号
+ Title string `gorm:"size:255" json:"title"` // 标题
+ AccountType int `gorm:"type:int(1)" json:"account_type"` // 账户类型 1:paypal 2:银行卡
+ BankCard
+ CreateBy string `gorm:"size:50" json:"create_by"` // 创建人/店铺
+ Amount float64 `gorm:"type:decimal(10,2)" json:"amount"` // 金额
+ CheckStatus string `gorm:"size:1" json:"check_status"` // 审核状态 0:待审核 1:审核通过 2:审核未通过
+ CheckTime *time.Time `gorm:"" json:"check_time"` // 审核时间
+ PayId string `gorm:"size:50" json:"pay_id"` // 支付id
+ Status string `gorm:"size:1" json:"status"` // 提现状态 0:进行中 1:成功 2:失败
+ Remark string `gorm:"size:255" json:"remark"` // 备注
+}
+
+type WithdrawalView struct {
+ FlowNo string `json:"flow_no"` // 流水号
+}
+
+func (Withdrawal) TableName() string {
+ return "withdrawal"
+}
diff --git a/openapi.yaml b/openapi.yaml
new file mode 100644
index 0000000..f8f3735
--- /dev/null
+++ b/openapi.yaml
@@ -0,0 +1,10 @@
+# Generated with protoc-gen-openapi
+# https://github.com/google/gnostic/tree/master/cmd/protoc-gen-openapi
+
+openapi: 3.0.3
+info:
+ title: ""
+ version: 0.0.1
+paths: {}
+components:
+ schemas: {}
diff --git a/packfile/notUsePackFile.go b/packfile/notUsePackFile.go
new file mode 100644
index 0000000..e54aad3
--- /dev/null
+++ b/packfile/notUsePackFile.go
@@ -0,0 +1,3 @@
+// +build !packfile
+
+package packfile
diff --git a/packfile/usePackFile.go b/packfile/usePackFile.go
new file mode 100644
index 0000000..055f03d
--- /dev/null
+++ b/packfile/usePackFile.go
@@ -0,0 +1,45 @@
+// +build packfile
+
+package packfile
+
+import (
+ "fmt"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "strings"
+)
+
+//go:generate go-bindata -o=staticFile.go -pkg=packfile -tags=packfile ../resource/... ../config.yaml
+
+func writeFile(path string, data []byte) {
+ // 如果文件夹不存在,预先创建文件夹
+ if lastSeparator := strings.LastIndex(path, "/"); lastSeparator != -1 {
+ dirPath := path[:lastSeparator]
+ if _, err := os.Stat(dirPath); err != nil && os.IsNotExist(err) {
+ os.MkdirAll(dirPath, os.ModePerm)
+ }
+ }
+
+ // 已存在的文件,不应该覆盖重写,可能在前端更改了配置文件等
+ if _, err := os.Stat(path); os.IsNotExist(err) {
+ if err2 := ioutil.WriteFile(path, data, os.ModePerm); err2 != nil {
+ fmt.Printf("Write file failed: %s\n", path)
+ }
+ } else {
+ fmt.Printf("File exist, skip: %s\n", path)
+ }
+}
+
+func init() {
+ for key := range _bindata {
+ filePath, _ := filepath.Abs(strings.TrimPrefix(key, "."))
+ data, err := Asset(key)
+ if err != nil {
+ // Asset was not found.
+ fmt.Printf("Fail to find: %s\n", filePath)
+ } else {
+ writeFile(filePath, data)
+ }
+ }
+}
diff --git a/resource/gorm_settings.yaml b/resource/gorm_settings.yaml
new file mode 100644
index 0000000..329cb43
--- /dev/null
+++ b/resource/gorm_settings.yaml
@@ -0,0 +1,25 @@
+gorm:
+ settings:
+ - dsn-name: dsn1
+ bind-tables:
+ - authority_menu
+ - casbin_rule
+ - exa_customers
+ - exa_file_chunks
+ - exa_file_upload_and_downloads
+ - exa_files
+ - exa_simple_uploaders
+ - jwt_blacklists
+ - sys_apis
+ - sys_authorities
+ - sys_authority_menus
+ - sys_base_menu_parameters
+ - sys_base_menus
+ - sys_data_authority_id
+ - sys_dictionaries
+ - sys_dictionary_details
+ - sys_operation_records
+ - sys_users
+ - dsn-name: dsn2
+ bind-tables:
+ - bs_channel
diff --git a/resource/rbac_model.conf b/resource/rbac_model.conf
new file mode 100644
index 0000000..04ebedf
--- /dev/null
+++ b/resource/rbac_model.conf
@@ -0,0 +1,14 @@
+[request_definition]
+r = sub, obj, act
+
+[policy_definition]
+p = sub, obj, act
+
+[role_definition]
+g = _, _
+
+[policy_effect]
+e = some(where (p.eft == allow))
+
+[matchers]
+m = r.sub == p.sub && ParamsMatch(r.obj,p.obj) && r.act == p.act
diff --git a/router/global/dict.go b/router/global/dict.go
new file mode 100644
index 0000000..42a6ee3
--- /dev/null
+++ b/router/global/dict.go
@@ -0,0 +1,13 @@
+package global
+
+import (
+ "github.com/gin-gonic/gin"
+ "pure/api/global"
+)
+
+func InitDictRouter(Router *gin.RouterGroup) {
+ DictRouter := Router.Group("/dict")
+ {
+ DictRouter.GET("getDictDataList", global.GetSysDictDataList)
+ }
+}
diff --git a/router/global/global.go b/router/global/global.go
new file mode 100644
index 0000000..ed5ddb4
--- /dev/null
+++ b/router/global/global.go
@@ -0,0 +1,19 @@
+package global
+
+import (
+ "pure/api/global"
+
+ "github.com/gin-gonic/gin"
+)
+
+func InitGlobalRouter(Router *gin.RouterGroup) {
+ InOtherRouter := Router.Group("global")
+ {
+ InOtherRouter.GET("address", global.GetAddressList) //获取收货地址
+ InOtherRouter.POST("address", global.AddAddress) //添加收货地址
+ InOtherRouter.PUT("address", global.UpdateAddress) //修改收货地址
+ InOtherRouter.DELETE("address", global.DeleteAddress) //删除收货地址
+ InOtherRouter.GET("usSelect", global.GetUsSelect) //美国地区选择器
+ InOtherRouter.GET("track", global.GetTrack) //美国地区选择器
+ }
+}
diff --git a/router/influencer/base.go b/router/influencer/base.go
new file mode 100644
index 0000000..fc56f75
--- /dev/null
+++ b/router/influencer/base.go
@@ -0,0 +1,25 @@
+package influencer
+
+import (
+ "pure/api/influencer"
+ "pure/api/sys"
+
+ "github.com/gin-gonic/gin"
+)
+
+func InitInfluencerOtherRouter(Router *gin.RouterGroup) {
+ WithoutLoginRouter := Router.Group("")
+ WithoutLoginRouter.GET("mission/recommend-list", influencer.GetRecommendMissionList) //首页推荐任务列表
+
+ InOtherRouter := Router.Group("base")
+ {
+ InOtherRouter.POST("login", influencer.LoginInfluencer) //登录
+ InOtherRouter.POST("register", influencer.Register) //注册
+ InOtherRouter.POST("sendMessage", influencer.SendMessage) //发送短信验证码
+ InOtherRouter.POST("sendEmail", influencer.SendEmail) //发送邮箱验证码
+ InOtherRouter.POST("authorized", influencer.Authorized) //授权登录
+ InOtherRouter.GET("brochure", sys.GetSysBrochure) //隐私协议单页
+ InOtherRouter.GET("chain", influencer.GetChainInfo) // 获取区块链信息
+ InOtherRouter.GET("version", sys.GetVersion) // 获取版本信息
+ }
+}
diff --git a/router/influencer/goods.go b/router/influencer/goods.go
new file mode 100644
index 0000000..561ae6f
--- /dev/null
+++ b/router/influencer/goods.go
@@ -0,0 +1,13 @@
+package influencer
+
+import (
+ "github.com/gin-gonic/gin"
+ "pure/api/influencer"
+)
+
+func InitInfluencerGoodsRouter(Router *gin.RouterGroup) {
+ InRouter := Router.Group("goods")
+ {
+ InRouter.GET("detail", influencer.GetTbGoodsDetail) //商品详情
+ }
+}
diff --git a/router/influencer/mission.go b/router/influencer/mission.go
new file mode 100644
index 0000000..5b36aa0
--- /dev/null
+++ b/router/influencer/mission.go
@@ -0,0 +1,36 @@
+package influencer
+
+import (
+ "pure/api/influencer"
+
+ "github.com/gin-gonic/gin"
+)
+
+func InitInfluencerMissionRouter(Router *gin.RouterGroup) {
+ InRouter := Router.Group("mission")
+ {
+ InRouter.GET("detail", influencer.GetMissionDetail) //任务详情
+ InRouter.GET("list", influencer.GetMissionList) //任务列表
+ InRouter.GET("claim", influencer.GetMissionClaim) //领取任务详情
+ InRouter.GET("claim-list", influencer.GetMissionClaimList) //领取任务列表
+ InRouter.POST("claim", influencer.ClaimMission) //领取任务
+ InRouter.GET("collect-list", influencer.GetCollectionMissionList) //收藏任务列表
+ InRouter.POST("collect", influencer.CollectMission) //收藏任务
+ InRouter.POST("submit-works", influencer.SubmitClaimMissionWorks) //领取任务的提交作品
+ InRouter.GET("bonus", influencer.GetMissionBonus) //任务累计奖金
+ InRouter.POST("submit-video", influencer.SubmitClaimMissionVideo) //固定费用任务上传视频
+ InRouter.GET("recommend-detail", influencer.GetRecommendMissionDetail) //首页推荐任务详情
+ //InRouter.GET("recommend-list", influencer.GetRecommendMissionList) //首页推荐任务列表
+ InRouter.GET("sys-reward-list", influencer.GetSysRewardList) //获取平台奖励列表
+ InRouter.GET("sys-reward-summary", influencer.GetSysRewardSummary) //获取平台奖励汇总
+
+ InRouter.GET("order-data", influencer.GetMissionOrderStatistic) // 获取任务下订单统计数据
+ }
+}
+
+func InitBanner(Router *gin.RouterGroup) {
+ bannerRouter := Router.Group("banner")
+ {
+ bannerRouter.GET("list", influencer.GetBannerList) // banner列表
+ }
+}
diff --git a/router/influencer/order.go b/router/influencer/order.go
new file mode 100644
index 0000000..51c9619
--- /dev/null
+++ b/router/influencer/order.go
@@ -0,0 +1,18 @@
+package influencer
+
+import (
+ "pure/api/influencer"
+
+ "github.com/gin-gonic/gin"
+)
+
+func InitInfluencerOrderRouter(Router *gin.RouterGroup) {
+ InRouter := Router.Group("order")
+ {
+ InRouter.GET("data", influencer.GetOrderData) // 数据
+ InRouter.GET("detail", influencer.GetOrderDetail) // 详情
+ InRouter.GET("goods/snapshot", influencer.GetOrderGoodsInfo) // 获取商品快照信息
+ InRouter.GET("list", influencer.GetUserOrderList) // 列表
+ InRouter.GET("total", influencer.GetOrderTotalList) // 订单统计
+ }
+}
diff --git a/router/influencer/user.go b/router/influencer/user.go
new file mode 100644
index 0000000..ad832d1
--- /dev/null
+++ b/router/influencer/user.go
@@ -0,0 +1,19 @@
+package influencer
+
+import (
+ "pure/api/influencer"
+
+ "github.com/gin-gonic/gin"
+)
+
+func InitInfluencerUserRouter(Router *gin.RouterGroup) {
+ InRouter := Router.Group("user")
+ {
+ InRouter.GET("detail", influencer.GetUserDetail) //个人基本信息
+ InRouter.PUT("detail", influencer.UpdateUserDetail) //修改基本信息
+ InRouter.POST("bandPhone", influencer.BandPhone) //绑定手机号
+ InRouter.POST("platformAuth", influencer.PlatformAuth) //平台认证
+ InRouter.GET("statistics", influencer.GetUserStatistics) //个人基本信息
+ InRouter.POST("logoff", influencer.UserLogOff) //注销账户
+ }
+}
diff --git a/router/influencer/wallet.go b/router/influencer/wallet.go
new file mode 100644
index 0000000..09bb6e0
--- /dev/null
+++ b/router/influencer/wallet.go
@@ -0,0 +1,28 @@
+package influencer
+
+import (
+ "pure/api/influencer"
+
+ "github.com/gin-gonic/gin"
+)
+
+func InitInfluencerWalletRouter(Router *gin.RouterGroup) {
+ InRouter := Router.Group("wallet")
+ {
+ InRouter.GET("detail", influencer.GetUserWalletDetail) //账户信息
+ InRouter.GET("accountList", influencer.GetUserAccountList) //提现账户列表
+ //InRouter.GET("account") //提现账户详情
+ InRouter.GET("bill/data", influencer.GetUserBillData) // 对账中心数据
+
+ InRouter.PUT("detail") //修改账户信息
+ InRouter.POST("account", influencer.AddUserAccount) //提现账户添加(需验证码)
+ InRouter.PUT("account/default", influencer.UpdateAccountIsDefault) // 设置默认账户
+ InRouter.DELETE("account", influencer.DeleteUserAccount) //提现账户删除(需验证码)
+
+ InRouter.GET("bill-list", influencer.GetBillList) // 获取账单列表
+ InRouter.GET("bill-notify", influencer.GetBillNotifyList) // 获取账单通知列表
+ InRouter.GET("withdrawal", influencer.GetWithdrawal) // 获取提现详情
+ InRouter.GET("withdrawal-list", influencer.GetWithdrawalList) // 获取提现列表
+ InRouter.POST("withdrawal", influencer.UserWithdrawal) // 提交提现申请
+ }
+}
diff --git a/service/address.go b/service/address.go
new file mode 100644
index 0000000..4ef30c7
--- /dev/null
+++ b/service/address.go
@@ -0,0 +1,181 @@
+package service
+
+import (
+ "encoding/json"
+ "errors"
+
+ "pure/global"
+ "pure/model"
+ "pure/model/request"
+ "pure/model/response"
+)
+
+func GetUserAddressList(userID string, info *request.ReqAddress) (error, any) {
+ var (
+ err error
+ list []model.Address
+ )
+ db := global.MG_DB.Model(&model.Address{}).Where("user_id=?", userID)
+ if info.ID != 0 {
+ db = db.Where("id=?", info.ID)
+ }
+ err = db.Find(&list).Error
+ if err != nil {
+ return errors.New("获取收货地址失败"), nil
+ }
+ return nil, list
+}
+
+func AddUserAddressList(userID string, data *model.Address) error {
+ var (
+ err error
+ )
+ data.UserID = userID
+ if data.FirstName == "" || data.LastName == "" || data.Bldg == "" || data.City == "" || data.Street == "" || data.State == "" || data.ZipCode == "" {
+ return errors.New("有必填项未填写")
+ }
+ if len(data.FirstName) > 255 {
+ return errors.New("FirstName长度超出限制")
+ }
+ if len(data.LastName) > 255 {
+ return errors.New("LastName长度超出限制")
+ }
+ if len(data.Street) > 255 {
+ return errors.New("Street长度超出限制")
+ }
+ if len(data.Bldg) > 255 {
+ return errors.New("Bldg长度超出限制")
+ }
+ if len(data.City) > 255 {
+ return errors.New("City长度超出限制")
+ }
+ if len(data.State) > 255 {
+ return errors.New("State长度超出限制")
+ }
+ if len(data.ZipCode) > 255 {
+ return errors.New("ZipCode长度超出限制")
+ }
+ if len(data.Phone) > 20 {
+ return errors.New("Phone长度超出限制")
+ }
+ if data.Default == 1 {
+ global.MG_DB.Model(&model.Address{}).Where("user_id=?", userID).Update("default", 2)
+ }
+ err = global.MG_DB.Model(&model.Address{}).Create(data).Error
+ if err != nil {
+ return errors.New("添加收货地址失败")
+ }
+ return nil
+}
+
+func UpdateAddress(userID string, data *model.Address) error {
+ var (
+ err error
+ )
+ if data.FirstName == "" || data.LastName == "" || data.Bldg == "" || data.City == "" || data.Street == "" || data.State == "" || data.ZipCode == "" {
+ return errors.New("有必填项未填写")
+ }
+ if len(data.FirstName) > 255 {
+ return errors.New("FirstName长度超出限制")
+ }
+ if len(data.LastName) > 255 {
+ return errors.New("LastName长度超出限制")
+ }
+ if len(data.Street) > 255 {
+ return errors.New("Street长度超出限制")
+ }
+ if len(data.Bldg) > 255 {
+ return errors.New("Bldg长度超出限制")
+ }
+ if len(data.City) > 255 {
+ return errors.New("City长度超出限制")
+ }
+ if len(data.State) > 255 {
+ return errors.New("State长度超出限制")
+ }
+ if len(data.ZipCode) > 255 {
+ return errors.New("ZipCode长度超出限制")
+ }
+ if len(data.Phone) > 20 {
+ return errors.New("Phone长度超出限制")
+ }
+ data.UserID = userID
+ if data.Default == 1 {
+ global.MG_DB.Model(&model.Address{}).Where("user_id=?", userID).Update("default", 2)
+ }
+ err = global.MG_DB.Model(&model.Address{}).Where("user_id=? and id=?", userID, data.ID).Updates(data).Error
+ if err != nil {
+ return errors.New("修改收货地址失败")
+ }
+ return nil
+}
+
+func DeleteAddress(userID string, ID *global.BASE_ID) error {
+ var (
+ err error
+ )
+ err = global.MG_DB.Model(&model.Address{}).Where("user_id=? and id=?", userID, ID.ID).Delete(&model.Address{}).Error
+ if err != nil {
+ return errors.New("删除收货地址失败")
+ }
+ return nil
+}
+
+func GetUsSelect() (error, any) {
+ var (
+ err error
+ list []model.UsSelect
+ data []model.UsCitys
+ )
+ err = global.MG_DB.Model(&model.UsStates{}).Find(&list).Error
+ if err != nil {
+ return errors.New("获取地址失败"), nil
+ }
+ err = global.MG_DB.Model(&model.UsCitys{}).Find(&data).Error
+ if err != nil {
+ return errors.New("获取地址失败"), nil
+ }
+ for v := range list {
+ for x := range data {
+ if data[x].IDState == list[v].ID {
+ list[v].Child = append(list[v].Child, data[x])
+ }
+ }
+ }
+ return nil, list
+}
+
+func GetTrack(trackId int64) ([]response.TrackItem, error) {
+ var list []response.TrackItem
+ var values []model.TrackValue
+ var track model.Track
+ err := global.MG_DB.Model(&model.Track{}).Where("id=?", trackId).First(&track).Error
+ if err != nil {
+ return list, err
+ }
+ err = json.Unmarshal([]byte(track.Value), &values)
+ if err != nil {
+ return list, err
+ }
+ for _, v := range values {
+ list = append(list, response.TrackItem{
+ CheckpointDate: v.CheckpointDate,
+ DeliveryStatus: v.CheckpointDeliveryStatus,
+ TrackingDetail: v.TrackingDetail,
+ DeliveryStatusCn: toDeliveryStatus(v.CheckpointDeliveryStatus),
+ })
+ }
+ return list, nil
+}
+
+func toDeliveryStatus(status string) string {
+ switch status {
+ case "transit":
+ return "运输途中"
+ case "pickup":
+ return "到达待取"
+ case "delivered":
+ return "已签收"
+ }
+ return ""
+}
diff --git a/service/banner.go b/service/banner.go
new file mode 100644
index 0000000..2650eb1
--- /dev/null
+++ b/service/banner.go
@@ -0,0 +1,41 @@
+package service
+
+import (
+ "pure/global"
+ "pure/model"
+ "pure/model/response"
+)
+
+func GetBannerList() (err error, list []response.BannerListResponse, total int64) {
+
+ db := global.MG_DB.Model(&model.Banner{})
+
+ err = db.Count(&total).Error
+ var res []model.Banner
+
+ err = db.Select("id,title,cover_url,relation_id,relation_type,link_type,link,type,status,sort").
+ Where("status = ?", "1").
+ Order("sort DESC").Find(&res).Error
+
+ if err != nil {
+ return err, nil, 0
+ }
+ for i := 0; i < len(res); i++ {
+ //精简字段赋值
+ vRes := response.BannerListResponse{
+ RelationId: res[i].RelationId,
+ RelationType: res[i].RelationType,
+ Title: res[i].Title,
+ CoverUrl: res[i].CoverUrl,
+ LinkType: res[i].LinkType,
+ Link: res[i].Link,
+ Type: res[i].Type,
+ Status: res[i].Status,
+ }
+ vRes.ID = res[i].ID
+ vRes.SortIndex = i + 1
+ list = append(list, vRes)
+ }
+
+ return err, list, total
+}
diff --git a/service/bill.go b/service/bill.go
new file mode 100644
index 0000000..dc53c5b
--- /dev/null
+++ b/service/bill.go
@@ -0,0 +1,157 @@
+package service
+
+import (
+ "errors"
+ "pure/dto"
+ "pure/global"
+ "pure/model"
+ "pure/model/request"
+ "pure/utils"
+ "time"
+)
+
+func GetBillData(userId string, info *request.GetBillDataParams) (dto.BillData, error) {
+ var (
+ err error
+ result dto.BillData
+ )
+ now := time.Now()
+ switch info.Uint {
+ case "1": //累计
+ var statistic model.DtStatisticOrder
+ statistic, err = getStatisticsOrderInfluence(userId, "", nil)
+ if err != nil {
+ return result, err
+ }
+ result.Income = statistic.SettleReward
+ result.OrderMoney = statistic.OrderMoney
+ result.OrderNum = statistic.OrderNum
+ result.CancelOrderNum = statistic.OrderCancelNum
+ result.CancelOrderMoney = statistic.OrderCancelMoney
+ _, result.RewardUnfinished = getMissionClaimRewardUnfinished(userId)
+
+ result.FlowIncome, result.FlowExpend, err = getBillFlowData(userId, &request.SearchBillParams{Uint: "1"})
+ case "2":
+ var (
+ timeArea = make([]string, 2)
+ statistic model.DtStatisticOrder
+ )
+ timeArea[0] = now.AddDate(0, 0, -1).Format(utils.DateFormat)
+ timeArea[1] = now.Format(utils.DateFormat)
+ statistic, err = getStatisticsOrderInfluence(userId, "", timeArea)
+ if err != nil {
+ return result, err
+ }
+ result.Income = statistic.SettleReward
+ result.OrderMoney = statistic.OrderMoney
+ result.OrderNum = statistic.OrderNum
+ result.CancelOrderNum = statistic.OrderCancelNum
+ result.CancelOrderMoney = statistic.OrderCancelMoney
+
+ result.FlowIncome, result.FlowExpend, err = getBillFlowData(userId, &request.SearchBillParams{Uint: "2"})
+ case "3":
+ var (
+ timeArea = make([]string, 2)
+ statistic model.DtStatisticOrder
+ )
+ timeArea[0] = now.AddDate(0, 0, -29).Format(utils.DateFormat)
+ timeArea[1] = now.AddDate(0, 0, 1).Format(utils.DateFormat)
+ statistic, err = getStatisticsOrderInfluence(userId, "", timeArea)
+ if err != nil {
+ return result, err
+ }
+ result.Income = statistic.SettleReward
+ result.OrderMoney = statistic.OrderMoney
+ result.OrderNum = statistic.OrderNum
+ result.CancelOrderNum = statistic.OrderCancelNum
+ result.CancelOrderMoney = statistic.OrderCancelMoney
+ result.FlowIncome, result.FlowExpend, err = getBillFlowData(userId, &request.SearchBillParams{Uint: "3"})
+ default:
+ return dto.BillData{}, errors.New("uint取值有误")
+ }
+ return result, err
+}
+
+func getBillData(userId string, info *request.SearchBillParams) (float64, error) {
+ var (
+ err error
+ result float64
+ )
+ db := global.MG_DB.Model(&model.Bill{}).Where("user_id = ?", userId)
+ now := time.Now()
+ switch info.Uint {
+ case "2": // 昨天
+ db = db.Where("created_at >= ? AND created_at < ?", now.AddDate(0, 0, -1).Format(utils.DateFormat), now.Format(utils.DateFormat))
+ case "3": // 30天
+ db = db.Where("created_at >= ? AND created_at < ?", now.AddDate(0, 0, -29).Format(utils.DateFormat), now.AddDate(0, 0, 1).Format(utils.DateFormat))
+ }
+ if info.Status != "" {
+ db = db.Where("`status` = ?", info.Status)
+ }
+ err = db.Select("SUM(price) as price").Scan(&result).Error
+ if err != nil {
+ return 0, err
+ }
+ return result, nil
+}
+
+func getBillFlowData(userId string, info *request.SearchBillParams) (income float64, expend float64, err error) {
+ var list []model.BillFlowData
+ db := global.MG_DB.Model(&model.Bill{}).Where("user_id = ?", userId)
+ now := time.Now()
+ switch info.Uint {
+ case "2": // 昨天
+ db = db.Where("created_at >= ? AND created_at < ?", now.AddDate(0, 0, -1).Format(utils.DateFormat), now.Format(utils.DateFormat))
+ case "3": // 30天
+ db = db.Where("created_at >= ? AND created_at < ?", now.AddDate(0, 0, -29).Format(utils.DateFormat), now.AddDate(0, 0, 1).Format(utils.DateFormat))
+ }
+ if info.Status != "" {
+ db = db.Where("`status` = ?", info.Status)
+ }
+ err = db.Select("`status`,SUM(price) as price").Group("`status`").Find(&list).Error
+ if err != nil {
+ return 0, 0, err
+ }
+ for _, data := range list {
+ if data.Status == 1 {
+ expend = data.Price
+ } else {
+ income = data.Price
+ }
+ }
+ return
+}
+
+func GetBillList(userId string, info *request.SearchBillParams) ([]model.Bill, error) {
+ var (
+ err error
+ result []model.Bill
+ )
+ limit := info.PageSize
+ offset := info.PageSize * (info.Page - 1)
+ db := global.MG_DB.Model(&model.Bill{}).Where("user_id = ?", userId)
+ now := time.Now()
+ switch info.Uint {
+ case "2": // 昨天
+ db = db.Where("created_at >= ? AND created_at < ?", now.AddDate(0, 0, -1).Format(utils.DateFormat), now.Format(utils.DateFormat))
+ case "3": // 30天
+ db = db.Where("created_at >= ? AND created_at < ?", now.AddDate(0, 0, -29).Format(utils.DateFormat), now.AddDate(0, 0, 1).Format(utils.DateFormat))
+ }
+ if info.Status != "" {
+ db = db.Where("`status` = ?", info.Status)
+ }
+ err = db.Order("id DESC").Offset(offset).Limit(limit).Find(&result).Error
+ if err != nil {
+ return nil, err
+ }
+ return result, nil
+}
+
+func getBillView(orderId string) (model.BillView, error) {
+ var (
+ err error
+ result model.BillView
+ )
+ err = global.MG_DB.Model(&model.Bill{}).Where("order_id = ?", orderId).Select("id,order_id,transaction_id").First(&result).Error
+ return result, err
+}
diff --git a/service/chain.go b/service/chain.go
new file mode 100644
index 0000000..1f7cf9c
--- /dev/null
+++ b/service/chain.go
@@ -0,0 +1,28 @@
+package service
+
+import (
+ "math/rand"
+ "pure/model/response"
+ "pure/utils"
+ "time"
+)
+
+func GetChainInfo(address string) (error, []response.ChainResp) {
+ var (
+ err error
+ result []response.ChainResp
+ )
+ now := time.Now()
+ r := rand.New(rand.NewSource(time.Now().UnixNano()))
+ for i := 0; i < 3; i++ {
+ intn := r.Intn(1000)
+ tmp := response.ChainResp{
+ Time: &now,
+ BlockHeight: 28741283 + int64(intn),
+ BlockAddress: utils.GetInvitationLowerLen(64),
+ Hash: utils.GetInvitationLowerLen(64),
+ }
+ result = append(result, tmp)
+ }
+ return err, result
+}
diff --git a/service/collectiom_goods.go b/service/collectiom_goods.go
new file mode 100644
index 0000000..f23e7e9
--- /dev/null
+++ b/service/collectiom_goods.go
@@ -0,0 +1,85 @@
+package service
+
+import (
+ "errors"
+ "gorm.io/gorm"
+ "pure/global"
+ "pure/model"
+ "pure/model/request"
+)
+
+func ChangeCollectionGoods(uuid string, info request.SpuNo) (err error, id uint) {
+ var (
+ tmp model.CollectionGoods
+ collectionGoods model.CollectionGoods
+ )
+ err = global.MG_DB.Model(&model.TbGoods{}).Where("spu_no = ?", info.SpuNo).First(&model.TbGoods{}).Error
+ if err != nil {
+ return
+ }
+ tx := global.MG_DB.Begin()
+ err = tx.Model(&model.CollectionGoods{}).Where("spu_no = ? AND create_by = ?", info.SpuNo, uuid).Find(&tmp).Error
+ if err != nil {
+ return
+ }
+ if tmp.ID == 0 {
+ collectionGoods.SpuNo = info.SpuNo
+ collectionGoods.CreateBy = uuid
+ err = tx.Model(&model.CollectionGoods{}).Create(&collectionGoods).Error
+ if err != nil {
+ tx.Rollback()
+ err = errors.New("收藏失败")
+ return
+ }
+ //商品收藏数+1
+ err = tx.Model(&model.TbGoods{}).Where("spu_no = ?", info.SpuNo).UpdateColumn("collection_num", gorm.Expr("collection_num + 1")).Error
+ if err != nil {
+ tx.Rollback()
+ return
+ }
+ } else {
+ err = tx.Model(&model.CollectionGoods{}).Delete(&tmp).Error
+ if err != nil {
+ tx.Rollback()
+ err = errors.New("取消收藏失败")
+ return
+ }
+ //任务收藏数-1
+ err = tx.Model(&model.TbGoods{}).Where("spu_no = ? AND collection_num > 0", info.SpuNo).UpdateColumn("collection_num", gorm.Expr("collection_num - 1")).Error
+ if err != nil {
+ tx.Rollback()
+ return
+ }
+ }
+ tx.Commit()
+ id = collectionGoods.ID
+ return
+}
+
+func GetCollectionGoodsList(uuid string, info request.SearchCollectionGoods) (err error, list interface{}, total int64) {
+ limit := info.PageSize
+ offset := info.PageSize * (info.Page - 1)
+ db := global.MG_DB.Model(&model.CollectionGoods{}).Joins("INNER JOIN mission ON mission.id = collection_mission.mission_id").
+ Where("collection_mission.create_by = ?", uuid)
+ err = db.Count(&total).Error
+ var res []model.TbGoodsDetail
+ err = db.Select("mission.id,mission.title,mission.goods_id,mission.goods_status,mission.num,mission.hire_type,mission.hire_money,mission.hire_ratio,mission.start_time,mission.end_time,mission.status").
+ Preload("Goods", func(db *gorm.DB) *gorm.DB {
+ return db.Select("id,spu_no,title,title_eng,images,tags")
+ }).Limit(limit).Offset(offset).Find(&res).Error
+ if err != nil {
+ return err, nil, 0
+ }
+ for i := 0; i < len(res); i++ {
+ res[i].CollectStatus = getGoodsCollectStatus(uuid, res[i].SpuNo)
+ }
+ return err, res, total
+}
+
+func getGoodsCollectStatus(uuid string, spuNo string) (result bool) {
+ err := global.MG_DB.Model(&model.CollectionGoods{}).Where("create_by = ? AND spu_no = ?", uuid, spuNo).First(&model.CollectionGoods{}).Error
+ if err != nil {
+ return false
+ }
+ return true
+}
diff --git a/service/collection_mission.go b/service/collection_mission.go
new file mode 100644
index 0000000..e072980
--- /dev/null
+++ b/service/collection_mission.go
@@ -0,0 +1,305 @@
+package service
+
+import (
+ "errors"
+ "gorm.io/gorm"
+ "pure/global"
+ "pure/model"
+ "pure/model/request"
+ "pure/model/response"
+ "pure/utils"
+ "strconv"
+)
+
+func ChangeCollectionMission(uuid string, info request.MissionId) (err error, id uint) {
+ var (
+ tmp model.CollectionMission
+ collectionMission model.CollectionMission
+ )
+ err = global.MG_DB.Model(&model.Mission{}).Where("id = ?", info.MissionId).First(&model.Mission{}).Error
+ if err != nil {
+ return
+ }
+ err = global.MG_DB.Model(&model.CollectionMission{}).Where("mission_id = ? AND create_by = ?", info.MissionId, uuid).Find(&tmp).Error
+ if err != nil {
+ return
+ }
+ tx := global.MG_DB.Begin()
+ if tmp.ID == 0 {
+ collectionMission.MissionId = info.MissionId
+ collectionMission.CreateBy = uuid
+ err = tx.Model(&model.CollectionMission{}).Create(&collectionMission).Error
+ if err != nil {
+ tx.Rollback()
+ err = errors.New("收藏失败")
+ return
+ }
+ //任务收藏数+1
+ err = tx.Model(&model.Mission{}).Where("id = ?", info.MissionId).UpdateColumn("collection_num", gorm.Expr("collection_num + 1")).Error
+ if err != nil {
+ tx.Rollback()
+ return
+ }
+ } else {
+ err = tx.Model(&model.CollectionMission{}).Delete(&tmp).Error
+ if err != nil {
+ tx.Rollback()
+ err = errors.New("取消收藏失败")
+ return
+ }
+ //任务收藏数-1
+ err = tx.Model(&model.Mission{}).Where("id = ? AND collection_num > 0", info.MissionId).UpdateColumn("collection_num", gorm.Expr("collection_num - 1")).Error
+ if err != nil {
+ tx.Rollback()
+ return
+ }
+ }
+ tx.Commit()
+ id = collectionMission.ID
+ return
+}
+
+// 已废弃
+func GetCollectionMissionListBak(uuid string, info request.SearchCollectionMission) (err error, list interface{}, total int64) {
+ limit := info.PageSize
+ offset := info.PageSize * (info.Page - 1)
+ db := global.MG_DB.Model(&model.CollectionMission{}).Joins("INNER JOIN mission ON mission.id = collection_mission.mission_id").
+ Where("collection_mission.create_by = ?", uuid)
+ err = db.Count(&total).Error
+ var res []model.MissionDetail
+ err = db.Select("mission.id,mission.title,mission.goods_id,mission.goods_status,mission.num,mission.hire_type,mission.hire_money,mission.hire_ratio,mission.start_time,mission.end_time,mission.`status`,mission.create_by").
+ Preload("Goods", func(db *gorm.DB) *gorm.DB {
+ return db.Select("id,spu_no,title,title_eng,cover,images,tags,retail_price,price_min,price_max")
+ }).Order("collection_mission.id DESC").Limit(limit).Offset(offset).Find(&res).Error
+ if err != nil {
+ return err, nil, 0
+ }
+ var (
+ ids []uint
+ uuids []string
+ )
+ for i := 0; i < len(res); i++ {
+ if res[i].CreateBy != "" {
+ uuids = append(uuids, res[i].CreateBy)
+ }
+ if res[i].HireType == 1 { //1:固定佣金
+ res[i].HireMoneyExpect = utils.FormatFloatToString(res[i].HireMoney)
+ } else { //2:比例抽成
+ if res[i].Goods.PriceMin == res[i].Goods.PriceMax {
+ res[i].HireMoneyExpect = utils.FormatFloatToString(res[i].Goods.PriceMin * (res[i].HireRatio / 100))
+ } else {
+ res[i].HireMoneyExpect = utils.FormatFloatToString(res[i].Goods.PriceMin*(res[i].HireRatio/100)) + "-" + utils.FormatFloatToString(res[i].Goods.PriceMax*(res[i].HireRatio/100))
+ }
+ }
+ ids = append(ids, res[i].ID)
+ //res[i].CollectStatus = getMissionCollectStatus(uuid, res[i].ID)
+ }
+ if len(ids) != 0 {
+ statusMap := getMissionCollectStatusMap(uuid, ids)
+ for i := 0; i < len(res); i++ {
+ res[i].CollectStatus = statusMap[res[i].ID]
+ }
+ }
+ if len(uuids) != 0 {
+ _, storeMap := getSellerStoreInfoMap(uuids)
+ for i := 0; i < len(res); i++ {
+ if val, ok := storeMap[res[i].CreateBy]; ok {
+ res[i].Store = val
+ }
+ }
+ }
+ return err, res, total
+}
+
+// 收藏任务列表
+func GetCollectionMissionList(uuid string, info request.SearchCollectionMission) (err error, list []response.MissionCollectView, total int64) {
+ limit := info.PageSize
+ offset := info.PageSize * (info.Page - 1)
+ db := global.MG_DB.Model(&model.CollectionMission{}).Joins("INNER JOIN mission ON mission.id = collection_mission.mission_id").
+ Where("collection_mission.create_by = ?", uuid)
+ err = db.Count(&total).Error
+ var res []model.MissionDetail
+
+ err = db.Select("mission.id,mission.title,mission.goods_id,mission.goods_status,mission.num,mission.hire_type,mission.hire_money,mission.hire_ratio,mission.start_time,mission.end_time,mission.`status`,mission.create_by").
+ Preload("Goods", func(db *gorm.DB) *gorm.DB {
+ return db.Select("id,spu_no,title,title_eng,cover,images,tags,retail_price,price_min,price_max")
+ }).Order("collection_mission.id DESC").Limit(limit).Offset(offset).Find(&res).Error
+ if err != nil {
+ return err, nil, 0
+ }
+ var (
+ ids []uint
+ uuids []string
+ missionList []response.MissionCollectView
+ )
+ for i := 0; i < len(res); i++ {
+ if res[i].CreateBy != "" {
+ uuids = append(uuids, res[i].CreateBy)
+ }
+ if res[i].HireType == 1 { //1:固定佣金
+ res[i].HireMoneyExpect = utils.FormatFloatToString(res[i].HireMoney)
+ } else { //2:比例抽成
+ //按最高价显示
+ res[i].HireMoneyExpect = utils.FormatFloatToString(res[i].Goods.PriceMax * (res[i].HireRatio / 100))
+ }
+ bonus, sales, _ := GetMissionBonusAndSales(res[i].ID)
+ vMission := response.MissionCollectView{
+ ID: 0,
+ MissionId: res[i].ID,
+ AchieveNum: sales,
+ TotalBonus: bonus.Total,
+ Status: res[i].Status,
+ HireType: res[i].HireType,
+ HireMoneyExpect: res[i].HireMoneyExpect,
+ Goods: response.MissionGoodsView{
+ GoodsId: res[i].GoodsId,
+ SkuNo: "",
+ Title: res[i].Goods.Title,
+ Images: res[i].Goods.Cover,
+ Price: res[i].Goods.PriceMax,
+ SpuNo: res[i].Goods.SpuNo,
+ TitleEng: res[i].Goods.TitleEng,
+ },
+ }
+ missionList = append(missionList, vMission)
+
+ ids = append(ids, res[i].ID)
+ //res[i].CollectStatus = getMissionCollectStatus(uuid, res[i].ID)
+ }
+
+ return err, missionList, total
+}
+
+func getMissionCollectStatus(uuid string, id uint) (result bool) {
+ err := global.MG_DB.Model(&model.CollectionMission{}).Where("create_by = ? AND mission_id = ?", uuid, id).First(&model.CollectionMission{}).Error
+ if err != nil {
+ return false
+ }
+ return true
+}
+
+func getMissionCollectStatusMap(uuid string, ids []uint) map[uint]bool {
+ var (
+ list []model.CollectionMission
+ result = make(map[uint]bool)
+ )
+ err := global.MG_DB.Model(&model.CollectionMission{}).Where("create_by = ? AND mission_id IN (?)", uuid, ids).Find(&list).Error
+ if err != nil {
+ return result
+ }
+ for i := 0; i < len(list); i++ {
+ result[list[i].MissionId] = true
+ }
+ for i := 0; i < len(ids); i++ {
+ if _, ok := result[ids[i]]; !ok {
+ result[ids[i]] = false
+ }
+ }
+ return result
+}
+
+// 收藏任务列表
+func GetRecommendMissionList(info request.SearchRecommendMission) (err error, list []response.MissionRecommendResponse, total int64) {
+ limit := info.PageSize
+ offset := info.PageSize * (info.Page - 1)
+ db := global.MG_DB.Model(&model.MissionRecommend{}).
+ Joins("inner join mission_claim_video on mission_recommend.relation_id = mission_claim_video.id").
+ Joins("inner join mission on mission.id = mission_claim_video.mission_id").
+ Where("mission_claim_video.status = 2"). //审核通过状态
+ Order("mission_recommend.sort desc")
+ err = db.Count(&total).Error
+ if err != nil {
+ return err, nil, 0
+ }
+ var res []model.MissionRecommendDetail
+
+ err = db.Preload("MissionVideo", func(db *gorm.DB) *gorm.DB {
+ return db.Preload("Mission", func(db *gorm.DB) *gorm.DB {
+ return db.Select("id,title,goods_id,goods_status,num,hire_type,hire_money,hire_ratio,claim_num,start_time,end_time,`status`,has_video,video_channel_ids,video_country_id,claim_days,create_by").
+ Preload("Goods", func(db *gorm.DB) *gorm.DB {
+ return db.Select("id,spu_no,title,title_eng,images,retail_price,price_min,price_max,stock,sales,online,created_at,updated_at")
+ })
+ }).Preload("Influencer", func(db *gorm.DB) *gorm.DB {
+ return db.Select("uuid,nick_name,phone")
+ })
+ }).Order("id DESC").Limit(limit).Offset(offset).Find(&res).Error
+
+ if err != nil {
+ return err, nil, 0
+ }
+ for i := 0; i < len(res); i++ {
+ //精简字段赋值
+ vRes := formatMissionRecommendData(res[i])
+ vRes.Tag = GetTagNamesByRelation(strconv.Itoa(int(vRes.MissionRecommend.RelationId)), "02")
+ list = append(list, vRes)
+ }
+
+ return err, list, total
+}
+
+func GetRecommendMissionDetail(id request.IdReq) (err error, data response.MissionRecommendResponse) {
+
+ db := global.MG_DB.Model(&model.MissionRecommend{}).
+ Joins("inner join mission_claim_video on mission_recommend.relation_id = mission_claim_video.id").
+ Joins("inner join mission on mission.id = mission_claim_video.mission_id").
+ Where("mission_recommend.id = ?", id.ID)
+ var res model.MissionRecommendDetail
+
+ err = db.Preload("MissionVideo", func(db *gorm.DB) *gorm.DB {
+ return db.Preload("Mission", func(db *gorm.DB) *gorm.DB {
+ return db.Select("id,title,goods_id,goods_status,num,hire_type,hire_money,hire_ratio,claim_num,start_time,end_time,`status`,has_video,video_channel_ids,video_country_id,claim_days,create_by").
+ Preload("Goods", func(db *gorm.DB) *gorm.DB {
+ return db.Select("id,spu_no,title,title_eng,images,retail_price,price_min,price_max,stock,sales,online,created_at,updated_at")
+ })
+ }).Preload("Influencer", func(db *gorm.DB) *gorm.DB {
+ return db.Select("uuid,nick_name,phone")
+ })
+ }).First(&res).Error
+
+ if err != nil {
+ return err, data
+ }
+ data = formatMissionRecommendData(res)
+
+ return err, data
+}
+
+func formatMissionRecommendData(res model.MissionRecommendDetail) response.MissionRecommendResponse {
+ bonus, sales, claimNum := GetMissionBonusAndSales(res.MissionVideo.MissionId)
+ if res.MissionVideo.Mission.HireType == 1 { //1:固定佣金
+ res.MissionVideo.Mission.HireMoneyExpect = utils.FormatFloatToString(res.MissionVideo.Mission.HireMoney)
+ } else { //2:比例抽成
+ //按最高价显示
+ res.MissionVideo.Mission.HireMoneyExpect = utils.FormatFloatToString(res.MissionVideo.Mission.Goods.PriceMax * (res.MissionVideo.Mission.HireRatio / 100))
+ }
+ //精简字段赋值
+ vRes := response.MissionRecommendResponse{
+ MissionRecommend: res.MissionRecommend,
+ MissionVideoCommonData: response.MissionVideoCommonData{
+ MissionId: res.MissionVideo.MissionId,
+ VideoUrl: res.MissionVideo.VideoUrl,
+ Cover: res.MissionVideo.Cover,
+ Title: res.MissionVideo.Mission.Title,
+ GoodsTitle: res.MissionVideo.Mission.Goods.Title,
+ GoodsTitleEng: res.MissionVideo.Mission.Goods.TitleEng,
+ Influencer: res.MissionVideo.Influencer,
+ Tag: "",
+ MissionStatus: res.MissionVideo.Mission.Status,
+ StartTime: res.MissionVideo.Mission.StartTime,
+ EndTime: res.MissionVideo.Mission.EndTime,
+ HireType: res.MissionVideo.Mission.HireType,
+ HireMoney: res.MissionVideo.Mission.HireMoney,
+ HireRatio: res.MissionVideo.Mission.HireRatio,
+ HireMoneyExpect: res.MissionVideo.Mission.HireMoneyExpect,
+ ReleaseCountry: res.MissionVideo.Mission.ReleaseCountry,
+ ReleaseChannels: res.MissionVideo.Mission.ReleaseChannels,
+ AchieveNum: sales,
+ TotalBonus: bonus.Total,
+ BoughtNum: bonus.UserTotal,
+ Width: res.MissionVideo.Width,
+ Height: res.MissionVideo.Height,
+ ClaimNum: claimNum,
+ },
+ }
+ return vRes
+}
diff --git a/service/dict.go b/service/dict.go
new file mode 100644
index 0000000..23b89ce
--- /dev/null
+++ b/service/dict.go
@@ -0,0 +1,56 @@
+package service
+
+import (
+ "fmt"
+ "pure/global"
+ "pure/model"
+)
+
+func GetSysDictDataLabel(typeCode, value string) string {
+ var res string
+
+ cacheKey := "bkb-admin_sys_dict_labels"
+ labelKey := fmt.Sprintf("%s_%s", typeCode, value)
+ res = RedisHashGet(cacheKey, labelKey)
+ if res == "" {
+ _ = global.MG_DB.Model(&model.SysDictData{}).Select("label").Where("type_code=? AND `value`=?", typeCode, value).Scan(&res).Error
+ go RedisHashSet(cacheKey, labelKey, res)
+ }
+ return res
+}
+
+func GetSysDictDataList(typeCode string) (err error, list interface{}) {
+ var lists []model.SysDictDataView
+ err = global.MG_DB.Model(&model.SysDictData{}).Where("type_code=? AND `status`='1'", typeCode).Order("sort asc").Find(&lists).Error
+ return err, lists
+}
+
+func GetSysDictDataListByTypeCode(typeCode string) (list []model.SysDictDataView, err error) {
+ var lists []model.SysDictDataView
+ err = global.MG_DB.Model(&model.SysDictData{}).Where("type_code=? AND `status`='1'", typeCode).Order("sort asc").Find(&lists).Error
+ return lists, err
+}
+
+func FormatDictLabels(typeCode string, values []string) (labels []string) {
+ for _, vid := range values {
+ vLabel := GetSysDictDataLabel(typeCode, vid)
+ labels = append(labels, vLabel)
+ }
+ return labels
+}
+
+func getDictMap(typeCode string, values []string) map[string]string {
+ var (
+ list []model.SysDictData
+ result = make(map[string]string)
+ )
+ db := global.MG_DB.Model(&model.SysDictData{}).Where("type_code = ?", typeCode)
+ if len(values) != 0 {
+ db = db.Where("values IN (?)", values)
+ }
+ _ = db.Find(&list).Error
+ for _, val := range list {
+ result[val.Value] = val.Label
+ }
+ return result
+}
diff --git a/service/jwt_black_list.go b/service/jwt_black_list.go
new file mode 100755
index 0000000..ca31810
--- /dev/null
+++ b/service/jwt_black_list.go
@@ -0,0 +1,53 @@
+package service
+
+import (
+ "errors"
+ "pure/global"
+ "pure/model"
+ "time"
+
+ "gorm.io/gorm"
+)
+
+//@function: JsonInBlacklist
+//@description: 拉黑jwt
+//@param: jwtList model.JwtBlacklist
+//@return: err error
+
+func JsonInBlacklist(jwtList model.JwtBlacklist) (err error) {
+ err = global.MG_DB.Create(&jwtList).Error
+ return
+}
+
+//@function: IsBlacklist
+//@description: 判断JWT是否在黑名单内部
+//@param: jwt string
+//@return: bool
+
+func IsBlacklist(jwt string) bool {
+ err := global.MG_DB.Where("jwt = ?", jwt).First(&model.JwtBlacklist{}).Error
+ isNotFound := errors.Is(err, gorm.ErrRecordNotFound)
+ return !isNotFound
+}
+
+//@function: GetRedisJWT
+//@description: 从redis取jwt
+//@param: userName string
+//@return: err error, redisJWT string
+
+func GetRedisJWT(userName string) (err error, redisJWT string) {
+ redisJWT, err = global.MG_REDIS.Get(userName).Result()
+ return err, redisJWT
+}
+
+//@function: SetRedisJWT
+//@description: jwt存入redis并设置过期时间
+//@param: jwt string, userName string
+//@return: err error
+
+func SetRedisJWT(jwt string, userName string) (err error) {
+ // 此处过期时间等于jwt过期时间
+ timer := time.Duration(global.MG_CONFIG.JWT.ExpiresTime) * time.Second
+ err = global.MG_REDIS.Set(userName, jwt, timer).Err()
+ return err
+}
diff --git a/service/mission.go b/service/mission.go
new file mode 100644
index 0000000..cd56e6e
--- /dev/null
+++ b/service/mission.go
@@ -0,0 +1,778 @@
+package service
+
+import (
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "math"
+ "pure/initialize/api"
+ "strconv"
+ "strings"
+ "time"
+
+ "github.com/spf13/cast"
+ "gorm.io/gorm"
+
+ "pure/global"
+ "pure/model"
+ "pure/model/request"
+ "pure/model/response"
+ "pure/utils"
+)
+
+func GetMissionDetail(uuid string, id uint) (error, model.MissionDetail) {
+ var (
+ err error
+ result model.MissionDetail
+ )
+ err = global.MG_DB.Model(&model.Mission{}).
+ Select("id,title,goods_id,goods_status,num,hire_type,hire_money,hire_ratio,start_time,end_time,status,create_by,has_sample,has_video,claim_stock,claim_days,claim_demands,video_channel_ids,description,claim_num,sample_num").
+ Where("id = ?", id).Preload("Goods", func(db *gorm.DB) *gorm.DB {
+ return db.Select("id,spu_no,title,title_eng,images,tags,retail_price,price_min,price_max,stock,sales").Preload("Specs", func(db *gorm.DB) *gorm.DB {
+ return db.Select("id,goods_id,specs,stock,sku_no,price,image,goods_no,code").Unscoped()
+ }).Unscoped()
+ }).First(&result).Error
+
+ if err != nil {
+ return err, result
+ }
+
+ if result.VideoChannelIds != "" {
+ channelLabels := FormatDictLabels(model.ReleaseChannelCode, strings.Split(result.VideoChannelIds, ","))
+ result.ReleaseChannels = strings.Join(channelLabels, "、")
+ }
+ claimExcept := GetMissionStatusExcept(result, uuid)
+ result.ClaimStatusExcept = claimExcept
+ trs := utils.InterTranslate(claimExcept, "zh", "en")
+ if trs != "" {
+ result.ClaimStatusExceptEng = trs
+ }
+
+ if result.HireType == 1 { // 1:固定佣金
+ result.HireMoneyExpect = utils.FormatFloatToString(result.HireMoney)
+ } else { // 2:比例抽成
+ if result.Goods.PriceMin == result.Goods.PriceMax {
+ result.HireMoneyExpect = utils.FormatFloatToString(result.Goods.PriceMin * (result.HireRatio / 100))
+ } else {
+ result.HireMoneyExpect = utils.FormatFloatToString(result.Goods.PriceMin*(result.HireRatio/100)) + "-" + utils.FormatFloatToString(result.Goods.PriceMax*(result.HireRatio/100))
+ }
+ }
+ if result.CreateBy != "" {
+ _, result.Store = GetSellerStoreInfo(result.CreateBy)
+ }
+ result.CollectStatus = getMissionCollectStatus(uuid, result.ID)
+ //
+ result.GoodsUrl = global.MG_CONFIG.Tools.CustomerUrl + `/CommodityDetails?id=` + cast.ToString(result.GoodsId)
+ err = getSpecs(&result.Goods)
+ return nil, result
+}
+
+func getSpecs(goods *model.TbGoodsSpecsView) (err error) {
+ attributeValues := make(map[uint]*model.TbAttributeValueJson)
+ for i := 0; i < len(goods.Specs); i++ {
+ err = json.Unmarshal([]byte(goods.Specs[i].Specs), &goods.Specs[i].Attributes)
+ if err != nil {
+ return err
+ }
+ if i == 0 {
+ var attributes []uint
+ for j := 0; j < len(goods.Specs[i].Attributes); j++ {
+ attributes = append(attributes, goods.Specs[i].Attributes[j].AttributeId)
+ }
+ orderSql := "FIELD(id"
+ for _, attribute := range attributes {
+ orderSql += fmt.Sprintf(",'%v'", attribute)
+ }
+ orderSql += ")"
+ err = global.MG_DB.Model(&model.TbAttribute{}).Select("id,`name`").Where("id IN (?)", attributes).Order(orderSql).Find(&goods.Attributes).Error
+ if err != nil {
+ return err
+ }
+ }
+ for _, attribute := range goods.Specs[i].Attributes {
+ if _, ok := attributeValues[attribute.AttributeId]; ok {
+ if !strings.Contains(attributeValues[attribute.AttributeId].Str, attribute.Value) {
+ attributeValues[attribute.AttributeId].Str += attribute.Value + ","
+ attributeValues[attribute.AttributeId].Items = append(attributeValues[attribute.AttributeId].Items, model.TbAttributeValueItem{
+ Id: attribute.ValueId, Name: attribute.Value, Image: goods.Specs[i].Image})
+ }
+ } else {
+ attributeValues[attribute.AttributeId] = &model.TbAttributeValueJson{Items: []model.TbAttributeValueItem{{
+ Id: attribute.ValueId, Name: attribute.Value, Image: goods.Specs[i].Image}}, Str: attribute.Value + ","}
+ }
+ }
+ }
+ for i := 0; i < len(goods.Attributes); i++ {
+ if val, ok := attributeValues[goods.Attributes[i].ID]; ok {
+ goods.Attributes[i].Values = val.Items
+ }
+ }
+ return
+}
+
+func GetMissionList(uuid string, info request.SearchMission) (err error, list any, total int64) {
+ limit := info.PageSize
+ offset := info.PageSize * (info.Page - 1)
+ db := global.MG_DB.Model(&model.Mission{}).Joins("INNER JOIN tb_goods ON tb_goods.id = mission.goods_id").
+ Where("mission.goods_status = 1 AND tb_goods.stock > 0")
+ err = db.Count(&total).Error
+ var res []model.MissionDetail
+ err = db.Select("mission.id,mission.title,mission.goods_id,mission.goods_status,mission.num,mission.hire_type,mission.hire_money,mission.hire_ratio,mission.start_time,mission.end_time,mission.`status`,mission.create_by,case when mission.status = 2 then 900000000 when mission.status = 1 then 500000000+mission.id else mission.id end as sort_value").
+ // 分段排序逻辑:进行中--结束时间正序,未开始--id倒序,已结束--id倒序
+ Preload("Goods", func(db *gorm.DB) *gorm.DB {
+ return db.Select("tb_goods.id,tb_goods.spu_no,title,title_eng,tb_goods.images,tb_goods.tags,retail_price,price_min,price_max").Unscoped()
+ }).Limit(limit).Offset(offset).Order("sort_value desc").Order("end_time asc").Find(&res).Error
+
+ if err != nil {
+ return err, nil, 0
+ }
+ var (
+ ids []uint
+ uuids []string
+ )
+ for i := 0; i < len(res); i++ {
+ if res[i].HireType == 1 { // 1:固定佣金
+ res[i].HireMoneyExpect = utils.FormatFloatToString(res[i].HireMoney)
+ } else { // 2:比例抽成
+ if res[i].Goods.PriceMin == res[i].Goods.PriceMax {
+ // res[i].HireMoneyExpect = fmt.Sprintf("%v", res[i].Goods.PriceMin*(res[i].HireRatio/100))
+ res[i].HireMoneyExpect = utils.FormatFloatToString(res[i].Goods.PriceMin * (res[i].HireRatio / 100))
+ } else {
+ res[i].HireMoneyExpect = utils.FormatFloatToString(res[i].Goods.PriceMin*(res[i].HireRatio/100)) + "-" + utils.FormatFloatToString(res[i].Goods.PriceMax*(res[i].HireRatio/100))
+ }
+ }
+ if res[i].CreateBy != "" {
+ uuids = append(uuids, res[i].CreateBy)
+ }
+ ids = append(ids, res[i].ID)
+ }
+ if len(ids) != 0 {
+ statusMap := getMissionCollectStatusMap(uuid, ids)
+ for i := 0; i < len(res); i++ {
+ if val, ok := statusMap[res[i].ID]; ok {
+ res[i].CollectStatus = val
+ }
+ }
+ }
+ if len(uuids) != 0 {
+ _, storeMap := getSellerStoreInfoMap(uuids)
+ for i := 0; i < len(res); i++ {
+ if val, ok := storeMap[res[i].CreateBy]; ok {
+ res[i].Store = val
+ }
+ }
+ }
+ return err, res, total
+}
+
+func getMissionClaim(uuid, claimNo string) (err error, result model.MissionClaim) {
+ err = global.MG_DB.Model(&model.MissionClaim{}).Where("create_by = ? AND claim_no = ?", uuid, claimNo).First(&result).Error
+ return
+}
+
+func GetMissionClaim(uuid string, id uint) (err error, res model.MissionClaimDetail) {
+ err = global.MG_DB.Model(&model.MissionClaim{}).Where("create_by = ? AND id = ?", uuid, id).
+ Select("id,mission_id,claim_no,achieve_num,`status`,created_at,updated_at,expire_at,finished,email").
+ Preload("Order", func(db *gorm.DB) *gorm.DB {
+ return db.Select("order_id,mission_claim_id,`status`,courier,courier_url,courier_number,send_time").
+ Preload("OrderGoods", func(db *gorm.DB) *gorm.DB {
+ return db.Select("order_id,price,sku_no,title,image,specs,id")
+ })
+ }).
+ Preload("Mission", func(db *gorm.DB) *gorm.DB {
+ return db.Select("id,title,goods_id,goods_status,num,hire_type,hire_money,hire_ratio,start_time,end_time,`status`,create_by,claim_days").
+ Preload("Goods", func(db *gorm.DB) *gorm.DB {
+ return db.Select("id,spu_no,title,title_eng,images,tags,retail_price,price_min,price_max").Unscoped()
+ })
+ }).Preload("Works").
+ Preload("Video", func(db *gorm.DB) *gorm.DB {
+ return db.Where("status in (1,2)").Order("id desc").Limit(1)
+ }).First(&res).Error
+ if err != nil {
+ return
+ }
+ res.Video.CreateTime = res.Video.CreatedAt
+
+ if res.Mission.CreateBy != "" {
+ _, res.Mission.Store = GetSellerStoreInfo(res.Mission.CreateBy)
+ }
+ if res.Mission.HireType == 1 { // 1:固定佣金
+ res.Mission.HireMoneyExpect = utils.FormatFloatToString(res.Mission.HireMoney)
+ } else { // 2:比例抽成
+ res.Mission.HireMoneyExpect = utils.FormatFloatToString(res.Order.OrderGoods.Price * (res.Mission.HireRatio / 100))
+ }
+ if res.Mission.ID != 0 {
+ res.Mission.CollectStatus = getMissionCollectStatus(uuid, res.Mission.ID)
+ }
+ res.StatusExcept = GetMissionClaimStatusExcept(res)
+
+ res.SpreadUrl = global.MG_CONFIG.Tools.CustomerUrl + "/CommodityDetails?id=" + fmt.Sprintf("%v", res.Mission.Goods.ID) + "&spu_no=" + res.Mission.Goods.SpuNo + "&claim_no=" + res.ClaimNo
+ return
+}
+
+func MergeMissionClaimList(uuid string, info request.SearchMissionClaim) (err error, list []model.MissionClaimDetail, total int64) {
+ // 进行中与已结束分段查询,在此处合并
+ db := global.MG_DB.Model(&model.MissionClaim{}).Joins("inner join mission on mission.id = mission_claim.mission_id").
+ Where("mission_claim.create_by = ?", uuid)
+ if info.HireType != 0 {
+ db = db.Where("mission.hire_type = ?", info.HireType)
+ }
+
+ //是否
+ if info.VideoUpload == 1 {
+ var delIds []uint
+ var claimVideos []model.MissionClaimVideo
+ err = global.MG_DB.Model(&model.MissionClaimVideo{}).
+ Select("id,mission_id,status,create_by,mission_claim_id").
+ Where("status in (1,2) and create_by = ?", uuid).
+ Find(&claimVideos).Error
+ for _, c := range claimVideos {
+ if c.MissionClaimId != 0 {
+ delIds = append(delIds, c.MissionClaimId)
+ }
+ }
+ info.ExcludeIds = delIds
+ db.Where("mission_claim.id not in (?)", info.ExcludeIds)
+ }
+
+ err = db.Count(&total).Error
+ var (
+ partTotal int64
+ partOffset int
+ limit int
+ offset int
+ newPage int
+ endedList []model.MissionClaimDetail
+ )
+ limit = info.PageSize
+ offset = info.PageSize * (info.Page - 1)
+ // 查询进行中的数据
+ info.MissionStatus = 2
+ err, list, partTotal = GetMissionClaimList(uuid, info, offset, limit)
+ if len(list) < limit {
+ // 查询已结束的数据补齐
+ info.MissionStatus = 3
+ // 进行中总页数
+ newPage = info.Page - int(math.Ceil(float64(partTotal)/float64(limit)))
+ partOffset = int(partTotal) % limit
+ if len(list) > 0 {
+ limit = info.PageSize - len(list)
+ offset = 0
+ } else {
+ limit = info.PageSize
+ offset = info.PageSize*newPage - partOffset
+ }
+
+ err, endedList, partTotal = GetMissionClaimList(uuid, info, offset, limit)
+ list = append(list, endedList...)
+ }
+
+ return err, list, total
+}
+
+func GetMissionClaimList(uuid string, info request.SearchMissionClaim, offset, limit int) (err error, list []model.MissionClaimDetail, total int64) {
+ db := global.MG_DB.Model(&model.MissionClaim{}).Where("mission_claim.create_by = ?", uuid)
+
+ var res []model.MissionClaimDetail
+
+ db = db.Joins("inner join mission on mission.id = mission_claim.mission_id").
+ Select("mission_claim.id,mission_claim.mission_id,mission_claim.claim_no,mission_claim.achieve_num,mission_claim.`status`,mission_claim.created_at,mission_claim.updated_at,mission_claim.expire_at,mission_claim.finished").Preload("Order", func(db *gorm.DB) *gorm.DB {
+ return db.Select("order_id,mission_claim_id,`status`,courier,courier_url,courier_number").
+ Preload("OrderGoods", func(db *gorm.DB) *gorm.DB {
+ return db.Select("order_id,sku_no,title,specs,image,price").Unscoped()
+ })
+ }).Preload("Mission", func(db *gorm.DB) *gorm.DB {
+ return db.Select("id,title,goods_id,goods_status,num,hire_type,hire_money,hire_ratio,start_time,end_time,`status`,create_by").
+ Preload("Goods", func(db *gorm.DB) *gorm.DB {
+ return db.Select("id,spu_no,title,title_eng,images,tags,retail_price,price_min,price_max").Unscoped()
+ })
+ })
+
+ if info.HireType != 0 {
+ db = db.Where("mission.hire_type = ?", info.HireType)
+ }
+
+ if len(info.ExcludeIds) != 0 {
+ db.Where("mission_claim.id not in (?)", info.ExcludeIds)
+ }
+
+ if info.MissionStatus == 2 {
+ db = db.Where("mission.status = 2").Order("mission_claim.expire_at asc")
+ } else {
+ db = db.Where("mission.status != 2")
+ }
+
+ err = db.Count(&total).Error
+ err = db.Order("mission_claim.id DESC").Limit(limit).Offset(offset).Find(&res).Error
+
+ if err != nil {
+ return err, nil, 0
+ }
+ var (
+ ids []uint
+ uuids []string
+ resList []response.MissionClaimView
+ )
+ for i := 0; i < len(res); i++ {
+ var vMissionClaim response.MissionClaimView
+
+ if res[i].Mission.CreateBy != "" {
+ uuids = append(uuids, res[i].Mission.CreateBy)
+ }
+ if res[i].Mission.HireType == 1 { // 1:固定佣金
+ res[i].Mission.HireMoneyExpect = utils.FormatFloatToString(res[i].Mission.HireMoney)
+ } else { // 2:比例抽成
+ res[i].Mission.HireMoneyExpect = utils.FormatFloatToString(res[i].Order.OrderGoods.Price * (res[i].Mission.HireRatio / 100))
+ }
+ res[i].SpreadUrl = global.MG_CONFIG.Tools.CustomerUrl + "/CommodityDetails?id=" + fmt.Sprintf("%v", res[i].Mission.Goods.ID) + "&spu_no=" + res[i].Mission.Goods.SpuNo + "&claim_no=" + res[i].ClaimNo
+
+ if res[i].Mission.ID != 0 {
+ ids = append(ids, res[i].Mission.ID)
+ }
+ vRes := res[i]
+ vMissionClaim.MissionId = vRes.MissionId
+ vMissionClaim = response.MissionClaimView{
+ ID: vRes.ID,
+ ClaimNo: vRes.ClaimNo,
+ MissionId: vRes.MissionId,
+ AchieveNum: vRes.AchieveNum,
+ Status: vRes.Status,
+ SpreadUrl: vRes.SpreadUrl,
+ HireType: vRes.Mission.HireType,
+ HireMoneyExpect: vRes.Mission.HireMoneyExpect,
+ EndTime: vRes.Mission.EndTime,
+ ExpireAt: vRes.ExpireAt,
+ CollectStatus: false,
+ Goods: response.MissionGoodsView{
+ GoodsId: vRes.Mission.GoodsId,
+ SkuNo: vRes.Order.OrderGoods.SkuNo,
+ Title: vRes.Order.OrderGoods.Title,
+ Images: vRes.Order.OrderGoods.Image,
+ Price: vRes.Order.OrderGoods.Price,
+ SpuNo: vRes.Mission.Goods.SpuNo,
+ TitleEng: vRes.Mission.Goods.TitleEng,
+ },
+ }
+
+ resList = append(resList, vMissionClaim)
+ }
+ if len(ids) != 0 {
+ statusMap := getMissionCollectStatusMap(uuid, ids)
+ for i := 0; i < len(res); i++ {
+ res[i].Mission.CollectStatus = statusMap[res[i].ID]
+ }
+ }
+ if len(uuids) != 0 {
+ _, storeMap := getSellerStoreInfoMap(uuids)
+ for i := 0; i < len(res); i++ {
+ if val, ok := storeMap[res[i].Mission.CreateBy]; ok {
+ res[i].Mission.Store = val
+ }
+ }
+ }
+
+ return err, res, total
+}
+
+func ClaimMission(uuid string, info request.ClaimMission) (err error, id uint) {
+ var mission model.Mission
+ //查询网红是否被禁用
+ var user model.User
+ err = global.MG_DB.Model(&model.User{}).Where("uuid = ?", uuid).First(&user).Error
+ if err != nil {
+ return errors.New("未找到用户信息"), 0
+ }
+ if user.IDForbidden {
+ return errors.New("账号已被禁用"), 0
+ }
+ if global.MG_DB.Model(&model.Mission{}).Where("id = ?", info.MissionId).First(&mission).Error != nil {
+ return errors.New("抱歉,未找到任务信息"), 0
+ }
+ if mission.Status != 2 || mission.GoodsStatus != 1 {
+ return errors.New("抱歉,当前任务不可领取"), 0
+ }
+ now := time.Now().UTC().Unix()
+ if mission.StartTime.Unix() > now || mission.EndTime.Unix() < now {
+ return errors.New("抱歉,不在任务领取时间内"), 0
+ }
+
+ if mission.HireType == 1 && mission.ClaimStock <= mission.ClaimNum {
+ return errors.New("可接人数已满额"), 0
+ }
+
+ if mission.HireType == 2 {
+ var total int64
+ global.MG_DB.Model(&model.MissionClaim{}).Where("create_by = ? AND mission_id = ? and hire_type = 2", uuid, mission.ID).Count(&total)
+ if total >= 10 {
+ return errors.New("进行中任务已达上限"), 0
+ }
+ }
+
+ var address model.Address
+ if !errors.Is(global.MG_DB.Model(&model.MissionClaim{}).Where("create_by = ? AND mission_id = ?", uuid, info.MissionId).First(&model.MissionClaim{}).Error, gorm.ErrRecordNotFound) { // 判断email是否注册
+ return errors.New("不可重复领取"), 0
+ }
+ if global.MG_DB.Model(&model.Address{}).Where("user_id = ? AND id = ?", uuid, info.AddressId).First(&address).Error != nil {
+ return errors.New("抱歉,未找到地址信息"), 0
+ }
+ var (
+ missionClaim model.MissionClaim
+ missionClaimOrder model.MissionClaimOrder
+ missionClaimOrderGoods model.MissionClaimOrderGoods
+ missionClaimAddress model.MissionClaimAddress
+ )
+ tx := global.MG_DB.Begin()
+ missionClaim.MissionId = info.MissionId
+ missionClaim.ClaimNo = utils.GetInvitationLowerLen(20)
+ missionClaim.AchieveNum = 0
+ missionClaim.CreateBy = uuid
+ missionClaim.Status = 1
+ expireDate := time.Now().AddDate(0, 0, mission.ClaimDays)
+ missionClaim.ExpireAt = expireDate
+ missionClaim.Email = info.Email //邮箱
+ err = tx.Model(&model.MissionClaim{}).Create(&missionClaim).Error
+ if err != nil {
+ tx.Rollback()
+ return
+ }
+ // 任务领取人数+1
+ err = tx.Model(&model.Mission{}).Where("id = ?", info.MissionId).UpdateColumn("claim_num", gorm.Expr("`claim_num` + 1")).Error
+ if err != nil {
+ tx.Rollback()
+ return
+ }
+
+ // 创建任务订单
+ var (
+ goods model.TbGoods
+ goodsSpec model.TbGoodsSpecs
+ )
+ err = tx.Model(&model.TbGoods{}).Where("online = 'on' AND spu_no = ?", info.SpuNo).First(&goods).Error
+ if err != nil {
+ tx.Rollback()
+ err = errors.New("未找到商品信息")
+ return
+ }
+ err = tx.Model(&model.TbGoodsSpecs{}).Where("status = 1 AND goods_id = ? AND sku_no = ?", goods.ID, info.SkuNo).First(&goodsSpec).Error
+ if err != nil {
+ tx.Rollback()
+ err = errors.New("未找到商品规格信息")
+ return
+ }
+ missionClaimOrder.OrderID = Generate()
+ missionClaimOrder.MissionClaimId = missionClaim.ID
+ missionClaimOrder.SpuNo = info.SpuNo
+ missionClaimOrder.SkuNo = info.SkuNo
+ missionClaimOrder.Number = 1
+ missionClaimOrder.CreateBy = uuid
+ missionClaimOrder.Status = 2 // 待发货
+ err = tx.Model(&model.MissionClaimOrder{}).Create(&missionClaimOrder).Error
+ if err != nil {
+ tx.Rollback()
+ err = errors.New("创建任务订单失败")
+ return
+ }
+ missionClaimOrderGoods.OrderID = missionClaimOrder.OrderID
+ missionClaimOrderGoods.SkuNo = info.SkuNo
+ missionClaimOrderGoods.Title = goods.Title
+ missionClaimOrderGoods.Image = goodsSpec.Image
+ missionClaimOrderGoods.Specs = goodsSpec.Specs
+ missionClaimOrderGoods.Price = goodsSpec.Price
+ err = tx.Model(&model.MissionClaimOrderGoods{}).Create(&missionClaimOrderGoods).Error
+ if err != nil {
+ tx.Rollback()
+ err = errors.New("创建任务订单失败")
+ return
+ }
+
+ // 创建任务收获地址
+ missionClaimAddress.Address = address
+ missionClaimAddress.ID = 0
+ missionClaimAddress.AddressId = address.ID
+ missionClaimAddress.MissionClaimId = missionClaim.ID
+ missionClaimAddress.OrderID = missionClaimOrder.OrderID
+ err = tx.Model(&model.MissionClaimAddress{}).Create(&missionClaimAddress).Error
+ if err != nil {
+ tx.Rollback()
+ return
+ }
+
+ _, seller := GetSellerStoreInfo(mission.CreateBy)
+
+ if mission.HireType == 1 {
+ // 固定佣金任务锁定商家营销账户
+ var wallet model.Wallet
+ err = global.MG_DB.Model(&model.Wallet{}).Where("platform = 'seller' AND user_id = ?", seller.StoreNo).First(&wallet).Error
+ if err != nil {
+ return
+ }
+ var billFund model.BillFund
+ billFund.UserID = mission.CreateBy
+ billFund.TransactionType = 1
+ billFund.TransactionId = "MB" + Generate() // mission-bill
+ billFund.Title = ""
+ billFund.Price = mission.HireMoney
+ billFund.Balance = wallet.Fund
+ billFund.Platform = "seller"
+ billFund.RelatedId = missionClaim.ClaimNo
+ billFund.Status = 1
+ err = tx.Model(&model.BillFund{}).Create(&billFund).Error
+ if err != nil {
+ tx.Rollback()
+ return
+ }
+ }
+ tx.Commit()
+ id = missionClaim.ID
+
+ //给商家发送邮件
+ go func(uid string, mission model.Mission, email string) {
+ _, user := GetUserDetail(uid)
+ body := fmt.Sprintf("您好,%s已被%s已接单,请及时回复网红疑问,促进网红完成任务", mission.Title, user.NickName)
+ global.EMAIL_CLIENT.SendEmail(context.Background(), &api.SendRequest{
+ To: []string{email},
+ Subject: "网红接任务",
+ Body: body,
+ })
+ }(uuid, mission, seller.Email)
+
+ //给网红发送邮件
+ if mission.HasVideo == 1 && mission.VideoUrl != "" {
+ go func(mission model.Mission, email string, files string) {
+ subject := fmt.Sprintf("任务《%s》素材已发送", mission.Title)
+ body := "嗨,您接任务的素材已发送到邮箱,请查看,尽快完成任务。"
+ global.EMAIL_CLIENT.SendEmail(context.Background(), &api.SendRequest{
+ To: []string{email},
+ Subject: subject,
+ Body: body,
+ Files: []string{files},
+ })
+ }(mission, info.Email, mission.VideoUrl)
+ }
+
+ return
+}
+
+func SubmitClaimMissionWorks(uuid string, info request.ClaimMissionWorksList) (err error) {
+ var (
+ missionClaim model.MissionClaim
+ )
+
+ err = global.MG_DB.Model(&model.MissionClaim{}).Where("create_by = ? AND id = ?", uuid, info.MissionClaimId).First(&missionClaim).Error
+ if err != nil {
+ err = errors.New("not found mission claim record")
+ return err
+ }
+
+ tx := global.MG_DB.Begin()
+ for i := 0; i < len(info.Works); i++ {
+ var works model.MissionClaimWorks
+ works.Type = info.Works[i].Type
+ works.Homepage = info.Works[i].Homepage
+ works.Image = info.Works[i].Image
+ works.VideoUrl = info.Works[i].VideoUrl
+ if info.Works[i].ID != 0 {
+ if info.Works[i].Homepage == "" {
+ err = tx.Model(&model.MissionClaimWorks{}).Where("id = ?", info.Works[i].ID).Delete(&model.MissionClaimWorks{}).Error
+ if err != nil {
+ tx.Rollback()
+ return err
+ }
+ } else {
+ err = tx.Model(&model.MissionClaimWorks{}).Where("id = ?", info.Works[i].ID).Select("Type", "Homepage", "Image", "VideoUrl").Updates(&works).Error
+ if err != nil {
+ tx.Rollback()
+ return err
+ }
+ }
+ } else {
+ works.MissionClaimId = info.MissionClaimId
+ err = tx.Model(&model.MissionClaimWorks{}).Create(&works).Error
+ if err != nil {
+ tx.Rollback()
+ return err
+ }
+ }
+ }
+ claimStatus := 3 // 推广中
+ err = tx.Model(&model.MissionClaim{}).Where("id = ? AND status = 2", info.MissionClaimId).UpdateColumn("status", claimStatus).Error
+ if err != nil {
+ tx.Rollback()
+ return err
+ }
+ tx.Commit()
+ return nil
+}
+
+func SubmitClaimMissionVideo(uuid string, info request.ClaimMissionVideo) (err error) {
+ var (
+ mission model.Mission
+ missionClaim model.MissionClaim
+ claimVideo model.MissionClaimVideo
+ achieveNum int64
+ )
+
+ err = global.MG_DB.Model(&model.MissionClaim{}).Where("create_by = ? AND id = ?", uuid, info.MissionClaimId).First(&missionClaim).Error
+ if err != nil {
+ err = errors.New("not found mission claim record")
+ return err
+ }
+ err = global.MG_DB.Model(&model.Mission{}).Where("id = ?", missionClaim.MissionId).First(&mission).Error
+ if err != nil {
+ err = errors.New("not found mission record")
+ return err
+ }
+
+ // 判断有无审核通过和待审核的
+ err = global.MG_DB.Model(&model.MissionClaimVideo{}).Where("mission_claim_id = ? and status in (1,2)", info.MissionClaimId).First(&model.MissionClaimVideo{}).Error
+ if !errors.Is(err, gorm.ErrRecordNotFound) {
+ return errors.New("不能重复上传")
+ }
+ if info.SourceType == 2 {
+ global.MG_DB.Model(&model.MissionClaimVideo{}).Where("create_by = ? and source_type = 2 and status in (1,2)", uuid).Count(&achieveNum)
+ }
+
+ tx := global.MG_DB.Begin()
+ claimVideo.MissionClaimId = info.MissionClaimId
+ claimVideo.VideoUrl = info.VideoUrl
+ claimVideo.Cover = info.Cover
+ claimVideo.Status = 1 // 待审核
+ claimVideo.SourceType = info.SourceType // 来源类型
+ claimVideo.MissionId = missionClaim.MissionId // 任务ID
+ claimVideo.CreateBy = uuid // 创建者ID
+ claimVideo.Width = info.Width //宽度
+ claimVideo.Height = info.Height //高度
+ err = tx.Model(&model.MissionClaimVideo{}).Create(&claimVideo).Error
+ if err != nil {
+ tx.Rollback()
+ return err
+ }
+ // 完成平台任务奖励
+ if info.SourceType == 2 {
+ err = AddSysMissionReward(request.AddSysMissionReward{
+ Type: 1,
+ RelationId: strconv.Itoa(int(claimVideo.ID)),
+ AchieveNum: achieveNum + 1,
+ CreateBy: uuid,
+ }, tx)
+ if err != nil {
+ tx.Rollback()
+ return err
+ }
+ }
+ tx.Commit()
+ return nil
+}
+
+// 查询任务奖金
+func GetMissionBonus(code string) model.MissionBonus {
+ var (
+ bonus model.MissionBonus
+ )
+ global.MG_DB.Model(&model.Bill{}).Select("sum(bill.price) total").Joins("inner join `order` b on bill.order_id=b.order_id and b.code=?", code).Where("bill.status=2 and bill.type=1").Scan(&bonus)
+ return bonus
+}
+
+func GetMissionStatusExcept(mission model.MissionDetail, uuid string) (except string) {
+ if mission.Status != 2 {
+ except = "当前时间,任务不可接"
+ return except
+ }
+ if mission.HireType == 1 && mission.ClaimStock <= mission.ClaimNum {
+ except = "可接人数已满额"
+ return except
+ }
+
+ if !errors.Is(global.MG_DB.Model(&model.MissionClaim{}).Where("create_by = ? AND mission_id = ?", uuid, mission.ID).First(&model.MissionClaim{}).Error, gorm.ErrRecordNotFound) { // 判断email是否注册
+ return "任务已接"
+ }
+
+ if mission.HireType == 2 {
+ var total int64
+ global.MG_DB.Model(&model.MissionClaim{}).Where("create_by = ? AND mission_id = ? and hire_type = 2", uuid, mission.ID).Count(&total)
+ if total >= 10 {
+ return "进行中任务已达上限"
+ }
+ }
+
+ if mission.GoodsStatus != 1 {
+ except = "商品已下架,任务不可接"
+ return except
+ }
+
+ //费用待发放
+
+ //费用已发放
+
+ return ""
+}
+
+func GetMissionBonusAndSales(missionId uint) (model.MissionBonus, int64, int64) {
+ var (
+ claimList []model.MissionClaim
+ codes []string
+ achieveNums int64
+ bonus model.MissionBonus
+ claimNum int64
+ )
+ global.MG_DB.Model(&model.MissionClaim{}).Where("mission_id = ?", missionId).Find(&claimList)
+ for _, vClaim := range claimList {
+ codes = append(codes, vClaim.ClaimNo)
+ achieveNums += vClaim.AchieveNum
+ }
+ claimNum = int64(len(claimList))
+
+ global.MG_DB.Model(&model.Bill{}).Joins("INNER JOIN `order` ON `order`.order_id = bill.order_id").
+ Select("SUM(bill.price) total,COUNT(DISTINCT bill.user_id) user_total").Where("bill.status=2 and bill.type=1 and `order`.`code` IN (?)", codes).Scan(&bonus)
+ return bonus, achieveNums, claimNum
+}
+
+func getMissionClaimRewardUnfinished(uuid string) (error, float64) {
+ var (
+ err error
+ result float64
+ )
+ err = global.MG_DB.Model(&model.MissionClaim{}).Where("create_by = ?", uuid).Select("SUM(reward_unfinished) as reward_unfinished").Scan(&result).Error
+ return err, result
+}
+
+func GetMissionClaimStatusExcept(res model.MissionClaimDetail) string {
+ var (
+ statusExcept string
+ )
+ switch res.Status {
+ //状态 1:已领取待发货 2:已发货 3:已收货推广中
+ case 1:
+ statusExcept = "等待样品发货"
+ case 2:
+ statusExcept = "等待链接上传"
+ if res.Mission.HireType == 1 {
+ if res.Video.ID == 0 {
+ statusExcept = "等待视频上传"
+ } else {
+ switch res.Video.Status {
+ case 1:
+ statusExcept = "等待视频审核"
+ case 2:
+
+ case 3:
+ statusExcept = "视频审核不通过"
+ }
+ }
+ }
+ case 3:
+ statusExcept = "链接已上传"
+ //todo 查看奖励发放状态
+ if res.Mission.HireType == 1 {
+ switch res.Video.RewardStatus {
+ case 1:
+ statusExcept = "费用待发放"
+ case 2:
+ statusExcept = "费用已发放"
+ }
+ }
+ }
+
+ return statusExcept
+}
diff --git a/service/notify.go b/service/notify.go
new file mode 100644
index 0000000..75bc61c
--- /dev/null
+++ b/service/notify.go
@@ -0,0 +1,24 @@
+package service
+
+import (
+ "pure/global"
+ "pure/model"
+ "pure/model/request"
+)
+
+func GetNotifyList(userId string, info *request.SearchNotify) ([]model.Notify, int64, error) {
+ var (
+ err error
+ total int64
+ result []model.Notify
+ )
+ limit := info.PageSize
+ offset := info.PageSize * (info.Page - 1)
+ db := global.MG_DB.Model(&model.Notify{}).Where("user_id = ?", userId)
+ if info.RelationType != "" {
+ db = db.Where("relation_type = ?", info.RelationType)
+ }
+ _ = db.Count(&total).Error
+ err = db.Order("id DESC").Offset(offset).Limit(limit).Find(&result).Error
+ return result, total, err
+}
diff --git a/service/order.go b/service/order.go
new file mode 100644
index 0000000..47fc6cd
--- /dev/null
+++ b/service/order.go
@@ -0,0 +1,459 @@
+package service
+
+import (
+ "encoding/json"
+ "errors"
+ "fmt"
+ "os"
+ "strings"
+ "sync/atomic"
+ "time"
+
+ "github.com/plutov/paypal"
+ "github.com/w3liu/go-common/constant/timeformat"
+
+ "pure/dto"
+ "pure/global"
+ "pure/model"
+ "pure/model/request"
+ "pure/utils"
+)
+
+func GetOrderData(userId string, info *request.SceneParams) (dto.OrderData, error) {
+ var (
+ // err error
+ result dto.OrderData
+ )
+ // TODO 全部数据包含哪些状态
+ switch info.Scene {
+ case "my":
+ result.Unship, _ = getOrderCount(userId, &request.SearchOrderList{Status: 2})
+ result.Shipped, _ = getOrderCount(userId, &request.SearchOrderList{Status: 3})
+ result.Finished, _ = getOrderCount(userId, &request.SearchOrderList{Status: 4})
+ result.Cancel, _ = getOrderCount(userId, &request.SearchOrderList{Status: 5})
+ default:
+ result.All, _ = getOrderCount(userId, &request.SearchOrderList{Status: 0})
+ result.Unship, _ = getOrderCount(userId, &request.SearchOrderList{Status: 2})
+ result.Shipped, _ = getOrderCount(userId, &request.SearchOrderList{Status: 3})
+ result.Finished, _ = getOrderCount(userId, &request.SearchOrderList{Status: 4})
+ result.Cancel, _ = getOrderCount(userId, &request.SearchOrderList{Status: 5})
+ }
+ return result, nil
+}
+
+func getOrderCount(userId string, info *request.SearchOrderList) (int64, error) {
+ var (
+ err error
+ result int64
+ )
+ db := global.MG_DB.Model(&model.Order{}).Joins("INNER JOIN mission_claim ON mission_claim.claim_no = `order`.`code`").
+ Where("`order`.`status` IN (2,3,4,5) AND mission_claim.create_by = ?", userId)
+ if info.Status != 0 {
+ db = db.Where("`order`.status = ?", info.Status)
+ }
+ if info.Code != "" {
+ db = db.Where("`order`.`code` = ?", info.Code)
+ }
+ switch info.Group {
+ case "user": // 下单人数
+ db = db.Group("`order`.user_id")
+ err = db.Count(&result).Error
+ default:
+ err = db.Count(&result).Error
+ }
+ return result, err
+}
+
+func GetOrderList(userId string, info *request.SearchOrderList) (error, any, int64) {
+ var (
+ err error
+ data []model.OrderList
+ total int64
+ )
+ limit := info.PageSize
+ offset := info.PageSize * (info.Page - 1)
+ db := global.MG_DB.Model(&model.Order{}).Joins("INNER JOIN mission_claim ON mission_claim.claim_no = `order`.`code`").
+ Where("`order`.`status` IN (2,3,4,5) AND mission_claim.create_by = ?", userId)
+ if info.Status != 0 {
+ db = db.Where("`order`.`status` = ?", info.Status)
+ }
+ if info.Code != "" {
+ db = db.Where("`order`.`code` = ?", info.Code)
+ }
+ err = db.Order("order.id desc").Offset(offset).Limit(limit).Find(&data).Error
+ if err != nil {
+ return errors.New("获取订单失败"), data, total
+ }
+ if len(data) == 0 {
+ return nil, data, total
+ }
+ var orderIds, userIds, claimNos, platforms []string
+ for _, val := range data {
+ orderIds = append(orderIds, val.OrderID)
+ userIds = append(userIds, val.UserID)
+ if val.Code != "" {
+ claimNos = append(claimNos, val.Code)
+ }
+ if val.Platform != "" {
+ platforms = append(platforms, val.Platform)
+ }
+ }
+ var (
+ orderGoodsList []model.OrderGoodsDetail
+ goodsMap = make(map[string]model.OrderGoodsDetail)
+ )
+ err = global.MG_DB.Model(&model.OrderGoods{}).Where("order_id IN (?)", orderIds).Find(&orderGoodsList).Error
+ if err != nil {
+ return errors.New("获取订单商品信息失败"), data, total
+ }
+ for _, goods := range orderGoodsList {
+ goodsMap[goods.OrderID] = goods
+ }
+ var (
+ users []model.UserSimple
+ userMap = make(map[string]model.UserSimple)
+ )
+ err = global.MG_DB.Model(&model.User{}).Where("`type` = 'customer' AND uuid IN (?)", userIds).Find(&users).Error
+ if err != nil {
+ return errors.New("获取订单用户信息失败"), data, total
+ }
+ for _, user := range users {
+ userMap[user.UUID.String()] = user
+ }
+ var (
+ missions []model.MissionClaimInfo
+ hireRatioMap = make(map[string]float64)
+ )
+ err = global.MG_DB.Model(&model.MissionClaim{}).Select("mission_claim.claim_no,mission_claim.mission_id,b.hire_type,b.hire_money,b.hire_ratio").
+ Joins("inner join mission b on mission_claim.mission_id=b.id").Where("claim_no IN (?) AND b.hire_type = 2", claimNos).Find(&missions).Error
+ if err != nil {
+ return errors.New("获取任务详情失败"), data, total
+ }
+ for _, val := range missions {
+ hireRatioMap[val.ClaimNo] = val.HireRatio
+ }
+ dictMap := getDictMap("release_channel", platforms)
+ for v := range data {
+ if val, ok := goodsMap[data[v].OrderID]; ok {
+ data[v].Goods = val
+ }
+ if val, ok := userMap[data[v].UserID]; ok {
+ data[v].User = val
+ }
+ if val, ok := hireRatioMap[data[v].Code]; ok {
+ data[v].InfluencerAmount = utils.FormatFloatToString(data[v].PaidPrice * val / 100)
+ }
+ if val, ok := dictMap[data[v].Platform]; ok {
+ data[v].Platform = val
+ }
+ }
+ return nil, data, total
+}
+
+func GetOrderDetail(userId string, info *request.GetOrderParams) (error, model.OrderDetail) {
+ var (
+ err error
+ data model.OrderDetail
+ tCommod model.TbGoods
+ )
+ err = global.MG_DB.Model(&model.Order{}).Joins("INNER JOIN mission_claim ON mission_claim.claim_no = `order`.`code`").
+ Where("mission_claim.create_by = ? AND order_id = ?", userId, info.OrderID).Find(&data).Error
+ if err != nil {
+ return errors.New("获取订单失败"), data
+ }
+ err = global.MG_DB.Model(&model.OrderAddress{}).Where("order_id=?", info.OrderID).Find(&data.Address).Error
+ if err != nil {
+ return errors.New("获取订单地址失败"), data
+ }
+ err = global.MG_DB.Model(&model.OrderGoods{}).Where("order_id=?", info.OrderID).Find(&data.Goods).Error
+ if err != nil {
+ return errors.New("获取订单商品信息失败"), data
+ }
+ err = global.MG_DB.Model(&model.OrderDeliver{}).Where("order_id=?", info.OrderID).Find(&data.Deliver).Error
+ if err != nil {
+ return errors.New("获取发货信息失败"), data
+ }
+ if data.Code != "" {
+ var mission model.MissionClaimInfo
+ _ = global.MG_DB.Model(&model.MissionClaim{}).Joins("inner join mission b on mission_claim.mission_id=b.id").
+ Select("mission_claim.claim_no,mission_claim.mission_id,b.hire_type,b.hire_money,b.hire_ratio").Where("claim_no = ? AND b.hire_type = 2", data.Code).First(&mission)
+ if mission.MissionId != 0 {
+ amount := data.PaidPrice * mission.HireRatio / 100
+ data.InfluencerAmount = utils.FormatFloatToString(amount)
+ }
+ }
+ if data.Platform != "" {
+ data.Platform = GetSysDictDataLabel("release_channel", data.Platform)
+ }
+ global.MG_DB.Model(&model.TbGoods{}).Where("id=?", data.CommodID).Find(&tCommod)
+ global.MG_DB.Model(&model.SellerStore{}).Select("store_no,`type`,email").Where("store_no = ?", tCommod.StoreNo).Find(&data.Store)
+ _ = global.MG_DB.Model(&model.OrderPostSale{}).Select("id,order_id,status,remark,examine_time,refund_time,refund_status,created_at").Where("order_id = ? AND status IN (1,2,3)", data.OrderID).First(&data.PostSale).Error
+ if data.PayTime != nil {
+ data.Bill, _ = getBillView(data.OrderID)
+ }
+ data.Chain = model.Chain{Address: "b714e5508531a7b50d0696abdc83d2333bd896db24f68eb1470bb9529390ef3e"}
+ return nil, data
+}
+
+func GetOrderGoods(userId string, info *request.GetOrderParams) (error, model.OrderGoodsDetail) {
+ var (
+ err error
+ order model.Order
+ result model.OrderGoodsDetail
+ )
+ err = global.MG_DB.Model(&model.Order{}).Joins("INNER JOIN mission_claim ON mission_claim.claim_no = `order`.`code`").
+ Where("mission_claim.create_by = ? AND order_id = ?", userId, info.OrderID).Find(&order).Error
+ if err != nil {
+ return errors.New("获取订单失败"), result
+ }
+ err = global.MG_DB.Model(&model.OrderGoods{}).Where("order_id = ?", info.OrderID).Find(&result).Error
+ if err != nil {
+ return errors.New("获取订单商品信息失败"), result
+ }
+ err = global.MG_DB.Model(&model.OrderGoodsSpecs{}).Where("order_goods_id = ?", result.ID).Find(&result.GoodsSpecs).Error
+ if err != nil {
+ return errors.New("获取订单商品规格信息失败"), result
+ }
+ attributeValues := make(map[uint]*model.TbAttributeValueJson)
+ for i := 0; i < len(result.GoodsSpecs); i++ {
+ var attributeList []model.TbAttributeDetail
+ err = json.Unmarshal([]byte(result.GoodsSpecs[i].Specs), &attributeList)
+ if err != nil {
+ return err, result
+ }
+ if i == 0 {
+ var attributes []uint
+ for j := 0; j < len(attributeList); j++ {
+ attributes = append(attributes, attributeList[j].AttributeId)
+ }
+ orderSql := "FIELD(id"
+ for _, attribute := range attributes {
+ orderSql += fmt.Sprintf(",'%v'", attribute)
+ }
+ orderSql += ")"
+ err = global.MG_DB.Model(&model.TbAttribute{}).Select("id,`name`").Where("id IN (?)", attributes).Order(orderSql).Find(&result.Attributes).Error
+ if err != nil {
+ return err, result
+ }
+ }
+ for _, attribute := range attributeList {
+ if _, ok := attributeValues[attribute.AttributeId]; ok {
+ if !strings.Contains(attributeValues[attribute.AttributeId].Str, attribute.Value) {
+ attributeValues[attribute.AttributeId].Str += attribute.Value + ","
+ attributeValues[attribute.AttributeId].Items = append(attributeValues[attribute.AttributeId].Items, model.TbAttributeValueItem{Id: attribute.ValueId, Name: attribute.Value, Image: result.GoodsSpecs[i].Image})
+ }
+ } else {
+ attributeValues[attribute.AttributeId] = &model.TbAttributeValueJson{Items: []model.TbAttributeValueItem{{Id: attribute.ValueId, Name: attribute.Value, Image: result.GoodsSpecs[i].Image}}, Str: attribute.Value + ","}
+ }
+ }
+ }
+ for i := 0; i < len(result.Attributes); i++ {
+ if val, ok := attributeValues[result.Attributes[i].ID]; ok {
+ result.Attributes[i].Values = val.Items
+ }
+ }
+ return err, result
+}
+
+// 用户提现
+func CreatePayOutPayer(paypalName, amount, withdID string) (error, *paypal.PayoutResponse) {
+ var (
+ err error
+ c *paypal.Client
+ )
+ if global.MG_CONFIG.Paypal.Env == "SandBox" {
+ c, err = paypal.NewClient(global.MG_CONFIG.Paypal.ClientID, global.MG_CONFIG.Paypal.Secret, paypal.APIBaseSandBox)
+ if err != nil {
+ return err, nil
+ }
+ } else {
+ c, err = paypal.NewClient(global.MG_CONFIG.Paypal.ClientID, global.MG_CONFIG.Paypal.Secret, paypal.APIBaseLive)
+ if err != nil {
+ return err, nil
+ }
+ }
+ _, err = c.GetAccessToken()
+ if err != nil {
+ return err, nil
+ }
+ payout := paypal.Payout{}
+ send := &paypal.SenderBatchHeader{
+ SenderBatchID: withdID,
+ }
+ item := make([]paypal.PayoutItem, 1)
+ fmt.Println(amount)
+ item[0] = paypal.PayoutItem{
+ RecipientType: "EMAIL",
+ Receiver: paypalName,
+ Amount: &paypal.AmountPayout{
+ Currency: "USD", // 收款类型
+ Value: amount, // 收款数量
+ },
+ Note: "打款",
+ }
+ payout.SenderBatchHeader = send
+ payout.Items = item
+ fmt.Println(payout.Items[0].Amount)
+ resp, err := c.CreateSinglePayout(payout)
+ if err != nil {
+ fmt.Println(err.Error())
+ fmt.Println(resp)
+ return err, nil
+ }
+ return err, resp
+}
+
+// 生成24位订单号
+// 前面17位代表时间精确到毫秒,中间3位代表进程id,最后4位代表序号
+var num int64
+
+func Generate() string {
+ t := time.Now()
+ s := t.Format(timeformat.Continuity)
+ m := t.UnixNano()/1e6 - t.UnixNano()/1e9*1e3
+ ms := sup(m, 3)
+ p := os.Getpid() % 1000
+ ps := sup(int64(p), 3)
+ i := atomic.AddInt64(&num, 1)
+ r := i % 10000
+ rs := sup(r, 4)
+ n := fmt.Sprintf("%s%s%s%s", s, ms, ps, rs)
+ return n
+}
+
+// 对长度不足n的数字前面补0
+func sup(i int64, n int) string {
+ m := fmt.Sprintf("%d", i)
+ for len(m) < n {
+ m = fmt.Sprintf("0%s", m)
+ }
+ return m
+}
+
+func GetOrderTotalList(info *request.SearchOrderList) (error, any) {
+ var (
+ err error
+ data model.OrderTotal
+ )
+ if info.Code == "" {
+ return errors.New("任务码不可为空"), nil
+ }
+ db := global.MG_DB.Model(&model.Order{})
+ if info.Status != 0 {
+ db = db.Where("status=?", info.Status)
+ }
+ if info.Code != "" {
+ db = db.Where("code=?", info.Code)
+ }
+ err = db.Select("sum(case when `status`=2 then 1 else 0 end) status2,sum(case when `status`=3 then 1 else 0 end) status3,sum(case when `status`=4 then 1 else 0 end) status4").Scan(&data).Error
+ if err != nil {
+ return errors.New("获取订单失败"), data
+ }
+ return nil, data
+}
+
+func GetMissionOrderStatistic(userId, claimNo string) (dto.MissionOrderStatistic, error) {
+ var (
+ err error
+ claim model.MissionClaim
+ statistic model.DtStatisticOrder
+ result dto.MissionOrderStatistic
+ )
+ err, claim = getMissionClaim(userId, claimNo)
+ if err != nil {
+ return result, err
+ }
+ statistic, _ = getStatisticsOrderByValues([]string{}, "", "2", claimNo)
+ visits := GetGoodsVisit(claimNo)
+ result = dto.MissionOrderStatistic{
+ OrderNum: statistic.OrderNum,
+ OrderDoneNum: statistic.OrderDoneNum,
+ OrderMoney: statistic.OrderMoney,
+ SettleReward: claim.RewardFinished,
+ TransitReward: claim.RewardUnfinished,
+ RewardRatio: 0.1,
+ Uv: visits,
+ SellNum: claim.AchieveNum,
+ }
+ result.OrderUserNum, _ = getOrderCount(userId, &request.SearchOrderList{Group: "user", Code: claimNo})
+
+ return result, nil
+}
+
+func getStatisticsOrder(value, unit, relationId string) (model.DtStatisticOrder, error) {
+ var (
+ err error
+ result model.DtStatisticOrder
+ )
+ db := global.MG_DB.Model(&model.DtStatisticOrder{}).Where("`value` = ? AND `unit` = ?", value, unit)
+ if relationId != "" {
+ db = db.Where("`relation_id` = ?", relationId)
+ }
+ err = db.First(&result).Error
+ return result, err
+}
+
+// 累计销量 "all","all","goods_id"
+// 30天销量 "day","30","goods_id"
+func GetStatisticsOrderByValues(unit string, value int, relationId string) (model.DtStatisticOrder, error) {
+ if value < 0 {
+ return model.DtStatisticOrder{}, errors.New("value error")
+ }
+ var values = make([]string, 0)
+ now := time.Now()
+ switch unit {
+ case "day":
+ if value == 0 {
+ values = append(values, now.Format("20060102"))
+ } else {
+ tmp := now.AddDate(0, 0, -value)
+ for i := 0; i < value; i++ {
+ values = append(values, tmp.Format("20060102"))
+ tmp = tmp.AddDate(0, 0, 1)
+ }
+ }
+ case "month":
+
+ }
+ return getStatisticsOrderByValues(values, "day", "", relationId)
+}
+
+func getStatisticsOrderByValues(values []string, unit, t, relationId string) (model.DtStatisticOrder, error) {
+ var (
+ err error
+ result model.DtStatisticOrder
+ )
+ db := global.MG_DB.Model(&model.DtStatisticOrder{}).Where("`unit` = ?", unit).
+ Select("SUM(order_num) as order_num,SUM(order_done_num) as order_done_num,SUM(order_money) as order_money,SUM(sale_volume) as sale_volume,SUM(settle_reward) as settle_reward,SUM(order_cancel_num) as order_cancel_num,SUM(order_cancel_money) as order_cancel_money")
+ if len(values) != 0 {
+ db = db.Where("`value` IN (?) ", values)
+ }
+ if t != "" {
+ db = db.Where("`type` = ?", t)
+ }
+ if relationId != "" {
+ db = db.Where("`relation_id` = ?", relationId)
+ }
+ err = db.First(&result).Error
+ return result, err
+}
+
+// 获取网红维度订单数据统计
+func getStatisticsOrderInfluence(uuid, unit string, timeArea []string) (model.DtStatisticOrder, error) {
+ var (
+ err error
+ result model.DtStatisticOrder
+ )
+ db := global.MG_DB.Model(&model.DtStatisticOrder{}).Joins("INNER JOIN mission_claim ON mission_claim.claim_no = dt_statistic_order.relation_id").
+ Where("dt_statistic_order.`type` = 2 AND mission_claim.create_by = ? AND dt_statistic_order.`unit` = ?", uuid, unit)
+ if len(timeArea) == 2 {
+ db = db.Where("dt_statistic_order.created_at >= ? AND dt_statistic_order.created_at < ?", timeArea[0], timeArea[1])
+ }
+ err = db.Select("SUM(dt_statistic_order.order_num) as order_num,SUM(dt_statistic_order.order_done_num) as order_done_num,SUM(dt_statistic_order.order_money) as order_money,SUM(dt_statistic_order.sale_volume) as sale_volume,SUM(dt_statistic_order.settle_reward) as settle_reward,SUM(dt_statistic_order.order_cancel_num) as order_cancel_num,SUM(dt_statistic_order.order_cancel_money) as order_cancel_money").First(&result).Error
+ return result, err
+}
+
+func GetGoodsVisit(claimNo string) (count int64) {
+ global.MG_DB.Model(&model.GoodsVisit{}).Where("claim_no=?", claimNo).Count(&count)
+ return count
+}
diff --git a/service/redis_tools.go b/service/redis_tools.go
new file mode 100644
index 0000000..ebdbf4f
--- /dev/null
+++ b/service/redis_tools.go
@@ -0,0 +1,355 @@
+package service
+
+import (
+ "fmt"
+ "pure/global"
+ "strconv"
+ "time"
+
+ "github.com/go-redis/redis"
+)
+
+// RedisGet ...
+func RedisGet(key string) string {
+ result, err := global.MG_REDIS.Get(key).Result()
+ if err != nil {
+ return ""
+ }
+ return result
+}
+
+func RedisSet(key string, value interface{}, expiration time.Duration) string {
+ result, err := global.MG_REDIS.Set(key, value, expiration).Result()
+ if err != nil {
+ //global.MG_LOG.Error("Redis Set Error:", zap.Any("err", err))
+ return ""
+ }
+ return result
+}
+
+func RedisDel(key ...string) (int64, error) {
+ result, err := global.MG_REDIS.Del(key...).Result()
+ if err != nil {
+ //global.MG_LOG.Error("Redis Del Error:", zap.Any("err", err))
+ return -1, err
+ }
+ return result, err
+}
+
+func RedisZAdd1(client *redis.Client, key string, values map[float64]interface{}) (int64, error) {
+ var members []redis.Z
+ for scale, value := range values {
+ members = append(members, redis.Z{
+ Score: scale,
+ Member: value,
+ })
+ }
+ result, err := client.ZAdd(key, members...).Result()
+ if err != nil {
+ //global.MG_LOG.Error("Redis ZAdd Error:", zap.Any("err", err))
+ return 0, err
+ }
+ return result, nil
+}
+
+func RedisDel2(client *redis.Client, key ...string) (int64, error) {
+ result, err := client.Del(key...).Result()
+ if err != nil {
+ //global.MG_LOG.Error("Redis2 Del Error:", zap.Any("err", err))
+ return -1, err
+ }
+ return result, err
+}
+
+// RedisHashSet 向key的hash中添加元素field的值
+func RedisHashSet(key, field string, data interface{}) error {
+ err := global.MG_REDIS.HSet(key, field, data).Err()
+ if err != nil {
+ //global.MG_LOG.Error("Redis HSet Error:", zap.Any("err", err))
+ return err
+ }
+ return nil
+}
+
+// RedisBatchHashSet 批量向key的hash添加对应元素field的值
+func RedisBatchHashSet(key string, fields map[string]interface{}) (error, string) {
+ val, err := global.MG_REDIS.HMSet(key, fields).Result()
+ if err != nil {
+ //global.MG_LOG.Error("Redis HMSet Error:", zap.Any("err", err))
+ return err, ""
+ }
+ return nil, val
+}
+
+func RedisHDel(key string, fields ...string) (error, int64) {
+ result, err := global.MG_REDIS.HDel(key, fields...).Result()
+ if err != nil {
+ //global.MG_LOG.Error("Redis HMSet Error:", zap.Any("err", err))
+ return err, 0
+ }
+ return nil, result
+}
+
+func RedisHSet(key, field string, value interface{}) (error, bool) {
+ val, err := global.MG_REDIS.HSet(key, field, value).Result()
+ if err != nil {
+ //global.MG_LOG.Error("Redis HSet Error:", zap.Any("err", err))
+ return err, false
+ }
+ return nil, val
+}
+
+func RedisBatchHashSet1(key string, fields map[string]interface{}) (error, string) {
+ val, err := global.MG_REDIS.HMSet(key, fields).Result()
+ if err != nil {
+ //global.MG_LOG.Error("Redis HMSet Error:", zap.Any("err", err))
+ return err, ""
+ }
+ return nil, val
+}
+
+// RedisHashGet 通过key获取hash的元素值
+func RedisHashGet(key, field string) string {
+ val, err := global.MG_REDIS.HGet(key, field).Result()
+ if err != nil {
+ return ""
+ }
+ return val
+}
+
+func RedisHashMGet(key string, fields ...string) []interface{} {
+ val, err := global.MG_REDIS.HMGet(key, fields...).Result()
+ if err != nil {
+ return nil
+ }
+ return val
+}
+
+//HGetAll
+func RedisHashGetAll(key string) map[string]string {
+ val, err := global.MG_REDIS.HGetAll(key).Result()
+ if err != nil {
+ return nil
+ }
+ return val
+}
+
+// RedisBatchHashGet 批量获取key的hash中对应多元素值
+func RedisBatchHashGet(key string, fields ...string) map[string]interface{} {
+ resMap := make(map[string]interface{})
+ for _, field := range fields {
+ val, err := global.MG_REDIS.HGet(key, fmt.Sprintf("%s", field)).Result()
+ if err == nil && val != "" {
+ resMap[field] = val
+ }
+ }
+ return resMap
+}
+
+func RedisLPush(key string, values ...interface{}) (int64, error) {
+ result, err := global.MG_REDIS.LPush(key, values...).Result()
+ if err != nil {
+ //global.MG_LOG.Error("Redis LPush Error:", zap.Any("err", err))
+ return 0, err
+ }
+ return result, nil
+}
+
+func RedisLPop(key string) (error, string) {
+ result, err := global.MG_REDIS.LPop(key).Result()
+ if err != nil {
+ return err, ""
+ }
+ return err, result
+}
+
+// RedisSAdd 无序集合添加
+func RedisSAdd(key string, values ...interface{}) (int64, error) {
+ result, err := global.MG_REDIS.SAdd(key, values...).Result()
+ if err != nil {
+ //global.MG_LOG.Error("Redis LPush Error:", zap.Any("err", err))
+ return 0, err
+ }
+ return result, nil
+}
+
+func RedisSIsMember(key string, value interface{}) (bool, error) {
+ result, err := global.MG_REDIS.SIsMember(key, value).Result()
+ if err != nil {
+ //global.MG_LOG.Error("Redis LPush Error:", zap.Any("err", err))
+ return false, err
+ }
+ return result, nil
+}
+
+func RedisSRem(key string, values ...interface{}) (int64, error) {
+ result, err := global.MG_REDIS.SRem(key, values...).Result()
+ if err != nil {
+ return 0, err
+ }
+ return result, err
+}
+
+// RedisSMembers 从无序集合中获取数据
+func RedisSMembers(key string) ([]string, error) {
+ val, err := global.MG_REDIS.SMembers(key).Result()
+ if err != nil {
+ //global.MG_LOG.Error("Redis SMembers Error:", zap.Any("err", err))
+ return nil, err
+ }
+ return val, nil
+}
+
+// RedisZAdd 有序集合添加
+func RedisZAdd(key string, values map[float64]interface{}) (int64, error) {
+ var members []redis.Z
+ for scale, value := range values {
+ members = append(members, redis.Z{
+ Score: scale,
+ Member: value,
+ })
+ }
+ result, err := global.MG_REDIS.ZAdd(key, members...).Result()
+ if err != nil {
+ //global.MG_LOG.Error("Redis ZAdd Error:", zap.Any("err", err))
+ return 0, err
+ }
+ return result, nil
+}
+
+func RedisZAdd2(key string, values ...global.RedisValueScore) (int64, error) {
+ var members []redis.Z
+ for _, value := range values {
+ members = append(members, redis.Z{
+ Score: value.Score,
+ Member: value.Value,
+ })
+ }
+ result, err := global.MG_REDIS.ZAdd(key, members...).Result()
+ if err != nil {
+ //global.MG_LOG.Error("Redis ZAdd Error:", zap.Any("err", err))
+ return 0, err
+ }
+ return result, nil
+}
+
+func RedisZRem(client *redis.Client, key string, values ...interface{}) (int64, error) {
+ result, err := client.ZRem(key, values...).Result()
+ if err != nil {
+ return 0, err
+ }
+ return result, err
+}
+
+func RedisZCard(key string) (int64, error) {
+ result, err := global.MG_REDIS.ZCard(key).Result()
+ if err != nil {
+ //global.MG_LOG.Error("Redis ZAdd Error:", zap.Any("err", err))
+ return 0, err
+ }
+ return result, nil
+}
+
+func RedisZRange(key string, start, stop int64, sort string) ([]interface{}, error) {
+ var val = make([]interface{}, 0)
+ if sort == "asc" { //scale 正序
+ result, err := global.MG_REDIS.ZRangeWithScores(key, start, stop).Result()
+ if err != nil {
+ //global.MG_LOG.Error("Redis ZPopMax Error:", zap.Any("err", err))
+ return val, err
+ }
+ for _, z := range result {
+ val = append(val, z.Member)
+ }
+ } else { //scale 倒序
+ result, err := global.MG_REDIS.ZRevRange(key, start, stop).Result()
+ if err != nil {
+ //global.MG_LOG.Error("Redis ZPopMax Error:", zap.Any("err", err))
+ return val, err
+ }
+ for _, z := range result {
+ val = append(val, z)
+ }
+ return val, nil
+ }
+
+ return val, nil
+}
+
+func RedisZRangeByScoreWithScores(client *redis.Client, key string, start, stop int64, offset, limit int, sort string) ([]interface{}, error) {
+ var (
+ err error
+ startStr, stopStr string
+ //flag string
+ result []redis.Z
+ val = make([]interface{}, 0)
+ )
+ if start > 0 {
+ startStr = strconv.FormatInt(start, 10)
+ } else {
+ startStr = "-inf"
+ }
+ if stop > 0 {
+ stopStr = strconv.FormatInt(stop, 10)
+ } else {
+ stopStr = "+inf"
+ }
+ if start != stop {
+ stopStr = "(" + stopStr
+ }
+ if sort == "asc" { //scale 正序
+ result, err = client.ZRangeByScoreWithScores(key, redis.ZRangeBy{
+ Min: startStr,
+ Max: stopStr,
+ Offset: int64(offset),
+ Count: int64(limit),
+ }).Result()
+ if err != nil {
+ //global.MG_LOG.Error("Redis ZRangeByScoreWithScores Error:", zap.Any("err", err))
+ return val, err
+ }
+ } else {
+ result, err = client.ZRevRangeByScoreWithScores(key, redis.ZRangeBy{
+ Min: startStr,
+ Max: stopStr,
+ Offset: int64(offset),
+ Count: int64(limit),
+ }).Result()
+ if err != nil {
+ //global.MG_LOG.Error("Redis ZRangeByScoreWithScores Error:", zap.Any("err", err))
+ return val, err
+ }
+ }
+ for _, z := range result {
+ val = append(val, z.Member)
+ }
+ return val, nil
+}
+
+// RedisIncr 获取自增唯一ID
+func RedisIncr(key string) int {
+ val, err := global.MG_REDIS.Incr(key).Result()
+ if err != nil {
+ //global.MG_LOG.Error("Redis RedisIncr Error:", zap.Any("err", err))
+ }
+ return int(val)
+}
+
+func RedisTest(key string, values ...interface{}) {
+ result, err := global.MG_REDIS.SRem(key, values...).Result()
+ if err != nil {
+ fmt.Println(err)
+ }
+ fmt.Println(result)
+}
+
+func RedisSetNX(key string, value interface{}, expiration time.Duration) (error, bool) {
+ val, err := global.MG_REDIS.SetNX(key, value, expiration).Result()
+ if err != nil {
+ if err != nil {
+ fmt.Println("Redis SetNX Error:", err.Error())
+ }
+ return err, false
+ }
+ return nil, val
+}
diff --git a/service/seller_store.go b/service/seller_store.go
new file mode 100644
index 0000000..50b3441
--- /dev/null
+++ b/service/seller_store.go
@@ -0,0 +1,24 @@
+package service
+
+import (
+ "pure/global"
+ "pure/model"
+)
+
+func GetSellerStoreInfo(uuid string) (err error, res model.SellerStoreInfo) {
+ err = global.MG_DB.Model(&model.SellerStore{}).Select("store_no,type,email,create_by").Where("create_by = ?", uuid).First(&res).Error
+ return
+}
+
+func getSellerStoreInfoMap(uuids []string) (err error, res map[string]model.SellerStoreInfo) {
+ var list []model.SellerStoreInfo
+ err = global.MG_DB.Model(&model.SellerStore{}).Select("store_no,type,email,create_by").Where("create_by IN (?)", uuids).Find(&list).Error
+ if err != nil {
+ return
+ }
+ res = make(map[string]model.SellerStoreInfo)
+ for i := 0; i < len(list); i++ {
+ res[list[i].CreateBy] = list[i]
+ }
+ return
+}
diff --git a/service/sys_brochure.go b/service/sys_brochure.go
new file mode 100644
index 0000000..68eb35a
--- /dev/null
+++ b/service/sys_brochure.go
@@ -0,0 +1,11 @@
+package service
+
+import (
+ "pure/global"
+ "pure/model"
+)
+
+func GetSysBrochure(t string) (err error, brochure model.SysBrochure) {
+ err = global.MG_DB.Model(&model.SysBrochure{}).Where("`type` = ?", t).First(&brochure).Error
+ return
+}
diff --git a/service/sys_mission_reward.go b/service/sys_mission_reward.go
new file mode 100644
index 0000000..f6ed117
--- /dev/null
+++ b/service/sys_mission_reward.go
@@ -0,0 +1,133 @@
+package service
+
+import (
+ "errors"
+ "fmt"
+ "gorm.io/gorm"
+ "pure/global"
+ "pure/model"
+ "pure/model/request"
+ "pure/model/response"
+)
+
+func AddSysMissionReward(params request.AddSysMissionReward, tx *gorm.DB) error {
+ switch params.Type {
+ case 1:
+ //上传视频
+ var (
+ rewardData, checkReward model.SysMissionReward
+ bonusMap map[int64]float64
+ err error
+ bonus float64
+ )
+ bonusMap = map[int64]float64{
+ 1: 0.5,
+ 3: 1.0,
+ 5: 2.0,
+ }
+ if _, ok := bonusMap[params.AchieveNum]; !ok {
+ return err
+ }
+ bonus = bonusMap[params.AchieveNum]
+ err = tx.Model(&model.SysMissionReward{}).
+ Where("create_by = ? and achieve_num = ? and type = ?", params.CreateBy, params.AchieveNum, params.Type).
+ First(&checkReward).Error
+ if checkReward.ID > 0 {
+ return errors.New("不能重复提交")
+ }
+ rewardData = model.SysMissionReward{
+ Title: fmt.Sprintf("上传%d次带货视频", params.AchieveNum),
+ Type: params.Type,
+ RelationId: params.RelationId,
+ Bonus: bonus,
+ Status: 1, //待发放
+ AchieveNum: params.AchieveNum,
+ CreateBy: params.CreateBy,
+ }
+ err = tx.Model(&model.SysMissionReward{}).Create(&rewardData).Error
+ if err != nil {
+ return errors.New("提交失败")
+ }
+ case 2:
+ //信息完善
+ return nil
+ case 3:
+ //商家任务
+ return nil
+ }
+ return nil
+}
+
+func GetSysMissionRewardList(params request.SearchSysReward, uuid string) (err error, list []model.SysMissionReward, total int64) {
+ limit := params.PageSize
+ offset := params.PageSize * (params.Page - 1)
+ db := global.MG_DB.Model(&model.SysMissionReward{}).
+ Where("create_by = ?", uuid)
+ if params.Status != 0 {
+ db = db.Where("status = ?", params.Status)
+ }
+ db.Count(&total)
+ var res []model.SysMissionReward
+ err = db.Order("id desc").Offset(offset).Limit(limit).Find(&res).Error
+ if err != nil {
+ return err, nil, 0
+ }
+
+ return err, res, total
+}
+
+func GetSysRewardSummary(uuid string, params request.SearchSysRewardSummary) (err error, res response.SysMissionBonus) {
+ var (
+ bonus []model.SysMissionBonus
+ )
+
+ db := global.MG_DB.Model(&model.SysMissionReward{}).Select("sum(bonus) as bonus,type,count(1) as total").
+ Where("create_by = ?", uuid)
+ if params.Status != 0 {
+ db = db.Where("status = ?", params.Status)
+ }
+ err = db.Group("type").Find(&bonus).Error
+ if err != nil {
+ return errors.New("查询失败"), res
+ }
+
+ db = global.MG_DB.Model(&model.SysMissionReward{}).
+ Where("create_by = ?", uuid)
+
+ var recordList []model.SysMissionReward
+ err = db.Order("id desc").Find(&recordList).Error
+ if err != nil {
+ return errors.New("查询失败"), res
+ }
+
+ res.VideoBonus.Title = "视频上传"
+ res.VideoBonus.AchieveMax = 5
+ res.VideoBonus.MissionList = []response.SysMissionDesc{
+ {Title: "上传1次带货视频", Bonus: 0.5, Description: "每个任务仅计入1次,不可重复上传", TitleEng: "Upload a sales video once", DescriptionEng: "Each task is only counted once and cannot be uploaded repeatedly"},
+ {Title: "上传3次带货视频", Bonus: 1, Description: "每个任务仅计入1次,不可重复上传", TitleEng: "Upload sales videos 3 times", DescriptionEng: "Each task is only counted once and cannot be uploaded repeatedly"},
+ {Title: "上传5次带货视频", Bonus: 2, Description: "每个任务仅计入1次,不可重复上传", TitleEng: "Upload sales videos 5 times", DescriptionEng: "Each task is only counted once and cannot be uploaded repeatedly"},
+ }
+
+ for _, vBonus := range bonus {
+ switch vBonus.Type {
+ case 1:
+ //视频上传
+ var achieveNum int64
+ global.MG_DB.Model(&model.MissionClaimVideo{}).Where("create_by = ? and source_type = 2 and status in (1,2)", uuid).Count(&achieveNum)
+ vBonus.AchieveNum = achieveNum
+ res.VideoBonus.SysMissionBonus = vBonus
+ //标记用户奖励状态
+ for vi, _ := range res.VideoBonus.MissionList {
+ for _, vRecord := range recordList {
+ if res.VideoBonus.MissionList[vi].Title == vRecord.Title {
+ res.VideoBonus.MissionList[vi].Status = vRecord.Status
+ }
+ }
+ }
+ }
+ res.Total += vBonus.Total
+ res.TotalBonus += vBonus.Bonus
+
+ }
+ return nil, res
+}
diff --git a/service/tags.go b/service/tags.go
new file mode 100644
index 0000000..de89aa9
--- /dev/null
+++ b/service/tags.go
@@ -0,0 +1,49 @@
+package service
+
+import (
+ "pure/global"
+ "pure/model"
+ "strings"
+)
+
+func GetTagsNameByIds(ids []uint) (tags string) {
+ var (
+ tagList []model.Tags
+ names []string
+ )
+ global.MG_DB.Model(&model.Tags{}).Where("id in (?)", ids).Find(&tagList)
+ for _, vTag := range tagList {
+ names = append(names, vTag.Value)
+ }
+
+ return strings.Join(names, ",")
+}
+
+func GetTagsByIds(ids []uint) (tags []model.TagsDesc) {
+ var (
+ tagList []model.TagsDesc
+ )
+ global.MG_DB.Model(&model.Tags{}).Where("id in (?)", ids).Find(&tagList)
+
+ return tagList
+}
+
+func GetTagNamesByRelation(relationId, relationType string) string {
+ //params:relationType 标签类型 01-任务 02-任务视频 03-网红
+ var (
+ relationList []model.TagRelation
+ tagIds []uint
+ tagNames string
+ )
+ global.MG_DB.Model(&model.TagRelation{}).
+ Where("relation_type = ? and relation_id = ?", relationType, relationId).Find(&relationList)
+ if len(relationList) == 0 {
+ return tagNames
+ }
+ for _, v := range relationList {
+ tagIds = append(tagIds, v.TagId)
+ }
+ tagNames = GetTagsNameByIds(tagIds)
+
+ return tagNames
+}
diff --git a/service/tb_category.go b/service/tb_category.go
new file mode 100644
index 0000000..37c78e3
--- /dev/null
+++ b/service/tb_category.go
@@ -0,0 +1,48 @@
+package service
+
+import (
+ "pure/global"
+ "pure/model"
+)
+
+func GetTbCategoryBreadcrumb(id uint) (error, []model.Breadcrumb) {
+ var (
+ category model.Breadcrumb
+ result = make([]model.Breadcrumb, 0)
+ )
+ err := global.MG_DB.Table("tb_category").Select("id,`name`,pid,is_leaf").Where("status = 1 AND id = ?", id).Find(&category).Error
+ if err != nil {
+ return err, nil
+ }
+ if category.Pid != 0 {
+ err = getTbCategoryParent(&category)
+ if err != nil {
+ return err, nil
+ }
+ }
+ transferBreadcrumbList(&category, &result)
+ return nil, result
+}
+
+func getTbCategoryParent(breadcrumb *model.Breadcrumb) (err error) {
+ var tmp model.Breadcrumb
+ err = global.MG_DB.Table("tb_category").Select("id,`name`,pid,is_leaf").Where("status = 1 AND id = ?", breadcrumb.Pid).Find(&tmp).Error
+ if err != nil {
+ return err
+ }
+ breadcrumb.Parent = &tmp
+ if breadcrumb.Parent.Pid != 0 {
+ err = getTbCategoryParent(breadcrumb.Parent)
+ return err
+ }
+ return nil
+}
+
+func transferBreadcrumbList(info *model.Breadcrumb, breadcrumbs *[]model.Breadcrumb) {
+ if info.ID != 0 {
+ *breadcrumbs = append(*breadcrumbs, *info)
+ if info.Parent != nil {
+ transferBreadcrumbList(info.Parent, breadcrumbs)
+ }
+ }
+}
diff --git a/service/tb_goods.go b/service/tb_goods.go
new file mode 100644
index 0000000..cb2b33a
--- /dev/null
+++ b/service/tb_goods.go
@@ -0,0 +1,146 @@
+package service
+
+import (
+ "encoding/json"
+ "errors"
+ "fmt"
+ "gorm.io/gorm"
+ "pure/global"
+ "pure/model"
+ "pure/model/request"
+ "strings"
+)
+
+func GetTbGoods(info request.Goods) (error, model.TbGoodsDetail) {
+ var (
+ err error
+ result model.TbGoodsDetail
+ )
+ if info.ID == 0 && info.SkuNo == "" {
+ err = errors.New("参数有误")
+ return err, result
+ }
+ db := global.MG_DB.Table("tb_goods").Select("id,spu_no,category_id,title,title_eng,images,content,content_text,list_price,retail_price,price_min,price_max,tags,online").
+ Preload("Specs", func(db *gorm.DB) *gorm.DB {
+ return db.Select("id,goods_id,specs,sku_no,stock,price,image,goods_no,code").Where("status = 1")
+ })
+ if info.ID != 0 {
+ db = db.Where("id = ?", info.ID)
+ }
+ if info.SkuNo != "" {
+ db = db.Where("spu_no = ?", info.SkuNo)
+ }
+ err = db.First(&result).Error
+ if err != nil {
+ return err, result
+ }
+ var attributeValues = make(map[uint]*model.TbAttributeValueJson)
+ for i := 0; i < len(result.Specs); i++ {
+ err = json.Unmarshal([]byte(result.Specs[i].Specs), &result.Specs[i].Attributes)
+ if err != nil {
+ return err, result
+ }
+ if i == 0 {
+ var attributes []uint
+ for j := 0; j < len(result.Specs[i].Attributes); j++ {
+ attributes = append(attributes, result.Specs[i].Attributes[j].AttributeId)
+ }
+ orderSql := "FIELD(id"
+ for _, attribute := range attributes {
+ orderSql += fmt.Sprintf(",'%v'", attribute)
+ }
+ orderSql += ")"
+ err = global.MG_DB.Model(&model.TbAttribute{}).Select("id,`name`").Where("id IN (?)", attributes).Order(orderSql).Find(&result.Attributes).Error
+ if err != nil {
+ return err, result
+ }
+ }
+ for _, attribute := range result.Specs[i].Attributes {
+ if _, ok := attributeValues[attribute.AttributeId]; ok {
+ if !strings.Contains(attributeValues[attribute.AttributeId].Str, attribute.Value) {
+ attributeValues[attribute.AttributeId].Str += attribute.Value + ","
+ attributeValues[attribute.AttributeId].Items = append(attributeValues[attribute.AttributeId].Items, model.TbAttributeValueItem{Name: attribute.Value, Image: result.Specs[i].Image})
+ }
+ } else {
+ attributeValues[attribute.AttributeId] = &model.TbAttributeValueJson{Items: []model.TbAttributeValueItem{{Name: attribute.Value, Image: result.Specs[i].Image}}, Str: attribute.Value + ","}
+ }
+ }
+ }
+ for i := 0; i < len(result.Attributes); i++ {
+ if val, ok := attributeValues[result.Attributes[i].ID]; ok {
+ result.Attributes[i].Values = val.Items
+ }
+ }
+ _, result.Breadcrumb = GetTbCategoryBreadcrumb(result.CategoryId) //获取分类面包屑
+ return nil, result
+}
+
+func GetTbGoodsWithMission(uuid string, info request.Goods) (error, model.TbGoodsDetail) {
+ var (
+ err error
+ result model.TbGoodsDetail
+ )
+ if info.ID == 0 && info.SkuNo == "" {
+ err = errors.New("参数有误")
+ return err, result
+ }
+ db := global.MG_DB.Table("tb_goods").Select("id,spu_no,category_id,title,title_eng,images,content,content_text,list_price,retail_price,price_min,price_max,tags,online").
+ Preload("Specs", func(db *gorm.DB) *gorm.DB {
+ return db.Select("id,goods_id,specs,sku_no,stock,price,image").Where("status = 1")
+ })
+ if info.ID != 0 {
+ db = db.Where("id = ?", info.ID)
+ }
+ if info.SkuNo != "" {
+ db = db.Where("spu_no = ?", info.SkuNo)
+ }
+ err = db.First(&result).Error
+ if err != nil {
+ return err, result
+ }
+ var attributeValues = make(map[uint]*model.TbAttributeValueJson)
+ for i := 0; i < len(result.Specs); i++ {
+ err = json.Unmarshal([]byte(result.Specs[i].Specs), &result.Specs[i].Attributes)
+ if err != nil {
+ return err, result
+ }
+ if i == 0 {
+ var attributes []uint
+ for j := 0; j < len(result.Specs[i].Attributes); j++ {
+ attributes = append(attributes, result.Specs[i].Attributes[j].AttributeId)
+ }
+ orderSql := "FIELD(id"
+ for _, attribute := range attributes {
+ orderSql += fmt.Sprintf(",'%v'", attribute)
+ }
+ orderSql += ")"
+ err = global.MG_DB.Model(&model.TbAttribute{}).Select("id,`name`").Where("id IN (?)", attributes).Order(orderSql).Find(&result.Attributes).Error
+ if err != nil {
+ return err, result
+ }
+ }
+ for _, attribute := range result.Specs[i].Attributes {
+ if _, ok := attributeValues[attribute.AttributeId]; ok {
+ if !strings.Contains(attributeValues[attribute.AttributeId].Str, attribute.Value) {
+ attributeValues[attribute.AttributeId].Str += attribute.Value + ","
+ attributeValues[attribute.AttributeId].Items = append(attributeValues[attribute.AttributeId].Items, model.TbAttributeValueItem{Name: attribute.Value, Image: result.Specs[i].Image})
+ }
+ } else {
+ attributeValues[attribute.AttributeId] = &model.TbAttributeValueJson{Items: []model.TbAttributeValueItem{{Name: attribute.Value, Image: result.Specs[i].Image}}, Str: attribute.Value + ","}
+ }
+ }
+ }
+ for i := 0; i < len(result.Attributes); i++ {
+ if val, ok := attributeValues[result.Attributes[i].ID]; ok {
+ result.Attributes[i].Values = val.Items
+ }
+ }
+ _, result.Breadcrumb = GetTbCategoryBreadcrumb(result.CategoryId) //获取分类面包屑
+ result.CollectStatus = getGoodsCollectStatus(uuid, info.SkuNo)
+ return nil, result
+}
+
+// 统计商品总销售量
+func UpdateTbGoodsSalesByGoodsId(goodsId uint, count int) {
+ _ = global.MG_DB.Model(&model.TbGoods{}).Where("id = ?", goodsId).UpdateColumn("sales", gorm.Expr("sales + ?", count)).Error
+}
diff --git a/service/user.go b/service/user.go
new file mode 100644
index 0000000..13808db
--- /dev/null
+++ b/service/user.go
@@ -0,0 +1,868 @@
+package service
+
+import (
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "net/http"
+ "net/url"
+ "pure/global"
+ "pure/initialize/api"
+ "pure/model"
+ "pure/model/request"
+ "pure/model/response"
+ "pure/utils"
+ "strconv"
+ "strings"
+ "time"
+
+ uuid "github.com/satori/go.uuid"
+ "golang.org/x/oauth2"
+ "golang.org/x/oauth2/google"
+ "golang.org/x/oauth2/instagram"
+)
+
+func UserLogin(u *request.UserLogin) (err error, userInter *model.User) {
+ var user model.User
+ switch u.Type {
+ case "1":
+ if global.MG_CONFIG.System.Env != "prod" && u.Code == "888888" {
+
+ } else {
+ resp, err := global.SMS_CLIENT.VerifyCode(context.Background(), &api.SmsCodeVerifyRequest{
+ Phone: u.Phone,
+ Code: u.Code,
+ })
+ if err != nil {
+ return err, nil
+ }
+ if resp.Code != 0 {
+ return errors.New("验证码验证失败"), nil
+ }
+ }
+ err = global.MG_DB.Where("phone = ? and appid=? and type=? and log_off_time is null", u.Phone, u.Appid, "influencer").Find(&user).Error
+ if err != nil {
+ return errors.New("获取用户失败"), nil
+ }
+ case "2":
+ code := RedisGet("email_code:" + u.Email)
+ if global.MG_CONFIG.System.Env != "prod" && u.Code == "888888" {
+
+ } else if code != u.Code {
+ return errors.New("验证码验证失败"), nil
+ }
+ err = global.MG_DB.Where("email = ? and appid=? and type=? and log_off_time is null", u.Email, u.Appid, "influencer").Find(&user).Error
+ if err != nil {
+ return errors.New("获取用户失败"), nil
+ }
+ }
+ if user.UUID == uuid.Nil {
+ return errors.New("用户名或密码错误"), nil
+ }
+ return err, &user
+}
+
+func UserRegister(u *request.UserRegister) (err error, userInter *model.User) {
+ var user model.User
+ global.MG_DB.Where("email = ? and appid=? and type=? and log_off_time is null", u.Email, u.Appid, "influencer").Find(&user)
+ if user.UUID == uuid.Nil {
+ //用户注册
+ user.UUID = uuid.NewV4()
+ user.NickName = u.Nickname
+ user.Email = u.Email
+ user.Avatar = u.Avatar
+ user.Appid = u.Appid
+ user.Type = "influencer"
+ user.CountryCode = u.CountryCode
+ err = global.MG_DB.Model(&model.User{}).Create(&user).Error
+ if err != nil {
+ return errors.New("注册失败,请稍后再试"), nil
+ }
+ var wallet model.Wallet
+ wallet.UserID = user.UUID.String()
+ wallet.Platform = "influencer"
+ wallet.State = 0
+ global.MG_DB.Model(&model.Wallet{}).Create(&wallet)
+ } else {
+ return errors.New("用户已存在"), nil
+ }
+ return err, &user
+}
+
+func UserBandPhone(u *request.UserBandPhone, appid, userID string) (err error) {
+ if global.MG_CONFIG.System.Env != "prod" && u.Code == "888888" {
+
+ } else {
+ resp, err := global.SMS_CLIENT.VerifyCode(context.Background(), &api.SmsCodeVerifyRequest{
+ Phone: u.Phone,
+ Code: u.Code,
+ })
+ if err != nil {
+ return err
+ }
+ if resp.Code != 0 {
+ return errors.New("验证码验证失败")
+ }
+ }
+ var user model.User
+ err = global.MG_DB.Where("phone = ? and appid=? and type=?", u.Phone, appid, "influencer").Find(&user).Error
+ if err != nil {
+ return errors.New("获取用户失败")
+ }
+ if user.UUID != uuid.Nil {
+ return errors.New("手机号已被绑定")
+ }
+ err = global.MG_DB.Model(&model.User{}).Where("uuid=?", userID).Update("phone", u.Phone).Error
+ if err != nil {
+ return errors.New("绑定失败")
+ }
+ return err
+}
+
+func UserPlatformAuth(u *request.UserPlatformAuth, userID string) (err error) {
+ var (
+ platformJson string
+ uMap = make(map[string]interface{})
+ user model.UserSimple
+ platforms []request.Platform
+ dictData []model.SysDictData
+ )
+ err = global.MG_DB.Model(&model.User{}).Where("uuid=?", userID).Find(&user).Error
+ if err != nil {
+ return errors.New("获取用户失败")
+ }
+ err = global.MG_DB.Model(&model.SysDictData{}).Where("type_code=?", "release_channel").Find(&dictData).Error
+ if err != nil {
+ return errors.New("获取用户失败")
+ }
+ err = json.Unmarshal([]byte(user.Platform), &platforms)
+ t := time.Now()
+ u.Platform.CreatedAt = &t
+ u.Platform.IsAuth = false
+ if err != nil {
+ for i := 0; i < len(dictData); i++ {
+ platforms = append(platforms, request.Platform{
+ Platform: dictData[i].Value,
+ })
+ }
+ for i := 0; i < len(platforms); i++ {
+ if platforms[i].Platform == u.Platform.Platform {
+ platforms[i] = u.Platform
+ platforms[i].CreatedAt = &t
+ }
+ }
+ // platforms = append(platforms, u.Platform)
+ } else {
+ for i := 0; i < len(platforms); i++ {
+ if platforms[i].Platform == u.Platform.Platform && !platforms[i].IsAuth {
+ platforms[i] = u.Platform
+ platforms[i].CreatedAt = &t
+ }
+ }
+ }
+ platformByte, err := json.Marshal(platforms)
+ if err != nil {
+ return errors.New("平台认证格式不正确")
+ }
+ platformJson = string(platformByte)
+ uMap["platform"] = platformJson
+ uMap["tags"] = u.Tags
+ tx := global.MG_DB.Begin()
+ err = tx.Model(&model.User{}).Where("uuid=?", userID).Updates(uMap).Error
+ if err != nil {
+ return errors.New("提交失败")
+ }
+ var platformAuth model.PlatformAuth
+ platformAuth.UserID = userID
+ platformAuth.Platform = u.Platform
+ platformAuth.Status = "0"
+ err = tx.Model(&model.PlatformAuth{}).Create(&platformAuth).Error
+ if err != nil {
+ tx.Rollback()
+ return errors.New("提交失败")
+ }
+ tx.Commit()
+ return nil
+}
+
+func UserAuthorized(u *request.UserAuthorized) (Iuser model.User, err error) {
+ var (
+ aceessToken string
+ userID string
+ provider model.Provider
+ user model.ProviderUser
+ providerList model.ClentProvider
+ application model.Application
+ )
+ err = global.MG_DB.Where("appid=?", u.Appid).Find(&application).Error
+ if err != nil {
+ return Iuser, errors.New("获取应用失败")
+ }
+ if application.ID == 0 {
+ return Iuser, errors.New("应用不存在")
+ }
+ err = json.Unmarshal([]byte(application.Provider), &providerList)
+ if err != nil {
+ return Iuser, errors.New("获取应用失败")
+ }
+ switch u.Client {
+ case "android":
+ for _, v := range providerList.Android {
+ if v.Code == u.Platform {
+ provider = v
+ }
+ }
+ case "ios":
+ for _, v := range providerList.Ios {
+ if v.Code == u.Platform {
+ provider = v
+ }
+ }
+ default:
+ for _, v := range providerList.Web {
+ if v.Code == u.Platform {
+ provider = v
+ }
+ }
+ }
+ if provider.Code == "" {
+ return Iuser, errors.New("平台不存在")
+ }
+ if u.Uuid == "" {
+ if u.Code != "" {
+ //换取token
+ err, aceessToken, userID = GetAccessToken(provider, u.Code)
+ if err != nil {
+ fmt.Println(err.Error())
+ return Iuser, errors.New("获取token失败")
+ }
+ }
+ if u.Token != "" {
+ aceessToken = u.Token
+ }
+ //换取用户信息
+ if provider.UserInfoURI != "" {
+ err, user = GetUserInfo(provider, aceessToken, userID)
+ if err != nil {
+ return Iuser, errors.New("获取用户信息失败")
+ }
+ if user.Avatar == "" {
+ user.Avatar = "https://minio.sumweal.com/nft/221109/C82M980ZLumQCzt857yxur92iAsGdCc7271sDn8MPf666sk44V.png"
+ }
+ }
+ } else {
+ user.UserID = u.Uuid
+ if user.Avatar == "" {
+ user.Avatar = "https://minio.sumweal.com/nft/221109/C82M980ZLumQCzt857yxur92iAsGdCc7271sDn8MPf666sk44V.png"
+ }
+ }
+ if user.UserID == "" {
+ return Iuser, errors.New("授权登录失败")
+ }
+ //查询用户是否存在
+ query := fmt.Sprintf("%s = ? AND appid = ? AND type = ? and log_off_time is null", provider.Code)
+ global.MG_DB.Where(query, user.UserID, u.Appid, "influencer").Find(&Iuser)
+ if Iuser.UUID == uuid.Nil {
+ //注册
+ Iuser.UUID = uuid.NewV4()
+ Iuser.NickName = user.NickName
+ Iuser.Avatar = user.Avatar
+ Iuser.Appid = u.Appid
+ Iuser.Type = "influencer"
+ switch provider.Code {
+ case "tiktok":
+ Iuser.Tiktok = user.UserID
+ case "facebook":
+ Iuser.Facebook = user.UserID
+ case "twitter":
+ Iuser.Twitter = user.UserID
+ case "google":
+ Iuser.Google = user.UserID
+ case "youtube":
+ Iuser.Youtube = user.UserID
+ case "instagram":
+ Iuser.Instagram = user.UserID
+ case "ios":
+ Iuser.Ios = user.UserID
+ }
+ if Iuser.NickName == "" {
+ Iuser.NickName = "BKB_" + utils.GetInvitationLen(4) + "_user"
+ }
+ if Iuser.Avatar == "" {
+ Iuser.Avatar = "https://minio.sumweal.com/nft/221109/C82M980ZLumQCzt857yxur92iAsGdCc7271sDn8MPf666sk44V.png"
+ }
+ err = global.MG_DB.Model(&model.User{}).Create(&Iuser).Error
+ if err != nil {
+ return Iuser, errors.New("注册失败,请稍后再试")
+ }
+ //添加三方登录标识
+ var wallet model.Wallet
+ wallet.UserID = Iuser.UUID.String()
+ wallet.Platform = "influencer"
+ wallet.State = 0
+ global.MG_DB.Model(&model.Wallet{}).Create(&wallet)
+ return Iuser, nil
+ }
+ return Iuser, nil
+}
+
+func GetAccessToken(provider model.Provider, Code string) (err error, aceessToken string, userID string) {
+ //发送post请求
+ switch provider.Code {
+ case "tiktok":
+ aceessToken, err = GetTiktokAccessToken(provider.ClientID, provider.ClientSecret, Code, provider.RedirectURI)
+ case "facebook":
+ //facebook可以直接获取token 暂不提供
+ case "twitter":
+ aceessToken, err = GetTwitterAccessToken(provider.ClientID, provider.ClientSecret, Code, provider.RedirectURI)
+ case "google":
+ var (
+ googleOauthConfig = &oauth2.Config{
+ RedirectURL: provider.RedirectURI,
+ ClientID: provider.ClientID,
+ ClientSecret: provider.ClientSecret,
+ Scopes: []string{"https://www.googleapis.com/auth/userinfo.profile", "https://www.googleapis.com/auth/userinfo.email"},
+ Endpoint: google.Endpoint,
+ }
+ token *oauth2.Token
+ )
+ token, err = googleOauthConfig.Exchange(context.Background(), Code)
+ if err != nil {
+ return err, aceessToken, ""
+ }
+ aceessToken = token.AccessToken
+ case "youtube":
+ var (
+ googleOauthConfig = &oauth2.Config{
+ RedirectURL: provider.RedirectURI,
+ ClientID: provider.ClientID,
+ ClientSecret: provider.ClientSecret,
+ Scopes: []string{"https://www.googleapis.com/auth/userinfo.profile", "https://www.googleapis.com/auth/userinfo.email"},
+ Endpoint: google.Endpoint,
+ }
+ token *oauth2.Token
+ )
+ fmt.Println(provider, Code)
+ token, err = googleOauthConfig.Exchange(context.Background(), Code)
+ if err != nil {
+ return err, aceessToken, ""
+ }
+ aceessToken = token.AccessToken
+ case "instagram":
+ var (
+ instagramOauthConfig = &oauth2.Config{
+ RedirectURL: provider.RedirectURI,
+ ClientID: provider.ClientID,
+ ClientSecret: provider.ClientSecret,
+ Scopes: []string{"user_profile"},
+ Endpoint: instagram.Endpoint,
+ }
+ )
+ token, err := instagramOauthConfig.Exchange(context.Background(), Code)
+ fmt.Println(token)
+ if err != nil {
+ return err, aceessToken, ""
+ }
+ aceessToken = token.AccessToken
+ userID = strconv.Itoa(int(token.Extra("user_id").(float64)))
+ case "ios":
+
+ default:
+ }
+ return
+}
+
+func GetUserInfo(provider model.Provider, aceessToken, userID string) (err error, user model.ProviderUser) {
+ switch provider.Code {
+ case "tiktok":
+ tuser, err := getUserInfo(aceessToken)
+ if err != nil {
+ fmt.Println("Error:", err)
+ return err, user
+ }
+ user.UserID = tuser.OpenID
+ user.NickName = tuser.DisplayName
+ user.Avatar = tuser.AvatarURL
+ return nil, user
+ case "facebook":
+ var userID string
+ //校验token
+ tokenCheckURI := provider.TokenCheckURI + "?input_token=" + aceessToken + "&access_token=" + getAccessToken(provider.ClientID, provider.ClientSecret)
+ err, userID := DebugFacebookToken(aceessToken, tokenCheckURI)
+ if err != nil {
+ return errors.New("token校验失败"), user
+ }
+ //获取用户信息
+ userInfoURI := strings.Replace(provider.UserInfoURI, "USER-ID", userID, 1)
+ userInfoURI = userInfoURI + "&access_token=" + getAccessToken(provider.ClientID, provider.ClientSecret)
+ faceUser, err := getThirdPartyLoginUserBO(userInfoURI)
+ if err != nil {
+ return errors.New("获取用户信息失败"), user
+ }
+ user.UserID = userID
+ user.NickName = faceUser.UserName
+ user.Email = faceUser.Email
+ user.Avatar = faceUser.Picture.Data.URL
+ return nil, user
+ case "instagram":
+ resp, err1 := http.Get(provider.UserInfoURI + userID + fmt.Sprintf("?fields=%v&access_token=%v", "id,username", aceessToken))
+ if err1 != nil {
+ fmt.Println("Failed to get user info: ", err.Error())
+ return
+ }
+
+ defer resp.Body.Close()
+ content, err1 := io.ReadAll(resp.Body)
+ if err1 != nil {
+ fmt.Println("Failed to read response body: ", err1.Error())
+ return
+ }
+ fmt.Println("Response body: ", string(content))
+ var googleUser response.TripartiteInstagram
+ err1 = json.Unmarshal(content, &googleUser)
+ if err1 != nil {
+ fmt.Println("Failed to read response body: ", err1.Error())
+ return
+ }
+ user.UserID = googleUser.ID
+ user.NickName = googleUser.Username
+ case "twitter":
+ user, err = getTwitterUserInfo(provider, aceessToken)
+ return err, user
+ case "google":
+ resp, err1 := http.Get("https://oauth2.googleapis.com/tokeninfo?id_token=" + aceessToken)
+ if err1 != nil {
+ fmt.Println("Failed to get user info: ", err.Error())
+ return
+ }
+
+ defer resp.Body.Close()
+ content, err1 := io.ReadAll(resp.Body)
+ if err1 != nil {
+ fmt.Println("Failed to read response body: ", err1.Error())
+ return
+ }
+ var googleUser response.TripartiteGoogle
+ err1 = json.Unmarshal(content, &googleUser)
+ if err1 != nil {
+ fmt.Println("Failed to read response body: ", err1.Error())
+ return
+ }
+ user.UserID = googleUser.Sub
+ user.NickName = googleUser.Name
+ // user.Email = googleUser.Email
+ user.Avatar = googleUser.Picture
+ fmt.Println("Response body: ", string(content))
+ case "youtube":
+ resp, err1 := http.Get("https://www.googleapis.com/oauth2/v2/userinfo?access_token=" + aceessToken)
+ fmt.Println("https://www.googleapis.com/oauth2/v2/userinfo?access_token=" + aceessToken)
+ if err1 != nil {
+ fmt.Println("Failed to get user info: ", err1.Error())
+ return
+ }
+
+ defer resp.Body.Close()
+ content, err1 := io.ReadAll(resp.Body)
+ if err1 != nil {
+ fmt.Println("Failed to read response body: ", err1.Error())
+ return
+ }
+ var googleUser response.TripartiteGoogle
+ err1 = json.Unmarshal(content, &googleUser)
+ if err1 != nil {
+ fmt.Println("Failed to read response body: ", err1.Error())
+ return
+ }
+ user.UserID = googleUser.ID
+ user.NickName = googleUser.Name
+ // user.Email = googleUser.Email
+ user.Avatar = googleUser.Picture
+ fmt.Println("Response body: ", string(content))
+
+ default:
+ }
+ return
+}
+
+func DebugFacebookToken(accessToken, url string) (err error, userID string) {
+ // 构建请求
+ req, err := http.NewRequest("GET", url, nil)
+ if err != nil {
+ return err, ""
+ }
+
+ // 发送请求
+ client := http.Client{}
+ resp, err := client.Do(req)
+ if err != nil {
+ return err, ""
+ }
+ defer resp.Body.Close()
+
+ // 读取响应数据
+ body, err := io.ReadAll(resp.Body)
+ if err != nil {
+ return err, ""
+ }
+ fmt.Println(string(body))
+ // 解析响应数据
+ var result = make(map[string]interface{})
+ if err := json.Unmarshal(body, &result); err != nil {
+ return err, ""
+ }
+ if _, ok := result["error"].(map[string]interface{}); ok {
+ errorMsg := result["error"].(map[string]interface{})["message"].(string)
+ return errors.New(errorMsg), ""
+ }
+ // 提取 access_token
+ if _, ok := result["data"].(map[string]interface{}); ok {
+ userID, ok := result["data"].(map[string]interface{})["user_id"].(string)
+ if !ok {
+ return errors.New("未能获取有效的user_id"), ""
+ }
+ return nil, userID
+ }
+ return errors.New("未能获取有效的user_id"), ""
+}
+
+func GetTiktokAccessToken(clientKey, clientSecret, code, redirectURI string) (string, error) {
+ // 构建请求体
+ data := url.Values{}
+ data.Set("client_key", clientKey)
+ data.Set("client_secret", clientSecret)
+ data.Set("code", code)
+ data.Set("grant_type", "authorization_code")
+ data.Set("redirect_uri", redirectURI)
+
+ // 构建请求
+ req, err := http.NewRequest("POST", "https://open.tiktokapis.com/v2/oauth/token", strings.NewReader(data.Encode()))
+ if err != nil {
+ return "", err
+ }
+
+ // 设置请求头
+ req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
+
+ // 发送请求
+ client := http.Client{}
+ resp, err := client.Do(req)
+ if err != nil {
+ return "", err
+ }
+ defer resp.Body.Close()
+
+ // 读取响应数据
+ body, err := io.ReadAll(resp.Body)
+ if err != nil {
+ return "", err
+ }
+
+ // 解析响应数据
+ var result map[string]interface{}
+ if err := json.Unmarshal(body, &result); err != nil {
+ return "", err
+ }
+
+ // 检查是否返回错误
+ if errorMsg, ok := result["error_description"].(string); ok {
+ return "", fmt.Errorf("获取 access token 失败:%s", errorMsg)
+ }
+
+ // 提取 access_token
+ accessToken, ok := result["access_token"].(string)
+ if !ok {
+ return "", fmt.Errorf("未能获取有效的 access token")
+ }
+
+ return accessToken, nil
+}
+
+func GetTwitterAccessToken(clientKey, clientSecret, code, redirectURI string) (string, error) {
+ // 构建请求体
+ data := url.Values{}
+ data.Set("code", code)
+ data.Set("grant_type", "authorization_code")
+ data.Set("client_id", clientKey)
+ data.Set("redirect_uri", redirectURI)
+ data.Set("code_verifier", "challenge")
+
+ req, err := http.NewRequest("POST", "https://api.twitter.com/2/oauth2/token", strings.NewReader(data.Encode()))
+ if err != nil {
+ // handle error
+ }
+
+ // 设置请求头
+ req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
+
+ // 发送请求
+ client := http.Client{}
+ resp, err := client.Do(req)
+ if err != nil {
+ return "", err
+ }
+ defer resp.Body.Close()
+
+ // 读取响应数据
+ body, err := io.ReadAll(resp.Body)
+ if err != nil {
+ return "", err
+ }
+
+ // 解析响应数据
+ var result map[string]interface{}
+ if err := json.Unmarshal(body, &result); err != nil {
+ return "", err
+ }
+
+ // 检查是否返回错误
+ if errorMsg, ok := result["error_description"].(string); ok {
+ return "", fmt.Errorf("获取 access token 失败:%s", errorMsg)
+ }
+
+ // 提取 access_token
+ accessToken, ok := result["access_token"].(string)
+ if !ok {
+ return "", fmt.Errorf("未能获取有效的 access token")
+ }
+
+ return accessToken, nil
+}
+
+func getThirdPartyLoginUserBO(url string) (model.FacebookUserInfo, error) {
+ resp, err := http.Get(url)
+ if err != nil {
+ return model.FacebookUserInfo{}, err
+ }
+ defer resp.Body.Close()
+
+ if resp.StatusCode < 200 || resp.StatusCode >= 300 {
+ return model.FacebookUserInfo{}, fmt.Errorf("Facebook请求查询用户接口失败,响应为%d", resp.StatusCode)
+ }
+
+ body, err := io.ReadAll(resp.Body)
+ if err != nil {
+ return model.FacebookUserInfo{}, err
+ }
+
+ var userInfo model.FacebookUserInfo
+ err = json.Unmarshal(body, &userInfo)
+ if err != nil {
+ return model.FacebookUserInfo{}, err
+ }
+
+ return userInfo, nil
+}
+
+func getAccessToken(clientId string, clientSecret string) string {
+ url := "https://graph.facebook.com/oauth/access_token?client_id=" + clientId + "&client_secret=" + clientSecret + "&grant_type=client_credentials"
+ req, err := http.NewRequest("GET", url, nil)
+ if err != nil {
+ return ""
+ }
+ res, err := http.DefaultClient.Do(req)
+ if err != nil {
+ return ""
+ }
+ defer res.Body.Close()
+ body, err := io.ReadAll(res.Body)
+ if err != nil {
+ return ""
+ }
+ var result map[string]interface{}
+ if err := json.Unmarshal(body, &result); err != nil {
+ return ""
+ }
+ fmt.Println(string(body))
+ accessToken, ok := result["access_token"].(string)
+ if !ok {
+ return ""
+ }
+ return accessToken
+ // return url.QueryEscape(clientId + "|" + clientSecret)
+}
+
+func getUserInfo(token string) (*model.TiktokUser, error) {
+ url := "https://open.tiktokapis.com/v2/user/info/?fields=open_id,union_id,avatar_url,display_name"
+ req, err := http.NewRequest("GET", url, nil)
+ if err != nil {
+ return nil, err
+ }
+
+ req.Header.Add("Authorization", "Bearer "+token)
+
+ res, err := http.DefaultClient.Do(req)
+ if err != nil {
+ return nil, err
+ }
+ defer res.Body.Close()
+
+ body, err := io.ReadAll(res.Body)
+ if err != nil {
+ return nil, err
+ }
+
+ var response response.TiktokResponse
+ err = json.Unmarshal(body, &response)
+ if err != nil {
+ return nil, err
+ }
+
+ if response.Error.Code != "ok" {
+ return nil, fmt.Errorf("API error: %s", response.Error.Message)
+ }
+
+ return &response.Data.User, nil
+}
+
+func getUserSimple(ut, uuid string) (model.UserSimple, error) {
+ var (
+ err error
+ result model.UserSimple
+ )
+ err = global.MG_DB.Model(&model.User{}).Select("uuid,nick_name,avatar,phone,platform,tags").Where("`type` = ? AND uuid = ?", ut, uuid).Find(&result).Error
+ if err != nil {
+ return result, err
+ }
+ return result, nil
+}
+
+func GetUserStatistics(uuid string) (err error, info response.UserStatistics) {
+ var (
+ user model.UserSimple
+ collectionTotal int64
+ )
+ err = global.MG_DB.Model(&model.User{}).Where("uuid=?", uuid).Find(&user).Error
+ if err != nil {
+ return errors.New("获取用户失败"), info
+ }
+
+ if user.Platform != "" {
+ var platforms []request.Platform
+ err = json.Unmarshal([]byte(user.Platform), &platforms)
+ for _, v := range platforms {
+ if v.IsAuth {
+ info.PlatformNum += 1
+ }
+ }
+ }
+
+ db := global.MG_DB.Model(&model.CollectionMission{}).Joins("INNER JOIN mission ON mission.id = collection_mission.mission_id").
+ Where("collection_mission.create_by = ?", uuid)
+ err = db.Count(&collectionTotal).Error
+ info.CollectionMissionNum = collectionTotal
+
+ return nil, info
+}
+
+func UpdateUserDetail(userID string, userInfo *request.UserDetail) error {
+ var (
+ err error
+ uMap = make(map[string]interface{})
+ )
+ switch userInfo.Type {
+ case "platform":
+ uMap["platform"] = userInfo.Platform
+ case "tags":
+ uMap["tags"] = userInfo.Tags
+ }
+ err = global.MG_DB.Model(&model.User{}).Where("uuid=?", userID).Updates(uMap).Error
+ if err != nil {
+ return errors.New("修改个人信息失败")
+ }
+ return nil
+}
+
+func GetUserDetail(userID string) (err error, userInfo *model.UserSimple) {
+ var (
+ user model.UserSimple
+ dictData []model.SysDictData
+ )
+ err = global.MG_DB.Model(&model.User{}).Where("uuid=?", userID).Find(&user).Error
+ if err != nil {
+ return errors.New("获取用户失败"), nil
+ }
+ err = global.MG_DB.Model(&model.SysDictData{}).Where("type_code=?", "release_channel").Find(&dictData).Error
+ if err != nil {
+ return errors.New("获取用户失败"), nil
+ }
+ platformsC := make([]request.Platform, 0)
+ for i := 0; i < len(dictData); i++ {
+ platformsC = append(platformsC, request.Platform{
+ Platform: dictData[i].Value,
+ Label: dictData[i].Label,
+ })
+ }
+ if user.Platform != "" {
+ var platforms []request.Platform
+ err = json.Unmarshal([]byte(user.Platform), &platforms)
+ fmt.Println(err)
+ for i := 0; i < len(platforms); i++ {
+ for j := 0; j < len(platformsC); j++ {
+ if platforms[i].Platform == platformsC[j].Platform {
+ platformsC[j].IsAuth = platforms[i].IsAuth
+ platformsC[j].Url = platforms[i].Url
+ platformsC[j].Image = platforms[i].Image
+ }
+ }
+ }
+ user.Platforms = platformsC
+ } else {
+ user.Platforms = platformsC
+ }
+ return nil, &user
+}
+
+func getTwitterUserInfo(provider model.Provider, aceessToken string) (model.ProviderUser, error) {
+ var result response.TripartiteTwitter
+ var user model.ProviderUser
+ req, err := http.NewRequest("GET", provider.UserInfoURI, nil)
+ if err != nil {
+ // handle error
+ return user, err
+ }
+
+ req.Header.Add("Authorization", "Bearer "+aceessToken)
+
+ client := &http.Client{}
+ resp, err := client.Do(req)
+ if err != nil {
+ // handle error
+ return user, err
+ }
+ defer resp.Body.Close()
+
+ body, err := io.ReadAll(resp.Body)
+ if err != nil {
+ // handle error
+ return user, err
+ }
+ fmt.Println("------twitter", string(body))
+ err = json.Unmarshal(body, &result)
+ if err != nil {
+ // handle error
+ fmt.Println("------twitter", err)
+ return user, err
+ }
+ user.UserID = result.Data.ID
+ user.NickName = result.Data.Name
+ return user, err
+}
+
+func UserLogOff(userID string) (err error) {
+ var (
+ uMap = make(map[string]interface{})
+ )
+ uMap["id_forbidden"] = 1
+ uMap["log_off_time"] = time.Now()
+ uMap["forbidden_time"] = time.Now()
+ uMap["forbidden_reason"] = "用户注销"
+ uMap["nick_name"] = "用户已注销"
+ uMap["avatar"] = "https://minio.sumweal.com/nft/221109/C82M980ZLumQCzt857yxur92iAsGdCc7271sDn8MPf666sk44V.png"
+ err = global.MG_DB.Model(&model.User{}).Where("uuid=?", userID).Updates(uMap).Error
+ if err != nil {
+ return errors.New("注销失败")
+ }
+ return nil
+}
diff --git a/service/version.go b/service/version.go
new file mode 100644
index 0000000..ff229b3
--- /dev/null
+++ b/service/version.go
@@ -0,0 +1,58 @@
+package service
+
+import (
+ "pure/global"
+ "pure/model"
+)
+
+func CheckVersion(platform, version string) (model.VersionV, error) {
+ var (
+ err error
+ current model.VersionV
+ result model.VersionV
+ )
+ current, err = GetVersion(platform, version)
+ if err != nil {
+ return result, err
+ }
+ result, err = getNewestVersion(platform, current.Code)
+ if err != nil {
+ return result, err
+ }
+ if current.Status == 2 {
+ result.HideAndSeek = true
+ }
+ return result, nil
+}
+
+func GetVersion(platform, version string) (model.VersionV, error) {
+ var (
+ err error
+ result model.VersionV
+ )
+ err = global.MG_DB.Model(&model.Version{}).Where("`type` = ? AND version = ? AND status IN (1,2)", platform, version).
+ Select("version,`code`,`type`,info,is_force,url,md5,tip,`status`").First(&result).Error
+ return result, err
+}
+
+func getNewestVersion(platform string, code int64) (model.VersionV, error) {
+ var (
+ err error
+ list []model.VersionV
+ result model.VersionV
+ )
+ err = global.MG_DB.Model(&model.Version{}).Where("`type` = ? AND `code` > ? AND `status` = 1", platform, code).
+ Select("version,`code`,`type`,info,is_force,url,md5,tip,`status`").Order("`code` DESC").Find(&list).Error
+ if err != nil {
+ return result, err
+ }
+ if len(list) > 0 {
+ result = list[0]
+ for _, ver := range list {
+ if !result.IsForce && ver.IsForce {
+ result.IsForce = true
+ }
+ }
+ }
+ return result, err
+}
diff --git a/service/wallet.go b/service/wallet.go
new file mode 100644
index 0000000..2e4f48d
--- /dev/null
+++ b/service/wallet.go
@@ -0,0 +1,281 @@
+package service
+
+import (
+ "errors"
+ "time"
+
+ "pure/global"
+ "pure/model"
+ "pure/model/request"
+ "pure/utils"
+
+ "gorm.io/gorm"
+)
+
+func GetUserWalletDetail(userID string) (err error, userInfo *model.Wallet) {
+ var user model.Wallet
+ err = global.MG_DB.Model(&model.Wallet{}).Where("user_id = ?", userID).Find(&user).Error
+ if err != nil {
+ return errors.New("获取用户失败"), nil
+ }
+ return nil, &user
+}
+
+func GetAccountList(userId string) ([]model.Account, error) {
+ var (
+ err error
+ result []model.Account
+ )
+ err = global.MG_DB.Model(&model.Account{}).Where("user_id = ?", userId).Order("created_at desc").Find(&result).Error
+ return result, err
+}
+
+func AddAccount(userId string, info *request.AddAccount) error {
+ var (
+ err error
+ checkAccount model.Account
+ )
+ // 校验重复绑定
+ if info.BankCard != "" {
+ err = global.MG_DB.Model(&model.Account{}).Where("platform = 'influencer' AND card_number = ?", info.BankCard).Find(&checkAccount).Error
+ if err != nil {
+ return err
+ }
+ }
+ if checkAccount.ID != 0 {
+ if checkAccount.UserID == userId {
+ return errors.New("the account already exists in yours account list")
+ } else {
+ //TODO 校验他人重复账户
+ }
+ }
+ tx := global.MG_DB.Begin()
+ if info.IsDefault {
+ err = tx.Model(&model.Account{}).Where("user_id = ? AND platform = ?", userId, "influencer").UpdateColumn("is_default", "0").Error
+ if err != nil {
+ return err
+ }
+ }
+ var account model.Account
+ account.UserID = userId
+ if info.BankCard != "" {
+ account.Type = 2
+ }
+ account.Platform = "influencer"
+ account.AccountName = info.AccountName
+ account.BankCode = info.BankCode
+ account.SwiftCode = info.SwiftCode
+ account.CardNumber = info.BankCard
+ account.Address = info.Address
+ account.Country = info.Country
+ account.Currency = info.Currency
+ account.IsDefault = info.IsDefault
+ err = tx.Create(&account).Error
+ if err != nil {
+ tx.Rollback()
+ return err
+ }
+ tx.Commit()
+ return nil
+}
+
+func UpdateAccountIsDefault(userId string, info *request.IdReq) error {
+ var (
+ err error
+ account model.Account
+ )
+ tx := global.MG_DB.Begin()
+ err = tx.Model(&model.Account{}).Where("user_id = ? AND id = ?", userId, info.ID).First(&account).Error
+ if err != nil {
+ tx.Rollback()
+ return errors.New("get account failed")
+ }
+ if account.IsDefault {
+ err = tx.Model(&model.Account{}).Where("id = ?", account.ID).UpdateColumn("is_default", "0").Error
+ if err != nil {
+ tx.Rollback()
+ return err
+ }
+ } else {
+ err = tx.Model(&model.Account{}).Where("id != ?", account.ID).UpdateColumn("is_default", "0").Error
+ if err != nil {
+ tx.Rollback()
+ return err
+ }
+ err = tx.Model(&model.Account{}).Where("id = ?", account.ID).UpdateColumn("is_default", "1").Error
+ if err != nil {
+ tx.Rollback()
+ return err
+ }
+ }
+ tx.Commit()
+ return err
+}
+
+func DeleteAccount(userId string, info *request.DeleteAccount) error {
+ // TODO 校验手机验证码
+
+ err := global.MG_DB.Model(&model.Account{}).Where("user_id=? and id=?", userId, info.ID).Delete(&model.Account{}).Error
+ return err
+}
+
+func GetUserCommissionList(userID string, info *request.SearchCommission) (error, interface{}, int64) {
+ var (
+ err error
+ data []model.Bill
+ limit int
+ offset int
+ total int64
+ )
+ limit = info.PageSize
+ offset = info.PageSize * (info.Page - 1)
+ db := global.MG_DB.Model(&model.Bill{})
+ if info.Receipt != 0 {
+ db = db.Where("receipt=?", info.Receipt)
+ }
+ err = db.Count(&total).Error
+ if err != nil {
+ return errors.New("获取总数失败"), data, total
+ }
+ err = db.Where("user_id=? and type=1", userID).Offset(offset).Limit(limit).Find(&data).Error
+ if err != nil {
+ return errors.New("获取用户账单失败"), data, total
+ }
+ return nil, data, total
+}
+
+func GetUserWithdrawalList(userID string, info *request.SearchWithdrawal) (error, interface{}, int64) {
+ var (
+ err error
+ data []model.Bill
+ limit int
+ offset int
+ total int64
+ )
+ limit = info.PageSize
+ offset = info.PageSize * (info.Page - 1)
+ db := global.MG_DB.Model(&model.Bill{})
+ if info.Status != 0 {
+ db = db.Where("receipt=?", info.Status)
+ }
+ err = db.Count(&total).Error
+ if err != nil {
+ return errors.New("获取总数失败"), data, total
+ }
+ err = db.Where("user_id=? and type=3", userID).Offset(offset).Limit(limit).Find(&data).Error
+ if err != nil {
+ return errors.New("获取用户账单失败"), data, total
+ }
+ return nil, data, total
+}
+
+func Withdrawal(userId string, info *request.WithdrawalParams) (error, model.WithdrawalView) {
+ var (
+ err error
+ user model.UserSimple
+ result model.WithdrawalView
+ )
+ user, err = getUserSimple("influencer", userId)
+ if err != nil {
+ return errors.New("获取用户信息失败"), result
+ }
+ if user.Phone == "" {
+ return errors.New("please bind your phone number"), result
+ }
+ // 开始交易
+ for {
+ ok, err := global.MG_REDIS.SetNX("withdrawal-"+userId, "used", 10*time.Second).Result()
+ if ok && err == nil {
+ // 获取成功
+ break
+ }
+ }
+ defer func() {
+ // 释放锁
+ _, _ = utils.RedisDel("withdrawal-" + userId)
+ }()
+ var (
+ wallet model.Wallet
+ //check model.Withdrawal
+ )
+ err = global.MG_DB.Model(&model.Wallet{}).Where("platform = 'influencer' AND user_id = ?", userId).First(&wallet).Error
+ if err != nil {
+ return err, result
+ }
+ if wallet.State != 0 {
+ return errors.New("account no withdrawal allowed"), result
+ }
+ //_ = global.MG_DB.Model(&model.Withdrawal{}).Where("platform = '1' AND user_id = ? AND status = '0'", userId).Find(&check).Error
+ //if check.ID != 0 {
+ // return errors.New("you have a withdrawal in progress"), result
+ //}
+ if wallet.Balance < info.Amount {
+ return errors.New("金额不足,无法提现"), result
+ }
+ var account model.Account
+ err = global.MG_DB.Model(&model.Account{}).Where("user_id = ? AND id = ?", userId, info.AccountID).First(&account).Error
+ if err != nil {
+ return errors.New("获取账户信息失败"), result
+ }
+ //if
+ tx := global.MG_DB.Begin()
+ err = tx.Model(&model.Wallet{}).Where("id = ?", wallet.ID).Updates(map[string]interface{}{"balance": gorm.Expr("balance - ?", info.Amount), "state": "1"}).Error
+ if err != nil {
+ tx.Rollback()
+ return errors.New("金额扣除失败,取消提现"), result
+ }
+ var withdrawal model.Withdrawal
+ withdrawal.Platform = "1"
+ withdrawal.WalletType = 1
+ withdrawal.FlowNo = Generate()
+ withdrawal.BillNo = Generate()
+ withdrawal.AccountType = account.Type
+ withdrawal.BankCard = account.BankCard
+ withdrawal.CreateBy = userId
+ withdrawal.Amount = info.Amount
+ withdrawal.CheckStatus = "0"
+ withdrawal.Status = "0"
+ withdrawal.Title = "提现"
+ err = tx.Create(&withdrawal).Error
+ if err != nil {
+ tx.Rollback()
+ return errors.New("提交申请失败"), result
+ }
+
+ var bill model.Bill
+ bill.UserID = userId
+ bill.Type = "3"
+ bill.WithdID = withdrawal.BillNo
+ bill.TransactionId = "B" + bill.WithdID
+ bill.Price = info.Amount
+ bill.Status = 1
+ bill.Receipt = 2
+ bill.WithdrawalStatus = 0
+ bill.Platform = "influencer"
+ //bill.Account = account.PayPalName
+ bill.CheckStatus = "0"
+ bill.Title = "钱包提现"
+ err = tx.Create(&bill).Error
+ if err != nil {
+ tx.Rollback()
+ return errors.New("提现失败,请稍后再试"), result
+ }
+ tx.Commit()
+
+ // 添加通知
+ var notify model.Notify
+ notify.UserId = userId
+ notify.RelationType = "1"
+ notify.RelationId = withdrawal.FlowNo
+ notify.Title = "当前有一笔提现还在审核中,不可发起新的提现"
+ _ = global.MG_DB.Model(&model.Notify{}).Create(¬ify).Error
+
+ result = model.WithdrawalView{
+ FlowNo: withdrawal.FlowNo,
+ }
+ return nil, result
+}
+
+//func addTransitReward(tx *gorm.DB) error {
+//
+//}
diff --git a/service/withdrawal.go b/service/withdrawal.go
new file mode 100644
index 0000000..4d99ae9
--- /dev/null
+++ b/service/withdrawal.go
@@ -0,0 +1,27 @@
+package service
+
+import (
+ "pure/global"
+ "pure/model"
+ "pure/model/request"
+)
+
+func GetWithdrawal(userId string, info *request.FlowNoParam) (error, model.Withdrawal) {
+ var (
+ err error
+ result model.Withdrawal
+ )
+ err = global.MG_DB.Model(&model.Withdrawal{}).Where("platform = '1' AND create_by = ? AND flow_no = ?", userId, info.FlowNo).First(&result).Error
+ return err, result
+}
+func GetWithdrawalList(userId string, info *request.PageInfo) (error, []model.Withdrawal) {
+ var (
+ err error
+ result []model.Withdrawal
+ )
+ limit := info.PageSize
+ offset := info.PageSize * (info.Page - 1)
+ err = global.MG_DB.Model(&model.Withdrawal{}).Where("platform = '1' AND create_by = ?", userId).
+ Order("id DESC").Offset(offset).Limit(limit).Find(&result).Error
+ return err, result
+}
diff --git a/tests/Makefile b/tests/Makefile
new file mode 100644
index 0000000..44b24fd
--- /dev/null
+++ b/tests/Makefile
@@ -0,0 +1,69 @@
+GOHOSTOS:=$(shell go env GOHOSTOS)
+GOPATH:=$(shell go env GOPATH)
+VERSION=$(shell git describe --tags --always)
+
+ifeq ($(GOHOSTOS), windows)
+ #the `find.exe` is different from `find` in bash/shell.
+ #to see https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/find.
+ #changed to use git-bash.exe to run find cli or other cli friendly, caused of every developer has a Git.
+ #Git_Bash= $(subst cmd\,bin\bash.exe,$(dir $(shell where git)))
+ Git_Bash=$(subst \,/,$(subst cmd\,bin\bash.exe,$(dir $(shell where git))))
+ INTERNAL_PROTO_FILES=$(shell $(Git_Bash) -c "find internal -name *.proto")
+ API_PROTO_FILES=$(shell $(Git_Bash) -c "find api -name *.proto")
+else
+ INTERNAL_PROTO_FILES=$(shell find internal -name *.proto)
+ API_PROTO_FILES=$(shell find api -name *.proto)
+
+endif
+
+.PHONY: init
+# init env
+init:
+ go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
+ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
+ go install github.com/go-kratos/kratos/cmd/kratos/v2@latest
+ go install github.com/go-kratos/kratos/cmd/protoc-gen-go-http/v2@latest
+ go install github.com/google/gnostic/cmd/protoc-gen-openapi@latest
+ go install github.com/google/wire/cmd/wire@latest
+
+.PHONY: config
+# generate internal proto
+config:
+ protoc --proto_path=./internal \
+ --proto_path=./third_party \
+ --go_out=paths=source_relative:./internal \
+ $(INTERNAL_PROTO_FILES)
+
+.PHONY: api
+# generate api proto
+api:
+ protoc --proto_path=./api \
+ --proto_path=./third_party \
+ --go_out=paths=source_relative:./api \
+ --go-http_out=paths=source_relative:./api \
+ --go-grpc_out=paths=source_relative:./api \
+ --openapi_out=fq_schema_naming=true,default_response=false:. \
+ $(API_PROTO_FILES)
+
+ ls ./api/*.pb.go | xargs -n1 -IX bash -c 'sed s/,omitempty// X > X.tmp && mv X{.tmp,}'
+
+
+
+# show help
+help:
+ @echo ''
+ @echo 'Usage:'
+ @echo ' make [target]'
+ @echo ''
+ @echo 'Targets:'
+ @awk '/^[a-zA-Z\-\_0-9]+:/ { \
+ helpMessage = match(lastLine, /^# (.*)/); \
+ if (helpMessage) { \
+ helpCommand = substr($$1, 0, index($$1, ":")); \
+ helpMessage = substr(lastLine, RSTART + 2, RLENGTH); \
+ printf "\033[36m%-22s\033[0m %s\n", helpCommand,helpMessage; \
+ } \
+ } \
+ { lastLine = $$0 }' $(MAKEFILE_LIST)
+
+.DEFAULT_GOAL := help
diff --git a/tests/api/recommender.proto b/tests/api/recommender.proto
new file mode 100644
index 0000000..a4de3fe
--- /dev/null
+++ b/tests/api/recommender.proto
@@ -0,0 +1,30 @@
+syntax = "proto3";
+
+package api;
+
+
+
+import "google/api/annotations.proto";
+option go_package = "pure/tests/api";
+
+
+// The greeting service definition.
+
+// The greeting service definition.
+service Recommender {
+ // Sends a greeting
+ rpc Ping (PingRequest) returns (PingReply) {
+
+ }
+}
+
+message PingRequest {
+ string name = 1;
+}
+
+
+
+message PingReply {
+ string message = 1;
+}
+
diff --git a/tests/grpc.go b/tests/grpc.go
new file mode 100644
index 0000000..ca8701d
--- /dev/null
+++ b/tests/grpc.go
@@ -0,0 +1 @@
+package tests
diff --git a/tests/grpc_test.go b/tests/grpc_test.go
new file mode 100644
index 0000000..ca8701d
--- /dev/null
+++ b/tests/grpc_test.go
@@ -0,0 +1 @@
+package tests
diff --git a/tests/openapi.yaml b/tests/openapi.yaml
new file mode 100644
index 0000000..f8f3735
--- /dev/null
+++ b/tests/openapi.yaml
@@ -0,0 +1,10 @@
+# Generated with protoc-gen-openapi
+# https://github.com/google/gnostic/tree/master/cmd/protoc-gen-openapi
+
+openapi: 3.0.3
+info:
+ title: ""
+ version: 0.0.1
+paths: {}
+components:
+ schemas: {}
diff --git a/utils/array.go b/utils/array.go
new file mode 100644
index 0000000..d57e797
--- /dev/null
+++ b/utils/array.go
@@ -0,0 +1,19 @@
+package utils
+
+func ArrayStrRemove(old, loser []string) []string {
+ for j := 0; j < len(loser); j++ {
+ for i := 0; i < len(old); i++ {
+ if old[i] == loser[j] { //将元素剔除
+ if old[i] == loser[j] {
+ if i == len(old)-1 {
+ old = old[:i]
+ } else {
+ old = append(old[:i], old[i+1:]...)
+ i--
+ }
+ }
+ }
+ }
+ }
+ return old
+}
diff --git a/utils/breakpoint_continue.go b/utils/breakpoint_continue.go
new file mode 100644
index 0000000..2dd003d
--- /dev/null
+++ b/utils/breakpoint_continue.go
@@ -0,0 +1,102 @@
+package utils
+
+import (
+ "io/ioutil"
+ "os"
+ "strconv"
+)
+
+// 前端传来文件片与当前片为什么文件的第几片
+// 后端拿到以后比较次分片是否上传 或者是否为不完全片
+// 前端发送每片多大
+// 前端告知是否为最后一片且是否完成
+
+const breakpointDir = "./breakpointDir/"
+const finishDir = "./fileDir/"
+
+//@function: BreakPointContinue
+//@description: 断点续传
+//@param: content []byte, fileName string, contentNumber int, contentTotal int, fileMd5 string
+//@return: error, string
+
+func BreakPointContinue(content []byte, fileName string, contentNumber int, contentTotal int, fileMd5 string) (error, string) {
+ path := breakpointDir + fileMd5 + "/"
+ err := os.MkdirAll(path, os.ModePerm)
+ if err != nil {
+ return err, path
+ }
+ err, pathc := makeFileContent(content, fileName, path, contentNumber)
+ return err, pathc
+
+}
+
+//@function: CheckMd5
+//@description: 检查Md5
+//@param: content []byte, chunkMd5 string
+//@return: CanUpload bool
+
+func CheckMd5(content []byte, chunkMd5 string) (CanUpload bool) {
+ fileMd5 := MD5V(content)
+ if fileMd5 == chunkMd5 {
+ return true // 可以继续上传
+ } else {
+ return false // 切片不完整,废弃
+ }
+}
+
+//@function: makeFileContent
+//@description: 创建切片内容
+//@param: content []byte, fileName string, FileDir string, contentNumber int
+//@return: error, string
+
+func makeFileContent(content []byte, fileName string, FileDir string, contentNumber int) (error, string) {
+ path := FileDir + fileName + "_" + strconv.Itoa(contentNumber)
+ f, err := os.Create(path)
+ if err != nil {
+ return err, path
+ } else {
+ _, err = f.Write(content)
+ if err != nil {
+ return err, path
+ }
+ }
+ defer f.Close()
+ return nil, path
+}
+
+//@function: makeFileContent
+//@description: 创建切片文件
+//@param: fileName string, FileMd5 string
+//@return: error, string
+
+func MakeFile(fileName string, FileMd5 string) (error, string) {
+ rd, err := ioutil.ReadDir(breakpointDir + FileMd5)
+ if err != nil {
+ return err, finishDir + fileName
+ }
+ _ = os.MkdirAll(finishDir, os.ModePerm)
+ fd, err := os.OpenFile(finishDir+fileName, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
+ if err != nil {
+ return err, finishDir + fileName
+ }
+ defer fd.Close()
+ for k := range rd {
+ content, _ := ioutil.ReadFile(breakpointDir + FileMd5 + "/" + fileName + "_" + strconv.Itoa(k))
+ _, err = fd.Write(content)
+ if err != nil {
+ _ = os.Remove(finishDir + fileName)
+ return err, finishDir + fileName
+ }
+ }
+ return nil, finishDir + fileName
+}
+
+//@function: RemoveChunk
+//@description: 移除切片
+//@param: FileMd5 string
+//@return: error
+
+func RemoveChunk(FileMd5 string) error {
+ err := os.RemoveAll(breakpointDir + FileMd5)
+ return err
+}
diff --git a/utils/constant.go b/utils/constant.go
new file mode 100644
index 0000000..a8534e2
--- /dev/null
+++ b/utils/constant.go
@@ -0,0 +1,6 @@
+package utils
+
+const (
+ ConfigEnv = "MG_CONFIG"
+ ConfigFile = "config.yaml"
+)
diff --git a/utils/cors.go b/utils/cors.go
new file mode 100644
index 0000000..1fcc834
--- /dev/null
+++ b/utils/cors.go
@@ -0,0 +1,17 @@
+package utils
+
+import (
+ uuid "github.com/satori/go.uuid"
+ "github.com/taskcluster/slugid-go/slugid"
+)
+
+// Get22UUID ...
+func Get22UUID() string {
+ return slugid.Nice()
+}
+
+// GetUUIDv4 ...
+func GetUUIDv4() string {
+ uid := uuid.NewV4()
+ return uid.String()
+}
diff --git a/utils/db_automation.go b/utils/db_automation.go
new file mode 100644
index 0000000..60c082a
--- /dev/null
+++ b/utils/db_automation.go
@@ -0,0 +1,28 @@
+package utils
+
+import (
+ "errors"
+ "fmt"
+ "time"
+
+ "gorm.io/gorm"
+)
+
+//@function: ClearTable
+//@description: 清理数据库表数据
+//@param: db(数据库对象) *gorm.DB, tableName(表名) string, compareField(比较字段) string, interval(间隔) string
+//@return: error
+
+func ClearTable(db *gorm.DB, tableName string, compareField string, interval string) error {
+ if db == nil {
+ return errors.New("db Cannot be empty")
+ }
+ duration, err := time.ParseDuration(interval)
+ if err != nil {
+ return err
+ }
+ if duration < 0 {
+ return errors.New("parse duration < 0")
+ }
+ return db.Debug().Exec(fmt.Sprintf("DELETE FROM %s WHERE %s < ?", tableName, compareField), time.Now().Add(-duration)).Error
+}
diff --git a/utils/directory.go b/utils/directory.go
new file mode 100644
index 0000000..3c995df
--- /dev/null
+++ b/utils/directory.go
@@ -0,0 +1,46 @@
+package utils
+
+import (
+ "os"
+ "pure/global"
+
+ "go.uber.org/zap"
+)
+
+//@function: PathExists
+//@description: 文件目录是否存在
+//@param: path string
+//@return: bool, error
+
+func PathExists(path string) (bool, error) {
+ _, err := os.Stat(path)
+ if err == nil {
+ return true, nil
+ }
+ if os.IsNotExist(err) {
+ return false, nil
+ }
+ return false, err
+}
+
+//@function: CreateDir
+//@description: 批量创建文件夹
+//@param: dirs ...string
+//@return: err error
+
+func CreateDir(dirs ...string) (err error) {
+ for _, v := range dirs {
+ exist, err := PathExists(v)
+ if err != nil {
+ return err
+ }
+ if !exist {
+ global.MG_LOG.Debug("create directory" + v)
+ err = os.MkdirAll(v, os.ModePerm)
+ if err != nil {
+ global.MG_LOG.Error("create directory"+v, zap.Any(" error:", err))
+ }
+ }
+ }
+ return err
+}
diff --git a/utils/email.go b/utils/email.go
new file mode 100644
index 0000000..b0df43a
--- /dev/null
+++ b/utils/email.go
@@ -0,0 +1,78 @@
+package utils
+
+import (
+ "crypto/tls"
+ "fmt"
+ "net/smtp"
+ "strings"
+
+ "pure/global"
+
+ "github.com/jordan-wright/email"
+)
+
+//@function: Email
+//@description: Email发送方法
+//@param: subject string, body string
+//@return: error
+
+func Email(subject string, body string) error {
+ to := strings.Split(global.MG_CONFIG.Email.To, ",")
+ return send(to, subject, body)
+}
+
+//@function: ErrorToEmail
+//@description: 给email中间件错误发送邮件到指定邮箱
+//@param: subject string, body string
+//@return: error
+
+func ErrorToEmail(subject string, body string) error {
+ to := strings.Split(global.MG_CONFIG.Email.To, ",")
+ if to[len(to)-1] == "" { // 判断切片的最后一个元素是否为空,为空则移除
+ to = to[:len(to)-1]
+ }
+ return send(to, subject, body)
+}
+
+//@function: EmailTest
+//@description: Email测试方法
+//@param: subject string, body string
+//@return: error
+
+func EmailTest(subject string, body string) error {
+ to := []string{global.MG_CONFIG.Email.From}
+ return send(to, subject, body)
+}
+
+//@function: send
+//@description: Email发送方法
+//@param: subject string, body string
+//@return: error
+
+func send(to []string, subject string, body string) error {
+ from := global.MG_CONFIG.Email.From
+ nickname := global.MG_CONFIG.Email.Nickname
+ secret := global.MG_CONFIG.Email.Secret
+ host := global.MG_CONFIG.Email.Host
+ port := global.MG_CONFIG.Email.Port
+ isSSL := global.MG_CONFIG.Email.IsSSL
+
+ auth := smtp.PlainAuth("", from, secret, host)
+ e := email.NewEmail()
+ if nickname != "" {
+ e.From = fmt.Sprintf("%s <%s>", nickname, from)
+ } else {
+ e.From = from
+ }
+ e.To = to
+ e.Subject = subject
+ e.HTML = []byte(body)
+ var err error
+ hostAddr := fmt.Sprintf("%s:%d", host, port)
+ if isSSL {
+ err = e.SendWithTLS(hostAddr, auth, &tls.Config{ServerName: host})
+ } else {
+ err = e.Send(hostAddr, auth)
+ }
+ return err
+}
diff --git a/utils/file_operations.go b/utils/file_operations.go
new file mode 100644
index 0000000..9b217f0
--- /dev/null
+++ b/utils/file_operations.go
@@ -0,0 +1,63 @@
+package utils
+
+import (
+ "os"
+ "path/filepath"
+ "reflect"
+ "strings"
+)
+
+//@function: FileMove
+//@description: 文件移动供外部调用
+//@param: src string, dst string(src: 源位置,绝对路径or相对路径, dst: 目标位置,绝对路径or相对路径,必须为文件夹)
+//@return: err error
+
+func FileMove(src string, dst string) (err error) {
+ if dst == "" {
+ return nil
+ }
+ src, err = filepath.Abs(src)
+ if err != nil {
+ return err
+ }
+ dst, err = filepath.Abs(dst)
+ if err != nil {
+ return err
+ }
+ var revoke = false
+ dir := filepath.Dir(dst)
+Redirect:
+ _, err = os.Stat(dir)
+ if err != nil {
+ err = os.MkdirAll(dir, 0755)
+ if err != nil {
+ return err
+ }
+ if !revoke {
+ revoke = true
+ goto Redirect
+ }
+ }
+ return os.Rename(src, dst)
+}
+
+//@function: TrimSpace
+//@description: 去除结构体空格
+//@param: target interface (target: 目标结构体,传入必须是指针类型)
+//@return: null
+
+func TrimSpace(target interface{}) {
+ t := reflect.TypeOf(target)
+ if t.Kind() != reflect.Ptr {
+ return
+ }
+ t = t.Elem()
+ v := reflect.ValueOf(target).Elem()
+ for i := 0; i < t.NumField(); i++ {
+ switch v.Field(i).Kind() {
+ case reflect.String:
+ v.Field(i).SetString(strings.TrimSpace(v.Field(i).String()))
+ }
+ }
+ return
+}
diff --git a/utils/float.go b/utils/float.go
new file mode 100644
index 0000000..57e0939
--- /dev/null
+++ b/utils/float.go
@@ -0,0 +1,28 @@
+package utils
+
+import (
+ "fmt"
+ "math"
+ "strconv"
+)
+
+func FormatFloat(num float64, decimal int) (float64, error) {
+ // 默认乘1
+ d := float64(1)
+ if decimal > 0 {
+ // 10的N次方
+ d = math.Pow10(decimal)
+ }
+ // math.trunc作用就是返回浮点数的整数部分
+ // 再除回去,小数点后无效的0也就不存在了
+ res := strconv.FormatFloat(math.Trunc(num*d)/d, 'f', -1, 64)
+ return strconv.ParseFloat(res, 64)
+}
+
+func FormatFloatToString(num float64) string {
+ float, err := FormatFloat(num, 2)
+ if err != nil {
+ return "-"
+ }
+ return fmt.Sprintf("%v", float)
+}
diff --git a/utils/fmt_plus.go b/utils/fmt_plus.go
new file mode 100644
index 0000000..e9258cc
--- /dev/null
+++ b/utils/fmt_plus.go
@@ -0,0 +1,36 @@
+package utils
+
+import (
+ "fmt"
+ "reflect"
+ "strings"
+)
+
+//@function: StructToMap
+//@description: 利用反射将结构体转化为map
+//@param: obj interface{}
+//@return: map[string]interface{}
+
+func StructToMap(obj interface{}) map[string]interface{} {
+ obj1 := reflect.TypeOf(obj)
+ obj2 := reflect.ValueOf(obj)
+
+ var data = make(map[string]interface{})
+ for i := 0; i < obj1.NumField(); i++ {
+ if obj1.Field(i).Tag.Get("mapstructure") != "" {
+ data[obj1.Field(i).Tag.Get("mapstructure")] = obj2.Field(i).Interface()
+ } else {
+ data[obj1.Field(i).Name] = obj2.Field(i).Interface()
+ }
+ }
+ return data
+}
+
+//@function: ArrayToString
+//@description: 将数组格式化为字符串
+//@param: array []interface{}
+//@return: string
+
+func ArrayToString(array []interface{}) string {
+ return strings.Replace(strings.Trim(fmt.Sprint(array), "[]"), " ", ",", -1)
+}
diff --git a/utils/injectionCode.go b/utils/injectionCode.go
new file mode 100644
index 0000000..aabacdd
--- /dev/null
+++ b/utils/injectionCode.go
@@ -0,0 +1,142 @@
+package utils
+
+import (
+ "fmt"
+ "go/ast"
+ "go/parser"
+ "go/token"
+ "io/ioutil"
+ "strings"
+)
+
+//@function: AutoInjectionCode
+//@description: 向文件中固定注释位置写入代码
+//@param: filepath string, funcName string, codeData string
+//@return: error
+
+func AutoInjectionCode(filepath string, funcName string, codeData string) error {
+ startComment := "Code generated by pure Begin; DO NOT EDIT."
+ endComment := "Code generated by pure End; DO NOT EDIT."
+ srcData, err := ioutil.ReadFile(filepath)
+ if err != nil {
+ return err
+ }
+ srcDataLen := len(srcData)
+ fset := token.NewFileSet()
+ fparser, err := parser.ParseFile(fset, filepath, srcData, parser.ParseComments)
+ if err != nil {
+ return err
+ }
+ codeData = strings.TrimSpace(codeData)
+ var codeStartPos = -1
+ var codeEndPos = srcDataLen
+ var expectedFunction *ast.FuncDecl
+
+ var startCommentPos = -1
+ var endCommentPos = srcDataLen
+
+ // 如果指定了函数名,先寻找对应函数
+ if funcName != "" {
+ for _, decl := range fparser.Decls {
+ if funDecl, ok := decl.(*ast.FuncDecl); ok && funDecl.Name.Name == funcName {
+ expectedFunction = funDecl
+ codeStartPos = int(funDecl.Body.Lbrace)
+ codeEndPos = int(funDecl.Body.Rbrace)
+ break
+ }
+ }
+ }
+
+ // 遍历所有注释
+ for _, comment := range fparser.Comments {
+ if int(comment.Pos()) > codeStartPos && int(comment.End()) <= codeEndPos {
+ if startComment != "" && strings.Contains(comment.Text(), startComment) {
+ startCommentPos = int(comment.Pos()) // Note: Pos is the second '/'
+ }
+ if endComment != "" && strings.Contains(comment.Text(), endComment) {
+ endCommentPos = int(comment.Pos()) // Note: Pos is the second '/'
+ }
+ }
+ }
+
+ if endCommentPos == srcDataLen {
+ return fmt.Errorf("comment:%s not found", endComment)
+ }
+
+ // 在指定函数名,且函数中startComment和endComment都存在时,进行区间查重
+ if (codeStartPos != -1 && codeEndPos <= srcDataLen) && (startCommentPos != -1 && endCommentPos != srcDataLen) && expectedFunction != nil {
+ if exist := checkExist(&srcData, startCommentPos, endCommentPos, expectedFunction.Body, codeData); exist {
+ fmt.Printf("文件 %s 待插入数据 %s 已存在\n", filepath, codeData)
+ return nil // 这里不需要返回错误?
+ }
+ }
+
+ // 两行注释中间没有换行时,会被认为是一条Comment
+ if startCommentPos == endCommentPos {
+ endCommentPos = startCommentPos + strings.Index(string(srcData[startCommentPos:]), endComment)
+ for srcData[endCommentPos] != '/' {
+ endCommentPos--
+ }
+ }
+
+ // 记录"//"之前的空字符,保持写入后的格式一致
+ tmpSpace := make([]byte, 0, 10)
+ for tmp := endCommentPos - 2; tmp >= 0; tmp-- {
+ if srcData[tmp] != '\n' {
+ tmpSpace = append(tmpSpace, srcData[tmp])
+ } else {
+ break
+ }
+ }
+
+ reverseSpace := make([]byte, 0, len(tmpSpace))
+ for index := len(tmpSpace) - 1; index >= 0; index-- {
+ reverseSpace = append(reverseSpace, tmpSpace[index])
+ }
+
+ // 插入数据
+ indexPos := endCommentPos - 1
+ insertData := []byte(append([]byte(codeData+"\n"), reverseSpace...))
+
+ remainData := append([]byte{}, srcData[indexPos:]...)
+ srcData = append(append(srcData[:indexPos], insertData...), remainData...)
+
+ // 写回数据
+ return ioutil.WriteFile(filepath, srcData, 0600)
+}
+
+func checkExist(srcData *[]byte, startPos int, endPos int, blockStmt *ast.BlockStmt, target string) bool {
+ for _, list := range blockStmt.List {
+ switch stmt := list.(type) {
+ case *ast.ExprStmt:
+ if callExpr, ok := stmt.X.(*ast.CallExpr); ok &&
+ int(callExpr.Pos()) > startPos && int(callExpr.End()) < endPos {
+ text := string((*srcData)[int(callExpr.Pos()-1):int(callExpr.End())])
+ key := strings.TrimSpace(text)
+ if key == target {
+ return true
+ }
+ }
+ case *ast.BlockStmt:
+ if checkExist(srcData, startPos, endPos, stmt, target) {
+ return true
+ }
+ case *ast.AssignStmt:
+ // 为 model 中的代码进行检查
+ if len(stmt.Rhs) > 0 {
+ if callExpr, ok := stmt.Rhs[0].(*ast.CallExpr); ok {
+ for _, arg := range callExpr.Args {
+ if int(arg.Pos()) > startPos && int(arg.End()) < endPos {
+ text := string((*srcData)[int(arg.Pos()-1):int(arg.End())])
+ key := strings.TrimSpace(text)
+ if key == target {
+ return true
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return false
+}
diff --git a/utils/international.go b/utils/international.go
new file mode 100644
index 0000000..83285d6
--- /dev/null
+++ b/utils/international.go
@@ -0,0 +1,32 @@
+package utils
+
+import (
+ "pure/global"
+ "pure/model"
+ "time"
+)
+
+func InterTranslate(original, form, to string) string {
+ data := global.MG_Language.(map[string]model.Internationalization)
+ if data[original].En != "" {
+ return data[original].En
+ }
+ go func() {
+ var (
+ data model.Internationalization
+ )
+ ok, err := global.MG_REDIS.SetNX("internationalization-"+original, "used", 10*time.Second).Result()
+ if ok && err == nil {
+ global.MG_DB.Model(&model.Internationalization{}).Where("ch=?", original).Find(&data)
+ if data.ID == 0 {
+ data.Ch = original
+ global.MG_DB.Create(&data)
+ } else {
+ newData := global.MG_Language.(map[string]model.Internationalization)
+ newData[original] = data
+ global.MG_Language = newData
+ }
+ }
+ }()
+ return ""
+}
diff --git a/utils/jpush/model.go b/utils/jpush/model.go
new file mode 100644
index 0000000..21b0b6f
--- /dev/null
+++ b/utils/jpush/model.go
@@ -0,0 +1,23 @@
+package jpush
+
+type notificationBody struct {
+}
+
+type cidList struct {
+ CidList []string `json:"cidlist"`
+}
+
+type tags struct {
+ Tags []string `json:"tags"`
+}
+
+type Error struct {
+ Code int `json:"code"`
+ Message string `json:"message"`
+}
+
+type PushResult struct {
+ Sendno string `json:"sendno"`
+ MsgId string `json:"msg_id"`
+ Error Error `json:"error"`
+}
diff --git a/utils/jpush/push.go b/utils/jpush/push.go
new file mode 100644
index 0000000..4951945
--- /dev/null
+++ b/utils/jpush/push.go
@@ -0,0 +1,202 @@
+package jpush
+
+import (
+ "encoding/base64"
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "net/http"
+ "pure/global"
+ "strings"
+)
+
+func createAuthorization(req *http.Request) *http.Request {
+ var (
+ str string
+ )
+ str = global.MG_CONFIG.JPush.Appkey + ":" + global.MG_CONFIG.JPush.Secret
+ req.Header.Add("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(str)))
+ return req
+}
+
+//JiGuangPush ...
+func JiGuangPush(reqParams map[string]interface{}) (result PushResult, err error) {
+ var (
+ client *http.Client
+ req *http.Request
+ params []byte
+ cid string
+ resBody []byte
+ options map[string]interface{}
+ )
+ options = make(map[string]interface{})
+ options["time_to_live"] = 0
+ if global.MG_CONFIG.System.Env == "mater" {
+ options["apns_production"] = true
+ } else {
+ options["apns_production"] = false
+ }
+ reqParams["options"] = options
+ cid, err = jiGuangCid()
+ if err != nil {
+ return
+ }
+ reqParams["cid"] = cid
+ params, err = json.Marshal(reqParams)
+ if err != nil {
+ return
+ }
+ client = &http.Client{}
+ req, err = http.NewRequest(http.MethodPost, "https://api.jpush.cn/v3/push", strings.NewReader(string(params)))
+ if err != nil {
+ return
+ }
+ req.Header.Add("Content-Type", "application/json")
+ createAuthorization(req)
+ resp, err := client.Do(req)
+ if err != nil {
+ return
+ }
+ defer resp.Body.Close()
+ resBody, err = ioutil.ReadAll(resp.Body)
+ if err != nil {
+ return
+ }
+ //fmt.Println(string(resBody))
+ global.MG_LOG.Info(string(resBody))
+ err = json.Unmarshal(resBody, &result)
+ if err != nil {
+ return
+ }
+ return
+}
+
+func jiGuangCid() (string, error) {
+ var (
+ err error
+ res string
+ client *http.Client
+ req *http.Request
+ resp *http.Response
+ resBody []byte
+ list cidList
+ )
+ client = &http.Client{}
+ req, err = http.NewRequest(http.MethodGet, "https://api.jpush.cn/v3/push/cid?count=10&type=push", nil)
+ if err != nil {
+ return res, err
+ }
+ req.Header.Add("Content-Type", "application/json")
+ createAuthorization(req)
+ resp, err = client.Do(req)
+ if err != nil {
+ return res, err
+ }
+ defer resp.Body.Close()
+ resBody, err = ioutil.ReadAll(resp.Body)
+ if err != nil {
+ return res, err
+ }
+ err = json.Unmarshal(resBody, &list)
+ if err != nil || len(list.CidList) == 0 {
+ return "", err
+ }
+ return list.CidList[0], err
+}
+
+func GetTagsList() (string, error) {
+ var (
+ err error
+ res string
+ client *http.Client
+ req *http.Request
+ resp *http.Response
+ resBody []byte
+ list tags
+ )
+ client = &http.Client{}
+ req, err = http.NewRequest(http.MethodGet, "https://device.jpush.cn/v3/tags/", nil)
+ if err != nil {
+ return res, err
+ }
+ req.Header.Add("Content-Type", "application/json")
+ createAuthorization(req)
+ resp, err = client.Do(req)
+ if err != nil {
+ return res, err
+ }
+ defer resp.Body.Close()
+ resBody, err = ioutil.ReadAll(resp.Body)
+ if err != nil {
+ return res, err
+ }
+ fmt.Println(string(resBody))
+ err = json.Unmarshal(resBody, &list)
+ if err != nil || len(list.Tags) == 0 {
+ return "", err
+ }
+ return list.Tags[0], err
+}
+
+func UpdateTags(tagValue string, registration map[string][]string) {
+ var (
+ err error
+ client *http.Client
+ req *http.Request
+ params []byte
+ reqParams map[string]interface{}
+ resBody []byte
+ )
+ reqParams = make(map[string]interface{})
+ reqParams["registration_ids"] = registration
+ params, err = json.Marshal(reqParams)
+ if err != nil {
+ return
+ }
+ client = &http.Client{}
+ req, err = http.NewRequest(http.MethodPost, "https://device.jpush.cn/v3/tags/"+tagValue, strings.NewReader(string(params)))
+ if err != nil {
+ return
+ }
+ req.Header.Add("Content-Type", "application/json")
+ createAuthorization(req)
+ resp, err := client.Do(req)
+ if err != nil {
+ return
+ }
+ defer resp.Body.Close()
+ resBody, err = ioutil.ReadAll(resp.Body)
+ if err != nil {
+ return
+ }
+ fmt.Println(string(resBody))
+ return
+}
+
+func GetRegistrationInfo(registration string) {
+ var (
+ err error
+ client *http.Client
+ req *http.Request
+ resp *http.Response
+ resBody []byte
+ )
+ client = &http.Client{}
+ req, err = http.NewRequest(http.MethodGet, "https://device.jpush.cn/v3/tags/", nil)
+ if err != nil {
+ return
+ }
+ req.Header.Add("Content-Type", "application/json")
+ createAuthorization(req)
+ resp, err = client.Do(req)
+ if err != nil {
+ return
+ }
+ defer resp.Body.Close()
+ resBody, err = ioutil.ReadAll(resp.Body)
+ if err != nil {
+ return
+ }
+ fmt.Println(string(resBody))
+ return
+}
diff --git a/utils/md5.go b/utils/md5.go
new file mode 100644
index 0000000..e359dc9
--- /dev/null
+++ b/utils/md5.go
@@ -0,0 +1,17 @@
+package utils
+
+import (
+ "crypto/md5"
+ "encoding/hex"
+)
+
+//@function: MD5V
+//@description: md5加密
+//@param: str []byte
+//@return: string
+
+func MD5V(str []byte) string {
+ h := md5.New()
+ h.Write(str)
+ return hex.EncodeToString(h.Sum(nil))
+}
diff --git a/utils/qiniu/model.go b/utils/qiniu/model.go
new file mode 100644
index 0000000..d5fe9f2
--- /dev/null
+++ b/utils/qiniu/model.go
@@ -0,0 +1,83 @@
+package qiniu
+
+type VideoStreams struct {
+ Index int `json:"index"`
+ CodecName string `json:"codec_name"`
+ CodecLongName string `json:"codec_long_name"`
+ Profile string `json:"profile"`
+ CodecType string `json:"codec_type"`
+ CodecTimeBase string `json:"codec_time_base"`
+ CodecTagString string `json:"codec_tag_string"`
+ CodecTag string `json:"codec_tag"`
+ Width int `json:"width,omitempty"`
+ Height int `json:"height,omitempty"`
+ CodedWidth int `json:"coded_width,omitempty"`
+ CodedHeight int `json:"coded_height,omitempty"`
+ HasBFrames int `json:"has_b_frames,omitempty"`
+ SampleAspectRatio string `json:"sample_aspect_ratio,omitempty"`
+ DisplayAspectRatio string `json:"display_aspect_ratio,omitempty"`
+ PixFmt string `json:"pix_fmt,omitempty"`
+ Level int `json:"level,omitempty"`
+ ChromaLocation string `json:"chroma_location,omitempty"`
+ Refs int `json:"refs,omitempty"`
+ IsAvc string `json:"is_avc,omitempty"`
+ NalLengthSize string `json:"nal_length_size,omitempty"`
+ RFrameRate string `json:"r_frame_rate"`
+ AvgFrameRate string `json:"avg_frame_rate"`
+ TimeBase string `json:"time_base"`
+ StartPts int `json:"start_pts"`
+ StartTime string `json:"start_time"`
+ DurationTs int `json:"duration_ts"`
+ Duration string `json:"duration"`
+ BitRate string `json:"bit_rate"`
+ BitsPerRawSample string `json:"bits_per_raw_sample,omitempty"`
+ NbFrames string `json:"nb_frames"`
+ Disposition struct {
+ Default int `json:"default"`
+ Dub int `json:"dub"`
+ Original int `json:"original"`
+ Comment int `json:"comment"`
+ Lyrics int `json:"lyrics"`
+ Karaoke int `json:"karaoke"`
+ Forced int `json:"forced"`
+ HearingImpaired int `json:"hearing_impaired"`
+ VisualImpaired int `json:"visual_impaired"`
+ CleanEffects int `json:"clean_effects"`
+ AttachedPic int `json:"attached_pic"`
+ TimedThumbnails int `json:"timed_thumbnails"`
+ } `json:"disposition"`
+ Tags struct {
+ Language string `json:"language"`
+ HandlerName string `json:"handler_name"`
+ } `json:"tags"`
+ SampleFmt string `json:"sample_fmt,omitempty"`
+ SampleRate string `json:"sample_rate,omitempty"`
+ Channels int `json:"channels,omitempty"`
+ ChannelLayout string `json:"channel_layout,omitempty"`
+ BitsPerSample int `json:"bits_per_sample,omitempty"`
+ MaxBitRate string `json:"max_bit_rate,omitempty"`
+}
+
+type VideoFormat struct {
+ NbStreams int `json:"nb_streams"`
+ NbPrograms int `json:"nb_programs"`
+ FormatName string `json:"format_name"`
+ FormatLongName string `json:"format_long_name"`
+ StartTime string `json:"start_time"`
+ Duration string `json:"duration"`
+ Size string `json:"size"`
+ BitRate string `json:"bit_rate"`
+ ProbeScore int `json:"probe_score"`
+ Tags struct {
+ MajorBrand string `json:"major_brand"`
+ MinorVersion string `json:"minor_version"`
+ CompatibleBrands string `json:"compatible_brands"`
+ Encoder string `json:"encoder"`
+ Description string `json:"description"`
+ } `json:"tags"`
+}
+
+type VideoInfo struct {
+ Streams []VideoStreams `json:"streams"`
+ Format VideoFormat `json:"format"`
+}
diff --git a/utils/qiniu/video.go b/utils/qiniu/video.go
new file mode 100644
index 0000000..0bb7af2
--- /dev/null
+++ b/utils/qiniu/video.go
@@ -0,0 +1,84 @@
+package qiniu
+
+import (
+ "crypto/hmac"
+ "crypto/sha1"
+ "encoding/base64"
+ "encoding/json"
+ "io/ioutil"
+ "math"
+ "net/http"
+ "pure/global"
+ "strconv"
+
+ "github.com/pili-engineering/pili-sdk-go.v2/pili"
+)
+
+// 计算token并加入Header
+func createAuthorization(req *http.Request, reqBody []byte) *http.Request {
+ var (
+ str string
+ hashed []byte
+ )
+
+ str = req.Method + " " + req.URL.Path
+ if req.URL.RawQuery != "" {
+ str += "?" + req.URL.RawQuery
+ }
+ str += "\nHost: " + req.Host
+ if contentType := req.Header.Get("Content-Type"); contentType != "" {
+ str += "\nContent-Type: " + contentType
+ }
+ str += "\n\n"
+ if len(reqBody) != 0 {
+ str += string(reqBody)
+ }
+ key := []byte(global.MG_CONFIG.Qiniu.SecretKey)
+ mac := hmac.New(sha1.New, key)
+ mac.Write([]byte(str))
+ hashed = mac.Sum(nil)
+ req.Header.Add("Authorization", "Qiniu "+global.MG_CONFIG.Qiniu.AccessKey+":"+base64.URLEncoding.EncodeToString(hashed))
+ return req
+}
+
+func getVideoInfo(url string) (result VideoInfo, err error) {
+ resp, err := http.Get(url + "?avinfo")
+ if err != nil {
+ return
+ }
+ defer resp.Body.Close()
+ resBody, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ return
+ }
+ //fmt.Println(string(resBody))
+ global.MG_LOG.Info(string(resBody))
+ err = json.Unmarshal(resBody, &result)
+ return
+}
+
+func GetVideoLen(url string) int {
+ info, err := getVideoInfo(url)
+ if err != nil {
+ return 0
+ }
+ f1, err := strconv.ParseFloat(info.Format.Duration, 64)
+ if err != nil {
+ return 0
+ }
+ s1 := strconv.FormatFloat(math.Floor(f1), 'f', -1, 64)
+ i, _ := strconv.Atoi(s1)
+ return i
+}
+
+func ReturnUrl2(key, zone, domain string, start, end int64) (string, error) {
+ mac := &pili.MAC{AccessKey: global.MG_CONFIG.Qiniu.AccessKey, SecretKey: []byte(global.MG_CONFIG.Qiniu.SecretKey)}
+ client := pili.New(mac, nil)
+ hub := client.Hub(zone)
+ stream := hub.Stream(key)
+ fName, err := stream.Save(start, end)
+ if err != nil {
+ return "", err
+ }
+ return "http://" + domain + "/" + fName, nil
+}
diff --git a/utils/redis.go b/utils/redis.go
new file mode 100644
index 0000000..4c97ac4
--- /dev/null
+++ b/utils/redis.go
@@ -0,0 +1,321 @@
+package utils
+
+import (
+ "fmt"
+ "pure/global"
+
+ "time"
+
+ "github.com/go-redis/redis"
+)
+
+// RedisGet ...
+func RedisGet(key string) string {
+ result, err := global.MG_REDIS.Get(key).Result()
+ if err != nil {
+ return ""
+ }
+ return result
+}
+
+func RedisSet(key string, value interface{}, expiration time.Duration) string {
+ result, err := global.MG_REDIS.Set(key, value, expiration).Result()
+ if err != nil {
+ return ""
+ }
+ return result
+}
+
+func RedisDel(key ...string) (int64, error) {
+ result, err := global.MG_REDIS.Del(key...).Result()
+ if err != nil {
+ return -1, err
+ }
+ return result, err
+}
+
+func RedisLLen(key string) (int64, error) {
+ result, err := global.MG_REDIS.LLen(key).Result()
+ if err != nil {
+ return -1, err
+ }
+ return result, err
+}
+
+// RedisHashSet 向key的hash中添加元素field的值
+func RedisHashSet(key, field string, data interface{}) error {
+ err := global.MG_REDIS.HSet(key, field, data).Err()
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+// RedisBatchHashSet 批量向key的hash添加对应元素field的值
+func RedisBatchHashSet(key string, fields map[string]interface{}) (error, string) {
+ val, err := global.MG_REDIS.HMSet(key, fields).Result()
+ if err != nil {
+ return err, ""
+ }
+ return nil, val
+}
+
+func RedisHDel(client *redis.Client, key string, fields ...string) (int64, string) {
+ result, err := client.HDel(key, fields...).Result()
+ if err != nil {
+ return 0, ""
+ }
+ return result, err.Error()
+}
+
+func RedisHSet(key, field string, value interface{}) (error, bool) {
+ val, err := global.MG_REDIS.HSet(key, field, value).Result()
+ if err != nil {
+ return err, false
+ }
+ return nil, val
+}
+
+func RedisSetNX(key string, value interface{}, expiration time.Duration) (error, bool) {
+ val, err := global.MG_REDIS.SetNX(key, value, expiration).Result()
+ if err != nil {
+ return err, false
+ }
+ return nil, val
+}
+
+// RedisHashGet 通过key获取hash的元素值
+func RedisHashGet(key, field string) string {
+ val, err := global.MG_REDIS.HGet(key, field).Result()
+ if err != nil {
+ return ""
+ }
+ return val
+}
+
+func RedisHashMGet(key string, fields ...string) []interface{} {
+ val, err := global.MG_REDIS.HMGet(key, fields...).Result()
+ if err != nil {
+ return nil
+ }
+ return val
+}
+
+//HGetAll
+func RedisHashGetAll(key string) map[string]string {
+ val, err := global.MG_REDIS.HGetAll(key).Result()
+ if err != nil {
+ return nil
+ }
+ return val
+}
+
+// RedisBatchHashGet 批量获取key的hash中对应多元素值
+func RedisBatchHashGet(key string, fields ...string) map[string]interface{} {
+ resMap := make(map[string]interface{})
+ for _, field := range fields {
+ val, err := global.MG_REDIS.HGet(key, fmt.Sprintf("%s", field)).Result()
+ if err == nil && val != "" {
+ resMap[field] = val
+ }
+ }
+ return resMap
+}
+
+func RedisLPush(key string, values ...interface{}) (int64, error) {
+ result, err := global.MG_REDIS.LPush(key, values...).Result()
+ if err != nil {
+ return 0, err
+ }
+ return result, nil
+}
+
+func RedisLPop(key string) (error, string) {
+ result, err := global.MG_REDIS.LPop(key).Result()
+ if err != nil {
+ return err, ""
+ }
+ return err, result
+}
+
+// RedisSAdd 无序集合添加
+func RedisSAdd(key string, values ...interface{}) (int64, error) {
+ result, err := global.MG_REDIS.SAdd(key, values...).Result()
+ if err != nil {
+ return 0, err
+ }
+ return result, nil
+}
+
+// RedisSMembers 从无序集合中获取数据
+func RedisSMembers(key string) ([]string, error) {
+ val, err := global.MG_REDIS.SMembers(key).Result()
+ if err != nil {
+ return nil, err
+ }
+ return val, nil
+}
+
+// RedisZAdd 有序集合添加
+func RedisZAdd(key string, values map[float64]interface{}) (int64, error) {
+ var members []redis.Z
+ for scale, value := range values {
+ members = append(members, redis.Z{
+ Score: scale,
+ Member: value,
+ })
+ }
+ result, err := global.MG_REDIS.ZAdd(key, members...).Result()
+ if err != nil {
+ return 0, err
+ }
+ return result, nil
+}
+
+func RedisZCard(key string) (int64, error) {
+ result, err := global.MG_REDIS.ZCard(key).Result()
+ if err != nil {
+ return 0, err
+ }
+ return result, nil
+}
+
+func RedisZCount(key string, min, max string) (int64, error) {
+ result, err := global.MG_REDIS.ZCount(key, min, max).Result()
+ if err != nil {
+ return 0, err
+ }
+ return result, nil
+}
+
+func RedisZRange(key string, start, stop int64, sort string) ([]interface{}, error) {
+ var val = make([]interface{}, 0)
+ if sort == "asc" { //scale 正序
+ result, err := global.MG_REDIS.ZRangeWithScores(key, start, stop).Result()
+ if err != nil {
+ return val, err
+ }
+ for _, z := range result {
+ val = append(val, z.Member)
+ }
+ } else { //scale 倒序
+ result, err := global.MG_REDIS.ZRevRange(key, start, stop).Result()
+ if err != nil {
+ return val, err
+ }
+ for _, z := range result {
+ val = append(val, z)
+ }
+ return val, nil
+ }
+
+ return val, nil
+}
+
+// RedisIncr 获取自增唯一ID
+func RedisIncr(key string) int {
+ val, err := global.MG_REDIS.Incr(key).Result()
+ if err != nil {
+ }
+ return int(val)
+}
+
+// RedisSetAdd 添加集合数据
+func RedisSetAdd(key, val string) {
+ global.MG_REDIS.SAdd(key, val)
+}
+
+func RedisRename(key, newKey string) (string, error) {
+ result, err := global.MG_REDIS.Rename(key, newKey).Result()
+ if err != nil {
+ return "", err
+ }
+ return result, nil
+}
+
+func RedisHashGet1(client *redis.Client, key, field string) string {
+ val, err := client.HGet(key, field).Result()
+ if err != nil {
+ return ""
+ }
+ return val
+}
+
+func RedisDel1(client *redis.Client, key ...string) (int64, error) {
+ result, err := client.Del(key...).Result()
+ if err != nil {
+ return -1, err
+ }
+ return result, err
+}
+
+func RedisBatchHashSet1(client *redis.Client, key string, fields map[string]interface{}) (error, string) {
+ val, err := client.HMSet(key, fields).Result()
+ if err != nil {
+ return err, ""
+ }
+ return nil, val
+}
+
+func RedisZAdd1(client *redis.Client, key string, values map[float64]interface{}) (int64, error) {
+ var members []redis.Z
+ for scale, value := range values {
+ members = append(members, redis.Z{
+ Score: scale,
+ Member: value,
+ })
+ }
+ result, err := client.ZAdd(key, members...).Result()
+ if err != nil {
+ return 0, err
+ }
+ return result, nil
+}
+
+func RedisZRange1(client *redis.Client, key string, start, stop int64, sort string) ([]interface{}, error) {
+ var val = make([]interface{}, 0)
+ if sort == "asc" { //scale 正序
+ result, err := client.ZRangeWithScores(key, start, stop).Result()
+ if err != nil {
+ return val, err
+ }
+ for _, z := range result {
+ val = append(val, z.Member)
+ }
+ } else { //scale 倒序
+ result, err := client.ZRevRange(key, start, stop).Result()
+ if err != nil {
+ return val, err
+ }
+ for _, z := range result {
+ val = append(val, z)
+ }
+ return val, nil
+ }
+
+ return val, nil
+}
+
+func RedisZRemRangeByRank(client *redis.Client, key string, start, stop int64) error {
+ _, err := client.ZRemRangeByRank(key, start, stop).Result()
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func RedisZCard1(client *redis.Client, key string) (int64, error) {
+ result, err := client.ZCard(key).Result()
+ if err != nil {
+ return 0, err
+ }
+ return result, nil
+}
+
+func RedisScan(client *redis.Client) ([]string, error) {
+ result, _, err := client.Scan(0, "", 0).Result()
+ if err != nil {
+ return nil, err
+ }
+ return result, nil
+}
diff --git a/utils/redis_store.go b/utils/redis_store.go
new file mode 100644
index 0000000..dfcd419
--- /dev/null
+++ b/utils/redis_store.go
@@ -0,0 +1,44 @@
+package utils
+
+import (
+ "fmt"
+ "pure/global"
+ "strings"
+ "time"
+)
+
+const CAPTCHA = "captcha:"
+
+type RedisStore struct{}
+
+func (e RedisStore) Set(id, value string) {
+ key := CAPTCHA + id
+ value = strings.ToLower(value)
+ err := global.MG_REDIS.Set(key, value, 2*time.Minute).Err()
+ if err != nil {
+ global.MG_LOG.Info(err.Error())
+ }
+}
+
+func (e RedisStore) Get(id string, clear bool) string {
+ key := CAPTCHA + id
+ val, err := global.MG_REDIS.Get(key).Result()
+ if err != nil {
+ fmt.Println(err)
+ return ""
+ }
+ if clear {
+ err := global.MG_REDIS.Del(key).Err()
+ if err != nil {
+ fmt.Println(err)
+ return ""
+ }
+ }
+ return val
+}
+
+func (e RedisStore) Verify(id, answer string, clear bool) bool {
+ v := RedisStore{}.Get(id, clear)
+ //fmt.Println("key:"+id+";value:"+v+";answer:"+answer)
+ return v == answer
+}
diff --git a/utils/reload.go b/utils/reload.go
new file mode 100644
index 0000000..de5499b
--- /dev/null
+++ b/utils/reload.go
@@ -0,0 +1,18 @@
+package utils
+
+import (
+ "errors"
+ "os"
+ "os/exec"
+ "runtime"
+ "strconv"
+)
+
+func Reload() error {
+ if runtime.GOOS == "windows" {
+ return errors.New("系统不支持")
+ }
+ pid := os.Getpid()
+ cmd := exec.Command("kill", "-1", strconv.Itoa(pid))
+ return cmd.Run()
+}
diff --git a/utils/rotatelogs_unix.go b/utils/rotatelogs_unix.go
new file mode 100644
index 0000000..6b1fe53
--- /dev/null
+++ b/utils/rotatelogs_unix.go
@@ -0,0 +1,30 @@
+// +build !windows
+
+package utils
+
+import (
+ "os"
+ "path"
+ "pure/global"
+ "time"
+
+ zaprotatelogs "github.com/lestrrat-go/file-rotatelogs"
+ "go.uber.org/zap/zapcore"
+)
+
+//@function: GetWriteSyncer
+//@description: zap logger中加入file-rotatelogs
+//@return: zapcore.WriteSyncer, error
+
+func GetWriteSyncer() (zapcore.WriteSyncer, error) {
+ fileWriter, err := zaprotatelogs.New(
+ path.Join(global.MG_CONFIG.Zap.Director, "%Y-%m-%d.log"),
+ zaprotatelogs.WithLinkName(global.MG_CONFIG.Zap.LinkName),
+ zaprotatelogs.WithMaxAge(7*24*time.Hour),
+ zaprotatelogs.WithRotationTime(24*time.Hour),
+ )
+ if global.MG_CONFIG.Zap.LogInConsole {
+ return zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(fileWriter)), err
+ }
+ return zapcore.AddSync(fileWriter), err
+}
diff --git a/utils/rotatelogs_windows.go b/utils/rotatelogs_windows.go
new file mode 100644
index 0000000..0c3f70f
--- /dev/null
+++ b/utils/rotatelogs_windows.go
@@ -0,0 +1,26 @@
+package utils
+
+import (
+ zaprotatelogs "github.com/lestrrat-go/file-rotatelogs"
+ "go.uber.org/zap/zapcore"
+ "os"
+ "path"
+ "pure/global"
+ "time"
+)
+
+//@function: GetWriteSyncer
+//@description: zap logger中加入file-rotatelogs
+//@return: zapcore.WriteSyncer, error
+
+func GetWriteSyncer() (zapcore.WriteSyncer, error) {
+ fileWriter, err := zaprotatelogs.New(
+ path.Join(global.MG_CONFIG.Zap.Director, "%Y-%m-%d.log"),
+ zaprotatelogs.WithMaxAge(7*24*time.Hour),
+ zaprotatelogs.WithRotationTime(24*time.Hour),
+ )
+ if global.MG_CONFIG.Zap.LogInConsole {
+ return zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(fileWriter)), err
+ }
+ return zapcore.AddSync(fileWriter), err
+}
diff --git a/utils/sendSms.go b/utils/sendSms.go
new file mode 100644
index 0000000..b47b240
--- /dev/null
+++ b/utils/sendSms.go
@@ -0,0 +1,109 @@
+package utils
+
+import (
+ "context"
+ "errors"
+ "pure/global"
+ "pure/initialize/api"
+)
+
+func SendSms(phone, code string, types int) error {
+ var (
+ reply *api.SendSmsReply
+ err error
+ )
+ ctx := context.Background()
+ reply, err = global.SMS_CLIENT.SendMessage(ctx, &api.SendSmsRequest{
+ Phone: phone,
+ SmsType: int32(types),
+ AreaCode: code,
+ })
+ if err != nil {
+ return err
+ }
+ if reply.Code != 0 {
+ return errors.New(reply.Message)
+ }
+ return nil
+}
+
+func SendEmail(email, types string) (string, error) {
+ var (
+ reply *api.SendEmailReply
+ err error
+ )
+ code := GetInvitation()
+ str := `To authorise your Login request , please use this One Time Password (OTP): ` + code
+ if types == "2" {
+ str = `To authorise your forgot password , please use this One Time Password (OTP): ` + code
+ }
+ body := `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+ Ouction NFT
+ ` + str + `
+
+ Thank you.
+ Ouction Team
+ |
+
+
+ |
+
+
+
+
+
+
+
+ © Ouction NFT
+
+ |
+
+
+ |
+
+
+ |
+
+
+
+
+ `
+ reply, err = global.EMAIL_CLIENT.SendEmail(context.Background(), &api.SendRequest{
+ To: []string{email},
+ Subject: "验证码",
+ Body: body,
+ })
+ if err != nil {
+ return "", err
+ }
+ if reply.Code != 0 {
+ return "", errors.New(reply.Message)
+ }
+ return code, nil
+}
diff --git a/utils/server.go b/utils/server.go
new file mode 100644
index 0000000..8f488fc
--- /dev/null
+++ b/utils/server.go
@@ -0,0 +1,113 @@
+package utils
+
+import (
+ "github.com/shirou/gopsutil/cpu"
+ "github.com/shirou/gopsutil/disk"
+ "github.com/shirou/gopsutil/mem"
+ "runtime"
+ "time"
+)
+
+const (
+ B = 1
+ KB = 1024 * B
+ MB = 1024 * KB
+ GB = 1024 * MB
+)
+
+type Server struct {
+ Os Os `json:"os"`
+ Cpu Cpu `json:"cpu"`
+ Rrm Rrm `json:"ram"`
+ Disk Disk `json:"disk"`
+}
+
+type Os struct {
+ GOOS string `json:"goos"`
+ NumCPU int `json:"numCpu"`
+ Compiler string `json:"compiler"`
+ GoVersion string `json:"goVersion"`
+ NumGoroutine int `json:"numGoroutine"`
+}
+
+type Cpu struct {
+ Cpus []float64 `json:"cpus"`
+ Cores int `json:"cores"`
+}
+
+type Rrm struct {
+ UsedMB int `json:"usedMb"`
+ TotalMB int `json:"totalMb"`
+ UsedPercent int `json:"usedPercent"`
+}
+
+type Disk struct {
+ UsedMB int `json:"usedMb"`
+ UsedGB int `json:"usedGb"`
+ TotalMB int `json:"totalMb"`
+ TotalGB int `json:"totalGb"`
+ UsedPercent int `json:"usedPercent"`
+}
+
+//@function: InitCPU
+//@description: OS信息
+//@return: o Os, err error
+
+func InitOS() (o Os) {
+ o.GOOS = runtime.GOOS
+ o.NumCPU = runtime.NumCPU()
+ o.Compiler = runtime.Compiler
+ o.GoVersion = runtime.Version()
+ o.NumGoroutine = runtime.NumGoroutine()
+ return o
+}
+
+//@function: InitCPU
+//@description: CPU信息
+//@return: c Cpu, err error
+
+func InitCPU() (c Cpu, err error) {
+ if cores, err := cpu.Counts(false); err != nil {
+ return c, err
+ } else {
+ c.Cores = cores
+ }
+ if cpus, err := cpu.Percent(time.Duration(200)*time.Millisecond, true); err != nil {
+ return c, err
+ } else {
+ c.Cpus = cpus
+ }
+ return c, nil
+}
+
+//@function: InitRAM
+//@description: ARM信息
+//@return: r Rrm, err error
+
+func InitRAM() (r Rrm, err error) {
+ if u, err := mem.VirtualMemory(); err != nil {
+ return r, err
+ } else {
+ r.UsedMB = int(u.Used) / MB
+ r.TotalMB = int(u.Total) / MB
+ r.UsedPercent = int(u.UsedPercent)
+ }
+ return r, nil
+}
+
+//@function: InitDisk
+//@description: 硬盘信息
+//@return: d Disk, err error
+
+func InitDisk() (d Disk, err error) {
+ if u, err := disk.Usage("/"); err != nil {
+ return d, err
+ } else {
+ d.UsedMB = int(u.Used) / MB
+ d.UsedGB = int(u.Used) / GB
+ d.TotalMB = int(u.Total) / MB
+ d.TotalGB = int(u.Total) / GB
+ d.UsedPercent = int(u.UsedPercent)
+ }
+ return d, nil
+}
diff --git a/utils/string.go b/utils/string.go
new file mode 100644
index 0000000..1d83c3a
--- /dev/null
+++ b/utils/string.go
@@ -0,0 +1,69 @@
+package utils
+
+import (
+ "math"
+ "math/rand"
+ "strconv"
+ "time"
+)
+
+const (
+ RegPhoneNumber = `^1[3456789]\d{9}$`
+ RegEmailNumber = `^[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}$`
+ RegNumberAndChar = `^\w+$`
+ RegVersionNumber = `^([1-9]\d|[1-9])(.([1-9]\d|\d)){2}$`
+)
+
+func GetInvitation() string {
+ var bs = make([]byte, 6)
+ for i := 0; i < 6; i++ {
+ rand.Seed(time.Now().UnixNano())
+ flag := rand.Intn(2)
+ if flag == 1 {
+ bs[i] = byte(rand.Float64()*10 + 48)
+ } else {
+ bs[i] = byte(rand.Float64()*26 + 65)
+ }
+ }
+ return string(bs)
+}
+
+func GetInvitationLen(length int) string {
+ var bs = make([]byte, length)
+ for i := 0; i < length; i++ {
+ rand.Seed(time.Now().UnixNano())
+ flag := rand.Intn(3)
+ if flag == 1 {
+ bs[i] = byte(rand.Float64()*10 + 48)
+ } else if flag == 0 {
+ bs[i] = byte(rand.Float64()*26 + 65)
+ } else {
+ bs[i] = byte(rand.Float64()*26 + 97)
+ }
+ }
+ return string(bs)
+}
+
+func GetInvitationLowerLen(length int) string {
+ var bs = make([]byte, length)
+ for i := 0; i < length; i++ {
+ rand.Seed(time.Now().UnixNano())
+ flag := rand.Intn(2)
+ if flag == 1 {
+ bs[i] = byte(rand.Float64()*10 + 48)
+ } else {
+ bs[i] = byte(rand.Float64()*26 + 97)
+ }
+ }
+ return string(bs)
+}
+
+func StringFloat64ToInt(s string) int {
+ f1, err := strconv.ParseFloat(s, 64)
+ if err != nil {
+ return 0
+ }
+ s1 := strconv.FormatFloat(math.Ceil(f1), 'f', -1, 64)
+ i, _ := strconv.Atoi(s1)
+ return i
+}
diff --git a/utils/time.go b/utils/time.go
new file mode 100644
index 0000000..3880bb8
--- /dev/null
+++ b/utils/time.go
@@ -0,0 +1,13 @@
+package utils
+
+import "time"
+
+const (
+ DateTimeFormat string = "2006-01-02 15:04:05"
+ DateTimeFormat2 string = "2006-01-02 15:04"
+ DateFormat string = "2006-01-02"
+)
+
+func GetCurrentTime() time.Time {
+ return time.Now()
+}
diff --git a/utils/timer/timed_task.go b/utils/timer/timed_task.go
new file mode 100644
index 0000000..881fdde
--- /dev/null
+++ b/utils/timer/timed_task.go
@@ -0,0 +1,109 @@
+package timer
+
+import (
+ "sync"
+
+ "github.com/robfig/cron/v3"
+)
+
+type Timer interface {
+ AddTaskByFunc(taskName string, spec string, task func()) (cron.EntryID, error)
+ AddTaskByJob(taskName string, spec string, job interface{ Run() }) (cron.EntryID, error)
+ FindCron(taskName string) (*cron.Cron, bool)
+ StartTask(taskName string)
+ StopTask(taskName string)
+ Remove(taskName string, id int)
+ Clear(taskName string)
+ Close()
+}
+
+// timer 定时任务管理
+type timer struct {
+ taskList map[string]*cron.Cron
+ sync.Mutex
+}
+
+// AddTaskByFunc 通过函数的方法添加任务
+func (t *timer) AddTaskByFunc(taskName string, spec string, task func()) (cron.EntryID, error) {
+ t.Lock()
+ defer t.Unlock()
+ if _, ok := t.taskList[taskName]; !ok {
+ t.taskList[taskName] = cron.New()
+ }
+ id, err := t.taskList[taskName].AddFunc(spec, task)
+ t.taskList[taskName].Start()
+ return id, err
+}
+
+// AddTaskByJob 通过接口的方法添加任务
+func (t *timer) AddTaskByJob(taskName string, spec string, job interface{ Run() }) (cron.EntryID, error) {
+ t.Lock()
+ defer t.Unlock()
+ if _, ok := t.taskList[taskName]; !ok {
+ t.taskList[taskName] = cron.New()
+ }
+ id, err := t.taskList[taskName].AddJob(spec, job)
+ t.taskList[taskName].Start()
+ return id, err
+}
+
+// FindCron 获取对应taskName的cron 可能会为空
+func (t *timer) FindCron(taskName string) (*cron.Cron, bool) {
+ t.Lock()
+ defer t.Unlock()
+ v, ok := t.taskList[taskName]
+ return v, ok
+}
+
+// StartTask 开始任务
+func (t *timer) StartTask(taskName string) {
+ t.Lock()
+ defer t.Unlock()
+ if v, ok := t.taskList[taskName]; ok {
+ v.Start()
+ }
+ return
+}
+
+// StopTask 停止任务
+func (t *timer) StopTask(taskName string) {
+ t.Lock()
+ defer t.Unlock()
+ if v, ok := t.taskList[taskName]; ok {
+ v.Stop()
+ }
+ return
+}
+
+// Remove 从taskName 删除指定任务
+func (t *timer) Remove(taskName string, id int) {
+ t.Lock()
+ defer t.Unlock()
+ if v, ok := t.taskList[taskName]; ok {
+ v.Remove(cron.EntryID(id))
+ }
+ return
+}
+
+// Clear 清除任务
+func (t *timer) Clear(taskName string) {
+ t.Lock()
+ defer t.Unlock()
+ if v, ok := t.taskList[taskName]; ok {
+ v.Stop()
+ delete(t.taskList, taskName)
+ }
+}
+
+// Close 释放资源
+func (t *timer) Close() {
+ t.Lock()
+ defer t.Unlock()
+ for _, v := range t.taskList {
+ v.Stop()
+ }
+}
+
+func NewTimerTask() Timer {
+ return &timer{taskList: make(map[string]*cron.Cron)}
+}
diff --git a/utils/upload/aliyun_oss.go b/utils/upload/aliyun_oss.go
new file mode 100644
index 0000000..c4fd850
--- /dev/null
+++ b/utils/upload/aliyun_oss.go
@@ -0,0 +1,75 @@
+package upload
+
+import (
+ "errors"
+ "mime/multipart"
+ "path/filepath"
+ "pure/global"
+ "time"
+
+ "github.com/aliyun/aliyun-oss-go-sdk/oss"
+ "go.uber.org/zap"
+)
+
+type AliyunOSS struct{}
+
+func (*AliyunOSS) UploadFile(file *multipart.FileHeader) (string, string, error) {
+ bucket, err := NewBucket()
+ if err != nil {
+ global.MG_LOG.Error("function AliyunOSS.NewBucket() Failed", zap.Any("err", err.Error()))
+ return "", "", errors.New("function AliyunOSS.NewBucket() Failed, err:" + err.Error())
+ }
+
+ // 读取本地文件。
+ f, openError := file.Open()
+ if openError != nil {
+ global.MG_LOG.Error("function file.Open() Failed", zap.Any("err", openError.Error()))
+ return "", "", errors.New("function file.Open() Failed, err:" + openError.Error())
+ }
+ defer f.Close() // 创建文件 defer 关闭
+ // 上传阿里云路径 文件名格式 自己可以改 建议保证唯一性
+ yunFileTmpPath := filepath.Join("uploads", time.Now().Format("2006-01-02")) + "/" + file.Filename
+
+ // 上传文件流。
+ err = bucket.PutObject(yunFileTmpPath, f)
+ if err != nil {
+ global.MG_LOG.Error("function formUploader.Put() Failed", zap.Any("err", err.Error()))
+ return "", "", errors.New("function formUploader.Put() Failed, err:" + err.Error())
+ }
+
+ return global.MG_CONFIG.AliyunOSS.BucketUrl + "/" + yunFileTmpPath, yunFileTmpPath, nil
+}
+
+func (*AliyunOSS) DeleteFile(key string) error {
+ bucket, err := NewBucket()
+ if err != nil {
+ global.MG_LOG.Error("function AliyunOSS.NewBucket() Failed", zap.Any("err", err.Error()))
+ return errors.New("function AliyunOSS.NewBucket() Failed, err:" + err.Error())
+ }
+
+ // 删除单个文件。objectName表示删除OSS文件时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg。
+ // 如需删除文件夹,请将objectName设置为对应的文件夹名称。如果文件夹非空,则需要将文件夹下的所有object删除后才能删除该文件夹。
+ err = bucket.DeleteObject(key)
+ if err != nil {
+ global.MG_LOG.Error("function bucketManager.Delete() Filed", zap.Any("err", err.Error()))
+ return errors.New("function bucketManager.Delete() Filed, err:" + err.Error())
+ }
+
+ return nil
+}
+
+func NewBucket() (*oss.Bucket, error) {
+ // 创建OSSClient实例。
+ client, err := oss.New(global.MG_CONFIG.AliyunOSS.Endpoint, global.MG_CONFIG.AliyunOSS.AccessKeyId, global.MG_CONFIG.AliyunOSS.AccessKeySecret)
+ if err != nil {
+ return nil, err
+ }
+
+ // 获取存储空间。
+ bucket, err := client.Bucket(global.MG_CONFIG.AliyunOSS.BucketName)
+ if err != nil {
+ return nil, err
+ }
+
+ return bucket, nil
+}
diff --git a/utils/upload/local.go b/utils/upload/local.go
new file mode 100644
index 0000000..80b83cd
--- /dev/null
+++ b/utils/upload/local.go
@@ -0,0 +1,79 @@
+package upload
+
+import (
+ "errors"
+ "io"
+ "mime/multipart"
+ "os"
+ "path"
+ "pure/global"
+ "pure/utils"
+ "strings"
+ "time"
+
+ "go.uber.org/zap"
+)
+
+type Local struct{}
+
+//@object: *Local
+//@function: UploadFile
+//@description: 上传文件
+//@param: file *multipart.FileHeader
+//@return: string, string, error
+
+func (*Local) UploadFile(file *multipart.FileHeader) (string, string, error) {
+ // 读取文件后缀
+ ext := path.Ext(file.Filename)
+ // 读取文件名并加密
+ name := strings.TrimSuffix(file.Filename, ext)
+ name = utils.MD5V([]byte(name))
+ // 拼接新文件名
+ filename := name + "_" + time.Now().Format("20060102150405") + ext
+ // 尝试创建此路径
+ mkdirErr := os.MkdirAll(global.MG_CONFIG.Local.Path, os.ModePerm)
+ if mkdirErr != nil {
+ global.MG_LOG.Error("function os.MkdirAll() Filed", zap.Any("err", mkdirErr.Error()))
+ return "", "", errors.New("function os.MkdirAll() Filed, err:" + mkdirErr.Error())
+ }
+ // 拼接路径和文件名
+ p := global.MG_CONFIG.Local.Path + "/" + filename
+
+ f, openError := file.Open() // 读取文件
+ if openError != nil {
+ global.MG_LOG.Error("function file.Open() Filed", zap.Any("err", openError.Error()))
+ return "", "", errors.New("function file.Open() Filed, err:" + openError.Error())
+ }
+ defer f.Close() // 创建文件 defer 关闭
+
+ out, createErr := os.Create(p)
+ if createErr != nil {
+ global.MG_LOG.Error("function os.Create() Filed", zap.Any("err", createErr.Error()))
+
+ return "", "", errors.New("function os.Create() Filed, err:" + createErr.Error())
+ }
+ defer out.Close() // 创建文件 defer 关闭
+
+ _, copyErr := io.Copy(out, f) // 传输(拷贝)文件
+ if copyErr != nil {
+ global.MG_LOG.Error("function io.Copy() Filed", zap.Any("err", copyErr.Error()))
+ return "", "", errors.New("function io.Copy() Filed, err:" + copyErr.Error())
+ }
+ return p, filename, nil
+}
+
+//@object: *Local
+//@function: DeleteFile
+//@description: 删除文件
+//@param: key string
+//@return: error
+
+func (*Local) DeleteFile(key string) error {
+ p := global.MG_CONFIG.Local.Path + "/" + key
+ if strings.Contains(p, global.MG_CONFIG.Local.Path) {
+ if err := os.Remove(p); err != nil {
+ return errors.New("本地文件删除失败, err:" + err.Error())
+ }
+ }
+ return nil
+}
diff --git a/utils/upload/minio.go b/utils/upload/minio.go
new file mode 100644
index 0000000..830bfee
--- /dev/null
+++ b/utils/upload/minio.go
@@ -0,0 +1,123 @@
+package upload
+
+import (
+ "bytes"
+ "encoding/json"
+ "errors"
+ "io"
+ "io/ioutil"
+ "mime/multipart"
+ "net/http"
+ "strings"
+)
+
+const (
+ BaseUrl = "http://file-upload-test.mangguonews.com/upload"
+ ImgSuffix = "jpg,jpeg,png,gif,tif,tiff,bmp,"
+ Type = "graph,video,doc,"
+)
+
+type Response struct {
+ Data struct {
+ File string `json:"file"`
+ Hash string `json:"hash"`
+ ScaleImage string `json:"scaleImage"`
+ UploadFileName string `json:"uploadFileName"`
+ BaseUrl string `json:"baseUrl"` //给前端返回另加的参数
+ } `json:"data"`
+ Message struct {
+ Desc string `json:"desc"`
+ Error interface{} `json:"error"`
+ } `json:"message"`
+ Status bool `json:"status"`
+}
+
+type ParamsUpload struct {
+ File *multipart.FileHeader `form:"file"` //文件
+ Type string `form:"type"` //类型 img:图片
+ ParamsGet
+}
+
+type ParamsGet struct {
+ Width string `form:"width"`
+ Height string `form:"height"`
+ Scale string `form:"scale"`
+}
+
+func createMgNewsUploadRequest(file multipart.File, params map[string]string, fileName string) (*http.Request, error) {
+ var (
+ err error
+ body *bytes.Buffer
+ w *multipart.Writer
+ writer io.Writer
+ req *http.Request
+ contentType string
+ )
+ body = &bytes.Buffer{}
+ w = multipart.NewWriter(body)
+ contentType = w.FormDataContentType()
+ for key, val := range params {
+ _ = w.WriteField(key, val)
+ }
+ if file != nil {
+ writer, err = w.CreateFormFile("file", fileName)
+ _, err = io.Copy(writer, file)
+ if err != nil {
+ return nil, err
+ }
+ }
+ w.Close()
+ req, err = http.NewRequest(http.MethodPost, BaseUrl, body)
+ req.Header.Set("Content-Type", contentType)
+ return req, err
+}
+
+func MgNewsUpload(file multipart.File, pm map[string]string, fileName string) (respData Response, err error) {
+ var (
+ client *http.Client
+ req *http.Request
+ resp *http.Response
+ resBody []byte
+ )
+ client = &http.Client{}
+ req, err = createMgNewsUploadRequest(file, pm, fileName)
+ if err != nil {
+ return
+ }
+ resp, _ = client.Do(req)
+ defer resp.Body.Close()
+ resBody, err = ioutil.ReadAll(resp.Body)
+ if err != nil {
+ return
+ }
+ if resp.StatusCode != 200 {
+ err = errors.New("上传失败")
+ return
+ }
+ //fmt.Println(string(resBody))
+ err = json.Unmarshal(resBody, &respData)
+ if err != nil {
+ return
+ }
+ return
+}
+
+func CheckType(t string) bool {
+ if strings.Index(Type, strings.ToLower(t)+",") >= 0 {
+ return true
+ }
+ return false
+}
+
+func CheckFileSuffix(fileName string, t string) bool {
+ var suffix string
+ suffix = fileName[(strings.LastIndex(fileName, "."))+1:]
+ if t == "graph" {
+ if strings.Index(ImgSuffix, strings.ToLower(suffix)+",") >= 0 {
+ return true
+ }
+ } else {
+ return false
+ }
+ return false
+}
diff --git a/utils/upload/tencent_cos.go b/utils/upload/tencent_cos.go
new file mode 100644
index 0000000..0ad3843
--- /dev/null
+++ b/utils/upload/tencent_cos.go
@@ -0,0 +1,60 @@
+package upload
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "mime/multipart"
+ "net/http"
+ "net/url"
+ "pure/global"
+ "time"
+
+ "github.com/tencentyun/cos-go-sdk-v5"
+ "go.uber.org/zap"
+)
+
+type TencentCOS struct{}
+
+// UploadFile upload file to COS
+func (*TencentCOS) UploadFile(file *multipart.FileHeader) (string, string, error) {
+ client := NewClient()
+ f, openError := file.Open()
+ if openError != nil {
+ global.MG_LOG.Error("function file.Open() Filed", zap.Any("err", openError.Error()))
+ return "", "", errors.New("function file.Open() Filed, err:" + openError.Error())
+ }
+ defer f.Close() // 创建文件 defer 关闭
+ fileKey := fmt.Sprintf("%d%s", time.Now().Unix(), file.Filename)
+
+ _, err := client.Object.Put(context.Background(), global.MG_CONFIG.TencentCOS.PathPrefix+"/"+fileKey, f, nil)
+ if err != nil {
+ panic(err)
+ }
+ return global.MG_CONFIG.TencentCOS.BaseURL + "/" + global.MG_CONFIG.TencentCOS.PathPrefix + "/" + fileKey, fileKey, nil
+}
+
+// DeleteFile delete file form COS
+func (*TencentCOS) DeleteFile(key string) error {
+ client := NewClient()
+ name := global.MG_CONFIG.TencentCOS.PathPrefix + "/" + key
+ _, err := client.Object.Delete(context.Background(), name)
+ if err != nil {
+ global.MG_LOG.Error("function bucketManager.Delete() Filed", zap.Any("err", err.Error()))
+ return errors.New("function bucketManager.Delete() Filed, err:" + err.Error())
+ }
+ return nil
+}
+
+// NewClient init COS client
+func NewClient() *cos.Client {
+ urlStr, _ := url.Parse("https://" + global.MG_CONFIG.TencentCOS.Bucket + ".cos." + global.MG_CONFIG.TencentCOS.Region + ".myqcloud.com")
+ baseURL := &cos.BaseURL{BucketURL: urlStr}
+ client := cos.NewClient(baseURL, &http.Client{
+ Transport: &cos.AuthorizationTransport{
+ SecretID: global.MG_CONFIG.TencentCOS.SecretID,
+ SecretKey: global.MG_CONFIG.TencentCOS.SecretKey,
+ },
+ })
+ return client
+}
diff --git a/utils/validator.go b/utils/validator.go
new file mode 100644
index 0000000..b5c2415
--- /dev/null
+++ b/utils/validator.go
@@ -0,0 +1,368 @@
+package utils
+
+import (
+ "bytes"
+ "errors"
+ "pure/model/request"
+ "reflect"
+ "strconv"
+ "strings"
+)
+
+type Rules map[string][]string
+
+type RulesMap map[string]Rules
+
+var CustomizeMap = make(map[string]Rules)
+
+//@function: RegisterRule
+//@description: 注册自定义规则方案建议在路由初始化层即注册
+//@param: key string, rule Rules
+//@return: err error
+
+func RegisterRule(key string, rule Rules) (err error) {
+ if CustomizeMap[key] != nil {
+ return errors.New(key + "已注册,无法重复注册")
+ } else {
+ CustomizeMap[key] = rule
+ return nil
+ }
+}
+
+//@function: NotEmpty
+//@description: 非空 不能为其对应类型的0值
+//@return: string
+
+func NotEmpty() string {
+ return "notEmpty"
+}
+
+//@function: Lt
+//@description: 小于入参(<) 如果为string array Slice则为长度比较 如果是 int uint float 则为数值比较
+//@param: mark string
+//@return: string
+
+func Lt(mark string) string {
+ return "lt=" + mark
+}
+
+//@function: Le
+//@description: 小于等于入参(<=) 如果为string array Slice则为长度比较 如果是 int uint float 则为数值比较
+//@param: mark string
+//@return: string
+
+func Le(mark string) string {
+ return "le=" + mark
+}
+
+//@function: Eq
+//@description: 等于入参(==) 如果为string array Slice则为长度比较 如果是 int uint float 则为数值比较
+//@param: mark string
+//@return: string
+
+func Eq(mark string) string {
+ return "eq=" + mark
+}
+
+//@function: Ne
+//@description: 不等于入参(!=) 如果为string array Slice则为长度比较 如果是 int uint float 则为数值比较
+//@param: mark string
+//@return: string
+
+func Ne(mark string) string {
+ return "ne=" + mark
+}
+
+//@function: Ge
+//@description: 大于等于入参(>=) 如果为string array Slice则为长度比较 如果是 int uint float 则为数值比较
+//@param: mark string
+//@return: string
+
+func Ge(mark string) string {
+ return "ge=" + mark
+}
+
+//@function: Gt
+//@description: 大于入参(>) 如果为string array Slice则为长度比较 如果是 int uint float 则为数值比较
+//@param: mark string
+//@return: string
+
+func Gt(mark string) string {
+ return "gt=" + mark
+}
+
+func Ct(marks ...string) string {
+ var result bytes.Buffer
+ for _, value := range marks {
+ result.WriteString(value + ",")
+ }
+ return "ct=" + result.String()
+}
+
+//@function: Verify
+//@description: 校验方法
+//@param: st interface{}, roleMap Rules(入参实例,规则map)
+//@return: err error
+
+func Verify(st interface{}, roleMap Rules) (err error) {
+ compareMap := map[string]bool{
+ "lt": true,
+ "le": true,
+ "eq": true,
+ "ne": true,
+ "ge": true,
+ "gt": true,
+ }
+
+ compareMap2 := map[string]bool{
+ "ct": true,
+ }
+
+ typ := reflect.TypeOf(st)
+ val := reflect.ValueOf(st) // 获取reflect.Type类型
+
+ kd := val.Kind() // 获取到st对应的类别
+ if kd != reflect.Struct {
+ return errors.New("expect struct")
+ }
+ num := val.NumField()
+ // 遍历结构体的所有字段
+ for i := 0; i < num; i++ {
+ tagVal := typ.Field(i)
+ val := val.Field(i)
+ if len(roleMap[tagVal.Name]) > 0 {
+ for _, v := range roleMap[tagVal.Name] {
+ switch {
+ case v == "notEmpty":
+ if isBlank(val) {
+ return errors.New(tagVal.Name + "值不能为空")
+ }
+ case compareMap[strings.Split(v, "=")[0]]:
+ if !compareVerify(val, v) {
+ return errors.New(tagVal.Name + "长度或值不在合法范围," + v)
+ }
+ case compareMap2[strings.Split(v, "=")[0]]:
+ if !compareVerify2(val, v) {
+ return errors.New(tagVal.Name + "取值不可用," + v)
+ }
+ }
+ }
+ }
+ }
+ return nil
+}
+
+func Verify2(st request.StructParams, roleMap Rules) (err error) {
+ compareMap := map[string]bool{
+ "lt": true,
+ "le": true,
+ "eq": true,
+ "ne": true,
+ "ge": true,
+ "gt": true,
+ }
+ compareMap2 := map[string]bool{
+ "ct": true,
+ }
+ for stk, stv := range st {
+ val := reflect.ValueOf(stv)
+ if len(roleMap[stk]) > 0 {
+ for _, v := range roleMap[stk] {
+ switch {
+ case v == "notEmpty":
+ if isBlank(val) {
+ return errors.New(stk + "值不能为空")
+ }
+ case compareMap[strings.Split(v, "=")[0]]:
+ if !compareVerify(val, v) {
+ return errors.New(stk + "长度或值不在合法范围," + v)
+ }
+ case compareMap2[strings.Split(v, "=")[0]]:
+ if !compareVerify2(val, v) {
+ return errors.New(stk + "取值不可用," + v)
+ }
+ }
+ }
+ }
+ }
+ return nil
+}
+
+//@function: compareVerify
+//@description: 长度和数字的校验方法 根据类型自动校验
+//@param: value reflect.Value, VerifyStr string
+//@return: bool
+
+func compareVerify(value reflect.Value, VerifyStr string) bool {
+ switch value.Kind() {
+ case reflect.String, reflect.Slice, reflect.Array:
+ return compare(value.Len(), VerifyStr)
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return compare(value.Uint(), VerifyStr)
+ case reflect.Float32, reflect.Float64:
+ return compare(value.Float(), VerifyStr)
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return compare(value.Int(), VerifyStr)
+ default:
+ return false
+ }
+}
+
+func compareVerify2(value reflect.Value, VerifyStr string) bool {
+ if value.String() != "" {
+ v := value.String() + ","
+ if strings.Index(VerifyStr, v) > 0 {
+ return true
+ }
+ }
+ return false
+}
+
+//@function: isBlank
+//@description: 非空校验
+//@param: value reflect.Value
+//@return: bool
+
+func isBlank(value reflect.Value) bool {
+ switch value.Kind() {
+ case reflect.String:
+ return value.Len() == 0
+ case reflect.Bool:
+ return !value.Bool()
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return value.Int() == 0
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return value.Uint() == 0
+ case reflect.Float32, reflect.Float64:
+ return value.Float() == 0
+ case reflect.Interface, reflect.Ptr:
+ return value.IsNil()
+ }
+ return reflect.DeepEqual(value.Interface(), reflect.Zero(value.Type()).Interface())
+}
+
+//@function: compare
+//@description: 比较函数
+//@param: value interface{}, VerifyStr string
+//@return: bool
+
+func compare(value interface{}, VerifyStr string) bool {
+ VerifyStrArr := strings.Split(VerifyStr, "=")
+ val := reflect.ValueOf(value)
+ switch val.Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ VInt, VErr := strconv.ParseInt(VerifyStrArr[1], 10, 64)
+ if VErr != nil {
+ return false
+ }
+ switch {
+ case VerifyStrArr[0] == "lt":
+ return val.Int() < VInt
+ case VerifyStrArr[0] == "le":
+ return val.Int() <= VInt
+ case VerifyStrArr[0] == "eq":
+ return val.Int() == VInt
+ case VerifyStrArr[0] == "ne":
+ return val.Int() != VInt
+ case VerifyStrArr[0] == "ge":
+ return val.Int() >= VInt
+ case VerifyStrArr[0] == "gt":
+ return val.Int() > VInt
+ default:
+ return false
+ }
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ VInt, VErr := strconv.Atoi(VerifyStrArr[1])
+ if VErr != nil {
+ return false
+ }
+ switch {
+ case VerifyStrArr[0] == "lt":
+ return val.Uint() < uint64(VInt)
+ case VerifyStrArr[0] == "le":
+ return val.Uint() <= uint64(VInt)
+ case VerifyStrArr[0] == "eq":
+ return val.Uint() == uint64(VInt)
+ case VerifyStrArr[0] == "ne":
+ return val.Uint() != uint64(VInt)
+ case VerifyStrArr[0] == "ge":
+ return val.Uint() >= uint64(VInt)
+ case VerifyStrArr[0] == "gt":
+ return val.Uint() > uint64(VInt)
+ default:
+ return false
+ }
+ case reflect.Float32, reflect.Float64:
+ VFloat, VErr := strconv.ParseFloat(VerifyStrArr[1], 64)
+ if VErr != nil {
+ return false
+ }
+ switch {
+ case VerifyStrArr[0] == "lt":
+ return val.Float() < VFloat
+ case VerifyStrArr[0] == "le":
+ return val.Float() <= VFloat
+ case VerifyStrArr[0] == "eq":
+ return val.Float() == VFloat
+ case VerifyStrArr[0] == "ne":
+ return val.Float() != VFloat
+ case VerifyStrArr[0] == "ge":
+ return val.Float() >= VFloat
+ case VerifyStrArr[0] == "gt":
+ return val.Float() > VFloat
+ default:
+ return false
+ }
+ default:
+ return false
+ }
+}
+
+func Transform(st request.StructParams, fields ...string) map[string]interface{} {
+ var (
+ fm = make(map[string]string)
+ res = make(map[string]interface{})
+ )
+ for _, v := range fields {
+ fm[v] = v
+ }
+ for k, v := range st {
+ if field, ok := fm[snakeString(k)]; ok {
+ res[field] = v
+ }
+ }
+ return res
+}
+
+func TransformRuin(st request.StructParams, fields ...string) map[string]interface{} {
+ var (
+ fm = make(map[string]string)
+ res = make(map[string]interface{})
+ )
+ for _, v := range fields {
+ fm[v] = v
+ }
+ for k, v := range st {
+ if _, ok := fm[snakeString(k)]; !ok {
+ res[snakeString(k)] = v
+ }
+ }
+ return res
+}
+
+func snakeString(s string) string {
+ data := make([]byte, 0, len(s)*2)
+ j := false
+ num := len(s)
+ for i := 0; i < num; i++ {
+ d := s[i]
+ if i > 0 && d >= 'A' && d <= 'Z' && j {
+ data = append(data, '_')
+ }
+ if d != '_' {
+ j = true
+ }
+ data = append(data, d)
+ }
+ return strings.ToLower(string(data[:]))
+}
diff --git a/utils/verify.go b/utils/verify.go
new file mode 100644
index 0000000..ef6717d
--- /dev/null
+++ b/utils/verify.go
@@ -0,0 +1,27 @@
+package utils
+
+var (
+ IdVerify = Rules{"ID": {NotEmpty()}}
+ SendMessageVerity = Rules{"Phone": {NotEmpty()}, "Type": {NotEmpty()}}
+ SendEmailVerify = Rules{"Email": {NotEmpty()}}
+ LoginVerify = Rules{"Appid": {NotEmpty()}, "Type": {NotEmpty()}}
+ LoginPhoneVerify = Rules{"Phone": {NotEmpty()}, "Code": {NotEmpty()}}
+ LoginEmailVerify = Rules{"Email": {NotEmpty()}, "Code": {NotEmpty()}}
+ RegisterVerify = Rules{"Email": {NotEmpty()}, "Code": {NotEmpty()}, "Appid": {NotEmpty()}, "Nickname": {NotEmpty()}, "Avatar": {NotEmpty()}}
+ BandPhoneVerify = Rules{"Phone": {NotEmpty()}, "Code": {NotEmpty()}}
+ PlatformAuthVerify = Rules{"Platform": {NotEmpty()}}
+ TypeVerify = Rules{"Type": {NotEmpty()}}
+ PageInfoVerify = Rules{"Page": {NotEmpty()}, "PageSize": {NotEmpty()}}
+ MissionClaimVerify = Rules{"MissionId": {NotEmpty()}, "AddressId": {NotEmpty()}}
+ MissionIdVerify = Rules{"MissionId": {NotEmpty()}}
+ SpuNoVerify = Rules{"SpuNo": {NotEmpty()}}
+ CustomerGoodsVerify = Rules{"SkuNo": {NotEmpty()}}
+ MissionClaimIdVerify = Rules{"MissionClaimId": {NotEmpty()}}
+ MissionCodeVerify = Rules{"Code": {NotEmpty()}}
+ DictDataVerity = Rules{"TypeCode": {NotEmpty()}}
+ BillListVerity = Rules{"Uint": {NotEmpty()}}
+ OrderIdVerity = Rules{"OrderID": {NotEmpty()}}
+ WithdrawalVerity = Rules{"Phone": {NotEmpty()}, "Code": {NotEmpty()}, "Amount": {NotEmpty()}, "AccountID": {NotEmpty()}}
+ FlowNoVerity = Rules{"FlowNo": {NotEmpty()}}
+ ChainVerify = Rules{"Hash": {NotEmpty()}}
+)
diff --git a/utils/zipfiles.go b/utils/zipfiles.go
new file mode 100644
index 0000000..921c9b4
--- /dev/null
+++ b/utils/zipfiles.go
@@ -0,0 +1,71 @@
+package utils
+
+import (
+ "archive/zip"
+ "io"
+ "os"
+ "strings"
+)
+
+//@function: ZipFiles
+//@description: 压缩文件
+//@param: filename string, files []string, oldForm, newForm string
+//@return: error
+
+func ZipFiles(filename string, files []string, oldForm, newForm string) error {
+
+ newZipFile, err := os.Create(filename)
+ if err != nil {
+ return err
+ }
+ defer func() {
+ _ = newZipFile.Close()
+ }()
+
+ zipWriter := zip.NewWriter(newZipFile)
+ defer func() {
+ _ = zipWriter.Close()
+ }()
+
+ // 把files添加到zip中
+ for _, file := range files {
+
+ err = func(file string) error {
+ zipFile, err := os.Open(file)
+ if err != nil {
+ return err
+ }
+ defer zipFile.Close()
+ // 获取file的基础信息
+ info, err := zipFile.Stat()
+ if err != nil {
+ return err
+ }
+
+ header, err := zip.FileInfoHeader(info)
+ if err != nil {
+ return err
+ }
+
+ // 使用上面的FileInforHeader() 就可以把文件保存的路径替换成我们自己想要的了,如下面
+ header.Name = strings.Replace(file, oldForm, newForm, -1)
+
+ // 优化压缩
+ // 更多参考see http://golang.org/pkg/archive/zip/#pkg-constants
+ header.Method = zip.Deflate
+
+ writer, err := zipWriter.CreateHeader(header)
+ if err != nil {
+ return err
+ }
+ if _, err = io.Copy(writer, zipFile); err != nil {
+ return err
+ }
+ return nil
+ }(file)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
diff --git a/webhook.json b/webhook.json
new file mode 100644
index 0000000..7682f1c
--- /dev/null
+++ b/webhook.json
@@ -0,0 +1,546 @@
+//用户付款
+{
+ "id": "WH-62W810145R7409724-8CH11354TY024302T",
+ "event_version": "1.0",
+ "create_time": "2022-10-21T06:42:32.606Z",
+ "resource_type": "checkout-order",
+ "resource_version": "2.0",
+ "event_type": "CHECKOUT.ORDER.APPROVED",
+ "summary": "An order has been approved by buyer",
+ "resource": {
+ "create_time": "2022-10-21T06:27:07Z",
+ "purchase_units": [
+ {
+ "reference_id": "default",
+ "amount": {
+ "currency_code": "USD",
+ "value": "4999.81"
+ },
+ "payee": {
+ "email_address": "sb-gsncy21794962@business.example.com",
+ "merchant_id": "3SQBR4YEWZ4BA"
+ },
+ "shipping": {
+ "name": {
+ "full_name": "John Doe"
+ },
+ "address": {
+ "address_line_1": "1 Main St",
+ "admin_area_2": "San Jose",
+ "admin_area_1": "CA",
+ "postal_code": "95131",
+ "country_code": "US"
+ }
+ }
+ }
+ ],
+ "links": [
+ {
+ "href": "https://api.sandbox.paypal.com/v2/checkout/orders/9JL52742K01513702",
+ "rel": "self",
+ "method": "GET"
+ },
+ {
+ "href": "https://api.sandbox.paypal.com/v2/checkout/orders/9JL52742K01513702",
+ "rel": "update",
+ "method": "PATCH"
+ },
+ {
+ "href": "https://api.sandbox.paypal.com/v2/checkout/orders/9JL52742K01513702/capture",
+ "rel": "capture",
+ "method": "POST"
+ }
+ ],
+ "id": "9JL52742K01513702",
+ "payment_source": {
+ "paypal": {}
+ },
+ "intent": "CAPTURE",
+ "payer": {
+ "name": {
+ "given_name": "John",
+ "surname": "Doe"
+ },
+ "email_address": "sb-79rfq21745286@business.example.com",
+ "payer_id": "RCSNJCSEN36ZJ",
+ "address": {
+ "country_code": "US"
+ }
+ },
+ "status": "APPROVED"
+ },
+ "links": [
+ {
+ "href": "https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-62W810145R7409724-8CH11354TY024302T",
+ "rel": "self",
+ "method": "GET"
+ },
+ {
+ "href": "https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-62W810145R7409724-8CH11354TY024302T/resend",
+ "rel": "resend",
+ "method": "POST"
+ }
+ ]
+}
+//确认收款
+{
+ "id": "WH-4KR61645R81861232-4LN31734K5078982S",
+ "event_version": "1.0",
+ "create_time": "2022-10-21T06:46:50.303Z",
+ "resource_type": "capture",
+ "resource_version": "2.0",
+ "event_type": "PAYMENT.CAPTURE.COMPLETED",
+ "summary": "Payment completed for $ 4999.81 USD",
+ "resource": {
+ "amount": {
+ "value": "4999.81",
+ "currency_code": "USD"
+ },
+ "seller_protection": {
+ "dispute_categories": [
+ "ITEM_NOT_RECEIVED",
+ "UNAUTHORIZED_TRANSACTION"
+ ],
+ "status": "ELIGIBLE"
+ },
+ "supplementary_data": {
+ "related_ids": {
+ "order_id": "9JL52742K01513702"
+ }
+ },
+ "update_time": "2022-10-21T06:46:46Z",
+ "create_time": "2022-10-21T06:46:46Z",
+ "final_capture": true,
+ "seller_receivable_breakdown": {
+ "paypal_fee": {
+ "value": "195.29",
+ "currency_code": "USD"
+ },
+ "gross_amount": {
+ "value": "4999.81",
+ "currency_code": "USD"
+ },
+ "net_amount": {
+ "value": "4804.52",
+ "currency_code": "USD"
+ }
+ },
+ "links": [
+ {
+ "method": "GET",
+ "rel": "self",
+ "href": "https://api.sandbox.paypal.com/v2/payments/captures/5FH6806799924231W"
+ },
+ {
+ "method": "POST",
+ "rel": "refund",
+ "href": "https://api.sandbox.paypal.com/v2/payments/captures/5FH6806799924231W/refund"
+ },
+ {
+ "method": "GET",
+ "rel": "up",
+ "href": "https://api.sandbox.paypal.com/v2/checkout/orders/9JL52742K01513702"
+ }
+ ],
+ "id": "5FH6806799924231W",
+ "status": "COMPLETED"
+ },
+ "links": [
+ {
+ "href": "https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-4KR61645R81861232-4LN31734K5078982S",
+ "rel": "self",
+ "method": "GET"
+ },
+ {
+ "href": "https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-4KR61645R81861232-4LN31734K5078982S/resend",
+ "rel": "resend",
+ "method": "POST"
+ }
+ ]
+}
+//提现(提现失败回调)
+{
+ "id": "WH-5A19140561140630Y-2JL02815W4313754E",
+ "event_version": "1.0",
+ "create_time": "2022-10-21T07:14:45.696Z",
+ "resource_type": "payouts",
+ "event_type": "PAYMENT.PAYOUTSBATCH.DENIED",
+ "summary": "Payouts batch got denied.",
+ "resource": {
+ "batch_header": {
+ "payout_batch_id": "34MY452YBHPQW",
+ "batch_status": "DENIED",
+ "time_created": "2022-10-21T07:14:34Z",
+ "sender_batch_header": {
+ "sender_batch_id": "dsdsdsd"
+ },
+ "funding_source": "BALANCE",
+ "amount": {
+ "currency": "USD",
+ "value": "0.00"
+ },
+ "fees": {
+ "currency": "USD",
+ "value": "0.00"
+ },
+ "payments": 1
+ },
+ "links": [
+ {
+ "href": "https://api.sandbox.paypal.com/v1/payments/payouts/34MY452YBHPQW",
+ "rel": "self",
+ "method": "GET",
+ "encType": "application/json"
+ }
+ ]
+ },
+ "links": [
+ {
+ "href": "https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-5A19140561140630Y-2JL02815W4313754E",
+ "rel": "self",
+ "method": "GET"
+ },
+ {
+ "href": "https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-5A19140561140630Y-2JL02815W4313754E/resend",
+ "rel": "resend",
+ "method": "POST"
+ }
+ ]
+}
+//转账成功
+{
+ "id": "WH-27156021MJ807552P-9XF02986TA428514C",
+ "event_version": "1.0",
+ "create_time": "2022-10-21T07:34:58.791Z",
+ "resource_type": "payouts",
+ "event_type": "PAYMENT.PAYOUTSBATCH.SUCCESS",
+ "summary": "Payouts batch completed successfully.",
+ "resource": {
+ "batch_header": {
+ "payout_batch_id": "RLBRKVTX9W5JL",
+ "batch_status": "SUCCESS",
+ "time_created": "2022-10-21T07:34:44Z",
+ "time_completed": "2022-10-21T07:34:45Z",
+ "time_closed": "2022-10-21T07:34:45Z",
+ "sender_batch_header": {
+ "sender_batch_id": "dsdsdsd"
+ },
+ "funding_source": "BALANCE",
+ "amount": {
+ "currency": "USD",
+ "value": "96.00"
+ },
+ "fees": {
+ "currency": "USD",
+ "value": "1.92"
+ },
+ "payments": 1
+ },
+ "links": [
+ {
+ "href": "https://api.sandbox.paypal.com/v1/payments/payouts/RLBRKVTX9W5JL",
+ "rel": "self",
+ "method": "GET",
+ "encType": "application/json"
+ }
+ ]
+ },
+ "links": [
+ {
+ "href": "https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-27156021MJ807552P-9XF02986TA428514C",
+ "rel": "self",
+ "method": "GET"
+ },
+ {
+ "href": "https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-27156021MJ807552P-9XF02986TA428514C/resend",
+ "rel": "resend",
+ "method": "POST"
+ }
+ ]
+}
+//取消支付(订单退款)
+{
+ "id": "WH-7GU47175YW005840T-0VM77075J61186502",
+ "event_version": "1.0",
+ "create_time": "2022-10-21T07:50:01.873Z",
+ "resource_type": "refund",
+ "resource_version": "2.0",
+ "event_type": "PAYMENT.CAPTURE.REFUNDED",
+ "summary": "A $ 4999.81 USD capture payment was refunded",
+ "resource": {
+ "seller_payable_breakdown": {
+ "total_refunded_amount": {
+ "value": "4999.81",
+ "currency_code": "USD"
+ },
+ "paypal_fee": {
+ "value": "194.99",
+ "currency_code": "USD"
+ },
+ "gross_amount": {
+ "value": "4999.81",
+ "currency_code": "USD"
+ },
+ "net_amount": {
+ "value": "4804.82",
+ "currency_code": "USD"
+ }
+ },
+ "amount": {
+ "value": "4999.81",
+ "currency_code": "USD"
+ },
+ "update_time": "2022-10-21T00:49:57-07:00",
+ "create_time": "2022-10-21T00:49:57-07:00",
+ "links": [
+ {
+ "method": "GET",
+ "rel": "self",
+ "href": "https://api.sandbox.paypal.com/v2/payments/refunds/9F317409RP583132H"
+ },
+ {
+ "method": "GET",
+ "rel": "up",
+ "href": "https://api.sandbox.paypal.com/v2/payments/captures/5FH6806799924231W"
+ }
+ ],
+ "id": "9F317409RP583132H",
+ "status": "COMPLETED"
+ },
+ "links": [
+ {
+ "href": "https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-7GU47175YW005840T-0VM77075J61186502",
+ "rel": "self",
+ "method": "GET"
+ },
+ {
+ "href": "https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-7GU47175YW005840T-0VM77075J61186502/resend",
+ "rel": "resend",
+ "method": "POST"
+ }
+ ]
+}
+//转账item信息
+{
+ "id": "WH-62214818PA778164H-6VJ474188Y3865907",
+ "event_version": "1.0",
+ "create_time": "2022-10-21T07:14:45.699Z",
+ "resource_type": "payouts_item",
+ "event_type": "PAYMENT.PAYOUTS-ITEM.FAILED",
+ "summary": "A payout item has failed",
+ "resource": {
+ "payout_item_fee": {
+ "currency": "USD",
+ "value": "0.00"
+ },
+ "transaction_status": "FAILED",
+ "sender_batch_id": "dsdsdsd",
+ "time_processed": "2022-10-21T07:14:34Z",
+ "payout_item": {
+ "recipient_type": "EMAIL",
+ "amount": {
+ "currency": "USD",
+ "value": "0.00"
+ },
+ "note": "打款",
+ "receiver": "sb-e37dy21833133@personal.example.com",
+ "recipient_wallet": "PAYPAL"
+ },
+ "links": [
+ {
+ "href": "https://api.sandbox.paypal.com/v1/payments/payouts-item/C67WB53FB6BAW",
+ "rel": "self",
+ "method": "GET",
+ "encType": "application/json"
+ },
+ {
+ "href": "https://api.sandbox.paypal.com/v1/payments/payouts/34MY452YBHPQW",
+ "rel": "batch",
+ "method": "GET",
+ "encType": "application/json"
+ }
+ ],
+ "payout_item_id": "C67WB53FB6BAW",
+ "payout_batch_id": "34MY452YBHPQW",
+ "errors": {
+ "name": "ZERO_AMOUNT",
+ "message": "The Payout can't be done without any amount. You must enter a valid amount that's greater than zero.",
+ "information_link": "https://developer.paypal.com/docs/api/payments.payouts-batch/#errors",
+ "details": [],
+ "links": []
+ }
+ },
+ "links": [
+ {
+ "href": "https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-62214818PA778164H-6VJ474188Y3865907",
+ "rel": "self",
+ "method": "GET"
+ },
+ {
+ "href": "https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-62214818PA778164H-6VJ474188Y3865907/resend",
+ "rel": "resend",
+ "method": "POST"
+ }
+ ]
+}
+
+{
+ "id": "WH-4CJ36714CJ204831L-9DY42878JG883501V",
+ "event_version": "1.0",
+ "create_time": "2022-10-21T07:34:58.765Z",
+ "resource_type": "payouts_item",
+ "event_type": "PAYMENT.PAYOUTS-ITEM.SUCCEEDED",
+ "summary": "A payout item has succeeded",
+ "resource": {
+ "transaction_id": "7X589343BN135035E",
+ "payout_item_fee": {
+ "currency": "USD",
+ "value": "1.92"
+ },
+ "transaction_status": "SUCCESS",
+ "sender_batch_id": "dsdsdsd",
+ "time_processed": "2022-10-21T07:34:45Z",
+ "activity_id": "07S085733Y1996237",
+ "payout_item": {
+ "recipient_type": "EMAIL",
+ "amount": {
+ "currency": "USD",
+ "value": "96.00"
+ },
+ "note": "打款",
+ "receiver": "sb-e37dy21833133@personal.example.com",
+ "recipient_wallet": "PAYPAL"
+ },
+ "links": [
+ {
+ "href": "https://api.sandbox.paypal.com/v1/payments/payouts-item/RGQUU37L46TEQ",
+ "rel": "self",
+ "method": "GET",
+ "encType": "application/json"
+ },
+ {
+ "href": "https://api.sandbox.paypal.com/v1/payments/payouts/RLBRKVTX9W5JL",
+ "rel": "batch",
+ "method": "GET",
+ "encType": "application/json"
+ }
+ ],
+ "payout_item_id": "RGQUU37L46TEQ",
+ "payout_batch_id": "RLBRKVTX9W5JL"
+ },
+ "links": [
+ {
+ "href": "https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-4CJ36714CJ204831L-9DY42878JG883501V",
+ "rel": "self",
+ "method": "GET"
+ },
+ {
+ "href": "https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-4CJ36714CJ204831L-9DY42878JG883501V/resend",
+ "rel": "resend",
+ "method": "POST"
+ }
+ ]
+}
+
+
+
+{
+ "id": "WH-2B088173KT8286923-7YM54303XB465773L",
+ "event_version": "1.0",
+ "create_time": "2022-11-03T13:58:49.707Z",
+ "resource_type": "payouts",
+ "event_type": "PAYMENT.PAYOUTSBATCH.PROCESSING",
+ "summary": "Payouts batch is getting processed.",
+ "resource": {
+ "batch_header": {
+ "payout_batch_id": "444ZSA7VMXR5L",
+ "batch_status": "PROCESSING",
+ "time_created": "2022-11-03T13:58:31Z",
+ "time_completed": "2022-11-03T13:58:33Z",
+ "time_closed": "2022-11-03T13:58:33Z",
+ "sender_batch_header": {
+ "sender_batch_id": "202211031358298010010001"
+ },
+ "funding_source": "BALANCE",
+ "amount": {
+ "currency": "USD",
+ "value": "499.00"
+ },
+ "fees": {
+ "currency": "USD",
+ "value": "9.98"
+ },
+ "payments": 1
+ },
+ "links": [
+ {
+ "href": "https://api.sandbox.paypal.com/v1/payments/payouts/444ZSA7VMXR5L",
+ "rel": "self",
+ "method": "GET",
+ "encType": "application/json"
+ }
+ ]
+ },
+ "links": [
+ {
+ "href": "https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-2B088173KT8286923-7YM54303XB465773L",
+ "rel": "self",
+ "method": "GET"
+ },
+ {
+ "href": "https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-2B088173KT8286923-7YM54303XB465773L/resend",
+ "rel": "resend",
+ "method": "POST"
+ }
+ ]
+}
+
+{
+ "id": "WH-2PN47871N9299911D-36A939639Y5266517",
+ "event_version": "1.0",
+ "create_time": "2022-11-22T15:36:17.558Z",
+ "resource_type": "payouts",
+ "event_type": "PAYMENT.PAYOUTSBATCH.SUCCESS",
+ "summary": "Payouts batch completed successfully.",
+ "resource": {
+ "batch_header": {
+ "payout_batch_id": "7KD8ZC2WRXZYN",
+ "batch_status": "SUCCESS",
+ "time_created": "2022-11-22T15:36:02Z",
+ "time_completed": "2022-11-22T15:36:03Z",
+ "sender_batch_header": {
+ "sender_batch_id": "202211222335594910010002"
+ },
+ "funding_source": "BALANCE",
+ "amount": {
+ "currency": "USD",
+ "value": "3000.00"
+ },
+ "fees": {
+ "currency": "USD",
+ "value": "0.25"
+ },
+ "payments": 1
+ },
+ "links": [
+ {
+ "href": "https://api.sandbox.paypal.com/v1/payments/payouts/7KD8ZC2WRXZYN",
+ "rel": "self",
+ "method": "GET",
+ "encType": "application/json"
+ }
+ ]
+ },
+ "links": [
+ {
+ "href": "https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-2PN47871N9299911D-36A939639Y5266517",
+ "rel": "self",
+ "method": "GET"
+ },
+ {
+ "href": "https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-2PN47871N9299911D-36A939639Y5266517/resend",
+ "rel": "resend",
+ "method": "POST"
+ }
+ ]
+}
\ No newline at end of file