增加社区列表接口,任务相关接口修改

This commit is contained in:
lianghuanjie
2024-12-19 21:14:14 +08:00
parent 391a9d3481
commit a3c4adfa25
32 changed files with 1163 additions and 197 deletions

View File

@@ -15,6 +15,12 @@ import (
func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
server.AddRoutes(
[]rest.Route{
{
// 获取社区列表
Method: http.MethodGet,
Path: "/community",
Handler: task.GetCommunityListHandler(serverCtx),
},
{
// 获取任务列表
Method: http.MethodGet,
@@ -36,7 +42,7 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
{
// 校验任务结果
Method: http.MethodGet,
Path: "/task/:id",
Path: "/task",
Handler: task.VerifyTaskResultHandler(serverCtx),
},
},

View File

@@ -0,0 +1,22 @@
package task
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"nova_task/internal/logic/task"
"nova_task/internal/svc"
)
// 获取社区列表
func GetCommunityListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
l := task.NewGetCommunityListLogic(r.Context(), svcCtx)
resp, err := l.GetCommunityList()
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}

View File

@@ -12,7 +12,7 @@ import (
// 校验任务结果
func VerifyTaskResultHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.TaskIdPath
var req types.VerifyTaskResultReq
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return

61
internal/job/earn/earn.go Normal file
View File

@@ -0,0 +1,61 @@
package earn
import (
"context"
ea "github.com/earn-alliance/earnalliance-go"
"github.com/spf13/cast"
"github.com/zeromicro/go-zero/core/logx"
"nova_task/internal/svc"
)
// Earn 用户数据上报earn平台定时任务
type Earn struct {
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewEarn(ctx context.Context, svcCtx *svc.ServiceContext) *Earn {
e := &Earn{ctx: ctx, svcCtx: svcCtx}
e.Run()
return e
}
func (e *Earn) Spec() string {
return "@every 5m"
}
func (e *Earn) Run() {
e.pushUserInfo(666)
e.pushUserBind()
}
func (e *Earn) pushUserInfo(shareId uint) {
us, err := e.svcCtx.PromoteBindModel.FindRequirePushUser(e.ctx, shareId)
if err != nil {
logx.Errorw("find require push user failed", logx.Field("err", err), logx.Field("share_id", shareId))
return
}
for _, u := range us {
ui, err := e.svcCtx.UserModel.FindOne(e.ctx, u.InvitedUid)
if err != nil {
logx.Errorw("find user failed", logx.Field("err", err), logx.Field("uid", u.InvitedUid))
continue
}
var twitterId string
ut, err := e.svcCtx.TwitterModel.FindOne(e.ctx, u.InvitedUid)
if err == nil {
twitterId = ut.TwitterId
}
e.svcCtx.Earn.SetIdentifiers(cast.ToString(ui.Id), &ea.Identifiers{
Email: ea.IdentifierFrom(ui.Email),
TwitterId: ea.IdentifierFrom(twitterId),
})
err = e.svcCtx.PromoteBindModel.UpdatePushUser(e.ctx, u.Id)
if err != nil {
logx.Errorw("update push user failed", logx.Field("err", err), logx.Field("uid", u.InvitedUid))
}
}
}
func (e *Earn) pushUserBind() {}

63
internal/job/job.go Normal file
View File

@@ -0,0 +1,63 @@
package job
import (
"context"
"errors"
"github.com/robfig/cron/v3"
"github.com/zeromicro/go-zero/core/logx"
"nova_task/internal/job/earn"
"nova_task/internal/job/pledge"
"nova_task/internal/svc"
)
type Job struct {
ctx context.Context
cancel context.CancelFunc
svcCtx *svc.ServiceContext
c *cron.Cron
}
type Spec interface {
Spec() string
}
func NewJob(svcCtx *svc.ServiceContext) *Job {
ctx, cancel := context.WithCancel(context.Background())
var cronList = []cron.Job{
earn.NewEarn(ctx, svcCtx),
pledge.NewPledge(ctx, svcCtx),
}
var err error
c := cron.New()
for _, cr := range cronList {
if cs, ok := cr.(Spec); ok {
_, err = c.AddJob(cs.Spec(), cr)
logx.Must(err)
continue
}
if cs, ok := cr.(cron.Schedule); ok {
c.Schedule(cs, cr)
continue
}
logx.Must(errors.New("cron job must implement either Spec or Schedule interface"))
}
return &Job{
ctx: ctx,
cancel: cancel,
svcCtx: svcCtx,
c: c,
}
}
func (j *Job) Start() {
logx.Info("start cron job")
j.c.Start()
}
func (j *Job) Stop() {
logx.Info("stop cron job")
<-j.c.Stop().Done()
logx.Info("cron job stopped")
j.cancel()
}

View File

@@ -0,0 +1,26 @@
package pledge
import (
"context"
"nova_task/internal/svc"
)
type Pledge struct {
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewPledge(ctx context.Context, svcCtx *svc.ServiceContext) *Pledge {
return &Pledge{
ctx: ctx,
svcCtx: svcCtx,
}
}
func (p *Pledge) Spec() string {
return "@every 30m"
}
func (p *Pledge) Run() {
}

View File

@@ -0,0 +1,48 @@
package task
import (
"context"
"nova_task/internal/pkg/errs"
"nova_task/internal/svc"
"nova_task/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type GetCommunityListLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
// 获取社区列表
func NewGetCommunityListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetCommunityListLogic {
return &GetCommunityListLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *GetCommunityListLogic) GetCommunityList() (*types.GetCommunityListResp, error) {
cs, err := l.svcCtx.CommunityModel.All(l.ctx)
if err != nil {
l.Errorw("get community list error", logx.Field("err", err))
return nil, errs.New(errs.ErrDatabaseOperate, err)
}
var communityList []types.Community
for _, c := range cs {
communityList = append(communityList, types.Community{
Id: c.Id,
Title: c.Title,
Logo: c.Logo,
Description: c.Description,
StartAt: c.StartAt.Time.Unix(),
EndAt: c.EndAt.Time.Unix(),
})
}
return &types.GetCommunityListResp{CommunityList: communityList}, nil
}

View File

@@ -33,7 +33,12 @@ func (l *GetTaskListLogic) GetTaskList(uid int, req *types.GetTaskListReq) (*typ
tasks, err := l.svcCtx.TaskModel.FindTasksByCommunity(l.ctx, req.CommunityId)
if err != nil {
l.Errorw("get task list failed", logx.Field("err", err), logx.Field("communityId", req.CommunityId))
return nil, errs.InternalServer(errs.ErrDatabaseOperate, err)
return nil, errs.New(errs.ErrDatabaseOperate, err)
}
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))
}
resp := &types.GetTaskListResp{}
@@ -44,25 +49,46 @@ func (l *GetTaskListLogic) GetTaskList(uid int, req *types.GetTaskListReq) (*typ
}
var finishState int8
if uid > 0 {
tp, err := l.svcCtx.TaskProgressModel.FindOneByUidTaskIdTaskSeq(l.ctx, uid, t.CommunityId, taskSeq)
tp, err := l.svcCtx.TaskProgressModel.FindOneByUidTaskIdTaskSeq(l.ctx, uid, t.Id, taskSeq)
if err == nil {
finishState = tp.Stage
}
}
hasFinishCount := 0
totalCount := 1
if t.Type == model.TASKTYPE_INVITE_USER {
totalCount = cast.ToInt(t.Param)
hasFinishCount = cast.ToInt(count)
}
if finishState >= model.TASK_PROGRESS_WAIT_REWARD {
hasFinishCount = totalCount
}
if hasFinishCount > totalCount {
hasFinishCount = totalCount
}
if hasFinishCount >= totalCount && finishState == model.TASK_PROGRESS_NOT_FINISHED {
finishState = model.TASK_PROGRESS_WAIT_VERIFY
}
resp.Tasks = append(resp.Tasks, types.Task{
Id: t.Id,
Title: t.Title,
SubTitle: t.SubTitle,
Description: t.Description,
Points: t.Points,
ButtonText: t.ButtonText,
Type: t.Type,
Url: t.Url,
StartAt: t.StartAt.Time.Format(time.DateTime),
EndAt: t.EndAt.Time.Format(time.DateTime),
Status: t.Status,
FinishState: finishState,
Id: t.Id,
Title: t.Title,
SubTitle: t.SubTitle,
Description: t.Description,
Points: t.Points,
ButtonText: t.ButtonText,
Params: t.Param,
Type: t.Type,
Url: t.Url,
StartAt: t.StartAt.Time.Format(time.DateTime),
EndAt: t.EndAt.Time.Format(time.DateTime),
Sort: t.Sort,
HasFinishCount: hasFinishCount,
TotalCount: totalCount,
FinishState: finishState,
})
}

View File

@@ -35,9 +35,9 @@ func (l *GetTaskRewardLogic) GetTaskReward(req *types.TaskIdPath) (*types.GetTas
task, err := l.svcCtx.TaskModel.FindOne(l.ctx, req.ID)
if err != nil {
if errors.Is(err, model.ErrNotFound) {
return nil, errs.BadRequest(errs.ErrTaskNotFound, "task not found")
return nil, errs.New(errs.ErrTaskNotFound, "task not found")
}
return nil, errs.InternalServer(errs.ErrDatabaseOperate, err)
return nil, errs.New(errs.ErrDatabaseOperate, err)
}
var taskSeq int
if task.Type == model.TASKTYPE_DAILY_PAY {
@@ -47,15 +47,15 @@ func (l *GetTaskRewardLogic) GetTaskReward(req *types.TaskIdPath) (*types.GetTas
if err != nil {
if !errors.Is(err, model.ErrNotFound) {
l.Errorw("find task progress error", logx.Field("err", err))
return nil, errs.InternalServer(errs.ErrDatabaseOperate, err)
return nil, errs.New(errs.ErrDatabaseOperate, err)
}
return nil, errs.BadRequest(errs.ErrTaskNotFinished, "task not finished")
return nil, errs.New(errs.ErrTaskNotFinished, "task not finished")
}
switch {
case tp.Stage < model.TASK_PROGRESS_WAIT_REWARD:
return nil, errs.BadRequest(errs.ErrTaskNotFinished, "task not finished")
return nil, errs.New(errs.ErrTaskNotFinished, "task not finished")
case tp.Stage > model.TASK_PROGRESS_WAIT_REWARD:
return nil, errs.BadRequest(errs.ErrTaskAlreadyReward, "task already reward")
return nil, errs.New(errs.ErrTaskAlreadyReward, "task already reward")
}
// 修改状态,增加积分和记录都在事物中执行
@@ -85,7 +85,7 @@ func (l *GetTaskRewardLogic) GetTaskReward(req *types.TaskIdPath) (*types.GetTas
if err != nil {
l.Errorw("给予用户奖励实物执行失败", logx.Field("err", err), logx.Field("task", task.Id), logx.Field("uid", uid))
return nil, errs.InternalServer(errs.ErrDatabaseOperate, err)
return nil, errs.New(errs.ErrDatabaseOperate, err)
}
return &types.GetTaskRewardResp{Points: task.Points}, nil

View File

@@ -27,14 +27,14 @@ func NewVerifyTaskResultLogic(ctx context.Context, svcCtx *svc.ServiceContext) *
}
}
func (l *VerifyTaskResultLogic) VerifyTaskResult(req *types.TaskIdPath) (*types.VerifyTaskResultResp, error) {
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.BadRequest(errs.ErrTaskNotFound, "task not found")
return nil, errs.New(errs.ErrTaskNotFound, "task not found")
}
return nil, errs.InternalServer(errs.ErrDatabaseOperate, err)
return nil, errs.New(errs.ErrDatabaseOperate, err)
}
var taskSeq int
if task.Type == model.TASKTYPE_DAILY_PAY {
@@ -44,7 +44,7 @@ func (l *VerifyTaskResultLogic) VerifyTaskResult(req *types.TaskIdPath) (*types.
if err != nil {
if !errors.Is(err, model.ErrNotFound) {
l.Errorw("find task progress error", logx.Field("err", err))
return nil, errs.InternalServer(errs.ErrDatabaseOperate, err)
return nil, errs.New(errs.ErrDatabaseOperate, err)
}
tp = &model.NhTaskProgress{
Uid: uid,
@@ -54,7 +54,7 @@ func (l *VerifyTaskResultLogic) VerifyTaskResult(req *types.TaskIdPath) (*types.
}
}
if tp.Stage == model.TASK_PROGRESS_REWARDED {
return nil, errs.BadRequest(errs.ErrTaskAlreadyReward, "task already reward")
return nil, errs.New(errs.ErrTaskAlreadyReward, "task already reward")
}
// todo: 校验用户是否完成该任务
switch task.Type {
@@ -62,7 +62,7 @@ func (l *VerifyTaskResultLogic) VerifyTaskResult(req *types.TaskIdPath) (*types.
tw, err := l.svcCtx.TwitterModel.FindOneByUid(l.ctx, uint(uid))
if err != nil {
if !errors.Is(err, model.ErrNotFound) {
return nil, errs.InternalServer(errs.ErrDatabaseOperate, err)
return nil, errs.New(errs.ErrDatabaseOperate, err)
}
return &types.VerifyTaskResultResp{Finish: false}, nil
}
@@ -72,6 +72,9 @@ func (l *VerifyTaskResultLogic) VerifyTaskResult(req *types.TaskIdPath) (*types.
case model.TASKTYPE_BIND_DISCORD:
case model.TASKTYPE_DAILY_PAY:
if req.Params == "" {
return &types.VerifyTaskResultResp{Finish: false}, nil
}
default:
}
@@ -84,7 +87,7 @@ func (l *VerifyTaskResultLogic) VerifyTaskResult(req *types.TaskIdPath) (*types.
if err != nil {
l.Errorw("update task progress error", logx.Field("err", err))
return nil, errs.InternalServer(errs.ErrDatabaseOperate, err)
return nil, errs.New(errs.ErrDatabaseOperate, err)
}
return &types.VerifyTaskResultResp{Finish: true}, nil

View File

@@ -0,0 +1,81 @@
package model
import (
"context"
"errors"
"fmt"
"github.com/patrickmn/go-cache"
"github.com/spf13/cast"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"time"
)
var _ NhPromoteBindModel = (*customNhPromoteBindModel)(nil)
type (
// NhPromoteBindModel is an interface to be customized, add more methods here,
// and implement the added methods in customNhPromoteBindModel.
NhPromoteBindModel interface {
nhPromoteBindModel
withSession(session sqlx.Session) NhPromoteBindModel
FindRequirePushUser(ctx context.Context, shareUid uint) ([]NhPromoteBind, error)
UpdatePushUser(ctx context.Context, id uint) error
UpdatePushRole(ctx context.Context, id uint) error
UserInviteCount(ctx context.Context, uid uint) (int64, error)
}
customNhPromoteBindModel struct {
*defaultNhPromoteBindModel
userInviteCountCache *cache.Cache
}
)
// NewNhPromoteBindModel returns a model for the database table.
func NewNhPromoteBindModel(conn sqlx.SqlConn) NhPromoteBindModel {
return &customNhPromoteBindModel{
defaultNhPromoteBindModel: newNhPromoteBindModel(conn),
userInviteCountCache: cache.New(time.Minute, time.Second*65),
}
}
func (m *customNhPromoteBindModel) withSession(session sqlx.Session) NhPromoteBindModel {
return NewNhPromoteBindModel(sqlx.NewSqlConnFromSession(session))
}
func (m *customNhPromoteBindModel) FindRequirePushUser(ctx context.Context, shareUid uint) ([]NhPromoteBind, error) {
query := fmt.Sprintf("select %s from %s where `share_uid` = ? and `is_push_user` = 0 limit 100", nhPromoteBindRows, m.table)
var resp []NhPromoteBind
err := m.conn.QueryRowsCtx(ctx, &resp, query, shareUid)
if err != nil && !errors.Is(err, sqlx.ErrNotFound) {
return nil, err
}
return resp, nil
}
func (m *customNhPromoteBindModel) UpdatePushUser(ctx context.Context, id uint) error {
update := fmt.Sprintf("update %s set `is_push_user` = 1 where `id` = ?", m.table)
_, err := m.conn.ExecCtx(ctx, update, id)
return err
}
func (m *customNhPromoteBindModel) UpdatePushRole(ctx context.Context, id uint) error {
update := fmt.Sprintf("update %s set `is_push_role` = 1 where `id` = ?", m.table)
_, err := m.conn.ExecCtx(ctx, update, id)
return err
}
func (m *customNhPromoteBindModel) UserInviteCount(ctx context.Context, uid uint) (int64, error) {
key := cast.ToString(uid)
v, ok := m.userInviteCountCache.Get(key)
if ok {
return v.(int64), nil
}
query := fmt.Sprintf("select count(*) as `count` from %s where `share_uid` = ?", m.table)
var count int64
err := m.conn.QueryRowCtx(ctx, &count, query, uid)
if err != nil && !errors.Is(err, sqlx.ErrNotFound) {
return 0, err
}
m.userInviteCountCache.SetDefault(key, count)
return count, nil
}

View File

@@ -0,0 +1,104 @@
// Code generated by goctl. DO NOT EDIT.
// versions:
// goctl version: 1.7.3
package model
import (
"context"
"database/sql"
"fmt"
"strings"
"github.com/zeromicro/go-zero/core/stores/builder"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/zeromicro/go-zero/core/stringx"
)
var (
nhPromoteBindFieldNames = builder.RawFieldNames(&NhPromoteBind{})
nhPromoteBindRows = strings.Join(nhPromoteBindFieldNames, ",")
nhPromoteBindRowsExpectAutoSet = strings.Join(stringx.Remove(nhPromoteBindFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",")
nhPromoteBindRowsWithPlaceHolder = strings.Join(stringx.Remove(nhPromoteBindFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?"
)
type (
nhPromoteBindModel interface {
Insert(ctx context.Context, data *NhPromoteBind) (sql.Result, error)
FindOne(ctx context.Context, id uint) (*NhPromoteBind, error)
FindOneByInvitedUid(ctx context.Context, invitedUid uint) (*NhPromoteBind, error)
Update(ctx context.Context, data *NhPromoteBind) error
Delete(ctx context.Context, id uint) error
}
defaultNhPromoteBindModel struct {
conn sqlx.SqlConn
table string
}
NhPromoteBind struct {
Id uint `db:"id"`
ShareUid uint `db:"share_uid"` // 分享者uid
InvitedUid uint `db:"invited_uid"` // 受邀者uid
CreateTime uint `db:"create_time"` // 创建时间
IsPushUser int8 `db:"is_push_user"` // 是否已推送用户信息
IsPushRole int8 `db:"is_push_role"` // 是否已推送绑定游戏账号
}
)
func newNhPromoteBindModel(conn sqlx.SqlConn) *defaultNhPromoteBindModel {
return &defaultNhPromoteBindModel{
conn: conn,
table: "`nh_promote_bind`",
}
}
func (m *defaultNhPromoteBindModel) Delete(ctx context.Context, id uint) error {
query := fmt.Sprintf("delete from %s where `id` = ?", m.table)
_, err := m.conn.ExecCtx(ctx, query, id)
return err
}
func (m *defaultNhPromoteBindModel) FindOne(ctx context.Context, id uint) (*NhPromoteBind, error) {
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", nhPromoteBindRows, m.table)
var resp NhPromoteBind
err := m.conn.QueryRowCtx(ctx, &resp, query, id)
switch err {
case nil:
return &resp, nil
case sqlx.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *defaultNhPromoteBindModel) FindOneByInvitedUid(ctx context.Context, invitedUid uint) (*NhPromoteBind, error) {
var resp NhPromoteBind
query := fmt.Sprintf("select %s from %s where `invited_uid` = ? limit 1", nhPromoteBindRows, m.table)
err := m.conn.QueryRowCtx(ctx, &resp, query, invitedUid)
switch err {
case nil:
return &resp, nil
case sqlx.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *defaultNhPromoteBindModel) Insert(ctx context.Context, data *NhPromoteBind) (sql.Result, error) {
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?)", m.table, nhPromoteBindRowsExpectAutoSet)
ret, err := m.conn.ExecCtx(ctx, query, data.ShareUid, data.InvitedUid, data.IsPushUser, data.IsPushRole)
return ret, err
}
func (m *defaultNhPromoteBindModel) Update(ctx context.Context, newData *NhPromoteBind) error {
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, nhPromoteBindRowsWithPlaceHolder)
_, err := m.conn.ExecCtx(ctx, query, newData.ShareUid, newData.InvitedUid, newData.IsPushUser, newData.IsPushRole, newData.Id)
return err
}
func (m *defaultNhPromoteBindModel) tableName() string {
return m.table
}

View File

@@ -0,0 +1,45 @@
package model
import (
"context"
"errors"
"fmt"
"github.com/zeromicro/go-zero/core/stores/sqlx"
)
var _ NhTaskCommunityModel = (*customNhTaskCommunityModel)(nil)
type (
// NhTaskCommunityModel is an interface to be customized, add more methods here,
// and implement the added methods in customNhTaskCommunityModel.
NhTaskCommunityModel interface {
nhTaskCommunityModel
withSession(session sqlx.Session) NhTaskCommunityModel
All(ctx context.Context) ([]NhTaskCommunity, error)
}
customNhTaskCommunityModel struct {
*defaultNhTaskCommunityModel
}
)
func (m *customNhTaskCommunityModel) All(ctx context.Context) ([]NhTaskCommunity, error) {
query := fmt.Sprintf("select %s from %s where `status` = 1", nhTaskCommunityRows, m.table)
var resp []NhTaskCommunity
err := m.conn.QueryRowsCtx(ctx, &resp, query)
if err != nil && !errors.Is(err, sqlx.ErrNotFound) {
return nil, err
}
return resp, nil
}
// NewNhTaskCommunityModel returns a model for the database table.
func NewNhTaskCommunityModel(conn sqlx.SqlConn) NhTaskCommunityModel {
return &customNhTaskCommunityModel{
defaultNhTaskCommunityModel: newNhTaskCommunityModel(conn),
}
}
func (m *customNhTaskCommunityModel) withSession(session sqlx.Session) NhTaskCommunityModel {
return NewNhTaskCommunityModel(sqlx.NewSqlConnFromSession(session))
}

View File

@@ -0,0 +1,94 @@
// Code generated by goctl. DO NOT EDIT.
// versions:
// goctl version: 1.7.3
package model
import (
"context"
"database/sql"
"fmt"
"strings"
"time"
"github.com/zeromicro/go-zero/core/stores/builder"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/zeromicro/go-zero/core/stringx"
)
var (
nhTaskCommunityFieldNames = builder.RawFieldNames(&NhTaskCommunity{})
nhTaskCommunityRows = strings.Join(nhTaskCommunityFieldNames, ",")
nhTaskCommunityRowsExpectAutoSet = strings.Join(stringx.Remove(nhTaskCommunityFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",")
nhTaskCommunityRowsWithPlaceHolder = strings.Join(stringx.Remove(nhTaskCommunityFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?"
)
type (
nhTaskCommunityModel interface {
Insert(ctx context.Context, data *NhTaskCommunity) (sql.Result, error)
FindOne(ctx context.Context, id uint) (*NhTaskCommunity, error)
Update(ctx context.Context, data *NhTaskCommunity) error
Delete(ctx context.Context, id uint) error
}
defaultNhTaskCommunityModel struct {
conn sqlx.SqlConn
table string
}
NhTaskCommunity struct {
Id uint `db:"id"`
Title string `db:"title"` // 社区
Logo string `db:"logo"` // logo图片链接
Description string `db:"description"` // 描述
Status int8 `db:"status"` // 0=不启用1=启用
StartAt sql.NullTime `db:"start_at"` // 开始时间
EndAt sql.NullTime `db:"end_at"` // 结束时间
CreatedAt time.Time `db:"created_at"` // 创建时间
UpdatedAt time.Time `db:"updated_at"` // 修改时间
Sort int `db:"sort"` // 数字越小越靠前
}
)
func newNhTaskCommunityModel(conn sqlx.SqlConn) *defaultNhTaskCommunityModel {
return &defaultNhTaskCommunityModel{
conn: conn,
table: "`nh_task_community`",
}
}
func (m *defaultNhTaskCommunityModel) Delete(ctx context.Context, id uint) error {
query := fmt.Sprintf("delete from %s where `id` = ?", m.table)
_, err := m.conn.ExecCtx(ctx, query, id)
return err
}
func (m *defaultNhTaskCommunityModel) FindOne(ctx context.Context, id uint) (*NhTaskCommunity, error) {
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", nhTaskCommunityRows, m.table)
var resp NhTaskCommunity
err := m.conn.QueryRowCtx(ctx, &resp, query, id)
switch err {
case nil:
return &resp, nil
case sqlx.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *defaultNhTaskCommunityModel) Insert(ctx context.Context, data *NhTaskCommunity) (sql.Result, error) {
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?)", m.table, nhTaskCommunityRowsExpectAutoSet)
ret, err := m.conn.ExecCtx(ctx, query, data.Title, data.Logo, data.Description, data.Status, data.StartAt, data.EndAt, data.Sort)
return ret, err
}
func (m *defaultNhTaskCommunityModel) Update(ctx context.Context, data *NhTaskCommunity) error {
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, nhTaskCommunityRowsWithPlaceHolder)
_, err := m.conn.ExecCtx(ctx, query, data.Title, data.Logo, data.Description, data.Status, data.StartAt, data.EndAt, data.Sort, data.Id)
return err
}
func (m *defaultNhTaskCommunityModel) tableName() string {
return m.table
}

View File

@@ -21,6 +21,7 @@ const (
TASKTYPE_BIND_DISCORD = 7
TASKTYPE_JOIN_TELEGRAM = 8
TASKTYPE_DAILY_PAY = 9
TASKTYPE_INVITE_USER = 10
)
type (
@@ -38,7 +39,7 @@ type (
)
func (m *customNhTaskModel) FindTasksByCommunity(ctx context.Context, communityId uint) ([]*NhTask, error) {
query := fmt.Sprintf("select %s from %s where community_id = 0 or community_id = ?", nhTaskRows, m.table)
query := fmt.Sprintf("select %s from %s where `status` = 1 and community_id = ? order by `sort`", nhTaskRows, m.table)
var tasks []*NhTask
err := m.conn.QueryRowsCtx(ctx, &tasks, query, communityId)
if err != nil && !errors.Is(err, sqlx.ErrNotFound) {

View File

@@ -51,6 +51,8 @@ type (
EndAt sql.NullTime `db:"end_at"` // 结束时间
CreatedAt time.Time `db:"created_at"` // 创建时间
UpdatedAt time.Time `db:"updated_at"` // 修改时间
Param string `db:"param"` // 备用参数,如果是邀请任务,可以填邀请的人数
Sort int `db:"sort"` // 数字越小越靠前
}
)
@@ -82,14 +84,14 @@ func (m *defaultNhTaskModel) FindOne(ctx context.Context, id uint) (*NhTask, err
}
func (m *defaultNhTaskModel) Insert(ctx context.Context, data *NhTask) (sql.Result, error) {
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table, nhTaskRowsExpectAutoSet)
ret, err := m.conn.ExecCtx(ctx, query, data.CommunityId, data.Title, data.SubTitle, data.Description, data.Points, data.ButtonText, data.Type, data.Url, data.Status, data.StartAt, data.EndAt)
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table, nhTaskRowsExpectAutoSet)
ret, err := m.conn.ExecCtx(ctx, query, data.CommunityId, data.Title, data.SubTitle, data.Description, data.Points, data.ButtonText, data.Type, data.Url, data.Status, data.StartAt, data.EndAt, data.Param, data.Sort)
return ret, err
}
func (m *defaultNhTaskModel) Update(ctx context.Context, data *NhTask) error {
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, nhTaskRowsWithPlaceHolder)
_, err := m.conn.ExecCtx(ctx, query, data.CommunityId, data.Title, data.SubTitle, data.Description, data.Points, data.ButtonText, data.Type, data.Url, data.Status, data.StartAt, data.EndAt, data.Id)
_, err := m.conn.ExecCtx(ctx, query, data.CommunityId, data.Title, data.SubTitle, data.Description, data.Points, data.ButtonText, data.Type, data.Url, data.Status, data.StartAt, data.EndAt, data.Param, data.Sort, data.Id)
return err
}

View File

@@ -0,0 +1,29 @@
package model
import "github.com/zeromicro/go-zero/core/stores/sqlx"
var _ NhTouristBindModel = (*customNhTouristBindModel)(nil)
type (
// NhTouristBindModel is an interface to be customized, add more methods here,
// and implement the added methods in customNhTouristBindModel.
NhTouristBindModel interface {
nhTouristBindModel
withSession(session sqlx.Session) NhTouristBindModel
}
customNhTouristBindModel struct {
*defaultNhTouristBindModel
}
)
// NewNhTouristBindModel returns a model for the database table.
func NewNhTouristBindModel(conn sqlx.SqlConn) NhTouristBindModel {
return &customNhTouristBindModel{
defaultNhTouristBindModel: newNhTouristBindModel(conn),
}
}
func (m *customNhTouristBindModel) withSession(session sqlx.Session) NhTouristBindModel {
return NewNhTouristBindModel(sqlx.NewSqlConnFromSession(session))
}

View File

@@ -0,0 +1,87 @@
// Code generated by goctl. DO NOT EDIT.
// versions:
// goctl version: 1.7.3
package model
import (
"context"
"database/sql"
"fmt"
"strings"
"github.com/zeromicro/go-zero/core/stores/builder"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/zeromicro/go-zero/core/stringx"
)
var (
nhTouristBindFieldNames = builder.RawFieldNames(&NhTouristBind{})
nhTouristBindRows = strings.Join(nhTouristBindFieldNames, ",")
nhTouristBindRowsExpectAutoSet = strings.Join(stringx.Remove(nhTouristBindFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",")
nhTouristBindRowsWithPlaceHolder = strings.Join(stringx.Remove(nhTouristBindFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?"
)
type (
nhTouristBindModel interface {
Insert(ctx context.Context, data *NhTouristBind) (sql.Result, error)
FindOne(ctx context.Context, id int) (*NhTouristBind, error)
Update(ctx context.Context, data *NhTouristBind) error
Delete(ctx context.Context, id int) error
}
defaultNhTouristBindModel struct {
conn sqlx.SqlConn
table string
}
NhTouristBind struct {
Id int `db:"id"`
TouristAccount string `db:"tourist_account"` // 游客账号
FormalAccount string `db:"formal_account"` // 正式账号
CreateTime int `db:"create_time"` // 创建时间
}
)
func newNhTouristBindModel(conn sqlx.SqlConn) *defaultNhTouristBindModel {
return &defaultNhTouristBindModel{
conn: conn,
table: "`nh_tourist_bind`",
}
}
func (m *defaultNhTouristBindModel) Delete(ctx context.Context, id int) error {
query := fmt.Sprintf("delete from %s where `id` = ?", m.table)
_, err := m.conn.ExecCtx(ctx, query, id)
return err
}
func (m *defaultNhTouristBindModel) FindOne(ctx context.Context, id int) (*NhTouristBind, error) {
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", nhTouristBindRows, m.table)
var resp NhTouristBind
err := m.conn.QueryRowCtx(ctx, &resp, query, id)
switch err {
case nil:
return &resp, nil
case sqlx.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *defaultNhTouristBindModel) Insert(ctx context.Context, data *NhTouristBind) (sql.Result, error) {
query := fmt.Sprintf("insert into %s (%s) values (?, ?)", m.table, nhTouristBindRowsExpectAutoSet)
ret, err := m.conn.ExecCtx(ctx, query, data.TouristAccount, data.FormalAccount)
return ret, err
}
func (m *defaultNhTouristBindModel) Update(ctx context.Context, data *NhTouristBind) error {
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, nhTouristBindRowsWithPlaceHolder)
_, err := m.conn.ExecCtx(ctx, query, data.TouristAccount, data.FormalAccount, data.Id)
return err
}
func (m *defaultNhTouristBindModel) tableName() string {
return m.table
}

29
internal/model/nh_user_model.go Executable file
View File

@@ -0,0 +1,29 @@
package model
import "github.com/zeromicro/go-zero/core/stores/sqlx"
var _ NhUserModel = (*customNhUserModel)(nil)
type (
// NhUserModel is an interface to be customized, add more methods here,
// and implement the added methods in customNhUserModel.
NhUserModel interface {
nhUserModel
withSession(session sqlx.Session) NhUserModel
}
customNhUserModel struct {
*defaultNhUserModel
}
)
// NewNhUserModel returns a model for the database table.
func NewNhUserModel(conn sqlx.SqlConn) NhUserModel {
return &customNhUserModel{
defaultNhUserModel: newNhUserModel(conn),
}
}
func (m *customNhUserModel) withSession(session sqlx.Session) NhUserModel {
return NewNhUserModel(sqlx.NewSqlConnFromSession(session))
}

View File

@@ -0,0 +1,108 @@
// Code generated by goctl. DO NOT EDIT.
// versions:
// goctl version: 1.7.3
package model
import (
"context"
"database/sql"
"fmt"
"strings"
"github.com/zeromicro/go-zero/core/stores/builder"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/zeromicro/go-zero/core/stringx"
)
var (
nhUserFieldNames = builder.RawFieldNames(&NhUser{})
nhUserRows = strings.Join(nhUserFieldNames, ",")
nhUserRowsExpectAutoSet = strings.Join(stringx.Remove(nhUserFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",")
nhUserRowsWithPlaceHolder = strings.Join(stringx.Remove(nhUserFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?"
)
type (
nhUserModel interface {
Insert(ctx context.Context, data *NhUser) (sql.Result, error)
FindOne(ctx context.Context, id uint) (*NhUser, error)
FindOneByEmail(ctx context.Context, email string) (*NhUser, error)
Update(ctx context.Context, data *NhUser) error
Delete(ctx context.Context, id uint) error
}
defaultNhUserModel struct {
conn sqlx.SqlConn
table string
}
NhUser struct {
Id uint `db:"id"`
Email string `db:"email"` // 邮箱
Password string `db:"password"` // 密码
CreateTime sql.NullInt64 `db:"create_time"` // 创建时间
InviteId int `db:"invite_id"` // 邀请码/测试码ID
LastLoginTime sql.NullInt64 `db:"last_login_time"` // 最后登陆时间
LastLoginIp string `db:"last_login_ip"` // 最后登录IP
Remarks sql.NullString `db:"remarks"` // 备注
Status uint8 `db:"status"` // 用户状态 1 正常 2 禁止
IsOpenSeason int8 `db:"is_open_season"` // 是否已开启赛季
}
)
func newNhUserModel(conn sqlx.SqlConn) *defaultNhUserModel {
return &defaultNhUserModel{
conn: conn,
table: "`nh_user`",
}
}
func (m *defaultNhUserModel) Delete(ctx context.Context, id uint) error {
query := fmt.Sprintf("delete from %s where `id` = ?", m.table)
_, err := m.conn.ExecCtx(ctx, query, id)
return err
}
func (m *defaultNhUserModel) FindOne(ctx context.Context, id uint) (*NhUser, error) {
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", nhUserRows, m.table)
var resp NhUser
err := m.conn.QueryRowCtx(ctx, &resp, query, id)
switch err {
case nil:
return &resp, nil
case sqlx.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *defaultNhUserModel) FindOneByEmail(ctx context.Context, email string) (*NhUser, error) {
var resp NhUser
query := fmt.Sprintf("select %s from %s where `email` = ? limit 1", nhUserRows, m.table)
err := m.conn.QueryRowCtx(ctx, &resp, query, email)
switch err {
case nil:
return &resp, nil
case sqlx.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *defaultNhUserModel) Insert(ctx context.Context, data *NhUser) (sql.Result, error) {
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?)", m.table, nhUserRowsExpectAutoSet)
ret, err := m.conn.ExecCtx(ctx, query, data.Email, data.Password, data.InviteId, data.LastLoginTime, data.LastLoginIp, data.Remarks, data.Status, data.IsOpenSeason)
return ret, err
}
func (m *defaultNhUserModel) Update(ctx context.Context, newData *NhUser) error {
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, nhUserRowsWithPlaceHolder)
_, err := m.conn.ExecCtx(ctx, query, newData.Email, newData.Password, newData.InviteId, newData.LastLoginTime, newData.LastLoginIp, newData.Remarks, newData.Status, newData.IsOpenSeason, newData.Id)
return err
}
func (m *defaultNhUserModel) tableName() string {
return m.table
}

View File

@@ -6,16 +6,14 @@ import (
)
type err struct {
code int
reason Reason
msg string
code Reason
msg string
}
func New(code int, reason Reason, message any) error {
func New(code Reason, message any) error {
return err{
code: code,
reason: reason,
msg: cast.ToString(message),
code: code,
msg: cast.ToString(message),
}
}
@@ -25,15 +23,10 @@ func (e err) Error() string {
}
// Code return code
func (e err) Code() int {
func (e err) Code() Reason {
return e.code
}
// Reason return reason
func (e err) Reason() Reason {
return e.reason
}
// Message return message
func (e err) Message() string {
return e.msg

View File

@@ -1,56 +1,5 @@
package errs
import (
"net/http"
)
func Success() error {
return New(http.StatusOK, ErrSucceed, "success")
}
func NotFound(reason Reason, v any) error {
return New(http.StatusNotFound, reason, v)
}
func BadRequest(reason Reason, v any) error {
return New(http.StatusBadRequest, reason, v)
}
func InternalServer(reason Reason, v any) error {
return New(http.StatusInternalServerError, reason, v)
}
// Unauthorized new Unauthorized error that is mapped to a 401 response.
func Unauthorized(reason Reason, v any) error {
return New(http.StatusUnauthorized, reason, v)
}
// Forbidden new Forbidden error that is mapped to a 403 response.
func Forbidden(reason Reason, v any) error {
return New(http.StatusForbidden, reason, v)
}
// Conflict new Conflict error that is mapped to a 409 response.
func Conflict(reason Reason, v any) error {
return New(http.StatusConflict, reason, v)
}
// ServiceUnavailable new ServiceUnavailable error that is mapped to an HTTP 503 response.
func ServiceUnavailable(reason Reason, v any) error {
return New(http.StatusServiceUnavailable, reason, v)
}
// GatewayTimeout new GatewayTimeout error that is mapped to an HTTP 504 response.
func GatewayTimeout(reason Reason, v any) error {
return New(http.StatusGatewayTimeout, reason, v)
}
// BadGateway new BadGateway error that is mapped to an HTTP 504 response.
func BadGateway(reason Reason, v any) error {
return New(http.StatusBadGateway, reason, v)
}
// ClientClosed new ClientClosed error that is mapped to an HTTP 499 response.
func ClientClosed(reason Reason, v any) error {
return New(499, reason, v)
return New(ErrSucceed, "ok")
}

View File

@@ -2,24 +2,45 @@ package errs
import (
"context"
"encoding/json"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/rest"
"github.com/zeromicro/go-zero/rest/httpx"
"net/http"
"os"
"strings"
)
var debug bool
func init() {
if strings.ToLower(os.Getenv("VANS_API_DEBUG")) == "on" {
debug = true
}
httpx.SetErrorHandlerCtx(ErrorHandleCtx)
httpx.SetErrorHandler(ErrorHandle)
httpx.SetOkHandler(OkHandle)
}
func SetDebug(d bool) {
debug = d
func OkHandle(ctx context.Context, v any) any {
return map[string]any{
"status": map[string]any{
"code": ErrSucceed,
"msg": "ok",
},
"data": v,
}
}
func WithUnauthorizedCallback() rest.RunOption {
return rest.WithUnauthorizedCallback(func(w http.ResponseWriter, r *http.Request, err error) {
body := map[string]any{
"status": map[string]any{
"code": ErrUnauthorized,
"msg": err.Error(),
},
}
data, _ := json.Marshal(body)
w.Header().Set(httpx.ContentType, "application/json; charset=utf-8")
w.WriteHeader(http.StatusOK)
_, err = w.Write(data)
if err != nil {
logx.Errorw("error write response", logx.Field("type", "http"), logx.Field("error", err))
}
})
}
func ErrorHandle(err error) (int, any) {
@@ -27,10 +48,9 @@ func ErrorHandle(err error) (int, any) {
}
func ErrorHandleCtx(ctx context.Context, err error) (int, any) {
code := http.StatusBadRequest
reason := ErrInternalServer
code := ErrUnknownReason
var msg string
if ec, ok := err.(interface{ Code() int }); ok {
if ec, ok := err.(interface{ Code() Reason }); ok {
code = ec.Code()
}
if ec, ok := err.(interface{ Message() string }); ok {
@@ -38,27 +58,17 @@ func ErrorHandleCtx(ctx context.Context, err error) (int, any) {
} else {
msg = err.Error()
}
if ec, ok := err.(interface{ Reason() Reason }); ok {
reason = ec.Reason()
}
var errMsg string
if reason < ErrUnknownLogicError && reason != ErrSucceed {
errMsg = msg
if code < ErrUnknownReason && code >= ErrInternalServer {
logx.Errorw("request system error", logx.Field("err-msg", msg))
msg = "system error"
}
body := map[string]any{
"code": reason,
"message": msg,
"status": map[string]any{
"code": code,
"msg": msg,
},
}
if errMsg != "" && debug {
body["err"] = errMsg
}
if ec, ok := err.(interface{ Metadata() any }); ok {
if md := ec.Metadata(); md != nil {
body["metadata"] = md
}
}
return code, body
return http.StatusOK, body
}

View File

@@ -3,10 +3,11 @@ package errs
type Reason int
const (
// ======= 系统错误:0~999 =======
ErrUnknownReason Reason = 0 // 未知错误
ErrSucceed Reason = 200 // 成功
ErrOverload Reason = 403 // 请求超载
// ======= 系统错误:10000~19999 =======
ErrUnknownReason Reason = 10000 // 未知错误
ErrSucceed Reason = 10200 // 成功
ErrUnauthorized Reason = 10401 // 未授权
ErrOverload Reason = 10403 // 请求超载
// ======= 服务器内部错误1000~9999 =======
ErrInternalServer Reason = 1000 // 未知的服务器内部错误
@@ -15,22 +16,10 @@ const (
ErrEncodePassword Reason = 1003 // 密码加密错误
ErrGenerateUUid Reason = 1004 // 生成uuid错误
ErrGenerateToken Reason = 1005 // 生成token错误
ErrGetExchangeRate Reason = 1005 // 获取汇率错误
// ======= 业务层错误:10000~99999 =======
ErrUnknownLogicError Reason = 10000 // 未知的业务错误
ErrInvalidParam Reason = 10001 // 无效参数错误
ErrInvalidSignature Reason = 10002 // 无效签名错误
ErrInvalidToken Reason = 10003 // 无效的token
ErrInvoiceHasPaid Reason = 10004 // 订单已支付
ErrInvalidAppId Reason = 10005 // 应用id无效
ErrUserNotHasInviter Reason = 10006 // 用户没有邀请人
ErrTaskNotFound Reason = 10007 // 任务不存在
ErrTaskAlreadyReward Reason = 10008 // 任务已领取
ErrTaskNotFinished Reason = 10009 // 任务未完成
// ========= admin 业务相关错误码: 30000~39999 =========
ErrUnknownAdminError Reason = 30000 // 未知的admin错误
ErrInvalidPassword Reason = 30001 // 无效密码
ErrInvalidAccount Reason = 30002 // 无效账号
// ======= 业务层错误:20000~29999 =======
ErrUnknownLogicError Reason = 20000 // 未知的业务错误
ErrTaskNotFound Reason = 20001 // 任务不存在
ErrTaskAlreadyReward Reason = 20002 // 任务已领取
ErrTaskNotFinished Reason = 20003 // 任务未完成
)

View File

@@ -9,27 +9,38 @@ import (
)
type ServiceContext struct {
Config config.Config
Config config.Config
TaskModel model.NhTaskModel
TaskAssetModel model.NhTaskAssetModel
TaskAssetRecordModel model.NhTaskAssetRecordModel
TaskProgressModel model.NhTaskProgressModel
TwitterModel model.NhTwitterModel
Earn *ea.Client
DBConn sqlx.SqlConn
PromoteBindModel model.NhPromoteBindModel
TouristBindModel model.NhTouristBindModel
CommunityModel model.NhTaskCommunityModel
UserModel model.NhUserModel
Earn *ea.Client
DBConn sqlx.SqlConn
}
func NewServiceContext(c config.Config) *ServiceContext {
dbConn := c.MySql.Conn()
return &ServiceContext{
Config: c,
Config: c,
TaskModel: model.NewNhTaskModel(dbConn),
TaskAssetModel: model.NewNhTaskAssetModel(dbConn),
TaskAssetRecordModel: model.NewNhTaskAssetRecordModel(dbConn),
TaskProgressModel: model.NewNhTaskProgressModel(dbConn),
TwitterModel: model.NewNhTwitterModel(dbConn),
Earn: c.Earn.BuildEarnClient(),
DBConn: dbConn,
PromoteBindModel: model.NewNhPromoteBindModel(dbConn),
CommunityModel: model.NewNhTaskCommunityModel(dbConn),
UserModel: model.NewNhUserModel(dbConn),
Earn: c.Earn.BuildEarnClient(),
DBConn: dbConn,
}
}

View File

@@ -3,6 +3,19 @@
package types
type Community struct {
Id uint `json:"id"` // 社区ID
Title string `json:"title"` // 社区标题
Logo string `json:"logo"` // 社区图标
Description string `json:"description"` // 社区描述
StartAt int64 `json:"start_at"` // 开始时间
EndAt int64 `json:"end_at"` // 结束时间
}
type GetCommunityListResp struct {
CommunityList []Community `json:"community_list"` // 社区列表
}
type GetTaskListReq struct {
CommunityId uint `form:"community_id,optional"` // 所属社区ID
}
@@ -16,25 +29,33 @@ type GetTaskRewardResp struct {
}
type Task struct {
Id uint `json:"id"` // 任务ID
CommunityId uint `json:"community_id"` // 所属社区ID
Title string `json:"title"` // 任务标题
SubTitle string `json:"sub_title"` // 副标题
Description string `json:"description"` // 任务描述
Points int `json:"points"` // 任务积分
ButtonText string `json:"button_text"` // 按钮文字
Type int8 `json:"type"` // 任务类型: 0=follow_twitter,1=bind_twitter,2=cast_twitter,3=publish_twitter,4=repost_twitter,5=watch_youtube,6=follow_youtube,7=bind_discord,8=join_telegram,9=daily_pay
Url string `json:"url"` // 跳转链接
Status int8 `json:"status"` // 任务状态: 0=不启用1=启用
StartAt string `json:"start_at"` // 开始时间
EndAt string `json:"end_at"` // 结束时间
FinishState int8 `json:"finish_state"` // 0:未完成 1:待校验 2:已完成未领取 3:已领取
Id uint `json:"id"` // 任务ID
CommunityId uint `json:"community_id"` // 所属社区ID
Title string `json:"title"` // 任务标题
SubTitle string `json:"sub_title"` // 副标题
Description string `json:"description"` // 任务描述
Points int `json:"points"` // 任务积分
ButtonText string `json:"button_text"` // 按钮文字
Params string `json:"params"` // 参数
Type int8 `json:"type"` // 任务类型: 0=follow_twitter,1=bind_twitter,2=cast_twitter,3=publish_twitter,4=repost_twitter,5=watch_youtube,6=follow_youtube,7=bind_discord,8=join_telegram,9=daily_pay,10=invite_user
Url string `json:"url"` // 跳转链接
Sort int `json:"sort"` // 排序
StartAt string `json:"start_at"` // 开始时间
EndAt string `json:"end_at"` // 结束时间
HasFinishCount int `json:"has_finish_count"` // 当前完成进度
TotalCount int `json:"total_count"` // 总进度
FinishState int8 `json:"finish_state"` // 0:未完成 1:待校验 2:已完成未领取 3:已领取
}
type TaskIdPath struct {
ID uint `path:"id"` // 任务ID
}
type VerifyTaskResultReq struct {
ID uint `form:"id"` // 任务ID
Params string `form:"params,optional"` // 额外的参数
}
type VerifyTaskResultResp struct {
Finish bool `json:"finish"` // 是否完成
}