Files
arenax-server/internal/logic/task/task.go

404 lines
13 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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) {
list := make([]model.UserTask, 0)
var total int
orm := dao.UserTasks.Ctx(ctx).Where(dao.UserTasks.Columns().Id, in.UserId)
if in.StoreId != 0 {
orm = orm.Where(dao.UserTasks.Columns().StoreId, in.StoreId)
}
err = orm.Page(in.Page, in.Size).ScanAndCount(&list, &total, false)
if err != nil {
return nil, ecode.Fail.Sub("获取用户任务列表失败")
}
return &model.UserTaskRecordsListOut{
List: list,
Total: total,
}, nil
}