478 lines
19 KiB
Plaintext
478 lines
19 KiB
Plaintext
generator client {
|
|
provider = "prisma-client-js"
|
|
}
|
|
|
|
datasource db {
|
|
provider = "postgresql"
|
|
url = env("DATABASE_URL")
|
|
}
|
|
|
|
// ============================================
|
|
// 报表定义表 (聚合根1)
|
|
// 定义各类报表的配置和调度规则
|
|
// ============================================
|
|
model ReportDefinition {
|
|
id BigInt @id @default(autoincrement()) @map("definition_id")
|
|
|
|
// === 报表基本信息 ===
|
|
reportType String @map("report_type") @db.VarChar(50)
|
|
reportName String @map("report_name") @db.VarChar(200)
|
|
reportCode String @unique @map("report_code") @db.VarChar(50)
|
|
description String? @map("description") @db.Text
|
|
|
|
// === 报表参数 ===
|
|
parameters Json @map("parameters")
|
|
|
|
// === 调度配置 ===
|
|
scheduleCron String? @map("schedule_cron") @db.VarChar(100)
|
|
scheduleTimezone String? @map("schedule_timezone") @db.VarChar(50) @default("Asia/Shanghai")
|
|
scheduleEnabled Boolean @default(false) @map("schedule_enabled")
|
|
|
|
// === 输出格式 ===
|
|
outputFormats String[] @map("output_formats")
|
|
|
|
// === 状态 ===
|
|
isActive Boolean @default(true) @map("is_active")
|
|
|
|
// === 时间戳 ===
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
lastGeneratedAt DateTime? @map("last_generated_at")
|
|
|
|
@@map("report_definitions")
|
|
@@index([reportType], name: "idx_def_type")
|
|
@@index([isActive], name: "idx_def_active")
|
|
@@index([scheduleEnabled], name: "idx_def_scheduled")
|
|
}
|
|
|
|
// ============================================
|
|
// 报表快照表 (聚合根2 - 读模型)
|
|
// 存储已生成的报表数据快照
|
|
// ============================================
|
|
model ReportSnapshot {
|
|
id BigInt @id @default(autoincrement()) @map("snapshot_id")
|
|
|
|
// === 报表信息 ===
|
|
reportType String @map("report_type") @db.VarChar(50)
|
|
reportCode String @map("report_code") @db.VarChar(50)
|
|
reportPeriod String @map("report_period") @db.VarChar(20)
|
|
periodKey String @map("period_key") @db.VarChar(30)
|
|
|
|
// === 快照数据 ===
|
|
snapshotData Json @map("snapshot_data")
|
|
summaryData Json? @map("summary_data")
|
|
|
|
// === 数据来源 ===
|
|
dataSources String[] @map("data_sources")
|
|
dataFreshness Int @default(0) @map("data_freshness")
|
|
|
|
// === 过滤条件 ===
|
|
filterParams Json? @map("filter_params")
|
|
|
|
// === 统计信息 ===
|
|
rowCount Int @default(0) @map("row_count")
|
|
|
|
// === 时间戳 ===
|
|
periodStartAt DateTime @map("period_start_at")
|
|
periodEndAt DateTime @map("period_end_at")
|
|
generatedAt DateTime @default(now()) @map("generated_at")
|
|
expiresAt DateTime? @map("expires_at")
|
|
|
|
// === 关联 ===
|
|
files ReportFile[]
|
|
|
|
@@map("report_snapshots")
|
|
@@unique([reportCode, periodKey], name: "uk_report_period")
|
|
@@index([reportType], name: "idx_snapshot_type")
|
|
@@index([reportCode], name: "idx_snapshot_code")
|
|
@@index([periodKey], name: "idx_snapshot_period")
|
|
@@index([generatedAt(sort: Desc)], name: "idx_snapshot_generated")
|
|
@@index([expiresAt], name: "idx_snapshot_expires")
|
|
}
|
|
|
|
// ============================================
|
|
// 报表文件表
|
|
// 存储已导出的报表文件信息
|
|
// ============================================
|
|
model ReportFile {
|
|
id BigInt @id @default(autoincrement()) @map("file_id")
|
|
snapshotId BigInt @map("snapshot_id")
|
|
|
|
// === 文件信息 ===
|
|
fileName String @map("file_name") @db.VarChar(500)
|
|
filePath String @map("file_path") @db.VarChar(1000)
|
|
fileUrl String? @map("file_url") @db.VarChar(1000)
|
|
fileSize BigInt @map("file_size")
|
|
fileFormat String @map("file_format") @db.VarChar(20)
|
|
mimeType String @map("mime_type") @db.VarChar(100)
|
|
|
|
// === 访问信息 ===
|
|
downloadCount Int @default(0) @map("download_count")
|
|
lastDownloadAt DateTime? @map("last_download_at")
|
|
|
|
// === 时间戳 ===
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
expiresAt DateTime? @map("expires_at")
|
|
|
|
// === 关联 ===
|
|
snapshot ReportSnapshot @relation(fields: [snapshotId], references: [id], onDelete: Cascade)
|
|
|
|
@@map("report_files")
|
|
@@index([snapshotId], name: "idx_file_snapshot")
|
|
@@index([fileFormat], name: "idx_file_format")
|
|
@@index([createdAt(sort: Desc)], name: "idx_file_created")
|
|
}
|
|
|
|
// ============================================
|
|
// 分析指标表 (聚合数据)
|
|
// 存储预聚合的分析指标数据
|
|
// ============================================
|
|
model AnalyticsMetric {
|
|
id BigInt @id @default(autoincrement()) @map("metric_id")
|
|
|
|
// === 指标信息 ===
|
|
metricType String @map("metric_type") @db.VarChar(50)
|
|
metricCode String @map("metric_code") @db.VarChar(50)
|
|
|
|
// === 维度 ===
|
|
dimensionTime DateTime? @map("dimension_time") @db.Date
|
|
dimensionRegion String? @map("dimension_region") @db.VarChar(100)
|
|
dimensionUserType String? @map("dimension_user_type") @db.VarChar(50)
|
|
dimensionRightType String? @map("dimension_right_type") @db.VarChar(50)
|
|
|
|
// === 指标值 ===
|
|
metricValue Decimal @map("metric_value") @db.Decimal(20, 8)
|
|
metricData Json? @map("metric_data")
|
|
|
|
// === 时间戳 ===
|
|
calculatedAt DateTime @default(now()) @map("calculated_at")
|
|
|
|
@@map("analytics_metrics")
|
|
@@unique([metricCode, dimensionTime, dimensionRegion, dimensionUserType, dimensionRightType], name: "uk_metric_dimensions")
|
|
@@index([metricType], name: "idx_metric_type")
|
|
@@index([metricCode], name: "idx_metric_code")
|
|
@@index([dimensionTime], name: "idx_metric_time")
|
|
@@index([dimensionRegion], name: "idx_metric_region")
|
|
}
|
|
|
|
// ============================================
|
|
// 认种统计日表 (每日聚合)
|
|
// ============================================
|
|
model PlantingDailyStat {
|
|
id BigInt @id @default(autoincrement()) @map("stat_id")
|
|
|
|
// === 统计日期 ===
|
|
statDate DateTime @map("stat_date") @db.Date
|
|
|
|
// === 区域维度 ===
|
|
provinceCode String? @map("province_code") @db.VarChar(10)
|
|
cityCode String? @map("city_code") @db.VarChar(10)
|
|
|
|
// === 统计数据 ===
|
|
orderCount Int @default(0) @map("order_count")
|
|
treeCount Int @default(0) @map("tree_count")
|
|
totalAmount Decimal @default(0) @map("total_amount") @db.Decimal(20, 8)
|
|
newUserCount Int @default(0) @map("new_user_count")
|
|
activeUserCount Int @default(0) @map("active_user_count")
|
|
|
|
// === 时间戳 ===
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
@@map("planting_daily_stats")
|
|
@@unique([statDate, provinceCode, cityCode], name: "uk_daily_stat")
|
|
@@index([statDate], name: "idx_pds_date")
|
|
@@index([provinceCode], name: "idx_pds_province")
|
|
@@index([cityCode], name: "idx_pds_city")
|
|
}
|
|
|
|
// ============================================
|
|
// 社区统计表
|
|
// ============================================
|
|
model CommunityStat {
|
|
id BigInt @id @default(autoincrement()) @map("stat_id")
|
|
|
|
// === 社区信息 ===
|
|
communityId BigInt @map("community_id")
|
|
communityName String @map("community_name") @db.VarChar(200)
|
|
parentCommunityId BigInt? @map("parent_community_id")
|
|
|
|
// === 统计日期 ===
|
|
statDate DateTime @map("stat_date") @db.Date
|
|
|
|
// === 统计数据 ===
|
|
totalPlanting Int @default(0) @map("total_planting")
|
|
dailyPlanting Int @default(0) @map("daily_planting")
|
|
weeklyPlanting Int @default(0) @map("weekly_planting")
|
|
monthlyPlanting Int @default(0) @map("monthly_planting")
|
|
memberCount Int @default(0) @map("member_count")
|
|
|
|
// === 时间戳 ===
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
@@map("community_stats")
|
|
@@unique([communityId, statDate], name: "uk_community_stat")
|
|
@@index([communityId], name: "idx_cs_community")
|
|
@@index([communityName], name: "idx_cs_name")
|
|
@@index([statDate], name: "idx_cs_date")
|
|
@@index([parentCommunityId], name: "idx_cs_parent")
|
|
}
|
|
|
|
// ============================================
|
|
// 系统账户月度统计表
|
|
// 省公司/市公司账户的月度数据
|
|
// ============================================
|
|
model SystemAccountMonthlyStat {
|
|
id BigInt @id @default(autoincrement()) @map("stat_id")
|
|
|
|
// === 账户信息 ===
|
|
accountId BigInt @map("account_id")
|
|
accountType String @map("account_type") @db.VarChar(30)
|
|
accountName String @map("account_name") @db.VarChar(200)
|
|
regionCode String @map("region_code") @db.VarChar(10)
|
|
|
|
// === 统计月份 ===
|
|
statMonth String @map("stat_month") @db.VarChar(7)
|
|
|
|
// === 月度数据 ===
|
|
monthlyHashpower Decimal @default(0) @map("monthly_hashpower") @db.Decimal(20, 8)
|
|
cumulativeHashpower Decimal @default(0) @map("cumulative_hashpower") @db.Decimal(20, 8)
|
|
monthlyMining Decimal @default(0) @map("monthly_mining") @db.Decimal(20, 8)
|
|
cumulativeMining Decimal @default(0) @map("cumulative_mining") @db.Decimal(20, 8)
|
|
monthlyCommission Decimal @default(0) @map("monthly_commission") @db.Decimal(20, 8)
|
|
cumulativeCommission Decimal @default(0) @map("cumulative_commission") @db.Decimal(20, 8)
|
|
monthlyPlantingBonus Decimal @default(0) @map("monthly_planting_bonus") @db.Decimal(20, 8)
|
|
cumulativePlantingBonus Decimal @default(0) @map("cumulative_planting_bonus") @db.Decimal(20, 8)
|
|
|
|
// === 时间戳 ===
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
@@map("system_account_monthly_stats")
|
|
@@unique([accountId, statMonth], name: "uk_account_month")
|
|
@@index([accountType], name: "idx_sams_type")
|
|
@@index([statMonth], name: "idx_sams_month")
|
|
@@index([regionCode], name: "idx_sams_region")
|
|
}
|
|
|
|
// ============================================
|
|
// 系统账户收益流水表
|
|
// 记录每笔收益的来源和时间
|
|
// ============================================
|
|
model SystemAccountIncomeRecord {
|
|
id BigInt @id @default(autoincrement()) @map("record_id")
|
|
|
|
// === 账户信息 ===
|
|
accountId BigInt @map("account_id")
|
|
accountType String @map("account_type") @db.VarChar(30)
|
|
|
|
// === 收益信息 ===
|
|
incomeType String @map("income_type") @db.VarChar(50)
|
|
incomeAmount Decimal @map("income_amount") @db.Decimal(20, 8)
|
|
currency String @map("currency") @db.VarChar(10)
|
|
|
|
// === 来源信息 ===
|
|
sourceType String @map("source_type") @db.VarChar(50)
|
|
sourceId String? @map("source_id") @db.VarChar(100)
|
|
sourceUserId BigInt? @map("source_user_id")
|
|
sourceAddress String? @map("source_address") @db.VarChar(200)
|
|
transactionNo String? @map("transaction_no") @db.VarChar(100)
|
|
|
|
// === 备注 ===
|
|
memo String? @map("memo") @db.Text
|
|
|
|
// === 时间戳 ===
|
|
occurredAt DateTime @map("occurred_at")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
|
|
@@map("system_account_income_records")
|
|
@@index([accountId], name: "idx_sair_account")
|
|
@@index([accountType], name: "idx_sair_type")
|
|
@@index([incomeType], name: "idx_sair_income_type")
|
|
@@index([sourceType], name: "idx_sair_source_type")
|
|
@@index([sourceAddress], name: "idx_sair_address")
|
|
@@index([transactionNo], name: "idx_sair_txno")
|
|
@@index([occurredAt(sort: Desc)], name: "idx_sair_occurred")
|
|
}
|
|
|
|
// ============================================
|
|
// 报表事件表
|
|
// ============================================
|
|
model ReportEvent {
|
|
id BigInt @id @default(autoincrement()) @map("event_id")
|
|
eventType String @map("event_type") @db.VarChar(50)
|
|
|
|
// 聚合根信息
|
|
aggregateId String @map("aggregate_id") @db.VarChar(100)
|
|
aggregateType String @map("aggregate_type") @db.VarChar(50)
|
|
|
|
// 事件数据
|
|
eventData Json @map("event_data")
|
|
|
|
// 元数据
|
|
userId BigInt? @map("user_id")
|
|
occurredAt DateTime @default(now()) @map("occurred_at") @db.Timestamp(6)
|
|
version Int @default(1) @map("version")
|
|
|
|
@@map("report_events")
|
|
@@index([aggregateType, aggregateId], name: "idx_report_event_aggregate")
|
|
@@index([eventType], name: "idx_report_event_type")
|
|
@@index([occurredAt], name: "idx_report_event_occurred")
|
|
}
|
|
|
|
// ============================================
|
|
// 仪表板统计快照表
|
|
// 缓存仪表板统计数据,避免实时计算
|
|
// ============================================
|
|
model DashboardStatsSnapshot {
|
|
id BigInt @id @default(autoincrement()) @map("snapshot_id")
|
|
|
|
// === 快照日期 ===
|
|
snapshotDate DateTime @map("snapshot_date") @db.Date
|
|
|
|
// === 核心统计数据 ===
|
|
totalPlantingCount Int @default(0) @map("total_planting_count")
|
|
totalPlantingChange Decimal @default(0) @map("total_planting_change") @db.Decimal(5, 2)
|
|
activeUserCount Int @default(0) @map("active_user_count")
|
|
activeUserChange Decimal @default(0) @map("active_user_change") @db.Decimal(5, 2)
|
|
provinceCompanyCount Int @default(0) @map("province_company_count")
|
|
provinceCompanyChange Decimal @default(0) @map("province_company_change") @db.Decimal(5, 2)
|
|
cityCompanyCount Int @default(0) @map("city_company_count")
|
|
cityCompanyChange Decimal @default(0) @map("city_company_change") @db.Decimal(5, 2)
|
|
|
|
// === 区域分布数据 (JSON) ===
|
|
regionDistribution Json? @map("region_distribution")
|
|
|
|
// === 时间戳 ===
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
@@map("dashboard_stats_snapshots")
|
|
@@unique([snapshotDate], name: "uk_dashboard_snapshot_date")
|
|
@@index([snapshotDate(sort: Desc)], name: "idx_dss_date")
|
|
}
|
|
|
|
// ============================================
|
|
// 仪表板趋势数据表
|
|
// 存储每日趋势数据点
|
|
// ============================================
|
|
model DashboardTrendData {
|
|
id BigInt @id @default(autoincrement()) @map("trend_id")
|
|
|
|
// === 数据日期 ===
|
|
trendDate DateTime @map("trend_date") @db.Date
|
|
|
|
// === 趋势指标 ===
|
|
plantingCount Int @default(0) @map("planting_count")
|
|
orderCount Int @default(0) @map("order_count")
|
|
newUserCount Int @default(0) @map("new_user_count")
|
|
activeUserCount Int @default(0) @map("active_user_count")
|
|
|
|
// === 时间戳 ===
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
@@map("dashboard_trend_data")
|
|
@@unique([trendDate], name: "uk_trend_date")
|
|
@@index([trendDate(sort: Desc)], name: "idx_dtd_date")
|
|
}
|
|
|
|
// ============================================
|
|
// 实时统计表 - 通过 Kafka 事件累加
|
|
// Dashboard 直接从此表读取数据
|
|
// ============================================
|
|
model RealtimeStats {
|
|
id BigInt @id @default(autoincrement()) @map("stats_id")
|
|
|
|
// === 统计日期 ===
|
|
statsDate DateTime @unique(map: "uk_realtime_stats_date") @map("stats_date") @db.Date
|
|
|
|
// === 认种统计 (来自 planting.order.paid) ===
|
|
dailyPlantingCount Int @default(0) @map("daily_planting_count")
|
|
dailyOrderCount Int @default(0) @map("daily_order_count")
|
|
dailyPlantingAmount Decimal @default(0) @map("daily_planting_amount") @db.Decimal(20, 8)
|
|
|
|
// === 用户统计 (来自 identity.UserAccountCreated) ===
|
|
dailyNewUserCount Int @default(0) @map("daily_new_user_count")
|
|
|
|
// === 授权统计 (来自 authorization-events) ===
|
|
dailyProvinceAuthCount Int @default(0) @map("daily_province_auth_count")
|
|
dailyCityAuthCount Int @default(0) @map("daily_city_auth_count")
|
|
|
|
// === 时间戳 ===
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
@@map("realtime_stats")
|
|
@@index([statsDate(sort: Desc)], name: "idx_rs_date")
|
|
}
|
|
|
|
// ============================================
|
|
// 全局累计统计表 - 存储总量数据
|
|
// ============================================
|
|
model GlobalStats {
|
|
id BigInt @id @default(autoincrement()) @map("stats_id")
|
|
|
|
// === 统计键 (单行记录) ===
|
|
statsKey String @unique @default("global") @map("stats_key") @db.VarChar(20)
|
|
|
|
// === 累计认种统计 ===
|
|
totalPlantingCount Int @default(0) @map("total_planting_count")
|
|
totalOrderCount Int @default(0) @map("total_order_count")
|
|
totalPlantingAmount Decimal @default(0) @map("total_planting_amount") @db.Decimal(20, 8)
|
|
|
|
// === 累计用户统计 ===
|
|
totalUserCount Int @default(0) @map("total_user_count")
|
|
|
|
// === 累计授权统计 ===
|
|
totalProvinceCompanyCount Int @default(0) @map("total_province_company_count")
|
|
totalCityCompanyCount Int @default(0) @map("total_city_company_count")
|
|
|
|
// === 时间戳 ===
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
@@map("global_stats")
|
|
}
|
|
|
|
// ============================================
|
|
// 系统活动日志表
|
|
// 记录系统中的重要活动事件
|
|
// ============================================
|
|
model SystemActivity {
|
|
id BigInt @id @default(autoincrement()) @map("activity_id")
|
|
|
|
// === 活动类型 ===
|
|
// user_register: 用户注册
|
|
// company_authorization: 公司授权
|
|
// planting_order: 认种订单
|
|
// system_update: 系统更新
|
|
// report_generated: 报表生成
|
|
activityType String @map("activity_type") @db.VarChar(50)
|
|
|
|
// === 活动信息 ===
|
|
title String @map("title") @db.VarChar(200)
|
|
description String @map("description") @db.VarChar(500)
|
|
icon String @default("📌") @map("icon") @db.VarChar(10)
|
|
|
|
// === 关联信息 ===
|
|
relatedUserId BigInt? @map("related_user_id")
|
|
relatedEntityId String? @map("related_entity_id") @db.VarChar(100)
|
|
relatedEntityType String? @map("related_entity_type") @db.VarChar(50)
|
|
|
|
// === 元数据 ===
|
|
metadata Json? @map("metadata")
|
|
|
|
// === 时间戳 ===
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
|
|
@@map("system_activities")
|
|
@@index([activityType], name: "idx_sa_type")
|
|
@@index([createdAt(sort: Desc)], name: "idx_sa_created")
|
|
@@index([relatedUserId], name: "idx_sa_user")
|
|
@@index([relatedEntityType, relatedEntityId], name: "idx_sa_entity")
|
|
// [2026-01-08] 新增:唯一约束防止同一实体的重复活动记录
|
|
@@unique([activityType, relatedEntityType, relatedEntityId], name: "uk_sa_entity_activity")
|
|
}
|