31 Commits

Author SHA1 Message Date
lijikun bc977a9216 12.31日,正式上线前调整解析token的地址 6 months ago
lijikun 27acfaf339 Merge branch 'dev' of http://39.101.133.168:8807/wanglin/CouponBackendGo into dev 6 months ago
lijikun d2b9b3619b 12.31日,将导入用户jwcode并回显改为直接导入并上传,以及传到后端一个数组并上传两个接口,导出未写 6 months ago
majun 03b200aa8f Merge branch 'majun' into dev 6 months ago
majun 80a40f2e67 优化卡券失效时间的代码 6 months ago
lijikun 65adb8a352 12.30日,将导入符合条件的jwcode到redis改为导入到数据库表后,将coupon_qualified_users表纳入管理,使得导入数据库表没有问题,有关coupon_qualified_users表的也都没有问题 6 months ago
lijikun b77770c8ac 12.30日,将导入符合条件的jwcode到redis改为导入到数据库表后,将coupon_qualified_users表纳入管理,使得导入数据库表没有问题,有关coupon_qualified_users表的也都没有问题 6 months ago
lijikun 6ac88add3b 12.30日,将导入符合条件的jwcode到redis改为导入到数据库表 6 months ago
lijikun 1fd602b689 Merge branch 'dev' of http://39.101.133.168:8807/wanglin/CouponBackendGo into dev 6 months ago
majun c7bf11108c Merge branch 'majun' into dev 6 months ago
lijikun 29f06aa2e6 Merge branch 'ljk' into dev 6 months ago
lijikun 15f102b89b 12.28日下午增加请求校验, 删除一些非必须的redis 6 months ago
majun 6f859fd76a 简化代码 6 months ago
lijikun eccc482dbf 12.28日下午增加请求校验 6 months ago
lijikun 014de4c7b7 12.28日下午合并majun分支 6 months ago
lijikun 4fc9b980c5 12.28日下午查看拥有卡券的用户添加分页,操作表时会更新redis 6 months ago
lijikun cf75ca3016 12.28日下午查看拥有卡券的用户添加分页,操作表时会更新redis 6 months ago
majun 6ccdf41bba 后端合并 6 months ago
majun d6db6d2b7d 后端合并 6 months ago
lijikun 94f7d77ffb 12.28日合并ljk, mj-wq分支 6 months ago
lijikun bd40c2d71c 12.28日mj分离后添加,删除多余方法 6 months ago
majun 28b1d81f18 完成编辑卡券接口 6 months ago
lijikun b252850557 12.28日检测用户是否有抽奖机会,是否抽取过, 6 months ago
majun e8d40bfb48 编写编辑卡券接口 6 months ago
majun 8894230c06 编写新建卡券接口 6 months ago
majun 8b7ae02a8b 编写添加用户选择武器记录接口 6 months ago
lijikun b84643bdc2 12.27日,完成给用户发放卡券,给单个用户发放卡券,从excel中导入数据到redis,解析token 6 months ago
majun 9713e047bf 编写删、查接口 6 months ago
majun 39670b7d3b 熟悉接口 6 months ago
lijikun 1bc4c62501 12.26日完成从excel表格中导入数据;调整数据库中jwcode类型(varchar->int)并修改dao层 6 months ago
lijikun 397071ea1a 12.25日生成service,编写查询拥有卡券的用户,删除用户卡券 6 months ago
  1. 0
      api/v1/.gitkeep
  2. 24
      api/v1/coupon/coupon.go
  3. 57
      api/v1/couponusers/couponUsers.go
  4. 7
      go.mod
  5. 16
      go.sum
  6. 2
      hack/config.yaml
  7. 19
      internal/cmd/cmd.go
  8. 9
      internal/consts/consts.go
  9. 0
      internal/controller/.gitkeep
  10. 105
      internal/controller/coupon/coupon.go
  11. 259
      internal/controller/couponusers/couponUsers.go
  12. 0
      internal/dao/.gitkeep
  13. 27
      internal/dao/coupon.go
  14. 27
      internal/dao/coupon_qualified_users.go
  15. 27
      internal/dao/coupon_users.go
  16. 89
      internal/dao/internal/coupon.go
  17. 75
      internal/dao/internal/coupon_qualified_users.go
  18. 85
      internal/dao/internal/coupon_users.go
  19. 139
      internal/dao/internal/member_info.go
  20. 27
      internal/dao/member_info.go
  21. 0
      internal/logic/.gitkeep
  22. 97
      internal/logic/coupon/coupon.go
  23. 402
      internal/logic/couponusers/couponUsers.go
  24. 10
      internal/logic/logic.go
  25. 10
      internal/logic/middleware/interceptor.go
  26. 0
      internal/model/.gitkeep
  27. 0
      internal/model/do/.gitkeep
  28. 24
      internal/model/do/coupon.go
  29. 16
      internal/model/do/coupon_qualified_users.go
  30. 21
      internal/model/do/coupon_users.go
  31. 49
      internal/model/do/member_info.go
  32. 9
      internal/model/dto/Result.go
  33. 15
      internal/model/dto/dto_coupon.go
  34. 0
      internal/model/entity/.gitkeep
  35. 22
      internal/model/entity/coupon.go
  36. 11
      internal/model/entity/coupon_qualified_users.go
  37. 16
      internal/model/entity/coupon_users.go
  38. 47
      internal/model/entity/member_info.go
  39. 0
      internal/service/.gitkeep
  40. 37
      internal/service/coupon.go
  41. 54
      internal/service/couponusers.go
  42. 8
      internal/service/middleware.go
  43. 129
      utility/utility.go

0
api/v1/.gitkeep

24
api/v1/coupon/coupon.go

@ -0,0 +1,24 @@
package coupon
import "github.com/gogf/gf/v2/os/gtime"
type GetCouponListReq struct {
PageNo int `v:"required#页码不能为空" dc:"页码"`
PageSize int `v:"required#页面大小不能为空" dc:"页面大小"`
}
type GetCouponReq struct {
Id int `v:"required#优惠券id不能为空" dc:"优惠券id"`
}
type DeleteCouponReq struct {
Id int `v:"required#优惠券id不能为空" dc:"优惠券id"`
}
type InsertCouponReq struct {
Id int `dc:"优惠券id"`
Title string `v:"required#优惠券名字不能为空" dc:"优惠券名字"`
Image string `v:"required#优惠券图片不能为空" dc:"优惠券图片"`
StartTime *gtime.Time `v:"required#优惠券生效时间不能为空" dc:"生效时间"`
EndTime *gtime.Time `v:"required#优惠券失效时间不能为空" dc:"失效时间"`
}

57
api/v1/couponusers/couponUsers.go

@ -0,0 +1,57 @@
package couponusers
// GetCouponUsersReq 查询卡券用户
type GetCouponUsersReq struct {
CouponId int `json:"couponId" v:"required#卡券id不能为空" dc:"卡券id"`
Jwcode int `json:"jwcode" dc:"查询条件中的精网号"`
Name string `json:"name" dc:"查询条件中的名字"`
PageNo int `json:"pageNo" v:"required#分页信息不能为空" dc:"页码"`
PageSize int `json:"pageSize" v:"required#分页信息不能为空" dc:"每页数量"`
}
// GetCouponUsersRes 查询卡券用户
type GetCouponUsersRes struct {
Name string `json:"name" dc:"姓名"`
Jwcode int `json:"jwcode" dc:"精网号"`
DeptName string `json:"deptName" dc:"部门"`
ShopName string `json:"shopName" dc:"门店"`
}
// DelCouponUserByJwcodeReq 删除卡券用户
type DelCouponUserByJwcodeReq struct {
CouponId int `json:"couponId" v:"required#卡券id不能为空" dc:"卡券id"`
Jwcode int `json:"jwcode" v:"required#精网号不能为空" dc:"精网号"`
}
// InsertCouponUserReq 给多个用户发放卡券 导入excel
type InsertCouponUserReq struct {
CouponId int `json:"couponId" v:"required#卡券id不能为空" dc:"卡券id"`
//Jwcodes []int `json:"jwcodes" v:"required#精网号不能为空" dc:"精网号"`
}
// InsertCouponUserByJwcodeStrReq 给多个用户发放卡券 传jwcodes字符串
type InsertCouponUserByJwcodeStrReq struct {
CouponId int `json:"couponId" v:"required#卡券id不能为空" dc:"卡券id"`
Jwcodes string `json:"jwcodes" v:"required#精网号不能为空" dc:"精网号"`
}
// IssueCouponUserReq 给单个用户发放卡券
type IssueCouponUserReq struct {
CouponId int `json:"couponId" v:"required#卡券id不能为空" dc:"卡券id"`
}
// IsEligibleUserReq 检测用户是否有抽取资格,是否已抽取
type IsEligibleUserReq struct {
CouponIds []int `json:"couponIds" v:"required#用于检测是否已抽取,不能为空" dc:"能抽出的卡券id"`
}
// AddRecordReq 添加武器
type AddRecordReq struct {
CouponId int `json:"couponId" dc:"卡券id"`
Name string `json:"name" dc:"选择武器名称"`
}
// InsertCouponUserRes 判断能否抽取卡券,给单个用户发放卡券 用于存放满足条件的精网号
type InsertCouponUserRes struct {
Jwcode int `json:"jwcode" dc:"精网号"`
}

