Compare commits

...

71 Commits

Author SHA1 Message Date
lijikun 5b9d5a02ad 12月24日下午后台查询页面逻辑,token过期时间,将导出方法分离到service 10 months ago
lijikun e2a5ee0274 12月24日下午后台查询页面逻辑,token过期时间,将导出方法分离到service 10 months ago
lijikun 475098fe03 12月24日上午修改查询每次作业提交此时逻辑 10 months ago
majun 93853d2d19 修改添加作业时间限制 10 months ago
majun 6091d688fe 修改返回提示信息 10 months ago
majun d3d31c2111 已优化作业完成次数查询逻辑 10 months ago
lijikun c26ec6e0dc 12月24日上午删除缓存多余语句(单个)删除 10 months ago
lijikun e8a984e7b0 12月23日晚,修改了redis逻辑,新增,修改作业后删除redis 10 months ago
lijikun 320bce7ea9 Merge branch 'dev' of http://39.101.133.168:8807/donghanyang/Link_Homework_Go into dev 10 months ago
lijikun d89b88cc32 12月21日 对返回前端的方法进行修改,实现代码重用 10 months ago
majun 4149dfff72 优化作业完成次数查询逻辑 10 months ago
lijikun 7e9535bf7a 12月21日 添加redis(客户端除提交题目,后台部门门店) 修改了出现错误时返回到前端的提示信息 10 months ago
lijikun 19b49d4c3c 12月20日下午,对登入token验证做了调整,客户端后台不冲突且可用 10 months ago
lijikun 5467af471e Merge branch 'dev' of http://39.101.133.168:8807/donghanyang/Link_Homework_Go into dev 10 months ago
lijikun fb787d40cf 12月20日修改响应文本信息 10 months ago
majun f0560e4cf1 优化查询逻辑 10 months ago
lijikun d1edd491fc Merge branch 'dev' of http://39.101.133.168:8807/donghanyang/Link_Homework_Go into dev 10 months ago
lijikun bfcfb32e89 12月20日添加返回结构体注解,去除日志 10 months ago
majun 08530b80f0 优化查询逻辑 10 months ago
majun 8750c8e851 优化查询逻辑 10 months ago
majun ee21d26098 优化查询逻辑 10 months ago
lijikun c5ae52c38d 12月19日晚 问题基本解决,日志关闭.前端退出登入token问题尚待解决 10 months ago
dhy 958c566f06 解决token问题 10 months ago
dhy fbbdaf5a93 Merge remote-tracking branch 'origin/dev' into dev 10 months ago
dhy e6ef2aa659 根据id导出用户的作答情况 10 months ago
lijikun 4cfb8587f1 12月19日 昨日导出完成结果 10 months ago
lijikun ee569dc254 Merge branch 'dev' of http://39.101.133.168:8807/donghanyang/Link_Homework_Go into dev 10 months ago
lijikun 88cc99e473 12月18日 解析token,获取jwcode 导出excel尝试 合并登入退出 10 months ago
dhy 08bdda001a 合并dhy分支内容 10 months ago
majun 900de7d3f1 优化查询逻辑 10 months ago
majun 514bbb00e5 优化查询逻辑 10 months ago
lijikun 34a9ce4b89 12月18日 导出excel尝试 合并登入退出 10 months ago
dhy f72b519ed2 合并dhy分支内容 10 months ago
dhy 77a1c66771 Merge branch 'refs/heads/dhy' into dev 10 months ago
lijikun ba62fa5255 12月18日 导出excel尝试 10 months ago
dhy 4e47b507b0 管理端-登录、退出接口 10 months ago
lijikun 78a1d1d36b 12月18日 导出excel尝试 10 months ago
lijikun 162073cf85 12月18日 导出excel尝试 10 months ago
dhy 96c960c04f 提交登录 10 months ago
majun 0d42255da7 合并修正 10 months ago
majun a2e0ed9d81 合并修正 10 months ago
majun a74448b654 合并修正 10 months ago
lijikun 857a110da7 12月18日合并调整后的lijikun分支 10 months ago
lijikun 20517c7cc8 12月18日合并调整后的details_ljk分支 10 months ago
lijikun d8c94ea682 12月18日合并调整后的client_ljk分支 10 months ago
lijikun 52faf6c60e 12月18日调整logic层与service层名字,功能未变动,对上次调整改错名字的改成了正确的 10 months ago
lijikun 5b963fdb5d 12月18日调整logic层与service层名字,功能未变动,删除不属于这个分支的文件 10 months ago
lijikun 76445706a7 12月18日调整logic层与service层名字,功能未变动 10 months ago
lijikun 998efa5384 12月17日合并接口并调整修改问题 10 months ago
lijikun 41d621438b 12月17日添加redis配置 10 months ago
lijikun 424d513850 12月17日完成接口后合并(待从token中获取jwcode) 10 months ago
lijikun 1afa93687e 12月17日完成客户端作业提交 10 months ago
majun cd09845d5e 新增查询单个作业信息接口 10 months ago
lijikun 0d3c157f2e 12月17日完成后台查看明细页面所有接口 10 months ago
majun 48e1611422 解决Redis主页查询 10 months ago
majun 019af5b2dc 解决跨库查询 10 months ago
majun c9149a0058 完善数据库关联 10 months ago
majun 556af2d138 完善注释 10 months ago
majun 549af372ab 编辑作业接口完成 10 months ago
majun 7a745e5ed5 Merge remote-tracking branch 'origin/majun' into majun 10 months ago
majun 8450299cdc 新建作业接口完成 10 months ago
majun bf09c9569f 新建作业接口完成 10 months ago
lijikun d43da39151 Merge branch 'client_ljk' of http://39.101.133.168:8807/donghanyang/Link_Homework_Go into client_ljk 10 months ago
lijikun 642d8cac46 12月12日代码编写,后台获取明细请求体,响应体 10 months ago
lijikun 55fb5a16ef 12月12日代码编写,对客户端主页查询接口进行修改完善(函数名,提交次数),完成作业题目查询 10 months ago
majun b1d2ad1559 作业列表修改v2 10 months ago
lijikun 686f9370ba 12月11日客户端首页查询接口编写(未从token获取jwcode) 10 months ago
lijikun 940d3bfcab 12月11日客户端首页查询接口编写(未从token获取jwcode) 10 months ago
majun b51b9d038d 作业列表修改v1 10 months ago
majun 653e16ecc7 作业列表修改 10 months ago
majun 27d16b6d82 作业列表 10 months ago
  1. 38
      link_homework/api/v1/ClientPage/ClientPage.go
  2. 5
      link_homework/api/v1/article/article.go
  3. 1
      link_homework/api/v1/hello.go
  4. 36
      link_homework/api/v1/homework/homework.go
  5. 1
      link_homework/api/v1/homework/login.go
  6. 68
      link_homework/api/v1/record/Record.go
  7. 20
      link_homework/go.mod
  8. 109
      link_homework/go.sum
  9. 2
      link_homework/hack/config.yaml
  10. 57
      link_homework/internal/cmd/cmd.go
  11. 6
      link_homework/internal/consts/consts.go
  12. 36
      link_homework/internal/controller/article/article.go
  13. 56
      link_homework/internal/controller/auth/login.go
  14. 84
      link_homework/internal/controller/clientPage/clientPage.go
  15. 105
      link_homework/internal/controller/homework/homework.go
  16. 28
      link_homework/internal/controller/live/live.go
  17. 95
      link_homework/internal/controller/record/manageRecord.go
  18. 24
      link_homework/internal/dao/internal/activity_interactive_form.go
  19. 24
      link_homework/internal/dao/internal/activity_interactive_group.go
  20. 24
      link_homework/internal/dao/internal/activity_interactive_record.go
  21. 22
      link_homework/internal/dao/internal/fx_article.go
  22. 24
      link_homework/internal/dao/internal/live.go
  23. 22
      link_homework/internal/dao/internal/member_info.go
  24. 25
      link_homework/internal/logic/article/article.go
  25. 121
      link_homework/internal/logic/client/client.go
  26. 0
      link_homework/internal/logic/homework/.gitkeep
  27. 260
      link_homework/internal/logic/homework/homework.go
  28. 36
      link_homework/internal/logic/live/live.go
  29. 14
      link_homework/internal/logic/logic.go
  30. 76
      link_homework/internal/logic/login/login.go
  31. 43
      link_homework/internal/logic/middleware/JWTMiddleware.go
  32. 21
      link_homework/internal/logic/middleware/interceptor.go
  33. 256
      link_homework/internal/logic/record/record.go
  34. 31
      link_homework/internal/model/dto/Result.go
  35. 24
      link_homework/internal/model/dto/ToolStruct.go
  36. 24
      link_homework/internal/model/entity/activity_interactive_group.go
  37. 194
      link_homework/internal/model/entity/fx_article.go
  38. 172
      link_homework/internal/model/entity/live.go
  39. 32
      link_homework/internal/service/article.go
  40. 34
      link_homework/internal/service/client.go
  41. 37
      link_homework/internal/service/homework.go
  42. 32
      link_homework/internal/service/live.go
  43. 34
      link_homework/internal/service/login.go
  44. 8
      link_homework/internal/service/middleware.go
  45. 43
      link_homework/internal/service/record.go
  46. 36
      link_homework/main.go
  47. 17
      link_homework/manifest/config/config.yaml
  48. 8
      link_homework/manifest/deploy/kustomize/overlays/develop/configmap.yaml
  49. 142
      link_homework/utility/utility.go

38
link_homework/api/v1/ClientPage/ClientPage.go

@ -0,0 +1,38 @@
package ClientPage
import (
"github.com/gogf/gf/v2/os/gtime"
)
type GetHomeworkListRse struct {
Id int `json:"groupId" orm:"table:activity_interactive_group;column:id" dc:"id" `
Name string `json:"name" orm:"table:activity_interactive_group;column:name" dc:"作业题目"`
EndDate *gtime.Time `json:"endData" orm:"table:activity_interactive_group;column:end_date;time_format:yy-MM-dd" dc:"作业截止时间"`
Submit int `json:"submit"`
}
type GetHomeworkQuestionReq struct {
Id int `json:"id" dc:"作业id"`
}
type GetHomeworkQuestionRes struct {
Id int `json:"id" orm:"table:activity_interactive_form;column:id" dc:"题目id"`
Name string `json:"name" orm:"table:activity_interactive_form;column:name" dc:"作业名称"`
Description string `json:"description" orm:"table:activity_interactive_form;column:description" dc:"作业题目名字"`
Content string `json:"content" orm:"table:activity_interactive_form;column:content" dc:"题目内容"`
Status int `json:"status"`
Type int `json:"type" orm:"table:activity_interactive_form;column:type" dc:"题目类型"`
}
//需要id(group_id)(form表),查id,form.name是作业的题目,form.description是作业题目的名字,content, status,type
type CommitHomeworkReq struct {
GroupId int `json:"id" v:"required:#作业id不能为空" dc:"作业id"`
CommitedAnswer []CommitAnswer `json:"homework" dc:"传过来的答案"`
}
type CommitAnswer struct {
Id int `json:"id" orm:"table:activity_interactive_record;column:form_id" dc:"作业题目id"`
Answer []string `json:"answer" v:"required:#答案不能为空" dc:"作业答案,包含两部分,第一部分是题目,第二部分是答案,使用','分割的"`
Type int `json:"type" v:"required:#题目类型不能为空" dc:"题目类型,1:单选,2:多选,3:简答"`
}

5
link_homework/api/v1/article/article.go

@ -0,0 +1,5 @@
package article
type GetArticleListReq struct {
Name string `dc:"文章模糊查询名称"`
}

1
link_homework/api/v1/hello.go

@ -1 +0,0 @@
package v1

36
link_homework/api/v1/homework/homework.go

@ -0,0 +1,36 @@
package homework
import (
"github.com/gogf/gf/v2/os/gtime"
"link_homework/internal/model/entity"
)
type GetHomeworkListReq struct {
PageNo int `v:"required#页码不能为空" dc:"页码"`
PageSize int `v:"required#页面大小不能为空" dc:"页面大小"`
}
type GetHomeworkReq struct {
Id int `v:"required#作业id不能为空" dc:"作业id"`
}
type AddHomeworkReq struct {
Name string `v:"required#作业名称不能为空" dc:"作业名称"`
ClubType int `v:"required|min:1|max:9#作业归属不能为空|作业归属不存在|作业归属不存在" dc:"作业归属"`
ArticleId int `v:"required-without:LiveId|min:1#请选择关联的文章或直播|关联文章不存在" dc:"关联文章id"`
LiveId int `v:"required-without:ArticleId|min:1#请选择关联的文章或直播|关联直播不存在" dc:"关联直播id"`
StartDate *gtime.Time `v:"required#作业开始时间不能为空" dc:"作业开始时间"`
EndDate *gtime.Time `v:"required|after-equal:StartDate#作业结束时间不能为空|作业结束时间必须晚于作业开始时间" dc:"作业结束时间"`
Questions []*entity.ActivityInteractiveForm `v:"required#题目集不能为空" dc:"题目集"`
}
type EditHomeworkReq struct {
Id int `v:"required#作业id不能为空" dc:"作业id"`
Name string `v:"required#作业名称不能为空" dc:"作业名称"`
ClubType int `v:"required|min:1|max:9#作业所属不能为空|作业所属不存在|作业所属不存在" dc:"作业所属"`
ArticleId int `v:"required-without:LiveId|min:1#请选择关联的文章或直播|关联文章不存在" dc:"关联文章id"`
LiveId int `v:"required-without:ArticleId|min:1#请选择关联的文章或直播|关联直播不存在" dc:"关联直播id"`
StartDate *gtime.Time `v:"required#作业开始时间不能为空" dc:"作业开始时间"`
EndDate *gtime.Time `v:"required|after-equal:StartDate#作业结束时间不能为空|作业结束时间必须晚于作业开始时间" dc:"作业结束时间"`
Questions []*entity.ActivityInteractiveForm `v:"required#题目集不能为空" dc:"题目集"`
}

1
link_homework/api/v1/homework/login.go

@ -0,0 +1 @@
package homework

68
link_homework/api/v1/record/Record.go

@ -0,0 +1,68 @@
package record
import (
"github.com/gogf/gf/v2/os/gtime"
"link_homework/internal/model/dto"
)
type GetRecordListReq struct {
Id int `json:"id" orm:"" dc:"作业id"`
PageNo int `json:"pageNo" dc:"当前页"`
PageSize int `json:"pageSize" dc:"每页条数"`
}
// 合并并返回的提交详情所用信息
type GetRecordListRes struct {
Total int `json:"total" dc:"总条数"`
Jwcode int `json:"jwcode" orm:"db:cms;table:member_info;column:jwcode" dc:"精网号"`
Name string `json:"name" orm:"db:cms;table:member_info;column:name" dc:"用户名字"`
DeptId string `json:"deptId" orm:"db:cms;table:member_info;column:deptId" dc:"部门id"`
DeptName string `json:"deptName" orm:"db:cms;member_info;column:deptName" dc:"部门名"`
ShopId string `json:"shopId" orm:"db:cms;member_info;column:shopId" dc:"门店id"`
ShopName string `json:"shopName" orm:"db:cms;member_info;column:shopName" dc:"门店名"`
Reply []dto.RecordInfo
}
type GetRecordByConditionReq struct {
Id int `json:"id" orm:"" dc:"作业id"`
Jwcode int `json:"jwcode" dc:"精网号"`
DeptId string `json:"deptId" dc:"部门id"`
ShopId string `json:"shopId" dc:"门店id"`
PageNo int `json:"pageNo" dc:"当前页"`
PageSize int `json:"pageSize" dc:"每页条数"`
}
/*GetRecordByConditionRes的返回值与GetRecordListRes的一致,所以直接套用*/
type GetDeptInfoRes struct {
DeptId string `json:"deptId" orm:"db:cms;table:member_info;column:deptId" dc:"部门id"`
DeptName string `json:"deptName" orm:"db:cms;member_info;column:deptName" dc:"部门名"`
}
type GetShopInfoByDeptIdReq struct {
DeptId string `json:"deptId" dc:"部门id"`
}
type GetShopInfoByDeptIdRes struct {
ShopId string `json:"shopId" orm:"db:cms;table:member_info;column:shopId" dc:"门店id"`
ShopName string `json:"shopName" orm:"db:cms;member_info;column:shopName" dc:"门店名"`
}
type ExcelExportReq struct {
Jwcode int `json:"jwcode" dc:"精网号"`
Name string `json:"name" dc:"用户名字"`
DeptId string `json:"deptId" dc:"部门id"`
DeptName string `json:"deptName" dc:"部门名"`
ShopId string `json:"shopId" dc:"门店id"`
ShopName string `json:"shopName" dc:"门店名"`
Reply []Reply `json:"Reply" dc:"答案详情"`
}
type Reply struct {
FormId int `json:"formId" dc:"作业题目id"`
Type int `json:"type" dc:"作业类型"`
FormTitle string `json:"formTitle" dc:"作业题目名"`
ContentTitle string `json:"contentTitle" dc:"作答题目名"`
Content string `json:"content" dc:"作答内容"`
SubmitTime gtime.Time `json:"submitTime" dc:"提交时间"`
}

20
link_homework/go.mod

@ -3,34 +3,40 @@ module link_homework
go 1.21.13 go 1.21.13
require ( require (
github.com/360EntSecGroup-Skylar/excelize v1.4.1
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.8.1 github.com/gogf/gf/contrib/drivers/mysql/v2 v2.8.1
github.com/gogf/gf/contrib/nosql/redis/v2 v2.8.1
github.com/gogf/gf/v2 v2.8.1 github.com/gogf/gf/v2 v2.8.1
github.com/golang-jwt/jwt/v4 v4.5.1
) )
require ( require (
github.com/BurntSushi/toml v1.4.0 // indirect github.com/BurntSushi/toml v1.4.0 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/clbanning/mxj/v2 v2.7.0 // indirect github.com/clbanning/mxj/v2 v2.7.0 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/emirpasic/gods v1.18.1 // indirect github.com/emirpasic/gods v1.18.1 // indirect
github.com/fatih/color v1.17.0 // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-sql-driver/mysql v1.7.1 // indirect github.com/go-sql-driver/mysql v1.7.1 // indirect
github.com/goflyfox/gtoken v1.5.10 // indirect
github.com/gorilla/websocket v1.5.3 // indirect github.com/gorilla/websocket v1.5.3 // indirect
github.com/grokify/html-strip-tags-go v0.1.0 // indirect github.com/grokify/html-strip-tags-go v0.1.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/magiconair/properties v1.8.9 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/redis/go-redis/v9 v9.7.0 // indirect
github.com/rivo/uniseg v0.4.7 // indirect github.com/rivo/uniseg v0.4.7 // indirect
go.opentelemetry.io/otel v1.24.0 // indirect go.opentelemetry.io/otel v1.24.0 // indirect
go.opentelemetry.io/otel/metric v1.24.0 // indirect go.opentelemetry.io/otel/metric v1.24.0 // indirect
go.opentelemetry.io/otel/sdk v1.24.0 // indirect go.opentelemetry.io/otel/sdk v1.24.0 // indirect
go.opentelemetry.io/otel/trace v1.24.0 // indirect go.opentelemetry.io/otel/trace v1.24.0 // indirect
golang.org/x/net v0.27.0 // indirect
golang.org/x/sys v0.22.0 // indirect
golang.org/x/text v0.16.0 // indirect
golang.org/x/net v0.32.0 // indirect
golang.org/x/sys v0.28.0 // indirect
golang.org/x/text v0.21.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
) )

109
link_homework/go.sum

