@@ -0,0 +1,433 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user