7
go.mod

@ -6,6 +6,7 @@ require (
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.8.3
github.com/gogf/gf/contrib/nosql/redis/v2 v2.8.3
github.com/gogf/gf/v2 v2.8.3
github.com/xuri/excelize/v2 v2.9.0
)
require (
@ -25,13 +26,19 @@ require (
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // 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/redis/go-redis/v9 v9.7.0 // indirect
github.com/richardlehane/mscfb v1.0.4 // indirect
github.com/richardlehane/msoleps v1.0.4 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d // indirect
github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 // indirect
go.opentelemetry.io/otel 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/trace v1.24.0 // indirect
golang.org/x/crypto v0.30.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

16
go.sum

@ -43,15 +43,28 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
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/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
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/richardlehane/mscfb v1.0.4 h1:WULscsljNPConisD5hR0+OyZjwK46Pfyr6mPu5ZawpM=
github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk=
github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
github.com/richardlehane/msoleps v1.0.4 h1:WuESlvhX3gH2IHcd8UqyCuFY5yiq/GR/yqaSM/9/g00=
github.com/richardlehane/msoleps v1.0.4/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d h1:llb0neMWDQe87IzJLS4Ci7psK/lVsjIS2otl+1WyRyY=
github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
github.com/xuri/excelize/v2 v2.9.0 h1:1tgOaEq92IOEumR1/JfYS/eR0KHOCsRv/rYXXh6YJQE=
github.com/xuri/excelize/v2 v2.9.0/go.mod h1:uqey4QBZ9gdMeWApPLdhm9x+9o2lq4iVmjiLfBS5hdE=
github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 h1:hPVCafDV85blFTabnqKgNhDCkJX25eik94Si9cTER4A=
github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
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/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI=
@ -60,6 +73,9 @@ go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucg
go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg=
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=
golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY=
golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/image v0.18.0 h1:jGzIakQa/ZXI1I0Fxvaa9W7yP25TqT6cHIHn+6CqvSQ=
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=

2
hack/config.yaml

@ -6,7 +6,7 @@ gfcli:
dao:
- link: "mysql:live:p4jMAMShNM8HTrbX@tcp(39.101.133.168:3306)/live?charset=utf8mb4&parseTime=True&loc=Local"
group: "default"
tables: "coupon, coupon_users, member_info"
tables: "coupon, coupon_users, member_info, coupon_qualified_users"
descriptionTag: true
docker:

19
internal/cmd/cmd.go

@ -1,6 +1,9 @@
package cmd
import (
"CouponBackendGo/internal/controller/coupon"
"CouponBackendGo/internal/controller/couponusers"
"CouponBackendGo/internal/logic/middleware"
"context"
"github.com/gogf/gf/v2/frame/g"
@ -16,7 +19,21 @@ var (
Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
s := g.Server()
s.Group("/api/coupon_backend", func(group *ghttp.RouterGroup) {
group.Middleware(middleware.MiddlewareCORS)
group.POST("/get-coupon-users", couponusers.NewCouponUsers().GetCouponUsers) // 获取拥有卡券的用户列表
group.POST("/delete-coupon-user", couponusers.NewCouponUsers().DeleteCouponUserByJwcode) //删除用户卡券
group.POST("/insert-coupon-users-by-excel", couponusers.NewCouponUsers().InsertCouponUserByExcel) // 通过excel导入jwcode并发放卡券
//group.POST("/insert-coupon-user", couponusers.NewCouponUsers().InsertCouponUser) //给用户发放卡券
group.POST("/insert-coupon-users-by-str", couponusers.NewCouponUsers().InsertCouponUserByJwcodeStr) //通过jwcodes字符串导入jwcode并发放卡券
//近期使用
group.POST("/insert-users-to-redis", couponusers.NewCouponUsers().InsertJwcodesToRedisByExcel) //导入满足条件的用户jwcode到redis
group.POST("/is-eligible-user", couponusers.NewCouponUsers().IsEligibleUser) //判断用户是否满足领取条件
group.POST("/issue-coupon-to-users", couponusers.NewCouponUsers().IssueCouponUser) //给单个用户发放卡券
group.POST("/add-record", couponusers.NewCouponUsers().AddRecord) //添加用户选择武器记录
group.POST("/get-coupon-list", coupon.Coupon().GetCouponList) //获取卡券列表
group.POST("/get-coupon", coupon.Coupon().GetCoupon) //获取卡券
group.POST("/delete-coupon", coupon.Coupon().DeleteCoupon) //删除卡券
group.POST("/insert-coupon", coupon.Coupon().InsertCoupon) //添加卡券
})
s.Run()
return nil

9
internal/consts/consts.go

@ -1 +1,10 @@
package consts
const (
URL_KEY = "jingwang:cms:env" //Redis中的键
//内容: http://39.101.133.168:8828/hljw
//测试环境解析token接口: http://39.101.133.168:8828/hljw/api/v2/member/info
//正式环境解析token接口: http://api.homilychart.com/hljw/api/v2/member/info
//URL_HASH_KEY = "HLJW_BASE_URL"
URL_HASH_KEY = "HLJW_URL"
)

0
internal/controller/.gitkeep

105
internal/controller/coupon/coupon.go

@ -0,0 +1,105 @@
package coupon
import (
"CouponBackendGo/api/v1/coupon"
"CouponBackendGo/internal/model/dto"
"CouponBackendGo/internal/service"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
)
type cCoupon struct{}
func Coupon() *cCoupon {
return &cCoupon{}
}
func (c cCoupon) GetCouponList(r *ghttp.Request) {
var req *coupon.GetCouponListReq
if err := r.Parse(&req); err != nil {
r.Response.WriteJsonExit(dto.Result{
Code: 400,
Message: err.Error(),
})
}
res, err := service.Coupon().GetCouponList(r.Context(), req.PageNo, req.PageSize)
total, err := service.Coupon().GetCouponListTotal(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 cCoupon) GetCoupon(r *ghttp.Request) {
var req *coupon.GetCouponReq
if err := r.Parse(&req); err != nil {
r.Response.WriteJsonExit(dto.Result{
Code: 400,
Message: err.Error(),
})
}
res, err := service.Coupon().GetCoupon(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 cCoupon) DeleteCoupon(r *ghttp.Request) {
var req *coupon.DeleteCouponReq
if err := r.Parse(&req); err != nil {
r.Response.WriteJsonExit(dto.Result{
Code: 400,
Message: err.Error(),
})
}
err := service.Coupon().DeleteCoupon(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",
})
}
func (c cCoupon) InsertCoupon(r *ghttp.Request) {
var req *coupon.InsertCouponReq
if err := r.Parse(&req); err != nil {
r.Response.WriteJsonExit(dto.Result{
Code: 400,
Message: err.Error(),
})
}
err := service.Coupon().InsertCoupon(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",
})
}

259
internal/controller/couponusers/couponUsers.go

@ -0,0 +1,259 @@
package couponusers
import (
"CouponBackendGo/api/v1/couponusers"
"CouponBackendGo/internal/model/dto"
"CouponBackendGo/internal/service"
"CouponBackendGo/utility"
"fmt"
"github.com/gogf/gf/v2/net/ghttp"
"mime/multipart"
)
type CouponUsers struct{}
func NewCouponUsers() *CouponUsers {
return &CouponUsers{}
}
// 获取拥有卡券的用户列表
func (c *CouponUsers) GetCouponUsers(r *ghttp.Request) {
//解析请求
var req *couponusers.GetCouponUsersReq
if err := r.Parse(&req); err != nil {
r.Response.WriteJsonExit(dto.Error(err.Error()))
}
result, err := service.CouponUsers().GetCouponUsersByCondition(r.Context(), req.CouponId, req.Jwcode, req.Name, req.PageNo, req.PageSize)
//错误处理
if err != nil {
r.Response.WriteJsonExit(dto.Error(err.Error()))
}
//没有错误,但获取到了0条
if result == nil {
r.Response.WriteJsonExit(dto.Error("没有符合条件的用户"))
}
//成功处理
r.Response.WriteJsonExit(dto.SuccessWithData(result))
}
// 删除用户卡券
func (c *CouponUsers) DeleteCouponUserByJwcode(r *ghttp.Request) {
// 解析请求
var req *couponusers.DelCouponUserByJwcodeReq
if err := r.Parse(&req); err != nil {
r.Response.WriteJsonExit(dto.Error(err.Error()))
}
result, err := service.CouponUsers().DeleteCouponUserByJwcode(r.Context(), req.CouponId, req.Jwcode)
//错误处理
if err != nil {
r.Response.WriteJsonExit(dto.Error(err.Error()))
}
//获取影响到的数据条数
affected, err := result.RowsAffected()
//没有错误,但删除0条
if affected == 0 {
r.Response.WriteJsonExit(dto.Error("删除失败,删除了0条"))
}
//成功处理
r.Response.WriteJsonExit(dto.SuccessWithMsg("删除成功"))
}
// 接受前端传来的excel表格,并解析,返回jwcode切片,可以有重复的,在插入时进行验证,如果有重复的,只插入一次
func (c *CouponUsers) InsertCouponUserByExcel(r *ghttp.Request) {
/*解析请求*/
var req *couponusers.InsertCouponUserReq
if err := r.Parse(&req); err != nil {
r.Response.WriteJsonExit(dto.Error(err.Error()))
}
/*解析请求*/
// 从请求中获取文件
file, _, err := r.FormFile("excelFile")
if err != nil {
r.Response.WriteJsonExit(dto.Error(err.Error()))
}
// 延时关闭文件
defer func(file multipart.File) {
err := file.Close()
if err != nil {
// 处理关闭文件时的错误
r.Response.WriteJsonExit(dto.Error("获取的文件关闭失败"))
}
}(file)
//参数校验,检查文件是否为空
if file == nil {
r.Response.WriteJsonExit(dto.Error("获取的文件为空"))
}
/*调用方法解析excel文件,并将解析出结果传入另一个函数去发放卡券*/
result, err := service.CouponUsers().InsertJwcodeByExcel(r.Context(), file, req.CouponId)
//错误处理
if err != nil {
r.Response.WriteJsonExit(dto.Error(err.Error()))
}
//没报错,但插入数据0条
if result == 0 {
r.Response.WriteJsonExit(dto.Error("发放失败,发放了0人"))
}
//成功处理
r.Response.WriteJsonExit(dto.SuccessWithMsg(fmt.Sprintf("发放成功,发放了%d人", result)))
/*调用方法解析excel文件,并将解析出结果传入另一个函数去发放卡券*/
}
// 传入jwcodes字符串,解析并发放卡券
func (c *CouponUsers) InsertCouponUserByJwcodeStr(r *ghttp.Request) {
// 解析请求
var req *couponusers.InsertCouponUserByJwcodeStrReq
if err := r.Parse(&req); err != nil {
r.Response.WriteJsonExit(dto.Error(err.Error()))
}
result, err := service.CouponUsers().InsertCouponUsersByJwcodeStr(r.Context(), req.Jwcodes, req.CouponId)
//错误处理
if err != nil {
r.Response.WriteJsonExit(dto.Error(err.Error()))
}
//没报错,但插入数据0条
if result == 0 {
r.Response.WriteJsonExit(dto.Error("发放失败,发放了0人"))
}
//成功处理
r.Response.WriteJsonExit(dto.SuccessWithMsg(fmt.Sprintf("发放成功,发放了%d人", result)))
}
/*近期使用*/
// 导入满足条件的用户jwcode到redis //不导入到redis了,导入到数据库表中
func (c *CouponUsers) InsertJwcodesToRedisByExcel(r *ghttp.Request) {
// 从请求中获取文件
file, _, err := r.FormFile("EligibleJwcodesExcel")
if err != nil {
r.Response.WriteJsonExit(dto.Error(err.Error()))
}
// 延时关闭文件
defer func(file multipart.File) {
err := file.Close()
if err != nil {
// 处理关闭文件时的错误
r.Response.WriteJsonExit(dto.Error("获取的文件关闭失败"))
}
}(file)
//参数校验,检查文件是否为空
if file == nil {
r.Response.WriteJsonExit(dto.Error("获取的文件为空"))
}
err = service.CouponUsers().InsertJwcodesToRedisByExcel(file)
//错误处理
if err != nil {
r.Response.WriteJsonExit(dto.Error(err.Error()))
}
//成功处理
//r.Response.WriteJsonExit(dto.SuccessWithMsg("导入redis成功"))
r.Response.WriteJsonExit(dto.SuccessWithMsg("导入coupon_qualified_users表成功"))
}
// 判断某用户能否抽到卡券
func (c *CouponUsers) IsEligibleUser(r *ghttp.Request) {
// 解析请求
var req *couponusers.IsEligibleUserReq
if err := r.Parse(&req); err != nil {
r.Response.WriteJsonExit(dto.Error(err.Error()))
}
fmt.Println(req.CouponIds)
/*解析token,获取jwcode*/
token := r.Header.Get("token")
if token == "" {
r.Response.WriteJsonExit(dto.Error("token为空"))
}
jwcode, err := utility.GetJwcodeJSON(token)
if err != nil {
r.Response.WriteJsonExit(dto.Error(err.Error()))
}
/*解析token,获取jwcode*/
img, err := service.CouponUsers().IsEligibleUser(r.Context(), jwcode, req.CouponIds)
if err != nil {
r.Response.WriteJsonExit(dto.Error(err.Error()))
}
if img != "" {
r.Response.WriteJsonExit(dto.SuccessWithMsgAndData("该用户已领取过该卡券", img))
}
r.Response.WriteJsonExit(dto.SuccessWithMsg("用户符合领取条件"))
}
// 给单个用户发放卡券
func (c *CouponUsers) IssueCouponUser(r *ghttp.Request) {
// 解析请求参数
var req *couponusers.IssueCouponUserReq
if err := r.Parse(&req); err != nil {
r.Response.WriteJsonExit(dto.Error(err.Error()))
}
//解析token,获取jwcode
token := r.Header.Get("token")
if token == "" {
r.Response.WriteJsonExit(dto.Error("token为空"))
}
jwcode, err := utility.GetJwcodeJSON(token)
if err != nil {
r.Response.WriteJsonExit(dto.Error(err.Error()))
}
err = service.CouponUsers().IssueCouponToUser(r.Context(), jwcode, req.CouponId)
//错误处理
if err != nil {
r.Response.WriteJsonExit(dto.Error(err.Error()))
}
//成功处理
r.Response.WriteJsonExit(dto.SuccessWithMsg("发放成功"))
}
// 添加用户选择武器记录
func (c *CouponUsers) AddRecord(r *ghttp.Request) {
var req *couponusers.AddRecordReq
if err := r.Parse(&req); err != nil {
r.Response.WriteJsonExit(dto.Error(err.Error()))
}
//解析token,获取jwcode
token := r.Header.Get("token")
if token == "" {
r.Response.WriteJsonExit(dto.Error("token为空"))
}
jwcode, err := utility.GetJwcodeJSON(token)
if err != nil {
r.Response.WriteJsonExit(dto.Error(err.Error()))
}
err = service.CouponUsers().AddRecord(r.Context(), jwcode, req.CouponId, req.Name)
//错误处理
if err != nil {
r.Response.WriteJsonExit(dto.Error(err.Error()))
}
//成功处理
r.Response.WriteJsonExit(dto.SuccessWithMsg("记录成功"))
}
/*近期使用*/
// 未编写
// 导出拥有卡券的用户
func (c *CouponUsers) ExportCouponUsers(r *ghttp.Request) {
var req *couponusers.GetCouponUsersReq
if err := r.Parse(&req); err != nil {
r.Response.WriteJsonExit(dto.Error(err.Error()))
}
//查询数据,创建excel文件,设置表头,写入数据,设置文件名,保存到缓冲区并返回,设置响应头,指定内容类型为excel文件,指定文件名为fileName,将buffer中的内容写入到响应
}

0
internal/dao/.gitkeep

27
internal/dao/coupon.go

@ -0,0 +1,27 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package dao
import (
"CouponBackendGo/internal/dao/internal"
)
// internalCouponDao is internal type for wrapping internal DAO implements.
type internalCouponDao = *internal.CouponDao
// couponDao is the data access object for table coupon.
// You can define custom methods on it to extend its functionality as you wish.
type couponDao struct {
internalCouponDao
}
var (
// Coupon is globally public accessible object for table coupon operations.
Coupon = couponDao{
internal.NewCouponDao(),
}
)
// Fill with you ideas below.

27
internal/dao/coupon_qualified_users.go

@ -0,0 +1,27 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package dao
import (
"CouponBackendGo/internal/dao/internal"
)
// internalCouponQualifiedUsersDao is internal type for wrapping internal DAO implements.
type internalCouponQualifiedUsersDao = *internal.CouponQualifiedUsersDao
// couponQualifiedUsersDao is the data access object for table coupon_qualified_users.
// You can define custom methods on it to extend its functionality as you wish.
type couponQualifiedUsersDao struct {
internalCouponQualifiedUsersDao
}
var (
// CouponQualifiedUsers is globally public accessible object for table coupon_qualified_users operations.
CouponQualifiedUsers = couponQualifiedUsersDao{
internal.NewCouponQualifiedUsersDao(),
}
)
// Fill with you ideas below.

27
internal/dao/coupon_users.go

@ -0,0 +1,27 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package dao
import (
"CouponBackendGo/internal/dao/internal"
)
// internalCouponUsersDao is internal type for wrapping internal DAO implements.
type internalCouponUsersDao = *internal.CouponUsersDao
// couponUsersDao is the data access object for table coupon_users.
// You can define custom methods on it to extend its functionality as you wish.
type couponUsersDao struct {
internalCouponUsersDao
}
var (
// CouponUsers is globally public accessible object for table coupon_users operations.
CouponUsers = couponUsersDao{
internal.NewCouponUsersDao(),
}
)
// Fill with you ideas below.

89
internal/dao/internal/coupon.go

@ -0,0 +1,89 @@
// ==========================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
import (
"context"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
)
// CouponDao is the data access object for table coupon.
type CouponDao struct {
table string // table is the underlying table name of the DAO.
group string // group is the database configuration group name of current DAO.
columns CouponColumns // columns contains all the column names of Table for convenient usage.
}
// CouponColumns defines and stores column names for table coupon.
type CouponColumns struct {
Id string //
Title string // 名字
Cover string // 封面小图片
ImgUrl string // 放大看全图
StartTime string // 有效期起始
EndTime string // 有效期截止
Deleted string // 是否删除?
CreatedAt string // 创建时间
UpdatedAt string // 更新时间
}
// couponColumns holds the columns for table coupon.
var couponColumns = CouponColumns{
Id: "id",
Title: "title",
Cover: "cover",
ImgUrl: "img_url",
StartTime: "start_time",
EndTime: "end_time",
Deleted: "deleted",
CreatedAt: "created_at",
UpdatedAt: "updated_at",
}
// NewCouponDao creates and returns a new DAO object for table data access.
func NewCouponDao() *CouponDao {
return &CouponDao{
group: "default",
table: "coupon",
columns: couponColumns,
}
}
// DB retrieves and returns the underlying raw database management object of current DAO.
func (dao *CouponDao) DB() gdb.DB {
return g.DB(dao.group)
}
// Table returns the table name of current dao.
func (dao *CouponDao) Table() string {
return dao.table
}
// Columns returns all column names of current dao.
func (dao *CouponDao) Columns() CouponColumns {
return dao.columns
}
// Group returns the configuration group name of database of current dao.
func (dao *CouponDao) Group() string {
return dao.group
}
// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
func (dao *CouponDao) Ctx(ctx context.Context) *gdb.Model {
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
}
// Transaction wraps the transaction logic using function f.
// 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.
//
// Note that, you should not Commit or Rollback the transaction in function f
// as it is automatically handled by this function.
func (dao *CouponDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f)
}

75
internal/dao/internal/coupon_qualified_users.go

@ -0,0 +1,75 @@
// ==========================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
import (
"context"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
)
// CouponQualifiedUsersDao is the data access object for table coupon_qualified_users.
type CouponQualifiedUsersDao struct {
table string // table is the underlying table name of the DAO.
group string // group is the database configuration group name of current DAO.
columns CouponQualifiedUsersColumns // columns contains all the column names of Table for convenient usage.
}
// CouponQualifiedUsersColumns defines and stores column names for table coupon_qualified_users.
type CouponQualifiedUsersColumns struct {
Id string //
Jwcode string //
}
// couponQualifiedUsersColumns holds the columns for table coupon_qualified_users.
var couponQualifiedUsersColumns = CouponQualifiedUsersColumns{
Id: "id",
Jwcode: "jwcode",
}
// NewCouponQualifiedUsersDao creates and returns a new DAO object for table data access.
func NewCouponQualifiedUsersDao() *CouponQualifiedUsersDao {
return &CouponQualifiedUsersDao{
group: "default",
table: "coupon_qualified_users",
columns: couponQualifiedUsersColumns,
}
}
// DB retrieves and returns the underlying raw database management object of current DAO.
func (dao *CouponQualifiedUsersDao) DB() gdb.DB {
return g.DB(dao.group)
}
// Table returns the table name of current dao.
func (dao *CouponQualifiedUsersDao) Table() string {
return dao.table
}
// Columns returns all column names of current dao.
func (dao *CouponQualifiedUsersDao) Columns() CouponQualifiedUsersColumns {
return dao.columns
}
// Group returns the configuration group name of database of current dao.
func (dao *CouponQualifiedUsersDao) Group() string {
return dao.group
}
// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
func (dao *CouponQualifiedUsersDao) Ctx(ctx context.Context) *gdb.Model {
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
}
// Transaction wraps the transaction logic using function f.
// 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.
//
// Note that, you should not Commit or Rollback the transaction in function f
// as it is automatically handled by this function.
func (dao *CouponQualifiedUsersDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f)
}

85
internal/dao/internal/coupon_users.go

@ -0,0 +1,85 @@
// ==========================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
import (
"context"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
)
// CouponUsersDao is the data access object for table coupon_users.
type CouponUsersDao struct {
table string // table is the underlying table name of the DAO.
group string // group is the database configuration group name of current DAO.
columns CouponUsersColumns // columns contains all the column names of Table for convenient usage.
}
// CouponUsersColumns defines and stores column names for table coupon_users.
type CouponUsersColumns struct {
Id string //
Jwcode string //
Time string // 领取时间
CouponId string // 优惠券id
Code string //
State string // 0 未使用 1 已使用
Record string // 武器记录
}
// couponUsersColumns holds the columns for table coupon_users.
var couponUsersColumns = CouponUsersColumns{
Id: "id",
Jwcode: "jwcode",
Time: "time",
CouponId: "coupon_id",
Code: "code",
State: "state",
Record: "record",
}
// NewCouponUsersDao creates and returns a new DAO object for table data access.
func NewCouponUsersDao() *CouponUsersDao {
return &CouponUsersDao{
group: "default",
table: "coupon_users",
columns: couponUsersColumns,
}
}
// DB retrieves and returns the underlying raw database management object of current DAO.
func (dao *CouponUsersDao) DB() gdb.DB {
return g.DB(dao.group)
}
// Table returns the table name of current dao.
func (dao *CouponUsersDao) Table() string {
return dao.table
}
// Columns returns all column names of current dao.
func (dao *CouponUsersDao) Columns() CouponUsersColumns {
return dao.columns
}
// Group returns the configuration group name of database of current dao.
func (dao *CouponUsersDao) Group() string {
return dao.group
}
// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
func (dao *CouponUsersDao) Ctx(ctx context.Context) *gdb.Model {
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
}
// Transaction wraps the transaction logic using function f.
// 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.
//
// Note that, you should not Commit or Rollback the transaction in function f
// as it is automatically handled by this function.
func (dao *CouponUsersDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f)
}

139
internal/dao/internal/member_info.go

@ -0,0 +1,139 @@
// ==========================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
import (
"context"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
)
// MemberInfoDao is the data access object for table member_info.
type MemberInfoDao struct {
table string // table is the underlying table name of the 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.
}
// MemberInfoColumns defines and stores column names for table member_info.
type MemberInfoColumns struct {
Id string //
Jwcode string //
Name string //
Sex string // 0:未知,1:男,2:女
Avatar string // 用户头像
Widget string // 头像挂件
DeptId string //
DeptName string //
ShopId string //
ShopName string //
MembershipTime string //
LiveLock string // 0:解锁 1:锁住
LocMarket string // 用户市场归属
Level string // 等级
LevelIcon string // 等级图标
Star string // 星级
AccountOwner string //
AccountOwnerText string //
Employee string // 1:员工
Dachang string // 0:不是大厂员工 1:是大厂员工
BoguMember string // 1:博股会员
LearningIcon string // 学习等级icon
Mobile string // 手机号
UserIdentity string // 0:无认证 1:红V 2:蓝V 3:黄V
UserIdentityTitle string // 用户身份头衔
Openid string // 微信openid
UserRole string // 用户身份(1:网员 2:非网)
IsBlacklist string // 是否是黑名单用户
IsLecturer string // 讲师
Shenqiangshou string // 神枪手
Huanqiu string // 环球
Age string // 年纪
CreatedAt string //
UpdatedAt string //
}
// memberInfoColumns holds the columns for table member_info.
var memberInfoColumns = MemberInfoColumns{
Id: "id",
Jwcode: "jwcode",
Name: "name",
Sex: "sex",
Avatar: "avatar",
Widget: "widget",
DeptId: "deptId",
DeptName: "deptName",
ShopId: "shopId",
ShopName: "shopName",
MembershipTime: "membership_time",
LiveLock: "live_lock",
LocMarket: "loc_market",
Level: "level",
LevelIcon: "level_icon",
Star: "star",
AccountOwner: "account_owner",
AccountOwnerText: "account_owner_text",
Employee: "employee",
Dachang: "dachang",
BoguMember: "bogu_member",
LearningIcon: "learning_icon",
Mobile: "mobile",
UserIdentity: "user_identity",
UserIdentityTitle: "user_identity_title",
Openid: "openid",
UserRole: "user_role",
IsBlacklist: "is_blacklist",
IsLecturer: "is_lecturer",
Shenqiangshou: "shenqiangshou",
Huanqiu: "huanqiu",
Age: "age",
CreatedAt: "created_at",
UpdatedAt: "updated_at",
}
// NewMemberInfoDao creates and returns a new DAO object for table data access.
func NewMemberInfoDao() *MemberInfoDao {
return &MemberInfoDao{
group: "default",
table: "member_info",
columns: memberInfoColumns,
}
}
// DB retrieves and returns the underlying raw database management object of current DAO.
func (dao *MemberInfoDao) DB() gdb.DB {
return g.DB(dao.group)
}
// Table returns the table name of current dao.
func (dao *MemberInfoDao) Table() string {
return dao.table
}
// Columns returns all column names of current dao.
func (dao *MemberInfoDao) Columns() MemberInfoColumns {
return dao.columns
}
// Group returns the configuration group name of database of current dao.
func (dao *MemberInfoDao) Group() string {
return dao.group
}
// 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 {
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
}
// Transaction wraps the transaction logic using function f.
// 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.
//
// Note that, you should not Commit or Rollback the transaction in function f
// 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) {
return dao.Ctx(ctx).Transaction(ctx, f)
}

