Files
wzdj/lib/db/schema.ts
v0 ecae8fcef8 Add new files
#VERCEL_SKIP

Co-authored-by: undefined <undefined+undefined@users.noreply.github.com>
2026-01-04 05:02:13 +00:00

882 lines
20 KiB
TypeScript

// 玩值电竞 - 完整数据库模式定义
// 使用 Dexie.js (IndexedDB) 作为本地数据库
import Dexie, { type Table } from "dexie"
// ==================== 用户相关 ====================
export interface User {
id?: number
odlId: string // 旧版用户ID兼容
phone: string
password?: string // 加密存储
name: string
avatar: string
level: number
experience: number
isVip: boolean
vipType?: "month" | "quarter" | "year"
vipExpiry?: string
gender: "male" | "female" | "unknown"
birthday?: string
bio?: string
tags: string[]
activity: number
following: number
followers: number
visitors: number
balance: number // 玩值币余额
totalRecharge: number // 总充值金额
totalSpent: number // 总消费金额
inviteCode?: string
invitedBy?: string
registerSource: string
registerTime: string
lastLoginTime: string
status: "active" | "banned" | "deleted"
createdAt: string
updatedAt: string
}
export interface UserAuth {
id?: number
userId: number
authType: "phone" | "wechat" | "qq" | "weibo"
authId: string // 第三方ID或手机号
accessToken?: string
refreshToken?: string
expiresAt?: string
createdAt: string
}
export interface UserFollow {
id?: number
userId: number
followUserId: number
followType: "user" | "streamer" | "star"
createdAt: string
}
// ==================== 主播相关 ====================
export interface Streamer {
id?: number
userId: number // 关联用户
name: string
avatar: string
coverImage: string
title: string
game: string
gameId: number
tags: string[]
level: number
fans: number
hotValue: number // 热度值
isLive: boolean
liveRoomId?: string
totalGifts: number
totalIncome: number
guildId?: number // 所属公会
commissionRate: number // 佣金比例
status: "pending" | "approved" | "rejected" | "suspended"
verifiedAt?: string
createdAt: string
updatedAt: string
}
export interface StreamerCourse {
id?: number
streamerId: number
title: string
description: string
coverImage: string
price: number
originalPrice: number
duration: number // 总时长(分钟)
lessonsCount: number
studentsCount: number
rating: number
game: string
category: string
tags: string[]
lessons: CourseLesson[]
status: "draft" | "published" | "offline"
createdAt: string
updatedAt: string
}
export interface CourseLesson {
id: number
title: string
duration: number // 分钟
isFree: boolean
videoUrl?: string
order: number
}
export interface CoursePurchase {
id?: number
userId: number
courseId: number
streamerId: number
price: number
progress: number // 学习进度百分比
lastWatchedLesson?: number
purchasedAt: string
completedAt?: string
}
// ==================== 公会/俱乐部 ====================
export interface Guild {
id?: number
name: string
logo: string
coverImage: string
description: string
ownerId: number
memberCount: number
maxMembers: number
level: number
totalIncome: number
commissionRate: number // 平台抽成比例
tags: string[]
games: string[]
requirements: string
benefits: string[]
status: "active" | "suspended" | "dissolved"
createdAt: string
updatedAt: string
}
export interface GuildMember {
id?: number
guildId: number
userId: number
role: "owner" | "admin" | "member"
contribution: number // 贡献值
monthlyIncome: number
joinedAt: string
status: "active" | "left" | "kicked"
}
export interface GuildApplication {
id?: number
guildId: number
userId: number
message: string
status: "pending" | "approved" | "rejected"
reviewedBy?: number
reviewedAt?: string
createdAt: string
}
// ==================== 明星/大神 ====================
export interface Star {
id?: number
userId: number
name: string
avatar: string
coverImage: string
title: string
game: string
gameId: number
tags: string[]
fans: number
hotValue: number // 热度值(万)
achievements: string[]
teamName?: string
socialLinks: {
weibo?: string
douyin?: string
bilibili?: string
}
partyRoomId?: string // 派对群ID
hourlyRate: number // 每小时价格
isOnline: boolean
status: "active" | "suspended"
verifiedAt: string
createdAt: string
updatedAt: string
}
export interface StarPartyRoom {
id?: number
starId: number
name: string
memberCount: number
maxMembers: number
entryFee: number
description: string
rules: string[]
isActive: boolean
createdAt: string
}
export interface StarPartyMember {
id?: number
partyRoomId: number
userId: number
role: "host" | "vip" | "member"
joinedAt: string
expiredAt?: string
}
// ==================== CP/陪练 ====================
export interface Companion {
id?: number
userId: number
name: string
avatar: string
coverImage: string
gender: "male" | "female"
age: number
tags: string[]
games: string[]
voiceSample?: string
bio: string
price: number // 每小时价格
originalPrice: number
rating: number
ordersCount: number
responseRate: number
onlineStatus: "online" | "busy" | "offline"
category: "cp" | "coach" // CP或陪练
coachType?: "pro" | "master" // 职业选手/王者大神
rank?: string // 游戏段位
guildId?: number
commissionRate: number
status: "active" | "suspended" | "reviewing"
createdAt: string
updatedAt: string
}
export interface CompanionOrder {
id?: number
orderNo: string
userId: number
companionId: number
type: "cp" | "coach"
game: string
hours: number
price: number
totalAmount: number
message?: string
status: "pending" | "accepted" | "in_progress" | "completed" | "cancelled" | "refunded"
startTime?: string
endTime?: string
rating?: number
review?: string
createdAt: string
updatedAt: string
}
// ==================== 星球匹配 ====================
export interface PlanetMatch {
id?: number
userId: number
matchType: "star" | "guild" | "cp" | "coach"
preferences: {
games?: string[]
gender?: string
priceRange?: [number, number]
tags?: string[]
}
matchedId?: number // 匹配结果ID
matchScore?: number // 匹配度
status: "matching" | "matched" | "cancelled"
createdAt: string
matchedAt?: string
}
// ==================== 直播相关 ====================
export interface LiveRoom {
id?: number
streamerId: number
title: string
coverImage: string
game: string
viewers: number
peakViewers: number
likes: number
gifts: LiveGift[]
status: "live" | "offline" | "replay"
startTime?: string
endTime?: string
duration?: number
createdAt: string
}
export interface LiveGift {
id?: number
liveRoomId: number
userId: number
giftId: number
giftName: string
giftIcon: string
price: number
quantity: number
totalAmount: number
createdAt: string
}
export interface LiveComment {
id?: number
liveRoomId: number
userId: number
userName: string
userAvatar: string
content: string
type: "normal" | "gift" | "enter" | "follow"
createdAt: string
}
// ==================== 商城相关 ====================
export interface Product {
id?: number
name: string
description: string
image: string
images: string[]
category: "skin" | "equipment" | "points" | "peripheral" | "gift"
game?: string
price: number
originalPrice: number
stock: number
sales: number
rating: number
tags: string[]
specifications?: ProductSpec[]
status: "active" | "soldout" | "offline"
createdAt: string
updatedAt: string
}
export interface ProductSpec {
name: string
options: string[]
}
export interface CartItem {
id?: number
userId: number
productId: number
quantity: number
selectedSpecs?: Record<string, string>
createdAt: string
}
export interface ProductOrder {
id?: number
orderNo: string
userId: number
items: OrderItem[]
totalAmount: number
discountAmount: number
finalAmount: number
status: "pending" | "paid" | "shipped" | "completed" | "cancelled" | "refunded"
shippingAddress?: ShippingAddress
trackingNo?: string
paidAt?: string
shippedAt?: string
completedAt?: string
createdAt: string
updatedAt: string
}
export interface OrderItem {
productId: number
productName: string
productImage: string
price: number
quantity: number
specs?: Record<string, string>
}
export interface ShippingAddress {
name: string
phone: string
province: string
city: string
district: string
address: string
isDefault: boolean
}
// ==================== 游戏点卡 ====================
export interface GamePointCard {
id?: number
game: string
gameId: number
gameLogo: string
name: string
description: string
faceValue: number // 面值
price: number
discount: number
stock: number
sales: number
deliveryType: "instant" | "manual"
instructions: string
status: "active" | "soldout" | "offline"
createdAt: string
}
export interface PointCardOrder {
id?: number
orderNo: string
userId: number
cardId: number
game: string
faceValue: number
price: number
quantity: number
totalAmount: number
cardCodes?: string[] // 卡密
status: "pending" | "paid" | "delivered" | "used" | "refunded"
createdAt: string
deliveredAt?: string
}
// ==================== 账号交易/典当 ====================
export interface GameAccount {
id?: number
sellerId: number
game: string
gameId: number
server: string
title: string
description: string
images: string[]
level: number
rank?: string
skins: string[]
heroes: string[]
assets: Record<string, number> // 游戏资产
price: number
originalPrice?: number
evaluatedPrice?: number // AI评估价
status: "reviewing" | "listed" | "sold" | "offline" | "pawned"
viewCount: number
favoriteCount: number
createdAt: string
updatedAt: string
}
export interface AccountPawn {
id?: number
userId: number
accountId: number
game: string
evaluatedValue: number // 评估价值
pawnAmount: number // 典当金额
serviceFee: number // 服务费
redeemAmount: number // 赎回金额
period: 7 | 15 | 30 // 典当期限(天)
phone: string
screenshots: string[]
antiAddiction: "none" | "limited" | "full"
canRename: "yes" | "no" | "once"
selectedSkins: string[]
agreementSigned: boolean
status: "pending" | "evaluating" | "approved" | "active" | "redeemed" | "overdue" | "forfeited"
approvedAt?: string
redeemedAt?: string
expiresAt?: string
createdAt: string
updatedAt: string
}
export interface AccountTransaction {
id?: number
orderNo: string
buyerId: number
sellerId: number
accountId: number
price: number
platformFee: number
sellerIncome: number
status: "pending" | "paid" | "transferring" | "completed" | "disputed" | "refunded"
createdAt: string
completedAt?: string
}
// ==================== 电竞酒店/网咖 ====================
export interface EsportsVenue {
id?: number
name: string
type: "hotel" | "cafe"
logo: string
images: string[]
description: string
address: string
city: string
district: string
latitude: number
longitude: number
phone: string
rating: number
reviewCount: number
pricePerHour?: number // 网咖按小时
pricePerNight?: number // 酒店按晚
facilities: string[]
tags: string[]
openTime: string
closeTime: string
isOpen24Hours: boolean
status: "active" | "closed" | "renovating"
createdAt: string
updatedAt: string
}
export interface VenueRoom {
id?: number
venueId: number
name: string
type: "single" | "double" | "vip" | "booth"
capacity: number
price: number
images: string[]
facilities: string[]
status: "available" | "occupied" | "maintenance"
}
export interface VenueBooking {
id?: number
orderNo: string
userId: number
venueId: number
roomId?: number
type: "hotel" | "cafe"
checkInTime: string
checkOutTime: string
duration: number // 小时
price: number
totalAmount: number
guests: number
contactName: string
contactPhone: string
status: "pending" | "confirmed" | "checked_in" | "completed" | "cancelled"
createdAt: string
confirmedAt?: string
}
// ==================== 钱包/交易 ====================
export interface Transaction {
id?: number
userId: number
orderNo: string
type: "recharge" | "withdraw" | "purchase" | "gift" | "income" | "refund" | "transfer"
category: string // 具体分类
amount: number
balanceBefore: number
balanceAfter: number
relatedId?: number // 关联订单ID
relatedType?: string // 关联类型
description: string
status: "pending" | "completed" | "failed"
createdAt: string
}
export interface RechargeOrder {
id?: number
orderNo: string
userId: number
amount: number
bonusAmount: number // 赠送金额
totalAmount: number
paymentMethod: "wechat" | "alipay" | "card"
status: "pending" | "paid" | "failed" | "refunded"
paidAt?: string
createdAt: string
}
export interface WithdrawOrder {
id?: number
orderNo: string
userId: number
amount: number
fee: number
actualAmount: number
accountType: "wechat" | "alipay" | "bank"
accountInfo: string
status: "pending" | "processing" | "completed" | "rejected"
reviewedBy?: number
reviewedAt?: string
completedAt?: string
rejectReason?: string
createdAt: string
}
// ==================== 消息/通知 ====================
export interface Message {
id?: number
conversationId: number
senderId: number
receiverId: number
type: "text" | "image" | "voice" | "gift" | "system"
content: string
mediaUrl?: string
duration?: number // 语音时长
isRead: boolean
createdAt: string
}
export interface Conversation {
id?: number
type: "private" | "group" | "system"
participants: number[]
lastMessage?: string
lastMessageTime?: string
unreadCount: number
isPinned: boolean
isMuted: boolean
createdAt: string
updatedAt: string
}
export interface Notification {
id?: number
userId: number
type: "system" | "order" | "follow" | "like" | "comment" | "gift" | "activity"
title: string
content: string
image?: string
link?: string
isRead: boolean
createdAt: string
}
// ==================== 动态/社交 ====================
export interface Moment {
id?: number
userId: number
userName: string
userAvatar: string
content: string
images: string[]
video?: string
game?: string
tags: string[]
location?: string
likes: number
comments: number
shares: number
isLiked: boolean
visibility: "public" | "followers" | "private"
status: "active" | "deleted" | "hidden"
createdAt: string
updatedAt: string
}
export interface MomentLike {
id?: number
momentId: number
userId: number
createdAt: string
}
export interface MomentComment {
id?: number
momentId: number
userId: number
userName: string
userAvatar: string
content: string
replyTo?: number // 回复的评论ID
replyToUser?: string
likes: number
status: "active" | "deleted"
createdAt: string
}
// ==================== 游戏数据 ====================
export interface Game {
id?: number
name: string
shortName: string
logo: string
coverImage: string
category: "moba" | "fps" | "mmorpg" | "card" | "sports" | "other"
platform: ("pc" | "mobile" | "console")[]
publisher: string
isHot: boolean
sortOrder: number
status: "active" | "inactive"
createdAt: string
}
export interface GameServer {
id?: number
gameId: number
name: string
region: string
sortOrder: number
status: "active" | "inactive"
}
// ==================== 数据库类定义 ====================
export class WanzhiDatabase extends Dexie {
// 用户相关
users!: Table<User>
userAuths!: Table<UserAuth>
userFollows!: Table<UserFollow>
// 主播相关
streamers!: Table<Streamer>
streamerCourses!: Table<StreamerCourse>
coursePurchases!: Table<CoursePurchase>
// 公会相关
guilds!: Table<Guild>
guildMembers!: Table<GuildMember>
guildApplications!: Table<GuildApplication>
// 明星相关
stars!: Table<Star>
starPartyRooms!: Table<StarPartyRoom>
starPartyMembers!: Table<StarPartyMember>
// CP/陪练
companions!: Table<Companion>
companionOrders!: Table<CompanionOrder>
// 星球匹配
planetMatches!: Table<PlanetMatch>
// 直播相关
liveRooms!: Table<LiveRoom>
liveGifts!: Table<LiveGift>
liveComments!: Table<LiveComment>
// 商城相关
products!: Table<Product>
cartItems!: Table<CartItem>
productOrders!: Table<ProductOrder>
// 游戏点卡
gamePointCards!: Table<GamePointCard>
pointCardOrders!: Table<PointCardOrder>
// 账号交易/典当
gameAccounts!: Table<GameAccount>
accountPawns!: Table<AccountPawn>
accountTransactions!: Table<AccountTransaction>
// 电竞酒店/网咖
esportsVenues!: Table<EsportsVenue>
venueRooms!: Table<VenueRoom>
venueBookings!: Table<VenueBooking>
// 钱包/交易
transactions!: Table<Transaction>
rechargeOrders!: Table<RechargeOrder>
withdrawOrders!: Table<WithdrawOrder>
// 消息/通知
messages!: Table<Message>
conversations!: Table<Conversation>
notifications!: Table<Notification>
// 动态/社交
moments!: Table<Moment>
momentLikes!: Table<MomentLike>
momentComments!: Table<MomentComment>
// 游戏数据
games!: Table<Game>
gameServers!: Table<GameServer>
constructor() {
super("WanzhiEsportsDB")
this.version(1).stores({
// 用户相关
users: "++id, odlId, phone, name, status, createdAt",
userAuths: "++id, userId, authType, authId",
userFollows: "++id, userId, followUserId, followType",
// 主播相关
streamers: "++id, userId, name, game, guildId, status, isLive",
streamerCourses: "++id, streamerId, game, status, price",
coursePurchases: "++id, userId, courseId, streamerId",
// 公会相关
guilds: "++id, name, ownerId, status",
guildMembers: "++id, guildId, userId, role, status",
guildApplications: "++id, guildId, userId, status",
// 明星相关
stars: "++id, userId, name, game, status",
starPartyRooms: "++id, starId, isActive",
starPartyMembers: "++id, partyRoomId, userId",
// CP/陪练
companions: "++id, userId, category, gender, status, onlineStatus",
companionOrders: "++id, orderNo, userId, companionId, status",
// 星球匹配
planetMatches: "++id, userId, matchType, status",
// 直播相关
liveRooms: "++id, streamerId, game, status",
liveGifts: "++id, liveRoomId, userId",
liveComments: "++id, liveRoomId, userId",
// 商城相关
products: "++id, name, category, game, status",
cartItems: "++id, userId, productId",
productOrders: "++id, orderNo, userId, status",
// 游戏点卡
gamePointCards: "++id, game, gameId, status",
pointCardOrders: "++id, orderNo, userId, status",
// 账号交易/典当
gameAccounts: "++id, sellerId, game, status",
accountPawns: "++id, userId, accountId, status",
accountTransactions: "++id, orderNo, buyerId, sellerId, status",
// 电竞酒店/网咖
esportsVenues: "++id, name, type, city, status",
venueRooms: "++id, venueId, type, status",
venueBookings: "++id, orderNo, userId, venueId, status",
// 钱包/交易
transactions: "++id, userId, orderNo, type, status",
rechargeOrders: "++id, orderNo, userId, status",
withdrawOrders: "++id, orderNo, userId, status",
// 消息/通知
messages: "++id, conversationId, senderId, receiverId, isRead",
conversations: "++id, type, updatedAt",
notifications: "++id, userId, type, isRead",
// 动态/社交
moments: "++id, userId, game, status, createdAt",
momentLikes: "++id, momentId, userId",
momentComments: "++id, momentId, userId",
// 游戏数据
games: "++id, name, category, isHot, sortOrder",
gameServers: "++id, gameId, region",
})
}
}
// 创建数据库实例
export const db = new WanzhiDatabase()