diff --git a/backend/services/wallet-service/prisma/migrations/20260106100000_add_system_withdrawal_order/migration.sql b/backend/services/wallet-service/prisma/migrations/20260106100000_add_system_withdrawal_order/migration.sql new file mode 100644 index 00000000..46088014 --- /dev/null +++ b/backend/services/wallet-service/prisma/migrations/20260106100000_add_system_withdrawal_order/migration.sql @@ -0,0 +1,52 @@ +-- ============================================ +-- 系统账户转出订单表 +-- 用于记录从系统账户(S开头/区域账户)转出到用户账户的订单 +-- ============================================ + +CREATE TABLE IF NOT EXISTS "system_withdrawal_orders" ( + "order_id" BIGSERIAL PRIMARY KEY, + "order_no" VARCHAR(50) NOT NULL UNIQUE, + + -- 转出方(系统账户) + "from_account_sequence" VARCHAR(20) NOT NULL, -- 系统账户序列号 (S0000000001, 9440000, 8440100 等) + "from_account_name" VARCHAR(100) NOT NULL, -- 系统账户名称 (总部账户, 广东省区域 等) + + -- 接收方(用户账户) + "to_account_sequence" VARCHAR(20) NOT NULL, -- 用户充值ID (D...) + "to_user_id" BIGINT NOT NULL, -- 用户ID + "to_user_name" VARCHAR(100), -- 用户姓名 + "to_address" VARCHAR(100) NOT NULL, -- 用户区块链地址 + + -- 金额 + "amount" DECIMAL(20, 8) NOT NULL, -- 转出金额 + "chain_type" VARCHAR(20) NOT NULL DEFAULT 'KAVA', -- 链类型 + + -- 交易信息 + "tx_hash" VARCHAR(100), -- 链上交易哈希 + + -- 状态: PENDING -> FROZEN -> BROADCASTED -> CONFIRMED / FAILED + "status" VARCHAR(20) NOT NULL DEFAULT 'PENDING', + "error_message" VARCHAR(500), + + -- 操作者 + "operator_id" VARCHAR(100) NOT NULL, -- 操作管理员ID + "operator_name" VARCHAR(100), -- 操作管理员姓名 + + -- 备注 + "memo" TEXT, + + -- 时间戳 + "frozen_at" TIMESTAMP, + "broadcasted_at" TIMESTAMP, + "confirmed_at" TIMESTAMP, + "created_at" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP +); + +-- 索引 +CREATE INDEX "idx_system_withdrawal_from_account" ON "system_withdrawal_orders" ("from_account_sequence"); +CREATE INDEX "idx_system_withdrawal_to_account" ON "system_withdrawal_orders" ("to_account_sequence"); +CREATE INDEX "idx_system_withdrawal_to_user" ON "system_withdrawal_orders" ("to_user_id"); +CREATE INDEX "idx_system_withdrawal_status" ON "system_withdrawal_orders" ("status"); +CREATE INDEX "idx_system_withdrawal_tx_hash" ON "system_withdrawal_orders" ("tx_hash"); +CREATE INDEX "idx_system_withdrawal_operator" ON "system_withdrawal_orders" ("operator_id"); +CREATE INDEX "idx_system_withdrawal_created" ON "system_withdrawal_orders" ("created_at"); \ No newline at end of file diff --git a/frontend/admin-web/src/app/(dashboard)/statistics/page.tsx b/frontend/admin-web/src/app/(dashboard)/statistics/page.tsx index 2e448b2e..5891d226 100644 --- a/frontend/admin-web/src/app/(dashboard)/statistics/page.tsx +++ b/frontend/admin-web/src/app/(dashboard)/statistics/page.tsx @@ -1,7 +1,7 @@ /** * 数据统计页面 * [2026-01-04] 更新:新增系统账户报表Tab - * [2026-01-06] 更新:认种统计改为真实数据 + * [2026-01-06] 更新:认种统计改为真实数据,删除不相关的mock功能 * 回滚方式:删除 SystemAccountsTab 导入及相关 mainTab state 和切换逻辑 */ 'use client'; @@ -15,93 +15,6 @@ import { dashboardService } from '@/services/dashboardService'; import type { PlantingGlobalStats } from '@/types'; import styles from './statistics.module.scss'; -/** - * 排名数据接口 - */ -interface RankingItem { - rank: number; - account: string; - count: number; - province: string; - city: string; -} - -/** - * 区域数据接口 - */ -interface RegionItem { - region: string; - period: string; - count: number; - ratio: string; -} - -/** - * 运营数据接口 - */ -interface OperationItem { - type: string; - name: string; - month: string; - hashrate: string; - mining: string; - commission: string; -} - -/** - * 收益数据接口 - */ -interface RevenueItem { - time: string; - account: string; - source: string; - amount: string; - address: string; - txId: string; -} - -// 排名数据 -const rankingData: RankingItem[] = [ - { rank: 1, account: 'user_001', count: 58, province: '广东', city: '深圳' }, - { rank: 2, account: 'user_002', count: 55, province: '广东', city: '广州' }, - { rank: 3, account: 'user_003', count: 49, province: '湖南', city: '长沙' }, - { rank: 4, account: 'user_004', count: 42, province: '浙江', city: '杭州' }, - { rank: 5, account: 'user_005', count: 38, province: '江苏', city: '南京' }, -]; - -// 区域数据 -const regionData: RegionItem[] = [ - { region: '广东省', period: '2023-10', count: 2345, ratio: '25.8%' }, - { region: '湖南省', period: '2023-10', count: 1890, ratio: '20.8%' }, - { region: '浙江省', period: '2023-10', count: 1560, ratio: '17.1%' }, - { region: '江苏省', period: '2023-10', count: 1230, ratio: '13.5%' }, -]; - -// 运营数据 -const operationData: OperationItem[] = [ - { type: '省公司', name: '广东省公司', month: '2023-10', hashrate: '150 TH/s', mining: '0.8 BTC', commission: '¥2,500' }, - { type: '市公司', name: '深圳市公司', month: '2023-10', hashrate: '80 TH/s', mining: '0.45 BTC', commission: '¥1,800' }, - { type: '市公司', name: '广州市公司', month: '2023-10', hashrate: '70 TH/s', mining: '0.35 BTC', commission: '¥1,500' }, -]; - -// 收益数据 -const revenueData: RevenueItem[] = [ - { time: '2023-10-26 10:30', account: 'user_001', source: '挖矿收益', amount: '+ ¥50.00', address: 'bc1...xyz', txId: 'TXN1234567890' }, - { time: '2023-10-26 09:15', account: 'user_002', source: '认种提成', amount: '+ ¥120.00', address: 'bc1...abc', txId: 'TXN0987654321' }, - { time: '2023-10-25 18:00', account: 'user_003', source: '分润', amount: '+ ¥35.50', address: 'bc1...def', txId: 'TXN5432109876' }, -]; - -// 运营指标数据 -const metricsData = [ - { label: '每月算力', value: '1,200\nTH/s' }, - { label: '累计算力', value: '15,000\nTH/s' }, - { label: '每月挖矿量', value: '5.6 BTC' }, - { label: '累计挖矿量', value: '67.8 BTC' }, - { label: '每月佣金', value: '¥12,345' }, - { label: '累计佣金', value: '¥150,000' }, - { label: '每月累计认种\n提成', value: '¥8,900' }, -]; - /** * 格式化数字显示 */ @@ -120,19 +33,12 @@ function formatAmount(amount: string): string { /** * 数据统计页面 - * 基于 UIPro Figma 设计实现 * [2026-01-04] 更新:新增系统账户报表Tab * [2026-01-06] 更新:认种统计改为真实数据 */ export default function StatisticsPage() { // [2026-01-04] 新增:主Tab切换 - 数据统计 vs 系统账户 const [mainTab, setMainTab] = useState<'statistics' | 'system-accounts'>('statistics'); - // 趋势图时间维度 - const [trendPeriod, setTrendPeriod] = useState<'day' | 'week' | 'month' | 'quarter' | 'year'>('day'); - // 龙虎榜时间维度 - const [rankingTab, setRankingTab] = useState<'daily' | 'weekly' | 'monthly'>('daily'); - // 区域统计维度 - const [regionType, setRegionType] = useState<'province' | 'city'>('province'); // [2026-01-06] 新增:认种统计数据状态 const [plantingStats, setPlantingStats] = useState(null); @@ -186,291 +92,63 @@ export default function StatisticsPage() { {/* [2026-01-04] 新增:系统账户报表Tab内容 */} {mainTab === 'system-accounts' && } - {/* 原有统计内容 - 仅在 statistics tab 显示 */} + {/* 认种统计内容 - 仅在 statistics tab 显示 */} {mainTab === 'statistics' && ( <> - {/* 统计概览卡片 - [2026-01-06] 改为真实数据 */} -
-
-
榴莲树认种总量
- {statsLoading ? ( -

加载中...

- ) : statsError ? ( -

--

- ) : ( - <> -

- {formatNumber(plantingStats?.totalTreeCount ?? 0)} -

-
- 积分: {formatAmount(plantingStats?.totalAmount ?? '0')} + {/* 统计概览卡片 - [2026-01-06] 改为真实数据 */} +
+
+
榴莲树认种总量
+ {statsLoading ? ( +

加载中...

+ ) : statsError ? ( +

--

+ ) : ( + <> +

+ {formatNumber(plantingStats?.totalTreeCount ?? 0)} +

+
+ 积分: {formatAmount(plantingStats?.totalAmount ?? '0')} +
+ + )}
- - )} -
-
-
今日认种数量
- {statsLoading ? ( -

加载中...

- ) : statsError ? ( -

--

- ) : ( - <> -

- {formatNumber(plantingStats?.todayStats?.treeCount ?? 0)} -

-
- 积分: {formatAmount(plantingStats?.todayStats?.amount ?? '0')} +
+
今日认种数量
+ {statsLoading ? ( +

加载中...

+ ) : statsError ? ( +

--

+ ) : ( + <> +

+ {formatNumber(plantingStats?.todayStats?.treeCount ?? 0)} +

+
+ 积分: {formatAmount(plantingStats?.todayStats?.amount ?? '0')} +
+ + )}
- - )} -
-
-
本月认种数量
- {statsLoading ? ( -

加载中...

- ) : statsError ? ( -

--

- ) : ( - <> -

- {formatNumber(plantingStats?.monthStats?.treeCount ?? 0)} -

-
- 积分: {formatAmount(plantingStats?.monthStats?.amount ?? '0')} +
+
本月认种数量
+ {statsLoading ? ( +

加载中...

+ ) : statsError ? ( +

--

+ ) : ( + <> +

+ {formatNumber(plantingStats?.monthStats?.treeCount ?? 0)} +

+
+ 积分: {formatAmount(plantingStats?.monthStats?.amount ?? '0')} +
+ + )}
- - )} -
-
- - {/* 榴莲树认种数量趋势 */} -
-
- 榴莲树认种数量趋势 -
- {(['day', 'week', 'month', 'quarter', 'year'] as const).map((period) => ( - - ))} -
-
-
Chart Placeholder
-
- - {/* 龙虎榜与排名统计 */} -
-

