diff --git a/api/reward/reward.go b/api/reward/reward.go index 907c53f..a022606 100644 --- a/api/reward/reward.go +++ b/api/reward/reward.go @@ -21,4 +21,5 @@ type IRewardV1 interface { GetGoods(ctx context.Context, req *v1.GetGoodsReq) (res *v1.GetGoodsRes, err error) GetGoodsDetails(ctx context.Context, req *v1.GetGoodsDetailsReq) (res *v1.GetGoodsDetailsRes, err error) OperateTaskReward(ctx context.Context, req *v1.OperateTaskRewardReq) (res *v1.OperateTaskRewardRes, err error) + GetUserRewardsCanClaimList(ctx context.Context, req *v1.GetUserRewardsCanClaimListReq) (res *v1.GetUserRewardsCanClaimListRes, err error) } diff --git a/api/reward/v1/reward.go b/api/reward/v1/reward.go index 30ef77a..52c04e6 100644 --- a/api/reward/v1/reward.go +++ b/api/reward/v1/reward.go @@ -280,3 +280,15 @@ type OperateTaskRewardReq struct { type OperateTaskRewardRes struct { Success bool `json:"success" dc:"是否成功"` } + +type GetUserRewardsCanClaimListReq struct { + g.Meta `path:"/reward/canClaim" method:"get" tags:"Reward" summary:"(PC)获取用户可领取的奖励列表"` + StoreId int64 `json:"storeId" dc:"门店id"` + NetbarAccount string `json:"netbarAccount" dc:"网吧账号"` + TaskId string `json:"taskId" dc:"任务id" v:"required#任务id不能为空"` +} + +type GetUserRewardsCanClaimListRes struct { + List interface{} `json:"list"` + Total int `json:"total"` +} diff --git a/internal/controller/reward/reward_v1_get_user_rewards_can_claim_list.go b/internal/controller/reward/reward_v1_get_user_rewards_can_claim_list.go new file mode 100644 index 0000000..4bf05b3 --- /dev/null +++ b/internal/controller/reward/reward_v1_get_user_rewards_can_claim_list.go @@ -0,0 +1,19 @@ +package reward + +import ( + "context" + "github.com/gogf/gf/v2/frame/g" + "server/internal/model" + "server/internal/service" + + "server/api/reward/v1" +) + +func (c *ControllerV1) GetUserRewardsCanClaimList(ctx context.Context, req *v1.GetUserRewardsCanClaimListReq) (res *v1.GetUserRewardsCanClaimListRes, err error) { + userId := g.RequestFromCtx(ctx).GetCtxVar("id").Int64() + out, err := service.Reward().GetUserClaimList(ctx, &model.GetUserClaimListIn{NetbarAccount: req.NetbarAccount, StoreId: req.StoreId, TaskId: req.TaskId, UserId: userId}) + if err != nil { + return nil, err + } + return &v1.GetUserRewardsCanClaimListRes{List: out.List, Total: out.Total}, nil +} diff --git a/internal/dao/internal/reward_types.go b/internal/dao/internal/reward_types.go index 14d6955..2c2e791 100644 --- a/internal/dao/internal/reward_types.go +++ b/internal/dao/internal/reward_types.go @@ -21,24 +21,26 @@ type RewardTypesDao struct { // RewardTypesColumns defines and stores column names for the table reward_types. type RewardTypesColumns struct { - Id string // 奖励类型ID - Name string // 类型名称 - Code string // 唯一编码 - IconUrl string // 图标链接地址 - CreatedAt string // 创建时间 - UpdatedAt string // 更新时间 - DeletedAt string // 软删除时间 + Id string // 奖励类型ID + Name string // 类型名称 + Code string // 唯一编码 + IconUrl string // 图标链接地址 + CreatedAt string // 创建时间 + UpdatedAt string // 更新时间 + DeletedAt string // 软删除时间 + TencentTypeId string // 腾讯类型 id } // rewardTypesColumns holds the columns for the table reward_types. var rewardTypesColumns = RewardTypesColumns{ - Id: "id", - Name: "name", - Code: "code", - IconUrl: "icon_url", - CreatedAt: "created_at", - UpdatedAt: "updated_at", - DeletedAt: "deleted_at", + Id: "id", + Name: "name", + Code: "code", + IconUrl: "icon_url", + CreatedAt: "created_at", + UpdatedAt: "updated_at", + DeletedAt: "deleted_at", + TencentTypeId: "tencent_type_id", } // NewRewardTypesDao creates and returns a new DAO object for table data access. diff --git a/internal/logic/reward/reward.go b/internal/logic/reward/reward.go index 6231ab8..dbbd4a4 100644 --- a/internal/logic/reward/reward.go +++ b/internal/logic/reward/reward.go @@ -669,3 +669,55 @@ func (s *sReward) CallBack(ctx context.Context, in *model.RewardCallbackIn) (out return &res, err } + +func (s *sReward) GetUserClaimList(ctx context.Context, in *model.GetUserClaimListIn) (out *model.GetUserClaimListOut, err error) { + // Input validation + if in == nil || in.UserId == 0 || in.TaskId == "" { + return nil, ecode.Params.Sub("用户任务记录不存在") + } + + // Initialize result slice + rewards := make([]model.Reward, 0) + var totalCount int + + // Query user task record + userTask, err := dao.UserTasks.Ctx(ctx). + Where(do.UserTasks{UserId: in.UserId, TaskId: in.TaskId}). + Fields(dao.UserTasks.Columns().Id). + One() + if err != nil { + return nil, ecode.Fail.Sub("查询用户任务记录异常") + } + if userTask == nil { + return nil, ecode.Params.Sub("用户任务记录不存在") + } + + // Build base query for rewards + query := dao.UserTaskRewards.Ctx(ctx). + LeftJoin(dao.Rewards.Table(), fmt.Sprintf("%s.%s = %s.%s", + dao.Rewards.Table(), + dao.Rewards.Columns().Id, + dao.UserTaskRewards.Table(), + dao.UserTaskRewards.Columns().RewardId)). + Where(fmt.Sprintf("%s.%s = ?", + dao.UserTaskRewards.Table(), + dao.UserTaskRewards.Columns().UserTaskId), + userTask["id"].Int64()). + Where(dao.UserTaskRewards.Columns().DeletedAt, nil). + Where(dao.Rewards.Columns().DeletedAt, nil) + + // Count rewards + if totalCount, err = query.Count(); err != nil { + return nil, ecode.Fail.Sub("任务奖励获取失败") + } + + // Scan rewards + if err = query.Fields(fmt.Sprintf("%s.*", dao.Rewards.Table())).Scan(&rewards); err != nil { + return nil, ecode.Fail.Sub("任务奖励获取失败") + } + + return &model.GetUserClaimListOut{ + List: rewards, + Total: totalCount, + }, nil +} diff --git a/internal/logic/task/task.go b/internal/logic/task/task.go index a410cf7..a703d34 100644 --- a/internal/logic/task/task.go +++ b/internal/logic/task/task.go @@ -182,20 +182,16 @@ func (s *sTask) GetNonLoginTaskList(ctx context.Context, in *model.GetTaskListIn // 组装奖励数据 err := dao.TaskRewards.Ctx(ctx). LeftJoin(dao.Rewards.Table(), - fmt.Sprintf("`%s`.`%s` = `%s`.`%s`", + fmt.Sprintf("`%s`.`%s` = `%s`.`%s` ", dao.Rewards.Table(), dao.Rewards.Columns().Id, - dao.TaskRewards.Table(), dao.TaskRewards.Columns().RewardId)). - LeftJoin(dao.RewardTypes.Table(), - fmt.Sprintf("`%s`.`%s` = `%s`.`%s`", - dao.RewardTypes.Table(), dao.RewardTypes.Columns().Id, - dao.Rewards.Table(), dao.Rewards.Columns().RewardTypeId)). - Fields( - fmt.Sprintf( - "%s.*, `%s`.`%s` AS %s", - dao.Rewards.Table(), - dao.RewardTypes.Table(), dao.RewardTypes.Columns().Name, "reward_type_name", + dao.TaskRewards.Table(), dao.TaskRewards.Columns().RewardId, ), - ).Where(dao.TaskRewards.Columns().TaskId, task.TaskID).Scan(&data.Rewards) + ).Fields( + fmt.Sprintf( + "%s.*", + dao.Rewards.Table(), + ), + ).Where(dao.TaskRewards.Columns().TaskId, task.TaskID).Scan(&data.Rewards) if err != nil { return nil, err } @@ -358,16 +354,16 @@ func (s *sTask) GetTask(ctx context.Context, in *model.GetTaskIn) (out *model.Ge return ecode.Fail.Sub("创建用户任务记录失败") } - snowid.GetSnowClient() // 查询该任务相关联的奖励, 创建对应奖励下发记录id - array, err := dao.TaskRewards.Ctx(ctx).Where(do.TaskRewards{TaskId: in.TaskId}).Fields(dao.TaskRewards.Columns().RewardId).Array() + array, err := dao.TaskRewards.Ctx(ctx).LeftJoin(dao.Rewards.Table(), "rewards.id = task_rewards.reward_id").Where(do.TaskRewards{TaskId: in.TaskId}).Fields(dao.TaskRewards.Columns().RewardId).Fields(dao.Rewards.Columns().Name).All() if err != nil { return ecode.Fail.Sub("获取任务关联奖励列表失败") } for _, v := range array { _, err = dao.UserTaskRewards.Ctx(ctx).Data(do.UserTaskRewards{ UserTaskId: id, - RewardId: v.Int64(), + RewardId: v["reward_id"].Int64(), + RewardName: v["name"].String(), Status: consts.RewardInitStatus, InnerOrderId: fmt.Sprintf("reward%s", guid.S()), }).Insert() @@ -385,14 +381,14 @@ func (s *sTask) GetTask(ctx context.Context, in *model.GetTaskIn) (out *model.Ge } func (s *sTask) GetUserTaskRecordsList(ctx context.Context, in *model.UserTaskRecordsListIn) (out *model.UserTaskRecordsListOut, err error) { - list := make([]model.UserTask, 0) + list := make([]model.UserTask2, 0) var total int - orm := dao.UserTasks.Ctx(ctx).Where(dao.UserTasks.Columns().Id, in.UserId) + orm := dao.UserTasks.Ctx(ctx).Where(dao.UserTasks.Columns().UserId, in.UserId) if in.StoreId != 0 { orm = orm.Where(dao.UserTasks.Columns().StoreId, in.StoreId) } - err = orm.Page(in.Page, in.Size).ScanAndCount(&list, &total, false) + err = orm.Page(in.Page, in.Size).WithAll().ScanAndCount(&list, &total, false) if err != nil { return nil, ecode.Fail.Sub("获取用户任务列表失败") } diff --git a/internal/model/do/reward_types.go b/internal/model/do/reward_types.go index a70b718..1ea0d59 100644 --- a/internal/model/do/reward_types.go +++ b/internal/model/do/reward_types.go @@ -11,12 +11,13 @@ import ( // RewardTypes is the golang structure of table reward_types for DAO operations like Where/Data. type RewardTypes struct { - g.Meta `orm:"table:reward_types, do:true"` - Id interface{} // 奖励类型ID - Name interface{} // 类型名称 - Code interface{} // 唯一编码 - IconUrl interface{} // 图标链接地址 - CreatedAt *gtime.Time // 创建时间 - UpdatedAt *gtime.Time // 更新时间 - DeletedAt *gtime.Time // 软删除时间 + g.Meta `orm:"table:reward_types, do:true"` + Id interface{} // 奖励类型ID + Name interface{} // 类型名称 + Code interface{} // 唯一编码 + IconUrl interface{} // 图标链接地址 + CreatedAt *gtime.Time // 创建时间 + UpdatedAt *gtime.Time // 更新时间 + DeletedAt *gtime.Time // 软删除时间 + TencentTypeId interface{} // 腾讯类型 id } diff --git a/internal/model/entity/reward_types.go b/internal/model/entity/reward_types.go index eb2f34f..6c887b7 100644 --- a/internal/model/entity/reward_types.go +++ b/internal/model/entity/reward_types.go @@ -10,11 +10,12 @@ import ( // RewardTypes is the golang structure for table reward_types. type RewardTypes struct { - Id int64 `json:"id" orm:"id" description:"奖励类型ID"` // 奖励类型ID - Name string `json:"name" orm:"name" description:"类型名称"` // 类型名称 - Code string `json:"code" orm:"code" description:"唯一编码"` // 唯一编码 - IconUrl string `json:"iconUrl" orm:"icon_url" description:"图标链接地址"` // 图标链接地址 - CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"` // 创建时间 - UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"` // 更新时间 - DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:"软删除时间"` // 软删除时间 + Id int64 `json:"id" orm:"id" description:"奖励类型ID"` // 奖励类型ID + Name string `json:"name" orm:"name" description:"类型名称"` // 类型名称 + Code string `json:"code" orm:"code" description:"唯一编码"` // 唯一编码 + IconUrl string `json:"iconUrl" orm:"icon_url" description:"图标链接地址"` // 图标链接地址 + CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"` // 创建时间 + UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"` // 更新时间 + DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:"软删除时间"` // 软删除时间 + TencentTypeId int `json:"tencentTypeId" orm:"tencent_type_id" description:"腾讯类型 id"` // 腾讯类型 id } diff --git a/internal/model/reward.go b/internal/model/reward.go index 533a0d4..08a4f1e 100644 --- a/internal/model/reward.go +++ b/internal/model/reward.go @@ -1,11 +1,13 @@ package model import ( + "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/os/gtime" ) // Reward 奖励表 type Reward struct { + g.Meta `orm:"table:rewards"` Id int64 `json:"id" orm:"id" description:"奖励ID"` // 奖励ID StoreId int64 `json:"storeId" orm:"store_id" description:"门店ID,系统奖励为NULL"` // 门店ID,系统奖励为NULL Name string `json:"name" orm:"name" description:"奖励名称"` // 奖励名称 diff --git a/internal/model/userTask.go b/internal/model/userTask.go index 313b6f3..94b73bb 100644 --- a/internal/model/userTask.go +++ b/internal/model/userTask.go @@ -10,7 +10,7 @@ type UserTask struct { Id int64 `json:"id" orm:"id" description:"用户任务唯一标识符"` // 用户任务唯一标识符 UserId int64 `json:"userId" orm:"user_id" description:"用户ID"` // 用户ID TaskId string `json:"taskId" orm:"task_id" description:"腾讯任务ID"` // 腾讯任务ID - Status int `json:"status" orm:"status" description:"任务状态:1=进行中,2=已完成中,3=未完成"` // 任务状态:1=进行中,2=已完成中,3=未完成 + Status int `json:"status" orm:"status" description:"任务状态:1=进行中,2=已完成中,3=未完成"` // 任务状态:1=进行中(显示领取按钮),2=已完成 SerialNumber string `json:"serialNumber" orm:"serial_number" description:"流水号,确保用户任务唯一性"` // 流水号,确保用户任务唯一性 CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"` // 创建时间 UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"` // 更新时间 @@ -19,11 +19,34 @@ type UserTask struct { StoreId int64 `json:"storeId" orm:"store_id" description:"门店 id"` // 门店 id TaskName string `json:"taskName" orm:"task_name" description:"任务名称"` // 任务名称 GameId int64 `json:"gameId" orm:"game_id" description:"游戏 id"` // 游戏 id - User User `json:"user" orm:"with:id=user_id"` - Game Game `json:"game" orm:"with:game_id=game_id"` + User User `json:"user,omitempty" orm:"with:id=user_id"` + Game Game `json:"game,omitempty" orm:"with:game_id=game_id"` // Store Store `json:"store" orm:"with:id=store_id"` } +type TaskReward struct { + g.Meta `orm:"table:task_rewards"` + TaskId string `json:"-" orm:"task_id"` + RewardId int64 `json:"-" orm:"reward_id"` + Rewards Reward `json:"reward" orm:"with:id=reward_id"` +} + +type UserTask2 struct { + Id int64 `json:"id" orm:"id" description:"用户任务唯一标识符"` // 用户任务唯一标识符 + UserId int64 `json:"userId" orm:"user_id" description:"用户ID"` // 用户ID + TaskId string `json:"taskId" orm:"task_id" description:"腾讯任务ID"` // 腾讯任务ID + Status int `json:"status" orm:"status" description:"任务状态:1=进行中,2=已完成中,3=未完成"` // 任务状态:1=进行中(显示领取按钮),2=已完成 + SerialNumber string `json:"serialNumber" orm:"serial_number" description:"流水号,确保用户任务唯一性"` // 流水号,确保用户任务唯一性 + CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"` // 创建时间 + UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"` // 更新时间 + CompletedAt *gtime.Time `json:"completedAt" orm:"completed_at" description:"任务完成时间"` // 任务完成时间 + DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:"软删除时间戳"` // 软删除时间戳 + StoreId int64 `json:"storeId" orm:"store_id" description:"门店 id"` // 门店 id + TaskName string `json:"taskName" orm:"task_name" description:"任务名称"` // 任务名称 + GameId int64 `json:"gameId" orm:"game_id" description:"游戏 id"` // 游戏 id + TaskRewards []TaskReward `json:"taskRewards" orm:"with:task_id=task_id"` +} + // UserTaskRankingIn 任务排行榜入参 type UserTaskRankingIn struct { Page int @@ -80,6 +103,6 @@ type UserTaskRecordsListIn struct { } type UserTaskRecordsListOut struct { - List []UserTask + List []UserTask2 Total int } diff --git a/internal/model/userTaskReward.go b/internal/model/userTaskReward.go index c7595fb..e4208aa 100644 --- a/internal/model/userTaskReward.go +++ b/internal/model/userTaskReward.go @@ -2,17 +2,23 @@ package model import "github.com/gogf/gf/v2/os/gtime" -type UserTaskRewards struct { - Id int64 `json:"id" orm:"id" description:"用户任务奖励记录唯一标识符"` // 用户任务奖励记录唯一标识符 - UserTaskId int64 `json:"userTaskId" orm:"user_task_id" description:"关联用户任务记录ID"` // 关联用户任务记录ID - RewardId int64 `json:"rewardId" orm:"reward_id" description:"奖励ID"` // 奖励ID - RewardName string `json:"rewardName" orm:"reward_name" description:"奖励名称冗余字段"` // 奖励名称冗余字段 - Status int `json:"status" orm:"status" description:"状态:1=待用户完成任务,2=待领取,3=已领取, 待兑换,4=已过期,5=发放失败, 6=结束"` // 状态:1=待用户完成任务,2=待领取,3=已领取, 待兑换,4=已过期,5=发放失败, 6=结束 - Remark string `json:"remark" orm:"remark" description:"备注或失败原因"` // 备注或失败原因 - ExternalOrderId string `json:"externalOrderId" orm:"external_order_id" description:"第三方发放平台的订单ID"` // 第三方发放平台的订单ID - InnerOrderId string `json:"innerOrderId" orm:"inner_order_id" description:"系统内部订单ID"` // 系统内部订单ID - CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"` // 创建时间 - UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"` // 更新时间 - DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:"软删除时间"` // 软删除时间 - ExpiredAt *gtime.Time `json:"expiredAt" orm:"expired_at" description:"奖励过期时间"` // 奖励过期时间 +type GetUserClaimListIn struct { + UserId int64 + TaskId string + NetbarAccount string + StoreId int64 +} +type UserTaskReward struct { + RewardName string `json:"rewardName" orm:"reward_name"` // 奖励名称冗余字段 + Source int `json:"source" orm:"source"` // 奖励来源,1是系统奖励统一调用, 2是门店奖励 + RewardType int `json:"rewardType" orm:"reward_type"` // 奖励类型, 实现不同的领取操作 + Status int `json:"status" orm:"status"` // 状态:1=待用户完成任务,2=待领取,3=已领取, 待兑换,4=已过期,5=发放失败, 6=结束、 + ExpireType int `json:"expireType" orm:"expire_type"` // 过期方式:1=时间段过期,2=领取后过期 + ValidFrom *gtime.Time `json:"validFrom" orm:"valid_from" ` // 有效期开始时间(expire_type=1时) + ValidTo *gtime.Time `json:"validTo" orm:"valid_to"` // 有效期结束时间(expire_type=1时) + ExpireDays int `json:"expireDays" orm:"expire_days"` // 领取后多少天过期(expire_type=2时) +} +type GetUserClaimListOut struct { + List []Reward + Total int } diff --git a/internal/packed/packed.go b/internal/packed/packed.go index d483800..e61b667 100644 --- a/internal/packed/packed.go +++ b/internal/packed/packed.go @@ -4,7 +4,7 @@ import ( _ "github.com/gogf/gf/contrib/drivers/mysql/v2" _ "github.com/gogf/gf/contrib/nosql/redis/v2" _ "server/utility/gamelife" - _ "server/utility/mqtt/emqx" + //_ "server/utility/mqtt/emqx" _ "server/utility/myCasbin" _ "server/utility/oss/aliyun" _ "server/utility/rsa" diff --git a/internal/service/reward.go b/internal/service/reward.go index 9d88ec2..cb1900d 100644 --- a/internal/service/reward.go +++ b/internal/service/reward.go @@ -31,6 +31,7 @@ type ( OperateTaskReward(ctx context.Context, in *model.OperateTaskRewardIn) (out *model.OperateTaskRewardOut, err error) // CallBack 奖励回调 CallBack(ctx context.Context, in *model.RewardCallbackIn) (out *model.RewardCallbackOut, err error) + GetUserClaimList(ctx context.Context, in *model.GetUserClaimListIn) (out *model.GetUserClaimListOut, err error) } ) diff --git a/utility/myCasbin/casbin.go b/utility/myCasbin/casbin.go index 2956513..59f68cf 100644 --- a/utility/myCasbin/casbin.go +++ b/utility/myCasbin/casbin.go @@ -83,9 +83,11 @@ func init() { // 任务 enforcer.AddPolicy("user", "/x/task/getLoginTaskList", "GET", "获取任务列表(已登录)") enforcer.AddPolicy("user", "/x/task/get", "POST", "领取任务") + enforcer.AddPolicy("user", "/x/task/records", "GET", "获取任务记录列表") // 奖励 enforcer.AddPolicy("user", "/x/reward/goods", "GET", "获取物品列表") + enforcer.AddPolicy("user", "/x/reward/canClaim", "GET", "获取该任务可领取奖励列表") } // 门店