27
internal/dao/member_info.go

@ -0,0 +1,27 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package dao
import (
"CouponBackendGo/internal/dao/internal"
)
// internalMemberInfoDao is internal type for wrapping internal DAO implements.
type internalMemberInfoDao = *internal.MemberInfoDao
// memberInfoDao is the data access object for table member_info.
// You can define custom methods on it to extend its functionality as you wish.
type memberInfoDao struct {
internalMemberInfoDao
}
var (
// MemberInfo is globally public accessible object for table member_info operations.
MemberInfo = memberInfoDao{
internal.NewMemberInfoDao(),
}
)
// Fill with you ideas below.

0
internal/logic/.gitkeep

97
internal/logic/coupon/coupon.go

@ -0,0 +1,97 @@
package coupon
import (
"CouponBackendGo/api/v1/coupon"
"CouponBackendGo/internal/dao"
"CouponBackendGo/internal/model/do"
"CouponBackendGo/internal/model/dto"
"CouponBackendGo/internal/service"
"context"
"github.com/gogf/gf/v2/os/gtime"
)
type (
sCoupon struct{}
)
func init() {
service.RegisterCoupon(New())
}
func New() service.ICoupon {
return &sCoupon{}
}
func (s *sCoupon) GetCouponList(ctx context.Context, pageNo int, pageSize int) (couponList []*dto.DtoCoupon, err error) {
err = dao.Coupon.Ctx(ctx).Where("deleted", 0).Order("updated_at desc, end_time desc").Page(pageNo, pageSize).Scan(&couponList)
couponList = InitCoupon(ctx, couponList)
if err != nil {
return nil, err
}
return
}
func InitCoupon(ctx context.Context, couponList []*dto.DtoCoupon) []*dto.DtoCoupon {
for _, v := range couponList {
v.Status = 0 //待使用期
if v.StartTime.Unix() <= gtime.Now().Unix() {
if v.EndTime.Unix() <= gtime.Now().Unix() {
v.Status = 2 //使用期后
} else {
v.Status = 1 //使用期中
}
}
v.Count, _ = dao.CouponUsers.Ctx(ctx).Where("coupon_id", v.Id).Count()
}
return couponList
}
func (s *sCoupon) GetCouponListTotal(ctx context.Context) (total int, err error) {
total, err = dao.Coupon.Ctx(ctx).Where("deleted", 0).Count()
if err != nil {
return 0, err
}
return
}
func (s *sCoupon) GetCoupon(ctx context.Context, id int) (coupon *dto.DtoCoupon, err error) {
err = dao.Coupon.Ctx(ctx).WherePri(id).Scan(&coupon)
if err != nil {
return nil, err
}
return
}
func (s *sCoupon) DeleteCoupon(ctx context.Context, id int) (err error) {
_, err = dao.Coupon.Ctx(ctx).Data(do.Coupon{
Deleted: 1,
}).WherePri(id).Update()
if err != nil {
return err
}
return
}
func (s *sCoupon) InsertCoupon(ctx context.Context, req *coupon.InsertCouponReq) (err error) {
if req.Id == 0 {
_, err = dao.Coupon.Ctx(ctx).Data(do.Coupon{
Title: req.Title,
Cover: req.Image,
ImgUrl: req.Image,
StartTime: req.StartTime.Unix(),
EndTime: req.EndTime.Add(23*gtime.H + 59*gtime.M + 59*gtime.S).Unix(),
}).Insert()
} else {
_, err = dao.Coupon.Ctx(ctx).Data(do.Coupon{
Title: req.Title,
Cover: req.Image,
ImgUrl: req.Image,
StartTime: req.StartTime.Unix(),
EndTime: req.EndTime.Add(23*gtime.H + 59*gtime.M + 59*gtime.S).Unix(),
}).WherePri(req.Id).Update()
}
if err != nil {
return err
}
return
}

