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" // PrizeType 与 prizemod.PrizeType 保持一致 const ( PrizeTypeCurrentValue = 1 // 活跃值 PrizeTypeGold = 2 // 金币 PrizeTypeVIPCard = 5 // 会员卡 PrizeTypeIntegral = 8 // 积分 PrizeTypeAIUndress = 9 // AI脱衣 PrizeTypeAIChangeFace = 10 // AI换脸 PrizeTypeVideoCoupon = 11 // 观影券 ) const CheckinTypeContinuously = 1 // activityPrizeDef 定义基础奖品 type activityPrizeDef struct { Name string Type int Count int32 Price int64 Desc string } // checkinPrizeDef 定义签到奖品配置 type checkinPrizeDef struct { Title string CheckinDays int64 BigPrize bool PrizeName string PrizeRef string // 引用 activityPrizeDef 的 key } func main() { ctx, cancel := context.WithTimeout(context.Background(), 60*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") now := time.Now() // ======================== // Step 0: 清理上次脚本插入的旧数据 // ======================== fmt.Println("=== Step 0: 清理旧签到配置数据 ===") db.Collection("checkin_config").DeleteMany(ctx, bson.M{}) db.Collection("checkin_prize").DeleteMany(ctx, bson.M{}) // 清理上次脚本创建的 activity_prize(按名称前缀匹配) delRes, _ := db.Collection("activity_prize").DeleteMany(ctx, bson.M{ "desc": bson.M{"$regex": "^签到奖励|^VIP签到"}, }) fmt.Printf(" 清理 activity_prize: %d, checkin_prize: all, checkin_config: all\n\n", delRes.DeletedCount) // ======================== // Step 1: 创建 activity_prize 基础奖品 // ======================== fmt.Println("=== Step 1: 创建 activity_prize 基础奖品 ===") activityPrizeColl := db.Collection("activity_prize") // 定义所有需要的奖品规格 prizeDefs := map[string]activityPrizeDef{ // 积分类 "integral_3": {Name: "签到积分x3", Type: PrizeTypeIntegral, Count: 3, Price: 3, Desc: "签到奖励3积分"}, "integral_5": {Name: "签到积分x5", Type: PrizeTypeIntegral, Count: 5, Price: 5, Desc: "签到奖励5积分"}, "integral_8": {Name: "签到积分x8", Type: PrizeTypeIntegral, Count: 8, Price: 8, Desc: "签到奖励8积分"}, "integral_10": {Name: "签到积分x10", Type: PrizeTypeIntegral, Count: 10, Price: 10, Desc: "签到奖励10积分"}, "integral_12": {Name: "签到积分x12", Type: PrizeTypeIntegral, Count: 12, Price: 12, Desc: "签到奖励12积分"}, "integral_15": {Name: "签到积分x15", Type: PrizeTypeIntegral, Count: 15, Price: 15, Desc: "签到奖励15积分"}, "integral_18": {Name: "签到积分x18", Type: PrizeTypeIntegral, Count: 18, Price: 18, Desc: "签到奖励18积分"}, "integral_20": {Name: "签到积分x20", Type: PrizeTypeIntegral, Count: 20, Price: 20, Desc: "签到奖励20积分"}, "integral_25": {Name: "签到积分x25", Type: PrizeTypeIntegral, Count: 25, Price: 25, Desc: "签到奖励25积分"}, "integral_30": {Name: "签到积分x30", Type: PrizeTypeIntegral, Count: 30, Price: 30, Desc: "签到奖励30积分"}, "integral_50": {Name: "签到积分x50", Type: PrizeTypeIntegral, Count: 50, Price: 50, Desc: "签到奖励50积分"}, "integral_80": {Name: "签到积分x80", Type: PrizeTypeIntegral, Count: 80, Price: 80, Desc: "签到奖励80积分"}, "integral_100": {Name: "签到积分x100", Type: PrizeTypeIntegral, Count: 100, Price: 100, Desc: "签到奖励100积分"}, // 金币类 "gold_50": {Name: "签到金币x50", Type: PrizeTypeGold, Count: 50, Price: 50, Desc: "签到奖励50金币"}, "gold_100": {Name: "签到金币x100", Type: PrizeTypeGold, Count: 100, Price: 100, Desc: "签到奖励100金币"}, "gold_200": {Name: "签到金币x200", Type: PrizeTypeGold, Count: 200, Price: 200, Desc: "签到奖励200金币"}, "gold_500": {Name: "签到金币x500", Type: PrizeTypeGold, Count: 500, Price: 500, Desc: "签到奖励500金币"}, // 观影券 "video_coupon_1": {Name: "观影券x1", Type: PrizeTypeVideoCoupon, Count: 1, Price: 1, Desc: "签到奖励1张观影券"}, "video_coupon_2": {Name: "观影券x2", Type: PrizeTypeVideoCoupon, Count: 2, Price: 2, Desc: "签到奖励2张观影券"}, "video_coupon_3": {Name: "观影券x3", Type: PrizeTypeVideoCoupon, Count: 3, Price: 3, Desc: "签到奖励3张观影券"}, // AI "ai_undress_1": {Name: "AI脱衣x1", Type: PrizeTypeAIUndress, Count: 1, Price: 1, Desc: "签到奖励AI脱衣1次"}, "ai_undress_2": {Name: "AI脱衣x2", Type: PrizeTypeAIUndress, Count: 2, Price: 2, Desc: "签到奖励AI脱衣2次"}, "ai_changeface_1": {Name: "AI换脸x1", Type: PrizeTypeAIChangeFace, Count: 1, Price: 1, Desc: "签到奖励AI换脸1次"}, "ai_changeface_2": {Name: "AI换脸x2", Type: PrizeTypeAIChangeFace, Count: 2, Price: 2, Desc: "签到奖励AI换脸2次"}, // VIP专属奖品 "vip_integral_5": {Name: "VIP积分x5", Type: PrizeTypeIntegral, Count: 5, Price: 5, Desc: "VIP签到额外5积分"}, "vip_integral_8": {Name: "VIP积分x8", Type: PrizeTypeIntegral, Count: 8, Price: 8, Desc: "VIP签到额外8积分"}, "vip_integral_10": {Name: "VIP积分x10", Type: PrizeTypeIntegral, Count: 10, Price: 10, Desc: "VIP签到额外10积分"}, "vip_integral_15": {Name: "VIP积分x15", Type: PrizeTypeIntegral, Count: 15, Price: 15, Desc: "VIP签到额外15积分"}, "vip_integral_20": {Name: "VIP积分x20", Type: PrizeTypeIntegral, Count: 20, Price: 20, Desc: "VIP签到额外20积分"}, "vip_integral_30": {Name: "VIP积分x30", Type: PrizeTypeIntegral, Count: 30, Price: 30, Desc: "VIP签到额外30积分"}, "vip_integral_50": {Name: "VIP积分x50", Type: PrizeTypeIntegral, Count: 50, Price: 50, Desc: "VIP签到额外50积分"}, "vip_gold_100": {Name: "VIP金币x100", Type: PrizeTypeGold, Count: 100, Price: 100, Desc: "VIP签到额外100金币"}, "vip_gold_200": {Name: "VIP金币x200", Type: PrizeTypeGold, Count: 200, Price: 200, Desc: "VIP签到额外200金币"}, "vip_gold_500": {Name: "VIP金币x500", Type: PrizeTypeGold, Count: 500, Price: 500, Desc: "VIP签到额外500金币"}, "vip_video_coupon_1": {Name: "VIP观影券x1", Type: PrizeTypeVideoCoupon, Count: 1, Price: 1, Desc: "VIP签到额外1张观影券"}, "vip_video_coupon_2": {Name: "VIP观影券x2", Type: PrizeTypeVideoCoupon, Count: 2, Price: 2, Desc: "VIP签到额外2张观影券"}, "vip_ai_undress_1": {Name: "VIP AI脱衣x1", Type: PrizeTypeAIUndress, Count: 1, Price: 1, Desc: "VIP签到额外AI脱衣1次"}, "vip_ai_undress_2": {Name: "VIP AI脱衣x2", Type: PrizeTypeAIUndress, Count: 2, Price: 2, Desc: "VIP签到额外AI脱衣2次"}, "vip_ai_changeface_1": {Name: "VIP AI换脸x1", Type: PrizeTypeAIChangeFace, Count: 1, Price: 1, Desc: "VIP签到额外AI换脸1次"}, "vip_ai_changeface_2": {Name: "VIP AI换脸x2", Type: PrizeTypeAIChangeFace, Count: 2, Price: 2, Desc: "VIP签到额外AI换脸2次"}, } prizeIdMap := make(map[string]primitive.ObjectID) for key, def := range prizeDefs { doc := bson.M{ "name": def.Name, "type": def.Type, "count": def.Count, "price": def.Price, "sort": 0, "desc": def.Desc, "value": 0, "weights": "0", "level": 1, "status": true, "validityTime": 0, "image": "", "updateTime": now, "createTimt": now, } result, err := activityPrizeColl.InsertOne(ctx, doc) if err != nil { log.Printf(" [WARN] 插入 '%s' 失败: %v", key, err) continue } prizeIdMap[key] = result.InsertedID.(primitive.ObjectID) } fmt.Printf(" 共创建 %d 个 activity_prize\n\n", len(prizeIdMap)) // ======================== // Step 2: 创建 checkin_config // ======================== fmt.Println("=== Step 2: 配置 checkin_config ===") configColl := db.Collection("checkin_config") configDoc := bson.M{ "enable": true, "description": "每日签到领好礼!连续签到天数越多奖励越丰厚,第7天可获得双倍奖励!月卡VIP用户每天额外领取专属奖品。坚持签到31天有超级大礼!", "backgroundImage": "", "rewardBgVideos": []bson.M{ {"prizeType": PrizeTypeIntegral, "bgMediaUrl": ""}, {"prizeType": PrizeTypeGold, "bgMediaUrl": ""}, {"prizeType": PrizeTypeVideoCoupon, "bgMediaUrl": ""}, {"prizeType": PrizeTypeAIUndress, "bgMediaUrl": ""}, {"prizeType": PrizeTypeAIChangeFace, "bgMediaUrl": ""}, }, "integerExchangeList": []bson.M{ {"name": "月卡VIP", "icon": ""}, {"name": "观影券x10", "icon": ""}, {"name": "AI脱衣x5", "icon": ""}, {"name": "AI换脸x5", "icon": ""}, }, } configColl.InsertOne(ctx, configDoc) fmt.Println(" checkin_config 已创建(enable=true)\n") // ======================== // Step 3: 创建 checkin_prize 31天连续签到(普通 + VIP) // ======================== fmt.Println("=== Step 3: 创建 checkin_prize 31天签到奖品 ===") checkinPrizeColl := db.Collection("checkin_prize") // 31天普通奖品配置(奖励递增,每周有节奏感) normalPrizes := []checkinPrizeDef{ // 第1周:基础奖励 {Title: "第1天", CheckinDays: 1, PrizeName: "积分x3", PrizeRef: "integral_3"}, {Title: "第2天", CheckinDays: 2, PrizeName: "积分x5", PrizeRef: "integral_5"}, {Title: "第3天", CheckinDays: 3, PrizeName: "积分x5", PrizeRef: "integral_5"}, {Title: "第4天", CheckinDays: 4, PrizeName: "积分x8", PrizeRef: "integral_8"}, {Title: "第5天", CheckinDays: 5, PrizeName: "积分x8", PrizeRef: "integral_8"}, {Title: "第6天", CheckinDays: 6, PrizeName: "积分x10", PrizeRef: "integral_10"}, {Title: "第7天", CheckinDays: 7, PrizeName: "观影券x1", PrizeRef: "video_coupon_1"}, // 第2周:稳步提升 {Title: "第8天", CheckinDays: 8, PrizeName: "积分x10", PrizeRef: "integral_10"}, {Title: "第9天", CheckinDays: 9, PrizeName: "积分x10", PrizeRef: "integral_10"}, {Title: "第10天", CheckinDays: 10, PrizeName: "积分x12", PrizeRef: "integral_12"}, {Title: "第11天", CheckinDays: 11, PrizeName: "积分x12", PrizeRef: "integral_12"}, {Title: "第12天", CheckinDays: 12, PrizeName: "积分x15", PrizeRef: "integral_15"}, {Title: "第13天", CheckinDays: 13, PrizeName: "金币x50", PrizeRef: "gold_50"}, {Title: "第14天", CheckinDays: 14, PrizeName: "观影券x1", PrizeRef: "video_coupon_1"}, // 第3周:中期奖励 {Title: "第15天", CheckinDays: 15, PrizeName: "积分x15", PrizeRef: "integral_15"}, {Title: "第16天", CheckinDays: 16, PrizeName: "积分x18", PrizeRef: "integral_18"}, {Title: "第17天", CheckinDays: 17, PrizeName: "积分x18", PrizeRef: "integral_18"}, {Title: "第18天", CheckinDays: 18, PrizeName: "积分x20", PrizeRef: "integral_20"}, {Title: "第19天", CheckinDays: 19, PrizeName: "AI脱衣x1", PrizeRef: "ai_undress_1"}, {Title: "第20天", CheckinDays: 20, PrizeName: "积分x20", PrizeRef: "integral_20"}, {Title: "第21天", CheckinDays: 21, PrizeName: "金币x100", PrizeRef: "gold_100"}, // 第4周:高级奖励 {Title: "第22天", CheckinDays: 22, PrizeName: "积分x25", PrizeRef: "integral_25"}, {Title: "第23天", CheckinDays: 23, PrizeName: "积分x25", PrizeRef: "integral_25"}, {Title: "第24天", CheckinDays: 24, PrizeName: "AI换脸x1", PrizeRef: "ai_changeface_1"}, {Title: "第25天", CheckinDays: 25, PrizeName: "积分x30", PrizeRef: "integral_30"}, {Title: "第26天", CheckinDays: 26, PrizeName: "观影券x2", PrizeRef: "video_coupon_2"}, {Title: "第27天", CheckinDays: 27, PrizeName: "积分x30", PrizeRef: "integral_30"}, {Title: "第28天", CheckinDays: 28, PrizeName: "金币x200", PrizeRef: "gold_200"}, // 最后冲刺 {Title: "第29天", CheckinDays: 29, PrizeName: "积分x50", PrizeRef: "integral_50"}, {Title: "第30天", CheckinDays: 30, PrizeName: "观影券x3", PrizeRef: "video_coupon_3"}, {Title: "第31天", CheckinDays: 31, PrizeName: "积分x100", PrizeRef: "integral_100"}, } // 31天VIP专属奖品配置 vipPrizes := []checkinPrizeDef{ // 第1周 {Title: "VIP第1天", CheckinDays: 1, BigPrize: true, PrizeName: "VIP积分x5", PrizeRef: "vip_integral_5"}, {Title: "VIP第2天", CheckinDays: 2, BigPrize: true, PrizeName: "VIP积分x5", PrizeRef: "vip_integral_5"}, {Title: "VIP第3天", CheckinDays: 3, BigPrize: true, PrizeName: "VIP积分x8", PrizeRef: "vip_integral_8"}, {Title: "VIP第4天", CheckinDays: 4, BigPrize: true, PrizeName: "VIP积分x8", PrizeRef: "vip_integral_8"}, {Title: "VIP第5天", CheckinDays: 5, BigPrize: true, PrizeName: "VIP积分x10", PrizeRef: "vip_integral_10"}, {Title: "VIP第6天", CheckinDays: 6, BigPrize: true, PrizeName: "VIP积分x10", PrizeRef: "vip_integral_10"}, {Title: "VIP第7天", CheckinDays: 7, BigPrize: true, PrizeName: "VIP观影券x1", PrizeRef: "vip_video_coupon_1"}, // 第2周 {Title: "VIP第8天", CheckinDays: 8, BigPrize: true, PrizeName: "VIP积分x10", PrizeRef: "vip_integral_10"}, {Title: "VIP第9天", CheckinDays: 9, BigPrize: true, PrizeName: "VIP积分x10", PrizeRef: "vip_integral_10"}, {Title: "VIP第10天", CheckinDays: 10, BigPrize: true, PrizeName: "VIP积分x15", PrizeRef: "vip_integral_15"}, {Title: "VIP第11天", CheckinDays: 11, BigPrize: true, PrizeName: "VIP积分x15", PrizeRef: "vip_integral_15"}, {Title: "VIP第12天", CheckinDays: 12, BigPrize: true, PrizeName: "VIP金币x100", PrizeRef: "vip_gold_100"}, {Title: "VIP第13天", CheckinDays: 13, BigPrize: true, PrizeName: "VIP积分x15", PrizeRef: "vip_integral_15"}, {Title: "VIP第14天", CheckinDays: 14, BigPrize: true, PrizeName: "VIP AI脱衣x1", PrizeRef: "vip_ai_undress_1"}, // 第3周 {Title: "VIP第15天", CheckinDays: 15, BigPrize: true, PrizeName: "VIP积分x15", PrizeRef: "vip_integral_15"}, {Title: "VIP第16天", CheckinDays: 16, BigPrize: true, PrizeName: "VIP积分x20", PrizeRef: "vip_integral_20"}, {Title: "VIP第17天", CheckinDays: 17, BigPrize: true, PrizeName: "VIP积分x20", PrizeRef: "vip_integral_20"}, {Title: "VIP第18天", CheckinDays: 18, BigPrize: true, PrizeName: "VIP观影券x1", PrizeRef: "vip_video_coupon_1"}, {Title: "VIP第19天", CheckinDays: 19, BigPrize: true, PrizeName: "VIP积分x20", PrizeRef: "vip_integral_20"}, {Title: "VIP第20天", CheckinDays: 20, BigPrize: true, PrizeName: "VIP AI换脸x1", PrizeRef: "vip_ai_changeface_1"}, {Title: "VIP第21天", CheckinDays: 21, BigPrize: true, PrizeName: "VIP金币x200", PrizeRef: "vip_gold_200"}, // 第4周 {Title: "VIP第22天", CheckinDays: 22, BigPrize: true, PrizeName: "VIP积分x20", PrizeRef: "vip_integral_20"}, {Title: "VIP第23天", CheckinDays: 23, BigPrize: true, PrizeName: "VIP积分x30", PrizeRef: "vip_integral_30"}, {Title: "VIP第24天", CheckinDays: 24, BigPrize: true, PrizeName: "VIP AI脱衣x2", PrizeRef: "vip_ai_undress_2"}, {Title: "VIP第25天", CheckinDays: 25, BigPrize: true, PrizeName: "VIP积分x30", PrizeRef: "vip_integral_30"}, {Title: "VIP第26天", CheckinDays: 26, BigPrize: true, PrizeName: "VIP观影券x2", PrizeRef: "vip_video_coupon_2"}, {Title: "VIP第27天", CheckinDays: 27, BigPrize: true, PrizeName: "VIP积分x30", PrizeRef: "vip_integral_30"}, {Title: "VIP第28天", CheckinDays: 28, BigPrize: true, PrizeName: "VIP金币x500", PrizeRef: "vip_gold_500"}, // 最后冲刺 {Title: "VIP第29天", CheckinDays: 29, BigPrize: true, PrizeName: "VIP积分x50", PrizeRef: "vip_integral_50"}, {Title: "VIP第30天", CheckinDays: 30, BigPrize: true, PrizeName: "VIP AI换脸x2", PrizeRef: "vip_ai_changeface_2"}, {Title: "VIP第31天", CheckinDays: 31, BigPrize: true, PrizeName: "VIP积分x50", PrizeRef: "vip_integral_50"}, } allCheckinPrizes := append(normalPrizes, vipPrizes...) insertedCount := 0 for _, cp := range allCheckinPrizes { prizeId, ok := prizeIdMap[cp.PrizeRef] if !ok { log.Printf(" [WARN] 找不到奖品引用 '%s',跳过", cp.PrizeRef) continue } doc := bson.M{ "title": cp.Title, "image": "", "checkinDays": cp.CheckinDays, "checkinType": int64(CheckinTypeContinuously), "prizeId": prizeId, "prizeName": cp.PrizeName, "status": true, "bigPrize": cp.BigPrize, "createdAt": now, "updatedAt": now, } _, err := checkinPrizeColl.InsertOne(ctx, doc) if err != nil { log.Printf(" [WARN] 插入 '%s' 失败: %v", cp.Title, err) continue } tag := "" if cp.BigPrize { tag = " [VIP]" } fmt.Printf(" Day%-2d %-16s => activity_prize(%s)%s\n", cp.CheckinDays, cp.PrizeName, prizeId.Hex(), tag) insertedCount++ } fmt.Printf(" 共创建 %d 个 checkin_prize(普通%d + VIP%d)\n\n", insertedCount, len(normalPrizes), len(vipPrizes)) // ======================== // Step 4: 生成测试用户签到记录 // ======================== fmt.Println("=== Step 4: 生成测试用户签到记录 ===") // ====== 在这里修改参数 ====== userIds := []uint64{300001} n := 6 // 生成6天签到记录,今天签到为第7天(触发双倍奖励) // =========================== SeedCheckin(ctx, db, userIds, n) fmt.Println("\n=== 全部配置完成 ===") fmt.Println("数据关联关系:") fmt.Println(" checkin_config (enable=true)") fmt.Println(" checkin_prize (31天普通 + 31天VIP) --[prizeId]--> activity_prize") fmt.Println(" user_checkin --[prizes]--> checkin_prize._id") fmt.Printf(" 测试用户: %v (已签到%d天,今天第%d天)\n", userIds, n, n+1) } // SeedCheckin 为指定用户生成N天连续签到数据 func SeedCheckin(ctx context.Context, db *mongo.Database, userIds []uint64, n int) { 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) // 查奖励配置(非大奖) cursor, err := prizeColl.Find(ctx, bson.M{ "status": true, "checkinType": int64(1), }, options.Find().SetSort(bson.M{"checkinDays": 1})) if err != nil { log.Printf(" query prizes failed: %v", err) return } var prizeConfigs []bson.M if err := cursor.All(ctx, &prizeConfigs); err != nil { log.Printf(" decode prizes failed: %v", err) return } 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) } } } delResult, err := checkinColl.DeleteMany(ctx, bson.M{ "userId": bson.M{"$in": userIds}, }) if err != nil { log.Printf(" delete failed: %v", err) return } fmt.Printf(" Deleted %d existing records\n", delResult.DeletedCount) 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"), continuouslyDays, prizes) } } } 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 } }