实现已认种果树所有权在用户间转让的完整功能。采用方案一: 独立 transfer-service 微服务 + Saga 编排器模式。 === 架构设计 === - Saga 编排器 8 步正向流程:卖方确认 → 冻结资金 → 锁定树 → 变更所有权 → 调整算力 → 更新统计 → 结算资金 → 完成 - 补偿回滚:任一步骤失败自动反向补偿(解冻资金 → 解锁树) - 13 种状态:PENDING → SELLER_CONFIRMED → PAYMENT_FROZEN → TREES_LOCKED → OWNERSHIP_TRANSFERRED → CONTRIBUTION_ADJUSTED → STATS_UPDATED → PAYMENT_SETTLED → COMPLETED / CANCELLED / FAILED / ROLLING_BACK / ROLLED_BACK === Phase 1-2: transfer-service(独立微服务) === 新建文件: - Prisma Schema:transfer_orders + transfer_status_logs + outbox_events - Domain:TransferOrder 聚合根 + TransferFeeService(5% 手续费) - Application:TransferApplicationService + SagaOrchestratorService - Infrastructure:Kafka 事件消费/生产 + Outbox Pattern - API:TransferController(用户端)+ AdminTransferController(管理端) - External Clients:wallet/planting/identity-service HTTP 客户端 - Docker + 环境配置 === Phase 3: 现有微服务扩展(纯追加) === planting-service: - Prisma schema 追加 transferLockId 可空字段 - InternalTransferController:锁定/解锁/执行 3 个新端点 - Kafka handlers:transfer-lock/execute/rollback 事件处理 - main.ts 追加 Kafka consumer group 配置 referral-service: - PlantingTransferredHandler:处理转让后团队统计更新 - TeamStatisticsAggregate 追加 handleTransfer() 方法 - TeamStatisticsRepository 追加 adjustForTransfer() 方法 - ProvinceCityDistribution 追加 transferTrees() 方法 contribution-service: - TransferOwnershipHandler:处理所有权变更事件 - TransferAdjustmentService:算力调整(879 行核心逻辑) - Prisma schema 追加 transferOrderId 可空字段 - ContributionAccount 追加 applyTransferAdjustment() 方法 === Phase 4A: wallet-service(3 个新内部端点) === 新建文件: - FreezeForTransferDto / UnfreezeForTransferDto / SettleTransferDto - FreezeForTransferCommand / UnfreezeForTransferCommand / SettleTransferPaymentCommand - InternalTransferWalletController(POST freeze/unfreeze/settle-transfer) 修改文件: - wallet-application.service.ts 追加 3 组方法(+437 行): freezeForTransfer / unfreezeForTransfer / settleTransferPayment (乐观锁 + 3 次重试 + Prisma $transaction + 幂等检查) - 结算操作:单事务内更新 3 个钱包(买方扣减 + 卖方入账 + 手续费归集) === Phase 4B: admin-web(转让管理页面) === 新建文件: - transferService.ts:API 调用服务 + 完整类型定义 - useTransfers.ts:React Query hooks(list/detail/stats/forceCancel) - /transfers/page.tsx:列表页(统计卡片 + 搜索筛选 + 分页 + 13 种状态 badge) - /transfers/[transferOrderNo]/page.tsx:详情页(Saga 时间线 + 状态日志 + 强制取消) - transfers.module.scss:完整样式 修改文件: - endpoints.ts 追加 TRANSFERS 端点配置 - Sidebar.tsx 追加「转让管理」菜单项 - hooks/index.ts 追加 useTransfers 导出 === Phase 4C: mobile-app(转让 UI) === 新建文件: - transfer_service.dart:Flutter API 服务 + Model(TransferOrder/Detail/StatusLog) - transfer_list_page.dart:转让记录列表(全部/转出/转入 Tab + 下拉刷新) - transfer_detail_page.dart:转让详情(Saga 时间线 + 确认/取消操作) - transfer_initiate_page.dart:发起转让表单(手续费自动计算) 修改文件: - injection_container.dart 追加 transferServiceProvider - route_paths.dart + route_names.dart 追加 3 个路由 - app_router.dart 追加 3 个 GoRoute - profile_page.dart 追加「发起转让」+「转让记录」按钮行 === 基础设施 === - docker-compose.yml 追加 transfer-service 容器配置 - deploy.sh 追加 transfer-service 部署 - init-databases.sh 追加 transfer_db 数据库初始化 === 纯新增原则 === 所有变更均为追加式修改,不修改任何现有业务逻辑: - 新增 nullable 字段(不影响现有数据) - 新增 enum 值(不影响现有枚举使用) - 新增 providers/controllers(不影响现有依赖注入) - 新增页面/路由(不影响现有页面行为) 回滚方式:删除 transfer-service 目录 + 移除各服务中带 [2026-02-19] 标记的代码 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| nginx | ||
| public | ||
| scripts | ||
| src | ||
| .dockerignore | ||
| .env.development | ||
| .env.production | ||
| .eslintrc.json | ||
| .gitignore | ||
| .prettierrc | ||
| Dockerfile | ||
| README.md | ||
| deploy.sh | ||
| docker-compose.yml | ||
| next.config.ts | ||
| package-lock.json | ||
| package.json | ||
| tsconfig.json | ||
README.md
RWADurian Admin Web
榴莲认种管理后台 - Next.js 15 + TypeScript + SCSS
技术栈
- 框架: Next.js 15 (App Router)
- 语言: TypeScript
- 样式: SCSS Modules
- 状态管理: Redux Toolkit + Zustand
- UI 组件: Recharts (图表)
- 部署: Docker + Nginx
本地开发
环境要求
- Node.js 20+
- npm 或 yarn
安装依赖
npm install
启动开发服务器
npm run dev
构建
npm run build
npm start
Docker 部署
快速部署 (推荐)
项目已配置 Docker 一键部署方案,使用 Git 管理代码。
在服务器上部署:
# 1. 克隆项目 (首次)
git clone <repository-url>
cd rwadurian/frontend/admin-web
# 2. 或更新代码 (已有项目)
cd ~/rwadurian/frontend/admin-web
git pull
# 3. 赋予脚本执行权限
chmod +x scripts/*.sh deploy.sh nginx/*.sh
# 4. 一键部署 Docker 应用
./scripts/deploy.sh
# 5. 安装 Nginx + SSL (首次需要)
sudo ./nginx/install.sh
Docker 管理脚本
| 脚本 | 功能 |
|---|---|
./scripts/deploy.sh |
一键部署 (构建+启动) |
./scripts/build.sh |
仅构建镜像 |
./scripts/start.sh |
启动服务 |
./scripts/stop.sh |
停止服务 |
./scripts/restart.sh |
重启服务 |
./scripts/logs.sh |
查看实时日志 |
./scripts/status.sh |
查看服务状态 |
./scripts/health.sh |
健康检查 |
./scripts/clean.sh |
清理容器和镜像 |
使用原始 deploy.sh
# 启动服务
./deploy.sh start
# 停止服务
./deploy.sh stop
# 重启服务
./deploy.sh restart
# 查看日志
./deploy.sh logs
# 查看状态
./deploy.sh status
# 清理
./deploy.sh clean
自定义端口
PORT=8080 ./scripts/deploy.sh
Nginx 配置
前提条件
- 域名 DNS A 记录已指向服务器 IP
- 防火墙开放 80 和 443 端口
- Docker 应用已在 3000 端口运行
一键安装 (推荐)
cd nginx
sudo ./install.sh
脚本会自动完成:
- 系统更新
- 安装 Nginx
- 安装 Certbot
- 配置防火墙
- 申请 Let's Encrypt SSL 证书
- 配置 HTTPS 反向代理
手动配置
项目结构
admin-web/
├── src/
│ ├── app/ # Next.js App Router
│ │ ├── (auth)/ # 认证相关页面 (登录、注册)
│ │ ├── (dashboard)/ # 仪表板页面
│ │ └── api/ # API 路由
│ ├── components/ # React 组件
│ │ ├── common/ # 通用组件
│ │ ├── features/ # 功能组件
│ │ └── layout/ # 布局组件
│ ├── store/ # 状态管理
│ │ ├── redux/ # Redux Toolkit
│ │ └── zustand/ # Zustand stores
│ ├── services/ # API 服务
│ ├── utils/ # 工具函数
│ └── styles/ # 全局样式
├── public/ # 静态资源
├── nginx/ # Nginx 配置
│ ├── README.md # Nginx 部署文档
│ ├── install.sh # 一键安装脚本
│ ├── setup-ssl.sh # SSL 配置脚本
│ └── rwaadmin.szaiai.com.conf # Nginx 站点配置
├── scripts/ # Docker 管理脚本
├── Dockerfile # Docker 镜像构建
├── docker-compose.yml # Docker 编排
├── deploy.sh # 部署脚本
└── README.md # 本文档
环境变量
项目使用不同的环境配置文件:
.env.local- 本地开发.env.development- 开发环境.env.production- 生产环境
功能特性
- ✅ 用户管理
- ✅ 排行榜
- ✅ 权限管理
- ✅ 数据统计
- ✅ 系统设置
- ✅ 帮助中心
- ✅ 侧边栏收起/展开
- ✅ 响应式布局
- ✅ 健康检查 API
API 端点
GET /api/health- 健康检查
访问地址
- 本地开发: http://localhost:3000
- 生产环境: https://rwaadmin.szaiai.com
常见问题
1. Docker 构建失败
确保本地有 .next 和 node_modules 已添加到 .dockerignore
2. 502 Bad Gateway
检查 Docker 容器是否运行:
docker ps
./scripts/status.sh
3. SSL 证书申请失败
- 确认域名 DNS 解析正确
- 确认 80 端口可访问
- 查看错误日志:
sudo tail -f /var/log/letsencrypt/letsencrypt.log
许可证
MIT