402
internal/logic/couponusers/couponUsers.go

@ -0,0 +1,402 @@
package couponusers
import (
"CouponBackendGo/api/v1/couponusers"
"CouponBackendGo/internal/dao"
"CouponBackendGo/internal/service"
"context"
"database/sql"
"errors"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
"github.com/xuri/excelize/v2"
"mime/multipart"
"strconv"
"strings"
)
type sCouponUsers struct{}
func init() {
service.RegisterCouponUsers(&sCouponUsers{})
}
// 根据优惠券id查看拥有优惠券的用户
func (s *sCouponUsers) GetCouponUsersByCondition(ctx context.Context, couponId, jwcode int, name string, pageNo, pageSize int) (users []couponusers.GetCouponUsersRes, err error) {
//没有条件查询时,分页
if jwcode == 0 && name == "" {
/*查询所有数据*/
//在coupon_users中查询出对应的jwcode
err = dao.CouponUsers.Ctx(ctx).Fields("jwcode").
Where("coupon_id = ", couponId).Page(pageNo, pageSize).Scan(&users)
if err != nil {
return nil, errors.New("根据卡券id搜索jwcode失败")
}
//根据jwcode查询用户信息
for i, userInfo := range users {
err = dao.MemberInfo.Ctx(ctx).Fields("jwcode", "name", "deptName", "shopName").
Where("jwcode = ?", userInfo.Jwcode).Scan(&users[i])
if err != nil {
return nil, errors.New("根据jwcode搜索用户信息失败")
}
}
/*查询所有数据*/
return users, err
} else { //有条件查询时,不在分页,全查后筛选
/*查询所有数据*/
//在coupon_users中查询出对应的jwcode
err = dao.CouponUsers.Ctx(ctx).Fields("jwcode").
Where("coupon_id = ", couponId).Scan(&users)
if err != nil {
return nil, errors.New("根据卡券id搜索jwcode失败")
}
//根据jwcode查询用户信息
for i, userInfo := range users {
err = dao.MemberInfo.Ctx(ctx).Fields("jwcode", "name", "deptName", "shopName").
Where("jwcode = ?", userInfo.Jwcode).Scan(&users[i])
if err != nil {
return nil, errors.New("根据jwcode搜索用户信息失败")
}
}
/*查询所有数据*/
//条件查询
if jwcode != 0 && name == "" {
var result []couponusers.GetCouponUsersRes
for _, user := range users {
if user.Jwcode == jwcode {
result = append(result, user)
}
}
return result, err
} else if jwcode == 0 && name != "" {
var result []couponusers.GetCouponUsersRes
for _, user := range users {
if strings.Contains(user.Name, name) {
result = append(result, user)
}
}
return result, err
} else if jwcode != 0 && name != "" {
var result []couponusers.GetCouponUsersRes
for _, user := range users {
if user.Jwcode == jwcode && strings.Contains(user.Name, name) {
result = append(result, user)
}
}
return result, err
}
return users, err
}
}
// 根据jwcode,优惠券id删除用户
func (s *sCouponUsers) DeleteCouponUserByJwcode(ctx context.Context, couponId, jwcode int) (result sql.Result, err error) {
if jwcode == 0 {
return nil, errors.New("jwcode不能为空")
}
if couponId == 0 {
return nil, errors.New("couponId不能为空")
}
result, err = dao.CouponUsers.Ctx(ctx).Where("coupon_id = ?", couponId).Where("jwcode = ?", jwcode).Delete()
if err != nil {
return nil, errors.New("删除用户失败")
}
return result, err
}
// 通过excel导入精网号
func (s *sCouponUsers) InsertJwcodeByExcel(ctx context.Context, file multipart.File, couponId int) (num int, err error) {
// func (s *sCouponUsers) InsertJwcodeByExcel(file multipart.File) (jwcodes []int, err error) {
//打开文件并返回一个excelize.File对象,用于读取和操作Excel文件的内容
f, err := excelize.OpenReader(file)
if err != nil {
return 0, errors.New("打开文件失败")
}
// 延时关闭文件
defer func(f *excelize.File) {
err := f.Close()
if err != nil {
return // 返回错误
}
}(f)
//读取所有工作表名称
GetSheetMap := f.GetSheetMap()
if len(GetSheetMap) == 0 {
return 0, errors.New("没有工作表")
}
rows, err := f.GetRows("Sheet1")
if err != nil {
return 0, err
}
// 将每行的第一列转换为int,并添加到切片中
var jwcodes []int
for i, row := range rows {
//跳过第一行
if i == 0 {
continue
}
// 假设jwcode在每行的第一列
/*参数校验*/
//参数校验,检查每行是否有足够数据
if len(row) == 0 {
continue // 跳过空行
}
//参数校验,检查jwcode是否为非空字符串
jwcodeStr := row[0]
if jwcodeStr == "" {
continue // 跳过空行
}
//将字符串转换为整数
jwcode, err := strconv.Atoi(jwcodeStr)
if err != nil {
return 0, errors.New("参数转换失败")
}
jwcodes = append(jwcodes, jwcode)
/*参数校验*/
}
/*给用户发放卡券*/
num, err = s.InsertCouponUsersByJwcodes(ctx, jwcodes, couponId)
/*给用户发放卡券*/
//return //返回jwcodes切片
return num, err
}
// 传来jwcodes字符串,解析并发放卡券
func (s *sCouponUsers) InsertCouponUsersByJwcodeStr(ctx context.Context, jwcodeStr string, couponId int) (num int, err error) {
//将字符串转换为切片
jwcodes := strings.Split(jwcodeStr, ",")
//转换成int
var jwcodesInt []int
for _, jwcode := range jwcodes {
//参数校验,检查jwcode是否为非空字符串
if jwcode == "" {
continue
}
jwcodeInt, err := strconv.Atoi(jwcode)
if err != nil {
return 0, errors.New("参数转换失败")
}
jwcodesInt = append(jwcodesInt, jwcodeInt)
}
/*给用户发放卡券*/
num, err = s.InsertCouponUsersByJwcodes(ctx, jwcodesInt, couponId)
/*给用户发放卡券*/
return
}
// 根据精网号发放用户优惠券,群发 //不被controller层调用了,但不能删除
func (s *sCouponUsers) InsertCouponUsersByJwcodes(ctx context.Context, jwcodes []int, couponId int) (num int, err error) {
//去重
m := make(map[int]bool)
var uniqueJwcodes []int //存放去重后的精网号
for _, jwcode := range jwcodes {
if _, exist := m[jwcode]; !exist {
m[jwcode] = true
uniqueJwcodes = append(uniqueJwcodes, jwcode)
}
}
//插入数据
for _, jwcode := range uniqueJwcodes {
//检查数据库中是否存在
count, err := dao.CouponUsers.Ctx(ctx).Where("jwcode = ?", jwcode).Where("coupon_id = ?", couponId).Count()
if err != nil {
return num, errors.New("检索数据库中是否已存在数据失败")
}
//不存在,可以插入
if count == 0 {
result, err := dao.CouponUsers.Ctx(ctx).Insert(g.Map{
"jwcode": jwcode,
"coupon_id": couponId,
"time": gtime.Now().Unix(),
})
if err != nil {
return num, errors.New("插入数据库失败")
}
//获取受影响的行数
affected, err := result.RowsAffected()
num += int(affected)
}
}
return num, err //返回受影响的行数,即新增的条数
}
// 导入满足条件的用户jwcode到redis //不上传到redis了,上传到数据库表,到时候直接从表里查
func (s *sCouponUsers) InsertJwcodesToRedisByExcel(file multipart.File) (err error) {
var ctx g.Ctx
//打开文件并返回一个excelize.File对象,用于读取和操作Excel文件的内容
f, err := excelize.OpenReader(file)
if err != nil {
return errors.New("打开文件失败")
}
// 延时关闭文件
defer func(f *excelize.File) {
err := f.Close()
if err != nil {
// 处理关闭文件时的错误
return
}
}(f)
//读取所有工作表名称
GetSheetMap := f.GetSheetMap()
if len(GetSheetMap) == 0 {
return errors.New("没有工作表")
}
// 读取第一个工作表
rows, err := f.GetRows("Sheet1")
if err != nil {
return err
}
// 将每行的第一列转换为int,并添加到切片中
//var jwcodes []int
for i, row := range rows {
//跳过第一行
if i == 0 {
continue
}
// 假设jwcode在每行的第一列
/*参数校验*/
//参数校验,检查每行是否有足够数据
if len(row) == 0 {
continue // 跳过空行
}
//参数校验,检查jwcode是否为非空字符串
jwcodeStr := row[0]
if jwcodeStr == "" {
continue // 跳过空行
}
//将字符串转换为整数
jwcode, err := strconv.Atoi(jwcodeStr)
if err != nil {
return errors.New("参数转换失败")
}
// 判断jwcode是否在表coupon_qualified_users中
count, err := dao.CouponQualifiedUsers.Ctx(ctx).Where("jwcode = ?", jwcode).Count()
if err != nil {
return errors.New("检索数据库中是否已存在数据失败")
}
if count == 0 { //不存在,插入
_, err = dao.CouponQualifiedUsers.Ctx(ctx).Insert(g.Map{
"jwcode": jwcode,
})
}
//jwcodes = append(jwcodes, jwcode)
/*参数校验*/
}
return //返回nil表示成功
}
// 判断某用户能否抽到卡券
func (s *sCouponUsers) IsEligibleUser(ctx context.Context, jwcode int, couponIds []int) (img string, err error) {
//从数据库中获取符合条件的精网号EligibleJwcodes
var EligibleJwcodes []couponusers.InsertCouponUserRes
err = dao.CouponQualifiedUsers.Ctx(ctx).Fields("jwcode").Scan(&EligibleJwcodes)
if err != nil {
return "", errors.New("从数据库中获取符合条件的精网号失败")
}
if len(EligibleJwcodes) == 0 {
return "", errors.New("核验数据库(满足条件)中数据为空")
}
//检查jwcode是否在EligibleJwcodes中
for _, EligibleJwcode := range EligibleJwcodes {
if EligibleJwcode.Jwcode == jwcode {
//存在,有资格,判断是否抽取过
for _, couponId := range couponIds {
count, err := dao.CouponUsers.Ctx(ctx).Where("jwcode = ?", jwcode).Where("coupon_id = ?", couponId).Count()
if err != nil {
return "", errors.New("检索数据库中是否已存在数据失败")
}
//有记录,抽取过
if count > 0 {
err = dao.CouponUsers.Ctx(ctx).Fields("img_url").Where("jwcode = ?", jwcode).Where("coupon_id = ?", couponId).Scan(&img)
return img, errors.New("该用户已领取过该卡券")
}
}
//所有的都没有记录,没有抽取过
return "", nil
}
}
return "", errors.New("该用户不满足领取条件")
}
// 给单个用户发放卡券
func (s *sCouponUsers) IssueCouponToUser(ctx context.Context, jwcode, couponId int) (err error) {
//查看库中是否已经存在
count, err := dao.CouponUsers.Ctx(ctx).Where("jwcode = ?", jwcode).Where("coupon_id = ?", couponId).Count()
if err != nil {
return errors.New("检索数据库中是否已存在数据失败")
}
//已存在 不添加,直接返回
if count > 0 {
return errors.New("该用户已领取该卡券")
}
//不存在 查看是否满足条件,满足就添加,不满足就返回
//从数据库中获取符合条件的精网号EligibleJwcodes
var EligibleJwcodes []couponusers.InsertCouponUserRes
err = dao.CouponQualifiedUsers.Ctx(ctx).Fields("jwcode").Scan(&EligibleJwcodes)
if err != nil {
return errors.New("从数据库中获取符合条件的精网号失败")
}
if len(EligibleJwcodes) == 0 {
return errors.New("核验数据库(满足条件)中数据为空")
}
//检查jwcode是否在EligibleJwcodes中
for _, EligibleJwcode := range EligibleJwcodes {
if EligibleJwcode.Jwcode == jwcode {
//存在,可以插入
_, err := dao.CouponUsers.Ctx(ctx).Insert(g.Map{
"jwcode": jwcode,
"coupon_id": couponId,
"time": gtime.Now().Unix(),
})
if err != nil {
return errors.New("插入数据库失败")
}
return err
}
}
return errors.New("该用户精网号不符合领取条件") //遍历完了所有满足条件的用户,发现不在其中,不符合条件
}
/*未编写*/
// 导出拥有卡券的用户列表
func (s *sCouponUsers) ExportCouponUsers() {
}
// 添加用户选择武器记录
func (s *sCouponUsers) AddRecord(ctx context.Context, jwcode int, id int, name string) (err error) {
_, err = dao.CouponUsers.Ctx(ctx).Data(g.Map{
"record": name,
}).Where("jwcode = ? and coupon_id = ?", jwcode, id).Update()
if err != nil {
return errors.New("添加武器记录失败")
}
return
}

