package task 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" "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/snowid" "sort" "strconv" "strings" "sync" "time" ) type sTask struct{} func New() service.ITask { return &sTask{} } func init() { service.RegisterTask(New()) } func (s *sTask) UserTaskRankingList(ctx context.Context, in *model.UserTaskRankingIn) (out *model.UserTaskRankingOut, err error) { // 判断排行类型 var start, end time.Time if in.Type == 1 { // 日 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()) } else if in.Type == 2 { // 周 now := time.Now() loc := now.Location() weekday := int(now.Weekday()) if weekday == 0 { // 周日是0 weekday = 7 } // 本周开始时间(周一 00:00:00) start = time.Date(now.Year(), now.Month(), now.Day()-weekday+1, 0, 0, 0, 0, loc) // 本周结束时间(周日 23:59:59) end = time.Date(now.Year(), now.Month(), now.Day()-weekday+7, 23, 59, 59, 0, loc) } else if in.Type == 3 { // 月 now := time.Now() loc := now.Location() // 本月开始时间(1号 00:00:00) start = time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, loc) // 下月1号 nextMonth := start.AddDate(0, 1, 0) // 本月结束时间(本月最后一天 23:59:59) end = nextMonth.Add(-time.Second) } else { return nil, ecode.Params.Sub("排行方式错误") } m := dao.UserTasks.Ctx(ctx) // 构建查询条件 if in.Page == 0 { in.Page = 1 } if in.Size == 0 { in.Size = 10 } var storeId int if in.StoreId > 0 { m = m.Where(dao.UserTasks.Columns().StoreId, in.StoreId) storeId = in.StoreId } else if in.NetBarAccount != "" && in.StoreId <= 0 { value, err := dao.Stores.Ctx(ctx).Where(dao.Stores.Columns().NetbarAccount, in.NetBarAccount).Fields(dao.Stores.Columns().Id).Value() if err != nil { return nil, ecode.Fail.Sub("查询门店ID失败") } if value.IsEmpty() { return nil, ecode.Fail.Sub("门店不存在") } storeId = value.Int() m = m.Where(dao.UserTasks.Columns().StoreId, storeId) } list := make([]model.UserTaskRankingArgs, 0) var total int // SELECT `uid`,`nickname` FROM `user` ORDER BY `uid` asc err = m.Page(in.Page, in.Size).LeftJoin(dao.Users.Table(), fmt.Sprintf("`%s`.`id` = `%s`.`user_id`", dao.Users.Table(), dao.UserTasks.Table())). Fields("username,nickname,avatar,count(*) num").WhereIn(dao.UserTasks.Columns().Status, []int{2, 3}). WhereBetween(dao.UserTasks.Columns().CompletedAt, start, end).OrderDesc("num").OrderDesc("username").Group("user_id"). ScanAndCount(&list, &total, false) if err != nil { return nil, ecode.Fail.Sub("查询排行榜失败") } // 判断登录查询当前任务完成数量,排名 var rankingNum int var loginUserRanking []model.LoginUserRanking var loginUserRankingNum model.LoginUserRankingNum if in.OperatorId != 0 { value, err := dao.UserTasks.Ctx(ctx).Fields("count(*) num").Where(dao.UserTasks.Columns().UserId, in.OperatorId).Where(dao.UserTasks.Columns().StoreId, storeId). WhereIn(dao.UserTasks.Columns().Status, []int{2, 3}). WhereBetween(dao.UserTasks.Columns().CompletedAt, start, end).Group("user_id"). Value() if err != nil { return nil, ecode.Fail.Sub("查询当前登录用户完成数失败") } if value.IsEmpty() { loginUserRankingNum.Num = 0 } else { loginUserRankingNum.Num = value.Int() } err = dao.UserTasks.Ctx(ctx).LeftJoin(dao.Users.Table(), fmt.Sprintf("`%s`.`id` = `%s`.`user_id`", dao.Users.Table(), dao.UserTasks.Table())). Fields("username,count(*) num").WhereIn(dao.UserTasks.Columns().StoreId, storeId).Where(dao.UserTasks.Columns().Status, []int{2, 3}). WhereBetween(dao.UserTasks.Columns().CompletedAt, start, end).OrderDesc("num").OrderDesc("username").Group("user_id"). Scan(&loginUserRanking) if err != nil { return nil, ecode.Fail.Sub("查询当前登录用户排名失败") } // 查找当前登录用户排名 //index := sort.Search(len(loginUserRanking), func(i int) bool { // return loginUserRanking[i].Num <= loginUserRankingNum.Num //}) index, flag := sort.Find(len(loginUserRanking), func(i int) int { return strings.Compare(strconv.Itoa(loginUserRanking[i].Num), strconv.Itoa(loginUserRankingNum.Num)) }) if flag { rankingNum = index + 1 } } return &model.UserTaskRankingOut{ List: list, Total: total, CompletedNum: loginUserRankingNum.Num, RankingNum: rankingNum, }, nil } // GetNonLoginTaskList 获取下发到指定网吧的任务列表(未登录) func (s *sTask) GetNonLoginTaskList(ctx context.Context, in *model.GetTaskListIn) (out *model.GetTaskListOut, err error) { // 调用外部接口 activity, err := gamelife.GetGamelifeClient(ctx).RequestActivity(ctx, &model.QQNetbarActivityIn{ServiceName: consts.GetNonLoginTaskList, TaskParam: model.TaskParam{Gid: in.Gid, NetBarAccount: in.NetBarAccount, Num: in.Num, Pageidx: in.Pageidx}}) if err != nil { return nil, err } result, ok := activity.(*model.GameTaskResponse) if !ok { return nil, ecode.Fail.Sub("数据类型转换失败") } // 剔除不需要的任务数据 var tasks []model.Task idx := result.PageIdx //for _, task := range result.TaskList { // //data := model.Task{ // // QqNetbarTaskId: task.TaskID, // // QqNetbarTaskName: task.Title, // // QqNetbarTaskMemo: task.TaskDesc, // // QqNetbarTaskRules: task.RuleDesc, // // QqNetbarTargetName: task.TargetName, // // QqNetbarTargetTime: task.TargetTimes, // // StartTime: task.CycleStart, // // EndTime: task.CycleEnd, // //} // // // 组装奖励数据 // err := dao.TaskRewards.Ctx(ctx). // LeftJoin(dao.Rewards.Table(), // fmt.Sprintf("`%s`.`%s` = `%s`.`%s` ", // dao.Rewards.Table(), dao.Rewards.Columns().Id, // dao.TaskRewards.Table(), dao.TaskRewards.Columns().RewardId, // ), // ).Fields( // fmt.Sprintf( // "%s.*", // dao.Rewards.Table(), // ), // ).Where(dao.TaskRewards.Columns().TaskId, task.TaskID).Scan(&data.Rewards) // if err != nil { // return nil, err // } // tasks = append(tasks, data) //} return &model.GetTaskListOut{ PageIdx: idx, Data: tasks, }, nil } func (s *sTask) GetLoginTaskList(ctx context.Context, in *model.GetTaskListIn) (out *model.GetTaskListOut, err error) { // 调用外部接口 activity, err := gamelife.GetGamelifeClient(ctx).RequestActivity(ctx, &model.QQNetbarActivityIn{ServiceName: consts.GetTaskList, PopenId: in.PopenId, BindType: in.BindType, TaskParam: model.TaskParam{Gid: in.Gid, NetBarAccount: in.NetBarAccount, Num: in.Num, Pageidx: in.Pageidx}}) if err != nil { return nil, err } result, ok := activity.(*model.GameTaskResponse) if !ok { return nil, ecode.Fail.Sub("数据类型转换失败") } pageIdx := result.PageIdx // 剔除不需要的任务数据 var tasks []model.Task //for _, task := range result.TaskList { // data := model.Task{ // QqNetbarTaskId: task.TaskID, // QqNetbarTaskName: task.Title, // QqNetbarTaskMemo: task.TaskDesc, // QqNetbarTaskRules: task.RuleDesc, // QqNetbarTargetName: task.TargetName, // QqNetbarTargetTime: task.TargetTimes, // StartTime: task.CycleStart, // EndTime: task.CycleEnd, // //Status: task.Status, // } // data.UserTaskResult.Usertimes = task.UserTimes // // 组装门店奖励数据 // err := dao.TaskRewards.Ctx(ctx). // LeftJoin(dao.Rewards.Table(), // 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", // ), // ).Where(dao.TaskRewards.Columns().TaskId, task.TaskID).Scan(&data.Rewards) // if err != nil { // return nil, err // } // // // 任务状态=1或者2不做操作,其他查询门店奖励是否全部领取 // if task.Status != 1 && task.Status != 2 { // count, err := dao.UserTasks.Ctx(ctx).Where(dao.UserTasks.Columns().TaskId, task.TaskID).Where(dao.UserTasks.Columns().UserId, in.UserId).LeftJoin(dao.UserTaskRewards.Table(), // fmt.Sprintf("%s.user_tasks_id = %s.id", dao.UserTaskRewards.Table(), dao.UserTasks.Table())).LeftJoin(dao.Rewards.Table(), fmt.Sprintf("%s.id = %s.reward_id", // dao.Rewards.Table(), dao.UserTaskRewards.Table())).Where(dao.Rewards.Columns().Source, 2).Where(dao.UserTaskRewards.Columns().Status, 2).Count() // if err != nil { // return nil, ecode.Fail.Sub("查询用户门店任务奖励失败") // } // // if count > 0 { // data.Status = 2 // } else { // data.Status = 3 // } // } else { // data.Status = task.Status // } // tasks = append(tasks, data) // // // 根据用户完成次数和任务指标次数判任务是否完成,修改任务记录状态为 3 // if int(task.UserTimes) >= task.TargetTimes { // _, err := dao.UserTasks.Ctx(ctx).Where(do.UserTasks{TaskId: task.TaskID}).Where(do.UserTasks{UserId: in.UserId}).Data(do.UserTasks{Status: 3}).Update() // if err != nil { // return nil, ecode.Fail.Sub("更新用户任务记录状态异常") // } // } //} return &model.GetTaskListOut{ Data: tasks, PageIdx: pageIdx, }, err } // GetTaskCompletedList 获取用户任务完成列表 func (s *sTask) GetTaskCompletedList(ctx context.Context, in *model.TaskListIn) (out *model.TaskListOut, err error) { m := dao.UserTasks.Ctx(ctx) //var data []model.UserTask var data []model.UserTaskRecord var total int if in.StoreId > 0 { m = m.Where(dao.UserTasks.Columns().StoreId, in.StoreId) } if in.StartTime != nil && in.StartTime != nil { m = m.WhereBetween(dao.UserTasks.Columns().CompletedAt, in.StartTime, in.EndTime) } //err = m.Page(in.Page, in.Size).Fields(fmt.Sprintf("%s.*, %s.*,%s.*, %s.*", dao.UserTasks.Table(), dao.Users.Table(), dao.Stores.Table(), dao.Games.Table())). // LeftJoin(dao.Users.Table(), fmt.Sprintf("`%s`.`id` = `%s`.`user_id`", dao.Users.Table(), dao.UserTasks.Table())). // LeftJoin(dao.Stores.Table(), fmt.Sprintf("`%s`.`id` = `%s`.`store_id`", dao.Stores.Table(), dao.UserTasks.Table())). // LeftJoin(dao.Games.Table(), fmt.Sprintf("`%s`.`game_id` = `%s`.`game_id`", dao.Games.Table(), dao.UserTasks.Table())).WithAll().ScanAndCount(&data, &total, false) err = m.Page(in.Page, in.Size).Where(dao.UserTasks.Columns().Status, 2).WithAll().ScanAndCount(&data, &total, false) if err != nil { return nil, ecode.Fail.Sub("获取已完成任务列表失败") } return &model.TaskListOut{ List: data, Total: total, }, nil } func (s *sTask) GetSelectorList(ctx context.Context, in *model.SelectorIn) (out *[]model.SelectorOut, err error) { data := make([]model.SelectorOut, 0) err = dao.Merchants.Ctx(ctx).WithAll().Scan(&data) for i, v := range data { for j, vv := range v.StoreDatas { str, err := dao.Stores.Ctx(ctx).Fields("name").One(do.Stores{Id: vv.Id}) if err != nil { return nil, ecode.Fail.Sub("获取门店名称失败") } data[i].StoreDatas[j].StoreName = str.Map()["name"].(string) } } if err != nil { return nil, ecode.Fail.Sub("获取选择列表失败") } return &data, nil } // GetTask 领取任务 func (s *sTask) GetTask(ctx context.Context, in *model.GetTaskIn) (out *model.GetTaskOut, err error) { var storeId int if in.StoreId == 0 && in.NetBarAccount == "" { return nil, ecode.Fail.Sub("请选择门店") } if in.StoreId > 0 { storeId = in.StoreId } else if in.NetBarAccount != "" && in.StoreId <= 0 { value, err := dao.Stores.Ctx(ctx).Where(do.Stores{NetbarAccount: in.NetBarAccount}).Fields(dao.Stores.Columns().Id).Value() if err != nil { return nil, ecode.Fail.Sub("获取门店ID异常") } if value.IsEmpty() { return nil, ecode.Fail.Sub("获取门店ID异常") } storeId = value.Int() } var userTask []*model.UserTask // 根据任务类型判断是否存在该任务 if in.TaskType == 1 { 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()) err = dao.UserTasks.Ctx(ctx).Where(do.UserTasks{UserId: in.UserId, TaskId: in.TaskId, StoreId: storeId, GameId: in.GameId, BindType: in.BindType}). WhereBetween(dao.UserTasks.Columns().CreatedAt, start, end).Scan(&userTask) } else { err = dao.UserTasks.Ctx(ctx).Where(do.UserTasks{UserId: in.UserId, TaskId: in.TaskId, StoreId: storeId, GameId: in.GameId, BindType: in.BindType}).Scan(&userTask) } if err != nil { return nil, ecode.Fail.Sub("查询用户该任务记录失败") } if userTask != nil { return nil, ecode.Fail.Sub("该任务记录已存在") } // TODO 流水号未知 serialNumber, err := snowid.GetSnowClient().GenerateSerialNumber() if err != nil { return nil, ecode.Fail.Sub("生成流水号异常") } if err = dao.UserTasks.Transaction(ctx, func(ctx context.Context, tx gdb.TX) (err error) { // 创建任务记录 id, err := dao.UserTasks.Ctx(ctx).InsertAndGetId(do.UserTasks{ UserId: in.UserId, TaskId: in.TaskId, StoreId: storeId, Status: 1, SerialNumber: serialNumber, TaskName: in.TaskName, GameId: in.GameId, TaskType: in.TaskType, UserTimes: in.UserTimes, BindType: in.BindType, }) if err != nil { return ecode.Fail.Sub("创建用户任务记录失败") } //查询该任务相关联的奖励, 创建对应奖励下发记录id 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).All() if err != nil { return ecode.Fail.Sub("获取任务关联奖励列表失败") } for _, v := range array { var reward entity.Rewards if err := dao.Rewards.Ctx(ctx).WherePri(v["reward_id"].Int64()).Scan(&reward); err != nil { return ecode.Fail.Sub("获取任务关联奖励列表失败") } _, err = dao.UserTaskRewards.Ctx(ctx).Data(do.UserTaskRewards{ UserTaskId: id, RewardId: v["reward_id"].Int64(), RewardName: reward.Name, Status: consts.RewardInitStatus, IssueQuantity: reward.GrantQuantity, Source: reward.Source, RewardTypeId: reward.RewardTypeId, }).Insert() if err != nil { return ecode.Fail.Sub("创建用户任务奖励记录失败") } } return }); err != nil { return nil, err } return &model.GetTaskOut{ Success: true, }, nil } func (s *sTask) GetUserTaskRecordsList(ctx context.Context, in *model.UserTaskRecordsListIn) (out *model.UserTaskRecordsListOut, err error) { list := make([]model.UserTask2, 0) var total int orm := dao.UserTasks.Ctx(ctx).Where(dao.UserTasks.Columns().UserId, in.UserId) if in.BindType != 0 { orm = orm.Where(dao.UserTasks.Columns().BindType, in.BindType) } if in.StoreId != 0 && in.NetBarAccount == "" { orm = orm.Where(dao.UserTasks.Columns().StoreId, in.StoreId) } if in.NetBarAccount != "" && in.StoreId == 0 { value, err := dao.Stores.Ctx(ctx).Where(do.Stores{NetbarAccount: in.NetBarAccount}).Fields(dao.Stores.Columns().Id).Value() if err != nil { return nil, err } if value.IsEmpty() { return nil, ecode.Params.Sub("网吧账号不存在") } orm = orm.Where(dao.UserTasks.Columns().StoreId, value.Int()) } if in.GameId != 0 { orm = orm.Where(dao.UserTasks.Columns().GameId, in.GameId) } switch in.TimeType { case 1: orm = orm.WhereGTE(dao.UserTasks.Columns().CreatedAt, gtime.Now().AddDate(0, 0, -7)) case 2: orm = orm.WhereGTE(dao.UserTasks.Columns().CreatedAt, gtime.Now().AddDate(0, 0, -30)) case 3: orm = orm.WhereGTE(dao.UserTasks.Columns().CreatedAt, gtime.Now().AddDate(0, 0, -365)) } err = orm.Page(in.Page, in.Size).LeftJoin(dao.UserTaskRewards.Table(), fmt.Sprintf("`%s`.`user_task_id` = `%s`.`id`", dao.UserTaskRewards.Table(), dao.UserTasks.Table())). Fields("user_tasks.*, group_concat(user_task_rewards.reward_name SEPARATOR ',') AS reward_name").Group("user_tasks.id").ScanAndCount(&list, &total, false) if err != nil { return nil, ecode.Fail.Sub("获取用户任务列表失败") } return &model.UserTaskRecordsListOut{ List: list, Total: total, }, nil } func (s *sTask) GetTaskList(ctx context.Context, in *model.GetTaskListV2In) (out *model.GetTaskListV2Out, err error) { out = &model.GetTaskListV2Out{} if in.IsBound == 1 { // 查询实时任务数据 activity, err := gamelife.GetGamelifeClient(ctx).RequestActivity(ctx, &model.QQNetbarActivityIn{ServiceName: consts.GetTaskList, PopenId: in.PopenId, BindType: in.BindType, TaskParam: model.TaskParam{Gid: in.Gid, NetBarAccount: in.NetBarAccount, Num: in.Num, Pageidx: in.Pageidx}}) if err != nil { return nil, err } result, ok := activity.(*model.GameTaskResponse) if !ok { return nil, ecode.Fail.Sub("数据类型转换失败") } for i, v := range result.TaskList { // 获取任务奖励列表 err := dao.TaskRewards.Ctx(ctx).Where(do.TaskRewards{TaskId: v.TaskID}).WhereOr(do.TaskRewards{TaskId: v.TaskID, NetbarAccount: in.NetBarAccount}). LeftJoin(dao.Rewards.Table(), "rewards.id = task_rewards.reward_id").Fields("rewards.*").Scan(&result.TaskList[i].Rewards) if err != nil { return nil, ecode.Fail.Sub("获取任务奖励列表失败") } orm := dao.UserTasks.Ctx(ctx).Where(do.UserTasks{UserId: in.UserId, TaskId: v.TaskID, BindType: in.BindType}) if v.GameTaskConfig.TimeType == 1 { // 每日任务 start := gtime.Now().StartOfDay() end := gtime.Now().EndOfDay() orm = orm.WhereBetween(dao.UserTasks.Columns().CreatedAt, start, end) } one, err := orm.Fields(dao.UserTasks.Columns().Id, dao.UserTasks.Columns().Status, dao.UserTasks.Columns().UserTimes).One() if err != nil { return nil, ecode.Fail.Sub("获取用户任务失败") } if one.IsEmpty() || one["id"].IsEmpty() { // 不存在用户任务记录,强制用户完成任务 result.TaskList[i].Status = 1 } else { // 存在用户记录,自行判断用户是否完成任务 if v.UserTimes-one["user_times"].Int64() >= v.TargetTimes { completeTime := gtime.Now() userTaskStatus := one["status"].Int64() if userTaskStatus == 1 { if err := dao.UserTasks.Transaction(ctx, func(ctx context.Context, tx gdb.TX) (err error) { // 用户任务完成修改任务记录完成时间 _, err = dao.UserTasks.Ctx(ctx).Where(do.UserTasks{UserId: in.UserId, TaskId: v.TaskID}).Data(do.UserTasks{CompletedAt: completeTime}).Update() if err != nil { return ecode.Fail.Sub("修改用户任务完成时间失败") } if _, err := dao.UserTasks.Ctx(ctx).WherePri(one["id"].Int64()).Where(do.UserTasks{Status: 1}).Data(do.UserTasks{Status: 3}).Update(); err != nil { return ecode.Fail.Sub("修改用户任务状态失败") } all, err := dao.UserTaskRewards.Ctx(ctx).Where(do.UserTaskRewards{UserTaskId: one["id"].Int64(), Status: 1}).Fields(dao.UserTaskRewards.Columns().Id, dao.UserTaskRewards.Columns().RewardId).All() if err != nil { return ecode.Fail.Sub("获取用户任务奖励失败") } for _, record := range all { updateData := do.UserTaskRewards{Status: consts.RewardPendingStatus} rewardTypeCode, err2 := dao.Rewards.Ctx(ctx).WherePri(record["reward_id"].Int64()). InnerJoin( dao.RewardTypes.Table(), fmt.Sprintf("%s.%s = %s.%s", dao.RewardTypes.Table(), dao.RewardTypes.Columns().Id, dao.Rewards.Table(), dao.Rewards.Columns().RewardTypeId, ), ).Fields(dao.RewardTypes.Columns().Code).Value() if err2 != nil { return ecode.Fail.Sub("获取用户任务奖励失败") } if rewardTypeCode.String() == consts.NetfeeCode { if quantity, err := CalculateNetfeeRewardQuantity(ctx, in.UserId, in.NetBarAccount, record["reward_id"].Int64(), completeTime); err == nil && quantity > 0 { updateData.IssueQuantity = quantity } } if _, err := dao.UserTaskRewards.Ctx(ctx).Data(updateData).Where(do.UserTaskRewards{Id: record["id"].Int64()}).Update(); err != nil { return ecode.Fail.Sub("修改用户任务奖励失败") } } return nil }); err != nil { return nil, err } result.TaskList[i].Status = 2 } else if userTaskStatus == 3 { result.TaskList[i].Status = 2 } else { result.TaskList[i].Status = 3 } } else { result.TaskList[i].UserTimes -= one["user_times"].Int64() result.TaskList[i].Status = 1 } result.TaskList[i].UserTaskId = one["id"].Int64() } } out.PageIdx = result.PageIdx out.Data = result.TaskList } else { // 从数据库获取数据 tasks := make([]model.Task, 0) err := dao.Tasks.Ctx(ctx).Where(do.Tasks{GameId: in.Gid, NetbarAcconut: in.NetBarAccount}).WithAll().WithAll().Scan(&tasks) if err != nil { return nil, ecode.Fail.Sub("获取任务列表失败") } for i, v := range tasks { err := json.Unmarshal([]byte(v.Task), &tasks[i].GameTask) if err != nil { return nil, ecode.Fail.Sub("解析任务信息失败") } if err = dao.TaskRewards.Ctx(ctx).Where(do.TaskRewards{TaskId: v.TaskId}).WhereOr(do.TaskRewards{TaskId: v.TaskId, NetbarAccount: in.NetBarAccount}). LeftJoin(dao.Rewards.Table(), "rewards.id = task_rewards.reward_id").Fields("rewards.*").Scan(&tasks[i].GameTask.Rewards); err != nil { return nil, ecode.Fail.Sub("获取任务奖励列表失败") } // 根据任务 id 查询门店奖励追加记录 out.Data = append(out.Data, tasks[i].GameTask) } } return } func (s *sTask) SyncTaskFromGamelife(ctx context.Context) (out *model.SyncTaskOut, err error) { stores, err := dao.Stores.Ctx(ctx).Fields(dao.Stores.Columns().Id, dao.Stores.Columns().NetbarAccount).All() if err != nil { return nil, err } games, err := dao.Games.Ctx(ctx).Fields(dao.Games.Columns().GameName, dao.Games.Columns().GameId).All() if err != nil { return nil, err } var wg sync.WaitGroup for _, store := range stores { store := store // 捕获循环变量 wg.Add(1) go func() { defer wg.Done() for _, game := range games { activity, err := gamelife.GetGamelifeClient(ctx).RequestActivity( ctx, &model.QQNetbarActivityIn{ ServiceName: consts.GetNonLoginTaskList, TaskParam: model.TaskParam{ Gid: game["game_id"].Int(), NetBarAccount: store["netbar_account"].String(), Num: 50, Pageidx: "", }, }, ) if err != nil { glog.Errorf(ctx, "获取任务失败,网吧=%s,游戏=%s,错误=%v", store["netbar_account"].String(), game["game_name"].String(), err) continue } result, ok := activity.(*model.GameTaskResponse) if !ok { glog.Errorf(ctx, "数据类型转换失败,网吧=%s,游戏=%s", store["netbar_account"].String(), game["game_name"].String()) continue } var insertCount, skipCount int for _, task := range result.TaskList { exist, err := dao.Tasks.Ctx(ctx). Where("task_id = ? AND store_id = ? AND game_id = ?", task.TaskID, store["id"].Int(), game["game_id"].Int()). Count() if err != nil { glog.Errorf(ctx, "检查任务是否存在失败,task_id=%s,网吧=%s,游戏=%s,错误=%v", task.TaskID, store["netbar_account"].String(), game["game_name"].String(), err) continue } if exist > 0 { skipCount++ continue } taskMap := gconv.Map(task) //delete(taskMap, "PrizeList") //delete(taskMap, "prize_list") delete(taskMap, "reward") if err := dao.Tasks.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error { _, err = dao.Tasks.Ctx(ctx).Data(do.Tasks{ TaskId: task.TaskID, StoreId: store["id"].Int(), GameId: game["game_id"].Int(), NetbarAcconut: store["netbar_account"].String(), Task: gconv.Bytes(taskMap), }).Insert() for _, prize := range task.PrizeList { for _, goods := range prize.GoodsList { if goods.GoodsType == 37 { continue } if id, err := dao.Rewards.Ctx(ctx).Data(do.Rewards{ ImageUrl: consts.PlatformRewards[goods.GoodsType], Name: goods.GoodsName, RewardTypeId: goods.GoodsType, GameId: game["game_id"].Int(), Status: 1, GrantQuantity: goods.Num, Source: 1, }).InsertAndGetId(); err == nil { if _, err := dao.TaskRewards.Ctx(ctx).Data(do.TaskRewards{ TaskId: task.TaskID, RewardId: id, }).Insert(); err != nil { continue } } } } return nil }); err != nil { glog.Errorf(ctx, "插入任务失败,task_id=%s,网吧=%s,游戏=%s,错误=%v", task.TaskID, store["netbar_account"].String(), game["game_name"].String(), err) continue } insertCount++ } glog.Infof(ctx, "任务同步完成,网吧=%s,游戏=%s,插入任务=%d,跳过任务=%d", store["netbar_account"].String(), game["game_name"].String(), insertCount, skipCount) } }() } wg.Wait() return } func CalculateNetfeeRewardQuantity(ctx context.Context, userId int64, netbarAccount string, rewardId int64, completedTime *gtime.Time) (uint64, error) { // 获取当前小时 & 星期几(0=周日) hour := completedTime.Hour() weekday := int(completedTime.Weekday()) // 获取上机记录 areaLevel, err := dao.StoreClientSessions.Ctx(ctx). Where(do.StoreClientSessions{UserId: userId}). WhereLTE(dao.StoreClientSessions.Columns().StartTime, completedTime). Where("end_time IS NULL OR end_time >= ?", completedTime). Fields("area_name,level_id"). OrderDesc(dao.StoreClientSessions.Columns().StartTime). One() if err != nil { return 0, ecode.Fail.Sub("获取用户上机记录失败") } // 获取会员等级ID(内部ID) levelId, err := dao.StoreMemberLevels.Ctx(ctx). Where(do.StoreMemberLevels{LevelId: areaLevel["level_id"].Int64()}). Fields("id"). Value() if err != nil { return 0, ecode.Fail.Sub("获取会员等级失败") } if levelId.IsEmpty() { return 0, nil } // 获取区域ID areaId, err := dao.StoreAreas.Ctx(ctx). Where(do.StoreAreas{AreaName: areaLevel["area_name"].String()}). Fields("id"). Value() if err != nil { return 0, ecode.Fail.Sub("获取区域失败") } if areaId.IsEmpty() { return 0, nil } storeId, err := dao.Stores.Ctx(ctx).Where(do.Stores{NetbarAccount: netbarAccount}).Fields("id").Value() if err != nil { return 0, ecode.Fail.Sub("获取门店失败") } if storeId.IsEmpty() { return 0, nil } // 获取门店该区域、等级、奖励配置 priceDataStr, err := dao.StoreNetfeeAreaLevel.Ctx(ctx). Where(do.StoreNetfeeAreaLevel{ StoreId: storeId, AreaId: areaId.Int(), MemberLevelId: levelId.Int(), RewardId: rewardId, }). Fields(dao.StoreNetfeeAreaLevel.Columns().PriceData). Value() if err != nil { return 0, ecode.Fail.Sub("获取网费奖励价格配置失败") } // 若配置为空,返回默认值 if priceDataStr.IsEmpty() { return 0, nil } // 解析 priceData var priceData [][]int if err := json.Unmarshal([]byte(priceDataStr.String()), &priceData); err != nil { return 0, ecode.Fail.Sub("网费价格配置解析失败") } // 防止越界 if weekday >= len(priceData) || hour >= len(priceData[weekday]) { return 0, ecode.Fail.Sub("网费奖励价格配置不完整") } grant := uint64(priceData[weekday][hour]) glog.Infof(ctx, "网费奖励金额为 %d(来源于门店配置)", grant) return grant, nil }