434 lines
12 KiB
Go
434 lines
12 KiB
Go
package taskser
|
|
|
|
import (
|
|
"91porn-server/app/appg"
|
|
"91porn-server/common/db"
|
|
"91porn-server/common/log"
|
|
"91porn-server/common/stderr"
|
|
"91porn-server/common/timeutil"
|
|
"91porn-server/models/v/prizemod"
|
|
"91porn-server/models/v/signtaskmod"
|
|
"91porn-server/models/v/taskrecordmod"
|
|
"91porn-server/models/v/txnmod"
|
|
"91porn-server/models/v/usermod"
|
|
"encoding/json"
|
|
"sort"
|
|
"strconv"
|
|
"time"
|
|
|
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
|
)
|
|
|
|
// 签到
|
|
func Sign(uid uint64, configID string) (code stderr.Code) {
|
|
now := time.Now()
|
|
id, err := primitive.ObjectIDFromHex(configID)
|
|
if err != nil {
|
|
return stderr.ErrParamError
|
|
}
|
|
// 获取用户信息
|
|
u, err := usermod.FindUserByUID(uid)
|
|
if err != nil || u == nil {
|
|
code = stderr.UserIsNotExists
|
|
return
|
|
}
|
|
// 获取配置列表
|
|
signConfig, err := signtaskmod.GetConfigList()
|
|
if err != nil {
|
|
return stderr.ErrDbQueryError
|
|
}
|
|
// 查询当前签到配置
|
|
configInfo, err := signtaskmod.GetConfigByID(id)
|
|
if err != nil {
|
|
return stderr.ErrDbQueryError
|
|
}
|
|
// 异常判定 未配置签到福利/签到福利类型不正确
|
|
if configInfo == nil || signConfig == nil || len(signConfig) == 0 {
|
|
log.Info("未配置签到福利")
|
|
return stderr.ErrInvalidRequest
|
|
}
|
|
// 查询签到信息
|
|
signRecordMap := make(map[string]bool, 0)
|
|
taskInfo, err := taskrecordmod.GetSignRecord(uid)
|
|
if err != nil {
|
|
return stderr.ErrDbQueryError
|
|
}
|
|
if taskInfo == nil {
|
|
log.Info("未查询到签到任务")
|
|
return stderr.ErrDbQueryError
|
|
}
|
|
for _, taskId := range taskInfo.SignRecord {
|
|
signRecordMap[taskId.Hex()] = true
|
|
}
|
|
// 判断是否重复签到
|
|
if _, ok := signRecordMap[configID]; ok {
|
|
log.Info("已签到")
|
|
return stderr.HasSigned
|
|
}
|
|
// 计算相差多少天
|
|
duration := timeutil.BeginningOfDay(now).Sub(taskInfo.SignTime)
|
|
diffDays := int64(duration.Hours() / 24)
|
|
// 判断此签到是否是当天签到
|
|
if configInfo.FinishCondition-1 != diffDays {
|
|
log.Info("条件不匹配")
|
|
return stderr.ErrInvalidRequest
|
|
}
|
|
// 获取奖品列表
|
|
prizes, err := prizemod.GetPrizeListByIDs(configInfo.Prizes)
|
|
if err != nil {
|
|
return stderr.ErrDbQueryError
|
|
}
|
|
// 获取额外奖品列表
|
|
signCount := len(signRecordMap)
|
|
for _, item := range signConfig {
|
|
if item.FinishCondition == int64(signCount)+1 {
|
|
extraPrizeIds, e := prizemod.GetPrizeListByIDs(item.ExtraPrizes)
|
|
if e != nil {
|
|
continue
|
|
}
|
|
prizes = append(prizes, extraPrizeIds...)
|
|
}
|
|
}
|
|
// 更新签到记录(事务)
|
|
if err = appg.VideoDB.Trans(func(t *db.MongoTool) error {
|
|
if err = taskrecordmod.TaskSignUpdate(t, uid, id); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}); err != nil {
|
|
return stderr.ErrDbTransError
|
|
}
|
|
// 发放奖励
|
|
for _, v := range prizes {
|
|
for i := 0; i < int(v.Count); i++ {
|
|
handler, err := prizemod.Run(uid, *v, txnmod.SignBoon)
|
|
if err != nil {
|
|
log.Error("签到发放奖励handler失败:", log.Any("err", err))
|
|
continue
|
|
}
|
|
err = appg.VideoDB.Trans(func(t *db.MongoTool) error {
|
|
err = handler.Run(t)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = txnmod.InsertManyTransactionLog(t, handler.GetTransactionLog())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
log.Error("签到发放奖励事务失败:", log.Any("err", err))
|
|
continue
|
|
}
|
|
}
|
|
}
|
|
return stderr.Success
|
|
}
|
|
|
|
// 补签
|
|
func ReSign(uid uint64, configID string) (code stderr.Code) {
|
|
now := time.Now()
|
|
redisKey := "task::resign::" + strconv.FormatUint(uid, 10)
|
|
if appg.Redis.Exists(redisKey) {
|
|
return stderr.ExceededTimes
|
|
}
|
|
id, err := primitive.ObjectIDFromHex(configID)
|
|
if err != nil {
|
|
return stderr.ErrParamError
|
|
}
|
|
// 获取用户信息
|
|
u, err := usermod.FindUserByUID(uid)
|
|
if err != nil || u == nil {
|
|
code = stderr.UserIsNotExists
|
|
return
|
|
}
|
|
// 获取配置列表
|
|
signConfig, err := signtaskmod.GetConfigList()
|
|
if err != nil {
|
|
return stderr.ErrDbQueryError
|
|
}
|
|
// 查询当前签到配置
|
|
configInfo, err := signtaskmod.GetConfigByID(id)
|
|
if err != nil {
|
|
return stderr.ErrDbQueryError
|
|
}
|
|
// 异常判定 未配置签到福利/签到福利类型不正确
|
|
if configInfo == nil || signConfig == nil || len(signConfig) == 0 {
|
|
log.Info("未配置签到福利")
|
|
return stderr.ErrInvalidRequest
|
|
}
|
|
//查询签到信息
|
|
signRecordMap := make(map[string]bool, 0)
|
|
taskInfo, err := taskrecordmod.GetSignRecord(uid)
|
|
if err != nil {
|
|
return stderr.ErrDbQueryError
|
|
}
|
|
if taskInfo == nil {
|
|
log.Info("未查询到签到任务")
|
|
return stderr.ErrDbQueryError
|
|
}
|
|
for _, taskId := range taskInfo.SignRecord {
|
|
signRecordMap[taskId.Hex()] = true
|
|
}
|
|
// 判断是否重复签到
|
|
if _, ok := signRecordMap[configID]; ok {
|
|
log.Info("已签到")
|
|
return stderr.HasSigned
|
|
}
|
|
// 计算相差多少天
|
|
duration := timeutil.BeginningOfDay(now).Sub(taskInfo.SignTime)
|
|
diffDays := int64(duration.Hours() / 24)
|
|
// 判断是否在补签范围
|
|
if configInfo.FinishCondition > diffDays {
|
|
log.Info("条件不匹配")
|
|
return stderr.ErrInvalidRequest
|
|
}
|
|
|
|
// redis作为倒计时(一天只能补签一次)
|
|
seconds := int64(timeutil.BeginningOfTomorrow(now).Sub(now).Seconds())
|
|
err = appg.Redis.Set(redisKey, configID, time.Duration(seconds)*time.Second)
|
|
if err != nil {
|
|
log.Error(err.Error())
|
|
}
|
|
return stderr.Success
|
|
}
|
|
|
|
// 补签回调
|
|
func ReSignCallBack(uid uint64) (code stderr.Code) {
|
|
now := time.Now()
|
|
redisKey := "task::resign::" + strconv.FormatUint(uid, 10)
|
|
if !appg.Redis.Exists(redisKey) {
|
|
return stderr.ErrParamError
|
|
}
|
|
configID, err := appg.Redis.Get(redisKey)
|
|
if err != nil {
|
|
log.Error("redis缓存不存在!")
|
|
return stderr.ErrParamError
|
|
}
|
|
if configID == nil {
|
|
log.Error("签到配置不存在!")
|
|
return stderr.ErrParamError
|
|
}
|
|
|
|
id, err := primitive.ObjectIDFromHex(*configID)
|
|
if err != nil {
|
|
return stderr.ErrParamError
|
|
}
|
|
// 获取用户信息
|
|
u, err := usermod.FindUserByUID(uid)
|
|
if err != nil || u == nil {
|
|
code = stderr.UserIsNotExists
|
|
return
|
|
}
|
|
// 获取配置列表
|
|
signConfig, err := signtaskmod.GetConfigList()
|
|
if err != nil {
|
|
return stderr.ErrDbQueryError
|
|
}
|
|
// 查询当前签到配置
|
|
configInfo, err := signtaskmod.GetConfigByID(id)
|
|
if err != nil {
|
|
return stderr.ErrDbQueryError
|
|
}
|
|
// 异常判定 未配置签到福利/签到福利类型不正确
|
|
if configInfo == nil || signConfig == nil || len(signConfig) == 0 {
|
|
log.Info("未配置签到福利")
|
|
return stderr.ErrInvalidRequest
|
|
}
|
|
//查询签到信息
|
|
signRecordMap := make(map[string]bool, 0)
|
|
taskInfo, err := taskrecordmod.GetSignRecord(uid)
|
|
if err != nil {
|
|
return stderr.ErrDbQueryError
|
|
}
|
|
if taskInfo == nil {
|
|
log.Info("未查询到签到任务")
|
|
return stderr.ErrDbQueryError
|
|
}
|
|
for _, taskId := range taskInfo.SignRecord {
|
|
signRecordMap[taskId.Hex()] = true
|
|
}
|
|
// 判断是否重复签到
|
|
if _, ok := signRecordMap[*configID]; ok {
|
|
log.Info("已签到")
|
|
return stderr.HasSigned
|
|
}
|
|
// 计算相差多少天
|
|
duration := timeutil.BeginningOfDay(now).Sub(taskInfo.SignTime)
|
|
diffDays := int64(duration.Hours() / 24)
|
|
// 判断是否在补签范围
|
|
if configInfo.FinishCondition > diffDays {
|
|
log.Info("条件不匹配")
|
|
return stderr.ErrInvalidRequest
|
|
}
|
|
// 获取奖品列表
|
|
prizes, err := prizemod.GetPrizeListByIDs(configInfo.Prizes)
|
|
if err != nil {
|
|
return stderr.ErrDbQueryError
|
|
}
|
|
// 获取额外奖品列表
|
|
signCount := len(signRecordMap)
|
|
for _, item := range signConfig {
|
|
if item.FinishCondition == int64(signCount) {
|
|
extraPrizeIds, e := prizemod.GetPrizeListByIDs(item.ExtraPrizes)
|
|
if e != nil {
|
|
continue
|
|
}
|
|
prizes = append(prizes, extraPrizeIds...)
|
|
}
|
|
}
|
|
// 更新签到记录(事务)
|
|
if err = appg.VideoDB.Trans(func(t *db.MongoTool) error {
|
|
if err = taskrecordmod.TaskSignUpdate(t, uid, id); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}); err != nil {
|
|
return stderr.ErrDbTransError
|
|
}
|
|
// 发放奖励
|
|
for _, v := range prizes {
|
|
for i := 0; i < int(v.Count); i++ {
|
|
handler, err := prizemod.Run(uid, *v, txnmod.SignBoon)
|
|
if err != nil {
|
|
log.Error("签到发放奖励handler失败:", log.Any("err", err))
|
|
continue
|
|
}
|
|
err = appg.VideoDB.Trans(func(t *db.MongoTool) error {
|
|
err = handler.Run(t)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = txnmod.InsertManyTransactionLog(t, handler.GetTransactionLog())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
log.Error("签到发放奖励事务失败:", log.Any("err", err))
|
|
continue
|
|
}
|
|
}
|
|
}
|
|
return stderr.Success
|
|
}
|
|
|
|
// 获取签到额外奖励
|
|
func SignExtraPrizes(uid uint64) (out []map[string]interface{}, code stderr.Code) {
|
|
out = make([]map[string]interface{}, 0)
|
|
taskInfo, err := taskrecordmod.GetSignRecord(uid)
|
|
if err != nil {
|
|
return out, stderr.ErrDbQueryError
|
|
}
|
|
signRecords := make([]primitive.ObjectID, 0)
|
|
if taskInfo != nil {
|
|
signRecords = taskInfo.SignRecord
|
|
}
|
|
signConfig, err := signtaskmod.GetConfigList()
|
|
if err != nil {
|
|
return out, stderr.ErrDbQueryError
|
|
}
|
|
// 获取奖品列表
|
|
prizes, err := prizemod.GetPrizeList()
|
|
for _, item := range signConfig {
|
|
if len(item.ExtraPrizes) == 0 {
|
|
continue
|
|
}
|
|
extraPrizes := getPrizeList(item.ExtraPrizes, prizes)
|
|
for _, prize := range extraPrizes {
|
|
b, _ := json.Marshal(&prize)
|
|
var extraPrizeMap map[string]interface{}
|
|
_ = json.Unmarshal(b, &extraPrizeMap)
|
|
days := item.FinishCondition - int64(len(signRecords))
|
|
if days < 0 {
|
|
days = 0
|
|
}
|
|
extraPrizeMap["finishCondition"] = days
|
|
// 设置额外奖励领取状态
|
|
if len(signRecords) >= int(item.FinishCondition) {
|
|
extraPrizeMap["extraPrizeStatus"] = true
|
|
} else {
|
|
extraPrizeMap["extraPrizeStatus"] = false
|
|
}
|
|
out = append(out, extraPrizeMap)
|
|
}
|
|
}
|
|
sort.Slice(out, func(i, j int) bool {
|
|
valI := out[i]["extraPrizeStatus"].(bool)
|
|
valJ := out[j]["extraPrizeStatus"].(bool)
|
|
return !valI && valJ
|
|
})
|
|
return out, stderr.Success
|
|
}
|
|
|
|
// 获取签到详情
|
|
func GetSignDetails(uid uint64) (out SignDetailsResponse, code stderr.Code) {
|
|
now := time.Now()
|
|
// 获取配置列表
|
|
signConfig, err := signtaskmod.GetConfigList()
|
|
if err != nil {
|
|
return out, stderr.ErrDbQueryError
|
|
}
|
|
// 查询用户签到信息
|
|
signRecordMap := make(map[string]bool, 0)
|
|
taskInfo, err := taskrecordmod.GetSignRecord(uid)
|
|
if err != nil {
|
|
return out, stderr.ErrDbQueryError
|
|
}
|
|
// 新增用户任务记录
|
|
if taskInfo == nil {
|
|
taskInfo, err = taskrecordmod.TaskSignInit(uid)
|
|
if err != nil {
|
|
return out, stderr.ErrDbQueryError
|
|
}
|
|
}
|
|
// 计算相差多少天
|
|
diffDays := int(timeutil.BeginningOfDay(now).Sub(taskInfo.SignTime).Hours() / 24)
|
|
// 判断是否重置数据
|
|
if diffDays >= len(signConfig) {
|
|
taskInfo, err = taskrecordmod.TaskSignReset(uid)
|
|
if err != nil {
|
|
return out, stderr.ErrDbQueryError
|
|
}
|
|
}
|
|
// 构建签到记录map
|
|
for _, item := range taskInfo.SignRecord {
|
|
signRecordMap[item.String()] = true
|
|
}
|
|
// 获取奖品列表
|
|
prizes, err := prizemod.GetPrizeList()
|
|
if err != nil {
|
|
return out, stderr.ErrDbQueryError
|
|
}
|
|
out.Value = int64(len(taskInfo.SignRecord))
|
|
out.List = make([]Config, len(signConfig))
|
|
for i, v := range signConfig {
|
|
taskConfig := Config{
|
|
ID: v.ID,
|
|
Prizes: getPrizeList(v.Prizes, prizes),
|
|
FinishCondition: v.FinishCondition,
|
|
Title: v.Title,
|
|
Desc: v.Desc,
|
|
Status: UnDone,
|
|
}
|
|
// 存在表示已经签到,不存在则需要判断是否是补签
|
|
if _, ok := signRecordMap[v.ID.String()]; ok {
|
|
// 如果存在,标记为已完成
|
|
taskConfig.Status = Finish
|
|
} else {
|
|
diffDays = int(timeutil.BeginningOfDay(now).Sub(taskInfo.SignTime).Hours() / 24)
|
|
if i < diffDays {
|
|
taskConfig.Status = ReDo
|
|
}
|
|
}
|
|
out.List[i] = taskConfig
|
|
}
|
|
// 当日任务标识
|
|
if diffDays >= 0 && diffDays < len(out.List) {
|
|
out.List[diffDays].IsToday = true
|
|
}
|
|
return out, stderr.Success
|
|
}
|