10
internal/logic/logic.go

@ -1 +1,11 @@
// ==========================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package logic
import (
_ "CouponBackendGo/internal/logic/coupon"
_ "CouponBackendGo/internal/logic/couponusers"
_ "CouponBackendGo/internal/logic/middleware"
)

10
internal/logic/middleware/interceptor.go

@ -0,0 +1,10 @@
package middleware
import (
"github.com/gogf/gf/v2/net/ghttp"
)
func MiddlewareCORS(r *ghttp.Request) {
r.Response.CORSDefault()
r.Middleware.Next()
}

0
internal/model/.gitkeep

0
internal/model/do/.gitkeep

24
internal/model/do/coupon.go

@ -0,0 +1,24 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// Coupon is the golang structure of table coupon for DAO operations like Where/Data.
type Coupon struct {
g.Meta `orm:"table:coupon, do:true"`
Id interface{} //
Title interface{} // 名字
Cover interface{} // 封面小图片
ImgUrl interface{} // 放大看全图
StartTime interface{} // 有效期起始
EndTime interface{} // 有效期截止
Deleted interface{} // 是否删除?
CreatedAt *gtime.Time // 创建时间
UpdatedAt *gtime.Time // 更新时间
}

16
internal/model/do/coupon_qualified_users.go

@ -0,0 +1,16 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
)
// CouponQualifiedUsers is the golang structure of table coupon_qualified_users for DAO operations like Where/Data.
type CouponQualifiedUsers struct {
g.Meta `orm:"table:coupon_qualified_users, do:true"`
Id interface{} //
Jwcode interface{} //
}

