7 changed files with 345 additions and 0 deletions
-
24api/v1/coupon/coupon.go
-
5internal/cmd/cmd.go
-
105internal/controller/coupon/coupon.go
-
158internal/logic/coupon/coupon.go
-
1internal/logic/logic.go
-
15internal/model/dto/dto_coupon.go
-
37internal/service/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:"失效时间"` |
||||
|
} |
@ -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", |
||||
|
}) |
||||
|
} |
@ -0,0 +1,158 @@ |
|||||
|
package coupon |
||||
|
|
||||
|
import ( |
||||
|
"CouponBackendGo/api/v1/coupon" |
||||
|
"CouponBackendGo/internal/dao" |
||||
|
"CouponBackendGo/internal/model/do" |
||||
|
"CouponBackendGo/internal/model/dto" |
||||
|
"CouponBackendGo/internal/service" |
||||
|
"context" |
||||
|
"encoding/json" |
||||
|
"fmt" |
||||
|
"github.com/gogf/gf/v2/frame/g" |
||||
|
"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) { |
||||
|
// 从Redis中获取数据
|
||||
|
value, _ := g.Redis().Get(ctx, fmt.Sprintf("%d-%d couponlist", pageNo, pageSize)) |
||||
|
if value.String() != "" { |
||||
|
// 如果Redis中有数据,尝试解析为Coupon列表
|
||||
|
err = json.Unmarshal(value.Bytes(), &couponList) //反序列化
|
||||
|
couponlist, cnt := UpdateCoupon(ctx, couponList) |
||||
|
|
||||
|
if cnt > 0 { |
||||
|
// 将修改后的卡券列表序列化并存储到Redis,更新频繁变更的数据
|
||||
|
couponListJson, _ := json.Marshal(couponlist) |
||||
|
_, err = g.Redis().Set(ctx, fmt.Sprintf("%d-%d couponlist", pageNo, pageSize), couponListJson) |
||||
|
} |
||||
|
|
||||
|
if err != nil { |
||||
|
return nil, err |
||||
|
} |
||||
|
return couponlist, err |
||||
|
} |
||||
|
|
||||
|
// 如果Redis中没有数据,查询数据库
|
||||
|
err = dao.Coupon.Ctx(ctx).Where("deleted", 0).Order("updated_at desc, end_time desc").Page(pageNo, pageSize).Scan(&couponList) |
||||
|
couponList = InitCoupon(ctx, couponList) |
||||
|
couponList, _ = UpdateCoupon(ctx, couponList) |
||||
|
if err != nil { |
||||
|
return nil, err |
||||
|
} |
||||
|
|
||||
|
// 将查询到的卡券列表序列化并存储到Redis,更新频繁变更的数据
|
||||
|
couponListJson, _ := json.Marshal(couponList) |
||||
|
_, err = g.Redis().Set(ctx, fmt.Sprintf("%d-%d couponlist", pageNo, pageSize), couponListJson) |
||||
|
|
||||
|
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 //使用期后
|
||||
|
v.Count, _ = dao.CouponUsers.Ctx(ctx).Where("coupon_id", v.Id).Count() |
||||
|
} else { |
||||
|
v.Status = 1 //使用期中
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return couponList |
||||
|
} |
||||
|
|
||||
|
func UpdateCoupon(ctx context.Context, couponList []*dto.DtoCoupon) ([]*dto.DtoCoupon, int) { |
||||
|
cnt := 0 |
||||
|
for _, v := range couponList { |
||||
|
if v.Status != 2 { |
||||
|
if v.StartTime.Unix() > gtime.Now().Unix() { |
||||
|
v.Status = 0 |
||||
|
} else if v.EndTime.Unix() <= gtime.Now().Unix() { |
||||
|
v.Status = 2 |
||||
|
cnt++ |
||||
|
} else { |
||||
|
v.Status = 1 |
||||
|
} |
||||
|
v.Count, _ = dao.CouponUsers.Ctx(ctx).Where("coupon_id", v.Id).Count() |
||||
|
} |
||||
|
} |
||||
|
return couponList, cnt |
||||
|
} |
||||
|
|
||||
|
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 |
||||
|
} |
||||
|
|
||||
|
// 软删除数据后,删除所有缓存
|
||||
|
keys, err := g.Redis().Keys(ctx, "*-* couponlist") |
||||
|
if len(keys) > 0 { |
||||
|
_, err = g.Redis().Del(ctx, keys...) |
||||
|
} |
||||
|
|
||||
|
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.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.Unix(), |
||||
|
}).WherePri(req.Id).Update() |
||||
|
} |
||||
|
if err != nil { |
||||
|
return err |
||||
|
} |
||||
|
|
||||
|
// 新增&编辑数据后,删除所有缓存
|
||||
|
keys, err := g.Redis().Keys(ctx, "*-* couponlist") |
||||
|
if len(keys) > 0 { |
||||
|
_, err = g.Redis().Del(ctx, keys...) |
||||
|
} |
||||
|
|
||||
|
return |
||||
|
} |
@ -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,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 |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue