2 Commits

  1. 27
      api/v1/couponusers/couponUsers.go
  2. 2
      hack/config.yaml
  3. 13
      internal/cmd/cmd.go
  4. 31
      internal/controller/couponusers/couponUsers.go
  5. 27
      internal/dao/coupon_qualified_users.go
  6. 75
      internal/dao/internal/coupon_qualified_users.go
  7. 65
      internal/logic/couponusers/couponUsers.go
  8. 16
      internal/model/do/coupon_qualified_users.go
  9. 11
      internal/model/entity/coupon_qualified_users.go
  10. 6
      internal/service/couponusers.go

27
api/v1/couponusers/couponUsers.go

@ -1,5 +1,6 @@
package couponusers
// GetCouponUsersReq 查询卡券用户
type GetCouponUsersReq struct {
CouponId int `json:"couponId" v:"required#卡券id不能为空" dc:"卡券id"`
Jwcode int `json:"jwcode" dc:"查询条件中的精网号"`
@ -8,6 +9,7 @@ type GetCouponUsersReq struct {
PageSize int `json:"pageSize" v:"required#分页信息不能为空" dc:"每页数量"`
}
// GetCouponUsersRes 查询卡券用户
type GetCouponUsersRes struct {
Name string `json:"name" dc:"姓名"`
Jwcode int `json:"jwcode" dc:"精网号"`
@ -15,20 +17,41 @@ type GetCouponUsersRes struct {
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:"精网号"`
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:"精网号"`
}

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:

13
internal/cmd/cmd.go

@ -19,10 +19,15 @@ var (
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("/import-excel", couponusers.NewCouponUsers().InsertJwcodeByExcel) // 通过excel导入jwcode
group.POST("/insert-coupon-user", couponusers.NewCouponUsers().InsertCouponUser) //给用户发放卡券
//group.POST("/get-coupon-users", couponusers.NewCouponUsers().GetCouponUsers) // 获取拥有卡券的用户列表
//group.POST("/delete-coupon-user", couponusers.NewCouponUsers().DeleteCouponUserByJwcode) //删除用户卡券
//group.POST("/import-excel", couponusers.NewCouponUsers().InsertJwcodeByExcel) // 通过excel导入jwcode
//group.POST("/insert-coupon-user", couponusers.NewCouponUsers().InsertCouponUser) //给用户发放卡券
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) //判断用户是否满足领取条件

31
internal/controller/couponusers/couponUsers.go

@ -60,7 +60,14 @@ func (c *CouponUsers) DeleteCouponUserByJwcode(r *ghttp.Request) {
}
// 接受前端传来的excel表格,并解析,返回jwcode切片,可以有重复的,在插入时进行验证,如果有重复的,只插入一次
func (c *CouponUsers) InsertJwcodeByExcel(r *ghttp.Request) {
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 {
@ -80,24 +87,32 @@ func (c *CouponUsers) InsertJwcodeByExcel(r *ghttp.Request) {
r.Response.WriteJsonExit(dto.Error("获取的文件为空"))
}
jwcodes, err := service.CouponUsers().InsertJwcodeByExcel(file)
/*调用方法解析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.SuccessWithData(jwcodes))
r.Response.WriteJsonExit(dto.SuccessWithMsg(fmt.Sprintf("发放成功,发放了%d人", result)))
/*调用方法解析excel文件,并将解析出结果传入另一个函数去发放卡券*/
}
// 给用户发放卡券
func (c *CouponUsers) InsertCouponUser(r *ghttp.Request) {
// 传入jwcodes字符串,解析并发放卡券
func (c *CouponUsers) InsertCouponUserByJwcodeStr(r *ghttp.Request) {
// 解析请求
var req *couponusers.InsertCouponUserReq
var req *couponusers.InsertCouponUserByJwcodeStrReq
if err := r.Parse(&req); err != nil {
r.Response.WriteJsonExit(dto.Error(err.Error()))
}
result, err := service.CouponUsers().InsertCouponUsersByJwcodes(r.Context(), req.Jwcodes, req.CouponId)
result, err := service.CouponUsers().InsertCouponUsersByJwcodeStr(r.Context(), req.Jwcodes, req.CouponId)
//错误处理
if err != nil {
r.Response.WriteJsonExit(dto.Error(err.Error()))
@ -111,7 +126,7 @@ func (c *CouponUsers) InsertCouponUser(r *ghttp.Request) {
}
/*近期使用*/
// 导入满足条件的用户jwcode到redis
// 导入满足条件的用户jwcode到redis //不导入到redis了,导入到数据库表中
func (c *CouponUsers) InsertJwcodesToRedisByExcel(r *ghttp.Request) {
// 从请求中获取文件
file, _, err := r.FormFile("EligibleJwcodesExcel")

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.

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)
}

65
internal/logic/couponusers/couponUsers.go

@ -109,11 +109,13 @@ func (s *sCouponUsers) DeleteCouponUserByJwcode(ctx context.Context, couponId, j
}
// 通过excel导入精网号
func (s *sCouponUsers) InsertJwcodeByExcel(file multipart.File) (jwcodes []int, err error) {
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 nil, errors.New("打开文件失败")
return 0, errors.New("打开文件失败")
}
// 延时关闭文件
defer func(f *excelize.File) {
@ -126,15 +128,16 @@ func (s *sCouponUsers) InsertJwcodeByExcel(file multipart.File) (jwcodes []int,
//读取所有工作表名称
GetSheetMap := f.GetSheetMap()
if len(GetSheetMap) == 0 {
return nil, errors.New("没有工作表")
return 0, errors.New("没有工作表")
}
rows, err := f.GetRows("Sheet1")
if err != nil {
return nil, err
return 0, err
}
// 将每行的第一列转换为int,并添加到切片中
var jwcodes []int
for i, row := range rows {
//跳过第一行
if i == 0 {
@ -154,15 +157,46 @@ func (s *sCouponUsers) InsertJwcodeByExcel(file multipart.File) (jwcodes []int,
//将字符串转换为整数
jwcode, err := strconv.Atoi(jwcodeStr)
if err != nil {
return nil, errors.New("参数转换失败")
return 0, errors.New("参数转换失败")
}
jwcodes = append(jwcodes, jwcode)
/*参数校验*/
}
return //返回jwcodes切片
/*给用户发放卡券*/
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)
@ -254,12 +288,12 @@ func (s *sCouponUsers) InsertJwcodesToRedisByExcel(file multipart.File) (err err
}
// 判断jwcode是否在表coupon_qualified_users中
count, err := g.DB().Model(ctx, "coupon_qualified_users").Where("jwcode = ?", jwcode).Count()
count, err := dao.CouponQualifiedUsers.Ctx(ctx).Where("jwcode = ?", jwcode).Count()
if err != nil {
return errors.New("检索数据库中是否已存在数据失败")
}
if count == 0 { //不存在,插入
_, err = g.DB().Model(ctx, "coupon_qualified_users").Insert(g.Map{
_, err = dao.CouponQualifiedUsers.Ctx(ctx).Insert(g.Map{
"jwcode": jwcode,
})
}
@ -274,19 +308,18 @@ func (s *sCouponUsers) InsertJwcodesToRedisByExcel(file multipart.File) (err err
// 判断某用户能否抽到卡券
func (s *sCouponUsers) IsEligibleUser(ctx context.Context, jwcode int, couponIds []int) (img string, err error) {
//从数据库中获取符合条件的精网号EligibleJwcodes
var EligibleJwcodes []int
err = g.DB().Model(ctx, "coupon_qualified_users").Fields("jwcode").Scan(&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("核验数据库(满足条件)中数据为空")
}
/*从redis中获取符合条件的精网号EligibleJwcodes*/
//检查jwcode是否在EligibleJwcodes中
for _, EligibleJwcode := range EligibleJwcodes {
if EligibleJwcode == jwcode {
if EligibleJwcode.Jwcode == jwcode {
//存在,有资格,判断是否抽取过
for _, couponId := range couponIds {
count, err := dao.CouponUsers.Ctx(ctx).Where("jwcode = ?", jwcode).Where("coupon_id = ?", couponId).Count()
@ -322,8 +355,8 @@ func (s *sCouponUsers) IssueCouponToUser(ctx context.Context, jwcode, couponId i
//不存在 查看是否满足条件,满足就添加,不满足就返回
//从数据库中获取符合条件的精网号EligibleJwcodes
var EligibleJwcodes []int
err = g.DB().Model(ctx, "coupon_qualified_users").Fields("jwcode").Scan(&EligibleJwcodes)
var EligibleJwcodes []couponusers.InsertCouponUserRes
err = dao.CouponQualifiedUsers.Ctx(ctx).Fields("jwcode").Scan(&EligibleJwcodes)
if err != nil {
return errors.New("从数据库中获取符合条件的精网号失败")
}
@ -333,7 +366,7 @@ func (s *sCouponUsers) IssueCouponToUser(ctx context.Context, jwcode, couponId i
//检查jwcode是否在EligibleJwcodes中
for _, EligibleJwcode := range EligibleJwcodes {
if EligibleJwcode == jwcode {
if EligibleJwcode.Jwcode == jwcode {
//存在,可以插入
_, err := dao.CouponUsers.Ctx(ctx).Insert(g.Map{
"jwcode": jwcode,

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{} //
}

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:""` //
}

6
internal/service/couponusers.go

@ -19,8 +19,10 @@ type (
// 根据jwcode,优惠券id删除用户
DeleteCouponUserByJwcode(ctx context.Context, couponId int, jwcode int) (result sql.Result, err error)
// 通过excel导入精网号
InsertJwcodeByExcel(file multipart.File) (jwcodes []int, err error)
// 根据精网号发放用户优惠券
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)

Loading…
Cancel
Save