Files
novatask/internal/logic/task/verify_task_result_logic.go
2025-05-06 20:36:39 +08:00

164 lines
5.2 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"
"encoding/json"
"errors"
"github.com/spf13/cast"
"github.com/zeromicro/go-zero/core/logx"
"nova_task/internal/consts"
"nova_task/internal/model"
"nova_task/internal/pkg/aptos"
"nova_task/internal/pkg/errs"
"nova_task/internal/pkg/tribally"
"nova_task/internal/svc"
"nova_task/internal/types"
"time"
)
// VerifyTaskResultLogic 校验任务结果逻辑
type VerifyTaskResultLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewVerifyTaskResultLogic(ctx context.Context, svcCtx *svc.ServiceContext) *VerifyTaskResultLogic {
return &VerifyTaskResultLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *VerifyTaskResultLogic) VerifyTaskResult(req *types.VerifyTaskResultReq) (*types.VerifyTaskResultResp, error) {
uid := cast.ToStringMapInt(l.ctx.Value("data"))["id"]
task, err := l.svcCtx.TaskModel.FindOne(l.ctx, req.ID)
if err != nil {
if errors.Is(err, model.ErrNotFound) {
return nil, errs.New(errs.ErrTaskNotFound, "task not found")
}
return nil, errs.New(errs.ErrDatabaseOperate, err)
}
var taskSeq int
if task.Type == model.TASKTYPE_DAILY_PAY || task.Type == model.TASKTYPE_AMBASSADOR_TASK {
taskSeq = cast.ToInt(time.Now().Format("20060102"))
}
tp, err := l.svcCtx.TaskProgressModel.FindOneByUidTaskIdTaskSeq(l.ctx, uid, task.Id, taskSeq)
if err != nil {
if !errors.Is(err, model.ErrNotFound) {
l.Errorw("find task progress error", logx.Field("err", err))
return nil, errs.New(errs.ErrDatabaseOperate, err)
}
tp = &model.NhTaskProgress{
Uid: uid,
TaskId: task.Id,
TaskSeq: taskSeq,
Stage: model.TASK_PROGRESS_NOT_FINISHED,
}
}
if tp.Stage == model.TASK_PROGRESS_REWARDED {
return nil, errs.New(errs.ErrTaskAlreadyReward, "task already reward")
}
// todo: 校验用户是否完成该任务
switch task.Type {
case model.TASKTYPE_BIND_TWITTER:
if !l.svcCtx.HasBindTwitter(l.ctx, uint(uid)) {
return &types.VerifyTaskResultResp{Finish: false}, nil
}
case model.TASKTYPE_INVITE_USER:
count, err := l.svcCtx.PromoteBindModel.UserInviteCount(l.ctx, uint(uid))
if err != nil {
l.Errorw("get user invite count failed", logx.Field("err", err), logx.Field("uid", uid))
return nil, errs.New(errs.ErrDatabaseOperate, err)
}
if count < cast.ToInt64(task.Param) {
return &types.VerifyTaskResultResp{Finish: false}, nil
}
case model.TASKTYPE_BIND_DISCORD:
case model.TASKTYPE_DAILY_PAY, model.TASKTYPE_TRUMP_HEAD:
if req.Params == "" {
return &types.VerifyTaskResultResp{Finish: false}, nil
} else {
if !l.checkoutTranscation(uid, req.Params) {
return &types.VerifyTaskResultResp{Finish: false}, nil
}
}
case model.TASKTYPE_AMBASSADOR_TASK:
if !l.svcCtx.IsAmbassador(l.ctx, uint(uid), 0) {
return &types.VerifyTaskResultResp{Finish: false}, nil
}
case model.TASKTYPE_BIND_TRIBALLY:
if req.Params == "" {
return &types.VerifyTaskResultResp{Finish: false}, nil
}
if err := tribally.VerifyTribally(req.Params); err != nil {
l.Errorw("verify tribally error", logx.Field("err", err), logx.Field("params", req.Params), logx.Field("uid", uid))
return &types.VerifyTaskResultResp{Finish: false}, nil
}
_, err = l.svcCtx.TriballyUserModel.FindOneByUid(l.ctx, uint(uid))
if err != nil {
if errors.Is(err, model.ErrNotFound) {
// TriballyUser表中不存在此用户插入
_, err = l.svcCtx.TriballyUserModel.Insert(l.ctx, &model.NhTriballyUser{
Uid: uint(uid),
Chapter: -1,
})
if err != nil {
l.Errorw("insert tribally user error", logx.Field("err", err), logx.Field("uid", uid))
return nil, errs.New(errs.ErrDatabaseOperate, err)
}
} else {
l.Errorw("find tribally user error", logx.Field("err", err), logx.Field("uid", uid))
return nil, errs.New(errs.ErrDatabaseOperate, err)
}
}
default:
}
tp.Stage = model.TASK_PROGRESS_WAIT_REWARD
if tp.Id > 0 {
err = l.svcCtx.TaskProgressModel.Update(l.ctx, tp)
} else {
_, err = l.svcCtx.TaskProgressModel.Insert(l.ctx, tp)
}
if err != nil {
l.Errorw("update task progress error", logx.Field("err", err))
return nil, errs.New(errs.ErrDatabaseOperate, err)
}
return &types.VerifyTaskResultResp{Finish: true}, nil
}
func (l *VerifyTaskResultLogic) checkoutTranscation(uid int, txHash string) bool {
conf := struct {
Contract string `json:"contract"`
Network string `json:"network"`
}{}
cf, err := l.svcCtx.ConfigModel.FindOneByName(l.ctx, consts.DailyPayConf)
if err != nil {
if !errors.Is(err, model.ErrNotFound) {
l.Errorw("find daily pay conf error", logx.Field("err", err))
}
return false
}
err = json.Unmarshal([]byte(cf.Value), &conf)
if err != nil {
l.Errorw("unmarshal daily pay conf error", logx.Field("err", err), logx.Field("value", cf.Value))
return false
}
address, err := aptos.GetTransactionOwnerAddress(conf.Contract, txHash, conf.Network)
if err != nil {
l.Errorw("get transaction owner address error", logx.Field("err", err))
return false
}
targetUid, err := l.svcCtx.WalletModel.FindUidByAddress(l.ctx, address)
if err != nil {
l.Errorw("find wallet by address error", logx.Field("err", err), logx.Field("address", address), logx.Field("target_uid", targetUid))
return false
}
return targetUid == uint(uid)
}