281 lines
9.0 KiB
TypeScript
281 lines
9.0 KiB
TypeScript
export class StaticDataService {
|
||
private static instance: StaticDataService
|
||
private data: any = {}
|
||
private lastRealtimeData: any = null
|
||
private startTime: number = Date.now()
|
||
|
||
static getInstance(): StaticDataService {
|
||
if (!StaticDataService.instance) {
|
||
StaticDataService.instance = new StaticDataService()
|
||
}
|
||
return StaticDataService.instance
|
||
}
|
||
|
||
// 生成只增长的实时数据
|
||
static generateRealtimeData() {
|
||
const svc = StaticDataService.getInstance()
|
||
|
||
// 如果是第一次调用,初始化基础数据
|
||
if (!svc.lastRealtimeData) {
|
||
svc.lastRealtimeData = {
|
||
totalStalls: 350,
|
||
privateUsers: 12500,
|
||
stallOwners: 120,
|
||
dailyRevenue: 75000,
|
||
timestamp: new Date().toISOString(),
|
||
}
|
||
return svc.lastRealtimeData
|
||
}
|
||
|
||
// 计算时间差(秒)
|
||
const now = Date.now()
|
||
const timeDiff = (now - svc.startTime) / 1000
|
||
|
||
// 基于时间的增长率(每秒增长)
|
||
const hourlyGrowthRates = {
|
||
// 不同时段的增长速度
|
||
revenue: svc.getHourlyRevenueGrowthRate(),
|
||
users: 0.1, // 用户每秒增长0.1
|
||
stalls: 0.01, // 摊位每秒增长0.01
|
||
}
|
||
|
||
// 计算新的数值(只增长,不减少)
|
||
const revenueIncrease = Math.floor(timeDiff * hourlyGrowthRates.revenue)
|
||
const userIncrease = Math.floor(timeDiff * hourlyGrowthRates.users)
|
||
const stallIncrease = Math.floor(timeDiff * hourlyGrowthRates.stalls)
|
||
|
||
svc.lastRealtimeData = {
|
||
totalStalls: 350 + stallIncrease,
|
||
privateUsers: 12500 + userIncrease,
|
||
stallOwners: 120 + Math.floor(stallIncrease * 0.3),
|
||
dailyRevenue: 75000 + revenueIncrease,
|
||
timestamp: new Date().toISOString(),
|
||
}
|
||
|
||
return svc.lastRealtimeData
|
||
}
|
||
|
||
// 根据当前时间获取收益增长率
|
||
private getHourlyRevenueGrowthRate(): number {
|
||
const hour = new Date().getHours()
|
||
|
||
// 电商/数据大屏的收益时间分布
|
||
if (hour >= 9 && hour <= 11) {
|
||
return 15 // 上午高峰:每秒15元
|
||
} else if (hour >= 12 && hour <= 14) {
|
||
return 25 // 午餐高峰:每秒25元
|
||
} else if (hour >= 18 && hour <= 22) {
|
||
return 35 // 晚间高峰:每秒35元
|
||
} else if (hour >= 6 && hour <= 23) {
|
||
return 8 // 其他营业时间:每秒8元
|
||
} else {
|
||
return 2 // 夜间:每秒2元
|
||
}
|
||
}
|
||
|
||
// 生成模拟统计数据(保持增长趋势)
|
||
generateStats() {
|
||
const baseTime = Date.now()
|
||
const dayProgress = (baseTime % (24 * 60 * 60 * 1000)) / (24 * 60 * 60 * 1000)
|
||
|
||
// 基础数据 + 当日累计增长
|
||
const baseUserCount = 12500
|
||
const baseStallCount = 350
|
||
const baseDailyRevenue = 75000
|
||
const baseActiveUsers = 4500
|
||
|
||
// 当日增长(基于时间进度)
|
||
const dailyUserGrowth = Math.floor(dayProgress * 200) // 每天最多增长200用户
|
||
const dailyStallGrowth = Math.floor(dayProgress * 10) // 每天最多增长10摊位
|
||
const dailyRevenueGrowth = Math.floor(dayProgress * 50000) // 每天最多增长5万收益
|
||
|
||
return {
|
||
userCount: baseUserCount + dailyUserGrowth,
|
||
stallCount: baseStallCount + dailyStallGrowth,
|
||
dailyRevenue: baseDailyRevenue + dailyRevenueGrowth,
|
||
activeUsers: baseActiveUsers + Math.floor(dailyUserGrowth * 0.6),
|
||
growthRate: Number((15.2 + dayProgress * 5).toFixed(1)), // 增长率也随时间提升
|
||
}
|
||
}
|
||
|
||
// 生成摊位统计数据
|
||
generateStallStats() {
|
||
const currentTime = Date.now()
|
||
const baseOccupancy = 85.1
|
||
const timeVariation = Math.sin(currentTime / 1000000) * 2 // 小幅波动
|
||
|
||
return {
|
||
totalStalls: 350,
|
||
activeStalls: 298,
|
||
occupancyRate: Math.max(80, baseOccupancy + timeVariation), // 确保不低于80%
|
||
averageRevenue: 3580 + Math.floor((currentTime % 10000) / 100), // 缓慢增长
|
||
topCategories: [
|
||
{ name: "餐饮", count: 120, percentage: 34.3 },
|
||
{ name: "服装", count: 85, percentage: 24.3 },
|
||
{ name: "数码", count: 65, percentage: 18.6 },
|
||
{ name: "其他", count: 80, percentage: 22.8 },
|
||
],
|
||
}
|
||
}
|
||
|
||
// 生成用户统计数据
|
||
generateUserStats() {
|
||
const stats = this.generateStats()
|
||
|
||
return {
|
||
totalUsers: stats.userCount,
|
||
activeUsers: stats.activeUsers,
|
||
newUsersToday: Math.floor((Date.now() % (24 * 60 * 60 * 1000)) / (60 * 60 * 1000)) + 50, // 基于小时数
|
||
userGrowthRate: stats.growthRate,
|
||
ageDistribution: [
|
||
{ range: "18-25", count: Math.floor(stats.userCount * 0.3), percentage: 30 },
|
||
{ range: "26-35", count: Math.floor(stats.userCount * 0.35), percentage: 35 },
|
||
{ range: "36-45", count: Math.floor(stats.userCount * 0.2), percentage: 20 },
|
||
{ range: "46+", count: Math.floor(stats.userCount * 0.15), percentage: 15 },
|
||
],
|
||
}
|
||
}
|
||
|
||
// 生成交易数据
|
||
generateDailyTransactions() {
|
||
const currentHour = new Date().getHours()
|
||
const hours = Array.from({ length: 24 }, (_, i) => {
|
||
const hour = i.toString().padStart(2, "0") + ":00"
|
||
let transactions = 0
|
||
|
||
// 已过去的小时显示累计数据,未来小时显示0
|
||
if (i <= currentHour) {
|
||
// 模拟不同时段的交易量
|
||
if (i >= 9 && i <= 11)
|
||
transactions = Math.floor(Math.random() * 50) + 80 // 上午高峰
|
||
else if (i >= 12 && i <= 14)
|
||
transactions = Math.floor(Math.random() * 60) + 100 // 午餐高峰
|
||
else if (i >= 18 && i <= 21)
|
||
transactions = Math.floor(Math.random() * 70) + 120 // 晚餐高峰
|
||
else if (i >= 6 && i <= 23)
|
||
transactions = Math.floor(Math.random() * 30) + 20 // 其他营业时间
|
||
else transactions = Math.floor(Math.random() * 5) // 夜间
|
||
}
|
||
|
||
return { time: hour, transactions }
|
||
})
|
||
|
||
const completedHours = hours.filter((h) => h.transactions > 0)
|
||
|
||
return {
|
||
todayTotal: completedHours.reduce((sum, h) => sum + h.transactions, 0),
|
||
hourlyData: hours,
|
||
averagePerHour:
|
||
completedHours.length > 0
|
||
? Math.floor(completedHours.reduce((sum, h) => sum + h.transactions, 0) / completedHours.length)
|
||
: 0,
|
||
peakHour: completedHours.reduce((max, h) => (h.transactions > max.transactions ? h : max), {
|
||
time: "00:00",
|
||
transactions: 0,
|
||
}),
|
||
}
|
||
}
|
||
|
||
// 生成资产价值数据
|
||
generateAssetValue() {
|
||
const months = ["1月", "2月", "3月", "4月", "5月", "6月"]
|
||
const baseValue = 1000000
|
||
const currentMonth = new Date().getMonth()
|
||
|
||
const monthlyData = months.map((month, index) => ({
|
||
month,
|
||
value: baseValue + index * 80000 + Math.floor(Math.random() * 50000), // 确保每月都增长
|
||
}))
|
||
|
||
const currentValue = monthlyData[Math.min(currentMonth, monthlyData.length - 1)].value
|
||
|
||
return {
|
||
currentValue,
|
||
monthlyData,
|
||
growthRate: 12.5,
|
||
totalAssets: currentValue * 4.2, // 总资产是当前价值的4.2倍
|
||
}
|
||
}
|
||
|
||
// 生成增长趋势数据
|
||
generateGrowthTrend() {
|
||
const days = Array.from({ length: 30 }, (_, i) => {
|
||
const date = new Date()
|
||
date.setDate(date.getDate() - (29 - i))
|
||
|
||
// 确保数据呈增长趋势
|
||
const baseUsers = 12000
|
||
const baseRevenue = 120000
|
||
const baseTransactions = 800
|
||
|
||
return {
|
||
date: date.toISOString().split("T")[0],
|
||
users: baseUsers + i * 25 + Math.floor(Math.random() * 50), // 每天增长25-75用户
|
||
revenue: baseRevenue + i * 1500 + Math.floor(Math.random() * 2000), // 每天增长1500-3500收益
|
||
transactions: baseTransactions + i * 8 + Math.floor(Math.random() * 15), // 每天增长8-23交易
|
||
}
|
||
})
|
||
|
||
return {
|
||
dailyData: days,
|
||
userGrowth: 8.5,
|
||
revenueGrowth: 12.3,
|
||
transactionGrowth: 6.8,
|
||
}
|
||
}
|
||
|
||
// 生成电竞明星数据
|
||
generateEsportsStars() {
|
||
const baseEarnings = [1250000, 980000, 850000]
|
||
const timeBonus = Math.floor((Date.now() % (24 * 60 * 60 * 1000)) / (60 * 60 * 1000)) * 1000 // 每小时增长1000
|
||
|
||
return [
|
||
{
|
||
id: 1,
|
||
name: "Faker",
|
||
game: "英雄联盟",
|
||
team: "T1",
|
||
rank: 1,
|
||
winRate: 87.5,
|
||
earnings: baseEarnings[0] + timeBonus,
|
||
avatar: "/placeholder.svg?height=64&width=64",
|
||
},
|
||
{
|
||
id: 2,
|
||
name: "s1mple",
|
||
game: "CS:GO",
|
||
team: "NAVI",
|
||
rank: 2,
|
||
winRate: 82.3,
|
||
earnings: baseEarnings[1] + timeBonus,
|
||
avatar: "/placeholder.svg?height=64&width=64",
|
||
},
|
||
{
|
||
id: 3,
|
||
name: "Uzi",
|
||
game: "英雄联盟",
|
||
team: "RNG",
|
||
rank: 3,
|
||
winRate: 79.8,
|
||
earnings: baseEarnings[2] + timeBonus,
|
||
avatar: "/placeholder.svg?height=64&width=64",
|
||
},
|
||
]
|
||
}
|
||
|
||
// 获取所有数据
|
||
getAllData() {
|
||
return {
|
||
stats: this.generateStats(),
|
||
stallStats: this.generateStallStats(),
|
||
userStats: this.generateUserStats(),
|
||
dailyTransactions: this.generateDailyTransactions(),
|
||
assetValue: this.generateAssetValue(),
|
||
growthTrend: this.generateGrowthTrend(),
|
||
esportsStars: this.generateEsportsStars(),
|
||
}
|
||
}
|
||
}
|
||
|
||
export const staticDataService = StaticDataService.getInstance()
|