Initial commit

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-15 13:57:10 +08:00
co-authored by Claude Opus 5
commit 8679200f41
1897 changed files with 257900 additions and 0 deletions
+21
View File
@@ -0,0 +1,21 @@
package taskrecordmod
type TaskType int
const (
//DailyTaskTypeUserInviteOne TaskType = 1 // 累计邀请1人
//DailyTaskTypeUserInviteThree TaskType = 2 // 累计邀请3人
//DailyTaskTypeUserInviteTen TaskType = 3 // 累计邀请10人
//DailyTaskTypeUserInviteThirty TaskType = 4 // 累计邀请30人
DailyTaskTypeAdsClick TaskType = 1 // 每日广告点击
DailyTaskTypeUserInvite TaskType = 2 // 每日邀请
DailyUserLogin TaskType = 5 // 每日登录
DailyComment TaskType = 6 // 每日评论
DailyPublish TaskType = 7 // 每日发布
OnceTaskTypeUserBuyVip TaskType = 8 // 购买vip
Download TaskType = 9 // 下载APP
DailyTaskCommentSetGod TaskType = 10 // 评论被设置成神评
DailyDoCollect TaskType = 11 // 每日收藏
DailyUnlockByGold TaskType = 12 // 每日解锁(video/acg)
)
+452
View File
@@ -0,0 +1,452 @@
package taskrecordmod
import (
"91porn-server/common/db"
"91porn-server/common/log"
"91porn-server/common/timeutil"
"91porn-server/models"
"errors"
"fmt"
"time"
"go.mongodb.org/mongo-driver/mongo/options"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
)
const table = models.Task
func coll(t *db.MongoTool) *db.MongoTool {
if t == nil {
return mdb.Coll(table)
}
return t.Coll(table)
}
// initIndex 索引设置
func initIndex() {
many := []mongo.IndexModel{ //batch set indexes //value is the type 1 or -1
{
Keys: bson.D{{"createdAt", -1}},
},
{
Keys: bson.D{{Key: "uid", Value: -1}, {Key: "taskId", Value: -1}, {Key: "recordTime", Value: -1}},
},
}
_, err := coll(nil).CreateIndex(many)
if err != nil {
panic(fmt.Sprintf("user model set index err ==>[%+v]", err))
}
}
func Init() {
mdb = db.Init(table)
initIndex()
}
func InsertOne(cfg Task) error {
if _, err := coll(nil).InsertOne(cfg); err != nil {
return err
}
return nil
}
// 添加任务记录
func AddTaskRecord(uid uint64) (taskRecord *Task, err error) {
now := time.Now()
receiveTime := timeutil.BeginningOfDay(now)
taskRecord = &Task{
UID: uid,
SignRecord: []primitive.ObjectID{},
SignTime: receiveTime,
JewelBoxRecord: []primitive.ObjectID{},
JewelBoxReceiveTime: receiveTime,
ConsumerFeedbackRecord: []primitive.ObjectID{},
ConsumerFeedbackReceiveTime: receiveTime,
CreateTime: now,
}
if _, err = coll(nil).InsertOne(&taskRecord); err != nil {
return nil, err
}
return
}
func InsertTask(t *db.MongoTool, filter bson.M, update bson.M) error {
var item *Task
if err := coll(t).FindOneAndUpsert(&item, filter, bson.M{"$set": update}); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "InsertTask", table, "FindOneAndUpsert", err),
log.Any("filter", filter),
log.Any("update", update),
)
return err
}
return nil
}
// CurrentCountUpdate 评论值更新
func CurrentCountUpdate(t *db.MongoTool, filter bson.M) error {
_, err := coll(t).UpdateOne(filter, bson.M{"$inc": bson.M{"count": 1}})
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "CurrentCountUpdate", models.Task, "UpdateOne", err),
log.Any("filter", filter),
)
return err
}
return nil
}
func GetByUID(uid uint64) (*Task, error) {
var out Task
if err := coll(nil).FindOne(&out, bson.M{"uid": uid}); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetByUID", models.Task, "FindOne", err),
log.Any("uid", uid),
)
return nil, err
}
if out.ID.IsZero() {
return nil, nil
}
return &out, nil
}
// SignUpdate 签到更新
func SignUpdate(t *db.MongoTool, uid uint64, taskID primitive.ObjectID) error {
update := bson.M{
"$set": bson.M{"signTime": time.Now()},
"$addToSet": bson.M{"signRecord": taskID},
}
result, err := coll(t).UpdateOne(bson.M{"uid": uid}, update)
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "SignUpdate", models.Task, "UpdateOne", err),
log.Any("uid", uid),
)
return err
}
if result.ModifiedCount == 0 {
err = errors.New("task UpdateOne ModifiedCount err")
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "SignUpdate", models.Task, "result.ModifiedCount == 0", err),
log.Any("uid", uid),
log.Any("addToSet", taskID),
)
return err
}
return nil
}
// 活跃值更新
func CurrentValueUpdate(t *db.MongoTool, uid uint64, currentValue int64) error {
result, err := coll(t).UpdateOne(bson.M{"uid": uid}, bson.M{"$inc": bson.M{"currentValue": currentValue}})
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "CurrentValueUpdate", models.Task, "UpdateOne", err),
log.Any("uid", uid),
log.Any("currentValue", currentValue),
)
return err
}
if result.ModifiedCount == 0 {
err = errors.New("task UpdateOne ModifiedCount err")
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "CurrentValueUpdate", models.Task, "result.ModifiedCount == 0", err),
log.Any("uid", uid),
log.Any("currentValue", currentValue),
)
return err
}
return nil
}
// 签到重置
func SignReset(uid uint64) (out *Task, err error) {
now := timeutil.BeginningOfDay(time.Now())
if err = coll(nil).FindOneAndUpdate(&out, bson.M{"uid": uid}, bson.M{
"$set": bson.M{
"currentValue": 0,
"signTime": now,
"jewelBoxRecord": []primitive.ObjectID{},
"jewelBoxReceiveTime": now,
"signRecord": []primitive.ObjectID{},
},
}); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "SignReset", models.Task, "FindOneAndUpdate", err),
log.Any("uid", uid),
)
return
}
return
}
// 消费返利重置
func ConsumerFeedbackReset(uid uint64) (out *Task, err error) {
now := timeutil.BeginningOfDay(time.Now())
err = coll(nil).FindOneAndUpdate(&out, bson.M{"uid": uid}, bson.M{
"$set": bson.M{
"consumerFeedbackRecord": []primitive.ObjectID{},
"consumerFeedbackReceiveTime": now,
},
})
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "ConsumerFeedbackReset", models.Task, "FindOneAndUpdate", err),
log.Any("uid", uid),
)
return
}
return
}
// 充值有礼重置
func ChessRechargePoliteReset(uid uint64) (out *Task, err error) {
now := timeutil.BeginningOfDay(time.Now())
if err = coll(nil).FindOneAndUpdate(&out, bson.M{"uid": uid}, bson.M{
"$set": bson.M{
"chessRechargePoliteRecord": []primitive.ObjectID{},
"chessRechargePoliteReceiveTime": now,
},
}); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "ConsumerFeedbackReset", models.Task, "FindOneAndUpdate", err),
log.Any("uid", uid),
)
return
}
return
}
// 福利记录更新
func BoonRecordUpdate(t *db.MongoTool, uid uint64, taskID primitive.ObjectID, configType ConfigType) error {
update := bson.M{
"$set": bson.M{"signTime": time.Now()},
}
switch configType {
case Sign:
update["$addToSet"] = bson.M{"signRecord": taskID}
update["$set"] = bson.M{"signTime": time.Now()}
case JewelBox:
update["$addToSet"] = bson.M{"jewelBoxRecord": taskID}
update["$set"] = bson.M{"jewelBoxReceiveTime": time.Now()}
case ConsumerFeedback:
update["$addToSet"] = bson.M{"consumerFeedbackRecord": taskID}
update["$set"] = bson.M{"consumerFeedbackReceiveTime": time.Now()}
}
result, err := coll(t).UpdateOne(bson.M{"uid": uid}, update)
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "SignUpdate", models.Task, "UpdateOne", err),
log.Any("uid", uid),
)
return err
}
if result.ModifiedCount == 0 {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail", "SignUpdate", models.Task, "result.ModifiedCount == 0"),
log.Any("uid", uid),
log.Any("addToSet", taskID),
)
return errors.New("task UpdateOne ModifiedCount err")
}
return nil
}
// 是否完成一次性任务
func IsOnceTaskComplete(t *db.MongoTool, uid uint64, taskId primitive.ObjectID) (bool, error) {
var tsk Task
if err := coll(t).FindOne(&tsk, bson.M{"uid": uid, "type": OnceTask}); err != nil {
return false, err
}
if tsk.ID.IsZero() {
return false, nil
}
for _, v := range tsk.OnceTask {
if taskId == v {
return true, nil
}
}
return false, nil
}
// IsDownloadTaskComplete 是否完成一次性任务 - 下载任务
func IsDownloadTaskComplete(t *db.MongoTool, uid uint64, taskId primitive.ObjectID) (int, error) {
var tsk Task
if err := coll(t).FindOne(&tsk, bson.M{"uid": uid, "taskId": taskId}); err != nil {
return 0, err
}
if tsk.ID.IsZero() {
return 0, nil
}
return tsk.Status, nil
}
func CompleteOnceTask(t *db.MongoTool, uid uint64, taskId primitive.ObjectID) error {
var tsk Task
if err := coll(t).FindOne(&tsk, bson.M{"uid": uid, "type": OnceTask}); err != nil {
return err
}
now := time.Now()
if tsk.ID.IsZero() {
receiveTime := timeutil.BeginningOfDay(now)
_, err := coll(t).InsertOne(&Task{
UID: uid,
Type: OnceTask,
SignRecord: []primitive.ObjectID{},
SignTime: receiveTime,
JewelBoxRecord: []primitive.ObjectID{},
JewelBoxReceiveTime: receiveTime,
ConsumerFeedbackRecord: []primitive.ObjectID{},
ConsumerFeedbackReceiveTime: receiveTime,
OnceTask: []primitive.ObjectID{taskId},
CreateTime: now,
})
return err
}
for _, v := range tsk.OnceTask {
if v == taskId { // 已经完成了
return nil
}
}
if len(tsk.OnceTask) == 0 {
_, err := coll(t).UpdateOne(bson.M{"_id": tsk.ID}, bson.M{"$set": bson.M{"onceTask": []primitive.ObjectID{taskId}}})
return err
}
_, err := coll(t).UpdateOne(bson.M{"_id": tsk.ID}, bson.M{"$addToSet": bson.M{"onceTask": taskId}})
return err
}
func GetUserRecordByTime(uid uint64, taskId primitive.ObjectID, record time.Time) (*Task, error) {
var out *Task
if err := coll(nil).FindOne(&out, bson.M{"uid": uid, "taskId": taskId, "recordTime": record}); err != nil {
log.Error(
fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetUserRecordByTime", models.Task, "FindOne", err),
log.Any("uid", uid),
)
return nil, err
}
return out, nil
}
// GetUserTaskRecordByUid 查询用户任务记录
func GetUserTaskRecordByUid(uid uint64, t ConfigType, taskId primitive.ObjectID) (*Task, error) {
var out *Task
if err := coll(nil).FindOne(&out, bson.M{"uid": uid, "type": t, "taskId": taskId}); err != nil {
log.Error(
fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetUserTaskRecordByUid", models.Task, "FindOne", err),
log.Any("uid", uid),
)
return nil, err
}
return out, nil
}
// GetUserTask 查询用户任务记录
func GetUserTask(uid uint64, taskId primitive.ObjectID) (Task, error) {
var out Task
if err := coll(nil).FindOne(&out, bson.M{"uid": uid, "taskId": taskId}); err != nil {
log.Error(
fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetUserTaskRecordByUid", models.Task, "FindOne", err),
log.Any("uid", uid),
)
return out, err
}
return out, nil
}
func UpdateStatusById(t *db.MongoTool, id primitive.ObjectID, status int) (out *Task, err error) {
update := bson.M{"$set": bson.M{"updateTime": time.Now(), "status": status}, "$inc": bson.M{"stage": 1}}
if err = coll(t).FindOneAndUpdate(&out, bson.M{"_id": id}, update); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "UpdateStatusById", models.Task, "UpdateStatusById", err),
log.Any("id", id.Hex()),
)
return
}
return
}
func UpsertOne(filter, updateDate bson.M) (err error) {
if _, err = coll(nil).UpsertOne(filter, updateDate); err != nil {
log.Error("UpsertOne error",
log.Any("filter", filter),
log.Any("updateDate", updateDate),
log.E(err))
return err
}
return
}
// GetSignRecord 取用户签到任务记录
func GetSignRecord(uid uint64) (*Task, error) {
var out *Task
if err := coll(nil).FindOne(&out, bson.M{"uid": uid, "type": Sign}); err != nil {
log.Error(
fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetUserRecordByType", models.Task, "FindOne", err),
log.Any("uid", uid),
)
return nil, err
}
return out, nil
}
// TaskSignUpdate 更新用户签到记录
func TaskSignUpdate(t *db.MongoTool, uid uint64, taskID primitive.ObjectID) error {
filter := bson.M{
"uid": uid,
"type": Sign,
}
update := bson.M{"$addToSet": bson.M{"signRecord": taskID}}
result, err := coll(t).UpdateOne(filter, update)
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "RecordUpdate", models.Task, "UpdateOne", err),
log.Any("uid", uid),
)
return err
}
if result.ModifiedCount == 0 {
err = errors.New("task sign UpdateOne ModifiedCount err")
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "RecordUpdate", models.Task, "result.ModifiedCount == 0", err),
log.Any("uid", uid),
log.Any("taskID", taskID),
log.Any("configType:sign", Sign),
)
return err
}
return nil
}
// TaskSignInit 任务记录初始化
func TaskSignInit(uid uint64) (*Task, error) {
now := time.Now()
receiveTime := timeutil.BeginningOfDay(now)
taskRecord := &Task{
UID: uid,
SignRecord: []primitive.ObjectID{},
SignTime: receiveTime,
JewelBoxRecord: []primitive.ObjectID{},
JewelBoxReceiveTime: receiveTime,
ConsumerFeedbackRecord: []primitive.ObjectID{},
ConsumerFeedbackReceiveTime: receiveTime,
TaskType: 0,
Type: Sign,
CreateTime: now,
}
if _, err := coll(nil).InsertOne(&taskRecord); err != nil {
return nil, err
}
return taskRecord, nil
}
// TaskSignReset 任务重置
func TaskSignReset(uid uint64) (*Task, error) {
var (
out *Task
now = timeutil.BeginningOfDay(time.Now())
)
if err := coll(nil).FindOneAndUpdate(&out, bson.M{"uid": uid, "type": Sign}, bson.M{
"$set": bson.M{
"signRecord": []primitive.ObjectID{},
"signTime": now,
},
}, options.FindOneAndUpdate().SetReturnDocument(options.After)); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "TaskReset", models.Task, "FindOneAndUpdate", err),
log.Any("uid", uid),
log.Any("configType:sign", Sign),
)
return nil, err
}
return out, nil
}
+74
View File
@@ -0,0 +1,74 @@
package taskrecordmod
import (
"91porn-server/common/db"
"time"
"go.mongodb.org/mongo-driver/bson/primitive"
)
var mdb *db.MongoDB
type ConfigType int
const (
OldSign ConfigType = iota + 1 // 1:签到福利
JewelBox // 2:宝箱福利
ConsumerFeedback // 3:消费回馈(站群)
OnceTask // 4:新手一次福利
DailyTask // 5:日常福利
GrowTask // 6:成长任务
Sign // 7:新的签到福利
)
const (
UnReceived = 1 // 未领取
Received = 2 // 已领取
)
type Task struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"` // 文档ID
UID uint64 `json:"uid" bson:"uid"` // 用户ID
CurrentValue int64 `json:"currentValue" bson:"currentValue"` // 活跃值
TaskID primitive.ObjectID `json:"taskId" bson:"taskId"` // 任务ID
Type ConfigType `json:"type" bson:"type"` // 任务分类
TaskType TaskType `json:"taskType" bson:"taskType"` // 任务类型
Status int `json:"status" bson:"status"` // 领取状态
Count int `json:"count" bson:"count"` // 领取次数
JewelBoxRecord []primitive.ObjectID `json:"jewelBoxRecord" bson:"jewelBoxRecord"` // 宝箱领取记录
JewelBoxReceiveTime time.Time `json:"jewelBoxReceiveTime" bson:"jewelBoxReceiveTime"` // 宝箱领取时间
SignRecord []primitive.ObjectID `json:"signRecord" bson:"signRecord"` // 签到记录
SignTime time.Time `json:"signTime" bson:"signTime"` // 签到时间
Stage int `json:"stage" bson:"stage"` // 当前的阶段(只有成长任务使用)
ConsumerFeedbackRecord []primitive.ObjectID `json:"consumerFeedbackRecord" bson:"consumerFeedbackRecord"` // 消费返利领取记录
ConsumerFeedbackReceiveTime time.Time `json:"consumerFeedbackReceiveTime" bson:"consumerFeedbackReceiveTime"` // 消费返利领取时间
OnceTask []primitive.ObjectID `json:"onceTask" bson:"onceTask"` // 一次性任务领奖记录
RecordTime time.Time `json:"recordTime" bson:"recordTime"` // 记录时间
UpdateTime time.Time `json:"updateTime" bson:"updateTime"` // 更新时间
CreateTime time.Time `json:"createTime" bson:"createTime"` // 创建时间
}
// HasReceived 是否领取福利
func (t *Task) HasReceived(id primitive.ObjectID, configType ConfigType) bool {
switch configType {
case Sign:
for _, v := range t.SignRecord {
if v == id {
return true
}
}
case JewelBox:
for _, v := range t.JewelBoxRecord {
if v == id {
return true
}
}
case ConsumerFeedback:
for _, v := range t.ConsumerFeedbackRecord {
if v == id {
return true
}
}
}
return false
}
+1
View File
@@ -0,0 +1 @@
package taskrecordmod