龙虎榜与排名统计

-
- - - -
-
- {/* 排名表格 */} -
-
-
-
排名
-
账户
-
认种数量
-
所属省
-
所属市
-
- {rankingData.map((item) => ( -
-
{item.rank}
-
{item.account}
-
{item.count}
-
{item.province}
-
{item.city}
-
- ))} -
-
- - {/* 授权公司第一名 */} -
-
- 授权省公司第一名 -

广东省公司

-
完成数据: 2,345
-
-
- 授权市公司第一名 -

深圳市公司

-
完成数据: 1,120
-
-
-
-
- - {/* 区域认种数据统计 */} -
-
-

区域认种数据统计

-
- - -
-
-
-
- 各省认购数量 -
Bar Chart Placeholder
-
-
-
-
-
区域
-
时间周期
-
认购数量
-
占比
-
- {regionData.map((item, index) => ( -
-
{item.region}
-
{item.period}
-
{item.count.toLocaleString()}
-
{item.ratio}
-
- ))} -
-
-
-
- -
-
- - {/* 省/市公司运营统计 */} -
-
-

省 / 市公司运营统计

- -
-
- {metricsData.map((metric) => ( -
-
{metric.label}
- {metric.value} -
- ))} -
-
-
-
账户类型(省公司 / 市公司)
-
账户名称
-
统计月份
-
算力
-
挖矿量
-
佣金
-
- {operationData.map((item, index) => ( -
-
{item.type}
-
{item.name}
-
{item.month}
-
{item.hashrate}
-
{item.mining}
-
{item.commission}
-
- ))} -
-
- - {/* 收益明细与来源 */} -
-

收益明细与来源

-
-
- - -
-
- -
-
- - - - -
- -
-
-
-
-
-
时间
-
账户
-
收益来源
-
收益金额
-
相关地址
-
交易流水号
-
- {revenueData.map((item, index) => ( -
-
{item.time}
-
{item.account}
-
{item.source}
-
{item.amount}
-
{item.address}
-
{item.txId}
-
- ))} -
-
- -
-
+ )}