294 lines
22 KiB
TypeScript
294 lines
22 KiB
TypeScript
/**
|
||
* 玩值电竞 - MongoDB 建库 + 索引 + 种子数据
|
||
* 执行:pnpm db:mongo:seed(会读取项目根目录 .env.local 中的 MONGODB_URI)
|
||
*/
|
||
|
||
import { config } from "dotenv"
|
||
import { resolve } from "path"
|
||
|
||
config({ path: resolve(process.cwd(), ".env.local") })
|
||
|
||
import { ObjectId } from "mongodb"
|
||
import { getDb, closeMongo } from "../../mongodb/client"
|
||
import { COLLECTIONS, INDEX_SPECS } from "./collections"
|
||
import { ensureCollections } from "./ensure-indexes"
|
||
import { LYTIAO_STREAMERS, LYTIAO_SOURCE } from "../../data/lytiao-streamers"
|
||
import { hashPassword } from "../../auth-utils"
|
||
|
||
const now = () => new Date().toISOString()
|
||
|
||
async function ensureIndexes() {
|
||
const db = await getDb()
|
||
for (const [name, specs] of Object.entries(INDEX_SPECS)) {
|
||
const coll = db.collection(name)
|
||
if (specs.length > 0) {
|
||
try {
|
||
await coll.createIndexes(specs)
|
||
} catch (e: unknown) {
|
||
const err = e as { code?: number }
|
||
if (err.code !== 85 && err.code !== 86) throw e
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
async function seed() {
|
||
const db = await getDb()
|
||
const gamesColl = db.collection(COLLECTIONS.games)
|
||
const usersColl = db.collection(COLLECTIONS.users)
|
||
const streamersColl = db.collection(COLLECTIONS.streamers)
|
||
|
||
// 1. 游戏(仅当无数据时写入)
|
||
const gamesCount = await gamesColl.countDocuments()
|
||
if (gamesCount === 0) {
|
||
const games = [
|
||
{ name: "王者荣耀", shortName: "wzry", logo: "/wzry.jpg", coverImage: "/wzry-cover.jpg", category: "moba", platform: ["mobile"], publisher: "腾讯", isHot: true, sortOrder: 1, status: "active", createdAt: now() },
|
||
{ name: "英雄联盟", shortName: "lol", logo: "/lol.jpg", coverImage: "/lol-cover.jpg", category: "moba", platform: ["pc"], publisher: "腾讯", isHot: true, sortOrder: 2, status: "active", createdAt: now() },
|
||
{ name: "和平精英", shortName: "pubgm", logo: "/pubgm.jpg", coverImage: "/pubgm-cover.jpg", category: "fps", platform: ["mobile"], publisher: "腾讯", isHot: true, sortOrder: 3, status: "active", createdAt: now() },
|
||
{ name: "原神", shortName: "ys", logo: "/ys.jpg", coverImage: "/ys-cover.jpg", category: "mmorpg", platform: ["pc", "mobile"], publisher: "米哈游", isHot: true, sortOrder: 4, status: "active", createdAt: now() },
|
||
{ name: "无畏契约", shortName: "valorant", logo: "/valorant.jpg", coverImage: "/valorant-cover.jpg", category: "fps", platform: ["pc"], publisher: "拳头", isHot: true, sortOrder: 5, status: "active", createdAt: now() },
|
||
{ name: "穿越火线", shortName: "cf", logo: "/cf.jpg", coverImage: "/cf-cover.jpg", category: "fps", platform: ["pc", "mobile"], publisher: "腾讯", isHot: false, sortOrder: 6, status: "active", createdAt: now() },
|
||
{ name: "梦幻西游", shortName: "mhxy", logo: "/mhxy.jpg", coverImage: "/mhxy-cover.jpg", category: "mmorpg", platform: ["pc", "mobile"], publisher: "网易", isHot: false, sortOrder: 7, status: "active", createdAt: now() },
|
||
{ name: "三角洲行动", shortName: "delta", logo: "/delta.jpg", coverImage: "/delta-cover.jpg", category: "fps", platform: ["pc", "mobile"], publisher: "腾讯", isHot: true, sortOrder: 8, status: "active", createdAt: now() },
|
||
{ name: "魔兽世界", shortName: "wow", logo: "/wow.jpg", coverImage: "/wow-cover.jpg", category: "mmorpg", platform: ["pc"], publisher: "暴雪", isHot: false, sortOrder: 9, status: "active", createdAt: now() },
|
||
]
|
||
await gamesColl.insertMany(games)
|
||
console.log("[Mongo] games:", games.length)
|
||
} else {
|
||
console.log("[Mongo] games 已有数据,跳过")
|
||
}
|
||
|
||
// 2. 用户(仅当无用户时写入默认用户)
|
||
const usersCount = await usersColl.countDocuments()
|
||
let userId: import("mongodb").ObjectId
|
||
if (usersCount === 0) {
|
||
const defaultUser = {
|
||
odlId: "888888",
|
||
phone: "13800138000",
|
||
name: "卡若",
|
||
avatar: "/gamer-boy-esports-jersey.jpg",
|
||
level: 12,
|
||
experience: 2450,
|
||
isVip: false,
|
||
gender: "male",
|
||
tags: ["英雄联盟", "王者荣耀"],
|
||
activity: 128,
|
||
following: 45,
|
||
followers: 892,
|
||
visitors: 1205,
|
||
balance: 6880,
|
||
totalRecharge: 10000,
|
||
totalSpent: 3120,
|
||
registerSource: "app",
|
||
registerTime: "2023-01-15",
|
||
lastLoginTime: now(),
|
||
status: "active",
|
||
createdAt: "2023-01-15",
|
||
updatedAt: now(),
|
||
}
|
||
const userRes = await usersColl.insertOne(defaultUser)
|
||
userId = userRes.insertedId
|
||
console.log("[Mongo] users: 1 (default)")
|
||
} else {
|
||
const first = await usersColl.findOne({})
|
||
if (!first || !(first as { _id?: unknown })._id) throw new Error("users 集合为空,请先执行全量种子")
|
||
userId = (first as { _id: import("mongodb").ObjectId })._id
|
||
console.log("[Mongo] users 已有数据,跳过")
|
||
}
|
||
|
||
// 2b. 管理端账号 admin / k123456(仅当无管理员时写入)
|
||
const adminsColl = db.collection(COLLECTIONS.admins)
|
||
const adminsCount = await adminsColl.countDocuments()
|
||
if (adminsCount === 0) {
|
||
await adminsColl.insertOne({
|
||
username: "admin",
|
||
passwordHash: hashPassword("k123456"),
|
||
createdAt: new Date(),
|
||
updatedAt: new Date(),
|
||
})
|
||
console.log("[Mongo] admins: 1 (admin)")
|
||
}
|
||
|
||
// 2c. 前端测试账号 15880802661 卡若 k123456(仅当该手机号未注册时写入)
|
||
const authsColl = db.collection(COLLECTIONS.userAuths)
|
||
const hasKaruo = await authsColl.findOne({ authType: "phone", authId: "15880802661" })
|
||
if (!hasKaruo) {
|
||
const karuoId = new ObjectId()
|
||
await usersColl.insertOne({
|
||
_id: karuoId,
|
||
name: "卡若",
|
||
phone: "15880802661",
|
||
avatar: "",
|
||
level: 1,
|
||
balance: 0,
|
||
status: "active",
|
||
createdAt: new Date(),
|
||
updatedAt: new Date(),
|
||
})
|
||
await authsColl.insertOne({
|
||
userId: karuoId,
|
||
authType: "phone",
|
||
authId: "15880802661",
|
||
credential: hashPassword("k123456"),
|
||
createdAt: new Date(),
|
||
updatedAt: new Date(),
|
||
})
|
||
console.log("[Mongo] 测试用户: 15880802661 卡若")
|
||
}
|
||
|
||
// 3. 主播:默认 6 条(仅当无主播时写入);老游条导师(按 source+name 去重补充)
|
||
const streamersCount = await streamersColl.countDocuments()
|
||
if (streamersCount === 0) {
|
||
const streamers = [
|
||
{ userId: userId.toString(), name: "GM-远洋", avatar: "/streamer-1.jpg", coverImage: "/lol-stream.jpg", title: "国服第一盲僧", game: "英雄联盟", gameId: 2, tags: ["打野", "教学"], level: 28, fans: 1256000, hotValue: 125.6, isLive: true, totalGifts: 89000, totalIncome: 156000, commissionRate: 0.7, status: "approved", verifiedAt: "2023-02-01", createdAt: "2023-01-20", updatedAt: now() },
|
||
{ userId: userId.toString(), name: "小狐狸", avatar: "/streamer-2.jpg", coverImage: "/valorant-stream.jpg", title: "无畏契约电竞女神", game: "无畏契约", gameId: 5, tags: ["竞技", "颜值"], level: 25, fans: 856000, hotValue: 89.2, isLive: true, totalGifts: 67000, totalIncome: 98000, commissionRate: 0.7, status: "approved", verifiedAt: "2023-03-01", createdAt: "2023-02-15", updatedAt: now() },
|
||
{ userId: userId.toString(), name: "王者阿杰", avatar: "/streamer-3.jpg", coverImage: "/wzry-stream.jpg", title: "国服最强边路", game: "王者荣耀", gameId: 1, tags: ["边路", "上分"], level: 30, fans: 2100000, hotValue: 168.5, isLive: false, totalGifts: 125000, totalIncome: 230000, commissionRate: 0.75, status: "approved", verifiedAt: "2023-01-10", createdAt: "2022-12-01", updatedAt: now() },
|
||
{ userId: userId.toString(), name: "原神小可爱", avatar: "/streamer-4.jpg", coverImage: "/ys-stream.jpg", title: "深渊满星攻略", game: "原神", gameId: 4, tags: ["攻略", "抽卡"], level: 22, fans: 568000, hotValue: 56.8, isLive: true, totalGifts: 45000, totalIncome: 78000, commissionRate: 0.65, status: "approved", verifiedAt: "2023-04-01", createdAt: "2023-03-10", updatedAt: now() },
|
||
{ userId: userId.toString(), name: "吃鸡大魔王", avatar: "/streamer-5.jpg", coverImage: "/pubgm-stream.jpg", title: "单排上分王", game: "和平精英", gameId: 3, tags: ["吃鸡", "技巧"], level: 26, fans: 980000, hotValue: 98.0, isLive: true, totalGifts: 72000, totalIncome: 135000, commissionRate: 0.7, status: "approved", verifiedAt: "2023-02-15", createdAt: "2023-01-25", updatedAt: now() },
|
||
{ userId: userId.toString(), name: "魔兽老玩家", avatar: "/streamer-6.jpg", coverImage: "/wow-stream.jpg", title: "怀旧服金团领队", game: "魔兽世界", gameId: 9, tags: ["怀旧", "金团"], level: 20, fans: 320000, hotValue: 32.5, isLive: false, totalGifts: 28000, totalIncome: 52000, commissionRate: 0.65, status: "approved", verifiedAt: "2023-05-01", createdAt: "2023-04-20", updatedAt: now() },
|
||
]
|
||
await streamersColl.insertMany(streamers)
|
||
console.log("[Mongo] streamers (默认):", streamers.length)
|
||
} else {
|
||
console.log("[Mongo] streamers 已有数据,仅补充老游条")
|
||
}
|
||
// 老游条导师:按 source+name 去重,不存在则插入
|
||
let lytiaoInserted = 0
|
||
for (const s of LYTIAO_STREAMERS) {
|
||
const exists = await streamersColl.findOne({ source: LYTIAO_SOURCE, name: s.name })
|
||
if (exists) continue
|
||
const fans = s.douyuFans ?? s.douyinFans ?? 0
|
||
const avatar = s.avatar || `/streamers/lytiao/${s.name.replace(/[丶\u3000]/g, "").trim()}.jpg`
|
||
await streamersColl.insertOne({
|
||
userId: userId.toString(),
|
||
name: s.name,
|
||
title: s.title,
|
||
intro: s.intro,
|
||
game: s.game,
|
||
gameId: s.gameId,
|
||
tags: s.tags,
|
||
avatar,
|
||
coverImage: s.coverImage || "",
|
||
level: 20,
|
||
fans: Math.max(0, fans),
|
||
douyuFans: s.douyuFans ?? undefined,
|
||
douyinFans: s.douyinFans ?? undefined,
|
||
hotValue: 0,
|
||
isLive: false,
|
||
totalGifts: 0,
|
||
totalIncome: 0,
|
||
commissionRate: 0.7,
|
||
status: "approved",
|
||
verifiedAt: now(),
|
||
source: LYTIAO_SOURCE,
|
||
city: s.city ?? "深圳",
|
||
createdAt: now(),
|
||
updatedAt: now(),
|
||
})
|
||
lytiaoInserted++
|
||
}
|
||
if (lytiaoInserted > 0) console.log("[Mongo] 老游条主播 新增:", lytiaoInserted)
|
||
|
||
// 以下仅在全量种子时写入(即 games 原本为空时)
|
||
if (gamesCount > 0) {
|
||
console.log("[Mongo] 其余种子(明星/公会等)已有数据,跳过")
|
||
return
|
||
}
|
||
|
||
// 4. 明星
|
||
const starsColl = db.collection(COLLECTIONS.stars)
|
||
const stars = [
|
||
{ userId: userId.toString(), name: "Faker", avatar: "/star-faker.jpg", coverImage: "/star-faker-cover.jpg", title: "LOL传奇中单", game: "英雄联盟", gameId: 2, tags: ["世界冠军", "中单"], fans: 46800000, hotValue: 468.0, achievements: ["三冠王", "S赛MVP"], teamName: "T1", socialLinks: { weibo: "faker_lol" }, partyRoomId: "faker-party", hourlyRate: 9999, isOnline: true, status: "active", verifiedAt: "2022-01-01", createdAt: "2022-01-01", updatedAt: now() },
|
||
{ userId: userId.toString(), name: "Uzi", avatar: "/star-uzi.jpg", coverImage: "/star-uzi-cover.jpg", title: "永远的神", game: "英雄联盟", gameId: 2, tags: ["ADC", "传奇"], fans: 38500000, hotValue: 385.0, achievements: ["MSI冠军", "LPL冠军"], teamName: "RNG", socialLinks: { weibo: "uzi_lol", douyin: "uzi" }, partyRoomId: "uzi-party", hourlyRate: 8888, isOnline: false, status: "active", verifiedAt: "2022-01-01", createdAt: "2022-01-01", updatedAt: now() },
|
||
{ userId: userId.toString(), name: "梦泪", avatar: "/star-menglei.jpg", coverImage: "/star-menglei-cover.jpg", title: "国服第一韩信", game: "王者荣耀", gameId: 1, tags: ["韩信", "打野"], fans: 52000000, hotValue: 520.0, achievements: ["KPL冠军", "最佳打野"], teamName: "AG超玩会", socialLinks: { douyin: "menglei" }, partyRoomId: "menglei-party", hourlyRate: 6666, isOnline: true, status: "active", verifiedAt: "2022-06-01", createdAt: "2022-06-01", updatedAt: now() },
|
||
{ userId: userId.toString(), name: "不求人", avatar: "/star-buqiuren.jpg", coverImage: "/star-buqiuren-cover.jpg", title: "和平精英一哥", game: "和平精英", gameId: 3, tags: ["吃鸡", "主播"], fans: 41000000, hotValue: 410.0, achievements: ["PEL冠军", "全明星MVP"], socialLinks: { douyin: "buqiuren" }, partyRoomId: "buqiuren-party", hourlyRate: 5888, isOnline: true, status: "active", verifiedAt: "2022-03-01", createdAt: "2022-03-01", updatedAt: now() },
|
||
]
|
||
await starsColl.insertMany(stars)
|
||
console.log("[Mongo] stars:", stars.length)
|
||
|
||
// 4.1 派对群(与明星关联,基础数据)
|
||
const firstStar = await starsColl.findOne({})
|
||
const firstStarId = firstStar ? (firstStar as { _id: import("mongodb").ObjectId })._id.toString() : ""
|
||
const partyRoomsColl = db.collection(COLLECTIONS.starPartyRooms)
|
||
const partyRoomsCount = await partyRoomsColl.countDocuments()
|
||
if (partyRoomsCount === 0 && firstStarId) {
|
||
const partyRooms = [
|
||
{ starId: firstStarId, name: "Faker 粉丝派对", coverImage: "/party-lol.jpg", memberCount: 12, maxMembers: 50, entryFee: 0, description: "与 Faker 一起开黑", rules: ["文明发言"], isActive: true, createdAt: now(), updatedAt: now() },
|
||
{ starId: firstStarId, name: "梦泪车队派对", coverImage: "/party-hok.jpg", memberCount: 8, maxMembers: 30, entryFee: 9, description: "带粉上分", rules: [], isActive: true, createdAt: now(), updatedAt: now() },
|
||
]
|
||
await partyRoomsColl.insertMany(partyRooms)
|
||
console.log("[Mongo] starPartyRooms:", partyRooms.length)
|
||
}
|
||
|
||
// 5. 公会(含玩值电竞、丸子公会)
|
||
const guildsColl = db.collection(COLLECTIONS.guilds)
|
||
const guilds = [
|
||
{ name: "玩值电竞", logo: "", coverImage: "", description: "玩值电竞官方公会", ownerId: userId.toString(), memberCount: 0, maxMembers: 5000, level: 10, totalIncome: 0, commissionRate: 0.1, tags: ["官方", "电竞"], games: ["魔兽世界", "英雄联盟", "王者荣耀"], requirements: "", benefits: ["流量扶持", "课程分成"], status: "active", createdAt: "2022-01-01", updatedAt: now() },
|
||
{ name: "丸子公会", logo: "", coverImage: "", description: "丸子公会,星探与主播培养", ownerId: userId.toString(), memberCount: 0, maxMembers: 5000, level: 10, totalIncome: 0, commissionRate: 0.1, tags: ["公会", "主播"], games: ["英雄联盟", "王者荣耀"], requirements: "", benefits: ["流量扶持"], status: "active", createdAt: "2022-06-01", updatedAt: now() },
|
||
{ name: "星耀电竞", logo: "/guild-xingyao.jpg", coverImage: "/guild-xingyao-cover.jpg", description: "顶级电竞公会", ownerId: userId.toString(), memberCount: 1280, maxMembers: 2000, level: 8, totalIncome: 2580000, commissionRate: 0.1, tags: ["职业", "培训"], games: ["英雄联盟", "王者荣耀"], requirements: "段位王者以上", benefits: ["签约底薪", "流量扶持"], status: "active", createdAt: "2022-01-01", updatedAt: now() },
|
||
{ name: "凤凰涅槃", logo: "/guild-fenghuang.jpg", coverImage: "/guild-fenghuang-cover.jpg", description: "女主播孵化基地", ownerId: userId.toString(), memberCount: 860, maxMembers: 1500, level: 6, totalIncome: 1680000, commissionRate: 0.12, tags: ["颜值", "才艺"], games: ["王者荣耀", "和平精英"], requirements: "颜值在线", benefits: ["形象包装", "运营指导"], status: "active", createdAt: "2022-06-01", updatedAt: now() },
|
||
{ name: "暗影战队", logo: "/guild-anying.jpg", coverImage: "/guild-anying-cover.jpg", description: "FPS游戏专业公会", ownerId: userId.toString(), memberCount: 520, maxMembers: 1000, level: 5, totalIncome: 980000, commissionRate: 0.1, tags: ["FPS", "硬核"], games: ["和平精英", "无畏契约"], requirements: "FPS高段位", benefits: ["战队训练", "比赛机会"], status: "active", createdAt: "2023-01-01", updatedAt: now() },
|
||
]
|
||
await guildsColl.insertMany(guilds)
|
||
console.log("[Mongo] guilds:", guilds.length)
|
||
|
||
// 6. CP/陪练
|
||
const companionsColl = db.collection(COLLECTIONS.companions)
|
||
const companions = [
|
||
{ userId: userId.toString(), name: "甜心小姐姐", avatar: "/cp-avatar-1.jpg", coverImage: "/cp-cover-1.jpg", gender: "female", age: 22, tags: ["甜美", "温柔"], games: ["王者荣耀", "和平精英"], bio: "声音甜美,陪你上分~", price: 30, originalPrice: 50, rating: 4.9, ordersCount: 1256, responseRate: 98, onlineStatus: "online", category: "cp", commissionRate: 0.3, status: "active", createdAt: "2023-01-01", updatedAt: now() },
|
||
{ userId: userId.toString(), name: "电竞小王子", avatar: "/cp-avatar-2.jpg", coverImage: "/cp-cover-2.jpg", gender: "male", age: 24, tags: ["阳光", "幽默"], games: ["英雄联盟", "无畏契约"], bio: "王者段位,带你上分", price: 35, originalPrice: 60, rating: 4.8, ordersCount: 986, responseRate: 95, onlineStatus: "online", category: "cp", commissionRate: 0.3, status: "active", createdAt: "2023-02-01", updatedAt: now() },
|
||
{ userId: userId.toString(), name: "职业选手小明", avatar: "/coach-avatar-1.jpg", coverImage: "/coach-cover-1.jpg", gender: "male", age: 26, tags: ["职业", "教学"], games: ["英雄联盟"], voiceSample: "/voice-sample-1.mp3", bio: "前职业选手,专业教学", price: 100, originalPrice: 150, rating: 4.95, ordersCount: 568, responseRate: 99, onlineStatus: "online", category: "coach", coachType: "pro", rank: "王者", commissionRate: 0.25, status: "active", createdAt: "2023-01-15", updatedAt: now() },
|
||
{ userId: userId.toString(), name: "王者大神", avatar: "/coach-avatar-2.jpg", coverImage: "/coach-cover-2.jpg", gender: "male", age: 23, tags: ["上分", "技术流"], games: ["王者荣耀"], bio: "国服百星", price: 80, originalPrice: 120, rating: 4.88, ordersCount: 892, responseRate: 97, onlineStatus: "busy", category: "coach", coachType: "master", rank: "荣耀王者100星", commissionRate: 0.25, status: "active", createdAt: "2023-03-01", updatedAt: now() },
|
||
]
|
||
await companionsColl.insertMany(companions)
|
||
console.log("[Mongo] companions:", companions.length)
|
||
|
||
// 7. 电竞酒店/网咖
|
||
const venuesColl = db.collection(COLLECTIONS.esportsVenues)
|
||
const venues = [
|
||
{ name: "玩值电竞酒店(旗舰店)", type: "hotel", logo: "/hotel-logo-1.jpg", images: ["/hotel-1.jpg"], description: "五星级电竞酒店", address: "厦门市思明区软件园二期", city: "厦门", district: "思明区", latitude: 24.4798, longitude: 118.0894, phone: "0592-12345678", rating: 4.9, reviewCount: 1256, pricePerNight: 399, facilities: ["RTX4090", "电竞椅", "144Hz显示器"], tags: ["热门", "高端"], openTime: "00:00", closeTime: "24:00", isOpen24Hours: true, status: "active", createdAt: "2022-01-01", updatedAt: now() },
|
||
{ name: "极客空间电竞公寓", type: "hotel", logo: "/hotel-logo-2.jpg", images: ["/hotel-2.jpg"], description: "年轻人的电竞乐园", address: "厦门市湖里区五缘湾", city: "厦门", district: "湖里区", latitude: 24.5102, longitude: 118.1456, phone: "0592-23456789", rating: 4.7, reviewCount: 896, pricePerNight: 299, facilities: ["RTX3080", "电竞椅"], tags: ["性价比"], openTime: "00:00", closeTime: "24:00", isOpen24Hours: true, status: "active", createdAt: "2022-06-01", updatedAt: now() },
|
||
{ name: "网鱼网咖(万达店)", type: "cafe", logo: "/cafe-logo-1.jpg", images: ["/cafe-1.jpg"], description: "专业电竞网咖", address: "厦门市思明区万达广场", city: "厦门", district: "思明区", latitude: 24.4656, longitude: 118.1023, phone: "0592-34567890", rating: 4.8, reviewCount: 2356, pricePerHour: 12, facilities: ["3080显卡", "特权公馆"], tags: ["连锁", "环境好"], openTime: "00:00", closeTime: "24:00", isOpen24Hours: true, status: "active", createdAt: "2021-01-01", updatedAt: now() },
|
||
{ name: "杰拉电竞馆", type: "cafe", logo: "/cafe-logo-2.jpg", images: ["/cafe-2.jpg"], description: "赛事级电竞馆", address: "厦门市集美区银泰城", city: "厦门", district: "集美区", latitude: 24.5789, longitude: 118.0956, phone: "0592-45678901", rating: 4.6, reviewCount: 1568, pricePerHour: 10, facilities: ["赛事级配置", "独立包间"], tags: ["比赛场地"], openTime: "09:00", closeTime: "02:00", isOpen24Hours: false, status: "active", createdAt: "2022-03-01", updatedAt: now() },
|
||
]
|
||
await venuesColl.insertMany(venues)
|
||
console.log("[Mongo] esportsVenues:", venues.length)
|
||
|
||
// 8. 商品
|
||
const productsColl = db.collection(COLLECTIONS.products)
|
||
const products = [
|
||
{ name: "王者荣耀皮肤礼包", description: "稀有皮肤随机礼包", image: "/product-skin-1.jpg", images: ["/product-skin-1.jpg"], category: "skin", game: "王者荣耀", price: 199, originalPrice: 299, stock: 1000, sales: 5680, rating: 4.8, tags: ["热销", "限定"], status: "active", createdAt: "2023-01-01", updatedAt: now() },
|
||
{ name: "电竞机械键盘", description: "青轴机械键盘,RGB背光", image: "/product-keyboard.jpg", images: ["/product-keyboard.jpg"], category: "peripheral", price: 299, originalPrice: 399, stock: 500, sales: 2356, rating: 4.9, tags: ["外设", "推荐"], status: "active", createdAt: "2023-02-01", updatedAt: now() },
|
||
{ name: "游戏鼠标垫", description: "超大电竞鼠标垫", image: "/product-mousepad.jpg", images: ["/product-mousepad.jpg"], category: "peripheral", price: 59, originalPrice: 99, stock: 2000, sales: 8956, rating: 4.7, tags: ["热销"], status: "active", createdAt: "2023-03-01", updatedAt: now() },
|
||
]
|
||
await productsColl.insertMany(products)
|
||
console.log("[Mongo] products:", products.length)
|
||
|
||
// 9. 游戏点卡
|
||
const pointCardsColl = db.collection(COLLECTIONS.gamePointCards)
|
||
const pointCards = [
|
||
{ game: "王者荣耀", gameId: 1, gameLogo: "/wzry.jpg", name: "点券充值", description: "官方点券直充", faceValue: 100, price: 98, discount: 0.98, stock: 9999, sales: 12568, deliveryType: "instant", instructions: "请提供游戏账号", status: "active", createdAt: "2023-01-01" },
|
||
{ game: "英雄联盟", gameId: 2, gameLogo: "/lol.jpg", name: "点券充值", description: "官方点券直充", faceValue: 100, price: 97, discount: 0.97, stock: 9999, sales: 9856, deliveryType: "instant", instructions: "请提供游戏账号", status: "active", createdAt: "2023-01-01" },
|
||
{ game: "原神", gameId: 4, gameLogo: "/ys.jpg", name: "创世结晶", description: "官方充值", faceValue: 648, price: 628, discount: 0.97, stock: 9999, sales: 15689, deliveryType: "instant", instructions: "请提供UID", status: "active", createdAt: "2023-01-01" },
|
||
]
|
||
await pointCardsColl.insertMany(pointCards)
|
||
console.log("[Mongo] gamePointCards:", pointCards.length)
|
||
|
||
console.log("[Mongo] 种子数据写入完成")
|
||
}
|
||
|
||
async function main() {
|
||
try {
|
||
await ensureCollections()
|
||
await ensureIndexes()
|
||
await seed()
|
||
} finally {
|
||
await closeMongo()
|
||
}
|
||
}
|
||
|
||
main().catch((e) => {
|
||
console.error(e)
|
||
process.exit(1)
|
||
})
|