Merge remote-tracking branch 'origin/master'

# Conflicts:
#	internal/model/userTaskReward.go
This commit is contained in:
chy
2025-06-26 21:02:26 +08:00
14 changed files with 183 additions and 65 deletions

View File

@ -21,4 +21,5 @@ type IRewardV1 interface {
GetGoods(ctx context.Context, req *v1.GetGoodsReq) (res *v1.GetGoodsRes, err error) GetGoods(ctx context.Context, req *v1.GetGoodsReq) (res *v1.GetGoodsRes, err error)
GetGoodsDetails(ctx context.Context, req *v1.GetGoodsDetailsReq) (res *v1.GetGoodsDetailsRes, 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) OperateTaskReward(ctx context.Context, req *v1.OperateTaskRewardReq) (res *v1.OperateTaskRewardRes, err error)
GetUserRewardsCanClaimList(ctx context.Context, req *v1.GetUserRewardsCanClaimListReq) (res *v1.GetUserRewardsCanClaimListRes, err error)
} }

View File

@ -280,3 +280,15 @@ type OperateTaskRewardReq struct {
type OperateTaskRewardRes struct { type OperateTaskRewardRes struct {
Success bool `json:"success" dc:"是否成功"` 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"`
}

View File

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

View File

@ -28,6 +28,7 @@ type RewardTypesColumns struct {
CreatedAt string // 创建时间 CreatedAt string // 创建时间
UpdatedAt string // 更新时间 UpdatedAt string // 更新时间
DeletedAt string // 软删除时间 DeletedAt string // 软删除时间
TencentTypeId string // 腾讯类型 id
} }
// rewardTypesColumns holds the columns for the table reward_types. // rewardTypesColumns holds the columns for the table reward_types.
@ -39,6 +40,7 @@ var rewardTypesColumns = RewardTypesColumns{
CreatedAt: "created_at", CreatedAt: "created_at",
UpdatedAt: "updated_at", UpdatedAt: "updated_at",
DeletedAt: "deleted_at", DeletedAt: "deleted_at",
TencentTypeId: "tencent_type_id",
} }
// NewRewardTypesDao creates and returns a new DAO object for table data access. // NewRewardTypesDao creates and returns a new DAO object for table data access.

View File

@ -669,3 +669,55 @@ func (s *sReward) CallBack(ctx context.Context, in *model.RewardCallbackIn) (out
return &res, err 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
}

View File

