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 } }