package reward import ( "context" "encoding/json" "fmt" "github.com/gogf/gf/v2/database/gdb" "github.com/gogf/gf/v2/os/glog" "github.com/gogf/gf/v2/os/gtime" "github.com/gogf/gf/v2/util/gconv" "github.com/gogf/gf/v2/util/guid" "server/internal/consts" "server/internal/dao" "server/internal/model" "server/internal/model/do" "server/internal/model/entity" "server/internal/service" "server/utility/ecode" "server/utility/gamelife" "server/utility/mqtt" "server/utility/mqtt/emqx" "strconv" "time" ) type sReward struct{} func init() { service.RegisterReward(New()) } func New() service.IReward { return &sReward{} } // Create 创建奖励 func (s *sReward) Create(ctx context.Context, in *model.RewardCreateIn) (out *model.RewardCreateOut, err error) { // 仅管理员能创建系统奖励(source=1) if in.Source == 1 && in.OperatorRole != consts.AdminRoleCode { return nil, ecode.Params.Sub("只有管理员可以创建系统奖励") } // 权限验证 switch in.OperatorRole { case consts.MerchantRoleCode: // 检查商户管理员是否有该门店权限 exist, err := dao.MerchantAdmins.Ctx(ctx).LeftJoin( dao.Stores.Table(), fmt.Sprintf("%s.%s = %s.%s", dao.MerchantAdmins.Table(), dao.MerchantAdmins.Columns().MerchantId, dao.Stores.Table(), dao.Stores.Columns().MerchantId, ), ).Where( fmt.Sprintf("%s.%s = ?", dao.Stores.Table(), dao.Stores.Columns().Id), in.StoreId, ).Where( do.MerchantAdmins{Id: in.OperatorId}, ).Exist() if err != nil { return nil, ecode.Fail.Sub("检查商户权限失败") } if !exist { return nil, ecode.Params.Sub("无门店权限") } case consts.StoreRoleCode: // 检查门店管理员是否有该门店权限 exist, err := dao.StoreAdmins.Ctx(ctx).LeftJoin( dao.Stores.Table(), fmt.Sprintf("%s.%s = %s.%s", dao.StoreAdmins.Table(), dao.StoreAdmins.Columns().StoreId, dao.Stores.Table(), dao.Stores.Columns().Id, ), ).Where( fmt.Sprintf("%s.%s = ?", dao.Stores.Table(), dao.Stores.Columns().Id), in.StoreId, ).Where( do.StoreAdmins{Id: in.OperatorId}, ).Exist() if err != nil { return nil, ecode.Fail.Sub("检查门店权限失败") } if !exist { return nil, ecode.Params.Sub("无门店权限") } } // 券ID-根据时间戳生成 id := "Q" + strconv.FormatInt(time.Now().Unix(), 10) // 创建奖励 _, err = dao.Rewards.Ctx(ctx).Data(do.Rewards{ StoreId: in.StoreId, Name: in.Name, RewardTypeId: in.RewardTypeId, ImageUrl: in.Img, QqGoodsId: in.QQGoodsId, QqGoodsIdStr: in.QQGoodsIdStr, Status: in.Status, ValidFrom: in.ValidFrom, ValidTo: in.ValidTo, ExpireType: in.ExpireType, ExpireDays: in.ExpireDays, DailyTotalLimit: in.DailyTotalLimit, TotalLimit: in.TotalLimit, GameId: in.GameId, UserDailyLimit: in.UserDailyLimit, UserTotalLimit: in.UserTotalLimit, PrizeId: id, Source: in.Source, GrantQuantity: in.GrantQuantity, }).OmitEmptyData().Insert() if err != nil { return nil, err } return &model.RewardCreateOut{Success: true}, nil } // Update 更新奖励 func (s *sReward) Update(ctx context.Context, in *model.RewardUpdateIn) (out *model.RewardUpdateOut, err error) { // 查询原始记录,确保存在,并获取 source 与 store_id 用于权限校验 data, err := dao.Rewards.Ctx(ctx). Fields(dao.Rewards.Columns().Id, dao.Rewards.Columns().StoreId). Where(do.Rewards{Id: in.Id}).One() if err != nil { return nil, ecode.Fail.Sub("查询奖励失败") } if data.IsEmpty() { return nil, ecode.Params.Sub("奖励不存在") } // 系统奖励(source=1)只能由管理员修改 if in.Source == 1 && in.OperatorRole != consts.AdminRoleCode { return nil, ecode.Params.Sub("只有管理员可以修改系统奖励") } storeId := data[dao.Rewards.Columns().StoreId].Int64() // 权限校验(管理员跳过) switch in.OperatorRole { case consts.MerchantRoleCode: // 商户管理员权限校验:是否管理该门店 exist, err := dao.MerchantAdmins.Ctx(ctx).LeftJoin( dao.Stores.Table(), fmt.Sprintf("%s.%s = %s.%s", dao.MerchantAdmins.Table(), dao.MerchantAdmins.Columns().MerchantId, dao.Stores.Table(), dao.Stores.Columns().MerchantId, ), ).Where( fmt.Sprintf("%s.%s = ?", dao.Stores.Table(), dao.Stores.Columns().Id), storeId, ).Where( do.MerchantAdmins{Id: in.OperatorId}, ).Exist() if err != nil { return nil, ecode.Fail.Sub("检查操作者权限异常") } if !exist { return nil, ecode.Params.Sub("无门店权限") } case consts.StoreRoleCode: // 门店管理员权限校验:是否管理该门店 exist, err := dao.StoreAdmins.Ctx(ctx).LeftJoin( dao.Stores.Table(), fmt.Sprintf("%s.%s = %s.%s", dao.StoreAdmins.Table(), dao.StoreAdmins.Columns().StoreId, dao.Stores.Table(), dao.Stores.Columns().Id, ), ).Where( fmt.Sprintf("%s.%s = ?", dao.Stores.Table(), dao.Stores.Columns().Id), storeId, ).Where( do.StoreAdmins{Id: in.OperatorId}, ).Exist() if err != nil { return nil, ecode.Fail.Sub("检查操作者权限异常") } if !exist { return nil, ecode.Params.Sub("无门店权限") } } // 执行更新(不允许更新 store_id 和 source) _, err = dao.Rewards.Ctx(ctx). Where(do.Rewards{Id: in.Id}). Data(do.Rewards{ Name: in.Name, RewardTypeId: in.RewardTypeId, GameId: in.GameId, ImageUrl: in.Img, QqGoodsId: in.QQGoodsId, QqGoodsIdStr: in.QQGoodsIdStr, Status: in.Status, ValidFrom: in.ValidFrom, ValidTo: in.ValidTo, ExpireType: in.ExpireType, ExpireDays: in.ExpireDays, DailyTotalLimit: in.DailyTotalLimit, TotalLimit: in.TotalLimit, UserDailyLimit: in.UserDailyLimit, UserTotalLimit: in.UserTotalLimit, GrantQuantity: in.GrantQuantity, }).OmitEmptyData().Update() if err != nil { return nil, ecode.Fail.Sub("更新奖励失败") } // 判断过期类型 if in.ExpireType == 1 { in.ExpireDays = 0 _, err = dao.Rewards.Ctx(ctx).Where(do.Rewards{Id: in.Id}).Update("expire_days = null") if err != nil { return nil, err } } else { _, err = dao.Rewards.Ctx(ctx).Where(do.Rewards{Id: in.Id}).Update("valid_from = null,valid_to = null") if err != nil { return nil, err } } return &model.RewardUpdateOut{Success: true}, nil } // Delete 删除奖励 func (s *sReward) Delete(ctx context.Context, in *model.RewardDeleteIn) (out *model.RewardDeleteOut, err error) { data, err := dao.Rewards.Ctx(ctx). Fields("id", "store_id"). Where(do.Rewards{Id: in.Id}).One() if err != nil { return nil, ecode.Fail.Sub("查询奖励失败") } if data.IsEmpty() { return nil, ecode.Params.Sub("奖励不存在") } if in.Source == 1 && in.OperatorRole != consts.AdminRoleCode { return nil, ecode.Params.Sub("只有管理员可以删除系统奖励") } storeId := data["store_id"].Int64() switch in.OperatorRole { case consts.MerchantRoleCode: exist, err := dao.MerchantAdmins.Ctx(ctx).LeftJoin( dao.Stores.Table(), fmt.Sprintf("%s.%s = %s.%s", dao.MerchantAdmins.Table(), dao.MerchantAdmins.Columns().MerchantId, dao.Stores.Table(), dao.Stores.Columns().MerchantId), ).Where(fmt.Sprintf("%s.%s = ?", dao.Stores.Table(), dao.Stores.Columns().Id), storeId). Where(do.MerchantAdmins{Id: in.OperatorId}).Exist() if err != nil { return nil, ecode.Fail.Sub("权限校验失败") } if !exist { return nil, ecode.Params.Sub("无门店权限") } case consts.StoreRoleCode: exist, err := dao.StoreAdmins.Ctx(ctx).Where(do.StoreAdmins{Id: in.OperatorId, StoreId: storeId}).Exist() if err != nil { return nil, ecode.Fail.Sub("权限校验失败") } if !exist { return nil, ecode.Params.Sub("无门店权限") } } _, err = dao.Rewards.Ctx(ctx).Where(do.Rewards{Id: in.Id}).Delete() if err != nil { return nil, ecode.Fail.Sub("删除失败") } return &model.RewardDeleteOut{Success: true}, nil } // List 奖励列表 func (s *sReward) List(ctx context.Context, in *model.RewardListIn) (out *model.RewardListOut, err error) { rewardCols := dao.Rewards.Columns() orm := dao.Rewards.Ctx(ctx).LeftJoin( dao.RewardTypes.Table(), fmt.Sprintf( "%s.%s = %s.%s", dao.Rewards.Table(), dao.Rewards.Columns().RewardTypeId, dao.RewardTypes.Table(), dao.RewardTypes.Columns().Id, ), ).Fields(fmt.Sprintf("%s.*,%s.name as reward_type_name", dao.Rewards.Table(), dao.RewardTypes.Table())) switch in.OperatorRole { case consts.AdminRoleCode: // 系统管理员只能查询 source = 1 的奖励 orm = orm.Where(rewardCols.Source, 1) case consts.MerchantRoleCode, consts.StoreRoleCode: // 合并商户和门店角色权限校验 var exist bool if in.OperatorRole == consts.MerchantRoleCode { exist, err = dao.MerchantAdmins.Ctx(ctx). Where(do.MerchantAdmins{Id: in.OperatorId}). LeftJoin( dao.Stores.Table(), fmt.Sprintf("%s.%s = %s.%s", dao.MerchantAdmins.Table(), dao.MerchantAdmins.Columns().MerchantId, dao.Stores.Table(), dao.Stores.Columns().MerchantId, ), ). Where(fmt.Sprintf("%s.%s = ?", dao.Stores.Table(), dao.Stores.Columns().Id), in.StoreId). Exist() } else { exist, err = dao.StoreAdmins.Ctx(ctx). Where(do.StoreAdmins{Id: in.OperatorId}). LeftJoin( dao.Stores.Table(), fmt.Sprintf("%s.%s = %s.%s", dao.StoreAdmins.Table(), dao.StoreAdmins.Columns().StoreId, dao.Stores.Table(), dao.Stores.Columns().Id, ), ). Where(fmt.Sprintf("%s.%s = ?", dao.Stores.Table(), dao.Stores.Columns().Id), in.StoreId). Exist() } if err != nil { return nil, ecode.Fail.Sub("检查操作者权限异常") } if !exist { return nil, ecode.Params.Sub("无门店权限") } orm = orm.Where(rewardCols.Source, 2) default: return nil, ecode.Params.Sub("无效的角色") } // ==== 其他查询条件 ==== if in.Status != 0 { orm = orm.Where(fmt.Sprintf("%s.%s = ?", dao.Rewards.Table(), rewardCols.Status), in.Status) } if in.RewardTypeId != 0 { // 确保 reward_type_id 过滤独立应用 orm = orm.Where(fmt.Sprintf("%s.%s = ?", dao.Rewards.Table(), rewardCols.RewardTypeId), in.RewardTypeId) } if in.Name != "" { orm = orm.WhereLike(rewardCols.Name, "%"+in.Name+"%") } // ==== 总数统计 ==== list := make([]model.Reward, 0) var total int err = orm.ScanAndCount(&list, &total, false) if err != nil { return nil, err } return &model.RewardListOut{ List: list, Total: total, }, nil } // ListInternetCharge 网费奖励列表 func (s *sReward) ListInternetCharge(ctx context.Context, in *model.RewardListIn) (out *model.InternetChargeRewardListOut, err error) { rewardCols := dao.Rewards.Columns() orm := dao.Rewards.Ctx(ctx).LeftJoin( dao.RewardTypes.Table(), fmt.Sprintf( "%s.%s = %s.%s", dao.Rewards.Table(), dao.Rewards.Columns().RewardTypeId, dao.RewardTypes.Table(), dao.RewardTypes.Columns().Id, ), ).Fields(fmt.Sprintf("%s.*,%s.name as reward_type_name", dao.Rewards.Table(), dao.RewardTypes.Table())) switch in.OperatorRole { case consts.AdminRoleCode: // 系统管理员只能查询 source = 1 的奖励 orm = orm.Where(rewardCols.Source, 1) case consts.MerchantRoleCode, consts.StoreRoleCode: // 合并商户和门店角色权限校验 var exist bool if in.OperatorRole == consts.MerchantRoleCode { exist, err = dao.MerchantAdmins.Ctx(ctx). Where(do.MerchantAdmins{Id: in.OperatorId}). LeftJoin( dao.Stores.Table(), fmt.Sprintf("%s.%s = %s.%s", dao.MerchantAdmins.Table(), dao.MerchantAdmins.Columns().MerchantId, dao.Stores.Table(), dao.Stores.Columns().MerchantId, ), ). Where(fmt.Sprintf("%s.%s = ?", dao.Stores.Table(), dao.Stores.Columns().Id), in.StoreId). Exist() } else { exist, err = dao.StoreAdmins.Ctx(ctx). Where(do.StoreAdmins{Id: in.OperatorId}). LeftJoin( dao.Stores.Table(), fmt.Sprintf("%s.%s = %s.%s", dao.StoreAdmins.Table(), dao.StoreAdmins.Columns().StoreId, dao.Stores.Table(), dao.Stores.Columns().Id, ), ). Where(fmt.Sprintf("%s.%s = ?", dao.Stores.Table(), dao.Stores.Columns().Id), in.StoreId). Exist() } if err != nil { return nil, ecode.Fail.Sub("检查操作者权限异常") } if !exist { return nil, ecode.Params.Sub("无门店权限") } orm = orm.Where(rewardCols.Source, 2) default: return nil, ecode.Params.Sub("无效的角色") } // ==== 其他查询条件 ==== if in.Status != 0 { orm = orm.Where(fmt.Sprintf("%s.%s = ?", dao.Rewards.Table(), rewardCols.Status), in.Status) } if in.Name != "" { orm = orm.WhereLike(rewardCols.Name, "%"+in.Name+"%") } // ==== 总数统计 ==== list := make([]model.InternetChargeReward, 0) var total int err = orm.Where(dao.Rewards.Columns().RewardTypeId, 1).Fields("rewards.name,rewards.grant_quantity").ScanAndCount(&list, &total, false) if err != nil { return nil, err } return &model.InternetChargeRewardListOut{ List: list, Total: total, }, nil } // GetLift 领取奖励 // func (s *sReward) GetLift(ctx context.Context, in *model.GetRewardIn) (out *model.GetRewardOut, err error) { // // giftParam := model.GiftParam{} // var needUrl bool // // 判断奖励类型 // if in.Source == 1 { // // 系统奖励处理 // if in.RewradTypeId == 16 { // // 需要大区角色 // giftParam.AreaId = in.AreaId // giftParam.Gid = in.GameId // giftParam.RoleIdx = in.RoleIdx // giftParam.TaskId = in.TaskId // } else { // // 不需要 // giftParam.TaskId = in.TaskId // giftParam.Gid = in.GameId // // } // if in.RewardId != 16 && in.RewardId != 37 { // needUrl = true // } // } else { // // 门店奖励处理 // // } // // glog.Info(ctx, "调用 tencent开始") // activity, err := gamelife.GetGamelifeClient(ctx).RequestActivity(ctx, &model.QQNetbarActivityIn{PopenId: in.PopenId, ServiceName: consts.GetGift, GiftParam: giftParam}) // // if err != nil { // return nil, err // } // glog.Info(ctx, "调用 tencent结束") // fmt.Print(activity) // // result, ok := activity.(*model.GiftResponse) // if !ok { // return nil, ecode.Fail.Sub("数据类型转换失败") // } // // if len(result.GiftItem) == 0 { // return nil, ecode.Fail.Sub("奖励领取异常") // } // // // 存储数据库记录 // var data model.GetRewardOut // if err = dao.RewardWaters.Transaction(ctx, func(ctx context.Context, tx gdb.TX) (err error) { // for _, item := range result.GiftItem { // marshal, err := json.Marshal(item.Water) // if err != nil { // return ecode.Fail.Sub("序列化 json 数据出现异常") // } // _, err = dao.RewardWaters.Ctx(ctx).Insert(model.RewardWaters{ // OrderId: item.Water.OrderId, // Status: int64(item.Result), // Uid: item.Water.Uid, // Water: string(marshal), // TaskId: in.TaskId, // GameId: int64(in.GameId), // }) // // if err != nil { // return ecode.Fail.Sub("添加奖励领取记录异常") // } // // // 根据 result判断 // data.Result = int64(item.Result) // if item.Result == 1 { // //// 奖励发放成功,修改状态,扣除数量 // glog.Infof(ctx, "奖励发放成功1,修改状态,扣除数量") // // 查询当前奖励是否为最后一个, 如果是则更新任务状态为2 完成 // count, err := dao.UserTaskRewards.Ctx(ctx).Where(do.UserTaskRewards{UserTaskId: in.UserTaskId}).WhereIn(dao.UserTaskRewards.Columns().Status, []int{2, 3, 5}).Count() // if err != nil { // return ecode.Fail.Sub("查询用户任务奖励失败") // } // // if count == 1 { // // 修改任务记录状态2 // _, err = dao.UserTasks.Ctx(ctx).Where(do.UserTasks{Id: in.UserTaskId}).Data(do.UserTasks{ // Status: 2, // }).Update() // // if err != nil { // return ecode.Fail.Sub("修改用户任务状态失败") // } // } // // // 增加奖励已领取数量 // _, err = dao.Rewards.Ctx(ctx).Where(do.Rewards{Id: in.RewardId}).Increment(dao.Rewards.Columns().ReceivedNum, 1) // if err != nil { // return ecode.Fail.Sub("获取奖励领取记录异常") // } // // // 修改用户任务奖励记录状态 // _, err = dao.UserTaskRewards.Ctx(ctx).Where(do.UserTaskRewards{UserTaskId: in.UserTaskId, RewardId: in.RewardId}).Data(do.UserTaskRewards{ // Status: consts.RewardSuccessStatus, // }).Update() // // if err != nil { // return ecode.Fail.Sub("修改用户任务奖励记录状态异常") // } // } else if item.Result == 2 || item.Result == 3 { // // 发放背包成功,修改状态 // glog.Infof(ctx, "奖励发放成功2,修改状态") // _, err = dao.UserTaskRewards.Ctx(ctx).Data(do.UserTaskRewards{ // Status: consts.RewardExchangeStatus, // }).Where(do.UserTaskRewards{ // Id: in.UserTaskId, // RewardId: in.RewardId, // }).Update() // // if err != nil { // return ecode.Fail.Sub("修改用户任务奖励记录状态异常") // } // } else if item.Result == 4 { // // 奖励领取失败,不做操作,直接返回 // glog.Infof(ctx, "领取奖励失败") // return ecode.Fail.Sub("领取奖励失败") // } // // //data.List = append(data.List, model.GetRewardNewOut{ // // Result: int64(item.Result), // // Water: item.Water, // //}) // } // // return // // }); err != nil { // return // } // // if needUrl { // data.Url, err = gamelife.GetGamelifeClient(ctx).GetGamelifePackageUrl(ctx, in.PopenId, in.GameCode, in.GameId, in.BindType) // if err != nil { // return nil, ecode.Fail.Sub("获取绑定链接失败") // } // } // // //return &model.GetRewardOut{ // // List: data.List, // //}, err // return &data, err // } func (s *sReward) GetLift(ctx context.Context, in *model.GetRewardIn) (out *model.GetRewardOut, err error) { out = &model.GetRewardOut{} // 判断奖励类型 if in.Source == 1 { var needUrl bool giftParam := model.GiftParam{} if in.RewradTypeId == 16 { // 需要大区角色 if in.AreaId == 0 || in.RoleIdx == "" { return nil, ecode.Params.Sub("获取角色信息失败") } giftParam.AreaId = in.AreaId giftParam.Gid = in.GameId giftParam.RoleIdx = in.RoleIdx giftParam.TaskId = in.TaskId } else { // 不需要 giftParam.TaskId = in.TaskId giftParam.Gid = in.GameId } if in.RewradTypeId != 37 && in.RewradTypeId != 16 { needUrl = true } glog.Info(ctx, "调用 tencent开始") activity, err2 := gamelife.GetGamelifeClient(ctx).RequestActivity(ctx, &model.QQNetbarActivityIn{PopenId: in.PopenId, ServiceName: consts.GetGift, GiftParam: giftParam}) if err2 != nil { return nil, err2 } glog.Info(ctx, "调用 tencent结束") fmt.Print(activity) result, ok := activity.(*model.GiftResponse) if !ok { return nil, ecode.Fail.Sub("数据类型转换失败") } if len(result.GiftItem) == 0 { return nil, ecode.Fail.Sub("奖励领取异常") } // 存储数据库记录 if err = dao.RewardWaters.Transaction(ctx, func(ctx context.Context, tx gdb.TX) (err error) { for _, item := range result.GiftItem { marshal, err := json.Marshal(item.Water) if err != nil { return ecode.Fail.Sub("序列化 json 数据出现异常") } _, err = dao.RewardWaters.Ctx(ctx).Insert(model.RewardWaters{ OrderId: item.Water.OrderId, Status: int64(item.Result), Uid: item.Water.Uid, Water: string(marshal), TaskId: in.TaskId, GameId: int64(in.GameId), }) if err != nil { return ecode.Fail.Sub("添加奖励领取记录异常") } // 根据 result判断 out.Result = int64(item.Result) if item.Result == 1 { //// 奖励发放成功,修改状态,扣除数量 glog.Infof(ctx, "奖励发放成功1,修改状态,扣除数量") // 查询当前奖励是否为最后一个, 如果是则更新任务状态为2 完成 count, err := dao.UserTaskRewards.Ctx(ctx).Where(do.UserTaskRewards{UserTaskId: in.UserTaskId}).WhereIn(dao.UserTaskRewards.Columns().Status, []int{2, 3, 5}).Count() if err != nil { return ecode.Fail.Sub("查询用户任务奖励失败") } if count == 1 { // 修改任务记录状态2 _, err = dao.UserTasks.Ctx(ctx).Where(do.UserTasks{Id: in.UserTaskId}).Data(do.UserTasks{ Status: 2, CompletedAt: gtime.Now(), }).Update() if err != nil { return ecode.Fail.Sub("修改用户任务状态失败") } } if in.Source == 1 && in.RewradTypeId == 37 { // 增加奖励已领取数量 _, err = dao.Rewards.Ctx(ctx).Where(do.Rewards{Id: in.RewardId}).Increment(dao.Rewards.Columns().ReceivedNum, 1) if err != nil { return ecode.Fail.Sub("获取奖励领取记录异常") } } // 修改用户任务奖励记录状态 _, err = dao.UserTaskRewards.Ctx(ctx).Where(do.UserTaskRewards{Id: in.Id}).Data(do.UserTaskRewards{ Status: consts.RewardSuccessStatus, }).Update() if err != nil { return ecode.Fail.Sub("修改用户任务奖励记录状态异常") } } else if item.Result == 2 || item.Result == 3 { // 查询奖励过期时间 var reward entity.Rewards if err := dao.Rewards.Ctx(ctx).Where(do.Rewards{Id: in.RewardId}).Scan(&reward); err != nil { return ecode.Fail.Sub("获取奖励信息异常") } var expireTime *gtime.Time if reward.ExpireType == 2 { expireTime = gtime.Now().AddDate(0, 0, reward.ExpireDays) } else { expireTime = reward.ValidTo } // 发放背包成功,修改状态 glog.Infof(ctx, "奖励发放成功2,修改状态") _, err = dao.UserTaskRewards.Ctx(ctx).Data(do.UserTaskRewards{ Status: consts.RewardExchangeStatus, ExpiredAt: expireTime, }).Where(do.UserTaskRewards{ Id: in.Id, }).Update() if err != nil { return ecode.Fail.Sub("修改用户任务奖励记录状态异常") } needUrl = true } else if item.Result == 4 { // 奖励领取失败,不做操作,直接返回 glog.Infof(ctx, "领取奖励失败") return ecode.Fail.Sub("领取奖励失败") } } return }); err != nil { return } if needUrl { out.Url, err = gamelife.GetGamelifeClient(ctx).GetGamelifePackageUrl(ctx, in.PopenId, in.GameCode, in.GameId, in.BindType) if err != nil { return nil, ecode.Fail.Sub("获取绑定链接失败") } } } else { // 门店奖励处理 value, err := dao.RewardTypes.Ctx(ctx).WherePri(in.RewradTypeId).Value() if err != nil { return nil, ecode.Fail.Sub("获取奖励类型失败") } if value.IsEmpty() { return nil, ecode.Params.Sub("奖励类型不存在") } switch value.String() { case consts.NetfeeCode: dao.UserTaskRewards.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error { xyUserId, err := dao.Users.Ctx(ctx).WherePri(in.UserId).Fields(dao.Users.Columns().XyUserId).Value() if err != nil { return err } if xyUserId.IsEmpty() { return ecode.Params.Sub("该用户暂未绑定8圈账号,无法发放网费奖励") } storeId, err := dao.Rewards.Ctx(ctx).WherePri(in.RewardId).Fields(dao.Rewards.Columns().StoreId).Value() if err != nil { return ecode.Fail.Sub("查询奖励信息失败") } if storeId.IsEmpty() { return ecode.Params.Sub("奖励信息有误") } // 增加奖励已领取数量 _, err = dao.Rewards.Ctx(ctx).Where(do.Rewards{Id: in.RewardId}).Increment(dao.Rewards.Columns().ReceivedNum, 1) if err != nil { return ecode.Fail.Sub("获取奖励领取记录异常") } // 修改用户任务奖励记录状态 _, err = dao.UserTaskRewards.Ctx(ctx).Where(do.UserTaskRewards{Id: in.Id}).Data(do.UserTaskRewards{ Status: consts.RewardExchangeStatus, }).Update() if err != nil { return ecode.Fail.Sub("修改用户任务奖励记录状态异常") } client, b := mqtt.GetClient("emqx") if !b { return ecode.Fail.Sub("获取mqtt客户端异常") } downData := emqx.DownData{CMD: consts.CmdUserFee, StoreId: storeId.Int(), Data: struct { XyUserId string `json:"xy_user_id"` Money int `json:"money"` Note string `json:"note"` OrderId string `json:"order_id"` }{ XyUserId: xyUserId.String(), Money: in.GrantQuantity, Note: fmt.Sprintf("用户领取 id 为 %d,下发记录 id 为 %d 的网费", in.RewardId, in.Id), OrderId: gconv.String(in.Id), }} marshal, err := json.Marshal(downData) if err != nil { return ecode.Fail.Sub("json.Marshal异常") } if err = client.Publish(fmt.Sprintf(consts.DOWNDataTopic, storeId.Int()), marshal); err != nil { return ecode.Fail.Sub("Publish异常") } return nil }) } } return out, err } // GetGoodsList 调用外部获取物品列表 func (s *sReward) GetGoodsList(ctx context.Context, in *model.GetGoodsListIn) (out *model.GetGoodsListOut, err error) { var user model.User // 查询用户信息 //err = dao.Users.Ctx(ctx).Where(do.Users{Id: in.UserId}).Scan(&user) err = dao.Users.Ctx(ctx).Where(do.Users{Id: 19}).Scan(&user) if err != nil { return nil, ecode.Fail.Sub("查询用户失败") } var pOpenId string // 判断绑定类型 QQ还是WX if in.BindType == 1 { pOpenId = user.QQPopenId } else { pOpenId = user.WXPopenId } // 调用 tencent result, err := gamelife.GetGamelifeClient(ctx).RequestActivity(ctx, &model.QQNetbarActivityIn{ServiceName: consts.QueryUserGoodsList, BindType: in.BindType, GoodsParam: model.GoodsParam{AppFilter: in.Appfilter, BigTime: in.BigTime, GoodsStatus: int(in.Goodsstatus), Num: int(in.Num), OrderByDesc: true, OrderType: in.OrderType, Pageidx: in.Pageidx, Gid: 26}, PopenId: pOpenId, NickName: user.Nickname}) if err != nil { return nil, ecode.Fail.Sub("请求失败") } response, ok := result.(*model.GoodsResponse) if !ok { return nil, ecode.Fail.Sub("类型断言失败") } return &model.GetGoodsListOut{ List: response.Waters, Pageidx: response.PageIdx, Total: response.Total, }, nil } // GetGoods 物品兑换 func (s *sReward) GetGoods(ctx context.Context, in *model.GetGoodsGetIn) (out *model.GoodsGetOut, err error) { return nil, err } // GetGoodsDetails 物品详情 func (s *sReward) GetGoodsDetails(ctx context.Context, in *model.GetGoodsDetailsIn) (out *model.QueryUserGoodsDetailResponse, err error) { // activity, err := gamelife.GetGamelifeClient(ctx).RequestActivity(ctx, &model.QQNetbarActivityIn{PopenId: in.PopenId, ServiceName: consts.QueryUserGoodsDetail, QueryUserGoodsDetailParam: model.QueryUserGoodsDetailParam{ Gid: in.Gid, WinningTime: in.WinningTime, OrderId: in.OrderId, IsActInfo: in.IsActInfo, IsDocument: in.IsDocument, IsDetail: in.IsDetail, }}) if err != nil { return nil, err } result, ok := activity.(*model.QueryUserGoodsDetailResponse) if !ok { return nil, ecode.Fail.Sub("数据类型转换失败") } return &model.QueryUserGoodsDetailResponse{ Water: result.Water, }, nil } func (s *sReward) OperateTaskReward(ctx context.Context, in *model.OperateTaskRewardIn) (out *model.OperateTaskRewardOut, err error) { // 如果是系统管理员给任务添加奖励,需要校验奖励的来源 exist, err := dao.Rewards.Ctx(ctx).Where(do.Rewards{Id: in.RewardId}).Exist() if err != nil { return nil, ecode.Fail.Sub("奖励不存在") } if !exist { return nil, ecode.Params.Sub("奖励不存在") } if in.Type == 1 { _, err := dao.TaskRewards.Ctx(ctx).Data(do.TaskRewards{TaskId: in.TaskId, RewardId: in.RewardId, NetbarAccount: in.NetbarAccount, StoreId: in.StoreId}).OmitEmptyData().Insert() return &model.OperateTaskRewardOut{Success: true}, err } else { _, err := dao.TaskRewards.Ctx(ctx).Where(do.TaskRewards{TaskId: in.TaskId, RewardId: in.RewardId, NetbarAccount: in.NetbarAccount, StoreId: in.StoreId}).OmitEmptyWhere().Delete() return &model.OperateTaskRewardOut{Success: true}, err } } // CallBack 奖励回调 // // func (s *sReward) CallBack(ctx context.Context, in *model.RewardCallbackIn) (out *model.RewardCallbackOut, err error) { // var reward *model.Reward // var res model.RewardCallbackOut // res.OrderId = in.OrderId // res.AppId = in.AppId // // // 查询奖励 // err = dao.Rewards.Ctx(ctx).Where(do.Rewards{PrizeId: in.PrizeId}).Scan(&reward) // if err != nil { // res.Errcode = -1 // res.Errmsg = "查询奖励异常" // res.Datas = nil // return &res, ecode.Fail.Sub("查询奖励异常") // } // // if reward == nil { // res.Errcode = -1 // res.Errmsg = "查询奖励为空" // res.Datas = nil // return &res, ecode.Params.Sub("查询奖励为空") // } // // // 判断是否过期 // if reward.ExpireType == 1 { // //时间段过期 // if reward.ValidTo.Before(gtime.Now()) { // res.Errcode = consts.BatchOutDate // res.Errmsg = consts.BatchOutDateMSG // } // } // // // 日 // now := time.Now() // // 当天开始时间 // start := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()) // // 当天结束时间 // end := time.Date(now.Year(), now.Month(), now.Day(), 23, 59, 59, 0, now.Location()) // // 查先询用户当日已领取 // //dailyGetNum, err := dao.Rewards.Ctx(ctx). // // LeftJoin(dao.UserTaskRewards.Table(), fmt.Sprintf("%s.id=%s.reward_id", dao.Rewards.Table(), dao.UserTaskRewards.Table())). // // Where(dao.Rewards.Columns().PrizeId, in.PrizeId). // // WhereBetween(dao.UserTaskRewards.Columns().UpdatedAt, start, end). // // Where(dao.UserTaskRewards.Columns().Status, 3).WhereOr(dao.UserTaskRewards.Columns().Status, 6).Count() // // // //// dailyGetNum, err := dao.Rewards.Ctx(ctx). // //// Where(dao.Rewards.Columns().PrizeId, in.PrizeId).InnerJoin(dao.UserTaskRewards.Table(), fmt.Sprintf("%s.id=%s.reward_id", dao.Rewards.Table(), // //// dao.UserTaskRewards.Table())).InnerJoin(dao.RewardWaters.Table(), fmt.Sprintf("%s.external_order_id = %s.order_id", dao.UserTaskRewards.Table(), dao.RewardWaters.Table())). // //// Where(dao.RewardWaters.Columns().Recvuid, in.Uid).Where(dao.UserTaskRewards.Columns().Status, 3).WhereOr(dao.UserTaskRewards.Columns().Status, 6). // //// WhereBetween(dao.UserTaskRewards.Columns().UpdatedAt, start, end).Fields(fmt.Sprintf("%s.*,%s.*", dao.Rewards.Table(), dao.UserTaskRewards.Table())).Count() // // // //if err != nil { // // res.Errcode = -1 // // res.Errmsg = "查询用户当日领取数量失败" // // res.Datas = nil // // return &res, ecode.Fail.Sub("查询用户当日领取数量失败") // //} // // // //// 判断是否达到用户日限制 // //if int(reward.UserDailyLimit) <= dailyGetNum { // // res.Errcode = consts.UserDayLimit // // res.Errmsg = consts.UserDayLimitMSG // //} // // // //// 查先询用户总共已领取 // //dailyTotalNum, err := dao.Rewards.Ctx(ctx).Where(dao.Rewards.Columns().PrizeId, in.PrizeId).InnerJoin(dao.UserTaskRewards.Table(), fmt.Sprintf("%s.id=%s.reward_id", dao.Rewards.Table(), // // dao.UserTaskRewards.Table())).InnerJoin(dao.RewardWaters.Table(), fmt.Sprintf("%s.external_order_id = %s.order_id", dao.UserTaskRewards.Table(), dao.RewardWaters.Table())). // // Where(dao.RewardWaters.Columns().Recvuid, in.Uid).Where(dao.UserTaskRewards.Columns().Status, 3).WhereOr(dao.UserTaskRewards.Columns().Status, 6). // // Fields(fmt.Sprintf("%s.*,%s.*", dao.Rewards.Table(), dao.UserTaskRewards.Table())).Count() // // // //if err != nil { // // res.Errcode = -1 // // res.Errmsg = "查询用户当日总共领取数量失败" // // res.Datas = nil // // return &res, ecode.Fail.Sub("查询用户当日总共领取数量失败") // //} // //// 判断是否达到用户总限制 // //if int(reward.UserTotalLimit) <= dailyTotalNum { // // res.Errcode = consts.UserTotalLimit // // res.Errmsg = consts.UserTotalLimitMSG // //} // // // //// 查先询该批次当日已领取 // //batchDailyGetNum, err := dao.Rewards.Ctx(ctx).Where(dao.Rewards.Columns().PrizeId, in.PrizeId).InnerJoin(dao.UserTaskRewards.Table(), fmt.Sprintf("%s.id = %s.reward_id", // // dao.Rewards.Table(), dao.UserTaskRewards.Table())).Where(dao.UserTaskRewards.Columns().Status, 3).WhereOr(dao.UserTaskRewards.Columns().Status, 6). // // WhereBetween(dao.UserTaskRewards.Columns().UpdatedAt, start, end).Fields(fmt.Sprintf("%s.*,%s.*", dao.Rewards.Table(), dao.UserTaskRewards.Table())).Count() // //if err != nil { // // res.Errcode = -1 // // res.Errmsg = "查询该批次当日总共领取数量失败" // // res.Datas = nil // // return &res, ecode.Fail.Sub("查询该批次当日总共领取数量失败") // //} // //// 判断是否达到该批次日限制 // //if int(reward.DailyTotalLimit) <= batchDailyGetNum { // // res.Errcode = consts.BatchDayLimit // // res.Errmsg = consts.BatchDayLimitMSG // //} // // // //// 查先询该批次总共已领取 // //batchTotalGetNum, err := dao.Rewards.Ctx(ctx).Where(dao.Rewards.Columns().PrizeId, in.PrizeId).InnerJoin(dao.UserTaskRewards.Table(), fmt.Sprintf("%s.id = %s.reward_id", // // dao.Rewards.Table(), dao.UserTaskRewards.Table())).Where(dao.UserTaskRewards.Columns().Status, 3).WhereOr(dao.UserTaskRewards.Columns().Status, 6). // // Fields(fmt.Sprintf("%s.*,%s.*", dao.Rewards.Table(), dao.UserTaskRewards.Table())).Count() // // // //if err != nil { // // res.Errcode = -1 // // res.Errmsg = "查询该批次总共领取数量失败" // // res.Datas = nil // // return &res, ecode.Fail.Sub("查询该批次总共领取数量失败") // //} // //// 判断是否达到该批次总共限制 // //if int(reward.TotalLimit) <= batchTotalGetNum { // // res.Errcode = consts.BatchTotalLimit // // res.Errmsg = consts.BatchTotalLimitMSG // //} // // _, err = dao.RewardCallback.Ctx(ctx).OmitEmptyData().Insert(do.RewardCallback{ // OrderId: in.OrderId, // PrizeId: in.PrizeId, // PrizeType: in.PrizeType, // PrizeSubType: in.PrizeSubType, // Uid: in.Uid, // Num: in.Num, // CustomInfo: in.CustomInfo, // AppId: in.AppId, // }) // // if err != nil { // res.Errcode = -1 // res.Errmsg = "存储奖励回调数据异常" // res.Datas = nil // return &res, ecode.Fail.Sub("存储奖励回调数据异常") // } // // // 回调成功,组装响应参数 // var userTaskReward []*model.UserTaskRewards // if err = dao.Rewards.Ctx(ctx).Where(dao.Rewards.Columns().PrizeId, in.PrizeId).InnerJoin(dao.UserTaskRewards.Table(), fmt.Sprintf("%s.%s = %s.%s", // dao.Rewards.Table(), dao.Rewards.Columns().Id, dao.UserTaskRewards.Table(), dao.UserTaskRewards.Columns().RewardId)).Scan(&userTaskReward); err != nil { // return nil, ecode.Fail.Sub("获取用户奖励记录异常") // } // // if userTaskReward == nil { // res.Errcode = -1 // res.Errmsg = "用户奖励记录为空" // res.Datas = nil // return &res, ecode.Fail.Sub("用户奖励记录为空") // } // // callbackData := make([]model.CallbackData, 0) // for _, v := range userTaskReward { // callbackData = append(callbackData, model.CallbackData{ // PrizeCode: v.InnerOrderId, // }) // } // // res.Datas = callbackData // // return &res, err // } func (s *sReward) CallBack(ctx context.Context, in *model.RewardCallbackIn) (out *model.RewardCallbackOut, err error) { var reward *model.Reward var res model.RewardCallbackOut res.OrderId = in.OrderId res.AppId = in.AppId // 查询奖励 err = dao.Rewards.Ctx(ctx).Where(do.Rewards{PrizeId: in.PrizeId}).Scan(&reward) if err != nil { res.Errcode = -1 res.Errmsg = "查询奖励异常" res.Datas = nil return &res, ecode.Fail.Sub("查询奖励异常") } if reward == nil { res.Errcode = -1 res.Errmsg = "查询奖励为空" res.Datas = nil return &res, ecode.Params.Sub("查询奖励为空") } // 判断是否过期 if reward.ExpireType == 1 { //时间段过期 if reward.ValidTo.Before(gtime.Now()) { res.Errcode = consts.BatchOutDate res.Errmsg = consts.BatchOutDateMSG } } // 日 now := time.Now() // 当天开始时间 start := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()) // 当天结束时间 end := time.Date(now.Year(), now.Month(), now.Day(), 23, 59, 59, 0, now.Location()) value, err := dao.Users.Ctx(ctx).Where(dao.Users.Columns().WxPopenId, fmt.Sprintf("WX_%s", in.Uid)).WhereOr(dao.Users.Columns().QqPopenId, fmt.Sprintf("QQ_%s", in.Uid)).Fields(dao.Users.Columns().Id).Value() if err != nil { res.Errcode = -1 res.Errmsg = "查询用户ID异常" res.Datas = nil return &res, ecode.Fail.Sub("查询用户ID异常") } userId := value.Int64() // 查询当前用户当天领取总数 userTodayNum, err := dao.UserTasks.Ctx(ctx).Where(do.UserTasks{UserId: userId}).LeftJoin(dao.UserTaskRewards.Table(), "utr", "utr.user_task_id = user_tasks.id"). WhereIn("utr.status", []int{3, 6}). Where("utr.reward_id = ?", reward.Id).WhereBetween("utr.updated_at", start, end).Count() if err != nil { res.Errcode = -1 res.Errmsg = "查询用户当天领取数量异常" res.Datas = nil return &res, ecode.Fail.Sub("查询用户当天领取数量异常") } if userTodayNum >= int(reward.UserDailyLimit) { res.Errcode = consts.UserDayLimit res.Errmsg = consts.UserDayLimitMSG } // 查询当前用户该奖励领取总数 userTotalNum, err := dao.UserTasks.Ctx(ctx).Where(do.UserTasks{UserId: userId}).LeftJoin(dao.UserTaskRewards.Table(), "utr", "utr.user_task_id = user_tasks.id"). WhereIn("utr.status", []int{3, 6}). Where("utr.reward_id = ?", reward.Id).Count() if err != nil { res.Errcode = -1 res.Errmsg = "查询用户领取数量异常" res.Datas = nil return &res, ecode.Fail.Sub("查询用户领取数量异常") } if userTotalNum >= int(reward.UserTotalLimit) { res.Errcode = consts.UserTotalLimit res.Errmsg = consts.UserTotalLimitMSG } // 查询该奖励今天发放总数 todayNum, err := dao.UserTaskRewards.Ctx(ctx).WhereBetween("updated_at", start, end).Where("reward_id = ?", reward.Id).WhereIn("status", []int{3, 6}).Count() if err != nil { res.Errcode = -1 res.Errmsg = "查询该批次今天领取数量异常" res.Datas = nil return &res, ecode.Fail.Sub("查询该批次今天领取数量异常") } if todayNum >= int(reward.DailyTotalLimit) { res.Errcode = consts.BatchDayLimit res.Errmsg = consts.BatchDayLimitMSG } // 查询该奖励所有领取总数 totalNum, err := dao.UserTaskRewards.Ctx(ctx).Where("reward_id = ?", reward.Id).WhereIn("status", []int{3, 6}).Count() if err != nil { res.Errcode = -1 res.Errmsg = "查询该批次总共领取数量异常" res.Datas = nil return &res, ecode.Fail.Sub("查询该批次总共领取数量异常") } if totalNum >= int(reward.TotalLimit) { res.Errcode = consts.BatchTotalLimit res.Errmsg = consts.BatchTotalLimitMSG } _, err = dao.RewardCallback.Ctx(ctx).OmitEmptyData().Insert(do.RewardCallback{ OrderId: in.OrderId, PrizeId: in.PrizeId, PrizeType: in.PrizeType, PrizeSubType: in.PrizeSubType, Uid: in.Uid, Num: in.Num, CustomInfo: in.CustomInfo, AppId: in.AppId, InnerOrderId: fmt.Sprintf("reward%s", guid.S()), }) if err != nil { res.Errcode = -1 res.Errmsg = "存储奖励回调数据异常" res.Datas = nil return &res, ecode.Fail.Sub("存储奖励回调数据异常") } //// 回调成功,组装响应参数 var rewardCallback []model.RewardCallback if err = dao.RewardCallback.Ctx(ctx).Where(dao.RewardCallback.Columns().PrizeId, in.PrizeId).Scan(&rewardCallback); err != nil { return nil, ecode.Fail.Sub("获取用户奖励记录异常") } //if userTaskReward == nil { // res.Errcode = -1 // res.Errmsg = "用户奖励记录为空" // res.Datas = nil // return &res, ecode.Fail.Sub("用户奖励记录为空") //} callbackData := make([]model.CallbackData, 0) for _, v := range rewardCallback { callbackData = append(callbackData, model.CallbackData{ PrizeCode: v.InnerOrderId, }) } res.Datas = callbackData return &res, err } func (s *sReward) GetUserClaimList(ctx context.Context, in *model.GetUserClaimListIn) (out *model.GetUserClaimListOut, err error) { // Initialize result slice rewards := make([]model.UserTaskRewards, 0) var total int if err = dao.UserTaskRewards.Ctx(ctx).Where(do.UserTaskRewards{UserTaskId: in.UserTaskId}). LeftJoin(dao.Rewards.Table(), "r", "r.id = user_task_rewards.reward_id").Fields("user_task_rewards.*, r.image_url").ScanAndCount(&rewards, &total, false); err != nil { return nil, ecode.Fail.Sub("查询用户领取列表异常") } return &model.GetUserClaimListOut{ List: rewards, Total: total, }, nil } func (s *sReward) NetfeeCallback(ctx context.Context, in *model.NetfeeCallbackIn) (out *model.NetfeeCallbackOut, err error) { if err = dao.UserTaskRewards.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error { value, err := dao.UserTaskRewards.Ctx(ctx).WherePri(in.OrderId).Fields(dao.UserTaskRewards.Columns().UserTaskId).Value() if err != nil { return ecode.Fail.Sub("查询用户任务奖励失败") } if value.IsEmpty() { return ecode.Fail.Sub("查询用户任务奖励失败") } count, err := dao.UserTaskRewards.Ctx(ctx).Where(do.UserTaskRewards{UserTaskId: value.Int64()}).WhereIn(dao.UserTaskRewards.Columns().Status, []int{2, 3, 5}).Count() if err != nil { return ecode.Fail.Sub("查询用户任务奖励失败") } if count == 1 { // 修改任务记录状态2 _, err = dao.UserTasks.Ctx(ctx).Where(do.UserTasks{Id: value.Int64()}).Data(do.UserTasks{ Status: 2, }).Update() if err != nil { return ecode.Fail.Sub("修改用户任务状态失败") } } if _, err := dao.UserTaskRewards.Ctx(ctx).Data(do.UserTaskRewards{ Status: consts.RewardSuccessStatus, }).Update(); err != nil { return ecode.Fail.Sub("修改用户任务奖励状态失败") } return nil }); err != nil { return nil, err } return &model.NetfeeCallbackOut{Success: true}, nil } func (s *sReward) GetNetfeeList(ctx context.Context, in *model.NetfeeListIn) (out *model.NetfeeListOut, err error) { // 查询奖励类型为网费的奖励 id value, err := dao.RewardTypes.Ctx(ctx).Where(do.RewardTypes{Code: "internet_fee"}).Fields(dao.RewardTypes.Columns().Id).Value() if err != nil { return nil, ecode.Fail.Sub("查询奖励类型id失败") } if value.IsEmpty() { return nil, ecode.Fail.Sub("查询奖励类型id为空") } var data model.NetfeeRewards var total int m := dao.Rewards.Ctx(ctx) if in.StartTime != nil && in.EndTime != nil { m = m.WhereBetween(dao.Rewards.Columns().UpdatedAt, in.StartTime, in.EndTime) } if err = m.Page(in.Page, in.Size).Where(do.Rewards{RewardTypeId: value.Int64(), StoreId: in.StoreId}).WithAll().ScanAndCount(&data, &total, false); err != nil { return nil, ecode.Fail.Sub("查询网费奖励列表失败") } return &model.NetfeeListOut{ List: data.NetfeeUserTaskRewards, Total: len(data.NetfeeUserTaskRewards), }, nil }