31 Commits

Author SHA1 Message Date
lijikun bc977a9216 12.31日,正式上线前调整解析token的地址 9 months ago
lijikun 27acfaf339 Merge branch 'dev' of http://39.101.133.168:8807/wanglin/CouponBackendGo into dev 9 months ago
lijikun d2b9b3619b 12.31日,将导入用户jwcode并回显改为直接导入并上传,以及传到后端一个数组并上传两个接口,导出未写 9 months ago
majun 03b200aa8f Merge branch 'majun' into dev 9 months ago
majun 80a40f2e67 优化卡券失效时间的代码 9 months ago
lijikun 65adb8a352 12.30日,将导入符合条件的jwcode到redis改为导入到数据库表后,将coupon_qualified_users表纳入管理,使得导入数据库表没有问题,有关coupon_qualified_users表的也都没有问题 9 months ago
lijikun b77770c8ac 12.30日,将导入符合条件的jwcode到redis改为导入到数据库表后,将coupon_qualified_users表纳入管理,使得导入数据库表没有问题,有关coupon_qualified_users表的也都没有问题 9 months ago
lijikun 6ac88add3b 12.30日,将导入符合条件的jwcode到redis改为导入到数据库表 9 months ago
lijikun 1fd602b689 Merge branch 'dev' of http://39.101.133.168:8807/wanglin/CouponBackendGo into dev 9 months ago
majun c7bf11108c Merge branch 'majun' into dev 9 months ago
lijikun 29f06aa2e6 Merge branch 'ljk' into dev 9 months ago
lijikun 15f102b89b 12.28日下午增加请求校验, 删除一些非必须的redis 9 months ago
majun 6f859fd76a 简化代码 9 months ago
lijikun eccc482dbf 12.28日下午增加请求校验 9 months ago
lijikun 014de4c7b7 12.28日下午合并majun分支 10 months ago
lijikun 4fc9b980c5 12.28日下午查看拥有卡券的用户添加分页,操作表时会更新redis 10 months ago
lijikun cf75ca3016 12.28日下午查看拥有卡券的用户添加分页,操作表时会更新redis 10 months ago
majun 6ccdf41bba 后端合并 10 months ago
majun d6db6d2b7d 后端合并 10 months ago
lijikun 94f7d77ffb 12.28日合并ljk, mj-wq分支 10 months ago
lijikun bd40c2d71c 12.28日mj分离后添加,删除多余方法 10 months ago
majun 28b1d81f18 完成编辑卡券接口 10 months ago
lijikun b252850557 12.28日检测用户是否有抽奖机会,是否抽取过, 10 months ago
majun e8d40bfb48 编写编辑卡券接口 10 months ago
majun 8894230c06 编写新建卡券接口 10 months ago
majun 8b7ae02a8b 编写添加用户选择武器记录接口 10 months ago
lijikun b84643bdc2 12.27日,完成给用户发放卡券,给单个用户发放卡券,从excel中导入数据到redis,解析token 10 months ago
majun 9713e047bf 编写删、查接口 10 months ago
majun 39670b7d3b 熟悉接口 10 months ago
lijikun 1bc4c62501 12.26日完成从excel表格中导入数据;调整数据库中jwcode类型(varchar->int)并修改dao层 10 months ago
lijikun 397071ea1a 12.25日生成service,编写查询拥有卡券的用户,删除用户卡券 10 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