48 KiB
48 KiB
榴莲认种管理后台 (RWADurian Admin Web) - 前端开发规范文档
项目名称: RWADurian Admin Web
版本: 1.0.0
目标路径:rwadurian/frontend/admin-web
文档用途: 供 Claude Code 阅读并指导完成项目开发
目录
1. 项目概述
1.1 项目背景
榴莲认种管理后台是一个面向管理员的 Web 应用系统,用于管理榴莲树认种业务的全流程,包括用户管理、排名龙虎榜、省市公司授权、数据统计分析等核心功能。
1.2 核心功能模块
| 模块名称 | 路由路径 | 功能描述 |
|---|---|---|
| 登录认证 | /login |
管理员登录、忘记密码、注册入口 |
| 仪表板 | /dashboard |
数据概览、趋势图表、最近活动 |
| 用户管理 | /users |
用户列表、搜索筛选、批量操作 |
| 龙虎榜管理 | /leaderboard |
日/周/月榜配置、虚拟排名设置 |
| 授权管理 | /authorization |
省/市公司授权、考核规则配置 |
| 数据统计 | /statistics |
多维度数据分析、报表导出 |
| 系统设置 | /settings |
结算参数、限额、安全配置 |
| 帮助中心 | /help |
文档、FAQ、联系支持 |
1.3 目标用户
- 超级管理员: 拥有全部权限,可管理其他管理员账号
- 运营管理员: 日常运营操作,无敏感设置权限
- 数据分析员: 只读权限,专注数据查看和报表导出
2. 技术架构
2.1 技术栈
核心框架:
- React: 18.x
- Next.js: 15.x (App Router)
- TypeScript: 5.x
状态管理:
- Redux Toolkit: 全局状态(用户认证、系统配置)
- Zustand: 局部状态(表单、UI临时状态)
样式方案:
- 纯 CSS/SCSS Modules (无第三方 UI 库)
- CSS Variables 主题系统
- Figma 导出的自定义设计
数据可视化:
- Recharts 或 ECharts (图表库)
- D3.js (复杂可视化需求)
网络请求:
- Axios + React Query (TanStack Query)
工具链:
- ESLint + Prettier
- Husky + lint-staged
- Jest + React Testing Library
2.2 Clean Architecture 分层
┌─────────────────────────────────────────────────────────────┐
│ Presentation Layer │
│ (Pages, Components, Hooks) │
├─────────────────────────────────────────────────────────────┤
│ Application Layer │
│ (Use Cases, Services, State Management) │
├─────────────────────────────────────────────────────────────┤
│ Domain Layer │
│ (Entities, Value Objects, Domain Services) │
├─────────────────────────────────────────────────────────────┤
│ Infrastructure Layer │
│ (API Clients, Storage, External Services) │
└─────────────────────────────────────────────────────────────┘
3. 目录结构
admin-web/
├── public/
│ ├── assets/
│ │ ├── images/
│ │ │ ├── logo.svg
│ │ │ └── icons/
│ │ └── fonts/
│ └── locales/
│ └── zh-CN.json
│
├── src/
│ ├── app/ # Next.js App Router
│ │ ├── (auth)/
│ │ │ ├── login/
│ │ │ │ └── page.tsx
│ │ │ ├── forgot-password/
│ │ │ │ └── page.tsx
│ │ │ └── layout.tsx
│ │ │
│ │ ├── (dashboard)/
│ │ │ ├── dashboard/
│ │ │ │ └── page.tsx
│ │ │ ├── users/
│ │ │ │ ├── page.tsx
│ │ │ │ └── [id]/
│ │ │ │ └── page.tsx
│ │ │ ├── leaderboard/
│ │ │ │ └── page.tsx
│ │ │ ├── authorization/
│ │ │ │ └── page.tsx
│ │ │ ├── statistics/
│ │ │ │ └── page.tsx
│ │ │ ├── settings/
│ │ │ │ └── page.tsx
│ │ │ ├── help/
│ │ │ │ └── page.tsx
│ │ │ └── layout.tsx
│ │ │
│ │ ├── layout.tsx
│ │ ├── page.tsx
│ │ └── globals.css
│ │
│ ├── components/ # UI 组件
│ │ ├── common/ # 通用基础组件
│ │ │ ├── Button/
│ │ │ │ ├── Button.tsx
│ │ │ │ ├── Button.module.scss
│ │ │ │ └── index.ts
│ │ │ ├── Input/
│ │ │ ├── Select/
│ │ │ ├── Table/
│ │ │ ├── Modal/
│ │ │ ├── Card/
│ │ │ ├── Badge/
│ │ │ ├── Avatar/
│ │ │ ├── Pagination/
│ │ │ ├── Toggle/
│ │ │ ├── Dropdown/
│ │ │ ├── Tabs/
│ │ │ ├── Tooltip/
│ │ │ ├── Loading/
│ │ │ └── Toast/
│ │ │
│ │ ├── layout/ # 布局组件
│ │ │ ├── Sidebar/
│ │ │ ├── Header/
│ │ │ ├── Breadcrumb/
│ │ │ └── PageContainer/
│ │ │
│ │ ├── charts/ # 图表组件
│ │ │ ├── LineChart/
│ │ │ ├── BarChart/
│ │ │ ├── PieChart/
│ │ │ └── DonutChart/
│ │ │
│ │ └── features/ # 业务组件
│ │ ├── dashboard/
│ │ │ ├── StatCard/
│ │ │ ├── TrendChart/
│ │ │ ├── RegionDistribution/
│ │ │ └── RecentActivity/
│ │ ├── users/
│ │ │ ├── UserTable/
│ │ │ ├── UserFilters/
│ │ │ └── UserDetailModal/
│ │ ├── leaderboard/
│ │ │ ├── RankingTable/
│ │ │ ├── BoardSettings/
│ │ │ └── VirtualRankPreview/
│ │ ├── authorization/
│ │ │ ├── CompanyTable/
│ │ │ ├── AssessmentRules/
│ │ │ └── LadderTargetTable/
│ │ ├── statistics/
│ │ │ ├── TrendAnalysis/
│ │ │ ├── RegionStats/
│ │ │ ├── CompanyOperations/
│ │ │ └── RevenueDetails/
│ │ ├── settings/
│ │ │ ├── SettlementConfig/
│ │ │ ├── LeaderboardConfig/
│ │ │ ├── QuotaConfig/
│ │ │ ├── AssessmentConfig/
│ │ │ ├── DisplayConfig/
│ │ │ └── SecurityConfig/
│ │ └── help/
│ │ ├── DocumentCard/
│ │ ├── DocumentList/
│ │ ├── FAQSection/
│ │ └── ContactSupport/
│ │
│ ├── domain/ # 领域层
│ │ ├── entities/
│ │ │ ├── User.ts
│ │ │ ├── Company.ts
│ │ │ ├── Ranking.ts
│ │ │ ├── Statistics.ts
│ │ │ └── Settings.ts
│ │ ├── value-objects/
│ │ │ ├── UserId.ts
│ │ │ ├── Province.ts
│ │ │ └── Currency.ts
│ │ └── interfaces/
│ │ ├── IUserRepository.ts
│ │ ├── ICompanyRepository.ts
│ │ └── IStatisticsRepository.ts
│ │
│ ├── application/ # 应用层
│ │ ├── use-cases/
│ │ │ ├── auth/
│ │ │ │ ├── LoginUseCase.ts
│ │ │ │ └── LogoutUseCase.ts
│ │ │ ├── users/
│ │ │ │ ├── GetUsersUseCase.ts
│ │ │ │ ├── UpdateUserUseCase.ts
│ │ │ │ └── ExportUsersUseCase.ts
│ │ │ ├── leaderboard/
│ │ │ │ ├── GetRankingsUseCase.ts
│ │ │ │ └── UpdateBoardSettingsUseCase.ts
│ │ │ └── ...
│ │ │
│ │ ├── services/
│ │ │ ├── AuthService.ts
│ │ │ ├── UserService.ts
│ │ │ ├── LeaderboardService.ts
│ │ │ ├── AuthorizationService.ts
│ │ │ ├── StatisticsService.ts
│ │ │ └── SettingsService.ts
│ │ │
│ │ └── dto/
│ │ ├── UserDTO.ts
│ │ ├── CompanyDTO.ts
│ │ └── StatisticsDTO.ts
│ │
│ ├── infrastructure/ # 基础设施层
│ │ ├── api/
│ │ │ ├── client.ts # Axios 实例配置
│ │ │ ├── endpoints.ts # API 端点定义
│ │ │ └── repositories/
│ │ │ ├── UserRepository.ts
│ │ │ ├── CompanyRepository.ts
│ │ │ └── StatisticsRepository.ts
│ │ │
│ │ ├── storage/
│ │ │ ├── localStorage.ts
│ │ │ └── sessionStorage.ts
│ │ │
│ │ └── external/
│ │ └── exportService.ts # Excel 导出等
│ │
│ ├── store/ # 状态管理
│ │ ├── redux/
│ │ │ ├── store.ts
│ │ │ ├── rootReducer.ts
│ │ │ └── slices/
│ │ │ ├── authSlice.ts
│ │ │ ├── settingsSlice.ts
│ │ │ └── notificationSlice.ts
│ │ │
│ │ └── zustand/
│ │ ├── useUserFiltersStore.ts
│ │ ├── useLeaderboardStore.ts
│ │ └── useModalStore.ts
│ │
│ ├── hooks/ # 自定义 Hooks
│ │ ├── useAuth.ts
│ │ ├── useUsers.ts
│ │ ├── useLeaderboard.ts
│ │ ├── useStatistics.ts
│ │ ├── usePagination.ts
│ │ ├── useDebounce.ts
│ │ └── useExport.ts
│ │
│ ├── utils/ # 工具函数
│ │ ├── formatters.ts # 数字、日期格式化
│ │ ├── validators.ts # 表单验证
│ │ ├── constants.ts # 常量定义
│ │ └── helpers.ts # 通用辅助函数
│ │
│ ├── styles/ # 全局样式
│ │ ├── variables.scss # CSS 变量
│ │ ├── mixins.scss # SCSS Mixins
│ │ ├── typography.scss # 字体样式
│ │ ├── animations.scss # 动画定义
│ │ └── reset.scss # 样式重置
│ │
│ └── types/ # TypeScript 类型
│ ├── api.types.ts
│ ├── user.types.ts
│ ├── company.types.ts
│ ├── statistics.types.ts
│ └── common.types.ts
│
├── .env.local
├── .env.development
├── .env.production
├── .eslintrc.json
├── .prettierrc
├── next.config.js
├── tsconfig.json
├── package.json
└── README.md
4. 功能模块详解
4.1 登录认证模块 (/login)
页面布局
- 居中卡片式设计,浅灰色背景 (
#F5F5F5) - Logo + 系统名称 "榴莲认种管理后台"
- 欢迎语 "欢迎回来"
功能点
| 功能 | 描述 | 交互 |
|---|---|---|
| 邮箱输入 | 邮箱格式验证 | 失焦验证 |
| 密码输入 | 密码强度提示 | 实时验证 |
| 忘记密码 | 跳转密码重置页 | 链接跳转 |
| 登录按钮 | 提交登录请求 | Loading 状态 |
| 注册入口 | 跳转注册页面 | 链接跳转 |
表单验证规则
interface LoginForm {
email: string; // 必填,邮箱格式
password: string; // 必填,6-20位
}
4.2 仪表板模块 (/dashboard)
页面结构
┌─────────────────────────────────────────────────────────────┐
│ [Sidebar] │ [Header: 面包屑 + 操作按钮 + 用户信息] │
│ ├─────────────────────────────────────────────────┤
│ │ [统计卡片区: 4个卡片横向排列] │
│ ├───────────────────────────┬─────────────────────┤
│ │ [认种趋势图] │ [最近活动] │
│ ├───────────────────────────┤ │
│ │ [月度增长图] │ │
│ ├───────────────────────────┤ │
│ │ [区域分布饼图] │ │
└───────────┴───────────────────────────┴─────────────────────┘
统计卡片数据
| 卡片名称 | 数据字段 | 增长指标 |
|---|---|---|
| 总认种量 | totalAdoptions |
百分比增长 |
| 活跃用户 | activeUsers |
百分比增长 |
| 省级公司 | provincialCompanies |
百分比增长 |
| 市级公司 | cityCompanies |
百分比增长 |
图表组件
认种趋势折线图
interface TrendChartData {
date: string;
value: number;
}
// 支持时间范围切换: 7天/30天/90天
月度增长柱状图
interface MonthlyGrowthData {
month: string;
adoptions: number;
growth: number; // 环比增长
}
区域分布环形图
interface RegionDistributionData {
region: string;
percentage: number;
color: string;
}
最近活动列表
interface ActivityItem {
id: string;
type: 'user_register' | 'company_activity' | 'system_update' | 'report_generated';
icon: string;
title: string;
description: string;
timestamp: string; // "5分钟前", "2小时前", "昨天"
}
顶部操作按钮
- 添加用户: 打开添加用户弹窗
- 授权管理: 跳转授权管理页
- 查看报表: 跳转数据统计页(主按钮样式)
4.3 用户管理模块 (/users)
页面功能
搜索与筛选
interface UserFilters {
keyword: string; // 账户ID、昵称搜索
advancedFilters: {
province?: string; // 省份筛选
city?: string; // 城市筛选
rankRange?: [number, number]; // 排名范围
adoptionRange?: [number, number]; // 认种量范围
status?: 'active' | 'inactive';
};
}
用户表格列定义
| 列名 | 字段 | 宽度 | 排序 | 说明 |
|---|---|---|---|---|
| 复选框 | - | 48px | - | 批量选择 |
| 账户序号 | accountId |
100px | ✓ | 唯一标识 |
| 头像 | avatar |
60px | - | 圆形头像+在线状态指示 |
| 昵称 | nickname |
80px | ✓ | - |
| 账户认种量 | personalAdoptions |
100px | ✓ | - |
| 团队总注册地址量 | teamAddresses |
120px | ✓ | - |
| 团队总认种量 | teamAdoptions |
100px | ✓ | - |
| 团队本省认种量及占比 | provincialAdoptions |
140px | ✓ | 显示数量(占比%) |
| 团队本市认种量及占比 | cityAdoptions |
140px | ✓ | 显示数量(占比%) |
| 推荐人序列号 | referrerId |
100px | - | - |
| 龙虎榜排名 | ranking |
80px | ✓ | 显示"-"表示未上榜 |
| 操作 | - | 120px | - | 查看详情、编辑 |
批量操作
- 导出 Excel (选中项/全部)
- 批量编辑(修改状态等)
分页配置
interface PaginationConfig {
pageSize: 10 | 20 | 50 | 100;
current: number;
total: number;
}
4.4 龙虎榜管理模块 (/leaderboard)
页面布局
┌─────────────────────────────────────────────────────────────┐
│ [页面标题] [导出排名数据按钮] │
├─────────────────────────────────┬───────────────────────────┤
│ │ │
│ ┌─────────────────────────┐ │ 榜单设置 │
│ │ 日榜 [开关] │ │ ┌───────────────────┐ │
│ │ 排名表格... │ │ │ 虚拟排名设置 │ │
│ └─────────────────────────┘ │ │ - 启用开关 │ │
│ │ │ - 虚拟账户数量 │ │
│ ┌─────────────────────────┐ │ │ - 规则说明 │ │
│ │ 周榜 [开关] │ │ │ - 实时预览 │ │
│ │ 榜单未开启/排名表格 │ │ └───────────────────┘ │
│ └─────────────────────────┘ │ ┌───────────────────┐ │
│ │ │ 显示设置 │ │
│ ┌─────────────────────────┐ │ │ - 前端显示数量 │ │
│ │ 月榜 [开关] │ │ └───────────────────┘ │
│ │ 榜单未开启/排名表格 │ │ │
│ └─────────────────────────┘ │ [保存设置按钮] │
│ │ │
└─────────────────────────────────┴───────────────────────────┘
排名表格
interface RankingItem {
rank: number; // 1, 2, 3 显示奖牌图标
avatar: string;
nickname: string;
isVirtual: boolean; // 虚拟用户标签
adoptionCount: number; // X 棵
teamData: string; // 团队标识 (A队, B队, C队)
}
榜单设置
interface BoardSettings {
virtualRanking: {
enabled: boolean;
virtualAccountCount: number; // 滑块 0-10
ruleDescription: string;
};
displaySettings: {
frontendDisplayCount: 10 | 20 | 50; // 下拉选择
};
}
榜单开关状态
- 已开启: 显示排名表格
- 未开启: 显示空状态图标 + "榜单未开启" + "待激活"
4.5 授权管理模块 (/authorization)
页面分区
1. 授权省公司管理
interface ProvinceCompanyFilter {
province: string;
authStatus: 'authorized' | 'pending' | 'all';
keyword: string;
}
interface ProvinceCompanyItem {
avatar: string;
nickname: string;
accountId: string;
province: string;
teamAdoptions: number;
authStatus: 'authorized' | 'pending';
actions: ['authorize' | 'revoke'];
}
2. 省公司团队权益考核规则
interface ProvinceAssessmentRules {
firstTriggerThreshold: number; // 首次考核触发门槛 (棵)
stageUnitBenefit: number; // 考核阶段单棵权益 (USDT)
incrementalBenefit: number; // 达标后每新增1棵获得 (USDT)
assessmentCycle: 'monthly' | 'quarterly';
failureResetEnabled: boolean; // 未达成目标时权益失效并重置
}
3. 授权市公司管理
- 结构同省公司,增加城市筛选
4. 市公司团队权益考核规则
- 结构同省公司规则,阈值和权益数值不同
5. 正式省/市公司授权管理
- 通过全部阶梯性考核后的正式公司列表
6. 授权限制规则
interface AuthorizationLimits {
oneProvinceOneCompany: boolean; // 每省份仅授权1个
oneCityOneCompany: boolean; // 每城市仅授权1个
topRankingRequired: number; // 排名前N才具备资格
specialCityRules: {
beijing: boolean; // 北京特例
shanghai: boolean; // 上海特例
};
}
7. 阶梯性考核目标表
interface LadderTarget {
assessmentMonth: number; // 考核月 (1-9)
provinceMonthlyTarget: number; // 省代当月目标
provinceCumulativeTarget: number; // 省代累计目标
cityMonthlyTarget: number; // 市代当月目标
cityCumulativeTarget: number; // 市代累计目标
}
4.6 数据统计模块 (/statistics)
页面分区
1. 顶部统计概览
interface StatisticsOverview {
totalAdoptions: number; // 榴莲树认种总量
todayAdoptions: number; // 今日认种数量
monthlyAdoptions: number; // 本月认种数量
}
2. 认种数量趋势
- 时间维度切换: 日 / 周 / 月 / 季度 / 年度
- 折线图展示
3. 龙虎榜与排名统计
interface LeaderboardStats {
activeTab: 'daily' | 'weekly' | 'monthly';
rankings: Array<{
rank: number;
account: string;
adoptionCount: number;
province: string;
city: string;
}>;
topProvince: {
name: string;
completionData: number;
};
topCity: {
name: string;
completionData: number;
};
}
4. 区域认种数据统计
- 按省统计 / 按市统计 切换
- 柱状图 + 详情表格
interface RegionStats {
region: string;
period: string; // 2023-10
adoptionCount: number;
percentage: number;
}
5. 省/市公司运营统计
interface OperationStats {
summary: {
monthlyHashRate: string; // "1,200 TH/s"
cumulativeHashRate: string; // "15,000 TH/s"
monthlyMining: string; // "5.6 BTC"
cumulativeMining: string; // "67.8 BTC"
monthlyCommission: number; // ¥12,345
cumulativeCommission: number; // ¥150,000
monthlyAdoptionBonus: number; // ¥8,900
};
details: Array<{
accountType: 'province' | 'city';
accountName: string;
statMonth: string;
hashRate: string;
miningAmount: string;
commission: number;
}>;
}
6. 收益明细与来源
interface RevenueDetail {
timestamp: string;
account: string;
source: 'mining' | 'adoption_completion' | 'share';
amount: number; // 带+号显示正数
relatedAddress: string; // bc1...xyz
transactionId: string; // TXN1234567890
}
4.7 系统设置模块 (/settings)
设置分区
1. 结算参数设置
interface SettlementConfig {
availableCurrencies: Array<'BNB' | 'OG' | 'USDT' | 'DST'>;
defaultCurrency: string;
}
2. 龙虎榜设置
interface LeaderboardConfig {
virtualAccountEnabled: boolean;
virtualAccountCount: number;
boardSwitches: {
daily: boolean;
weekly: boolean;
monthly: boolean;
};
frontendDisplayCount: string; // "10, 20, 31"
}
3. 认种限额设置
interface QuotaConfig {
singleAccountQuota: {
enabled: boolean;
days: number;
maxCount: number;
};
networkTotalQuota: {
enabled: boolean;
days: number;
maxCount: number;
};
}
4. 考核规则设置
interface AssessmentConfig {
localUserPercentageThreshold: number; // 5%
exemptionEnabled: boolean; // 允许豁免
ladderTargets: LadderTarget[];
}
5. 前端展示设置
interface DisplayConfig {
allowNonAdopterViewHeatmap: boolean;
heatmapDisplayMode: 'exact_count' | 'level'; // 高/中/低
}
6. 后台账号与安全
interface SecurityConfig {
accounts: Array<{
username: string;
role: '超级管理员' | '运营人员';
status: 'active' | 'disabled';
lastLogin: string;
}>;
sensitiveOperationApprovers: number; // 审批人数
sensitiveOperations: string[]; // 需审批的操作
operationLogs: Array<{
timestamp: string;
operator: string;
type: string;
description: string;
approvalResult: 'approved' | 'pending' | 'rejected';
}>;
}
4.8 帮助中心模块 (/help)
页面分区
1. 搜索区
- 搜索文档或问题的输入框
2. 推荐文档卡片
interface RecommendedDoc {
title: string;
description: string;
helpfulCount: number;
notHelpfulCount: number;
}
固定展示3个推荐文档
3. 文档列表
interface DocumentItem {
title: string;
category: '系统设置' | '账号安全' | '数据统计' | '授权管理';
lastUpdated: string;
rating: {
helpful: boolean | null;
};
}
4. 常见问题 (FAQ)
interface FAQItem {
question: string;
answer: string;
expanded: boolean;
}
5. 联系支持
interface SupportInfo {
phone: string; // "400-123-4567"
workingHours: string; // "工作日 9:00 - 18:00"
email: string; // "support@durian-adopt.com"
onlineChat: boolean; // 在线客服入口
}
5. UI/UX 设计规范
5.1 色彩系统
// 主色调
$primary-color: #1565C0; // 主蓝色 - 按钮、链接、激活状态
$primary-light: #1E88E5; // 浅蓝色 - Hover 状态
$primary-dark: #0D47A1; // 深蓝色 - 点击状态
// 辅助色
$success-color: #4CAF50; // 成功绿
$warning-color: #F5A623; // 警告黄/金色
$error-color: #E53935; // 错误红
$info-color: #2196F3; // 信息蓝
// 中性色
$text-primary: #212121; // 主要文字
$text-secondary: #757575; // 次要文字
$text-disabled: #BDBDBD; // 禁用文字
$border-color: #E0E0E0; // 边框色
$background-color: #F5F5F5; // 页面背景
$card-background: #FFFFFF; // 卡片背景
$sidebar-background: #1565C0; // 侧边栏背景
// 语义色
$increase-color: #4CAF50; // 增长 (+5.6%)
$decrease-color: #E53935; // 下降
5.2 字体系统
// 字体族
$font-family-base: 'PingFang SC', 'Microsoft YaHei', -apple-system, BlinkMacSystemFont, sans-serif;
$font-family-number: 'DIN Alternate', 'Roboto', $font-family-base;
// 字号
$font-size-xs: 12px; // 辅助文字、标签
$font-size-sm: 13px; // 表格内容
$font-size-base: 14px; // 正文
$font-size-md: 16px; // 小标题
$font-size-lg: 18px; // 二级标题
$font-size-xl: 20px; // 页面标题
$font-size-xxl: 24px; // 大数字
$font-size-display: 32px; // 统计数字
// 行高
$line-height-tight: 1.25;
$line-height-base: 1.5;
$line-height-loose: 1.75;
// 字重
$font-weight-regular: 400;
$font-weight-medium: 500;
$font-weight-semibold: 600;
$font-weight-bold: 700;
5.3 间距系统
// 基础间距 (4px 为基础单位)
$spacing-xs: 4px;
$spacing-sm: 8px;
$spacing-md: 12px;
$spacing-base: 16px;
$spacing-lg: 20px;
$spacing-xl: 24px;
$spacing-xxl: 32px;
$spacing-xxxl: 48px;
// 组件内间距
$padding-card: 24px;
$padding-modal: 24px;
$padding-input: 12px 16px;
$padding-button: 10px 24px;
// 页面边距
$page-padding: 24px;
$sidebar-width: 240px;
$sidebar-collapsed-width: 64px;
5.4 圆角系统
$border-radius-sm: 4px; // 小按钮、标签
$border-radius-base: 8px; // 输入框、卡片
$border-radius-lg: 12px; // 大卡片、弹窗
$border-radius-xl: 16px; // 特殊组件
$border-radius-round: 50%; // 圆形头像
$border-radius-pill: 999px; // 药丸形状
5.5 阴影系统
$shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
$shadow-base: 0 2px 8px rgba(0, 0, 0, 0.08);
$shadow-md: 0 4px 12px rgba(0, 0, 0, 0.1);
$shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.12);
$shadow-xl: 0 16px 48px rgba(0, 0, 0, 0.15);
5.6 动画系统
// 时长
$duration-fast: 150ms;
$duration-base: 250ms;
$duration-slow: 350ms;
// 缓动函数
$ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
$ease-out: cubic-bezier(0, 0, 0.2, 1);
$ease-in: cubic-bezier(0.4, 0, 1, 1);
// 常用动画
@mixin transition-base {
transition: all $duration-base $ease-in-out;
}
@mixin hover-lift {
transition: transform $duration-fast $ease-out, box-shadow $duration-fast $ease-out;
&:hover {
transform: translateY(-2px);
box-shadow: $shadow-md;
}
}
6. 组件设计指南
6.1 基础组件清单
Button 按钮
interface ButtonProps {
variant: 'primary' | 'secondary' | 'outline' | 'ghost' | 'danger';
size: 'sm' | 'md' | 'lg';
icon?: ReactNode;
iconPosition?: 'left' | 'right';
loading?: boolean;
disabled?: boolean;
fullWidth?: boolean;
children: ReactNode;
onClick?: () => void;
}
样式规范:
- Primary: 蓝色填充背景
#1565C0,白色文字 - Secondary: 白色背景,蓝色边框和文字
- Outline: 透明背景,灰色边框
- Ghost: 无边框,悬停显示背景
- Danger: 红色填充背景
Input 输入框
interface InputProps {
type: 'text' | 'password' | 'email' | 'number';
size: 'sm' | 'md' | 'lg';
placeholder?: string;
prefix?: ReactNode; // 前置图标
suffix?: ReactNode; // 后置图标/清除按钮
error?: string;
disabled?: boolean;
value: string;
onChange: (value: string) => void;
}
Select 下拉选择
interface SelectProps<T> {
options: Array<{ label: string; value: T }>;
value: T;
onChange: (value: T) => void;
placeholder?: string;
multiple?: boolean;
searchable?: boolean;
disabled?: boolean;
}
Table 表格
interface TableProps<T> {
columns: Array<{
key: string;
title: string;
width?: number;
sortable?: boolean;
render?: (value: any, record: T) => ReactNode;
}>;
data: T[];
loading?: boolean;
pagination?: PaginationConfig;
rowSelection?: {
selectedRowKeys: string[];
onChange: (keys: string[]) => void;
};
onRowClick?: (record: T) => void;
}
Modal 弹窗
interface ModalProps {
visible: boolean;
title: string;
width?: number;
onClose: () => void;
onConfirm?: () => void;
confirmText?: string;
cancelText?: string;
loading?: boolean;
children: ReactNode;
}
Card 卡片
interface CardProps {
title?: string;
extra?: ReactNode; // 右上角操作区
padding?: boolean;
shadow?: boolean;
children: ReactNode;
}
6.2 布局组件
Sidebar 侧边栏
interface SidebarProps {
collapsed: boolean;
onCollapse: (collapsed: boolean) => void;
activeKey: string;
menuItems: Array<{
key: string;
icon: ReactNode;
label: string;
path: string;
badge?: number;
}>;
}
菜单项结构:
const menuItems = [
{ key: 'dashboard', icon: <DashboardIcon />, label: '仪表板', path: '/dashboard' },
{ key: 'users', icon: <UsersIcon />, label: '用户管理', path: '/users' },
{ key: 'leaderboard', icon: <TrophyIcon />, label: '龙虎榜', path: '/leaderboard' },
{ key: 'authorization', icon: <AuthIcon />, label: '授权管理', path: '/authorization' },
{ key: 'statistics', icon: <ChartIcon />, label: '数据统计', path: '/statistics' },
{ key: 'settings', icon: <SettingsIcon />, label: '系统设置', path: '/settings' },
// 底部固定
{ key: 'help', icon: <HelpIcon />, label: '帮助中心', path: '/help', position: 'bottom' },
{ key: 'logout', icon: <LogoutIcon />, label: '退出登录', path: '/logout', position: 'bottom' },
];
Header 顶部栏
interface HeaderProps {
title: string;
breadcrumb: Array<{ label: string; path?: string }>;
actions?: ReactNode;
user: {
name: string;
role: string;
avatar: string;
};
notifications?: number;
}
6.3 图表组件
StatCard 统计卡片
interface StatCardProps {
title: string;
value: number | string;
suffix?: string; // "棵", "人"
change?: {
value: number;
trend: 'up' | 'down';
};
icon?: ReactNode;
color?: string;
}
视觉规范:
- 卡片白色背景,8px 圆角
- 数字使用
$font-family-number,32px 字号 - 增长指标使用绿色,下降使用红色
- 带
+或-前缀
LineChart 折线图
interface LineChartProps {
data: Array<{ x: string; y: number }>;
xAxisKey: string;
yAxisKey: string;
color?: string;
gradient?: boolean; // 面积渐变填充
height?: number;
}
BarChart 柱状图
interface BarChartProps {
data: Array<{ category: string; value: number }>;
colors?: string[];
horizontal?: boolean;
showLabels?: boolean;
height?: number;
}
DonutChart 环形图
interface DonutChartProps {
data: Array<{ name: string; value: number; color: string }>;
innerRadius?: number;
outerRadius?: number;
centerContent?: ReactNode; // 中心显示内容
}
7. 状态管理方案
7.1 Redux Toolkit (全局状态)
用于管理需要跨页面持久化的状态:
// store/redux/slices/authSlice.ts
interface AuthState {
user: User | null;
token: string | null;
isAuthenticated: boolean;
permissions: string[];
}
// store/redux/slices/settingsSlice.ts
interface SettingsState {
sidebarCollapsed: boolean;
theme: 'light' | 'dark';
language: 'zh-CN' | 'en-US';
}
// store/redux/slices/notificationSlice.ts
interface NotificationState {
unreadCount: number;
notifications: Notification[];
}
7.2 Zustand (局部状态)
用于管理页面级别的临时状态:
// store/zustand/useUserFiltersStore.ts
interface UserFiltersStore {
keyword: string;
province: string;
city: string;
status: string;
setKeyword: (keyword: string) => void;
setFilters: (filters: Partial<UserFilters>) => void;
resetFilters: () => void;
}
// store/zustand/useLeaderboardStore.ts
interface LeaderboardStore {
activeBoard: 'daily' | 'weekly' | 'monthly';
virtualSettings: VirtualSettings;
setActiveBoard: (board: string) => void;
updateVirtualSettings: (settings: Partial<VirtualSettings>) => void;
}
// store/zustand/useModalStore.ts
interface ModalStore {
activeModal: string | null;
modalData: any;
openModal: (name: string, data?: any) => void;
closeModal: () => void;
}
7.3 React Query (服务端状态)
用于管理 API 数据缓存:
// hooks/useUsers.ts
export const useUsers = (filters: UserFilters) => {
return useQuery({
queryKey: ['users', filters],
queryFn: () => userService.getUsers(filters),
staleTime: 5 * 60 * 1000, // 5分钟缓存
});
};
// hooks/useStatistics.ts
export const useStatistics = (period: string) => {
return useQuery({
queryKey: ['statistics', period],
queryFn: () => statisticsService.getOverview(period),
refetchInterval: 30 * 1000, // 30秒自动刷新
});
};
8. API 集成规范
8.1 API 客户端配置
// infrastructure/api/client.ts
import axios from 'axios';
const apiClient = axios.create({
baseURL: process.env.NEXT_PUBLIC_API_BASE_URL,
timeout: 30000,
headers: {
'Content-Type': 'application/json',
},
});
// 请求拦截器
apiClient.interceptors.request.use((config) => {
const token = store.getState().auth.token;
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
// 响应拦截器
apiClient.interceptors.response.use(
(response) => response.data,
(error) => {
if (error.response?.status === 401) {
store.dispatch(logout());
router.push('/login');
}
return Promise.reject(error);
}
);
8.2 API 端点定义
// infrastructure/api/endpoints.ts
export const API_ENDPOINTS = {
// 认证
AUTH: {
LOGIN: '/auth/login',
LOGOUT: '/auth/logout',
REFRESH: '/auth/refresh',
FORGOT_PASSWORD: '/auth/forgot-password',
},
// 用户管理
USERS: {
LIST: '/users',
DETAIL: (id: string) => `/users/${id}`,
UPDATE: (id: string) => `/users/${id}`,
EXPORT: '/users/export',
},
// 龙虎榜
LEADERBOARD: {
RANKINGS: '/leaderboard/rankings',
SETTINGS: '/leaderboard/settings',
EXPORT: '/leaderboard/export',
},
// 授权管理
AUTHORIZATION: {
PROVINCE_COMPANIES: '/authorization/province-companies',
CITY_COMPANIES: '/authorization/city-companies',
ASSESSMENT_RULES: '/authorization/assessment-rules',
LADDER_TARGETS: '/authorization/ladder-targets',
},
// 数据统计
STATISTICS: {
OVERVIEW: '/statistics/overview',
TREND: '/statistics/trend',
REGION: '/statistics/region',
OPERATIONS: '/statistics/operations',
REVENUE: '/statistics/revenue',
},
// 系统设置
SETTINGS: {
ALL: '/settings',
SETTLEMENT: '/settings/settlement',
LEADERBOARD: '/settings/leaderboard',
QUOTA: '/settings/quota',
ASSESSMENT: '/settings/assessment',
DISPLAY: '/settings/display',
SECURITY: '/settings/security',
},
// 帮助中心
HELP: {
DOCUMENTS: '/help/documents',
FAQ: '/help/faq',
SEARCH: '/help/search',
},
};
8.3 通用响应格式
// types/api.types.ts
interface ApiResponse<T> {
code: number;
message: string;
data: T;
}
interface PaginatedResponse<T> {
code: number;
message: string;
data: {
list: T[];
pagination: {
current: number;
pageSize: number;
total: number;
};
};
}
9. 开发规范与约定
9.1 命名规范
// 文件命名
components/Button/Button.tsx // PascalCase 组件
components/Button/Button.module.scss // 样式模块
hooks/useAuth.ts // camelCase hooks
utils/formatters.ts // camelCase 工具
types/user.types.ts // kebab-case 类型文件
// 变量命名
const userName = 'admin'; // camelCase 变量
const MAX_RETRY_COUNT = 3; // UPPER_SNAKE_CASE 常量
const UserRole = { ADMIN: 'admin' }; // PascalCase 枚举
// 组件命名
const UserListPage = () => {}; // PascalCase 组件
const useUserData = () => {}; // use 前缀 hooks
// CSS 类命名 (BEM 风格)
.button {}
.button--primary {}
.button--disabled {}
.button__icon {}
9.2 代码组织
// 组件文件结构
// components/Button/Button.tsx
import { FC } from 'react';
import styles from './Button.module.scss';
import type { ButtonProps } from './Button.types';
// 1. 类型定义 (或单独文件)
// 2. 常量定义
// 3. 辅助函数
// 4. 组件定义
// 5. 导出
export const Button: FC<ButtonProps> = ({
variant = 'primary',
size = 'md',
children,
...props
}) => {
return (
<button
className={`${styles.button} ${styles[`button--${variant}`]} ${styles[`button--${size}`]}`}
{...props}
>
{children}
</button>
);
};
9.3 Git 提交规范
# 格式: <type>(<scope>): <subject>
feat(users): 添加用户列表分页功能
fix(auth): 修复登录token失效问题
style(button): 调整按钮hover状态样式
refactor(api): 重构API请求拦截器
docs(readme): 更新项目说明文档
test(users): 添加用户服务单元测试
chore(deps): 更新依赖版本
9.4 注释规范
/**
* 用户服务类
* 处理所有用户相关的业务逻辑
*/
class UserService {
/**
* 获取用户列表
* @param filters - 筛选条件
* @param pagination - 分页参数
* @returns 用户列表响应
*/
async getUsers(
filters: UserFilters,
pagination: PaginationParams
): Promise<PaginatedResponse<User>> {
// TODO: 添加缓存优化
// FIXME: 处理边界情况
return apiClient.get(API_ENDPOINTS.USERS.LIST, {
params: { ...filters, ...pagination },
});
}
}
10. 开发优先级与里程碑
Phase 1: 基础框架搭建 (Week 1-2)
目标: 完成项目基础架构和核心组件库
├── 项目初始化
│ ├── Next.js 15 项目创建
│ ├── TypeScript 配置
│ ├── ESLint + Prettier 配置
│ ├── 目录结构创建
│ └── 环境变量配置
│
├── 样式系统
│ ├── CSS 变量定义
│ ├── SCSS Mixins
│ ├── 全局样式重置
│ └── 字体引入
│
├── 基础组件 (10个)
│ ├── Button
│ ├── Input
│ ├── Select
│ ├── Table (基础版)
│ ├── Modal
│ ├── Card
│ ├── Badge
│ ├── Avatar
│ ├── Loading
│ └── Toast
│
└── 布局组件
├── Sidebar
├── Header
└── PageContainer
Phase 2: 认证与仪表板 (Week 3)
目标: 完成登录流程和仪表板页面
├── 登录模块
│ ├── 登录页面 UI
│ ├── 表单验证
│ ├── 登录 API 集成
│ ├── Token 管理
│ └── 路由守卫
│
├── 仪表板模块
│ ├── 统计卡片组件
│ ├── 折线图组件
│ ├── 柱状图组件
│ ├── 环形图组件
│ ├── 最近活动列表
│ └── 数据获取与展示
│
└── 状态管理
├── Redux Store 配置
├── Auth Slice
└── React Query 配置
Phase 3: 用户管理 (Week 4)
目标: 完成用户管理全部功能
├── 用户列表
│ ├── 表格组件完善
│ ├── 搜索功能
│ ├── 高级筛选
│ ├── 分页功能
│ └── 排序功能
│
├── 用户操作
│ ├── 查看详情弹窗
│ ├── 编辑用户
│ ├── 批量选择
│ └── 导出 Excel
│
└── Zustand 集成
└── 用户筛选状态管理
Phase 4: 龙虎榜与授权 (Week 5-6)
目标: 完成龙虎榜和授权管理模块
├── 龙虎榜模块
│ ├── 日/周/月榜切换
│ ├── 排名表格
│ ├── 榜单开关
│ ├── 虚拟排名设置
│ ├── 显示设置
│ └── 导出功能
│
└── 授权管理模块
├── 省公司管理
├── 市公司管理
├── 考核规则配置
├── 限制规则设置
└── 阶梯目标表格
Phase 5: 数据统计 (Week 7)
目标: 完成数据统计全部图表和报表
├── 统计概览
│ ├── 顶部统计卡片
│ └── 趋势图表
│
├── 详细统计
│ ├── 龙虎榜统计
│ ├── 区域数据统计
│ ├── 公司运营统计
│ └── 收益明细
│
└── 导出功能
├── 运营报表导出
└── 明细数据导出
Phase 6: 系统设置与帮助 (Week 8)
目标: 完成系统设置和帮助中心
├── 系统设置
│ ├── 结算参数
│ ├── 龙虎榜设置
│ ├── 认种限额
│ ├── 考核规则
│ ├── 前端展示
│ └── 账号与安全
│
├── 帮助中心
│ ├── 搜索功能
│ ├── 推荐文档
│ ├── 文档列表
│ ├── FAQ
│ └── 联系支持
│
└── 全局功能
├── 通知系统
└── 操作日志
Phase 7: 测试与优化 (Week 9-10)
目标: 完成测试、性能优化和上线准备
├── 测试
│ ├── 单元测试
│ ├── 集成测试
│ └── E2E 测试
│
├── 性能优化
│ ├── 代码分割
│ ├── 图片优化
│ ├── 缓存策略
│ └── Bundle 分析
│
└── 部署准备
├── CI/CD 配置
├── 环境配置
└── 监控接入
附录
A. 图标资源
建议使用以下图标来源:
- 侧边栏菜单图标: 自定义 SVG 或 Lucide Icons
- 操作图标: 保持与 Figma 设计一致
B. 第三方库版本
{
"dependencies": {
"react": "^18.2.0",
"next": "^15.0.0",
"typescript": "^5.0.0",
"@reduxjs/toolkit": "^2.0.0",
"zustand": "^4.4.0",
"@tanstack/react-query": "^5.0.0",
"axios": "^1.6.0",
"recharts": "^2.10.0",
"xlsx": "^0.18.5",
"dayjs": "^1.11.0",
"clsx": "^2.0.0"
}
}
C. 环境变量
# .env.local
NEXT_PUBLIC_API_BASE_URL=http://localhost:8080/api
NEXT_PUBLIC_APP_NAME=榴莲认种管理后台
NEXT_PUBLIC_VERSION=1.0.0
文档版本: 1.0.0
最后更新: 2024年
维护者: Claude Code