package reward import ( "context" "encoding/json" "fmt" "server/internal/consts" "server/internal/dao" "server/internal/model" "server/internal/model/do" "server/internal/service" "server/utility/ecode" "server/utility/gamelife" ) 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("无门店权限") } } // 创建奖励 _, 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, }).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() rewardTypeCols := dao.RewardTypes.Columns() rewardTypeIds := make([]int64, 0) // ==== 权限校验 ==== switch in.OperatorRole { case consts.AdminRoleCode: // 系统管理员只能查询 source = 1 的奖励 array, err := dao.RewardTypes.Ctx(ctx).Where(do.RewardTypes{Source: 1}).Fields(rewardTypeCols.Id).Array() if err != nil { return nil, ecode.Fail.Sub("获取奖励类型列表失败") } for _, value := range array { rewardTypeIds = append(rewardTypeIds, value.Int64()) } 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("无门店权限") } // array, err := dao.RewardTypes.Ctx(ctx).Where(do.RewardTypes{Source: 2, StoreId: in.StoreId}).Fields(rewardTypeCols.Id).Array() if err != nil { return nil, ecode.Fail.Sub("获取奖励类型列表失败") } for _, value := range array { rewardTypeIds = append(rewardTypeIds, value.Int64()) } default: return nil, ecode.Params.Sub("无效的角色") } 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())). WhereIn(dao.Rewards.Columns().RewardTypeId, rewardTypeIds) // ==== 其他查询条件 ==== 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 } // GetLift 领取奖励 func (s *sReward) GetLift(ctx context.Context, in *model.GetRewardIn) (out *model.GetRewardOut, err error) { // 遍历奖励类型列表 //for _, v := range in.RewradTypeId { // if v > 0 { // // 发背包+兑换 // // } // if v > 0 { // // 直接发背包 // } //} activity, err := gamelife.GetGamelifeClient(ctx).RequestActivity(ctx, &model.QQNetbarActivityIn{PopenId: in.PopenId, ServiceName: consts.GetGift, GiftParam: model.GiftParam{ TaskId: in.TaskId, AreaId: in.AreaId, Gid: in.GameId, RoleIdx: in.RoleIdx, }}) if err != nil { return nil, err } result, ok := activity.(*model.GiftResponse) if !ok { return nil, ecode.Fail.Sub("数据类型转换失败") } // 存储数据库记录 for _, item := range result.GiftItem { marshal, err := json.Marshal(item.Water) if err != nil { return nil, ecode.Fail.Sub("序列化 json 数据出现异常") } _, err = dao.RewardWaters.Ctx(ctx).Insert(model.RewardWaters{ OrderId: item.Water.OrderId, Status: int64(item.Water.Status), Uid: item.Water.Uid, TaskId: "BZD", Water: string(marshal), }) if err != nil { return nil, ecode.Fail.Sub("添加奖励领取记录异常") } } return nil, 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.Tasks.Ctx(ctx).Where(do.Tasks{Id: in.TaskId}).Exist() if err != nil { return nil, ecode.Fail.Sub("任务不存在") } if !exist { return nil, ecode.Params.Sub("任务不存在") } 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("奖励不存在") } opiton := dao.TaskRewards.Ctx(ctx).Data(do.TaskRewards{TaskId: in.TaskId, RewardId: in.RewardId}) if in.Type == 1 { _, err := opiton.Insert() return &model.OperateTaskRewardOut{Success: true}, err } else { _, err := opiton.Delete() return &model.OperateTaskRewardOut{Success: true}, err } }