21
internal/model/do/coupon_users.go

@ -0,0 +1,21 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
)
// CouponUsers is the golang structure of table coupon_users for DAO operations like Where/Data.
type CouponUsers struct {
g.Meta `orm:"table:coupon_users, do:true"`
Id interface{} //
Jwcode interface{} //
Time interface{} // 领取时间
CouponId interface{} // 优惠券id
Code interface{} //
State interface{} // 0 未使用 1 已使用
Record interface{} // 武器记录
}

49
internal/model/do/member_info.go

@ -0,0 +1,49 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// MemberInfo is the golang structure of table member_info for DAO operations like Where/Data.
type MemberInfo struct {
g.Meta `orm:"table:member_info, do:true"`
Id interface{} //
Jwcode interface{} //
Name interface{} //
Sex interface{} // 0:未知,1:男,2:女
Avatar interface{} // 用户头像
Widget interface{} // 头像挂件
DeptId interface{} //
DeptName interface{} //
ShopId interface{} //
ShopName interface{} //
MembershipTime *gtime.Time //
LiveLock interface{} // 0:解锁 1:锁住
LocMarket interface{} // 用户市场归属
Level interface{} // 等级
LevelIcon interface{} // 等级图标
Star interface{} // 星级
AccountOwner interface{} //
AccountOwnerText interface{} //
Employee interface{} // 1:员工
Dachang interface{} // 0:不是大厂员工 1:是大厂员工
BoguMember interface{} // 1:博股会员
LearningIcon interface{} // 学习等级icon
Mobile interface{} // 手机号
UserIdentity interface{} // 0:无认证 1:红V 2:蓝V 3:黄V
UserIdentityTitle interface{} // 用户身份头衔
Openid interface{} // 微信openid
UserRole interface{} // 用户身份(1:网员 2:非网)
IsBlacklist interface{} // 是否是黑名单用户
IsLecturer interface{} // 讲师
Shenqiangshou interface{} // 神枪手
Huanqiu interface{} // 环球
Age interface{} // 年纪
CreatedAt *gtime.Time //
UpdatedAt *gtime.Time //
}