@ -182,18 +182,14 @@ func (s *sTask) GetNonLoginTaskList(ctx context.Context, in *model.GetTaskListIn
// 组装奖励数据 // 组装奖励数据
err := dao.TaskRewards.Ctx(ctx). err := dao.TaskRewards.Ctx(ctx).
LeftJoin(dao.Rewards.Table(), LeftJoin(dao.Rewards.Table(),
fmt.Sprintf("`%s`.`%s` = `%s`.`%s`", fmt.Sprintf("`%s`.`%s` = `%s`.`%s` ",
dao.Rewards.Table(), dao.Rewards.Columns().Id, dao.Rewards.Table(), dao.Rewards.Columns().Id,
dao.TaskRewards.Table(), dao.TaskRewards.Columns().RewardId)). dao.TaskRewards.Table(), dao.TaskRewards.Columns().RewardId,
LeftJoin(dao.RewardTypes.Table(), ),
fmt.Sprintf("`%s`.`%s` = `%s`.`%s`", ).Fields(
dao.RewardTypes.Table(), dao.RewardTypes.Columns().Id,
dao.Rewards.Table(), dao.Rewards.Columns().RewardTypeId)).
Fields(
fmt.Sprintf( fmt.Sprintf(
"%s.*, `%s`.`%s` AS %s", "%s.*",
dao.Rewards.Table(), dao.Rewards.Table(),
dao.RewardTypes.Table(), dao.RewardTypes.Columns().Name, "reward_type_name",
), ),
).Where(dao.TaskRewards.Columns().TaskId, task.TaskID).Scan(&data.Rewards) ).Where(dao.TaskRewards.Columns().TaskId, task.TaskID).Scan(&data.Rewards)
if err != nil { if err != nil {
@ -358,16 +354,16 @@ func (s *sTask) GetTask(ctx context.Context, in *model.GetTaskIn) (out *model.Ge
return ecode.Fail.Sub("创建用户任务记录失败") return ecode.Fail.Sub("创建用户任务记录失败")
} }
snowid.GetSnowClient()
// 查询该任务相关联的奖励, 创建对应奖励下发记录id // 查询该任务相关联的奖励, 创建对应奖励下发记录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 { if err != nil {
return ecode.Fail.Sub("获取任务关联奖励列表失败") return ecode.Fail.Sub("获取任务关联奖励列表失败")
} }
for _, v := range array { for _, v := range array {
_, err = dao.UserTaskRewards.Ctx(ctx).Data(do.UserTaskRewards{ _, err = dao.UserTaskRewards.Ctx(ctx).Data(do.UserTaskRewards{
UserTaskId: id, UserTaskId: id,
RewardId: v.Int64(), RewardId: v["reward_id"].Int64(),
RewardName: v["name"].String(),
Status: consts.RewardInitStatus, Status: consts.RewardInitStatus,
InnerOrderId: fmt.Sprintf("reward%s", guid.S()), InnerOrderId: fmt.Sprintf("reward%s", guid.S()),
}).Insert() }).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) { 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 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 { if in.StoreId != 0 {
orm = orm.Where(dao.UserTasks.Columns().StoreId, in.StoreId) 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 { if err != nil {
return nil, ecode.Fail.Sub("获取用户任务列表失败") return nil, ecode.Fail.Sub("获取用户任务列表失败")
} }

View File

@ -19,4 +19,5 @@ type RewardTypes struct {
CreatedAt *gtime.Time // 创建时间 CreatedAt *gtime.Time // 创建时间
UpdatedAt *gtime.Time // 更新时间 UpdatedAt *gtime.Time // 更新时间
DeletedAt *gtime.Time // 软删除时间 DeletedAt *gtime.Time // 软删除时间
TencentTypeId interface{} // 腾讯类型 id
} }

View File

@ -17,4 +17,5 @@ type RewardTypes struct {
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"` // 创建时间 CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"` // 创建时间
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"` // 更新时间 UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"` // 更新时间
DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:"软删除时间"` // 软删除时间 DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:"软删除时间"` // 软删除时间
TencentTypeId int `json:"tencentTypeId" orm:"tencent_type_id" description:"腾讯类型 id"` // 腾讯类型 id
} }

View File

@ -1,11 +1,13 @@
package model package model
import ( import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime" "github.com/gogf/gf/v2/os/gtime"
) )
// Reward 奖励表 // Reward 奖励表
type Reward struct { type Reward struct {
g.Meta `orm:"table:rewards"`
Id int64 `json:"id" orm:"id" description:"奖励ID"` // 奖励ID Id int64 `json:"id" orm:"id" description:"奖励ID"` // 奖励ID
StoreId int64 `json:"storeId" orm:"store_id" description:"门店ID系统奖励为NULL"` // 门店ID系统奖励为NULL StoreId int64 `json:"storeId" orm:"store_id" description:"门店ID系统奖励为NULL"` // 门店ID系统奖励为NULL
Name string `json:"name" orm:"name" description:"奖励名称"` // 奖励名称 Name string `json:"name" orm:"name" description:"奖励名称"` // 奖励名称

View File

@ -10,7 +10,7 @@ type UserTask struct {
Id int64 `json:"id" orm:"id" description:"用户任务唯一标识符"` // 用户任务唯一标识符 Id int64 `json:"id" orm:"id" description:"用户任务唯一标识符"` // 用户任务唯一标识符
UserId int64 `json:"userId" orm:"user_id" description:"用户ID"` // 用户ID UserId int64 `json:"userId" orm:"user_id" description:"用户ID"` // 用户ID
TaskId string `json:"taskId" orm:"task_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:"流水号,确保用户任务唯一性"` // 流水号,确保用户任务唯一性 SerialNumber string `json:"serialNumber" orm:"serial_number" description:"流水号,确保用户任务唯一性"` // 流水号,确保用户任务唯一性
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"` // 创建时间 CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"` // 创建时间
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_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 StoreId int64 `json:"storeId" orm:"store_id" description:"门店 id"` // 门店 id
TaskName string `json:"taskName" orm:"task_name" description:"任务名称"` // 任务名称 TaskName string `json:"taskName" orm:"task_name" description:"任务名称"` // 任务名称
GameId int64 `json:"gameId" orm:"game_id" description:"游戏 id"` // 游戏 id GameId int64 `json:"gameId" orm:"game_id" description:"游戏 id"` // 游戏 id
User User `json:"user" orm:"with:id=user_id"` User User `json:"user,omitempty" orm:"with:id=user_id"`
Game Game `json:"game" orm:"with:game_id=game_id"` Game Game `json:"game,omitempty" orm:"with:game_id=game_id"`
// Store Store `json:"store" orm:"with:id=store_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 任务排行榜入参 // UserTaskRankingIn 任务排行榜入参
type UserTaskRankingIn struct { type UserTaskRankingIn struct {
Page int Page int
@ -80,6 +103,6 @@ type UserTaskRecordsListIn struct {
} }
type UserTaskRecordsListOut struct { type UserTaskRecordsListOut struct {
List []UserTask List []UserTask2
Total int Total int
} }

View File

@ -2,17 +2,23 @@ package model
import "github.com/gogf/gf/v2/os/gtime" import "github.com/gogf/gf/v2/os/gtime"
type UserTaskRewards struct { type GetUserClaimListIn struct {
Id int64 `json:"id" orm:"id" description:"用户任务奖励记录唯一标识符"` // 用户任务奖励记录唯一标识符 UserId int64
UserTaskId int64 `json:"userTaskId" orm:"user_task_id" description:"关联用户任务记录ID"` // 关联用户任务记录ID TaskId string
RewardId int64 `json:"rewardId" orm:"reward_id" description:"奖励ID"` // 奖励ID NetbarAccount string
RewardName string `json:"rewardName" orm:"reward_name" description:"奖励名称冗余字段"` // 奖励名称冗余字段 StoreId int64
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:"备注或失败原因"` // 备注或失败原因 type UserTaskReward struct {
ExternalOrderId string `json:"externalOrderId" orm:"external_order_id" description:"第三方发放平台的订单ID"` // 第三方发放平台的订单ID RewardName string `json:"rewardName" orm:"reward_name"` // 奖励名称冗余字段
InnerOrderId string `json:"innerOrderId" orm:"inner_order_id" description:"系统内部订单ID"` // 系统内部订单ID Source int `json:"source" orm:"source"` // 奖励来源1是系统奖励统一调用, 2是门店奖励
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"` // 创建时间 RewardType int `json:"rewardType" orm:"reward_type"` // 奖励类型, 实现不同的领取操作
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"` // 更新时间 Status int `json:"status" orm:"status"` // 状态1=待用户完成任务2=待领取3=已领取, 待兑换4=已过期5=发放失败, 6=结束、
DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:"软删除时间"` // 软删除时间 ExpireType int `json:"expireType" orm:"expire_type"` // 过期方式1=时间段过期2=领取后过期
ExpiredAt *gtime.Time `json:"expiredAt" orm:"expired_at" description:"奖励过期时间"` // 奖励过期时间 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
} }

View File

@ -4,7 +4,7 @@ import (
_ "github.com/gogf/gf/contrib/drivers/mysql/v2" _ "github.com/gogf/gf/contrib/drivers/mysql/v2"
_ "github.com/gogf/gf/contrib/nosql/redis/v2" _ "github.com/gogf/gf/contrib/nosql/redis/v2"
_ "server/utility/gamelife" _ "server/utility/gamelife"
_ "server/utility/mqtt/emqx" //_ "server/utility/mqtt/emqx"
_ "server/utility/myCasbin" _ "server/utility/myCasbin"
_ "server/utility/oss/aliyun" _ "server/utility/oss/aliyun"
_ "server/utility/rsa" _ "server/utility/rsa"

View File

@ -31,6 +31,7 @@ type (
OperateTaskReward(ctx context.Context, in *model.OperateTaskRewardIn) (out *model.OperateTaskRewardOut, err error) OperateTaskReward(ctx context.Context, in *model.OperateTaskRewardIn) (out *model.OperateTaskRewardOut, err error)
// CallBack 奖励回调 // CallBack 奖励回调
CallBack(ctx context.Context, in *model.RewardCallbackIn) (out *model.RewardCallbackOut, err error) CallBack(ctx context.Context, in *model.RewardCallbackIn) (out *model.RewardCallbackOut, err error)
GetUserClaimList(ctx context.Context, in *model.GetUserClaimListIn) (out *model.GetUserClaimListOut, err error)
} }
) )

View File

@ -83,9 +83,11 @@ func init() {
// 任务 // 任务
enforcer.AddPolicy("user", "/x/task/getLoginTaskList", "GET", "获取任务列表(已登录)") enforcer.AddPolicy("user", "/x/task/getLoginTaskList", "GET", "获取任务列表(已登录)")
enforcer.AddPolicy("user", "/x/task/get", "POST", "领取任务") 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/goods", "GET", "获取物品列表")
enforcer.AddPolicy("user", "/x/reward/canClaim", "GET", "获取该任务可领取奖励列表")
} }
// 门店 // 门店