Files
rootandClaude Opus 5 8679200f41 Initial commit
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 13:57:10 +08:00

162 lines
4.5 KiB
Go

package main
import (
"context"
"fmt"
"log"
"time"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
const mongoURI = "mongodb://admin:TESTwfeZYP0kjBdy8DAUdwU@172.104.181.99:57017,172.104.181.99:57018,172.104.181.99:57019/91porn?replicaSet=yctest&maxPoolSize=200&connectTimeout=30&authSource=admin"
// SeedCheckin 为指定用户生成N天连续签到数据,使得今天是第N+1天签到
// userIds: 用户ID列表 (uint64, 对应本项目的 UID)
// n: 已签到天数(生成过去N天的记录,今天为第N+1天)
func SeedCheckin(ctx context.Context, db *mongo.Database, userIds []uint64, n int) error {
prizeColl := db.Collection("checkin_prize")
checkinColl := db.Collection("user_checkin")
// 东八区
loc, _ := time.LoadLocation("Asia/Shanghai")
now := time.Now().In(loc)
today := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, loc)
fmt.Printf("Now: %v\n", now)
fmt.Printf("Today (CST 00:00): %v\n", today)
fmt.Printf("生成 %d 天签到记录,今天签到为第 %d 天\n", n, n+1)
// 1. 查奖励配置(非大奖)
cursor, err := prizeColl.Find(ctx, bson.M{
"status": true,
"checkinType": int64(1),
}, options.Find().SetSort(bson.M{"checkinDays": 1}))
if err != nil {
return fmt.Errorf("query prizes failed: %w", err)
}
var prizeConfigs []bson.M
if err := cursor.All(ctx, &prizeConfigs); err != nil {
return fmt.Errorf("decode prizes failed: %w", err)
}
// 按天数映射奖品ID(本项目用 ObjectID)
dayPrizes := make(map[int64][]primitive.ObjectID)
for _, p := range prizeConfigs {
days := toInt64(p["checkinDays"])
bigPrize, _ := p["bigPrize"].(bool)
if !bigPrize {
if oid, ok := p["_id"].(primitive.ObjectID); ok {
dayPrizes[days] = append(dayPrizes[days], oid)
}
}
}
// 2. 删除这些用户的所有签到记录
delResult, err := checkinColl.DeleteMany(ctx, bson.M{
"userId": bson.M{"$in": userIds},
})
if err != nil {
return fmt.Errorf("delete failed: %w", err)
}
fmt.Printf("\nDeleted %d existing records\n", delResult.DeletedCount)
// 3. 插入过去N天的签到记录(东八区时间)
for _, userId := range userIds {
fmt.Printf("\n--- userId=%d ---\n", userId)
for day := n; day >= 1; day-- {
date := today.AddDate(0, 0, -day)
continuouslyDays := int64(n - day + 1)
cumulativeDays := continuouslyDays
prizes := dayPrizes[continuouslyDays]
doc := bson.M{
"_id": primitive.NewObjectID(),
"date": date,
"userId": userId,
"prizes": prizes,
"gave": true,
"vipPrizeGave": false,
"continuouslyDays": continuouslyDays,
"cumulativeDays": cumulativeDays,
"isReset": false,
"createdAt": date.Add(10 * time.Hour),
}
_, err := checkinColl.InsertOne(ctx, doc)
if err != nil {
log.Printf(" Insert failed: %v", err)
continue
}
fmt.Printf(" date=%s contDays=%d prizes=%v ✓\n",
date.Format("2006-01-02 15:04:05 MST"),
continuouslyDays, prizes)
}
}
// 4. 验证
fmt.Println("\n=== Verification ===")
loc2, _ := time.LoadLocation("Asia/Shanghai")
for _, userId := range userIds {
cur, _ := checkinColl.Find(ctx, bson.M{
"userId": userId,
}, options.Find().SetSort(bson.M{"date": -1}))
var records []bson.M
_ = cur.All(ctx, &records)
fmt.Printf("userId=%d: %d records, 今天签到为第%d天\n", userId, len(records), len(records)+1)
for _, r := range records {
var t time.Time
switch d := r["date"].(type) {
case primitive.DateTime:
t = d.Time().In(loc2)
case time.Time:
t = d.In(loc2)
}
fmt.Printf(" date=%s contDays=%v prizes=%v\n",
t.Format("2006-01-02 15:04:05 MST"),
r["continuouslyDays"], r["prizes"])
}
}
fmt.Println("\nDone!")
return nil
}
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
client, err := mongo.Connect(ctx, options.Client().ApplyURI(mongoURI))
if err != nil {
log.Fatal("connect failed:", err)
}
defer client.Disconnect(ctx)
db := client.Database("91porn")
// ====== 在这里修改参数 ======
userIds := []uint64{303458}
n := 6 // 生成6天签到记录,今天签到为第7天
// ===========================
if err := SeedCheckin(ctx, db, userIds, n); err != nil {
log.Fatal(err)
}
}
func toInt64(v interface{}) int64 {
switch n := v.(type) {
case int64:
return n
case int32:
return int64(n)
case float64:
return int64(n)
default:
return 0
}
}