9
internal/model/dto/Result.go

@ -34,6 +34,15 @@ func SuccessWithData(data interface{}) *Result {
}
}
/*成功,自定义信息和数据*/
func SuccessWithMsgAndData(msg string, data interface{}) *Result {
return &Result{
Code: 200,
Message: msg,
Data: data,
}
}
/*错误,只有错误信息,错误码0*/
func Error(msg string) *Result {
return &Result{

15
internal/model/dto/dto_coupon.go

@ -0,0 +1,15 @@
package dto
import "github.com/gogf/gf/v2/os/gtime"
type DtoCoupon struct {
Id uint `json:"id" orm:"db:default;table:coupon;column:id" description:"ID"` // ID
Title string `json:"title" orm:"db:default;table:coupon;column:title" description:"名字"` // 名字
Cover string `json:"cover" orm:"db:default;table:coupon;column:cover" description:"封面小图片"` // 封面小图片
ImgUrl string `json:"imgUrl" orm:"db:default;table:coupon;column:img_url" description:"放大看全图"` // 放大看全图
UpdatedAt *gtime.Time `json:"updatedAt" orm:"db:default;table:coupon;column:updated_at" description:"更新时间"` // 更新时间
StartTime *gtime.Time `json:"startTime" description:"有效期起始"` // 有效期起始
EndTime *gtime.Time `json:"endTime" description:"有效期截止"` // 有效期截止
Status int `json:"status" description:"卡券状态"` // 卡券状态
Count int `json:"count" description:"持有人数"` // 持有人数
}

0
internal/model/entity/.gitkeep

22
internal/model/entity/coupon.go

@ -0,0 +1,22 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// Coupon is the golang structure for table coupon.
type Coupon struct {
Id uint `json:"id" orm:"id" description:""` //
Title string `json:"title" orm:"title" description:"名字"` // 名字
Cover string `json:"cover" orm:"cover" description:"封面小图片"` // 封面小图片
ImgUrl string `json:"imgUrl" orm:"img_url" description:"放大看全图"` // 放大看全图
StartTime int `json:"startTime" orm:"start_time" description:"有效期起始"` // 有效期起始
EndTime int `json:"endTime" orm:"end_time" description:"有效期截止"` // 有效期截止
Deleted int `json:"deleted" orm:"deleted" description:"是否删除?"` // 是否删除?
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"` // 创建时间
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"` // 更新时间
}

11
internal/model/entity/coupon_qualified_users.go

@ -0,0 +1,11 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
// CouponQualifiedUsers is the golang structure for table coupon_qualified_users.
type CouponQualifiedUsers struct {
Id uint `json:"id" orm:"id" description:""` //
Jwcode int `json:"jwcode" orm:"jwcode" description:""` //
}

16
internal/model/entity/coupon_users.go

@ -0,0 +1,16 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
// CouponUsers is the golang structure for table coupon_users.
type CouponUsers struct {
Id uint `json:"id" orm:"id" description:""` //
Jwcode int `json:"jwcode" orm:"jwcode" description:""` //
Time int `json:"time" orm:"time" description:"领取时间"` // 领取时间
CouponId int `json:"couponId" orm:"coupon_id" description:"优惠券id"` // 优惠券id
Code string `json:"code" orm:"code" description:""` //
State int `json:"state" orm:"state" description:"0 未使用 1 已使用"` // 0 未使用 1 已使用
Record string `json:"record" orm:"record" description:"武器记录"` // 武器记录
}

47
internal/model/entity/member_info.go

@ -0,0 +1,47 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// MemberInfo is the golang structure for table member_info.
type MemberInfo struct {
Id int `json:"id" orm:"id" description:""` //
Jwcode int `json:"jwcode" orm:"jwcode" description:""` //
Name string `json:"name" orm:"name" description:""` //
Sex int `json:"sex" orm:"sex" description:"0:未知,1:男,2:女"` // 0:未知,1:男,2:女
Avatar string `json:"avatar" orm:"avatar" description:"用户头像"` // 用户头像
Widget string `json:"widget" orm:"widget" description:"头像挂件"` // 头像挂件
DeptId string `json:"deptId" orm:"deptId" description:""` //
DeptName string `json:"deptName" orm:"deptName" description:""` //
ShopId string `json:"shopId" orm:"shopId" description:""` //
ShopName string `json:"shopName" orm:"shopName" description:""` //
MembershipTime *gtime.Time `json:"membershipTime" orm:"membership_time" description:""` //
LiveLock int `json:"liveLock" orm:"live_lock" description:"0:解锁 1:锁住"` // 0:解锁 1:锁住
LocMarket string `json:"locMarket" orm:"loc_market" description:"用户市场归属"` // 用户市场归属
Level int `json:"level" orm:"level" description:"等级"` // 等级
LevelIcon string `json:"levelIcon" orm:"level_icon" description:"等级图标"` // 等级图标
Star int `json:"star" orm:"star" description:"星级"` // 星级
AccountOwner string `json:"accountOwner" orm:"account_owner" description:""` //
AccountOwnerText string `json:"accountOwnerText" orm:"account_owner_text" description:""` //
Employee int `json:"employee" orm:"employee" description:"1:员工"` // 1:员工
Dachang int `json:"dachang" orm:"dachang" description:"0:不是大厂员工 1:是大厂员工"` // 0:不是大厂员工 1:是大厂员工
BoguMember int `json:"boguMember" orm:"bogu_member" description:"1:博股会员"` // 1:博股会员
LearningIcon string `json:"learningIcon" orm:"learning_icon" description:"学习等级icon"` // 学习等级icon
Mobile string `json:"mobile" orm:"mobile" description:"手机号"` // 手机号
UserIdentity int `json:"userIdentity" orm:"user_identity" description:"0:无认证 1:红V 2:蓝V 3:黄V"` // 0:无认证 1:红V 2:蓝V 3:黄V
UserIdentityTitle string `json:"userIdentityTitle" orm:"user_identity_title" description:"用户身份头衔"` // 用户身份头衔
Openid string `json:"openid" orm:"openid" description:"微信openid"` // 微信openid
UserRole int `json:"userRole" orm:"user_role" description:"用户身份(1:网员 2:非网)"` // 用户身份(1:网员 2:非网)
IsBlacklist int `json:"isBlacklist" orm:"is_blacklist" description:"是否是黑名单用户"` // 是否是黑名单用户
IsLecturer int `json:"isLecturer" orm:"is_lecturer" description:"讲师"` // 讲师
Shenqiangshou int `json:"shenqiangshou" orm:"shenqiangshou" description:"神枪手"` // 神枪手
Huanqiu int `json:"huanqiu" orm:"huanqiu" description:"环球"` // 环球
Age uint `json:"age" orm:"age" description:"年纪"` // 年纪
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:""` //
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:""` //
}

0
internal/service/.gitkeep

37
internal/service/coupon.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 (
"CouponBackendGo/api/v1/coupon"
"CouponBackendGo/internal/model/dto"
"context"
)
type (
ICoupon interface {
GetCouponList(ctx context.Context, pageNo int, pageSize int) (couponList []*dto.DtoCoupon, err error)
GetCouponListTotal(ctx context.Context) (total int, err error)
GetCoupon(ctx context.Context, id int) (coupon *dto.DtoCoupon, err error)
DeleteCoupon(ctx context.Context, id int) (err error)
InsertCoupon(ctx context.Context, req *coupon.InsertCouponReq) (err error)
}
)
var (
localCoupon ICoupon
)
func Coupon() ICoupon {
if localCoupon == nil {
panic("implement not found for interface ICoupon, forgot register?")
}
return localCoupon
}
func RegisterCoupon(i ICoupon) {
localCoupon = i
}

54
internal/service/couponusers.go

@ -0,0 +1,54 @@
// ================================================================================
// 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 (
"CouponBackendGo/api/v1/couponusers"
"context"
"database/sql"
"mime/multipart"
)
type (
ICouponUsers interface {
// 根据优惠券id查看拥有优惠券的用户
GetCouponUsersByCondition(ctx context.Context, couponId int, jwcode int, name string, pageNo int, pageSize int) (users []couponusers.GetCouponUsersRes, err error)
// 根据jwcode,优惠券id删除用户
DeleteCouponUserByJwcode(ctx context.Context, couponId int, jwcode int) (result sql.Result, err error)
// 通过excel导入精网号
InsertJwcodeByExcel(ctx context.Context, file multipart.File, couponId int) (num int, err error)
// 传来jwcodes字符串,解析并发放卡券
InsertCouponUsersByJwcodeStr(ctx context.Context, jwcodeStr string, couponId int) (num int, err error)
// 根据精网号发放用户优惠券,群发 //不被controller层调用了,但不能删除
InsertCouponUsersByJwcodes(ctx context.Context, jwcodes []int, couponId int) (num int, err error)
// 导入满足条件的用户jwcode到redis //不上传到redis了,上传到数据库表,到时候直接从表里查
InsertJwcodesToRedisByExcel(file multipart.File) (err error)
// 判断某用户能否抽到卡券
IsEligibleUser(ctx context.Context, jwcode int, couponIds []int) (img string, err error)
// 给单个用户发放卡券
IssueCouponToUser(ctx context.Context, jwcode int, couponId int) (err error)
/*未编写*/
// 导出拥有卡券的用户列表
ExportCouponUsers()
// 添加用户选择武器记录
AddRecord(ctx context.Context, jwcode int, id int, name string) (err error)
}
)
var (
localCouponUsers ICouponUsers
)
func CouponUsers() ICouponUsers {
if localCouponUsers == nil {
panic("implement not found for interface ICouponUsers, forgot register?")
}
return localCouponUsers
}
func RegisterCouponUsers(i ICouponUsers) {
localCouponUsers = i
}

8
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 ()

129
utility/utility.go

@ -0,0 +1,129 @@
package utility
import (
"CouponBackendGo/internal/consts"
"CouponBackendGo/internal/model/dto"
"encoding/json"
"errors"
"fmt"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gctx"
"io/ioutil"
"net/http"
"strconv"
"strings"
)
// 查询数据库中的URL
func selectBaseUrl(hashKey string) *dto.Result {
//查询数据库
//env表中存储着一些所需要的地址,值等,可能是需要查出来存放到redis中(value字段中是值)
//key为"HLJW_URL"时,value为:http://39.101.133.168:8828/hljw,为测试环境时前置地址
value, err := g.DB().Model("env").Where("`key` = ?", hashKey).Value("value")
if err != nil {
return dto.Error("数据库env查询失败")
}
if value.IsNil() || value.String() == "" {
return dto.Error("未找到对应数据")
}
return dto.SuccessWithData(value.String())
}
// 获取URL
func getUrl(key, hashKey string) *dto.Result {
ctx := gctx.New()
//测试环境: http://39.101.133.168:8828/hljw/api/v2/member/info
//正式环境: http://api.homilychart.com:8828/hljw/api/v2/member/info
//1. 从Redis获取URL
redisUrl, err := g.Redis().Do(ctx, "HGET", key, hashKey)
if err == nil && redisUrl.String() != "" {
return dto.SuccessWithMsgAndData(fmt.Sprintf("从Redis获取URL: %s", redisUrl.String()), redisUrl.String())
}
//2. 如果Redis中没有, 查询数据库
urlResult := selectBaseUrl(hashKey)
if urlResult.Code != 200 {
return urlResult
}
url := urlResult.Data.(string)
//3. 将URL存入Redis
_, err = g.Redis().Do(ctx, "HSET", key, hashKey, url)
if err != nil {
return dto.Error("将数据存入Redis失败")
}
return dto.SuccessWithData(url)
}
// 获取jwcode
func GetJwcodeJSON(token string) (int, error) {
//获取基础URL 用于解析token的接口地址
urlResult := getUrl(consts.URL_KEY, consts.URL_HASH_KEY)
if urlResult.Code != 200 {
return 0, errors.New(fmt.Sprintf("获取基础URL失败: %s", urlResult.Message))
}
baseUrl := urlResult.Data.(string)
//拼接完整的URL, 用于发送请求并解析token
url := baseUrl + "/api/v2/member/info"
requestBody := strings.NewReader(`{"token":"` + token + `"}`)
//创建HTTP请求(POST)
req, err := http.NewRequest("POST", url, requestBody)
if err != nil {
return 0, fmt.Errorf("创建HTTP请求失败: %w", err)
}
//设置请求头
req.Header.Set("Content-Type", "application/json")
//发送请求
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return 0, fmt.Errorf("发送HTTP请求失败: %w", err) //
}
//延时关闭响应体
defer resp.Body.Close()
//检查HTTP状态码
if resp.StatusCode != http.StatusOK {
return 0, fmt.Errorf("HTTP请求失败, 状态码: %d", resp.StatusCode)
}
//读取并解析响应体
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return 0, fmt.Errorf("读取响应体失败: %w", err)
}
//解析JSON数据
var jsonResponse map[string]interface{}
err = json.Unmarshal(body, &jsonResponse)
if err != nil {
return 0, fmt.Errorf("解析JSON数据失败: %w", err)
}
//提取data节点
data, ok := jsonResponse["data"].(map[string]interface{})
if !ok {
return 0, errors.New("响应体中没有有效的data节点")
}
//提取jwcode字段节点并转换为整数
jwcode, ok := data["jwcode"].(string) //首先尝试解析为字符串
if ok {
jwcodeInt, err := strconv.Atoi(jwcode) //将字符串转换为整数
if err != nil {
return 0, fmt.Errorf("解析jwcode字段为整数失败: %w", err)
}
return jwcodeInt, nil
}
//如果jwcode不是字符串,返回错误日志
return 0, errors.New("响应体中没有有效的jwcode字段")
}
Loading…
Cancel
Save