package task import ( "context" "fmt" "github.com/gogf/gf/v2/database/gdb" "github.com/gogf/gf/v2/util/guid" "server/internal/consts" "server/internal/dao" "server/internal/model" "server/internal/model/do" "server/internal/service" "server/utility/ecode" "server/utility/gamelife" "server/utility/snowid" "sort" "strconv" "strings" "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 } if in.StoreId > 0 { m = m.Where(dao.UserTasks.Columns().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("门店不存在") } m = m.Where(dao.UserTasks.Columns().StoreId, value.Int()) } 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,avatar,count(*) num").Where(dao.UserTasks.Columns().Status, 2). 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, in.StoreId).Where(dao.UserTasks.Columns().Status, 2). 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").Where(dao.UserTasks.Columns().StoreId, in.StoreId).Where(dao.UserTasks.Columns().Status, 2). 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)). 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 } 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 } tasks = append(tasks, data) } 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 total int if in.StoreId > 0 { m = m.Where(dao.UserTasks.Columns().StoreId, in.StoreId) } //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).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 { 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 err = dao.UserTasks.Ctx(ctx).Where(do.UserTasks{UserId: in.UserId, TaskId: in.TaskId, StoreId: storeId, GameId: in.GameId}).WhereNot("status", 3).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, }) if err != nil { 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() if err != nil { return ecode.Fail.Sub("获取任务关联奖励列表失败") } for _, v := range array { _, err = dao.UserTaskRewards.Ctx(ctx).Data(do.UserTaskRewards{ UserTaskId: id, RewardId: v.Int64(), Status: consts.RewardInitStatus, InnerOrderId: fmt.Sprintf("reward%s", guid.S()), }).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) { return }