@ -1,134 +1,87 @@
github.com/BurntSushi/toml v1.2.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/360EntSecGroup-Skylar/excelize v1.4.1 h1:l55mJb6rkkaUzOpSsgEeKYtS6/0gHwBYyfo5Jcjv/Ks=
github.com/360EntSecGroup-Skylar/excelize v1.4.1/go.mod h1:vnax29X2usfl7HHkBrX5EvSCJcmH3dT9luvxzu8iGAE=
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/clbanning/mxj/v2 v2.7.0 h1:WA/La7UGCanFe5NpHF0Q3DNtnCsVoxbPKuyBNHWRyME= github.com/clbanning/mxj/v2 v2.7.0 h1:WA/La7UGCanFe5NpHF0Q3DNtnCsVoxbPKuyBNHWRyME=
github.com/clbanning/mxj/v2 v2.7.0/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s= github.com/clbanning/mxj/v2 v2.7.0/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s=
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 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4=
github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI=
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/goflyfox/gtoken v1.5.10 h1:oj/v5r/1TjMMZvxpyEZYdsEvG2ZK/SGGnyjvsKi4uHk=
github.com/goflyfox/gtoken v1.5.10/go.mod h1:YpoSAn9tbfrSBoQnY7raQP0HaiRjQAE+4J179ecRH5I=
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.8.1 h1:jbaPawkb8qmaYzrmBDbTa8Zkhzacq1RBOZw+qRJExI4= github.com/gogf/gf/contrib/drivers/mysql/v2 v2.8.1 h1:jbaPawkb8qmaYzrmBDbTa8Zkhzacq1RBOZw+qRJExI4=
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.8.1/go.mod h1:s2aI1fV9AvKi4NtMpv3pV0EHtazkvfUNVQmzapr7UJQ= github.com/gogf/gf/contrib/drivers/mysql/v2 v2.8.1/go.mod h1:s2aI1fV9AvKi4NtMpv3pV0EHtazkvfUNVQmzapr7UJQ=
github.com/gogf/gf/v2 v2.5.4/go.mod h1:7yf5qp0BznfsYx7Sw49m3mQvBsHpwAjJk3Q9ZnKoUEc=
github.com/gogf/gf/contrib/nosql/redis/v2 v2.8.1 h1:1vPFyN0GLv24JD3WGhvKzXvKG+fmuixDTawbtfzCzRQ=
github.com/gogf/gf/contrib/nosql/redis/v2 v2.8.1/go.mod h1:IWyGxzplp06tRc6Ah/eCLuBntnKSw9sn1maH0vzPPtw=
github.com/gogf/gf/v2 v2.8.1 h1:1oVQg3G5OgCats4qWFTH3pHLe92nfUQeUDta05tUs1g= github.com/gogf/gf/v2 v2.8.1 h1:1oVQg3G5OgCats4qWFTH3pHLe92nfUQeUDta05tUs1g=
github.com/gogf/gf/v2 v2.8.1/go.mod h1:6iYuZZ+A0ZcH8+4MDS/P0SvTPCvKzRvyAsY1kbkJYJc= github.com/gogf/gf/v2 v2.8.1/go.mod h1:6iYuZZ+A0ZcH8+4MDS/P0SvTPCvKzRvyAsY1kbkJYJc=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/golang-jwt/jwt/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo=
github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grokify/html-strip-tags-go v0.0.1/go.mod h1:2Su6romC5/1VXOQMaWL2yb618ARB8iVo6/DR99A6d78=
github.com/grokify/html-strip-tags-go v0.1.0 h1:03UrQLjAny8xci+R+qjCce/MYnpNXCtgzltlQbOBae4= github.com/grokify/html-strip-tags-go v0.1.0 h1:03UrQLjAny8xci+R+qjCce/MYnpNXCtgzltlQbOBae4=
github.com/grokify/html-strip-tags-go v0.1.0/go.mod h1:ZdzgfHEzAfz9X6Xe5eBLVblWIxXfYSQ40S/VKrAOGpc= github.com/grokify/html-strip-tags-go v0.1.0/go.mod h1:ZdzgfHEzAfz9X6Xe5eBLVblWIxXfYSQ40S/VKrAOGpc=
github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/magiconair/properties v1.8.9 h1:nWcCbLq1N2v/cpNsy5WvQ37Fb+YElfq20WJ/a8RkpQM=
github.com/magiconair/properties v1.8.9/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 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/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/redis/go-redis/v9 v9.7.0 h1:HhLSs+B6O021gwzl+locl0zEDnyNkxMtf/Z3NNBMa9E=
github.com/redis/go-redis/v9 v9.7.0/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93GewI7inzyWw=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
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.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.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.2.3-0.20181224173747-660f15d67dbb/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU=
go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo=
go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo=
go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI=
go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco=
go.opentelemetry.io/otel/sdk v1.14.0/go.mod h1:bwIC5TjrNG6QDCHNWvW4HLHtUQ4I+VQDsnjhvyZCALM=
go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucgoDw= go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucgoDw=
go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg= go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg=
go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8=
go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI=
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/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.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/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/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI=
golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/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.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
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/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

2
link_homework/hack/config.yaml

@ -5,7 +5,7 @@ gfcli:
gen: gen:
dao: dao:
- link: "mysql:live:p4jMAMShNM8HTrbX@tcp(39.101.133.168:3306)/live?charset=utf8mb4&parseTime=True&loc=Local" - link: "mysql:live:p4jMAMShNM8HTrbX@tcp(39.101.133.168:3306)/live?charset=utf8mb4&parseTime=True&loc=Local"
group: "live"
group: "default"
tables: "live, activity_interactive_form, activity_interactive_group, activity_interactive_record" tables: "live, activity_interactive_form, activity_interactive_group, activity_interactive_record"
descriptionTag: true descriptionTag: true
- link: "mysql:cms:AF42R3ib6YkFaemm@tcp(39.101.133.168:3306)/cms?charset=utf8mb4&parseTime=True&loc=Local" - link: "mysql:cms:AF42R3ib6YkFaemm@tcp(39.101.133.168:3306)/cms?charset=utf8mb4&parseTime=True&loc=Local"

57
link_homework/internal/cmd/cmd.go

@ -2,10 +2,16 @@ package cmd
import ( import (
"context" "context"
"github.com/goflyfox/gtoken/gtoken"
"github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp" "github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/os/gcmd" "github.com/gogf/gf/v2/os/gcmd"
"link_homework/internal/controller/article"
"link_homework/internal/controller/auth"
"link_homework/internal/controller/clientPage"
"link_homework/internal/controller/homework"
"link_homework/internal/controller/live"
"link_homework/internal/controller/record"
"link_homework/internal/logic/middleware"
) )
var ( var (
@ -16,33 +22,42 @@ var (
Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
s := g.Server() s := g.Server()
//后台 //后台
//启动gtoken
// 创建一个GfToken对象,用于处理用户登录、登出、权限验证等操作
gfToken := &gtoken.GfToken{
// 设置登录路径,即用户登录接口登入成功后会获得一个Token
LoginPath: "/login",
//// 设置登录前执行的函数,在用户登录之前会调用这个函数进行一些预处理,比如验证用户名和密码等。
//LoginBeforeFunc: loginFunc, //手动编写 没有同时配置登入路径,登入方法,登出路径启动时会报错
// 设置登出路径,即用户登出接口登入成功后会删除Token
LogoutPath: "/user/logout",
//// 设置需要拦截的路径,按照前缀拦截,所有以/user或/system开头的路径都需要进行Token认证。
//AuthPaths: g.SliceStr{"/user", "/system"},
//// 设置不需要拦截的路径,所有以/user/info或/system/user/开头的路径都不需要进行Token认证。
//AuthExcludePaths: g.SliceStr{"/user/info", "/system/user/*"},
//// 开启全局拦截,默认关闭,如果设置为true,则所有请求都会经过Token认证中间件,如果设置为false,则只有指定路径的请求会经过Token认证中间件。
//GlobalMiddleware: true,
}
s.Group("/api", func(group *ghttp.RouterGroup) {
// 登录接口
group.POST("/login", auth.NewLoginController().Login)
// 退出接口
group.POST("/logout", auth.NewLoginController().Logout)
})
s.Group("/api/homework_manage", func(group *ghttp.RouterGroup) { s.Group("/api/homework_manage", func(group *ghttp.RouterGroup) {
//group.Middleware(middleware.MiddlewareIsLogin)
gfToken.Middleware(ctx, group)
//group.Middleware(middleware.MiddlewareCORS)
group.Middleware(middleware.MiddlewareIsLogin)
//gfToken.Middleware(ctx, group)
//直接写接口,不用再分组 //直接写接口,不用再分组
group.POST("/getrecordlist", record.NewManageRecord().GetRecordList)
group.POST("/getrecordbycondition", record.NewManageRecord().GetRecordByCondition)
group.POST("/getdeptinfo", record.NewManageRecord().GetDeptInfo)
group.POST("/getshopinfo", record.NewManageRecord().GetShopInfo)
group.POST("/get-homework-list", homework.Homework().GetHomeworkList)
group.POST("/get-homework", homework.Homework().GetHomework)
group.POST("/add-homework", homework.Homework().AddHomework)
group.POST("/edit-homework", homework.Homework().EditHomework)
group.ALL("/get-article-list", article.Article().GetArticleList)
group.ALL("/get-live-list", live.Live().GetLiveList)
//导出excel
//group.ALL("/export-record", record.NewExportRecord().ExportRecordByCondition)
//group.POST("/exceleexport", record.NewManageRecord().ExeclExport)
group.ALL("export-record", record.NewManageRecord().ExportRecordByCondition)
}) })
//客户端 //客户端
s.Group("/api/homework_client", func(group *ghttp.RouterGroup) { s.Group("/api/homework_client", func(group *ghttp.RouterGroup) {
//group.Middleware(middleware.MiddlewareCORS)
//group.Middleware(middleware.MiddlewareIsLogin) //group.Middleware(middleware.MiddlewareIsLogin)
gfToken.Middleware(ctx, group)
group.Middleware(middleware.MiddlewareIsLoginClient)
//gfToken.Middleware(ctx, group)
//直接写接口,不用再分组 //直接写接口,不用再分组
group.POST("/gethomeworklist", clientPage.NewClientPage().GetHomeworkList)
group.POST("/gethomeworkquestion", clientPage.NewClientPage().GetHomeworkQuestion)
group.POST("/commithomework", clientPage.NewClientPage().CommitHomework)
}) })
s.Run() s.Run()

6
link_homework/internal/consts/consts.go

@ -1 +1,7 @@
package consts package consts
// Redis和其他配置常量
const (
URL_KEY = "jingwang:cms:env" // Redis中的键
URL_HASH_KEY = "HLJW_BASE_URL" // Redis中的hashKey
)

36
link_homework/internal/controller/article/article.go

@ -0,0 +1,36 @@
package article
import (
"github.com/gogf/gf/v2/net/ghttp"
"link_homework/api/v1/article"
"link_homework/internal/model/dto"
"link_homework/internal/service"
)
type cArticle struct{}
func Article() *cArticle {
return &cArticle{}
}
func (c cArticle) GetArticleList(r *ghttp.Request) {
var req *article.GetArticleListReq
if err := r.Parse(&req); err != nil {
r.Response.WriteJsonExit(dto.Result{
Code: 400,
Message: err.Error(),
})
}
res, err := service.Article().GetArticleList(r.Context(), req.Name)
if err != nil {
r.Response.WriteJsonExit(dto.Result{
Code: 400,
Message: err.Error(),
})
}
r.Response.WriteJsonExit(dto.Result{
Code: 200,
Message: "success",
Data: res,
})
}

56
link_homework/internal/controller/auth/login.go

@ -0,0 +1,56 @@
package auth
import (
"net/http"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
"link_homework/internal/model/dto"
"link_homework/internal/service"
)
type LoginController struct {
}
func NewLoginController() *LoginController {
return &LoginController{}
}
// 登录接口
func (c *LoginController) Login(r *ghttp.Request) {
var (
username = r.Get("username").String()
password = r.Get("password").String()
)
token, err := service.LoginLogic().Login(r.Context(), username, password)
if err != nil {
r.Response.WriteJsonExit(dto.Error(err.Error()))
}
r.Response.WriteJsonExit(dto.SuccessWithData(g.Map{
"token": token,
}))
}
// 退出接口
func (c *LoginController) Logout(r *ghttp.Request) {
// 获取请求中的 context
ctx := r.Context()
// 从请求头中获取 token
token := r.Header.Get("token")
if token == "" {
r.Response.WriteJsonExit(dto.ErrorWithCode(http.StatusUnauthorized, "Token 不能为空"))
}
// 校验 Token 是否有效
valid, err := service.LoginLogic().ValidateToken(ctx, token)
if err != nil || !valid {
r.Response.WriteJsonExit(dto.ErrorWithCode(http.StatusUnauthorized, "Token 无效"))
}
// 返回登出成功
r.Response.WriteJsonExit(dto.Success())
}

84
link_homework/internal/controller/clientPage/clientPage.go

@ -1 +1,85 @@
package clientPage package clientPage
import (
"github.com/gogf/gf/v2/net/ghttp"
CPage "link_homework/api/v1/ClientPage"
"link_homework/internal/model/dto"
"link_homework/internal/service"
"link_homework/utility"
)
type ClientPage struct{}
func NewClientPage() *ClientPage {
return &ClientPage{}
}
// 查询作业列表
func (c *ClientPage) GetHomeworkList(r *ghttp.Request) {
// 获取请求头中的token
token := r.Header.Get("token")
// 调用utility包中的GetJwcodeJSON函数,传入token,获取jwcode
jwcode, err := utility.GetJwcodeJSON(token)
// 如果出现错误,则返回错误信息
if err != nil {
r.Response.WriteJsonExit(dto.Error(err.Error()))
}
// 调用service包中的ClientGetHomeworkList函数,传入r.Context()和jwcode,获取作业列表
result, err := service.Client().ClientGetHomeworkList(r.Context(), jwcode)
// 如果出现错误,则返回错误信息
if err != nil {
r.Response.WriteJsonExit(dto.Error(err.Error()))
}
// 返回作业列表
r.Response.WriteJsonExit(dto.SuccessWithData(result))
}
// 查询题目列表
func (c *ClientPage) GetHomeworkQuestion(r *ghttp.Request) {
// 定义一个CPage.GetHomeworkQuestionReq类型的变量req
var req CPage.GetHomeworkQuestionReq
// 解析请求参数,将解析结果赋值给req
if err := r.Parse(&req); err != nil {
// 如果解析失败,返回错误信息
r.Response.WriteJsonExit(dto.Error(err.Error()))
}
// 调用service.Client().GetHomeworkQuestion方法,传入req.Id作为参数,获取作业题目
result, err := service.Client().GetHomeworkQuestion(r.Context(), req.Id)
// 如果获取作业题目失败,返回错误信息
if err != nil {
r.Response.WriteJsonExit(dto.Error(err.Error()))
}
// 如果获取的作业题目为空,返回错误信息
if result == nil {
r.Response.WriteJsonExit(dto.Error("该作业没有题目"))
}
// 返回作业题目
r.Response.WriteJsonExit(dto.SuccessWithData(result))
}
func (c *ClientPage) CommitHomework(r *ghttp.Request) {
// 获取请求头中的token
token := r.Request.Header.Get("token")
// 根据token获取jwcode
jwcode, err := utility.GetJwcodeJSON(token)
// 如果获取失败,返回错误信息
if err != nil {
r.Response.WriteJsonExit(dto.Error(err.Error()))
}
// 定义提交作业请求结构体
var req CPage.CommitHomeworkReq
// 解析请求参数
if err := r.Parse(&req); err != nil {
// 如果解析失败,返回错误信息
r.Response.WriteJsonExit(dto.Error(err.Error()))
}
// 调用服务提交作业
err = service.Client().CommitHomework(r.Context(), req, jwcode)
// 如果提交失败,返回错误信息
if err != nil {
r.Response.WriteJsonExit(dto.Error(err.Error()))
}
// 提交成功,返回成功信息
r.Response.WriteJsonExit(dto.SuccessWithMsg("提交作业成功"))
}

105
link_homework/internal/controller/homework/homework.go

@ -0,0 +1,105 @@
package homework
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
"link_homework/api/v1/homework"
"link_homework/internal/model/dto"
"link_homework/internal/service"
)
type cHomework struct{}
func Homework() *cHomework {
return &cHomework{}
}
func (c cHomework) GetHomeworkList(r *ghttp.Request) {
var req *homework.GetHomeworkListReq
if err := r.Parse(&req); err != nil {
r.Response.WriteJsonExit(dto.Result{
Code: 400,
Message: err.Error(),
})
}
res, err := service.Homework().GetHomeworkList(r.Context(), req.PageNo, req.PageSize)
total, err := service.Homework().GetHomeworkListTotal(r.Context())
if err != nil {
r.Response.WriteJsonExit(dto.Result{
Code: 400,
Message: err.Error(),
})
}
r.Response.WriteJsonExit(dto.Result{
Code: 200,
Message: "success",
Data: g.Map{
"list": res,
"total": total,
},
})
}
func (c cHomework) GetHomework(r *ghttp.Request) {
var req *homework.GetHomeworkReq
if err := r.Parse(&req); err != nil {
r.Response.WriteJsonExit(dto.Result{
Code: 400,
Message: err.Error(),
})
}
res, err := service.Homework().GetHomework(r.Context(), req.Id)
if err != nil {
r.Response.WriteJsonExit(dto.Result{
Code: 400,
Message: err.Error(),
})
}
r.Response.WriteJsonExit(dto.Result{
Code: 200,
Message: "success",
Data: res,
})
}
func (c cHomework) AddHomework(r *ghttp.Request) {
var req *homework.AddHomeworkReq
if err := r.Parse(&req); err != nil {
r.Response.WriteJsonExit(dto.Result{
Code: 400,
Message: err.Error(),
})
}
err := service.Homework().AddHomework(r.Context(), req)
if err != nil {
r.Response.WriteJsonExit(dto.Result{
Code: 400,
Message: err.Error(),
})
}
r.Response.WriteJsonExit(dto.Result{
Code: 200,
Message: "success",
})
}
func (c cHomework) EditHomework(r *ghttp.Request) {
var req *homework.EditHomeworkReq
if err := r.Parse(&req); err != nil {
r.Response.WriteJsonExit(dto.Result{
Code: 400,
Message: err.Error(),
})
}
err := service.Homework().EditHomework(r.Context(), req)
if err != nil {
r.Response.WriteJsonExit(dto.Result{
Code: 400,
Message: err.Error(),
})
}
r.Response.WriteJsonExit(dto.Result{
Code: 200,
Message: "success",
})
}

28
link_homework/internal/controller/live/live.go

@ -0,0 +1,28 @@
package live
import (
"github.com/gogf/gf/v2/net/ghttp"
"link_homework/internal/model/dto"
"link_homework/internal/service"
)
type cLive struct{}
func Live() *cLive {
return &cLive{}
}
func (c cLive) GetLiveList(r *ghttp.Request) {
res, err := service.Live().GetLiveList(r.Context())
if err != nil {
r.Response.WriteJsonExit(dto.Result{
Code: 400,
Message: err.Error(),
})
}
r.Response.WriteJsonExit(dto.Result{
Code: 200,
Message: "success",
Data: res,
})
}

95
link_homework/internal/controller/record/manageRecord.go

@ -0,0 +1,95 @@
package record
import (
"github.com/gogf/gf/v2/net/ghttp"
"link_homework/api/v1/record"
"link_homework/internal/model/dto"
"link_homework/internal/service"
)
type ManageRecord struct{}
func NewManageRecord() *ManageRecord {
return &ManageRecord{}
}
// 查询所有提交记录
func (m *ManageRecord) GetRecordList(r *ghttp.Request) {
// 定义一个record.GetRecordListReq类型的变量req
var req record.GetRecordListReq
// 解析请求参数,如果解析失败,则返回错误信息
if err := r.Parse(&req); err != nil {
r.Response.WriteJsonExit(dto.Error("参数解析失败: " + err.Error()))
}
// 调用service.Record().GetRecordList方法,获取记录列表,如果获取失败,则返回错误信息
result, err := service.Record().GetRecordList(r.Context(), req.Id, req.PageNo, req.PageSize)
if err != nil {
r.Response.WriteJsonExit(dto.Error(err.Error()))
}
// 返回成功信息,并附带记录列表
r.Response.WriteJsonExit(dto.SuccessWithData(result))
}
// 根据条件查询提交记录
func (m *ManageRecord) GetRecordByCondition(r *ghttp.Request) {
// 定义一个record.GetRecordByConditionReq类型的变量req
var req record.GetRecordByConditionReq
// 解析请求参数,将解析结果赋值给req
if err := r.Parse(&req); err != nil {
// 如果解析失败,返回错误信息
r.Response.WriteJsonExit(dto.Error(err.Error()))
}
// 调用service.Record().GetRecordByCondition方法,根据req中的参数查询记录
result, err := service.Record().GetRecordByCondition(r.Context(), req.Id, req.Jwcode, req.DeptId, req.ShopId, req.PageNo, req.PageSize)
// 如果查询失败,返回错误信息
if err != nil {
r.Response.WriteJsonExit(dto.Error(err.Error()))
}
// 如果查询结果为空,返回错误信息
if result == nil {
r.Response.WriteJsonExit(dto.Error("没有查询到记录"))
}
// 返回查询结果
r.Response.WriteJsonExit(dto.SuccessWithData(result))
}
// 查询用户部门信息
func (m *ManageRecord) GetDeptInfo(r *ghttp.Request) {
// 调用service.Record().GetDeptInfo()方法,获取部门信息
result, err := service.Record().GetDeptInfo(r.Context())
// 如果出现错误,则返回错误信息
if err != nil {
r.Response.WriteJsonExit(dto.Error(err.Error()))
}
// 如果没有错误,则返回成功信息
r.Response.WriteJsonExit(dto.SuccessWithData(result))
}
// 查询用户门店信息
func (m *ManageRecord) GetShopInfo(r *ghttp.Request) {
// 定义一个结构体变量req,用于存储请求参数
var req record.GetShopInfoByDeptIdReq
// 解析请求参数,如果解析失败,则返回错误信息
if err := r.Parse(&req); err != nil {
r.Response.WriteJsonExit(dto.Error(err.Error()))
}
// 调用service.Record().GetShopInfoByDeptId方法,根据部门ID获取店铺信息,如果获取失败,则返回错误信息
result, err := service.Record().GetShopInfoByDeptId(r.Context(), req.DeptId)
if err != nil {
r.Response.WriteJsonExit(dto.Error(err.Error()))
}
// 返回成功信息,包含获取到的店铺信息
r.Response.WriteJsonExit(dto.SuccessWithData(result))
}
// ExportRecordByCondition 导出记录
func (m *ManageRecord) ExportRecordByCondition(r *ghttp.Request) {
var req record.GetRecordByConditionReq
// 解析查询条件
if err := r.Parse(&req); err != nil {
r.Response.WriteJsonExit(dto.Error("参数解析失败: " + err.Error()))
return
}
//查询数据,创建excel文件,设置表头,写入数据,设置文件名,保存到缓冲区并返回,设置响应头,指定内容类型为excel文件,指定文件名为fileName,将buffer中的内容写入响应
service.Record().ExportExcel(r, req.Id, req.Jwcode, req.DeptId, req.ShopId, req.PageNo, req.PageSize)
}

24
link_homework/internal/dao/internal/activity_interactive_form.go

@ -11,14 +11,14 @@ import (
"github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/frame/g"
) )
// ActivityInteractiveFormDao is the data access object for the table activity_interactive_form.
// ActivityInteractiveFormDao is the data access object for table activity_interactive_form.
type ActivityInteractiveFormDao struct { type ActivityInteractiveFormDao struct {
table string // table is the underlying table name of the DAO. table string // table is the underlying table name of the DAO.
group string // group is the database configuration group name of the current DAO.
group string // group is the database configuration group name of current DAO.
columns ActivityInteractiveFormColumns // columns contains all the column names of Table for convenient usage. columns ActivityInteractiveFormColumns // columns contains all the column names of Table for convenient usage.
} }
// ActivityInteractiveFormColumns defines and stores column names for the table activity_interactive_form.
// ActivityInteractiveFormColumns defines and stores column names for table activity_interactive_form.
type ActivityInteractiveFormColumns struct { type ActivityInteractiveFormColumns struct {
Id string // Id string //
Name string // 名称 Name string // 名称
@ -32,7 +32,7 @@ type ActivityInteractiveFormColumns struct {
GroupId string // 问题分组id GroupId string // 问题分组id
} }
// activityInteractiveFormColumns holds the columns for the table activity_interactive_form.
// activityInteractiveFormColumns holds the columns for table activity_interactive_form.
var activityInteractiveFormColumns = ActivityInteractiveFormColumns{ var activityInteractiveFormColumns = ActivityInteractiveFormColumns{
Id: "id", Id: "id",
Name: "name", Name: "name",
@ -49,42 +49,42 @@ var activityInteractiveFormColumns = ActivityInteractiveFormColumns{
// NewActivityInteractiveFormDao creates and returns a new DAO object for table data access. // NewActivityInteractiveFormDao creates and returns a new DAO object for table data access.
func NewActivityInteractiveFormDao() *ActivityInteractiveFormDao { func NewActivityInteractiveFormDao() *ActivityInteractiveFormDao {
return &ActivityInteractiveFormDao{ return &ActivityInteractiveFormDao{
group: "live",
group: "default",
table: "activity_interactive_form", table: "activity_interactive_form",
columns: activityInteractiveFormColumns, columns: activityInteractiveFormColumns,
} }
} }
// DB retrieves and returns the underlying raw database management object of the current DAO.
// DB retrieves and returns the underlying raw database management object of current DAO.
func (dao *ActivityInteractiveFormDao) DB() gdb.DB { func (dao *ActivityInteractiveFormDao) DB() gdb.DB {
return g.DB(dao.group) return g.DB(dao.group)
} }
// Table returns the table name of the current DAO.
// Table returns the table name of current dao.
func (dao *ActivityInteractiveFormDao) Table() string { func (dao *ActivityInteractiveFormDao) Table() string {
return dao.table return dao.table
} }
// Columns returns all column names of the current DAO.
// Columns returns all column names of current dao.
func (dao *ActivityInteractiveFormDao) Columns() ActivityInteractiveFormColumns { func (dao *ActivityInteractiveFormDao) Columns() ActivityInteractiveFormColumns {
return dao.columns return dao.columns
} }
// Group returns the database configuration group name of the current DAO.
// Group returns the configuration group name of database of current dao.
func (dao *ActivityInteractiveFormDao) Group() string { func (dao *ActivityInteractiveFormDao) Group() string {
return dao.group return dao.group
} }
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
func (dao *ActivityInteractiveFormDao) Ctx(ctx context.Context) *gdb.Model { func (dao *ActivityInteractiveFormDao) Ctx(ctx context.Context) *gdb.Model {
return dao.DB().Model(dao.table).Safe().Ctx(ctx) return dao.DB().Model(dao.table).Safe().Ctx(ctx)
} }
// Transaction wraps the transaction logic using function f. // Transaction wraps the transaction logic using function f.
// It rolls back the transaction and returns the error if function f returns a non-nil error.
// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
// It commits the transaction and returns nil if function f returns nil. // It commits the transaction and returns nil if function f returns nil.
// //
// Note: Do not commit or roll back the transaction in function f,
// Note that, you should not Commit or Rollback the transaction in function f
// as it is automatically handled by this function. // as it is automatically handled by this function.
func (dao *ActivityInteractiveFormDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) { func (dao *ActivityInteractiveFormDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f) return dao.Ctx(ctx).Transaction(ctx, f)

24
link_homework/internal/dao/internal/activity_interactive_group.go

@ -11,14 +11,14 @@ import (
"github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/frame/g"
) )
// ActivityInteractiveGroupDao is the data access object for the table activity_interactive_group.
// ActivityInteractiveGroupDao is the data access object for table activity_interactive_group.
type ActivityInteractiveGroupDao struct { type ActivityInteractiveGroupDao struct {
table string // table is the underlying table name of the DAO. table string // table is the underlying table name of the DAO.
group string // group is the database configuration group name of the current DAO.
group string // group is the database configuration group name of current DAO.
columns ActivityInteractiveGroupColumns // columns contains all the column names of Table for convenient usage. columns ActivityInteractiveGroupColumns // columns contains all the column names of Table for convenient usage.
} }
// ActivityInteractiveGroupColumns defines and stores column names for the table activity_interactive_group.
// ActivityInteractiveGroupColumns defines and stores column names for table activity_interactive_group.
type ActivityInteractiveGroupColumns struct { type ActivityInteractiveGroupColumns struct {
Id string // Id string //
Name string // 表单名称 Name string // 表单名称
@ -32,7 +32,7 @@ type ActivityInteractiveGroupColumns struct {
EndDate string // 作业结束时间 EndDate string // 作业结束时间
} }
// activityInteractiveGroupColumns holds the columns for the table activity_interactive_group.
// activityInteractiveGroupColumns holds the columns for table activity_interactive_group.
var activityInteractiveGroupColumns = ActivityInteractiveGroupColumns{ var activityInteractiveGroupColumns = ActivityInteractiveGroupColumns{
Id: "id", Id: "id",
Name: "name", Name: "name",
@ -49,42 +49,42 @@ var activityInteractiveGroupColumns = ActivityInteractiveGroupColumns{
// NewActivityInteractiveGroupDao creates and returns a new DAO object for table data access. // NewActivityInteractiveGroupDao creates and returns a new DAO object for table data access.
func NewActivityInteractiveGroupDao() *ActivityInteractiveGroupDao { func NewActivityInteractiveGroupDao() *ActivityInteractiveGroupDao {
return &ActivityInteractiveGroupDao{ return &ActivityInteractiveGroupDao{
group: "live",
group: "default",
table: "activity_interactive_group", table: "activity_interactive_group",
columns: activityInteractiveGroupColumns, columns: activityInteractiveGroupColumns,
} }
} }
// DB retrieves and returns the underlying raw database management object of the current DAO.
// DB retrieves and returns the underlying raw database management object of current DAO.
func (dao *ActivityInteractiveGroupDao) DB() gdb.DB { func (dao *ActivityInteractiveGroupDao) DB() gdb.DB {
return g.DB(dao.group) return g.DB(dao.group)
} }
// Table returns the table name of the current DAO.
// Table returns the table name of current dao.
func (dao *ActivityInteractiveGroupDao) Table() string { func (dao *ActivityInteractiveGroupDao) Table() string {
return dao.table return dao.table
} }
// Columns returns all column names of the current DAO.
// Columns returns all column names of current dao.
func (dao *ActivityInteractiveGroupDao) Columns() ActivityInteractiveGroupColumns { func (dao *ActivityInteractiveGroupDao) Columns() ActivityInteractiveGroupColumns {
return dao.columns return dao.columns
} }
// Group returns the database configuration group name of the current DAO.
// Group returns the configuration group name of database of current dao.
func (dao *ActivityInteractiveGroupDao) Group() string { func (dao *ActivityInteractiveGroupDao) Group() string {
return dao.group return dao.group
} }
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
func (dao *ActivityInteractiveGroupDao) Ctx(ctx context.Context) *gdb.Model { func (dao *ActivityInteractiveGroupDao) Ctx(ctx context.Context) *gdb.Model {
return dao.DB().Model(dao.table).Safe().Ctx(ctx) return dao.DB().Model(dao.table).Safe().Ctx(ctx)
} }
// Transaction wraps the transaction logic using function f. // Transaction wraps the transaction logic using function f.
// It rolls back the transaction and returns the error if function f returns a non-nil error.
// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
// It commits the transaction and returns nil if function f returns nil. // It commits the transaction and returns nil if function f returns nil.
// //
// Note: Do not commit or roll back the transaction in function f,
// Note that, you should not Commit or Rollback the transaction in function f
// as it is automatically handled by this function. // as it is automatically handled by this function.
func (dao *ActivityInteractiveGroupDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) { func (dao *ActivityInteractiveGroupDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f) return dao.Ctx(ctx).Transaction(ctx, f)

24
link_homework/internal/dao/internal/activity_interactive_record.go

@ -11,14 +11,14 @@ import (
"github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/frame/g"
) )
// ActivityInteractiveRecordDao is the data access object for the table activity_interactive_record.
// ActivityInteractiveRecordDao is the data access object for table activity_interactive_record.
type ActivityInteractiveRecordDao struct { type ActivityInteractiveRecordDao struct {
table string // table is the underlying table name of the DAO. table string // table is the underlying table name of the DAO.
group string // group is the database configuration group name of the current DAO.
group string // group is the database configuration group name of current DAO.
columns ActivityInteractiveRecordColumns // columns contains all the column names of Table for convenient usage. columns ActivityInteractiveRecordColumns // columns contains all the column names of Table for convenient usage.
} }
// ActivityInteractiveRecordColumns defines and stores column names for the table activity_interactive_record.
// ActivityInteractiveRecordColumns defines and stores column names for table activity_interactive_record.
type ActivityInteractiveRecordColumns struct { type ActivityInteractiveRecordColumns struct {
Id string // Id string //
Jwcode string // Jwcode string //
@ -30,7 +30,7 @@ type ActivityInteractiveRecordColumns struct {
ContentTitle string // ContentTitle string //
} }
// activityInteractiveRecordColumns holds the columns for the table activity_interactive_record.
// activityInteractiveRecordColumns holds the columns for table activity_interactive_record.
var activityInteractiveRecordColumns = ActivityInteractiveRecordColumns{ var activityInteractiveRecordColumns = ActivityInteractiveRecordColumns{
Id: "id", Id: "id",
Jwcode: "jwcode", Jwcode: "jwcode",
@ -45,42 +45,42 @@ var activityInteractiveRecordColumns = ActivityInteractiveRecordColumns{
// NewActivityInteractiveRecordDao creates and returns a new DAO object for table data access. // NewActivityInteractiveRecordDao creates and returns a new DAO object for table data access.
func NewActivityInteractiveRecordDao() *ActivityInteractiveRecordDao { func NewActivityInteractiveRecordDao() *ActivityInteractiveRecordDao {
return &ActivityInteractiveRecordDao{ return &ActivityInteractiveRecordDao{
group: "live",
group: "default",
table: "activity_interactive_record", table: "activity_interactive_record",
columns: activityInteractiveRecordColumns, columns: activityInteractiveRecordColumns,
} }
} }
// DB retrieves and returns the underlying raw database management object of the current DAO.
// DB retrieves and returns the underlying raw database management object of current DAO.
func (dao *ActivityInteractiveRecordDao) DB() gdb.DB { func (dao *ActivityInteractiveRecordDao) DB() gdb.DB {
return g.DB(dao.group) return g.DB(dao.group)
} }
// Table returns the table name of the current DAO.
// Table returns the table name of current dao.
func (dao *ActivityInteractiveRecordDao) Table() string { func (dao *ActivityInteractiveRecordDao) Table() string {
return dao.table return dao.table
} }
// Columns returns all column names of the current DAO.
// Columns returns all column names of current dao.
func (dao *ActivityInteractiveRecordDao) Columns() ActivityInteractiveRecordColumns { func (dao *ActivityInteractiveRecordDao) Columns() ActivityInteractiveRecordColumns {
return dao.columns return dao.columns
} }
// Group returns the database configuration group name of the current DAO.
// Group returns the configuration group name of database of current dao.
func (dao *ActivityInteractiveRecordDao) Group() string { func (dao *ActivityInteractiveRecordDao) Group() string {
return dao.group return dao.group
} }
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
func (dao *ActivityInteractiveRecordDao) Ctx(ctx context.Context) *gdb.Model { func (dao *ActivityInteractiveRecordDao) Ctx(ctx context.Context) *gdb.Model {
return dao.DB().Model(dao.table).Safe().Ctx(ctx) return dao.DB().Model(dao.table).Safe().Ctx(ctx)
} }
// Transaction wraps the transaction logic using function f. // Transaction wraps the transaction logic using function f.
// It rolls back the transaction and returns the error if function f returns a non-nil error.
// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
// It commits the transaction and returns nil if function f returns nil. // It commits the transaction and returns nil if function f returns nil.
// //
// Note: Do not commit or roll back the transaction in function f,
// Note that, you should not Commit or Rollback the transaction in function f
// as it is automatically handled by this function. // as it is automatically handled by this function.
func (dao *ActivityInteractiveRecordDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) { func (dao *ActivityInteractiveRecordDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f) return dao.Ctx(ctx).Transaction(ctx, f)

22
link_homework/internal/dao/internal/fx_article.go

@ -11,14 +11,14 @@ import (
"github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/frame/g"
) )
// FxArticleDao is the data access object for the table fx_article.
// FxArticleDao is the data access object for table fx_article.
type FxArticleDao struct { type FxArticleDao struct {
table string // table is the underlying table name of the DAO. table string // table is the underlying table name of the DAO.
group string // group is the database configuration group name of the current DAO.
group string // group is the database configuration group name of current DAO.
columns FxArticleColumns // columns contains all the column names of Table for convenient usage. columns FxArticleColumns // columns contains all the column names of Table for convenient usage.
} }
// FxArticleColumns defines and stores column names for the table fx_article.
// FxArticleColumns defines and stores column names for table fx_article.
type FxArticleColumns struct { type FxArticleColumns struct {
Id string // Id string //
Title string // 标题 Title string // 标题
@ -117,7 +117,7 @@ type FxArticleColumns struct {
VideoType string // 视频类型 1 横屏 2 竖屏 VideoType string // 视频类型 1 横屏 2 竖屏
} }
// fxArticleColumns holds the columns for the table fx_article.
// fxArticleColumns holds the columns for table fx_article.
var fxArticleColumns = FxArticleColumns{ var fxArticleColumns = FxArticleColumns{
Id: "id", Id: "id",
Title: "title", Title: "title",
@ -225,36 +225,36 @@ func NewFxArticleDao() *FxArticleDao {
} }
} }
// DB retrieves and returns the underlying raw database management object of the current DAO.
// DB retrieves and returns the underlying raw database management object of current DAO.
func (dao *FxArticleDao) DB() gdb.DB { func (dao *FxArticleDao) DB() gdb.DB {
return g.DB(dao.group) return g.DB(dao.group)
} }
// Table returns the table name of the current DAO.
// Table returns the table name of current dao.
func (dao *FxArticleDao) Table() string { func (dao *FxArticleDao) Table() string {
return dao.table return dao.table
} }
// Columns returns all column names of the current DAO.
// Columns returns all column names of current dao.
func (dao *FxArticleDao) Columns() FxArticleColumns { func (dao *FxArticleDao) Columns() FxArticleColumns {
return dao.columns return dao.columns
} }
// Group returns the database configuration group name of the current DAO.
// Group returns the configuration group name of database of current dao.
func (dao *FxArticleDao) Group() string { func (dao *FxArticleDao) Group() string {
return dao.group return dao.group
} }
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
func (dao *FxArticleDao) Ctx(ctx context.Context) *gdb.Model { func (dao *FxArticleDao) Ctx(ctx context.Context) *gdb.Model {
return dao.DB().Model(dao.table).Safe().Ctx(ctx) return dao.DB().Model(dao.table).Safe().Ctx(ctx)
} }
// Transaction wraps the transaction logic using function f. // Transaction wraps the transaction logic using function f.
// It rolls back the transaction and returns the error if function f returns a non-nil error.
// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
// It commits the transaction and returns nil if function f returns nil. // It commits the transaction and returns nil if function f returns nil.
// //
// Note: Do not commit or roll back the transaction in function f,
// Note that, you should not Commit or Rollback the transaction in function f
// as it is automatically handled by this function. // as it is automatically handled by this function.
func (dao *FxArticleDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) { func (dao *FxArticleDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f) return dao.Ctx(ctx).Transaction(ctx, f)

24
link_homework/internal/dao/internal/live.go

@ -11,14 +11,14 @@ import (
"github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/frame/g"
) )
// LiveDao is the data access object for the table live.
// LiveDao is the data access object for table live.
type LiveDao struct { type LiveDao struct {
table string // table is the underlying table name of the DAO. table string // table is the underlying table name of the DAO.
group string // group is the database configuration group name of the current DAO.
group string // group is the database configuration group name of current DAO.
columns LiveColumns // columns contains all the column names of Table for convenient usage. columns LiveColumns // columns contains all the column names of Table for convenient usage.
} }
// LiveColumns defines and stores column names for the table live.
// LiveColumns defines and stores column names for table live.
type LiveColumns struct { type LiveColumns struct {
Id string // Id string //
Jwcode string // Jwcode string //
@ -106,7 +106,7 @@ type LiveColumns struct {
JoinClassButton string // 进群按钮 1:开启 JoinClassButton string // 进群按钮 1:开启
} }
// liveColumns holds the columns for the table live.
// liveColumns holds the columns for table live.
var liveColumns = LiveColumns{ var liveColumns = LiveColumns{
Id: "id", Id: "id",
Jwcode: "jwcode", Jwcode: "jwcode",
@ -197,42 +197,42 @@ var liveColumns = LiveColumns{
// NewLiveDao creates and returns a new DAO object for table data access. // NewLiveDao creates and returns a new DAO object for table data access.
func NewLiveDao() *LiveDao { func NewLiveDao() *LiveDao {
return &LiveDao{ return &LiveDao{
group: "live",
group: "default",
table: "live", table: "live",
columns: liveColumns, columns: liveColumns,
} }
} }
// DB retrieves and returns the underlying raw database management object of the current DAO.
// DB retrieves and returns the underlying raw database management object of current DAO.
func (dao *LiveDao) DB() gdb.DB { func (dao *LiveDao) DB() gdb.DB {
return g.DB(dao.group) return g.DB(dao.group)
} }
// Table returns the table name of the current DAO.
// Table returns the table name of current dao.
func (dao *LiveDao) Table() string { func (dao *LiveDao) Table() string {
return dao.table return dao.table
} }
// Columns returns all column names of the current DAO.
// Columns returns all column names of current dao.
func (dao *LiveDao) Columns() LiveColumns { func (dao *LiveDao) Columns() LiveColumns {
return dao.columns return dao.columns
} }
// Group returns the database configuration group name of the current DAO.
// Group returns the configuration group name of database of current dao.
func (dao *LiveDao) Group() string { func (dao *LiveDao) Group() string {
return dao.group return dao.group
} }
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
func (dao *LiveDao) Ctx(ctx context.Context) *gdb.Model { func (dao *LiveDao) Ctx(ctx context.Context) *gdb.Model {
return dao.DB().Model(dao.table).Safe().Ctx(ctx) return dao.DB().Model(dao.table).Safe().Ctx(ctx)
} }
// Transaction wraps the transaction logic using function f. // Transaction wraps the transaction logic using function f.
// It rolls back the transaction and returns the error if function f returns a non-nil error.
// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
// It commits the transaction and returns nil if function f returns nil. // It commits the transaction and returns nil if function f returns nil.
// //
// Note: Do not commit or roll back the transaction in function f,
// Note that, you should not Commit or Rollback the transaction in function f
// as it is automatically handled by this function. // as it is automatically handled by this function.
func (dao *LiveDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) { func (dao *LiveDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f) return dao.Ctx(ctx).Transaction(ctx, f)

22
link_homework/internal/dao/internal/member_info.go

@ -11,14 +11,14 @@ import (
"github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/frame/g"
) )
// MemberInfoDao is the data access object for the table member_info.
// MemberInfoDao is the data access object for table member_info.
type MemberInfoDao struct { type MemberInfoDao struct {
table string // table is the underlying table name of the DAO. table string // table is the underlying table name of the DAO.
group string // group is the database configuration group name of the current DAO.
group string // group is the database configuration group name of current DAO.
columns MemberInfoColumns // columns contains all the column names of Table for convenient usage. columns MemberInfoColumns // columns contains all the column names of Table for convenient usage.
} }
// MemberInfoColumns defines and stores column names for the table member_info.
// MemberInfoColumns defines and stores column names for table member_info.
type MemberInfoColumns struct { type MemberInfoColumns struct {
Id string // Id string //
Jwcode string // Jwcode string //
@ -60,7 +60,7 @@ type MemberInfoColumns struct {
CreateTime string // 账号注册时间 CreateTime string // 账号注册时间
} }
// memberInfoColumns holds the columns for the table member_info.
// memberInfoColumns holds the columns for table member_info.
var memberInfoColumns = MemberInfoColumns{ var memberInfoColumns = MemberInfoColumns{
Id: "id", Id: "id",
Jwcode: "jwcode", Jwcode: "jwcode",
@ -111,36 +111,36 @@ func NewMemberInfoDao() *MemberInfoDao {
} }
} }
// DB retrieves and returns the underlying raw database management object of the current DAO.
// DB retrieves and returns the underlying raw database management object of current DAO.
func (dao *MemberInfoDao) DB() gdb.DB { func (dao *MemberInfoDao) DB() gdb.DB {
return g.DB(dao.group) return g.DB(dao.group)
} }
// Table returns the table name of the current DAO.
// Table returns the table name of current dao.
func (dao *MemberInfoDao) Table() string { func (dao *MemberInfoDao) Table() string {
return dao.table return dao.table
} }
// Columns returns all column names of the current DAO.
// Columns returns all column names of current dao.
func (dao *MemberInfoDao) Columns() MemberInfoColumns { func (dao *MemberInfoDao) Columns() MemberInfoColumns {
return dao.columns return dao.columns
} }
// Group returns the database configuration group name of the current DAO.
// Group returns the configuration group name of database of current dao.
func (dao *MemberInfoDao) Group() string { func (dao *MemberInfoDao) Group() string {
return dao.group return dao.group
} }
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
func (dao *MemberInfoDao) Ctx(ctx context.Context) *gdb.Model { func (dao *MemberInfoDao) Ctx(ctx context.Context) *gdb.Model {
return dao.DB().Model(dao.table).Safe().Ctx(ctx) return dao.DB().Model(dao.table).Safe().Ctx(ctx)
} }
// Transaction wraps the transaction logic using function f. // Transaction wraps the transaction logic using function f.
// It rolls back the transaction and returns the error if function f returns a non-nil error.
// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
// It commits the transaction and returns nil if function f returns nil. // It commits the transaction and returns nil if function f returns nil.
// //
// Note: Do not commit or roll back the transaction in function f,
// Note that, you should not Commit or Rollback the transaction in function f
// as it is automatically handled by this function. // as it is automatically handled by this function.
func (dao *MemberInfoDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) { func (dao *MemberInfoDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f) return dao.Ctx(ctx).Transaction(ctx, f)

25
link_homework/internal/logic/article/article.go

@ -0,0 +1,25 @@
package article
import (
"context"
"link_homework/internal/dao"
"link_homework/internal/model/entity"
"link_homework/internal/service"
)
type (
sArticle struct{}
)
func init() {
service.RegisterArticle(New())
}
func New() service.IArticle {
return &sArticle{}
}
func (s *sArticle) GetArticleList(ctx context.Context, name string) (articleList []*entity.FxArticle, err error) {
err = dao.FxArticle.Ctx(ctx).Where("title like ?", "%"+name+"%").OrderDesc("update_time").Limit(8).Scan(&articleList)
return
}

121
link_homework/internal/logic/client/client.go

@ -0,0 +1,121 @@
package client
import (
"context"
"encoding/json"
"errors"
"fmt"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
"link_homework/api/v1/ClientPage"
"link_homework/internal/dao"
"link_homework/internal/service"
)
type sClient struct{}
func init() {
service.RegisterClient(&sClient{})
}
func (s *sClient) ClientGetHomeworkList(ctx context.Context, jwcode int) (homeworkList []ClientPage.GetHomeworkListRse, err error) {
// 从Redis中获取数据
value, _ := g.Redis().Get(ctx, fmt.Sprintf("%d ClientHomeworkList", jwcode)) //从Redis中获取ClientHomeworkList的值
if value.String() != "" { //如果值不为空
err = json.Unmarshal(value.Bytes(), &homeworkList) //JSON -> Go数据结构
if err != nil { //如果解析失败
return nil, errors.New("从Redis获取数据,JSON解析失败") //返回错误信息
}
return
}
// 如果Redis中没有数据,查询数据库
// 查询活动互动组表,根据条件查询id、name、end_date字段,并按照end_date降序排列
err = dao.ActivityInteractiveGroup.Ctx(ctx).Fields("id", "name", "DATE_FORMAT(end_date, '%Y-%m-%d') as end_date").
Where("end_date>?", gtime.Now()).Where("status", 1).OrderDesc("end_date").Scan(&homeworkList)
if err != nil {
return
}
//计算提交次数
for i, item := range homeworkList {
result, _ := dao.ActivityInteractiveRecord.Ctx(ctx).Where("group_id", item.Id).Where("jwcode", jwcode).
Group("form_id").Limit(1).Value("COUNT(*)")
homeworkList[i].Submit = result.Int()
}
// 将查询结果JSON化并存入Redis
ClientHomeworkListJSON, _ := json.Marshal(homeworkList)
_, err = g.Redis().Set(ctx, "ClientHomeworkList", ClientHomeworkListJSON)
if err != nil {
return nil, errors.New("Redis存储失败")
}
return
}
func (s *sClient) GetHomeworkQuestion(ctx context.Context, groupId int) (questions []ClientPage.GetHomeworkQuestionRes, err error) {
// 从Redis中获取数据
value, _ := g.Redis().Get(ctx, fmt.Sprintf("%d HomeworkQuestions", groupId))
if value.String() != "" {
err = json.Unmarshal(value.Bytes(), &questions) //JSON -> Go数据结构
if err != nil {
return nil, errors.New("从Redis获取数据,JSON解析失败")
}
return
}
// 如果Redis中没有数据,查询数据库
err = dao.ActivityInteractiveForm.Ctx(ctx).Fields("id", "name", "content", "status", "type", "description").
Where("group_id", groupId).Scan(&questions)
// 将查询结果JSON化并存入Redis
HomeworkQuestionsJSON, _ := json.Marshal(questions)
_, err = g.Redis().Set(ctx, fmt.Sprintf("%d HomeworkQuestions", groupId), HomeworkQuestionsJSON)
return
}
func (s *sClient) CommitHomework(ctx context.Context, req ClientPage.CommitHomeworkReq, jwcode int) (err error) {
//req中需要有:作业id,提交的每一个题的答案,每一个提的类型
for _, answer := range req.CommitedAnswer {
if answer.Type == 1 { //单选或者多选
// 插入单选或者多选答案
_, err := dao.ActivityInteractiveRecord.Ctx(ctx).Data(g.Map{
"jwcode": jwcode, // 问卷编号
"form_id": answer.Id, // 答案编号
"group_id": req.GroupId, // 组编号
"content": answer.Answer[0], // 答案内容
}).Insert()
if err != nil {
return err
}
} else if answer.Type == 2 { //多选
// 插入多选答案
_, err := dao.ActivityInteractiveRecord.Ctx(ctx).Data(g.Map{
"jwcode": jwcode, // 问卷编号
"form_id": answer.Id, // 答案编号
"group_id": req.GroupId, // 组编号
"content": answer.Answer, // 答案内容
}).Insert()
if err != nil {
return err
}
} else if answer.Type == 3 { //简答
// 插入简答答案
_, err := dao.ActivityInteractiveRecord.Ctx(ctx).Data(g.Map{
"jwcode": jwcode, // 问卷编号
"form_id": answer.Id, // 答案编号
"group_id": req.GroupId, // 组编号
"content_title": answer.Answer[0], // 答案标题
"content": answer.Answer[1], // 答案内容
}).Insert()
if err != nil {
return err
}
}
}
key, _ := g.Redis().Keys(ctx, fmt.Sprintf("%d ClientHomeworkList", jwcode))
if len(key) > 0 {
_, _ = g.Redis().Del(ctx, key...)
}
return
}

0
link_homework/internal/logic/homework/.gitkeep

260
link_homework/internal/logic/homework/homework.go

@ -0,0 +1,260 @@
package homework
import (
"context"
"encoding/json"
"fmt"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
"link_homework/api/v1/homework"
"link_homework/internal/dao"
"link_homework/internal/model/do"
"link_homework/internal/model/entity"
"link_homework/internal/service"
)
type (
sHomework struct{}
)
func init() {
service.RegisterHomework(New())
}
func New() service.IHomework {
return &sHomework{}
}
func (s *sHomework) GetHomeworkList(ctx context.Context, pageNo int, pageSize int) (homeworkList []*entity.ActivityInteractiveGroup, err error) {
// 从Redis中获取数据
value, _ := g.Redis().Get(ctx, fmt.Sprintf("%d-%d homeworklist", pageNo, pageSize))
if value.String() != "" {
// 如果Redis中有数据,尝试解析为ActivityInteractiveGroup列表
err = json.Unmarshal(value.Bytes(), &homeworkList) //反序列化
homeworklist, cnt := UpdateHomework(ctx, homeworkList)
if cnt > 0 {
// 将修改后的作业列表序列化并存储到Redis,更新频繁变更的数据
homeworkListJson, _ := json.Marshal(homeworklist)
_, err = g.Redis().Set(ctx, fmt.Sprintf("%d-%d homeworklist", pageNo, pageSize), homeworkListJson)
}
if err != nil {
return nil, err
}
return homeworklist, err
}
// 如果Redis中没有数据,查询数据库
err = dao.ActivityInteractiveGroup.Ctx(ctx).With(entity.Live{}).OrderDesc("created_at").Page(pageNo, pageSize).Scan(&homeworkList)
err = g.DB("cms").Model("fx_article").Where("id", gdb.ListItemValuesUnique(homeworkList, "ArticleId")).ScanList(&homeworkList, "Article", "id:ArticleId")
homeworkList = InitHomework(ctx, homeworkList)
homeworkList, _ = UpdateHomework(ctx, homeworkList)
if err != nil {
return nil, err
}
// 将查询到的作业列表序列化并存储到Redis,更新频繁变更的数据
homeworkListJson, _ := json.Marshal(homeworkList)
_, err = g.Redis().Set(ctx, fmt.Sprintf("%d-%d homeworklist", pageNo, pageSize), homeworkListJson)
return
}
func UpdateHomework(ctx context.Context, homeworkList []*entity.ActivityInteractiveGroup) ([]*entity.ActivityInteractiveGroup, int) {
cnt := 0
for _, v := range homeworkList {
if v.Status != 2 {
if v.StartDate.After(gtime.Now()) {
v.Status = 0
} else if v.EndDate.Before(gtime.Now().AddDate(0, 0, -1)) {
v.Status = 2
cnt++
_, _ = dao.ActivityInteractiveGroup.Ctx(ctx).Data(do.ActivityInteractiveGroup{
Status: 2,
}).WherePri(v.Id).Update()
} else {
v.Status = 1
}
if v.Status != 0 {
result, _ := dao.ActivityInteractiveRecord.Ctx(ctx).Where("group_id", v.Id).Group("form_id").Limit(1).Value("COUNT(*)")
v.Count = result.Int()
}
}
}
return homeworkList, cnt
}
func InitHomework(ctx context.Context, homeworkList []*entity.ActivityInteractiveGroup) []*entity.ActivityInteractiveGroup {
for _, v := range homeworkList {
if v.Status == 2 {
if v.Status != 0 {
result, _ := dao.ActivityInteractiveRecord.Ctx(ctx).Where("group_id", v.Id).Group("form_id").Limit(1).Value("COUNT(*)")
v.Count = result.Int()
}
}
}
return homeworkList
}
func (s *sHomework) GetHomeworkListTotal(ctx context.Context) (total int, err error) {
total, err = dao.ActivityInteractiveGroup.Ctx(ctx).Count()
if err != nil {
return 0, err
}
return
}
func (s *sHomework) GetHomework(ctx context.Context, id int) (homework *entity.ActivityInteractiveGroup, err error) {
err = dao.ActivityInteractiveGroup.Ctx(ctx).Where("id", id).With(entity.Live{}, entity.ActivityInteractiveForm{}).Scan(&homework)
err = g.DB("cms").Model("fx_article").Where("id", homework.ArticleId).Scan(&homework.Article)
return
}
func (s *sHomework) AddHomework(ctx context.Context, req *homework.AddHomeworkReq) (err error) {
// 判断作业是否已结束
status := 0
if req.StartDate.Before(gtime.Now()) {
if req.EndDate.Before(gtime.Now().AddDate(0, 0, -1)) {
return fmt.Errorf("作业时间已过期,无法添加!")
} else {
status = 1
}
}
var Id int64
if req.ArticleId == 0 { // 关联文章
Id, err = dao.ActivityInteractiveGroup.Ctx(ctx).Data(do.ActivityInteractiveGroup{
Name: req.Name,
Status: status,
ClubType: req.ClubType,
LiveId: req.LiveId,
StartDate: req.StartDate,
EndDate: req.EndDate,
}).InsertAndGetId()
} else if req.LiveId == 0 { // 关联直播
Id, err = dao.ActivityInteractiveGroup.Ctx(ctx).Data(do.ActivityInteractiveGroup{
Name: req.Name,
Status: status,
ClubType: req.ClubType,
ArticleId: req.ArticleId,
StartDate: req.StartDate,
EndDate: req.EndDate,
}).InsertAndGetId()
} else {
return fmt.Errorf("不能同时关联文章和直播!")
}
// 添加所有题目
for _, v := range req.Questions {
_, err = dao.ActivityInteractiveForm.Ctx(ctx).Data(do.ActivityInteractiveForm{
Name: req.Name,
Description: v.Description,
Content: v.Content,
Status: status,
Type: v.Type,
GroupId: Id,
}).Insert()
}
// 添加数据后,删除所有缓存
keys, err := g.Redis().Keys(ctx, "*-* homeworklist")
if len(keys) > 0 {
_, err = g.Redis().Del(ctx, keys...)
}
//删除客户端缓存
keys, err = g.Redis().Keys(ctx, "* ClientHomeworkList")
if len(keys) > 0 {
_, err = g.Redis().Del(ctx, keys...)
}
return
}
func (s *sHomework) EditHomework(ctx context.Context, req *homework.EditHomeworkReq) (err error) {
// 判断作业是否已结束
var nowhomework *entity.ActivityInteractiveGroup
err = dao.ActivityInteractiveGroup.Ctx(ctx).WherePri(req.Id).Scan(&nowhomework)
if nowhomework.EndDate.Before(gtime.Now()) {
return fmt.Errorf("作业已结束,无法修改!")
} else {
// 判断作业是否已开始
flag := true
if nowhomework.StartDate.Before(gtime.Now()) {
flag = false
}
// 判断提交修改表单状态
status := 0
if req.StartDate.Before(gtime.Now()) {
if req.EndDate.Before(gtime.Now()) {
status = 2
} else {
status = 1
}
}
// 判断是否关联文章或直播
if req.ArticleId == 0 {
_, err = g.Model("activity_interactive_group").Data(g.Map{
"name": req.Name,
"status": status,
"club_type": req.ClubType,
"article_id": nil,
"live_id": req.LiveId,
"start_date": req.StartDate,
"end_date": req.EndDate,
}).WherePri(req.Id).Update()
} else if req.LiveId == 0 {
_, err = g.Model("activity_interactive_group").Data(g.Map{
"name": req.Name,
"status": status,
"club_type": req.ClubType,
"article_id": req.ArticleId,
"live_id": nil,
"start_date": req.StartDate,
"end_date": req.EndDate,
}).WherePri(req.Id).Update()
} else {
return fmt.Errorf("不能同时关联文章和直播!")
}
if flag { // 未开始
_, err = dao.ActivityInteractiveForm.Ctx(ctx).Where("group_id", req.Id).Delete()
for _, v := range req.Questions {
_, err = dao.ActivityInteractiveForm.Ctx(ctx).Data(do.ActivityInteractiveForm{
Name: req.Name,
Description: v.Description,
Content: v.Content,
Status: status,
Type: v.Type,
GroupId: req.Id,
}).Insert()
}
} else { // 已开始
for _, v := range req.Questions {
_, err = dao.ActivityInteractiveForm.Ctx(ctx).Data(do.ActivityInteractiveForm{
Name: req.Name,
Description: v.Description,
Content: v.Content,
Status: status,
}).WherePri(v.Id).Update()
}
}
// 修改数据后,删除所有缓存
keys, _ := g.Redis().Keys(ctx, "*-* homeworklist")
if len(keys) > 0 {
_, _ = g.Redis().Del(ctx, keys...)
}
//删除客户端缓存
keys, err = g.Redis().Keys(ctx, "* ClientHomeworkList")
if len(keys) > 0 {
_, err = g.Redis().Del(ctx, keys...)
}
keys, err = g.Redis().Keys(ctx, "* HomeworkQuestions")
if len(keys) > 0 {
_, err = g.Redis().Del(ctx, keys...)
}
return
}
}

36
link_homework/internal/logic/live/live.go

@ -0,0 +1,36 @@
package live
import (
"context"
"link_homework/internal/dao"
"link_homework/internal/model/entity"
"link_homework/internal/service"
"time"
)
type (
sLive struct{}
)
func init() {
service.RegisterLive(New())
}
func New() service.ILive {
return &sLive{}
}
func (s *sLive) GetLiveList(ctx context.Context) (liveList []*entity.Live, err error) {
// 获取当前时间
now := time.Now()
// 获取当天时间的0点
now = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
// 计算时间范围
startTime := now.AddDate(0, 0, -1).Unix()
endTime := now.AddDate(0, 0, 8).Unix()
err = dao.Live.Ctx(ctx).Where("start_time >= ? and start_time < ?", startTime, endTime).OrderAsc("start_time").Scan(&liveList)
return
}

14
link_homework/internal/logic/logic.go

@ -1 +1,15 @@
// ==========================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package logic package logic
import (
_ "link_homework/internal/logic/article"
_ "link_homework/internal/logic/client"
_ "link_homework/internal/logic/homework"
_ "link_homework/internal/logic/live"
_ "link_homework/internal/logic/login"
_ "link_homework/internal/logic/middleware"
_ "link_homework/internal/logic/record"
)

76
link_homework/internal/logic/login/login.go

@ -0,0 +1,76 @@
package login
import (
"context"
"errors"
"time"
"github.com/golang-jwt/jwt/v4"
"link_homework/internal/service"
)
type sLoginLogic struct{}
var (
SecretKey = []byte("HomilyLink") // 用于签名和验证 JWT 的密钥
)
// 自定义声明结构
type CustomClaims struct {
Username string `json:"username"`
jwt.RegisteredClaims
}
func NewLoginLogic() *sLoginLogic {
return &sLoginLogic{}
}
// 确保在初始化时注册该实现
func init() {
service.RegisterLoginLogic(&sLoginLogic{})
}
// Login 方法实现用户登录并生成 Token
func (l *sLoginLogic) Login(ctx context.Context, username, password string) (string, error) {
if username != "admin" || password != "12345" {
return "", errors.New("用户名或密码错误")
}
// 创建 JWT Token
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"username": username,
"exp": time.Now().Add(time.Hour * 8).Unix(), // 8 小时后过期
})
// 签名并获取完整的编码后的字符串 token
tokenString, err := token.SignedString(SecretKey)
if err != nil {
return "", err
}
return tokenString, nil
}
// ValidateToken 验证 Token 是否有效
func (l *sLoginLogic) ValidateToken(ctx context.Context, tokenString string) (bool, error) {
// 解析 token
token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) {
return SecretKey, nil
})
if err != nil {
return false, errors.New("Token 无效: " + err.Error())
}
// 如果 token 有效,返回 true
if token.Valid {
// 提取 CustomClaims 并打印 username
//if claims, ok := token.Claims.(*CustomClaims); ok {
// log.Printf("解析到的用户名: %s", claims.Username) // 打印解析到的用户名
//}
return true, nil
}
// 如果 token 无效
return false, errors.New("Token 验证失败")
}

43
link_homework/internal/logic/middleware/JWTMiddleware.go

@ -0,0 +1,43 @@
package middleware
import (
"link_homework/internal/logic/login"
"net/http"
"strings"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/golang-jwt/jwt/v4"
)
// JWT 验证中间件
func JWTMiddleware(r *ghttp.Request) {
// 从请求头中获取 token
authHeader := r.Header.Get("Authorization")
if authHeader == "" {
r.Response.WriteStatusExit(http.StatusUnauthorized, "Authorization header missing")
}
// 检查 token 前缀
parts := strings.SplitN(authHeader, " ", 2)
if len(parts) != 2 || parts[0] != "Bearer" {
r.Response.WriteStatusExit(http.StatusUnauthorized, "Invalid Authorization header format")
}
tokenString := parts[1]
// 解析 token
token, err := jwt.ParseWithClaims(tokenString, &login.CustomClaims{}, func(token *jwt.Token) (interface{}, error) {
return login.SecretKey, nil
})
if err != nil || !token.Valid {
r.Response.WriteStatusExit(http.StatusUnauthorized, "Invalid token")
}
// 将用户信息存储在上下文中
if claims, ok := token.Claims.(*login.CustomClaims); ok {
r.SetCtxVar("username", claims.Username)
}
r.Middleware.Next()
}

21
link_homework/internal/logic/middleware/interceptor.go

@ -3,6 +3,7 @@ package middleware
import ( import (
"github.com/gogf/gf/v2/net/ghttp" "github.com/gogf/gf/v2/net/ghttp"
"link_homework/internal/model/dto" "link_homework/internal/model/dto"
"link_homework/internal/service"
) )
func MiddlewareCORS(r *ghttp.Request) { func MiddlewareCORS(r *ghttp.Request) {
@ -11,11 +12,25 @@ func MiddlewareCORS(r *ghttp.Request) {
} }
func MiddlewareIsLogin(r *ghttp.Request) { func MiddlewareIsLogin(r *ghttp.Request) {
token := r.GetHeader("Authorization")
if token == "" {
token := r.GetHeader("token")
valid, err := service.LoginLogic().ValidateToken(r.Context(), token)
if err != nil || !valid {
r.Response.WriteJsonExit(dto.Result{ r.Response.WriteJsonExit(dto.Result{
Code: 401, Code: 401,
Message: "未登录",
Message: "Token 无效",
})
} else {
r.Middleware.Next()
}
}
func MiddlewareIsLoginClient(r *ghttp.Request) {
token := r.GetHeader("token")
const LocalToken = "9ior41AF0xTIbIG2pRnnbZi0+fEeMx8pywnIlrmTwo5FbqJ9lWrSWOxp9MkpKiNtedtUafqvzIwpFKrwuMs"
if token != LocalToken {
r.Response.WriteJsonExit(dto.Result{
Code: 401,
Message: "客户端Token 无效123",
}) })
} else { } else {
r.Middleware.Next() r.Middleware.Next()

256
link_homework/internal/logic/record/record.go

@ -0,0 +1,256 @@
package record
import (
"context"
"encoding/json"
"errors"
"fmt"
"github.com/360EntSecGroup-Skylar/excelize"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
pkgRecord "link_homework/api/v1/record"
"link_homework/internal/dao"
"link_homework/internal/model/dto"
"link_homework/internal/service"
"strconv"
"time"
)
type sRecord struct{}
func init() {
service.RegisterRecord(&sRecord{})
}
func NewRecord() *sRecord {
return &sRecord{}
}
// 无条件全查
func (s *sRecord) GetRecordList(ctx context.Context, groupId, pageNo, pageSize int) (record []pkgRecord.GetRecordListRes, err error) {
//从record表中查询出jwcode,根据group_id
if pageNo == 0 && pageSize == 0 {
err = dao.ActivityInteractiveRecord.Ctx(ctx).Fields("jwcode").Where("group_id", groupId).Group("jwcode").Scan(&record)
} else {
err = dao.ActivityInteractiveRecord.Ctx(ctx).Fields("jwcode").Where("group_id", groupId).Group("jwcode").
Page(pageNo, pageSize).Scan(&record)
}
if err != nil {
return nil, errors.New("无条件查jwcode失败")
}
//fmt.Println(record)
//根据jwcode在member_info表中查询姓名(name), 部门id(deptId), 部门名(deptName), 门店id(shopId), 门店名(shopName)
for i, info := range record {
err = g.DB("cms").Model("member_info").Fields("jwcode", "name", "deptId", "deptName", "shopId", "shopName").
Where("jwcode", info.Jwcode).Scan(&record[i])
if err != nil {
return nil, errors.New("无条件根据jwcode查member_info表失败")
}
total, err1 := dao.ActivityInteractiveRecord.Ctx(ctx).Fields("jwcode").Where("group_id", groupId).Group("jwcode").Count()
if err1 != nil {
return nil, errors.New("无条件查询总数失败")
}
record[i].Total = total
//根据jwcode,groupId在record表中查询最新的提交记录进行存放
var recordInfo []dto.RecordInfo
err = dao.ActivityInteractiveRecord.Ctx(ctx).Fields("content", "content_title", "updated_at", "form_id").
Where("jwcode", info.Jwcode).Where("group_id", groupId).Group("form_id").Order("updated_at desc").Scan(&recordInfo)
if err != nil {
return nil, errors.New("根据jwcode查询提交记录失败")
}
for i, title := range recordInfo {
err = dao.ActivityInteractiveForm.Ctx(ctx).Fields("description", "type").Where("id", title.FormId).Scan(&recordInfo[i])
if err != nil {
return nil, errors.New("根据jwcode查询作业题目信息失败")
}
}
record[i].Reply = recordInfo
//fmt.Println(record)
}
return
}
// 根据条件查询 对所有结果进行筛选
func (s *sRecord) GetRecordByCondition(ctx context.Context, groupId, jwcode int, deptId, shopId string, pageNo, pageSize int) (record []pkgRecord.GetRecordListRes, err error) {
//全查
recordList, err := s.GetRecordList(ctx, groupId, pageNo, pageSize)
if err != nil {
return recordList, err
}
//判断传来的jwcode, deptId, shopId是否为空,根据情况进行不同的筛选
if jwcode == 0 { //没有传jwcode
if deptId == "" && shopId == "" { //000
return recordList, err
} else if deptId != "" && shopId == "" { //010
for _, info := range recordList {
if info.DeptId == deptId {
record = append(record, info)
}
}
if record == nil {
return nil, errors.New("只部门没有查询到相关记录")
}
return record, err
} else if deptId != "" && shopId != "" { //011
for _, info := range recordList {
if info.DeptId == deptId && info.ShopId == shopId {
record = append(record, info)
}
}
if record == nil {
return nil, errors.New("部门,门店 没有查询到相关记录")
}
return record, err
}
} else { //传了jwcode
if deptId == "" && shopId == "" { //100
for _, info := range recordList {
if info.Jwcode == jwcode {
record = append(record, info)
}
}
if record == nil {
return nil, errors.New("只精网号没有查询到相关记录")
}
return record, err
} else if deptId != "" && shopId == "" { //110
for _, info := range recordList {
if info.Jwcode == jwcode && info.DeptId == deptId {
record = append(record, info)
}
}
if record == nil {
return nil, errors.New("精网号,部门 没有查询到相关记录")
}
return record, err
} else if deptId != "" && shopId != "" { //111
for _, info := range recordList {
if info.Jwcode == jwcode && info.DeptId == deptId && info.ShopId == shopId {
record = append(record, info)
}
}
if record == nil {
return nil, errors.New("精网号,部门,门店 没有查询到相关记录")
}
return record, err
}
}
return nil, errors.New("检查一下穿的参数是否正常")
}
// 查询部门信息
func (s *sRecord) GetDeptInfo(ctx context.Context) (depts []pkgRecord.GetDeptInfoRes, err error) {
// 从Redis中获取数据
value, _ := g.Redis().Get(ctx, "deptinfo")
if value.String() != "" {
err = json.Unmarshal(value.Bytes(), &depts)
if err != nil {
return nil, errors.New("从Redis获取数据,JSON解析失败")
}
return
}
// 如果Redis中没有数据,查询数据库
err = g.DB("cms").Model("member_info").Fields("deptId", "deptName").Group("deptId").Scan(&depts)
if err != nil {
return nil, errors.New("查询部门信息失败")
}
// 将查询结果JSON化并存入Redis
deptJSON, _ := json.Marshal(depts)
_, err = g.Redis().Set(ctx, "deptinfo", deptJSON)
if err != nil {
return nil, errors.New("Redis存储失败")
}
return
}
// 根据部门信息查询门店信息
func (s *sRecord) GetShopInfoByDeptId(ctx context.Context, deptId string) (shops []pkgRecord.GetShopInfoByDeptIdRes, err error) {
// 从Redis中获取数据
value, _ := g.Redis().Get(ctx, fmt.Sprintf("%s shopinfo", deptId))
if value.String() != "" {
err = json.Unmarshal(value.Bytes(), &shops)
if err != nil {
return nil, errors.New("从Redis获取数据,JSON解析失败")
}
return
}
// 如果Redis中没有数据,查询数据库
err = g.DB("cms").Model("member_info").Fields("shopId", "shopName").
Where("deptId", deptId).Group("shopId").Scan(&shops)
// 将查询结果JSON化并存入Redis
shopJSON, _ := json.Marshal(shops)
_, err = g.Redis().Set(ctx, fmt.Sprintf("%s shopinfo", deptId), shopJSON)
return
}
// ExportExcel 查询数据,创建excel文件,设置表头,写入数据,设置文件名,保存到缓冲区并返回,设置响应头,指定内容类型为excel文件,指定文件名为fileName,将buffer中的内容写入响应
func (s *sRecord) ExportExcel(r *ghttp.Request, groupId, jwcode int, deptId, shopId string, pageNo, pageSize int) {
// 调用查询服务
records, err := service.Record().GetRecordByCondition(
r.Context(), groupId, jwcode, deptId, shopId, pageNo, pageSize)
if err != nil {
//g.Log().Error(r.Context(), "查询记录失败: ", err)
r.Response.WriteJsonExit(dto.Error("查询记录失败: " + err.Error()))
return
}
if len(records) == 0 {
//g.Log().Warning(r.Context(), "查询结果为空: 参数 = ", req)
r.Response.WriteJsonExit(dto.Error("查询结果为空"))
return
}
// 创建 Excel 文件
excelFile := excelize.NewFile() // 默认会创建一个 Sheet1
sheetName := "Sheet1" // 使用默认的 Sheet1
// 设置表头
headers := []string{"序号", "精网号", "名字", "部门ID", "部门名称", "门店ID", "门店名称", "题目ID", "题目类型", "题目名称", "简答题标题", "作答内容", "提交时间"}
for i, header := range headers {
col := string('A' + i) // 将索引转换为 Excel 列名
excelFile.SetCellValue(sheetName, col+"1", header)
}
/*写入数据*/
// 写入数据
rowIndex := 2 // 从第二行开始写入数据
for _, record := range records {
for _, reply := range record.Reply { // 遍历每个 `Reply`
excelFile.SetCellValue(sheetName, "A"+strconv.Itoa(rowIndex), rowIndex-1)
excelFile.SetCellValue(sheetName, "B"+strconv.Itoa(rowIndex), record.Jwcode)
excelFile.SetCellValue(sheetName, "C"+strconv.Itoa(rowIndex), record.Name)
excelFile.SetCellValue(sheetName, "D"+strconv.Itoa(rowIndex), record.DeptId)
excelFile.SetCellValue(sheetName, "E"+strconv.Itoa(rowIndex), record.DeptName)
excelFile.SetCellValue(sheetName, "F"+strconv.Itoa(rowIndex), record.ShopId)
excelFile.SetCellValue(sheetName, "G"+strconv.Itoa(rowIndex), record.ShopName)
excelFile.SetCellValue(sheetName, "H"+strconv.Itoa(rowIndex), reply.FormId)
excelFile.SetCellValue(sheetName, "I"+strconv.Itoa(rowIndex), reply.Type)
excelFile.SetCellValue(sheetName, "J"+strconv.Itoa(rowIndex), reply.Description)
excelFile.SetCellValue(sheetName, "K"+strconv.Itoa(rowIndex), reply.ContentTitle)
excelFile.SetCellValue(sheetName, "L"+strconv.Itoa(rowIndex), reply.Content)
excelFile.SetCellValue(sheetName, "M"+strconv.Itoa(rowIndex), reply.UpdatedAt.String())
rowIndex++
}
}
/*写入数据*/
// 设置文件名
fileName := "Records_" + time.Now().Format("20060102150405") + ".xlsx"
// 保存到缓冲区并返回
buffer, err := excelFile.WriteToBuffer()
if err != nil {
r.Response.WriteJsonExit(dto.Error("生成 Excel 文件失败: " + err.Error()))
return
}
// 设置响应头,指定内容类型为Excel文件
r.Response.Header().Set("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
// 设置响应头,指定文件名为fileName
r.Response.Header().Set("Content-Disposition", "attachment; filename="+fileName)
// 将buffer中的内容写入响应
r.Response.Write(buffer.Bytes())
}

31
link_homework/internal/model/dto/Result.go

@ -1,9 +1,5 @@
package dto package dto
import (
"github.com/gogf/gf/v2/frame/g"
)
// 定义响应结构 // 定义响应结构
type Result struct { type Result struct {
Code int `json:"code"` Code int `json:"code"`
@ -16,7 +12,18 @@ func Success() *Result {
return &Result{ return &Result{
Code: 200, Code: 200,
Message: "success", Message: "success",
Data: g.Map{},
//Data: g.Map{},
Data: nil,
}
}
/*成功,自定义相应信息*/
func SuccessWithMsg(msg string) *Result {
return &Result{
Code: 200,
Message: msg,
//Data: g.Map{},
Data: nil,
} }
} }
@ -32,9 +39,10 @@ func SuccessWithData(data interface{}) *Result {
/*错误,只有错误信息,错误码0*/ /*错误,只有错误信息,错误码0*/
func Error(msg string) *Result { func Error(msg string) *Result {
return &Result{ return &Result{
Code: 0, // 错误码
Code: 400, // 错误码
Message: msg, // 错误信息 Message: msg, // 错误信息
Data: g.Map{},
//Data: g.Map{},
Data: nil,
} }
} }
@ -43,7 +51,8 @@ func ErrorWithCode(code int, msg string) *Result {
return &Result{ return &Result{
Code: code, // 错误码 Code: code, // 错误码
Message: msg, // 错误信息 Message: msg, // 错误信息
Data: g.Map{},
//Data: g.Map{},
Data: nil,
} }
} }
@ -52,7 +61,8 @@ func Unauthorized(msg string) *Result {
return &Result{ return &Result{
Code: 401, // 错误码 Code: 401, // 错误码
Message: msg, // 错误信息 Message: msg, // 错误信息
Data: g.Map{},
//Data: g.Map{},
Data: nil,
} }
} }
@ -61,6 +71,7 @@ func UnauthorizedWithCode(code int, msg string) *Result {
return &Result{ return &Result{
Code: code, // 错误码 Code: code, // 错误码
Message: msg, // 错误信息 Message: msg, // 错误信息
Data: g.Map{},
//Data: g.Map{},
Data: nil,
} }
} }

24
link_homework/internal/model/dto/ToolStruct.go

@ -0,0 +1,24 @@
package dto
import "github.com/gogf/gf/v2/os/gtime"
// 从cms库中查询用户信息
type MemberInfo struct {
Jwcode int `json:"jwcode" orm:"db:cms;table:member_info;column:jwcode" dc:"精网号"`
Name string `json:"name" orm:"db:cms;table:member_info;column:name" dc:"用户名字"`
DeptId string `json:"deptId" orm:"db:cms;table:member_info;column:deptId" dc:"部门id"`
DeptName string `json:"deptName" orm:"db:cms;member_info;column:deptName" dc:"部门名"`
ShopId string `json:"shopId" orm:"db:cms;member_info;column:shopId" dc:"门店id"`
ShopName string `json:"shopName" orm:"db:cms;member_info;column:shopName" dc:"门店名"`
}
// 从live库里查询作业信息
type RecordInfo struct {
//Jwcode int `json:"jwcode" orm:"db:default;table:activity_interactive_record;column:jwcode" dc:"精网号"`
FormId int `json:"formId" orm:"db:default;table:activity_interactive_record;column:form_id" dc:"题目id"`
Type int `json:"type" orm:"db:default;table:activity_interactive_form;column:type" dc:"题目类型"`
Description string `json:"formTitle" orm:"db:default;table:activity_interactive_form;column:description" dc:"题目"`
ContentTitle string `json:"contentTitle" orm:"db:default;table:activity_interactive_record;column:content_title" dc:"作答标题"`
Content string `json:"content" orm:"db:default;table:activity_interactive_record;column:content" dc:"作答内容"`
UpdatedAt gtime.Time `json:"submitTime" orm:"db:default;table:activity_interactive_record;column:updated_at" dc:"提交时间/更新时间"`
}

24
link_homework/internal/model/entity/activity_interactive_group.go

@ -10,14 +10,18 @@ import (
// ActivityInteractiveGroup is the golang structure for table activity_interactive_group. // ActivityInteractiveGroup is the golang structure for table activity_interactive_group.
type ActivityInteractiveGroup struct { type ActivityInteractiveGroup struct {
Id int `json:"id" orm:"id" description:""` //
Name string `json:"name" orm:"name" description:"表单名称"` // 表单名称
Status uint `json:"status" orm:"status" description:"表单状态 0 未发布 1 发布中 2 过期"` // 表单状态 0 未发布 1 发布中 2 过期
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"` // 创建时间
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:""` //
ClubType int `json:"clubType" orm:"club_type" description:"1:牧民俱乐部 2:博股论坛 3:神枪手俱乐部 4:环球俱乐部 5:价值投资 6:波段行情 7:抄底卖顶 8:资金及仓位管理 9 财富的游戏"` // 1:牧民俱乐部 2:博股论坛 3:神枪手俱乐部 4:环球俱乐部 5:价值投资 6:波段行情 7:抄底卖顶 8:资金及仓位管理 9 财富的游戏
ArticleId int `json:"articleId" orm:"article_id" description:"关联文章id"` // 关联文章id
LiveId int `json:"liveId" orm:"live_id" description:"关联直播id"` // 关联直播id
StartDate *gtime.Time `json:"startDate" orm:"start_date" description:"作业开始时间"` // 作业开始时间
EndDate *gtime.Time `json:"endDate" orm:"end_date" description:"作业结束时间"` // 作业结束时间
Id int `json:"id" orm:"id" description:""` //
Name string `json:"name" orm:"name" description:"表单名称"` // 表单名称
Status uint `json:"status" orm:"status" description:"表单状态 0 未发布 1 发布中 2 过期"` // 表单状态 0 未发布 1 发布中 2 过期
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"` // 创建时间
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"` //
ClubType int `json:"clubType" orm:"club_type" description:"1:牧民俱乐部 2:博股论坛 3:神枪手俱乐部 4:环球俱乐部 5:价值投资 6:波段行情 7:抄底卖顶 8:资金及仓位管理 9 财富的游戏"` // 1:牧民俱乐部 2:博股论坛 3:神枪手俱乐部 4:环球俱乐部 5:价值投资 6:波段行情 7:抄底卖顶 8:资金及仓位管理 9 财富的游戏
ArticleId int `json:"articleId" orm:"article_id" description:"关联文章id"` // 关联文章id
LiveId int `json:"liveId" orm:"live_id" description:"关联直播id"` // 关联直播id
StartDate *gtime.Time `json:"startDate" orm:"start_date" description:"作业开始时间"` // 作业开始时间
EndDate *gtime.Time `json:"endDate" orm:"end_date" description:"作业结束时间"` // 作业结束时间
Article *FxArticle `json:"article" description:"关联文章"` // 关联文章
Live *Live `json:"live" orm:"with:id=live_id" description:"关联直播"` // 关联直播
Form []*ActivityInteractiveForm `json:"form" orm:"with:group_id=id" description:"关联题目"`
Count int `json:"count" description:"作业提交次数"`
} }

194
link_homework/internal/model/entity/fx_article.go

@ -4,105 +4,101 @@
package entity package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// FxArticle is the golang structure for table fx_article. // FxArticle is the golang structure for table fx_article.
type FxArticle struct { type FxArticle struct {
Id int `json:"id" orm:"id" description:""` //
Title string `json:"title" orm:"title" description:"标题"` // 标题
Style string `json:"style" orm:"style" description:"标题颜色"` // 标题颜色
Flags int `json:"flags" orm:"flags" description:"属性 0 无 1 置顶 2 热点"` // 属性 0 无 1 置顶 2 热点
Des int `json:"des" orm:"des" description:"排序"` // 排序
Tags string `json:"tags" orm:"tags" description:"TAG标签"` // TAG标签
Image string `json:"image" orm:"image" description:"缩略图"` // 缩略图
Typeid int `json:"typeid" orm:"typeid" description:"栏目"` // 栏目
Click int `json:"click" orm:"click" description:"观看次数"` // 观看次数
Keywords string `json:"keywords" orm:"keywords" description:"关键词"` // 关键词
Description string `json:"description" orm:"description" description:"内容描述"` // 内容描述
Arcrank int `json:"arcrank" orm:"arcrank" description:"阅读权限"` // 阅读权限
Template string `json:"template" orm:"template" description:"模板文件"` // 模板文件
CreateTime string `json:"createTime" orm:"create_time" description:"添加时间"` // 添加时间
UpdateTime string `json:"updateTime" orm:"update_time" description:"更新时间"` // 更新时间
Content string `json:"content" orm:"content" description:""` //
Hide int `json:"hide" orm:"hide" description:"-1转码中,0隐藏 1显示文章 2审核 3拒绝 4用户自己删除5定时发布的视频"` // -1转码中,0隐藏 1显示文章 2审核 3拒绝 4用户自己删除5定时发布的视频
Url string `json:"url" orm:"url" description:"跳转"` // 跳转
Source string `json:"source" orm:"source" description:"来源"` // 来源
Uid int `json:"uid" orm:"uid" description:"会员UID 识别注明哪个会员投稿"` // 会员UID 识别注明哪个会员投稿
Writer string `json:"writer" orm:"writer" description:"文章作者"` // 文章作者
Mychannel int `json:"mychannel" orm:"mychannel" description:"文章类型 1 文章 2 图文集 3 视频 4 小视频"` // 文章类型 1 文章 2 图文集 3 视频 4 小视频
Images string `json:"images" orm:"images" description:"图片集,如果mytype值是2,则是图片文章"` // 图片集,如果mytype值是2,则是图片文章
Video string `json:"video" orm:"video" description:"视频"` // 视频
Videodate string `json:"videodate" orm:"videodate" description:"视频时间"` // 视频时间
Zan uint `json:"zan" orm:"zan" description:"点赞数量"` // 点赞数量
Cai uint `json:"cai" orm:"cai" description:""` //
PingNum uint `json:"pingNum" orm:"pingNum" description:"评论数量"` // 评论数量
Weitoutiao int `json:"weitoutiao" orm:"weitoutiao" description:"0显示文章 1微头条"` // 0显示文章 1微头条
ToutiaoTiemId string `json:"toutiaoTiemId" orm:"toutiao_tiemId" description:"今日头条原文章ID"` // 今日头条原文章ID
QiniuVideo string `json:"qiniuVideo" orm:"qiniu_video" description:""` //
QiniuVideoType int `json:"qiniuVideoType" orm:"qiniu_video_type" description:"1转码中 0转码成功"` // 1转码中 0转码成功
Dtitle string `json:"dtitle" orm:"dtitle" description:"短标题 热点专用"` // 短标题 热点专用
Rootid int64 `json:"rootid" orm:"rootid" description:""` //
Jwcode int `json:"jwcode" orm:"jwcode" description:""` //
Boardcode string `json:"boardcode" orm:"boardcode" description:""` //
ScoreBasic float64 `json:"scoreBasic" orm:"scoreBasic" description:"用于提升文章排序分数的基础分数"` // 用于提升文章排序分数的基础分数
Cmsid int `json:"cmsid" orm:"cmsid" description:"0 文章 1话题文章"` // 0 文章 1话题文章
AId int `json:"aId" orm:"a_id" description:"转发文章的id"` // 转发文章的id
SourceType int `json:"sourceType" orm:"source_type" description:"转发内容的类型:0:没有转发;1:文章;2:快讯"` // 转发内容的类型:0:没有转发;1:文章;2:快讯
IsT int `json:"isT" orm:"is_t" description:"0 文章 1话题文章"` // 0 文章 1话题文章
Flag int `json:"flag" orm:"flag" description:""` //
Share int `json:"share" orm:"share" description:"是否允许分享,0:不允许,1:允许"` // 是否允许分享,0:不允许,1:允许
DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:""` //
VideoDuration int `json:"videoDuration" orm:"video_duration" description:"视频的播放时长"` // 视频的播放时长
VideoName string `json:"videoName" orm:"video_name" description:""` //
VideoMemory float64 `json:"videoMemory" orm:"video_memory" description:""` //
Kan int `json:"kan" orm:"kan" description:"观看人数(不重复)"` // 观看人数(不重复)
KanFinish int `json:"kanFinish" orm:"kan_finish" description:"看完人数(不重复)"` // 看完人数(不重复)
Favorite int `json:"favorite" orm:"favorite" description:""` //
ShowTime int `json:"showTime" orm:"show_time" description:"定时发布时间"` // 定时发布时间
EmployeeExclusive int `json:"employeeExclusive" orm:"employee_exclusive" description:"员工专属(1:专属,0:非专属)"` // 员工专属(1:专属,0:非专属)
Language string `json:"language" orm:"language" description:""` //
Market string `json:"market" orm:"market" description:""` //
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:""` //
CId int `json:"cId" orm:"c_id" description:"合集id"` // 合集id
TargetUserRole int `json:"targetUserRole" orm:"target_user_role" description:"目标用户 1:网员 2:非网 3:网员和非网"` // 目标用户 1:网员 2:非网 3:网员和非网
Weight int `json:"weight" orm:"weight" description:"权重"` // 权重
Herdsman uint `json:"herdsman" orm:"herdsman" description:"0非牧民1牧民专属"` // 0非牧民1牧民专属
CrossPlatform string `json:"crossPlatform" orm:"cross_platform" description:"0 仅精网 1 toujiao 2 homliylink"` // 0 仅精网 1 toujiao 2 homliylink
JwAid int `json:"jwAid" orm:"jw_aid" description:"精网文章id"` // 精网文章id
ToujiaoPdid int `json:"toujiaoPdid" orm:"toujiao_pdid" description:"分享至投教频道id"` // 分享至投教频道id
HomilylinkPdid int `json:"homilylinkPdid" orm:"homilylink_pdid" description:"分享至homeLink频道id"` // 分享至homeLink频道id
TargetUserRoleHomilylink int `json:"targetUserRoleHomilylink" orm:"target_user_role_homilylink" description:"目标用户 1:网员 2:非网 3:网员和非网"` // 目标用户 1:网员 2:非网 3:网员和非网
Cost uint `json:"cost" orm:"cost" description:"需要消费的金豆"` // 需要消费的金豆
Preview string `json:"preview" orm:"preview" description:"预览内容"` // 预览内容
CoverType int `json:"coverType" orm:"cover_type" description:"1:横屏,2:竖屏"` // 1:横屏,2:竖屏
Reward int `json:"reward" orm:"reward" description:"文章打赏功能 0 未开启 1开启"` // 文章打赏功能 0 未开启 1开启
Recommend int `json:"recommend" orm:"recommend" description:"1:推荐 2:不推荐"` // 1:推荐 2:不推荐
RecommendAble int `json:"recommendAble" orm:"recommend_able" description:"1:可以被推荐 2:不可以被推荐"` // 1:可以被推荐 2:不可以被推荐
RecommendDeadline int `json:"recommendDeadline" orm:"recommend_deadline" description:"推荐截止时间"` // 推荐截止时间
QrcodeState int `json:"qrcodeState" orm:"qrcode_state" description:"1:开启,0:关闭"` // 1:开启,0:关闭
QrcodeJwcode int `json:"qrcodeJwcode" orm:"qrcode_jwcode" description:"精网号"` // 精网号
QrcodeUserid int `json:"qrcodeUserid" orm:"qrcode_userid" description:"crm用户id"` // crm用户id
QrcodeUrl string `json:"qrcodeUrl" orm:"qrcode_url" description:"二维码地址"` // 二维码地址
LessonId int `json:"lessonId" orm:"lesson_id" description:"关联课程id"` // 关联课程id
AudioUrl string `json:"audioUrl" orm:"audio_url" description:""` //
AudioDuration int `json:"audioDuration" orm:"audio_duration" description:"音频时常"` // 音频时常
Note int `json:"note" orm:"note" description:"1:笔记 2:剧场精选 3:铁粉专享(海外) 4:剧场栏目 5:铁粉专享 6:三体哲学"` // 1:笔记 2:剧场精选 3:铁粉专享(海外) 4:剧场栏目 5:铁粉专享 6:三体哲学
NoteLabel int `json:"noteLabel" orm:"note_label" description:"笔记标签 1:心得"` // 笔记标签 1:心得
Term int `json:"term" orm:"term" description:"到期时间 0 永久 大于0 到期时间"` // 到期时间 0 永久 大于0 到期时间
NonClubMemberCost int `json:"nonClubMemberCost" orm:"non_club_member_cost" description:"cost 付费文章 俱乐部成员价格 non_club_member_cost 非本俱乐部成员价格"` // cost 付费文章 俱乐部成员价格 non_club_member_cost 非本俱乐部成员价格
PowerType int `json:"powerType" orm:"power_type" description:"权限类别 1 免费 2 会员专享 3 付费"` // 权限类别 1 免费 2 会员专享 3 付费
Total int `json:"total" orm:"total" description:"点赞+评论+阅读量"` // 点赞+评论+阅读量
LockCost int `json:"lockCost" orm:"lock_cost" description:"解锁文章金豆数"` // 解锁文章金豆数
FeaturedVideo int `json:"featuredVideo" orm:"featured_video" description:"是否精选视频 0 不是 1 是"` // 是否精选视频 0 不是 1 是
AdType int `json:"adType" orm:"ad_type" description:"广告类型 1 直播 2 活动"` // 广告类型 1 直播 2 活动
AdContent string `json:"adContent" orm:"ad_content" description:"广告内容"` // 广告内容
AdClick int `json:"adClick" orm:"ad_click" description:"广告点击量"` // 广告点击量
AdImage string `json:"adImage" orm:"ad_image" description:"广告图片"` // 广告图片
AdLiveId int `json:"adLiveId" orm:"ad_live_id" description:"广告直播id"` // 广告直播id
IsPush int `json:"isPush" orm:"is_push" description:"频道内容 0 未推送 1 已推送"` // 频道内容 0 未推送 1 已推送
SyncMoment int `json:"syncMoment" orm:"sync_moment" description:"是否同步到动态 0 不同步 1 同步"` // 是否同步到动态 0 不同步 1 同步
MomentContent string `json:"momentContent" orm:"moment_content" description:""` //
VideoType int `json:"videoType" orm:"video_type" description:"视频类型 1 横屏 2 竖屏"` // 视频类型 1 横屏 2 竖屏
Id int `json:"id" orm:"id" description:""` //
Title string `json:"title" orm:"title" description:"标题"` // 标题
//Style string `json:"style" orm:"style" description:"标题颜色"` // 标题颜色
//Flags int `json:"flags" orm:"flags" description:"属性 0 无 1 置顶 2 热点"` // 属性 0 无 1 置顶 2 热点
//Des int `json:"des" orm:"des" description:"排序"` // 排序
//Tags string `json:"tags" orm:"tags" description:"TAG标签"` // TAG标签
//Image string `json:"image" orm:"image" description:"缩略图"` // 缩略图
//Typeid int `json:"typeid" orm:"typeid" description:"栏目"` // 栏目
//Click int `json:"click" orm:"click" description:"观看次数"` // 观看次数
//Keywords string `json:"keywords" orm:"keywords" description:"关键词"` // 关键词
//Description string `json:"description" orm:"description" description:"内容描述"` // 内容描述
//Arcrank int `json:"arcrank" orm:"arcrank" description:"阅读权限"` // 阅读权限
//Template string `json:"template" orm:"template" description:"模板文件"` // 模板文件
CreateTime string `json:"createTime" orm:"create_time" description:"添加时间"` // 添加时间
UpdateTime string `json:"updateTime" orm:"update_time" description:"更新时间"` // 更新时间
//Content string `json:"content" orm:"content" description:""` //
//Hide int `json:"hide" orm:"hide" description:"-1转码中,0隐藏 1显示文章 2审核 3拒绝 4用户自己删除5定时发布的视频"` // -1转码中,0隐藏 1显示文章 2审核 3拒绝 4用户自己删除5定时发布的视频
//Url string `json:"url" orm:"url" description:"跳转"` // 跳转
//Source string `json:"source" orm:"source" description:"来源"` // 来源
//Uid int `json:"uid" orm:"uid" description:"会员UID 识别注明哪个会员投稿"` // 会员UID 识别注明哪个会员投稿
//Writer string `json:"writer" orm:"writer" description:"文章作者"` // 文章作者
//Mychannel int `json:"mychannel" orm:"mychannel" description:"文章类型 1 文章 2 图文集 3 视频 4 小视频"` // 文章类型 1 文章 2 图文集 3 视频 4 小视频
//Images string `json:"images" orm:"images" description:"图片集,如果mytype值是2,则是图片文章"` // 图片集,如果mytype值是2,则是图片文章
//Video string `json:"video" orm:"video" description:"视频"` // 视频
//Videodate string `json:"videodate" orm:"videodate" description:"视频时间"` // 视频时间
//Zan uint `json:"zan" orm:"zan" description:"点赞数量"` // 点赞数量
//Cai uint `json:"cai" orm:"cai" description:""` //
//PingNum uint `json:"pingNum" orm:"pingNum" description:"评论数量"` // 评论数量
//Weitoutiao int `json:"weitoutiao" orm:"weitoutiao" description:"0显示文章 1微头条"` // 0显示文章 1微头条
//ToutiaoTiemId string `json:"toutiaoTiemId" orm:"toutiao_tiemId" description:"今日头条原文章ID"` // 今日头条原文章ID
//QiniuVideo string `json:"qiniuVideo" orm:"qiniu_video" description:""` //
//QiniuVideoType int `json:"qiniuVideoType" orm:"qiniu_video_type" description:"1转码中 0转码成功"` // 1转码中 0转码成功
//Dtitle string `json:"dtitle" orm:"dtitle" description:"短标题 热点专用"` // 短标题 热点专用
//Rootid int64 `json:"rootid" orm:"rootid" description:""` //
//Jwcode int `json:"jwcode" orm:"jwcode" description:""` //
//Boardcode string `json:"boardcode" orm:"boardcode" description:""` //
//ScoreBasic float64 `json:"scoreBasic" orm:"scoreBasic" description:"用于提升文章排序分数的基础分数"` // 用于提升文章排序分数的基础分数
//Cmsid int `json:"cmsid" orm:"cmsid" description:"0 文章 1话题文章"` // 0 文章 1话题文章
//AId int `json:"aId" orm:"a_id" description:"转发文章的id"` // 转发文章的id
//SourceType int `json:"sourceType" orm:"source_type" description:"转发内容的类型:0:没有转发;1:文章;2:快讯"` // 转发内容的类型:0:没有转发;1:文章;2:快讯
//IsT int `json:"isT" orm:"is_t" description:"0 文章 1话题文章"` // 0 文章 1话题文章
//Flag int `json:"flag" orm:"flag" description:""` //
//Share int `json:"share" orm:"share" description:"是否允许分享,0:不允许,1:允许"` // 是否允许分享,0:不允许,1:允许
//DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:""` //
//VideoDuration int `json:"videoDuration" orm:"video_duration" description:"视频的播放时长"` // 视频的播放时长
//VideoName string `json:"videoName" orm:"video_name" description:""` //
//VideoMemory float64 `json:"videoMemory" orm:"video_memory" description:""` //
//Kan int `json:"kan" orm:"kan" description:"观看人数(不重复)"` // 观看人数(不重复)
//KanFinish int `json:"kanFinish" orm:"kan_finish" description:"看完人数(不重复)"` // 看完人数(不重复)
//Favorite int `json:"favorite" orm:"favorite" description:""` //
//ShowTime int `json:"showTime" orm:"show_time" description:"定时发布时间"` // 定时发布时间
//EmployeeExclusive int `json:"employeeExclusive" orm:"employee_exclusive" description:"员工专属(1:专属,0:非专属)"` // 员工专属(1:专属,0:非专属)
//Language string `json:"language" orm:"language" description:""` //
//Market string `json:"market" orm:"market" description:""` //
//UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:""` //
//CId int `json:"cId" orm:"c_id" description:"合集id"` // 合集id
//TargetUserRole int `json:"targetUserRole" orm:"target_user_role" description:"目标用户 1:网员 2:非网 3:网员和非网"` // 目标用户 1:网员 2:非网 3:网员和非网
//Weight int `json:"weight" orm:"weight" description:"权重"` // 权重
//Herdsman uint `json:"herdsman" orm:"herdsman" description:"0非牧民1牧民专属"` // 0非牧民1牧民专属
//CrossPlatform string `json:"crossPlatform" orm:"cross_platform" description:"0 仅精网 1 toujiao 2 homliylink"` // 0 仅精网 1 toujiao 2 homliylink
//JwAid int `json:"jwAid" orm:"jw_aid" description:"精网文章id"` // 精网文章id
//ToujiaoPdid int `json:"toujiaoPdid" orm:"toujiao_pdid" description:"分享至投教频道id"` // 分享至投教频道id
//HomilylinkPdid int `json:"homilylinkPdid" orm:"homilylink_pdid" description:"分享至homeLink频道id"` // 分享至homeLink频道id
//TargetUserRoleHomilylink int `json:"targetUserRoleHomilylink" orm:"target_user_role_homilylink" description:"目标用户 1:网员 2:非网 3:网员和非网"` // 目标用户 1:网员 2:非网 3:网员和非网
//Cost uint `json:"cost" orm:"cost" description:"需要消费的金豆"` // 需要消费的金豆
//Preview string `json:"preview" orm:"preview" description:"预览内容"` // 预览内容
//CoverType int `json:"coverType" orm:"cover_type" description:"1:横屏,2:竖屏"` // 1:横屏,2:竖屏
//Reward int `json:"reward" orm:"reward" description:"文章打赏功能 0 未开启 1开启"` // 文章打赏功能 0 未开启 1开启
//Recommend int `json:"recommend" orm:"recommend" description:"1:推荐 2:不推荐"` // 1:推荐 2:不推荐
//RecommendAble int `json:"recommendAble" orm:"recommend_able" description:"1:可以被推荐 2:不可以被推荐"` // 1:可以被推荐 2:不可以被推荐
//RecommendDeadline int `json:"recommendDeadline" orm:"recommend_deadline" description:"推荐截止时间"` // 推荐截止时间
//QrcodeState int `json:"qrcodeState" orm:"qrcode_state" description:"1:开启,0:关闭"` // 1:开启,0:关闭
//QrcodeJwcode int `json:"qrcodeJwcode" orm:"qrcode_jwcode" description:"精网号"` // 精网号
//QrcodeUserid int `json:"qrcodeUserid" orm:"qrcode_userid" description:"crm用户id"` // crm用户id
//QrcodeUrl string `json:"qrcodeUrl" orm:"qrcode_url" description:"二维码地址"` // 二维码地址
//LessonId int `json:"lessonId" orm:"lesson_id" description:"关联课程id"` // 关联课程id
//AudioUrl string `json:"audioUrl" orm:"audio_url" description:""` //
//AudioDuration int `json:"audioDuration" orm:"audio_duration" description:"音频时常"` // 音频时常
//Note int `json:"note" orm:"note" description:"1:笔记 2:剧场精选 3:铁粉专享(海外) 4:剧场栏目 5:铁粉专享 6:三体哲学"` // 1:笔记 2:剧场精选 3:铁粉专享(海外) 4:剧场栏目 5:铁粉专享 6:三体哲学
//NoteLabel int `json:"noteLabel" orm:"note_label" description:"笔记标签 1:心得"` // 笔记标签 1:心得
//Term int `json:"term" orm:"term" description:"到期时间 0 永久 大于0 到期时间"` // 到期时间 0 永久 大于0 到期时间
//NonClubMemberCost int `json:"nonClubMemberCost" orm:"non_club_member_cost" description:"cost 付费文章 俱乐部成员价格 non_club_member_cost 非本俱乐部成员价格"` // cost 付费文章 俱乐部成员价格 non_club_member_cost 非本俱乐部成员价格
//PowerType int `json:"powerType" orm:"power_type" description:"权限类别 1 免费 2 会员专享 3 付费"` // 权限类别 1 免费 2 会员专享 3 付费
//Total int `json:"total" orm:"total" description:"点赞+评论+阅读量"` // 点赞+评论+阅读量
//LockCost int `json:"lockCost" orm:"lock_cost" description:"解锁文章金豆数"` // 解锁文章金豆数
//FeaturedVideo int `json:"featuredVideo" orm:"featured_video" description:"是否精选视频 0 不是 1 是"` // 是否精选视频 0 不是 1 是
//AdType int `json:"adType" orm:"ad_type" description:"广告类型 1 直播 2 活动"` // 广告类型 1 直播 2 活动
//AdContent string `json:"adContent" orm:"ad_content" description:"广告内容"` // 广告内容
//AdClick int `json:"adClick" orm:"ad_click" description:"广告点击量"` // 广告点击量
//AdImage string `json:"adImage" orm:"ad_image" description:"广告图片"` // 广告图片
//AdLiveId int `json:"adLiveId" orm:"ad_live_id" description:"广告直播id"` // 广告直播id
//IsPush int `json:"isPush" orm:"is_push" description:"频道内容 0 未推送 1 已推送"` // 频道内容 0 未推送 1 已推送
//SyncMoment int `json:"syncMoment" orm:"sync_moment" description:"是否同步到动态 0 不同步 1 同步"` // 是否同步到动态 0 不同步 1 同步
//MomentContent string `json:"momentContent" orm:"moment_content" description:""` //
//VideoType int `json:"videoType" orm:"video_type" description:"视频类型 1 横屏 2 竖屏"` // 视频类型 1 横屏 2 竖屏
} }

172
link_homework/internal/model/entity/live.go

@ -4,94 +4,90 @@
package entity package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// Live is the golang structure for table live. // Live is the golang structure for table live.
type Live struct { type Live struct {
Id int `json:"id" orm:"id" description:""` //
Jwcode int `json:"jwcode" orm:"jwcode" description:""` //
Type int `json:"type" orm:"type" description:"直播类型 1:频道直播 2:课程直播 3:班级群直播 4:财富的游戏(课程) 5:财富的游戏(剧场)"` // 直播类型 1:频道直播 2:课程直播 3:班级群直播 4:财富的游戏(课程) 5:财富的游戏(剧场)
ChannelId int `json:"channelId" orm:"channel_id" description:""` //
ChannelType int `json:"channelType" orm:"channel_type" description:"频道类型"` // 频道类型
ClassId int `json:"classId" orm:"class_id" description:"班级群id"` // 班级群id
ParentLiveId int `json:"parentLiveId" orm:"parent_live_id" description:"父live_id"` // 父live_id
CourseType int `json:"courseType" orm:"course_type" description:"直播课程类型 1:服务课 2:宣教课 3:知识课"` // 直播课程类型 1:服务课 2:宣教课 3:知识课
CourseLimitStartDate *gtime.Time `json:"courseLimitStartDate" orm:"course_limit_start_date" description:"课程类型限制 开始日期"` // 课程类型限制 开始日期
CourseLimitEndDate *gtime.Time `json:"courseLimitEndDate" orm:"course_limit_end_date" description:"课程类型限制 结束日期"` // 课程类型限制 结束日期
CourseLimitSwitch int `json:"courseLimitSwitch" orm:"course_limit_switch" description:"1:屏蔽网员"` // 1:屏蔽网员
ShowQrcode int `json:"showQrcode" orm:"show_qrcode" description:"1:二维码 2:获客助手 3:手机号"` // 1:二维码 2:获客助手 3:手机号
QrcodeJwcode int `json:"qrcodeJwcode" orm:"qrcode_jwcode" description:"二维码下精网号"` // 二维码下精网号
QrcodeJwcodeIds string `json:"qrcodeJwcodeIds" orm:"qrcode_jwcode_ids" description:"二维码下精网号下的ids(以,分隔)"` // 二维码下精网号下的ids(以,分隔)
RoomId string `json:"roomId" orm:"room_id" description:""` //
TName string `json:"tName" orm:"t_name" description:"主讲人姓名"` // 主讲人姓名
Name string `json:"name" orm:"name" description:""` //
Icon string `json:"icon" orm:"icon" description:""` //
State int `json:"state" orm:"state" description:"0:未开播 1:直播中 2:直播结束 3:已删除"` // 0:未开播 1:直播中 2:直播结束 3:已删除
Switch string `json:"switch" orm:"switch" description:""` //
Url string `json:"url" orm:"url" description:""` //
PlayUrl string `json:"playUrl" orm:"play_url" description:""` //
PlayUrlM3U8 string `json:"playUrlM3U8" orm:"play_url_m3u8" description:""` //
PlayUrlLhd string `json:"playUrlLhd" orm:"play_url_lhd" description:"flv(高清)"` // flv(高清)
PlayUrlM3U8Lhd string `json:"playUrlM3U8Lhd" orm:"play_url_m3u8_lhd" description:"m3u8(高清)"` // m3u8(高清)
PlayUrlLsd string `json:"playUrlLsd" orm:"play_url_lsd" description:"flv(标清)"` // flv(标清)
PlayUrlM3U8Lsd string `json:"playUrlM3U8Lsd" orm:"play_url_m3u8_lsd" description:"m3u8(标清)"` // m3u8(标清)
Cover string `json:"cover" orm:"cover" description:""` //
Introduce string `json:"introduce" orm:"introduce" description:""` //
StartTime int `json:"startTime" orm:"start_time" description:""` //
Manager string `json:"manager" orm:"manager" description:""` //
Product string `json:"product" orm:"product" description:""` //
ProductId string `json:"productId" orm:"product_id" description:""` //
Qx int `json:"qx" orm:"qx" description:"直播观看权限 1:所有用户 2:部分客户 3 : 外地客户 4: 静态专区客户 5:大财神 6:终免 7:半年版"` // 直播观看权限 1:所有用户 2:部分客户 3 : 外地客户 4: 静态专区客户 5:大财神 6:终免 7:半年版
Show int `json:"show" orm:"show" description:"是否展示直播 0:不展示 1:展示"` // 是否展示直播 0:不展示 1:展示
Oaid string `json:"oaid" orm:"oaid" description:"频道oa号"` // 频道oa号
Platform int `json:"platform" orm:"platform" description:"直播平台 1是pc直播2是手机直播"` // 直播平台 1是pc直播2是手机直播
Sig string `json:"sig" orm:"sig" description:"腾讯sig"` // 腾讯sig
Playback int `json:"playback" orm:"playback" description:"有无回放 1:有 0:无"` // 有无回放 1:有 0:无
PlaybackType int `json:"playbackType" orm:"playback_type" description:"回放类型 1:永久 2: 有期限"` // 回放类型 1:永久 2: 有期限
PlaybackExpire int `json:"playbackExpire" orm:"playback_expire" description:"回放过期时间"` // 回放过期时间
ShowInApp int `json:"showInApp" orm:"show_in_app" description:"0:不在app展示 1:在app展示"` // 0:不在app展示 1:在app展示
ClassName string `json:"className" orm:"class_name" description:"班级名称"` // 班级名称
CopyUrl int `json:"copyUrl" orm:"copy_url" description:"1:不允许客户复制链接"` // 1:不允许客户复制链接
LiveType int `json:"liveType" orm:"live_type" description:"直播形式 1:obs 2:录播 3:连麦 4:重播 5:竖屏推流"` // 直播形式 1:obs 2:录播 3:连麦 4:重播 5:竖屏推流
RepeatLiveId int `json:"repeatLiveId" orm:"repeat_live_id" description:"重播对应的live_id"` // 重播对应的live_id
LiveVideoId int `json:"liveVideoId" orm:"live_video_id" description:"录播视频id"` // 录播视频id
VideoUrl string `json:"videoUrl" orm:"video_url" description:"录播视频地址"` // 录播视频地址
MemberWatchLimit int `json:"memberWatchLimit" orm:"member_watch_limit" description:"网员观看权限(静态专区) 1:全部用户 2:终免用户"` // 网员观看权限(静态专区) 1:全部用户 2:终免用户
RealStartTime int `json:"realStartTime" orm:"real_start_time" description:"实际开始时间"` // 实际开始时间
PopupQrcodeSwitch int `json:"popupQrcodeSwitch" orm:"popup_qrcode_switch" description:"弹窗二维码开关 0:关 1:开"` // 弹窗二维码开关 0:关 1:开
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:""` //
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:""` //
SyncPlatform string `json:"syncPlatform" orm:"sync_platform" description:"同步的平台 海外(en), 投教(toujiao)"` // 同步的平台 海外(en), 投教(toujiao)
SyncToujiaoChannelId int `json:"syncToujiaoChannelId" orm:"sync_toujiao_channel_id" description:"同步投教频道id"` // 同步投教频道id
SyncOverseaChannelId int `json:"syncOverseaChannelId" orm:"sync_oversea_channel_id" description:"同步海外频道id"` // 同步海外频道id
SyncLiveId int `json:"syncLiveId" orm:"sync_live_id" description:"从该live_id同步过来的"` // 从该live_id同步过来的
PayNum int `json:"payNum" orm:"pay_num" description:"付费金豆数量"` // 付费金豆数量
IsHerdsman int `json:"isHerdsman" orm:"is_herdsman" description:"1:牧民直播间"` // 1:牧民直播间
HerdsmanLimit int `json:"herdsmanLimit" orm:"herdsman_limit" description:"1:限制只有牧民观看"` // 1:限制只有牧民观看
ClubType int `json:"clubType" orm:"club_type" description:"俱乐部 1:牧民俱乐部 2:博股论坛 3:神枪手俱乐部 4:环球俱乐部 5:价值投资 6:波段行情 7:抄底卖顶 8:资金及仓位管理"` // 俱乐部 1:牧民俱乐部 2:博股论坛 3:神枪手俱乐部 4:环球俱乐部 5:价值投资 6:波段行情 7:抄底卖顶 8:资金及仓位管理
ClubTypeLimit int `json:"clubTypeLimit" orm:"club_type_limit" description:"俱乐部权限 0:没有 1:有"` // 俱乐部权限 0:没有 1:有
ExportPower int `json:"exportPower" orm:"export_power" description:"1:有导入名单权限"` // 1:有导入名单权限
InvestorSwitch int `json:"investorSwitch" orm:"investor_switch" description:"1: 开启合格投资者"` // 1: 开启合格投资者
SignSwitch int `json:"signSwitch" orm:"sign_switch" description:"1:开启签到"` // 1:开启签到
OnlinePeopleSwitch int `json:"onlinePeopleSwitch" orm:"online_people_switch" description:"在线人数开关 1:实时在线人数 2:场观次数"` // 在线人数开关 1:实时在线人数 2:场观次数
LessonId int `json:"lessonId" orm:"lesson_id" description:"课程id"` // 课程id
LessonSectionId int `json:"lessonSectionId" orm:"lesson_section_id" description:"课程章节id"` // 课程章节id
Password string `json:"password" orm:"password" description:"口令"` // 口令
Sort int `json:"sort" orm:"sort" description:"排序(大的优先)"` // 排序(大的优先)
ContentIntro string `json:"contentIntro" orm:"content_intro" description:"内容介绍"` // 内容介绍
RelatedClubType int `json:"relatedClubType" orm:"related_club_type" description:"关联俱乐部 1:牧民俱乐部 2:博股论坛 3:神枪手俱乐部 4:环球俱乐部"` // 关联俱乐部 1:牧民俱乐部 2:博股论坛 3:神枪手俱乐部 4:环球俱乐部
Poster string `json:"poster" orm:"poster" description:"海报"` // 海报
Tabs string `json:"tabs" orm:"tabs" description:"1:推荐课程 2:课程作业 3:邀约榜"` // 1:推荐课程 2:课程作业 3:邀约榜
PreviewVideo string `json:"previewVideo" orm:"preview_video" description:"预告视频"` // 预告视频
ReceiveKit int `json:"receiveKit" orm:"receive_kit" description:"1: 领取锦囊指标"` // 1: 领取锦囊指标
OaMark string `json:"oaMark" orm:"oa_mark" description:"oa_mark"` // oa_mark
OaMarkName string `json:"oaMarkName" orm:"oa_mark_name" description:"oa_mark_name"` // oa_mark_name
Stage int `json:"stage" orm:"stage" description:"销售阶段 1:课程销售阶段 2:软件销售阶段"` // 销售阶段 1:课程销售阶段 2:软件销售阶段
StageCourse int `json:"stageCourse" orm:"stage_course" description:"阶段课程类型 1:开班课 2:服务课 3:销售课"` // 阶段课程类型 1:开班课 2:服务课 3:销售课
TopTime int `json:"topTime" orm:"top_time" description:"置顶时间"` // 置顶时间
PlaybackSort int `json:"playbackSort" orm:"playback_sort" description:"直播回放排序, 越大越靠前"` // 直播回放排序, 越大越靠前
RelateClassIds string `json:"relateClassIds" orm:"relate_class_ids" description:"关联班级ids"` // 关联班级ids
JoinClassButton int `json:"joinClassButton" orm:"join_class_button" description:"进群按钮 1:开启"` // 进群按钮 1:开启
Id int `json:"id" orm:"id" description:""` //
//Jwcode int `json:"jwcode" orm:"jwcode" description:""` //
//Type int `json:"type" orm:"type" description:"直播类型 1:频道直播 2:课程直播 3:班级群直播 4:财富的游戏(课程) 5:财富的游戏(剧场)"` // 直播类型 1:频道直播 2:课程直播 3:班级群直播 4:财富的游戏(课程) 5:财富的游戏(剧场)
//ChannelId int `json:"channelId" orm:"channel_id" description:""` //
//ChannelType int `json:"channelType" orm:"channel_type" description:"频道类型"` // 频道类型
//ClassId int `json:"classId" orm:"class_id" description:"班级群id"` // 班级群id
//ParentLiveId int `json:"parentLiveId" orm:"parent_live_id" description:"父live_id"` // 父live_id
//CourseType int `json:"courseType" orm:"course_type" description:"直播课程类型 1:服务课 2:宣教课 3:知识课"` // 直播课程类型 1:服务课 2:宣教课 3:知识课
//CourseLimitStartDate *gtime.Time `json:"courseLimitStartDate" orm:"course_limit_start_date" description:"课程类型限制 开始日期"` // 课程类型限制 开始日期
//CourseLimitEndDate *gtime.Time `json:"courseLimitEndDate" orm:"course_limit_end_date" description:"课程类型限制 结束日期"` // 课程类型限制 结束日期
//CourseLimitSwitch int `json:"courseLimitSwitch" orm:"course_limit_switch" description:"1:屏蔽网员"` // 1:屏蔽网员
//ShowQrcode int `json:"showQrcode" orm:"show_qrcode" description:"1:二维码 2:获客助手 3:手机号"` // 1:二维码 2:获客助手 3:手机号
//QrcodeJwcode int `json:"qrcodeJwcode" orm:"qrcode_jwcode" description:"二维码下精网号"` // 二维码下精网号
//QrcodeJwcodeIds string `json:"qrcodeJwcodeIds" orm:"qrcode_jwcode_ids" description:"二维码下精网号下的ids(以,分隔)"` // 二维码下精网号下的ids(以,分隔)
//RoomId string `json:"roomId" orm:"room_id" description:""` //
//TName string `json:"tName" orm:"t_name" description:"主讲人姓名"` // 主讲人姓名
Name string `json:"name" orm:"name" description:""` //
//Icon string `json:"icon" orm:"icon" description:""` //
//State int `json:"state" orm:"state" description:"0:未开播 1:直播中 2:直播结束 3:已删除"` // 0:未开播 1:直播中 2:直播结束 3:已删除
//Switch string `json:"switch" orm:"switch" description:""` //
//Url string `json:"url" orm:"url" description:""` //
//PlayUrl string `json:"playUrl" orm:"play_url" description:""` //
//PlayUrlM3U8 string `json:"playUrlM3U8" orm:"play_url_m3u8" description:""` //
//PlayUrlLhd string `json:"playUrlLhd" orm:"play_url_lhd" description:"flv(高清)"` // flv(高清)
//PlayUrlM3U8Lhd string `json:"playUrlM3U8Lhd" orm:"play_url_m3u8_lhd" description:"m3u8(高清)"` // m3u8(高清)
//PlayUrlLsd string `json:"playUrlLsd" orm:"play_url_lsd" description:"flv(标清)"` // flv(标清)
//PlayUrlM3U8Lsd string `json:"playUrlM3U8Lsd" orm:"play_url_m3u8_lsd" description:"m3u8(标清)"` // m3u8(标清)
//Cover string `json:"cover" orm:"cover" description:""` //
//Introduce string `json:"introduce" orm:"introduce" description:""` //
StartTime int `json:"startTime" orm:"start_time" description:""` //
//Manager string `json:"manager" orm:"manager" description:""` //
//Product string `json:"product" orm:"product" description:""` //
//ProductId string `json:"productId" orm:"product_id" description:""` //
//Qx int `json:"qx" orm:"qx" description:"直播观看权限 1:所有用户 2:部分客户 3 : 外地客户 4: 静态专区客户 5:大财神 6:终免 7:半年版"` // 直播观看权限 1:所有用户 2:部分客户 3 : 外地客户 4: 静态专区客户 5:大财神 6:终免 7:半年版
//Show int `json:"show" orm:"show" description:"是否展示直播 0:不展示 1:展示"` // 是否展示直播 0:不展示 1:展示
//Oaid string `json:"oaid" orm:"oaid" description:"频道oa号"` // 频道oa号
//Platform int `json:"platform" orm:"platform" description:"直播平台 1是pc直播2是手机直播"` // 直播平台 1是pc直播2是手机直播
//Sig string `json:"sig" orm:"sig" description:"腾讯sig"` // 腾讯sig
//Playback int `json:"playback" orm:"playback" description:"有无回放 1:有 0:无"` // 有无回放 1:有 0:无
//PlaybackType int `json:"playbackType" orm:"playback_type" description:"回放类型 1:永久 2: 有期限"` // 回放类型 1:永久 2: 有期限
//PlaybackExpire int `json:"playbackExpire" orm:"playback_expire" description:"回放过期时间"` // 回放过期时间
//ShowInApp int `json:"showInApp" orm:"show_in_app" description:"0:不在app展示 1:在app展示"` // 0:不在app展示 1:在app展示
//ClassName string `json:"className" orm:"class_name" description:"班级名称"` // 班级名称
//CopyUrl int `json:"copyUrl" orm:"copy_url" description:"1:不允许客户复制链接"` // 1:不允许客户复制链接
//LiveType int `json:"liveType" orm:"live_type" description:"直播形式 1:obs 2:录播 3:连麦 4:重播 5:竖屏推流"` // 直播形式 1:obs 2:录播 3:连麦 4:重播 5:竖屏推流
//RepeatLiveId int `json:"repeatLiveId" orm:"repeat_live_id" description:"重播对应的live_id"` // 重播对应的live_id
//LiveVideoId int `json:"liveVideoId" orm:"live_video_id" description:"录播视频id"` // 录播视频id
//VideoUrl string `json:"videoUrl" orm:"video_url" description:"录播视频地址"` // 录播视频地址
//MemberWatchLimit int `json:"memberWatchLimit" orm:"member_watch_limit" description:"网员观看权限(静态专区) 1:全部用户 2:终免用户"` // 网员观看权限(静态专区) 1:全部用户 2:终免用户
//RealStartTime int `json:"realStartTime" orm:"real_start_time" description:"实际开始时间"` // 实际开始时间
//PopupQrcodeSwitch int `json:"popupQrcodeSwitch" orm:"popup_qrcode_switch" description:"弹窗二维码开关 0:关 1:开"` // 弹窗二维码开关 0:关 1:开
//CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:""` //
//UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:""` //
//SyncPlatform string `json:"syncPlatform" orm:"sync_platform" description:"同步的平台 海外(en), 投教(toujiao)"` // 同步的平台 海外(en), 投教(toujiao)
//SyncToujiaoChannelId int `json:"syncToujiaoChannelId" orm:"sync_toujiao_channel_id" description:"同步投教频道id"` // 同步投教频道id
//SyncOverseaChannelId int `json:"syncOverseaChannelId" orm:"sync_oversea_channel_id" description:"同步海外频道id"` // 同步海外频道id
//SyncLiveId int `json:"syncLiveId" orm:"sync_live_id" description:"从该live_id同步过来的"` // 从该live_id同步过来的
//PayNum int `json:"payNum" orm:"pay_num" description:"付费金豆数量"` // 付费金豆数量
//IsHerdsman int `json:"isHerdsman" orm:"is_herdsman" description:"1:牧民直播间"` // 1:牧民直播间
//HerdsmanLimit int `json:"herdsmanLimit" orm:"herdsman_limit" description:"1:限制只有牧民观看"` // 1:限制只有牧民观看
//ClubType int `json:"clubType" orm:"club_type" description:"俱乐部 1:牧民俱乐部 2:博股论坛 3:神枪手俱乐部 4:环球俱乐部 5:价值投资 6:波段行情 7:抄底卖顶 8:资金及仓位管理"` // 俱乐部 1:牧民俱乐部 2:博股论坛 3:神枪手俱乐部 4:环球俱乐部 5:价值投资 6:波段行情 7:抄底卖顶 8:资金及仓位管理
//ClubTypeLimit int `json:"clubTypeLimit" orm:"club_type_limit" description:"俱乐部权限 0:没有 1:有"` // 俱乐部权限 0:没有 1:有
//ExportPower int `json:"exportPower" orm:"export_power" description:"1:有导入名单权限"` // 1:有导入名单权限
//InvestorSwitch int `json:"investorSwitch" orm:"investor_switch" description:"1: 开启合格投资者"` // 1: 开启合格投资者
//SignSwitch int `json:"signSwitch" orm:"sign_switch" description:"1:开启签到"` // 1:开启签到
//OnlinePeopleSwitch int `json:"onlinePeopleSwitch" orm:"online_people_switch" description:"在线人数开关 1:实时在线人数 2:场观次数"` // 在线人数开关 1:实时在线人数 2:场观次数
//LessonId int `json:"lessonId" orm:"lesson_id" description:"课程id"` // 课程id
//LessonSectionId int `json:"lessonSectionId" orm:"lesson_section_id" description:"课程章节id"` // 课程章节id
//Password string `json:"password" orm:"password" description:"口令"` // 口令
//Sort int `json:"sort" orm:"sort" description:"排序(大的优先)"` // 排序(大的优先)
//ContentIntro string `json:"contentIntro" orm:"content_intro" description:"内容介绍"` // 内容介绍
//RelatedClubType int `json:"relatedClubType" orm:"related_club_type" description:"关联俱乐部 1:牧民俱乐部 2:博股论坛 3:神枪手俱乐部 4:环球俱乐部"` // 关联俱乐部 1:牧民俱乐部 2:博股论坛 3:神枪手俱乐部 4:环球俱乐部
//Poster string `json:"poster" orm:"poster" description:"海报"` // 海报
//Tabs string `json:"tabs" orm:"tabs" description:"1:推荐课程 2:课程作业 3:邀约榜"` // 1:推荐课程 2:课程作业 3:邀约榜
//PreviewVideo string `json:"previewVideo" orm:"preview_video" description:"预告视频"` // 预告视频
//ReceiveKit int `json:"receiveKit" orm:"receive_kit" description:"1: 领取锦囊指标"` // 1: 领取锦囊指标
//OaMark string `json:"oaMark" orm:"oa_mark" description:"oa_mark"` // oa_mark
//OaMarkName string `json:"oaMarkName" orm:"oa_mark_name" description:"oa_mark_name"` // oa_mark_name
//Stage int `json:"stage" orm:"stage" description:"销售阶段 1:课程销售阶段 2:软件销售阶段"` // 销售阶段 1:课程销售阶段 2:软件销售阶段
//StageCourse int `json:"stageCourse" orm:"stage_course" description:"阶段课程类型 1:开班课 2:服务课 3:销售课"` // 阶段课程类型 1:开班课 2:服务课 3:销售课
//TopTime int `json:"topTime" orm:"top_time" description:"置顶时间"` // 置顶时间
//PlaybackSort int `json:"playbackSort" orm:"playback_sort" description:"直播回放排序, 越大越靠前"` // 直播回放排序, 越大越靠前
//RelateClassIds string `json:"relateClassIds" orm:"relate_class_ids" description:"关联班级ids"` // 关联班级ids
//JoinClassButton int `json:"joinClassButton" orm:"join_class_button" description:"进群按钮 1:开启"` // 进群按钮 1:开启
} }

32
link_homework/internal/service/article.go

@ -0,0 +1,32 @@
// ================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// You can delete these comments if you wish manually maintain this interface file.
// ================================================================================
package service
import (
"context"
"link_homework/internal/model/entity"
)
type (
IArticle interface {
GetArticleList(ctx context.Context, name string) (articleList []*entity.FxArticle, err error)
}
)
var (
localArticle IArticle
)
func Article() IArticle {
if localArticle == nil {
panic("implement not found for interface IArticle, forgot register?")
}
return localArticle
}
func RegisterArticle(i IArticle) {
localArticle = i
}

34
link_homework/internal/service/client.go

@ -0,0 +1,34 @@
// ================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// You can delete these comments if you wish manually maintain this interface file.
// ================================================================================
package service
import (
"context"
"link_homework/api/v1/ClientPage"
)
type (
IClient interface {
ClientGetHomeworkList(ctx context.Context, jwcode int) (homeworkList []ClientPage.GetHomeworkListRse, err error)
GetHomeworkQuestion(ctx context.Context, groupId int) (questions []ClientPage.GetHomeworkQuestionRes, err error)
CommitHomework(ctx context.Context, req ClientPage.CommitHomeworkReq, jwcode int) (err error)
}
)
var (
localClient IClient
)
func Client() IClient {
if localClient == nil {
panic("implement not found for interface IClient, forgot register?")
}
return localClient
}
func RegisterClient(i IClient) {
localClient = i
}

37
link_homework/internal/service/homework.go

@ -0,0 +1,37 @@
// ================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// You can delete these comments if you wish manually maintain this interface file.
// ================================================================================
package service
import (
"context"
"link_homework/api/v1/homework"
"link_homework/internal/model/entity"
)
type (
IHomework interface {
GetHomeworkList(ctx context.Context, pageNo int, pageSize int) (homeworkList []*entity.ActivityInteractiveGroup, err error)
GetHomeworkListTotal(ctx context.Context) (total int, err error)
GetHomework(ctx context.Context, id int) (homework *entity.ActivityInteractiveGroup, err error)
AddHomework(ctx context.Context, req *homework.AddHomeworkReq) (err error)
EditHomework(ctx context.Context, req *homework.EditHomeworkReq) (err error)
}
)
var (
localHomework IHomework
)
func Homework() IHomework {
if localHomework == nil {
panic("implement not found for interface IHomework, forgot register?")
}
return localHomework
}
func RegisterHomework(i IHomework) {
localHomework = i
}

32
link_homework/internal/service/live.go

@ -0,0 +1,32 @@
// ================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// You can delete these comments if you wish manually maintain this interface file.
// ================================================================================
package service
import (
"context"
"link_homework/internal/model/entity"
)
type (
ILive interface {
GetLiveList(ctx context.Context) (liveList []*entity.Live, err error)
}
)
var (
localLive ILive
)
func Live() ILive {
if localLive == nil {
panic("implement not found for interface ILive, forgot register?")
}
return localLive
}
func RegisterLive(i ILive) {
localLive = i
}

34
link_homework/internal/service/login.go

@ -0,0 +1,34 @@
// ================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// You can delete these comments if you wish manually maintain this interface file.
// ================================================================================
package service
import (
"context"
)
type (
ILoginLogic interface {
// Login 方法实现用户登录并生成 Token
Login(ctx context.Context, username string, password string) (string, error)
// ValidateToken 验证 Token 是否有效
ValidateToken(ctx context.Context, tokenString string) (bool, error)
}
)
var (
localLoginLogic ILoginLogic
)
func LoginLogic() ILoginLogic {
if localLoginLogic == nil {
panic("implement not found for interface ILoginLogic, forgot register?")
}
return localLoginLogic
}
func RegisterLoginLogic(i ILoginLogic) {
localLoginLogic = i
}

8
link_homework/internal/service/middleware.go

@ -0,0 +1,8 @@
// ================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// You can delete these comments if you wish manually maintain this interface file.
// ================================================================================
package service
type ()

43
link_homework/internal/service/record.go

@ -0,0 +1,43 @@
// ================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// You can delete these comments if you wish manually maintain this interface file.
// ================================================================================
package service
import (
"context"
pkgRecord "link_homework/api/v1/record"
"github.com/gogf/gf/v2/net/ghttp"
)
type (
IRecord interface {
// 无条件全查
GetRecordList(ctx context.Context, groupId int, pageNo int, pageSize int) (record []pkgRecord.GetRecordListRes, err error)
// 根据条件查询 对所有结果进行筛选
GetRecordByCondition(ctx context.Context, groupId int, jwcode int, deptId string, shopId string, pageNo int, pageSize int) (record []pkgRecord.GetRecordListRes, err error)
// 查询部门信息
GetDeptInfo(ctx context.Context) (depts []pkgRecord.GetDeptInfoRes, err error)
// 根据部门信息查询门店信息
GetShopInfoByDeptId(ctx context.Context, deptId string) (shops []pkgRecord.GetShopInfoByDeptIdRes, err error)
// ExportExcel 查询数据,创建excel文件,设置表头,写入数据,设置文件名,保存到缓冲区并返回,设置响应头,指定内容类型为excel文件,指定文件名为fileName,将buffer中的内容写入响应
ExportExcel(r *ghttp.Request, groupId int, jwcode int, deptId string, shopId string, pageNo int, pageSize int)
}
)
var (
localRecord IRecord
)
func Record() IRecord {
if localRecord == nil {
panic("implement not found for interface IRecord, forgot register?")
}
return localRecord
}
func RegisterRecord(i IRecord) {
localRecord = i
}

36
link_homework/main.go

@ -4,9 +4,9 @@ import (
"github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/frame/g"
_ "link_homework/internal/packed" _ "link_homework/internal/packed"
"github.com/gogf/gf/v2/os/gctx"
_ "github.com/gogf/gf/contrib/drivers/mysql/v2" _ "github.com/gogf/gf/contrib/drivers/mysql/v2"
_ "github.com/gogf/gf/contrib/nosql/redis/v2"
"github.com/gogf/gf/v2/os/gctx"
"link_homework/internal/cmd" "link_homework/internal/cmd"
@ -17,28 +17,46 @@ func main() {
ctx := gctx.GetInitCtx() ctx := gctx.GetInitCtx()
//启动日志 //启动日志
g.Log().Info(ctx, "服务启动中")
//g.Log().Info(ctx, "服务启动中")
//检查数据库链接 //检查数据库链接
// 检查默认数据库链接 // 检查默认数据库链接
db := g.DB() db := g.DB()
if err := db.PingMaster(); err != nil { if err := db.PingMaster(); err != nil {
g.Log().Fatal(ctx, "默认数据库链接失败,请检查数据库链接配置")
//g.Log().Fatal(ctx, "默认数据库链接失败,请检查数据库链接配置")
return return
} }
g.Log().Info(ctx, "默认数据库链接成功")
//g.Log().Info(ctx, "默认数据库链接成功")
// 检查 CMS 数据库链接 // 检查 CMS 数据库链接
cmsDb := g.DB("cms") cmsDb := g.DB("cms")
if err := cmsDb.PingMaster(); err != nil { if err := cmsDb.PingMaster(); err != nil {
g.Log().Fatal(ctx, "CMS 数据库链接失败,请检查数据库链接配置")
//g.Log().Fatal(ctx, "CMS 数据库链接失败,请检查数据库链接配置")
return
}
//g.Log().Info(ctx, "CMS 数据库链接成功")
// 检查 Redis 配置并连接
// 如果配置中存在 Redis 配置,初始化 Redis 客户端
// 打印 Redis 配置,确保它加载正确
//redisConfig, err := g.Cfg().Get(ctx, "redis.default")
_, err := g.Cfg().Get(ctx, "redis.default")
if err != nil {
//fmt.Println("获取 Redis 配置失败:", err)
return
}
//fmt.Printf("Redis 配置:%v\n", redisConfig)
// 测试 Redis 连接
_, err = g.Redis().Do(ctx, "PING")
if err != nil {
//g.Log().Fatal(ctx, fmt.Sprintf("Redis 链接失败: %v", err))
return return
} }
g.Log().Info(ctx, "CMS 数据库链接成功")
//g.Log().Info(ctx, "Redis 链接成功")
//启动主命令逻辑 //启动主命令逻辑
cmd.Main.Run(ctx) cmd.Main.Run(ctx)
//服务启动完成日志 //服务启动完成日志
g.Log().Info(ctx, "服务启动完成")
//g.Log().Info(ctx, "服务启动完成")
} }

17
link_homework/manifest/config/config.yaml

@ -1,13 +1,11 @@
# https://goframe.org/docs/web/server-config-file-template # https://goframe.org/docs/web/server-config-file-template
server: server:
address: ":8080"
openapiPath: "/api.json"
swaggerPath: "/swagger"
address: ":8080"
# https://goframe.org/docs/core/glog-config # https://goframe.org/docs/core/glog-config
logger:
level : "all"
stdout: true
#logger:
# level : "all"
# stdout: true
# https://goframe.org/docs/core/gdb-config-file # https://goframe.org/docs/core/gdb-config-file
database: database:
@ -18,4 +16,9 @@ database:
link: "mysql:cms:AF42R3ib6YkFaemm@tcp(39.101.133.168:3306)/cms?charset=utf8mb4&parseTime=True&loc=Local" link: "mysql:cms:AF42R3ib6YkFaemm@tcp(39.101.133.168:3306)/cms?charset=utf8mb4&parseTime=True&loc=Local"
debug: true debug: true
# redis暂不配置,记得加
# redis配置
redis:
default:
address: 121.89.234.155:7001
pass: RH0YTFo0ByLD
db: 1

8
link_homework/manifest/deploy/kustomize/overlays/develop/configmap.yaml

@ -8,7 +8,7 @@ data:
address: ":8000" address: ":8000"
openapiPath: "/api.json" openapiPath: "/api.json"
swaggerPath: "/swagger" swaggerPath: "/swagger"
logger:
level : "all"
stdout: true
#
# logger:
# level : "all"
# stdout: true

142
link_homework/utility/utility.go

@ -0,0 +1,142 @@
package utility
import (
"encoding/json"
"errors"
"fmt"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gctx"
"io/ioutil"
"link_homework/internal/consts"
"link_homework/internal/model/dto"
"net/http"
"strconv"
"strings"
)
// 获取 URL
func getUrl(key, hashKey string) *dto.Result {
ctx := gctx.New()
// 1. 从 Redis 获取 URL
redisUrl, err := g.Redis().Do(ctx, "HGET", key, hashKey)
if err == nil && redisUrl.String() != "" {
//g.Log().Infof(ctx, "从 Redis 获取到 URL: %s", redisUrl.String())
return dto.SuccessWithData(redisUrl.String())
}
// 2. 如果 Redis 中没有,查询数据库
urlResult := selectBaseUrl(hashKey)
if urlResult.Code != 200 {
return urlResult // 数据库查询失败,返回错误
}
url := urlResult.Data.(string)
// 3. 将 URL 存入 Redis
if _, err = g.Redis().Do(ctx, "HSET", key, hashKey, url); err != nil {
//g.Log().Warningf(ctx, "将数据存入 Redis 失败: %v", err)
}
//g.Log().Infof(ctx, "将 URL 存入 Redis: %s", url)
return dto.SuccessWithData(url)
}
// 查询数据库中的 URL
func selectBaseUrl(hashKey string) *dto.Result {
//ctx := gctx.New()
// 查询数据库
value, err := g.DB("cms").Model("env").Where("`key` = ?", hashKey).Value("value")
if err != nil {
//g.Log().Errorf(ctx, "数据库查询失败, 错误: %v, key: %s", err, hashKey)
return dto.Error("数据库查询失败")
}
if value.IsNil() || value.String() == "" {
//g.Log().Errorf(ctx, "未找到对应数据, key: %s", hashKey)
return dto.Error("未找到对应数据")
}
return dto.SuccessWithData(value.String())
}
// 获取 jwcode
// 获取 jwcode
func GetJwcodeJSON(token string) (int, error) { // 返回类型为 int
//ctx := gctx.New()
// 1. 获取基础 URL
urlResult := getUrl(consts.URL_KEY, consts.URL_HASH_KEY)
if urlResult.Code != 200 {
//g.Log().Errorf(ctx, "获取基础 URL 失败: %s", urlResult.Message)
return 0, errors.New("获取基础 URL 失败: " + urlResult.Message)
}
baseUrl := urlResult.Data.(string)
//g.Log().Debugf(ctx, "成功获取基础 URL: %s", baseUrl)
// 2. 拼接完整的 URL
url := baseUrl + "/api/v2/member/info"
requestBody := strings.NewReader(`{"token":"` + token + `"}`)
// 3. 创建 HTTP 请求
req, err := http.NewRequest("POST", url, requestBody)
if err != nil {
//g.Log().Errorf(ctx, "HTTP 请求创建失败: %v", err)
return 0, fmt.Errorf("HTTP 请求创建失败: %w", err)
}
req.Header.Set("Content-Type", "application/json")
// 4. 发送请求
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
//g.Log().Errorf(ctx, "HTTP 请求失败: %v", err)
return 0, fmt.Errorf("HTTP 请求失败: %w", err)
}
defer resp.Body.Close()
// 5. 检查 HTTP 状态码
if resp.StatusCode != http.StatusOK {
//g.Log().Errorf(ctx, "HTTP 状态码错误: %d", resp.StatusCode)
return 0, fmt.Errorf("HTTP 状态码错误: %d", resp.StatusCode)
}
// 6. 读取并解析响应体
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
//g.Log().Errorf(ctx, "读取响应失败: %v", err)
return 0, fmt.Errorf("读取响应失败: %w", err)
}
//g.Log().Debugf(ctx, "响应体内容: %s", string(body))
// 7. 解析 JSON 数据
var jsonResponse map[string]interface{}
if err = json.Unmarshal(body, &jsonResponse); err != nil {
//g.Log().Errorf(ctx, "解析 JSON 失败: %v", err)
return 0, fmt.Errorf("解析 JSON 失败: %w", err)
}
//g.Log().Debugf(ctx, "解析后的 JSON: %+v", jsonResponse)
// 8. 提取 data 节点
data, ok := jsonResponse["data"].(map[string]interface{})
if !ok {
//g.Log().Errorf(ctx, "响应体中没有 data 节点,完整响应: %+v", jsonResponse)
return 0, errors.New("响应体中没有 data 节点")
}
// 9. 提取 jwcode 并转换为整数
jwcode, ok := data["jwcode"].(string) // 首先尝试解析为字符串
if ok {
jwcodeInt, err := strconv.Atoi(jwcode) // 将字符串转换为整数
if err != nil {
//g.Log().Errorf(ctx, "解析 jwcode 字段失败: %v", err)
return 0, fmt.Errorf("解析 jwcode 字段失败: %w", err)
}
//g.Log().Infof(ctx, "成功获取 jwcode: %d", jwcodeInt)
return jwcodeInt, nil
}
// 如果 jwcode 不是字符串,记录错误日志
//g.Log().Errorf(ctx, "data 节点中没有 jwcode 字段,或字段格式不正确,data: %+v", data)
return 0, errors.New("响应体中没有有效的 jwcode 字段")
}
Loading…
Cancel
Save