Add comprehensive development guides for all platform components
- 00-UI设计需求 v1.1: AI Agent deep integration specs - 01-Flutter移动端: Consumer + Merchant App (Riverpod + Clean Architecture) - 02-Flutter管理后台: Issuer Console App (credit scoring, template-based issuance) - 03-Web管理前端: Admin Dashboard (React + Next.js + Zustand + RTK) - 04-小程序H5: Mini-program + H5 (Taro 3.x cross-platform) - 05-后端: Backend services (NestJS + Go + DDD + Kong + PostgreSQL) - 06-区块链: Genex Chain + 7-contract system (Cosmos SDK + cosmos/evm + Solidity) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
aa449d6bd3
commit
a0d2271cd5
|
|
@ -0,0 +1,461 @@
|
||||||
|
# Genex 平台 - UI设计需求文档
|
||||||
|
|
||||||
|
> 基于《软件需求规格 v4.1》提取的全部界面设计需求。所有界面遵循 **Web2体验原则**:零区块链术语,与支付宝/Zelle一致的使用体验。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 设计原则
|
||||||
|
|
||||||
|
1. **零区块链感知**:用户界面不出现"钱包/链上/Gas/哈希/NFT"等术语
|
||||||
|
2. **术语映射**:我的券(非NFT)、订单号(非TX Hash)、余额(非USDC)、转赠(非Transfer)
|
||||||
|
3. **3秒规则**:核心操作(购买/核销/转赠)3步以内完成
|
||||||
|
4. **信息层级**:关键信息一屏可见,详情按需展开
|
||||||
|
5. **AI Agent优先**:所有端深度融合AI Agent,AI作为用户管理和使用券资源的核心助手
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## AI Agent 设计规范
|
||||||
|
|
||||||
|
> 所有客户端(消费者端、商户端、发行方管理端、Web管理端、小程序/H5)均深度融合AI Agent,用于协助用户使用和管理平台全部券资源。
|
||||||
|
|
||||||
|
### 总体设计原则
|
||||||
|
|
||||||
|
1. **全局入口**:所有端右下角悬浮AI助手按钮(可拖拽),点击展开对话面板
|
||||||
|
2. **上下文感知**:AI Agent感知当前页面、用户身份、持券状态、交易历史,主动提供相关建议
|
||||||
|
3. **自然语言交互**:支持文字和语音输入,理解券交易领域语义
|
||||||
|
4. **操作代理**:AI不仅提供建议,还可代用户执行操作(需用户确认)
|
||||||
|
5. **多模态理解**:支持截图识别券信息、拍照识别线下优惠券导入
|
||||||
|
|
||||||
|
### AI Agent 通用UI组件
|
||||||
|
|
||||||
|
| 组件 | 说明 | 交互 |
|
||||||
|
|------|------|------|
|
||||||
|
| **悬浮入口按钮** | 圆形AI图标按钮,右下角悬浮,显示未读建议数量红点 | 点击展开对话面板,长按显示快捷操作 |
|
||||||
|
| **对话面板** | 底部Sheet或侧边抽屉,支持文字/语音输入 | 流式输出回答,支持富文本(券卡片、图表、操作按钮) |
|
||||||
|
| **快捷建议条** | 页面顶部/底部横向滚动的AI建议标签 | 如"这张券3天后到期,建议今天使用",点击执行建议 |
|
||||||
|
| **智能卡片** | AI主动推送的建议卡片,嵌入信息流 | 出现在首页Feed、我的券列表中,可关闭/执行 |
|
||||||
|
| **操作确认弹窗** | AI代理执行操作前的二次确认 | 展示操作详情,用户确认后执行 |
|
||||||
|
|
||||||
|
### 各端AI Agent功能
|
||||||
|
|
||||||
|
#### 消费者端AI Agent
|
||||||
|
|
||||||
|
| 场景 | AI能力 | UI表现 |
|
||||||
|
|------|--------|--------|
|
||||||
|
| **智能选券** | 根据用户偏好、消费记录、位置推荐最优券 | 首页智能推荐Feed + 对话中推荐券卡片 |
|
||||||
|
| **价格顾问** | 分析券价格走势,提示最佳买入/卖出时机 | 券详情页AI价格趋势分析标签 + "AI建议:当前价格偏低,适合买入" |
|
||||||
|
| **到期管理** | 追踪所有持券到期时间,按紧迫度提醒 | 我的券列表中AI排序"即将到期优先",推送提醒卡片 |
|
||||||
|
| **出售定价** | 基于市场供需和历史成交,建议挂单价格 | 出售页面中AI建议价格标签 + 价格解释 |
|
||||||
|
| **使用规划** | 根据行程/位置智能规划券使用顺序 | "您附近有3家可使用门店,建议路线:..." |
|
||||||
|
| **自然语言搜索** | "帮我找200元以下的星巴克券" | 对话面板中返回筛选后的券卡片列表 |
|
||||||
|
| **交易助手** | 自动比价、批量操作、组合购买建议 | "同类券在二级市场更便宜,要看看吗?" |
|
||||||
|
| **资产报告** | 生成个人券资产报告(总价值、收益率、使用率) | 周/月报告推送,可视化图表 |
|
||||||
|
|
||||||
|
#### 商户端AI Agent
|
||||||
|
|
||||||
|
| 场景 | AI能力 | UI表现 |
|
||||||
|
|------|--------|--------|
|
||||||
|
| **核销辅助** | 异常券实时识别(过期/已用/非本店)、快速提示 | 核销时AI红色警示标签 |
|
||||||
|
| **客流预测** | 基于历史核销数据预测当日/本周客流量 | 仪表盘AI预测卡片 |
|
||||||
|
| **问题解答** | 回答核销操作疑问、离线模式说明 | 对话面板 |
|
||||||
|
|
||||||
|
#### 发行方管理端AI Agent
|
||||||
|
|
||||||
|
| 场景 | AI能力 | UI表现 |
|
||||||
|
|------|--------|--------|
|
||||||
|
| **发券建议** | 分析市场趋势,建议发券时间/面值/折扣/数量 | 发券中心顶部AI建议卡片 |
|
||||||
|
| **定价优化** | 基于三因子模型 + AI定价引擎,提供最优定价策略 | 创建券时AI推荐价格 + 对比分析 |
|
||||||
|
| **信用提升** | 分析信用评分各维度,给出提升建议 | 信用等级页面AI改善建议列表 |
|
||||||
|
| **销售分析** | 智能解读销售数据,发现异常和机会 | 数据中心AI洞察卡片 |
|
||||||
|
| **额度规划** | 预测发行额度消耗速度,建议补充计划 | 额度页面AI规划时间线 |
|
||||||
|
| **合规助手** | 提醒合规要求,辅助材料准备 | 入驻审核时AI检查清单 |
|
||||||
|
|
||||||
|
#### Web管理端AI Agent
|
||||||
|
|
||||||
|
| 场景 | AI能力 | UI表现 |
|
||||||
|
|------|--------|--------|
|
||||||
|
| **风险预警** | 实时检测异常交易模式,自动预警 | 风控仪表盘AI警告卡片 + 处理建议 |
|
||||||
|
| **审核辅助** | AI预审发行方资料/券信息,标记风险点 | 审核页面AI评分+风险标签 |
|
||||||
|
| **合规报告** | 自动生成SAR/CTR/监管报表草稿 | 合规报表页AI生成按钮 |
|
||||||
|
| **运营洞察** | 分析平台运营数据,提出优化建议 | Dashboard AI洞察面板 |
|
||||||
|
| **智能搜索** | 自然语言查询用户/订单/交易 | "查找过去7天金额超过5000的可疑交易" |
|
||||||
|
| **决策支持** | 手续费率调整建议、额度配置建议 | 系统配置页AI建议标签 |
|
||||||
|
|
||||||
|
#### 小程序/H5 AI Agent
|
||||||
|
|
||||||
|
| 场景 | AI能力 | UI表现 |
|
||||||
|
|------|--------|--------|
|
||||||
|
| **轻量推荐** | 基于分享来源和用户标签快速推荐 | 首页精简推荐条 |
|
||||||
|
| **购买引导** | 引导新用户完成首次购买 | 对话气泡式引导 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## A. 消费者端(Consumer App)— Flutter
|
||||||
|
|
||||||
|
### A1. 注册/登录模块
|
||||||
|
|
||||||
|
| 页面 | 核心元素 | 交互说明 |
|
||||||
|
|------|---------|---------|
|
||||||
|
| **欢迎页** | 品牌Logo、Slogan、「手机号注册」「邮箱注册」按钮、社交登录入口(Google/Apple) | 启动页→欢迎页→注册 |
|
||||||
|
| **手机号注册** | 手机号输入、获取验证码、验证码输入、设置密码、用户协议勾选 | 注册成功后后台静默创建MPC钱包 |
|
||||||
|
| **邮箱注册** | 邮箱输入、获取验证码、设置密码 | 同上 |
|
||||||
|
| **登录** | 手机号/邮箱+密码、忘记密码、验证码快捷登录 | |
|
||||||
|
| **忘记密码** | 手机号/邮箱验证→重置密码 | |
|
||||||
|
|
||||||
|
### A2. 首页/市场模块
|
||||||
|
|
||||||
|
| 页面 | 核心元素 | 交互说明 |
|
||||||
|
|------|---------|---------|
|
||||||
|
| **首页** | 搜索栏、Banner轮播(推荐券/活动)、热门分类(餐饮/购物/娱乐/出行)、精选券列表、底部Tab导航 | Tab:首页/市场/我的券/消息/我的 |
|
||||||
|
| **市场(交易大厅)** | 分类筛选(行业/品牌/折扣范围)、排序(价格/折扣率/到期时间)、券卡片列表(图片+品牌+面值+当前价+折扣率+到期时间) | 一级市场(全新)+二级市场(转售)标签切换 |
|
||||||
|
| **券详情页** | 券图片、品牌Logo、面值、当前价格、折扣率(如"8.5折")、有效期、使用条件、使用门店、发行方信用等级(如AAA)、「立即购买」「加入收藏」按钮、价格走势图(可选)、历史成交价、同类券推荐 | |
|
||||||
|
| **搜索结果** | 搜索框+筛选器+结果列表 | 支持品牌、券名称、分类搜索 |
|
||||||
|
|
||||||
|
### A3. 购买流程
|
||||||
|
|
||||||
|
| 页面 | 核心元素 | 交互说明 |
|
||||||
|
|------|---------|---------|
|
||||||
|
| **确认订单** | 券信息摘要、数量选择、价格计算(单价×数量)、支付方式选择 | |
|
||||||
|
| **支付** | 银行卡/信用卡/Apple Pay选择、支付确认(密码/指纹/Face ID) | 后台:法币→USDC→Settlement合约 |
|
||||||
|
| **支付成功** | 成功动画、订单号(如GNX-20260209-001234)、「查看我的券」「继续逛」 | |
|
||||||
|
|
||||||
|
### A4. 我的券模块
|
||||||
|
|
||||||
|
| 页面 | 核心元素 | 交互说明 |
|
||||||
|
|------|---------|---------|
|
||||||
|
| **我的券列表** | 券卡片(图片+品牌+面值+状态+到期倒计时)、筛选(全部/可使用/待使用/已过期)、批量操作 | 状态标签:可使用/待核销/已过期 |
|
||||||
|
| **券详情** | 券二维码/条形码(核销用)、券信息、使用说明、「转赠」「出售」「使用说明」按钮 | |
|
||||||
|
| **转赠流程** | 输入对方手机号/邮箱、确认转赠、安全验证(密码/指纹)、成功页 | 后台:手机号→地址解析→P2P链上转移 |
|
||||||
|
| **出售挂单** | 设定售价(系统提示建议价格和面值上限)、确认挂单 | Utility Track价格 ≤ 面值 |
|
||||||
|
| **提取到外部钱包** | 输入外部钱包地址、确认提取、风险提示(提取后平台不再托管) | 需KYC L2+ |
|
||||||
|
|
||||||
|
### A5. 交易模块(二级市场)
|
||||||
|
|
||||||
|
| 页面 | 核心元素 | 交互说明 |
|
||||||
|
|------|---------|---------|
|
||||||
|
| **我的挂单** | 挂单列表(券信息+挂单价+状态+挂单时间)、撤单按钮 | |
|
||||||
|
| **我的交易记录** | 买入/卖出记录、成交价、时间、状态、订单号 | |
|
||||||
|
| **求购(可选P2)** | 设定求购券品牌+价格+数量 | 延后实现 |
|
||||||
|
|
||||||
|
### A6. 账户模块
|
||||||
|
|
||||||
|
| 页面 | 核心元素 | 交互说明 |
|
||||||
|
|------|---------|---------|
|
||||||
|
| **我的余额** | 总余额(美元显示)、可提现金额、冻结金额、「充值」「提现」按钮 | 后台聚合链上+链下余额 |
|
||||||
|
| **充值** | 选择支付方式、输入金额、确认 | |
|
||||||
|
| **提现** | 输入提现金额、选择银行卡、确认 | T+1到账 |
|
||||||
|
| **交易记录** | 时间线列表(买入/卖出/转赠/核销/充值/提现),每条含订单号、金额、状态 | |
|
||||||
|
|
||||||
|
### A7. 个人中心
|
||||||
|
|
||||||
|
| 页面 | 核心元素 | 交互说明 |
|
||||||
|
|------|---------|---------|
|
||||||
|
| **个人主页** | 头像、昵称、KYC等级标识、信用积分 | |
|
||||||
|
| **KYC认证** | 当前等级、升级引导(L0→L1→L2→L3)、身份证/护照上传、人脸识别 | |
|
||||||
|
| **支付管理** | 已绑定银行卡列表、添加银行卡 | 需KYC L2 |
|
||||||
|
| **设置** | 通知设置、语言切换、安全设置(修改密码/支付密码)、「高级设置」(Pro模式入口)、关于、退出登录 | |
|
||||||
|
| **Pro模式设置** | 开启说明、风险提示确认、WalletConnect连接、链上地址显示、交易哈希查看 | 默认隐藏,设置→高级 |
|
||||||
|
|
||||||
|
### A8. 消息模块
|
||||||
|
|
||||||
|
| 页面 | 核心元素 | 交互说明 |
|
||||||
|
|------|---------|---------|
|
||||||
|
| **消息列表** | 交易通知、系统公告、券到期提醒、价格提醒 | 分类Tab |
|
||||||
|
| **消息详情** | 消息内容、关联操作跳转 | |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## B. 商户核销端(Merchant App)— Flutter
|
||||||
|
|
||||||
|
### B1. 登录与权限
|
||||||
|
|
||||||
|
| 页面 | 核心元素 | 交互说明 |
|
||||||
|
|------|---------|---------|
|
||||||
|
| **员工登录** | 手机号+密码/验证码、门店选择(多门店员工) | 权限:收银员(仅核销)/店长(核销+数据)/管理员(全部) |
|
||||||
|
|
||||||
|
### B2. 核销模块
|
||||||
|
|
||||||
|
| 页面 | 核心元素 | 交互说明 |
|
||||||
|
|------|---------|---------|
|
||||||
|
| **扫码核销**(主页) | 大面积扫码区域、手电筒开关、「手动输码」入口 | 扫码→显示券信息→确认核销→成功/失败提示 |
|
||||||
|
| **券信息确认** | 券名称、面值、有效期、使用条件、消费者头像/昵称、「确认核销」按钮 | 核销≤3秒 |
|
||||||
|
| **核销成功** | 成功动画、券信息摘要、「继续核销」 | |
|
||||||
|
| **手动输码** | 券码输入框、「查询」按钮 | 扫码设备故障时备用 |
|
||||||
|
| **离线核销提示** | 网络状态标识(在线/离线)、离线核销说明、待同步数量标记 | 断网自动切换离线模式 |
|
||||||
|
|
||||||
|
### B3. 核销记录
|
||||||
|
|
||||||
|
| 页面 | 核心元素 | 交互说明 |
|
||||||
|
|------|---------|---------|
|
||||||
|
| **核销记录列表** | 时间、券名、面值、核销员、状态(已同步/待同步) | 筛选:今日/本周/自定义时间 |
|
||||||
|
| **待同步队列** | 离线核销待上链的记录、「手动同步」按钮 | 联网后自动同步 |
|
||||||
|
|
||||||
|
### B4. 门店数据(店长权限)
|
||||||
|
|
||||||
|
| 页面 | 核心元素 | 交互说明 |
|
||||||
|
|------|---------|---------|
|
||||||
|
| **门店仪表盘** | 今日核销笔数/金额、本周趋势图、核销员排行 | |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## C. 发行方管理后台App(Issuer Console)— Flutter
|
||||||
|
|
||||||
|
### C1. 发行方入驻
|
||||||
|
|
||||||
|
| 页面 | 核心元素 | 交互说明 |
|
||||||
|
|------|---------|---------|
|
||||||
|
| **企业注册** | 企业名称、营业执照上传(OCR识别)、联系人信息、法人信息 | |
|
||||||
|
| **审核状态** | 审核进度条(已提交→审核中→已通过/已驳回)、驳回原因 | |
|
||||||
|
|
||||||
|
### C2. 发券中心
|
||||||
|
|
||||||
|
| 页面 | 核心元素 | 交互说明 |
|
||||||
|
|------|---------|---------|
|
||||||
|
| **券模板选择** | 预设模板卡片(满减券/折扣券/礼品卡/储值券)、模板预览 | |
|
||||||
|
| **创建券活动** | 券名称、面值、发行价格(折扣率)、有效期、使用条件描述、券封面图上传、发行数量 | 发行方视角:创建"优惠活动" |
|
||||||
|
| **规则配置** | 7项可配置规则(可转让/转售次数/人群限定/限购数量/门店限定/叠加使用/最低消费)、开关+输入表单 | Web2界面,无合约参数 |
|
||||||
|
| **预览与提交** | 券预览卡片、规则摘要、发行费用提示、「提交审核」 | 审核通过后自动链上铸造+上架 |
|
||||||
|
| **券管理列表** | 券名、状态(审核中/已上架/已下架/已售罄)、发行量/已售/已核销/已过期统计 | |
|
||||||
|
| **券详情管理** | 券信息、下架/召回操作、补充发行 | |
|
||||||
|
|
||||||
|
### C3. 核销管理
|
||||||
|
|
||||||
|
| 页面 | 核心元素 | 交互说明 |
|
||||||
|
|------|---------|---------|
|
||||||
|
| **核销概览** | 今日/本周/本月核销统计、核销趋势图 | |
|
||||||
|
| **门店管理** | 门店列表(总部→区域→门店树形结构)、添加门店、门店核销权限配置 | |
|
||||||
|
| **员工管理** | 员工列表、角色分配(收银员/店长/管理员) | |
|
||||||
|
|
||||||
|
### C4. 财务管理
|
||||||
|
|
||||||
|
| 页面 | 核心元素 | 交互说明 |
|
||||||
|
|------|---------|---------|
|
||||||
|
| **收入概览** | 总销售额、已到账金额、待结算金额、Breakage收入 | 法币视图 |
|
||||||
|
| **提现** | 可提现金额、银行账户选择、提现申请 | |
|
||||||
|
| **对账报表** | 日/月对账单、交易流水、导出 | |
|
||||||
|
|
||||||
|
### C5. 数据中心
|
||||||
|
|
||||||
|
| 页面 | 核心元素 | 交互说明 |
|
||||||
|
|------|---------|---------|
|
||||||
|
| **仪表盘** | 发行量/销量/兑付率/Breakage率/流通中数量 实时图表 | |
|
||||||
|
| **销售分析** | 按时间/按券类型/按门店 分析 | |
|
||||||
|
| **用户画像** | 购买用户分布(仅汇总数据,不含个人信息) | |
|
||||||
|
|
||||||
|
### C6. 信用与额度
|
||||||
|
|
||||||
|
| 页面 | 核心元素 | 交互说明 |
|
||||||
|
|------|---------|---------|
|
||||||
|
| **信用等级** | 当前等级(如AA)、评分详情(核销率/沉淀率/满意度/存续时长)、提升建议 | |
|
||||||
|
| **发行额度** | 当前额度/已用额度/剩余额度、额度变动历史 | |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## D. Web管理前端(Platform Admin)— React + Next.js
|
||||||
|
|
||||||
|
### D1. 平台运营仪表盘
|
||||||
|
|
||||||
|
| 页面 | 核心元素 |
|
||||||
|
|------|---------|
|
||||||
|
| **总览Dashboard** | 平台总交易量/金额、活跃用户数、发行方数量、券流通总量、实时交易流、系统健康状态 |
|
||||||
|
|
||||||
|
### D2. 发行方管理
|
||||||
|
|
||||||
|
| 页面 | 核心元素 |
|
||||||
|
|------|---------|
|
||||||
|
| **入驻审核列表** | 待审核/已通过/已驳回列表、审核详情(企业资料、工商数据校验结果) |
|
||||||
|
| **发行方详情** | 企业信息、信用评级、发行记录、违规记录、操作(升级/降级/冻结/解冻) |
|
||||||
|
| **券审核列表** | 待审核券列表、券信息预览、审核通过/驳回 |
|
||||||
|
|
||||||
|
### D3. 用户管理
|
||||||
|
|
||||||
|
| 页面 | 核心元素 |
|
||||||
|
|------|---------|
|
||||||
|
| **用户列表** | 搜索(手机号/邮箱/用户ID)、KYC等级筛选、用户详情入口 |
|
||||||
|
| **用户详情** | 基本信息、KYC状态、持券列表、交易记录、风险标签 |
|
||||||
|
| **KYC审核** | 待审核KYC申请、证件照片查看、人脸比对结果、通过/驳回 |
|
||||||
|
|
||||||
|
### D4. 交易监控
|
||||||
|
|
||||||
|
| 页面 | 核心元素 |
|
||||||
|
|------|---------|
|
||||||
|
| **实时交易流** | 交易实时滚动列表、大额交易高亮 |
|
||||||
|
| **交易统计** | 交易量/金额趋势、各类型交易占比、平均折扣率 |
|
||||||
|
| **订单管理** | 订单搜索、订单详情、争议订单标记 |
|
||||||
|
|
||||||
|
### D5. 风控中心
|
||||||
|
|
||||||
|
| 页面 | 核心元素 |
|
||||||
|
|------|---------|
|
||||||
|
| **风险仪表盘** | 风险事件数量、可疑交易数量、冻结账户数量 |
|
||||||
|
| **可疑交易** | 可疑交易列表(异常模式、大额、高频)、处理操作(标记/冻结/上报SAR) |
|
||||||
|
| **黑名单管理** | 黑名单列表(用户/地址)、添加/移除 |
|
||||||
|
| **OFAC筛查日志** | 筛查记录、命中记录、处理状态 |
|
||||||
|
|
||||||
|
### D6. 合规报表
|
||||||
|
|
||||||
|
| 页面 | 核心元素 |
|
||||||
|
|------|---------|
|
||||||
|
| **SAR管理** | 可疑活动报告列表、生成SAR、提交状态 |
|
||||||
|
| **CTR管理** | 大额交易报告、自动生成 |
|
||||||
|
| **审计日志** | 全链路操作日志搜索、导出 |
|
||||||
|
| **监管报表** | 日报/月报自动生成、下载 |
|
||||||
|
|
||||||
|
### D7. 系统管理
|
||||||
|
|
||||||
|
| 页面 | 核心元素 |
|
||||||
|
|------|---------|
|
||||||
|
| **管理员账号** | 管理员列表、角色权限配置(RBAC)、操作日志 |
|
||||||
|
| **系统配置** | 手续费率设置、KYC阈值配置、交易限额配置 |
|
||||||
|
| **合约管理** | 合约部署状态、升级提案管理、升级日志 |
|
||||||
|
| **系统监控** | 服务健康检查、API响应时间、Genex Chain节点状态 |
|
||||||
|
|
||||||
|
### D8. 争议处理
|
||||||
|
|
||||||
|
| 页面 | 核心元素 |
|
||||||
|
|------|---------|
|
||||||
|
| **工单列表** | 争议工单(买方申诉/卖方申诉/退款申请)、状态、处理时效 |
|
||||||
|
| **工单详情** | 双方信息、链上交易记录(作为证据)、仲裁操作 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## E. 小程序 + H5
|
||||||
|
|
||||||
|
> 消费者端的轻量版,核心购买和查看功能。
|
||||||
|
|
||||||
|
### E1. 小程序核心页面
|
||||||
|
|
||||||
|
| 页面 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| **首页** | 同Consumer App首页,精简版(热门券+分类入口) |
|
||||||
|
| **券详情+购买** | 同App,微信支付/支付宝支付 |
|
||||||
|
| **我的券** | 券列表+券码展示(核销用) |
|
||||||
|
| **我的订单** | 订单列表 |
|
||||||
|
|
||||||
|
### E2. H5页面
|
||||||
|
|
||||||
|
| 页面 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| **券分享页** | 券信息展示+「打开App购买」/「小程序购买」引导 |
|
||||||
|
| **活动落地页** | 发行方推广活动入口页 |
|
||||||
|
| **注册引导页** | 未注册用户引导注册 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## F. 通用组件库
|
||||||
|
|
||||||
|
| 组件 | 说明 | 使用端 |
|
||||||
|
|------|------|--------|
|
||||||
|
| **券卡片** | 券封面图+品牌+面值+折扣率+到期时间 | 全端 |
|
||||||
|
| **价格标签** | 当前价格(大字)+ 原价删除线 + 折扣标签 | 全端 |
|
||||||
|
| **信用等级徽章** | AAA/AA/A/BBB/BB颜色标识 | 全端 |
|
||||||
|
| **KYC等级标识** | L0/L1/L2/L3徽章 | 消费者端+管理端 |
|
||||||
|
| **交易状态标签** | 处理中/已完成/已取消/退款中 颜色标签 | 全端 |
|
||||||
|
| **空状态页** | 各场景的空状态插画+引导操作 | 全端 |
|
||||||
|
| **加载/骨架屏** | 列表加载、详情加载 | 全端 |
|
||||||
|
| **底部Sheet** | 支付确认、转赠确认等操作确认 | 移动端 |
|
||||||
|
| **Toast/Snackbar** | 操作反馈提示 | 全端 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## G. 核心用户流程图
|
||||||
|
|
||||||
|
### G1. 消费者购买券
|
||||||
|
|
||||||
|
```
|
||||||
|
首页浏览 → 券详情 → 立即购买 → 确认订单 → 选择支付 → 支付验证 → 成功
|
||||||
|
↓
|
||||||
|
我的券(可查看)
|
||||||
|
```
|
||||||
|
|
||||||
|
### G2. 消费者转赠券
|
||||||
|
|
||||||
|
```
|
||||||
|
我的券 → 选择券 → 转赠 → 输入对方手机号 → 安全验证 → 成功
|
||||||
|
```
|
||||||
|
|
||||||
|
### G3. 消费者出售券
|
||||||
|
|
||||||
|
```
|
||||||
|
我的券 → 选择券 → 出售 → 设定价格(≤面值提示) → 确认挂单 → 等待成交
|
||||||
|
```
|
||||||
|
|
||||||
|
### G4. 消费者使用券(线下)
|
||||||
|
|
||||||
|
```
|
||||||
|
我的券 → 选择券 → 出示券码(二维码/条形码) → 商户扫码核销 → 核销成功通知
|
||||||
|
```
|
||||||
|
|
||||||
|
### G5. 发行方发券
|
||||||
|
|
||||||
|
```
|
||||||
|
登录后台 → 发券中心 → 选择模板 → 填写券信息+规则 → 预览 → 提交审核
|
||||||
|
↓
|
||||||
|
审核通过 → 自动铸造上架
|
||||||
|
```
|
||||||
|
|
||||||
|
### G6. 商户核销
|
||||||
|
|
||||||
|
```
|
||||||
|
打开核销App → 扫码 → 确认券信息 → 核销 → 成功
|
||||||
|
↓ (断网)
|
||||||
|
离线验证 → 暂存 → 联网后自动同步
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## H. AI Agent 技术架构要求
|
||||||
|
|
||||||
|
### H1. 前端集成架构
|
||||||
|
|
||||||
|
```
|
||||||
|
┌──────────────────────────────────┐
|
||||||
|
│ UI Layer (各端) │
|
||||||
|
│ 悬浮按钮 / 对话面板 / 建议卡片 │
|
||||||
|
├──────────────────────────────────┤
|
||||||
|
│ AI Agent SDK (统一) │
|
||||||
|
│ 对话管理 / 上下文组装 / 流式渲染 │
|
||||||
|
├──────────────────────────────────┤
|
||||||
|
│ Agent Gateway API │
|
||||||
|
│ WebSocket(实时) / REST(批量) │
|
||||||
|
├──────────────────────────────────┤
|
||||||
|
│ Backend AI Agent Service │
|
||||||
|
│ LLM编排 / RAG / 工具调用 / 记忆 │
|
||||||
|
└──────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### H2. 上下文数据协议
|
||||||
|
|
||||||
|
AI Agent需要的上下文数据(前端组装后发送至后端Agent Service):
|
||||||
|
|
||||||
|
| 上下文字段 | 说明 | 来源 |
|
||||||
|
|-----------|------|------|
|
||||||
|
| `user_profile` | 用户身份、KYC等级、偏好 | 本地缓存 + API |
|
||||||
|
| `current_page` | 当前页面路由和关键参数 | 路由状态 |
|
||||||
|
| `coupon_portfolio` | 用户持券列表摘要 | 本地状态 |
|
||||||
|
| `recent_actions` | 最近10条操作记录 | 本地记录 |
|
||||||
|
| `market_snapshot` | 当前市场热门/价格摘要 | API缓存 |
|
||||||
|
| `location` | 用户位置(如授权) | 设备GPS |
|
||||||
|
|
||||||
|
### H3. AI Agent 操作能力(Tool Calling)
|
||||||
|
|
||||||
|
AI Agent可代用户执行的操作(均需用户确认):
|
||||||
|
|
||||||
|
| 操作 | 描述 | 适用端 |
|
||||||
|
|------|------|--------|
|
||||||
|
| `search_coupons` | 按条件搜索券 | 消费者/小程序 |
|
||||||
|
| `get_price_analysis` | 获取券价格分析 | 消费者/发行方 |
|
||||||
|
| `create_sell_order` | 创建出售挂单 | 消费者 |
|
||||||
|
| `suggest_pricing` | 获取AI定价建议 | 发行方 |
|
||||||
|
| `generate_report` | 生成数据报告 | 发行方/管理端 |
|
||||||
|
| `query_transactions` | 查询交易记录 | 全端 |
|
||||||
|
| `risk_assessment` | 风险评估 | 管理端 |
|
||||||
|
| `compliance_check` | 合规检查 | 管理端 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*文档版本: v1.1*
|
||||||
|
*基于: Genex 券交易平台 - 软件需求规格说明书 v4.1*
|
||||||
|
*更新: 增加AI Agent深度融合设计规范*
|
||||||
|
|
@ -0,0 +1,559 @@
|
||||||
|
# Genex Flutter 移动端开发指南
|
||||||
|
|
||||||
|
> Consumer App(消费者端)+ Merchant App(商户核销端)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. 技术栈概览
|
||||||
|
|
||||||
|
| 技术 | 版本 | 用途 |
|
||||||
|
|------|------|------|
|
||||||
|
| **Flutter** | 3.x | 跨平台UI框架 |
|
||||||
|
| **Dart** | 3.x | 开发语言 |
|
||||||
|
| **Riverpod** | 2.x | 状态管理(Provider替代方案,编译安全) |
|
||||||
|
| **GoRouter** | 最新 | 声明式路由、深链接 |
|
||||||
|
| **Dio** | 5.x | HTTP客户端 |
|
||||||
|
| **Freezed** | 最新 | 不可变数据模型代码生成 |
|
||||||
|
| **Hive/Isar** | 最新 | 本地持久化 |
|
||||||
|
| **WebSocket** | 内置 | AI Agent实时通信、行情推送 |
|
||||||
|
| **flutter_localizations** | 内置 | 国际化 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 项目架构:Clean Architecture + Riverpod
|
||||||
|
|
||||||
|
### 2.1 目录结构
|
||||||
|
|
||||||
|
```
|
||||||
|
genex_mobile/
|
||||||
|
├── lib/
|
||||||
|
│ ├── main.dart # 应用入口
|
||||||
|
│ ├── app/
|
||||||
|
│ │ ├── app.dart # MaterialApp配置
|
||||||
|
│ │ ├── router.dart # GoRouter路由定义
|
||||||
|
│ │ └── theme/ # 主题配置
|
||||||
|
│ ├── core/
|
||||||
|
│ │ ├── constants/ # 常量(API地址、术语映射表)
|
||||||
|
│ │ ├── network/ # Dio配置、拦截器、错误处理
|
||||||
|
│ │ ├── storage/ # 本地存储封装
|
||||||
|
│ │ ├── utils/ # 工具类
|
||||||
|
│ │ └── extensions/ # Dart扩展方法
|
||||||
|
│ ├── features/ # 按功能模块组织
|
||||||
|
│ │ ├── auth/ # 注册/登录
|
||||||
|
│ │ │ ├── data/
|
||||||
|
│ │ │ │ ├── datasources/ # 远程/本地数据源
|
||||||
|
│ │ │ │ ├── models/ # DTO(Freezed生成)
|
||||||
|
│ │ │ │ └── repositories/ # Repository实现
|
||||||
|
│ │ │ ├── domain/
|
||||||
|
│ │ │ │ ├── entities/ # 领域实体
|
||||||
|
│ │ │ │ ├── repositories/ # Repository接口
|
||||||
|
│ │ │ │ └── usecases/ # 用例
|
||||||
|
│ │ │ └── presentation/
|
||||||
|
│ │ │ ├── providers/ # Riverpod Providers
|
||||||
|
│ │ │ ├── pages/ # 页面Widget
|
||||||
|
│ │ │ └── widgets/ # 模块专用组件
|
||||||
|
│ │ ├── coupons/ # 券浏览/购买/持有
|
||||||
|
│ │ ├── trading/ # 二级市场交易
|
||||||
|
│ │ ├── wallet/ # 余额/资产/交易记录
|
||||||
|
│ │ ├── redeem/ # 券使用/核销
|
||||||
|
│ │ ├── transfer/ # P2P转赠
|
||||||
|
│ │ ├── profile/ # 个人中心/KYC
|
||||||
|
│ │ ├── ai_agent/ # AI Agent对话/建议
|
||||||
|
│ │ └── merchant/ # 商户端核销(共享模块)
|
||||||
|
│ ├── shared/
|
||||||
|
│ │ ├── widgets/ # 全局共享组件
|
||||||
|
│ │ ├── providers/ # 全局Provider
|
||||||
|
│ │ └── models/ # 共享数据模型
|
||||||
|
│ └── l10n/ # 国际化资源
|
||||||
|
├── test/ # 单元/Widget测试
|
||||||
|
├── integration_test/ # 集成测试
|
||||||
|
└── pubspec.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.2 Clean Architecture 分层
|
||||||
|
|
||||||
|
```
|
||||||
|
┌────────────────────────────────────────┐
|
||||||
|
│ Presentation Layer │
|
||||||
|
│ Pages → Widgets → Riverpod Providers │
|
||||||
|
├────────────────────────────────────────┤
|
||||||
|
│ Domain Layer │
|
||||||
|
│ Entities → UseCases → Repository(接口)│
|
||||||
|
├────────────────────────────────────────┤
|
||||||
|
│ Data Layer │
|
||||||
|
│ Models(DTO) → DataSources → Repo实现 │
|
||||||
|
└────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
**依赖方向**:Presentation → Domain ← Data(Domain层不依赖任何外层)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. 核心模块实现
|
||||||
|
|
||||||
|
### 3.1 术语映射(全局执行)
|
||||||
|
|
||||||
|
> 所有面向用户的UI文本必须使用Web2术语,禁止出现区块链术语。
|
||||||
|
|
||||||
|
```dart
|
||||||
|
// lib/core/constants/terminology.dart
|
||||||
|
class Terminology {
|
||||||
|
// 用户界面术语 → 底层技术术语
|
||||||
|
static const Map<String, String> mapping = {
|
||||||
|
'我的账户': '链上钱包地址',
|
||||||
|
'我的券': 'ERC-721/1155 NFT资产',
|
||||||
|
'我的余额': '链上稳定币(USDC)余额',
|
||||||
|
'转赠给朋友': 'P2P链上转移',
|
||||||
|
'购买': '链上原子交换',
|
||||||
|
'核销/使用': '合约兑付(Redemption)',
|
||||||
|
'订单号': '交易哈希(TX Hash)',
|
||||||
|
'安全验证': '链上签名(MPC钱包后台执行)',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.2 认证模块
|
||||||
|
|
||||||
|
```dart
|
||||||
|
// lib/features/auth/domain/entities/user.dart
|
||||||
|
@freezed
|
||||||
|
class User with _$User {
|
||||||
|
const factory User({
|
||||||
|
required String id,
|
||||||
|
required String phone, // 或 email
|
||||||
|
required KycLevel kycLevel, // L0/L1/L2/L3
|
||||||
|
required WalletMode walletMode, // standard/pro
|
||||||
|
String? displayName,
|
||||||
|
String? avatar,
|
||||||
|
}) = _User;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum KycLevel { L0, L1, L2, L3 }
|
||||||
|
enum WalletMode { standard, pro }
|
||||||
|
```
|
||||||
|
|
||||||
|
```dart
|
||||||
|
// lib/features/auth/domain/usecases/register_usecase.dart
|
||||||
|
class RegisterUseCase {
|
||||||
|
final AuthRepository _repo;
|
||||||
|
RegisterUseCase(this._repo);
|
||||||
|
|
||||||
|
/// 注册:手机号/邮箱 → 后台自动创建MPC钱包,用户无感知
|
||||||
|
Future<Either<Failure, User>> call(RegisterParams params) {
|
||||||
|
return _repo.register(
|
||||||
|
phone: params.phone,
|
||||||
|
email: params.email,
|
||||||
|
password: params.password,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.3 券资产模块
|
||||||
|
|
||||||
|
```dart
|
||||||
|
// lib/features/coupons/domain/entities/coupon.dart
|
||||||
|
@freezed
|
||||||
|
class Coupon with _$Coupon {
|
||||||
|
const factory Coupon({
|
||||||
|
required String id, // 券ID(链上唯一)
|
||||||
|
required String issuerName, // 发行方名称
|
||||||
|
required double faceValue, // 面值
|
||||||
|
required double currentPrice, // 当前市场价
|
||||||
|
required DateTime expiryDate, // 到期日期
|
||||||
|
required CouponStatus status, // 可用/已使用/已过期
|
||||||
|
required CouponType type, // utility/security
|
||||||
|
String? imageUrl,
|
||||||
|
String? description,
|
||||||
|
List<String>? usageConditions,
|
||||||
|
}) = _Coupon;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum CouponStatus { available, used, expired, listed }
|
||||||
|
enum CouponType { utility, security }
|
||||||
|
```
|
||||||
|
|
||||||
|
```dart
|
||||||
|
// lib/features/coupons/presentation/providers/coupon_providers.dart
|
||||||
|
final couponListProvider = FutureProvider.autoDispose<List<Coupon>>((ref) {
|
||||||
|
final repo = ref.watch(couponRepositoryProvider);
|
||||||
|
return repo.getMyCoupons();
|
||||||
|
});
|
||||||
|
|
||||||
|
final couponDetailProvider = FutureProvider.autoDispose.family<Coupon, String>(
|
||||||
|
(ref, couponId) {
|
||||||
|
final repo = ref.watch(couponRepositoryProvider);
|
||||||
|
return repo.getCouponDetail(couponId);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.4 交易模块
|
||||||
|
|
||||||
|
```dart
|
||||||
|
// lib/features/trading/domain/entities/order.dart
|
||||||
|
@freezed
|
||||||
|
class TradeOrder with _$TradeOrder {
|
||||||
|
const factory TradeOrder({
|
||||||
|
required String orderId, // 订单号(映射TX Hash)
|
||||||
|
required String couponId,
|
||||||
|
required OrderSide side, // buy/sell
|
||||||
|
required double price,
|
||||||
|
required OrderStatus status,
|
||||||
|
required DateTime createdAt,
|
||||||
|
}) = _TradeOrder;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum OrderSide { buy, sell }
|
||||||
|
enum OrderStatus { pending, matched, settled, cancelled }
|
||||||
|
```
|
||||||
|
|
||||||
|
**Utility Track价格校验(前端 + 后端双重验证)**:
|
||||||
|
|
||||||
|
```dart
|
||||||
|
// lib/features/trading/presentation/providers/sell_provider.dart
|
||||||
|
class SellNotifier extends StateNotifier<SellState> {
|
||||||
|
// Utility Track券:卖出价 ≤ 面值
|
||||||
|
bool validatePrice(double sellPrice, double faceValue, CouponType type) {
|
||||||
|
if (type == CouponType.utility && sellPrice > faceValue) {
|
||||||
|
return false; // 消费型券不允许溢价
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.5 P2P转赠
|
||||||
|
|
||||||
|
```dart
|
||||||
|
// 转赠流程:输入朋友手机号 → 翻译层解析为链上地址 → 链上P2P转移
|
||||||
|
class TransferUseCase {
|
||||||
|
final TransferRepository _repo;
|
||||||
|
TransferUseCase(this._repo);
|
||||||
|
|
||||||
|
Future<Either<Failure, TransferResult>> call({
|
||||||
|
required String couponId,
|
||||||
|
required String recipientPhone, // 手机号(非链上地址)
|
||||||
|
}) {
|
||||||
|
return _repo.transferByPhone(
|
||||||
|
couponId: couponId,
|
||||||
|
recipientPhone: recipientPhone,
|
||||||
|
);
|
||||||
|
// 后端翻译层:手机号 → 链上地址 → Gas代付 → 链上P2P转移
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. AI Agent 集成
|
||||||
|
|
||||||
|
### 4.1 架构
|
||||||
|
|
||||||
|
```
|
||||||
|
┌──────────────────────────────┐
|
||||||
|
│ AI Agent UI Layer │
|
||||||
|
│ 悬浮按钮 / 对话面板 / 建议条 │
|
||||||
|
├──────────────────────────────┤
|
||||||
|
│ AI Agent SDK │
|
||||||
|
│ 对话管理 / 上下文组装 / 流式 │
|
||||||
|
├──────────────────────────────┤
|
||||||
|
│ WebSocket连接 │
|
||||||
|
│ Agent Gateway API │
|
||||||
|
└──────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.2 悬浮入口按钮
|
||||||
|
|
||||||
|
```dart
|
||||||
|
// lib/features/ai_agent/presentation/widgets/ai_fab.dart
|
||||||
|
class AiAgentFab extends ConsumerWidget {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final unreadCount = ref.watch(aiUnreadCountProvider);
|
||||||
|
return Positioned(
|
||||||
|
right: 16,
|
||||||
|
bottom: 80,
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () => _showAgentPanel(context),
|
||||||
|
onLongPress: () => _showQuickActions(context),
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
CircleAvatar(
|
||||||
|
radius: 28,
|
||||||
|
child: Icon(Icons.smart_toy_outlined),
|
||||||
|
),
|
||||||
|
if (unreadCount > 0)
|
||||||
|
Positioned(
|
||||||
|
right: 0, top: 0,
|
||||||
|
child: Badge(count: unreadCount),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.3 对话面板(流式输出)
|
||||||
|
|
||||||
|
```dart
|
||||||
|
// lib/features/ai_agent/presentation/pages/agent_chat_panel.dart
|
||||||
|
class AgentChatPanel extends ConsumerStatefulWidget {
|
||||||
|
@override
|
||||||
|
_AgentChatPanelState createState() => _AgentChatPanelState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AgentChatPanelState extends ConsumerState<AgentChatPanel> {
|
||||||
|
final _channel = WebSocketChannel.connect(
|
||||||
|
Uri.parse('wss://api.gogenex.com/agent/ws'),
|
||||||
|
);
|
||||||
|
|
||||||
|
void _sendMessage(String text) {
|
||||||
|
final context = _buildContext(); // 组装上下文
|
||||||
|
_channel.sink.add(jsonEncode({
|
||||||
|
'type': 'chat',
|
||||||
|
'message': text,
|
||||||
|
'context': context,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _buildContext() {
|
||||||
|
return {
|
||||||
|
'user_profile': ref.read(userProfileProvider).toJson(),
|
||||||
|
'current_page': GoRouter.of(context).location,
|
||||||
|
'coupon_portfolio': ref.read(myCouponsProvider).toSummary(),
|
||||||
|
'recent_actions': ref.read(recentActionsProvider),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.4 消费者端AI场景
|
||||||
|
|
||||||
|
| 场景 | 实现方式 |
|
||||||
|
|------|---------|
|
||||||
|
| 智能选券推荐 | 首页Feed中插入AI推荐卡片 |
|
||||||
|
| 价格顾问 | 券详情页底部AI分析标签 |
|
||||||
|
| 到期管理 | 我的券列表AI排序+推送提醒 |
|
||||||
|
| 出售定价 | 出售页面AI建议价格+解释 |
|
||||||
|
| 自然语言搜索 | 对话面板返回筛选券卡片 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. 商户端核销模块
|
||||||
|
|
||||||
|
### 5.1 核销方式
|
||||||
|
|
||||||
|
| 方式 | 场景 | 技术 |
|
||||||
|
|------|------|------|
|
||||||
|
| 扫码核销 | 门店扫消费者券码 | Camera → QR解码 → API调用 |
|
||||||
|
| 输码核销 | 手动输入券码 | 文本输入 → API调用 |
|
||||||
|
| 离线核销 | 网络不可用 | 本地验证 → 队列缓存 → 联网同步 |
|
||||||
|
|
||||||
|
### 5.2 离线核销实现
|
||||||
|
|
||||||
|
```dart
|
||||||
|
// lib/features/merchant/data/services/offline_redeem_service.dart
|
||||||
|
class OfflineRedeemService {
|
||||||
|
final _queue = HiveBox<PendingRedemption>('offline_queue');
|
||||||
|
final _localValidator = LocalCouponValidator();
|
||||||
|
|
||||||
|
/// 离线核销:本地验证 + 缓存 + 联网自动同步
|
||||||
|
Future<RedeemResult> redeemOffline(String couponCode) async {
|
||||||
|
// 1. 本地验证(预下载的有效券列表 + 签名验证)
|
||||||
|
final isValid = await _localValidator.validate(couponCode);
|
||||||
|
if (!isValid) return RedeemResult.invalid();
|
||||||
|
|
||||||
|
// 2. 本地标记已核销,加入同步队列
|
||||||
|
await _queue.add(PendingRedemption(
|
||||||
|
couponCode: couponCode,
|
||||||
|
timestamp: DateTime.now(),
|
||||||
|
storeId: currentStoreId,
|
||||||
|
));
|
||||||
|
|
||||||
|
return RedeemResult.pendingSync();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 联网后自动同步
|
||||||
|
Future<void> syncPendingRedemptions() async {
|
||||||
|
final pending = _queue.values.toList();
|
||||||
|
for (final item in pending) {
|
||||||
|
try {
|
||||||
|
await _api.confirmRedemption(item);
|
||||||
|
await _queue.delete(item.key);
|
||||||
|
} catch (_) {
|
||||||
|
// 重试逻辑
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. 网络层
|
||||||
|
|
||||||
|
### 6.1 Dio配置
|
||||||
|
|
||||||
|
```dart
|
||||||
|
// lib/core/network/api_client.dart
|
||||||
|
class ApiClient {
|
||||||
|
late final Dio _dio;
|
||||||
|
|
||||||
|
ApiClient() {
|
||||||
|
_dio = Dio(BaseOptions(
|
||||||
|
baseUrl: 'https://api.gogenex.com/api/v1',
|
||||||
|
connectTimeout: Duration(seconds: 10),
|
||||||
|
receiveTimeout: Duration(seconds: 30),
|
||||||
|
));
|
||||||
|
|
||||||
|
_dio.interceptors.addAll([
|
||||||
|
AuthInterceptor(), // JWT Token注入
|
||||||
|
LoggingInterceptor(), // 日志
|
||||||
|
RetryInterceptor(), // 重试策略
|
||||||
|
ErrorInterceptor(), // 统一错误处理
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.2 错误处理
|
||||||
|
|
||||||
|
```dart
|
||||||
|
// lib/core/network/failure.dart
|
||||||
|
@freezed
|
||||||
|
class Failure with _$Failure {
|
||||||
|
const factory Failure.network({String? message}) = NetworkFailure;
|
||||||
|
const factory Failure.server({required int code, String? message}) = ServerFailure;
|
||||||
|
const factory Failure.auth({String? message}) = AuthFailure;
|
||||||
|
const factory Failure.validation({required Map<String, String> errors}) = ValidationFailure;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. 状态管理模式(Riverpod)
|
||||||
|
|
||||||
|
```dart
|
||||||
|
// 只读数据查询
|
||||||
|
final couponListProvider = FutureProvider.autoDispose<List<Coupon>>((ref) async {
|
||||||
|
return ref.watch(couponRepoProvider).getAll();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 可变状态管理
|
||||||
|
final cartProvider = StateNotifierProvider<CartNotifier, CartState>((ref) {
|
||||||
|
return CartNotifier(ref.watch(orderRepoProvider));
|
||||||
|
});
|
||||||
|
|
||||||
|
// 异步操作
|
||||||
|
final purchaseProvider = FutureProvider.family<Order, PurchaseParams>((ref, params) {
|
||||||
|
return ref.watch(orderRepoProvider).purchase(params);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. 应用构建配置
|
||||||
|
|
||||||
|
### 8.1 多环境配置
|
||||||
|
|
||||||
|
```dart
|
||||||
|
// lib/core/config/env.dart
|
||||||
|
enum Environment { dev, staging, prod }
|
||||||
|
|
||||||
|
class AppConfig {
|
||||||
|
static late Environment env;
|
||||||
|
static String get apiBase => switch (env) {
|
||||||
|
Environment.dev => 'https://dev-api.gogenex.com',
|
||||||
|
Environment.staging => 'https://staging-api.gogenex.com',
|
||||||
|
Environment.prod => 'https://api.gogenex.com',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 8.2 Flavor构建
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Consumer App
|
||||||
|
flutter run --flavor consumer -t lib/main_consumer.dart
|
||||||
|
|
||||||
|
# Merchant App
|
||||||
|
flutter run --flavor merchant -t lib/main_merchant.dart
|
||||||
|
```
|
||||||
|
|
||||||
|
Consumer和Merchant共享核心模块(`core/`、`shared/`),通过不同入口和路由配置区分功能。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. 测试策略
|
||||||
|
|
||||||
|
| 层级 | 工具 | 覆盖目标 |
|
||||||
|
|------|------|---------|
|
||||||
|
| 单元测试 | `flutter_test` + `mocktail` | UseCase、Repository、Provider |
|
||||||
|
| Widget测试 | `flutter_test` | 关键页面组件 |
|
||||||
|
| 集成测试 | `integration_test` | 购买流程、核销流程、转赠流程 |
|
||||||
|
| Golden测试 | `golden_toolkit` | UI快照回归 |
|
||||||
|
|
||||||
|
```dart
|
||||||
|
// test/features/trading/sell_notifier_test.dart
|
||||||
|
void main() {
|
||||||
|
test('Utility券不允许溢价出售', () {
|
||||||
|
final notifier = SellNotifier();
|
||||||
|
expect(
|
||||||
|
notifier.validatePrice(110.0, 100.0, CouponType.utility),
|
||||||
|
false, // 110 > 面值100,拒绝
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
notifier.validatePrice(85.0, 100.0, CouponType.utility),
|
||||||
|
true, // 85 < 面值100,允许
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. 性能优化
|
||||||
|
|
||||||
|
| 策略 | 实现 |
|
||||||
|
|------|------|
|
||||||
|
| 图片懒加载 | `cached_network_image` + CDN |
|
||||||
|
| 列表虚拟化 | `ListView.builder` + 分页加载 |
|
||||||
|
| 离线缓存 | Hive本地数据库 + 增量同步 |
|
||||||
|
| 启动优化 | 延迟初始化非核心服务 |
|
||||||
|
| 包体积 | Tree-shaking + 延迟加载 |
|
||||||
|
| 内存管理 | `autoDispose` Provider自动释放 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11. 安全规范
|
||||||
|
|
||||||
|
- JWT Token存储于Flutter Secure Storage(非SharedPreferences)
|
||||||
|
- 敏感操作(大额交易、转赠)需二次验证(PIN/生物识别)
|
||||||
|
- API通信全链路HTTPS,Certificate Pinning
|
||||||
|
- 本地数据加密存储(Hive加密Box)
|
||||||
|
- 禁止在日志中输出敏感信息(Token、用户手机号)
|
||||||
|
- ProGuard/R8混淆(Android)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 12. 发布流程
|
||||||
|
|
||||||
|
```
|
||||||
|
开发 → 提交PR → CI自动测试 → Code Review → 合入main
|
||||||
|
↓
|
||||||
|
自动构建(GitHub Actions / GitLab CI)
|
||||||
|
↓
|
||||||
|
┌────────────────┼────────────────┐
|
||||||
|
↓ ↓ ↓
|
||||||
|
Dev Build Staging Build Prod Build
|
||||||
|
(内部测试) (TestFlight/Beta) (App Store/Play Store)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*文档版本: v1.0*
|
||||||
|
*基于: Genex 券交易平台 - 软件需求规格说明书 v4.1*
|
||||||
|
*技术栈: Flutter 3.x + Riverpod + Clean Architecture*
|
||||||
|
|
@ -0,0 +1,287 @@
|
||||||
|
# Genex Flutter 管理后台 App 开发指南
|
||||||
|
|
||||||
|
> 发行方管理控制台(Issuer Console App)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. 产品定位
|
||||||
|
|
||||||
|
发行方管理后台App为企业/政府/机构提供**Web2体验**的券发行与管理工具。发行方无需了解区块链技术,发券 = 创建优惠活动,链上铸造在后台自动完成。
|
||||||
|
|
||||||
|
**核心设计原则**:
|
||||||
|
- 发行方看到的是"创建优惠活动",不是"链上铸造NFT"
|
||||||
|
- 消费数据隔离:发行方仅可见汇总数据(兑付率、销量),不可见消费者个人信息
|
||||||
|
- AI Agent深度融合:协助发券建议、定价优化、信用提升
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 技术栈
|
||||||
|
|
||||||
|
| 技术 | 用途 |
|
||||||
|
|------|------|
|
||||||
|
| **Flutter 3.x** | 跨平台(iOS/Android),与Consumer App共享核心模块 |
|
||||||
|
| **Riverpod 2.x** | 状态管理 |
|
||||||
|
| **GoRouter** | 路由管理 |
|
||||||
|
| **Dio** | HTTP客户端 |
|
||||||
|
| **Freezed** | 不可变数据模型 |
|
||||||
|
| **fl_chart** | 数据可视化图表 |
|
||||||
|
| **qr_code_scanner** | 扫码核销 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. 项目结构
|
||||||
|
|
||||||
|
```
|
||||||
|
genex_issuer/
|
||||||
|
├── lib/
|
||||||
|
│ ├── main.dart
|
||||||
|
│ ├── app/
|
||||||
|
│ │ ├── router.dart # 发行方专用路由
|
||||||
|
│ │ └── theme/ # 企业端主题(区别于消费者端)
|
||||||
|
│ ├── core/ # 共享核心模块(可从mono-repo引用)
|
||||||
|
│ ├── features/
|
||||||
|
│ │ ├── auth/ # 企业注册/登录
|
||||||
|
│ │ ├── onboarding/ # 入驻审核流程
|
||||||
|
│ │ ├── coupon_management/ # 券管理(核心模块)
|
||||||
|
│ │ │ ├── create/ # 创建券(模板化发券)
|
||||||
|
│ │ │ ├── list/ # 券列表管理
|
||||||
|
│ │ │ ├── detail/ # 券详情/数据
|
||||||
|
│ │ │ └── recall/ # 券召回/下架
|
||||||
|
│ │ ├── redemption/ # 核销管理
|
||||||
|
│ │ ├── finance/ # 财务管理
|
||||||
|
│ │ ├── credit/ # 信用评级
|
||||||
|
│ │ ├── dashboard/ # 数据仪表盘
|
||||||
|
│ │ ├── ai_agent/ # AI Agent
|
||||||
|
│ │ └── settings/ # 设置
|
||||||
|
│ └── shared/ # 共享组件
|
||||||
|
├── test/
|
||||||
|
└── pubspec.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. 核心功能模块
|
||||||
|
|
||||||
|
### 4.1 企业入驻审核
|
||||||
|
|
||||||
|
```dart
|
||||||
|
// 入驻流程状态机
|
||||||
|
enum OnboardingStep {
|
||||||
|
companyInfo, // 企业基本信息
|
||||||
|
documents, // 营业执照/资质文件上传
|
||||||
|
contactPerson, // 联系人信息
|
||||||
|
review, // 等待平台审核
|
||||||
|
approved, // 审核通过
|
||||||
|
rejected, // 审核拒绝(可重新提交)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 零保证金入驻:审核通过后给予初始低额度
|
||||||
|
@freezed
|
||||||
|
class IssuerProfile with _$IssuerProfile {
|
||||||
|
const factory IssuerProfile({
|
||||||
|
required String id,
|
||||||
|
required String companyName,
|
||||||
|
required String businessLicense,
|
||||||
|
required CreditRating creditRating, // 信用等级
|
||||||
|
required double issuanceQuota, // 发行额度
|
||||||
|
required IssuerTier tier, // 白银/黄金/铂金/钻石
|
||||||
|
required OnboardingStep onboardingStep,
|
||||||
|
}) = _IssuerProfile;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum CreditRating { AAA, AA, A, BBB, BB }
|
||||||
|
enum IssuerTier { silver, gold, platinum, diamond }
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.2 模板化发券
|
||||||
|
|
||||||
|
> 发行方通过Web2界面创建券,无需了解NFT/ERC标准。
|
||||||
|
|
||||||
|
```dart
|
||||||
|
// 券模板类型
|
||||||
|
enum CouponTemplate {
|
||||||
|
discount, // 折扣券
|
||||||
|
voucher, // 代金券
|
||||||
|
giftCard, // 礼品卡
|
||||||
|
storedValue, // 储值券
|
||||||
|
}
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class CreateCouponParams with _$CreateCouponParams {
|
||||||
|
const factory CreateCouponParams({
|
||||||
|
required CouponTemplate template,
|
||||||
|
required String name,
|
||||||
|
required double faceValue,
|
||||||
|
required DateTime expiryDate, // ≤12个月(Utility Track强制)
|
||||||
|
required int quantity, // 发行数量
|
||||||
|
double? issuePrice, // 发行价(通常折价)
|
||||||
|
bool? transferable, // 是否允许转让(默认可转让)
|
||||||
|
int? maxResaleCount, // 最大转售次数(默认2-3次)
|
||||||
|
bool? stackable, // 是否可叠加使用
|
||||||
|
double? minPurchaseAmount, // 最低消费金额
|
||||||
|
List<String>? allowedStoreIds, // 限定门店
|
||||||
|
String? description,
|
||||||
|
String? imageUrl,
|
||||||
|
}) = _CreateCouponParams;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```dart
|
||||||
|
// 发券流程
|
||||||
|
// 选择模板 → 填写信息 → 设定规则 → 预览 → 提交审核 → 审核通过 → 自动链上铸造+上架
|
||||||
|
class CreateCouponUseCase {
|
||||||
|
Future<Either<Failure, CouponDraft>> call(CreateCouponParams params) async {
|
||||||
|
// 前端校验
|
||||||
|
if (params.expiryDate.difference(DateTime.now()).inDays > 365) {
|
||||||
|
return Left(Failure.validation(
|
||||||
|
errors: {'expiryDate': 'Utility Track有效期不得超过12个月'},
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return _repo.submitCouponDraft(params);
|
||||||
|
// 后端:审核通过 → 自动调用CouponFactory合约铸造(发行方无感知)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.3 数据仪表盘
|
||||||
|
|
||||||
|
```dart
|
||||||
|
// 发行方数据概览
|
||||||
|
@freezed
|
||||||
|
class IssuerDashboard with _$IssuerDashboard {
|
||||||
|
const factory IssuerDashboard({
|
||||||
|
required int totalIssued, // 总发行量
|
||||||
|
required int totalRedeemed, // 总核销量
|
||||||
|
required double redemptionRate, // 兑付率
|
||||||
|
required double breakageRate, // Breakage率
|
||||||
|
required double totalRevenue, // 总销售收入
|
||||||
|
required double availableBalance, // 可提现余额
|
||||||
|
required CreditRating creditRating, // 信用等级
|
||||||
|
required double quotaUsed, // 已用额度
|
||||||
|
required double quotaTotal, // 总额度
|
||||||
|
}) = _IssuerDashboard;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.4 财务管理
|
||||||
|
|
||||||
|
```dart
|
||||||
|
// 财务视图:法币展示,不暴露链上稳定币细节
|
||||||
|
@freezed
|
||||||
|
class FinanceOverview with _$FinanceOverview {
|
||||||
|
const factory FinanceOverview({
|
||||||
|
required double salesRevenue, // 销售收入
|
||||||
|
required double pendingSettlement, // 待结算
|
||||||
|
required double withdrawable, // 可提现
|
||||||
|
required double totalWithdrawn, // 已提现
|
||||||
|
required List<Transaction> recentTransactions,
|
||||||
|
}) = _FinanceOverview;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.5 信用评级展示
|
||||||
|
|
||||||
|
```dart
|
||||||
|
// 四因子信用评分:核销率35% + (1-Breakage率)25% + 市场存续20% + 用户满意度20%
|
||||||
|
class CreditScoreWidget extends StatelessWidget {
|
||||||
|
final CreditDetail credit;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Column(children: [
|
||||||
|
// 总分和等级
|
||||||
|
CreditScoreGauge(score: credit.totalScore, rating: credit.rating),
|
||||||
|
// 四因子明细
|
||||||
|
FactorBar(label: '核销率', value: credit.redemptionRate, weight: 0.35),
|
||||||
|
FactorBar(label: '沉淀控制', value: 1 - credit.breakageRate, weight: 0.25),
|
||||||
|
FactorBar(label: '市场存续', value: credit.tenureScore, weight: 0.20),
|
||||||
|
FactorBar(label: '用户满意度', value: credit.satisfaction, weight: 0.20),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. AI Agent 集成
|
||||||
|
|
||||||
|
### 5.1 发行方AI Agent场景
|
||||||
|
|
||||||
|
| 场景 | AI能力 | UI实现 |
|
||||||
|
|------|--------|--------|
|
||||||
|
| 发券建议 | 分析市场趋势,建议发券时间/面值/折扣/数量 | 发券中心顶部AI建议卡片 |
|
||||||
|
| 定价优化 | 三因子模型+AI定价引擎,提供最优定价策略 | 创建券时AI推荐价格+对比分析 |
|
||||||
|
| 信用提升 | 分析信用评分各维度,给出改善建议 | 信用等级页面AI建议列表 |
|
||||||
|
| 销售分析 | 智能解读销售数据,发现异常和机会 | 数据中心AI洞察卡片 |
|
||||||
|
| 额度规划 | 预测额度消耗速度,建议补充计划 | 额度页面AI规划时间线 |
|
||||||
|
| 合规助手 | 提醒合规要求,辅助材料准备 | 入驻审核时AI检查清单 |
|
||||||
|
|
||||||
|
### 5.2 AI建议卡片组件
|
||||||
|
|
||||||
|
```dart
|
||||||
|
class AiSuggestionCard extends StatelessWidget {
|
||||||
|
final AiSuggestion suggestion;
|
||||||
|
final VoidCallback onAccept;
|
||||||
|
final VoidCallback onDismiss;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Card(
|
||||||
|
child: Column(children: [
|
||||||
|
Row(children: [
|
||||||
|
Icon(Icons.smart_toy, color: Colors.blue),
|
||||||
|
Text('AI建议', style: Theme.of(context).textTheme.titleSmall),
|
||||||
|
]),
|
||||||
|
Text(suggestion.content),
|
||||||
|
if (suggestion.actionable)
|
||||||
|
Row(children: [
|
||||||
|
TextButton(onPressed: onDismiss, child: Text('忽略')),
|
||||||
|
ElevatedButton(onPressed: onAccept, child: Text('采纳')),
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. 发行方分层激励展示
|
||||||
|
|
||||||
|
| 层级 | 月发行量 | 手续费率 | 增值服务 |
|
||||||
|
|------|---------|---------|---------|
|
||||||
|
| 白银 | < 100万 | 1.5% | 基础数据看板 |
|
||||||
|
| 黄金 | 100-500万 | 1.2% | 高级数据分析+推荐位 |
|
||||||
|
| 铂金 | 500-2000万 | 1.0% | 专属客服+定制报表 |
|
||||||
|
| 钻石 | > 2000万 | 0.8% | 定制开发+专属API+联合营销 |
|
||||||
|
|
||||||
|
> 新入驻发行方首月享黄金层级手续费(获客激励)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. 与Consumer App共享
|
||||||
|
|
||||||
|
| 共享模块 | 内容 |
|
||||||
|
|---------|------|
|
||||||
|
| `core/network/` | Dio配置、拦截器 |
|
||||||
|
| `core/storage/` | 本地存储封装 |
|
||||||
|
| `core/constants/` | 术语映射、API地址 |
|
||||||
|
| `shared/widgets/` | 通用UI组件 |
|
||||||
|
| `shared/models/` | Coupon、User等共享模型 |
|
||||||
|
|
||||||
|
通过Dart Package或Mono-repo方式实现代码共享。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. 测试与发布
|
||||||
|
|
||||||
|
- 单元测试:发券参数校验、信用评分计算、额度校验
|
||||||
|
- Widget测试:发券表单、仪表盘图表
|
||||||
|
- 集成测试:完整发券流程、核销流程
|
||||||
|
- 发布通道:与Consumer App独立(不同App ID,不同签名)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*文档版本: v1.0*
|
||||||
|
*基于: Genex 券交易平台 - 软件需求规格说明书 v4.1*
|
||||||
|
*技术栈: Flutter 3.x + Riverpod + Clean Architecture*
|
||||||
|
|
@ -0,0 +1,352 @@
|
||||||
|
# Genex Web 管理前端开发指南
|
||||||
|
|
||||||
|
> 平台管理后台(Admin Dashboard) — React + TypeScript + Next.js
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. 技术栈
|
||||||
|
|
||||||
|
| 技术 | 版本 | 用途 |
|
||||||
|
|------|------|------|
|
||||||
|
| **React** | 18.x | UI框架 |
|
||||||
|
| **TypeScript** | 5.x | 类型安全 |
|
||||||
|
| **Next.js** | 14.x | SSR/SSG + App Router |
|
||||||
|
| **Zustand** | 4.x | 轻量状态管理(UI状态) |
|
||||||
|
| **Redux Toolkit** | 2.x | 复杂业务状态(交易、审核流程) |
|
||||||
|
| **RTK Query** | 内置 | API数据获取与缓存 |
|
||||||
|
| **Ant Design** | 5.x | 企业级UI组件库 |
|
||||||
|
| **ECharts / Recharts** | 最新 | 数据可视化 |
|
||||||
|
| **TanStack Table** | 8.x | 高性能数据表格 |
|
||||||
|
| **React Hook Form** | 7.x | 表单管理 |
|
||||||
|
| **Zod** | 3.x | 运行时类型校验 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 项目结构
|
||||||
|
|
||||||
|
```
|
||||||
|
genex-admin/
|
||||||
|
├── src/
|
||||||
|
│ ├── app/ # Next.js App Router
|
||||||
|
│ │ ├── layout.tsx # 根布局
|
||||||
|
│ │ ├── page.tsx # Dashboard首页
|
||||||
|
│ │ ├── (auth)/ # 认证路由组
|
||||||
|
│ │ │ ├── login/page.tsx
|
||||||
|
│ │ │ └── layout.tsx
|
||||||
|
│ │ ├── (dashboard)/ # 管理面板路由组
|
||||||
|
│ │ │ ├── layout.tsx # 侧边栏+顶栏布局
|
||||||
|
│ │ │ ├── users/ # 用户管理
|
||||||
|
│ │ │ ├── issuers/ # 发行方管理
|
||||||
|
│ │ │ ├── coupons/ # 券管理
|
||||||
|
│ │ │ ├── trading/ # 交易监控
|
||||||
|
│ │ │ ├── compliance/ # 合规管理
|
||||||
|
│ │ │ ├── risk/ # 风控中心
|
||||||
|
│ │ │ ├── finance/ # 财务管理
|
||||||
|
│ │ │ ├── chain/ # 链上监控
|
||||||
|
│ │ │ └── system/ # 系统管理
|
||||||
|
│ ├── components/
|
||||||
|
│ │ ├── ui/ # 基础UI组件
|
||||||
|
│ │ ├── business/ # 业务组件
|
||||||
|
│ │ └── ai-agent/ # AI Agent组件
|
||||||
|
│ ├── features/ # 功能模块(Redux slices)
|
||||||
|
│ │ ├── auth/
|
||||||
|
│ │ ├── users/
|
||||||
|
│ │ ├── issuers/
|
||||||
|
│ │ ├── coupons/
|
||||||
|
│ │ ├── trading/
|
||||||
|
│ │ ├── compliance/
|
||||||
|
│ │ └── risk/
|
||||||
|
│ ├── services/ # API服务层
|
||||||
|
│ │ ├── api.ts # RTK Query base API
|
||||||
|
│ │ └── endpoints/ # 按模块分的API端点
|
||||||
|
│ ├── stores/ # Zustand stores
|
||||||
|
│ │ ├── ui-store.ts # UI状态(侧边栏、主题)
|
||||||
|
│ │ └── ai-agent-store.ts # AI Agent状态
|
||||||
|
│ ├── hooks/ # 自定义Hooks
|
||||||
|
│ ├── lib/ # 工具函数
|
||||||
|
│ │ ├── constants.ts
|
||||||
|
│ │ ├── utils.ts
|
||||||
|
│ │ └── types.ts
|
||||||
|
│ └── styles/ # 全局样式
|
||||||
|
├── public/
|
||||||
|
├── tests/
|
||||||
|
├── next.config.js
|
||||||
|
├── tailwind.config.ts
|
||||||
|
└── package.json
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. 状态管理策略
|
||||||
|
|
||||||
|
### Zustand vs Redux Toolkit 分工
|
||||||
|
|
||||||
|
| 类型 | 工具 | 场景 |
|
||||||
|
|------|------|------|
|
||||||
|
| **UI状态** | Zustand | 侧边栏折叠、主题切换、弹窗控制 |
|
||||||
|
| **服务端数据** | RTK Query | API数据获取、缓存、自动刷新 |
|
||||||
|
| **复杂业务流** | Redux Toolkit | 审核流程、交易状态机、多步骤表单 |
|
||||||
|
| **AI Agent** | Zustand | 对话历史、Agent面板状态 |
|
||||||
|
|
||||||
|
### 3.1 RTK Query API定义
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// src/services/api.ts
|
||||||
|
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
|
||||||
|
|
||||||
|
export const api = createApi({
|
||||||
|
baseQuery: fetchBaseQuery({
|
||||||
|
baseUrl: '/api/v1',
|
||||||
|
prepareHeaders: (headers) => {
|
||||||
|
const token = getToken();
|
||||||
|
if (token) headers.set('Authorization', `Bearer ${token}`);
|
||||||
|
return headers;
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
tagTypes: ['Users', 'Issuers', 'Coupons', 'Orders', 'Compliance'],
|
||||||
|
endpoints: () => ({}),
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// src/services/endpoints/issuers.ts
|
||||||
|
export const issuerApi = api.injectEndpoints({
|
||||||
|
endpoints: (builder) => ({
|
||||||
|
getIssuers: builder.query<PaginatedResult<Issuer>, IssuerQuery>({
|
||||||
|
query: (params) => ({ url: '/issuers', params }),
|
||||||
|
providesTags: ['Issuers'],
|
||||||
|
}),
|
||||||
|
approveIssuer: builder.mutation<void, { id: string; decision: 'approve' | 'reject' }>({
|
||||||
|
query: ({ id, ...body }) => ({
|
||||||
|
url: `/issuers/${id}/review`,
|
||||||
|
method: 'POST',
|
||||||
|
body,
|
||||||
|
}),
|
||||||
|
invalidatesTags: ['Issuers'],
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.2 Zustand UI Store
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// src/stores/ui-store.ts
|
||||||
|
import { create } from 'zustand';
|
||||||
|
|
||||||
|
interface UiState {
|
||||||
|
sidebarCollapsed: boolean;
|
||||||
|
theme: 'light' | 'dark';
|
||||||
|
toggleSidebar: () => void;
|
||||||
|
setTheme: (theme: 'light' | 'dark') => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useUiStore = create<UiState>((set) => ({
|
||||||
|
sidebarCollapsed: false,
|
||||||
|
theme: 'light',
|
||||||
|
toggleSidebar: () => set((s) => ({ sidebarCollapsed: !s.sidebarCollapsed })),
|
||||||
|
setTheme: (theme) => set({ theme }),
|
||||||
|
}));
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. 核心页面模块
|
||||||
|
|
||||||
|
### 4.1 Dashboard 首页
|
||||||
|
|
||||||
|
- 关键指标卡片:日交易量、活跃用户、新发行方、待审核数
|
||||||
|
- 交易量趋势图(ECharts线图)
|
||||||
|
- 异常交易告警列表
|
||||||
|
- AI洞察面板
|
||||||
|
|
||||||
|
### 4.2 用户管理
|
||||||
|
|
||||||
|
- 用户列表(TanStack Table,支持搜索/排序/分页)
|
||||||
|
- KYC审核详情
|
||||||
|
- 用户资产查看(我的券、余额、交易记录)
|
||||||
|
- 风控标记用户处理
|
||||||
|
|
||||||
|
### 4.3 发行方管理
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 发行方审核流程
|
||||||
|
interface IssuerReview {
|
||||||
|
issuerId: string;
|
||||||
|
companyName: string;
|
||||||
|
businessLicense: string;
|
||||||
|
documents: Document[];
|
||||||
|
creditRating: CreditRating;
|
||||||
|
aiRiskScore: number; // AI预审风险分
|
||||||
|
aiRiskFlags: string[]; // AI标记的风险点
|
||||||
|
reviewStatus: 'pending' | 'approved' | 'rejected';
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
| 功能 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| 入驻审核 | AI预审+人工复核,标记风险点 |
|
||||||
|
| 信用管理 | 查看/调整信用评级,额度管理 |
|
||||||
|
| 发行监控 | 发行量、兑付率、Breakage率监控 |
|
||||||
|
| 违约处理 | 降级、冻结发行、账户冻结 |
|
||||||
|
|
||||||
|
### 4.4 交易监控
|
||||||
|
|
||||||
|
- 实时交易流(WebSocket推送)
|
||||||
|
- 订单簿深度图
|
||||||
|
- 异常交易检测告警
|
||||||
|
- 做市商活动监控
|
||||||
|
|
||||||
|
### 4.5 合规管理
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
interface ComplianceCase {
|
||||||
|
id: string;
|
||||||
|
type: 'KYC' | 'AML' | 'OFAC' | 'TravelRule';
|
||||||
|
severity: 'low' | 'medium' | 'high' | 'critical';
|
||||||
|
status: 'open' | 'investigating' | 'resolved' | 'escalated';
|
||||||
|
aiAnalysis: string; // AI合规分析
|
||||||
|
suggestedAction: string; // AI建议操作
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.6 风控中心
|
||||||
|
|
||||||
|
- 风控仪表盘(实时风险指标)
|
||||||
|
- 异常交易图谱(关联分析可视化)
|
||||||
|
- 自动冻结记录
|
||||||
|
- SAR(可疑交易报告)管理
|
||||||
|
|
||||||
|
### 4.7 系统管理
|
||||||
|
|
||||||
|
| 页面 | 功能 |
|
||||||
|
|------|------|
|
||||||
|
| 管理员账号 | 管理员列表、RBAC角色权限、操作日志 |
|
||||||
|
| 系统配置 | 手续费率、KYC阈值、交易限额 |
|
||||||
|
| 合约管理 | 合约部署状态、升级提案、升级日志 |
|
||||||
|
| 系统监控 | 服务健康、API响应时间、Genex Chain节点状态 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. AI Agent 集成
|
||||||
|
|
||||||
|
### 5.1 管理端AI Agent功能
|
||||||
|
|
||||||
|
| 场景 | AI能力 | UI实现 |
|
||||||
|
|------|--------|--------|
|
||||||
|
| 风险预警 | 实时检测异常交易模式 | 仪表盘AI警告卡片+处理建议 |
|
||||||
|
| 审核辅助 | AI预审发行方资料,标记风险点 | 审核页面AI评分+风险标签 |
|
||||||
|
| 合规报告 | 自动生成SAR/CTR/监管报表草稿 | 合规报表页AI生成按钮 |
|
||||||
|
| 运营洞察 | 分析运营数据,提出优化建议 | Dashboard AI洞察面板 |
|
||||||
|
| 智能搜索 | 自然语言查询用户/订单/交易 | 全局搜索框支持NL查询 |
|
||||||
|
| 决策支持 | 手续费率调整建议、额度配置建议 | 系统配置页AI建议标签 |
|
||||||
|
|
||||||
|
### 5.2 AI Agent侧边面板
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
// src/components/ai-agent/AgentPanel.tsx
|
||||||
|
export function AgentPanel() {
|
||||||
|
const { messages, sendMessage, isStreaming } = useAgentChat();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Drawer title="AI助手" placement="right" width={400}>
|
||||||
|
<ChatMessageList messages={messages} />
|
||||||
|
{isStreaming && <StreamingIndicator />}
|
||||||
|
<ChatInput onSend={sendMessage} placeholder="描述你要查询或分析的内容..." />
|
||||||
|
</Drawer>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. 权限管理(RBAC)
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 角色定义
|
||||||
|
enum AdminRole {
|
||||||
|
SuperAdmin = 'super_admin', // 超级管理员:全部权限
|
||||||
|
OperationAdmin = 'ops_admin', // 运营管理员:用户+发行方+券管理
|
||||||
|
ComplianceOfficer = 'compliance', // 合规官:合规+风控
|
||||||
|
FinanceAdmin = 'finance_admin', // 财务管理员:财务+结算
|
||||||
|
Viewer = 'viewer', // 只读:仅查看Dashboard
|
||||||
|
}
|
||||||
|
|
||||||
|
// 路由守卫
|
||||||
|
function AuthGuard({ children, requiredRole }: GuardProps) {
|
||||||
|
const { user } = useAuth();
|
||||||
|
if (!hasPermission(user.role, requiredRole)) {
|
||||||
|
return <ForbiddenPage />;
|
||||||
|
}
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. 实时数据
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// WebSocket连接管理
|
||||||
|
class AdminWebSocket {
|
||||||
|
private ws: WebSocket;
|
||||||
|
|
||||||
|
connect() {
|
||||||
|
this.ws = new WebSocket('wss://api.gogenex.com/admin/ws');
|
||||||
|
this.ws.onmessage = (event) => {
|
||||||
|
const data = JSON.parse(event.data);
|
||||||
|
switch (data.type) {
|
||||||
|
case 'trade_alert':
|
||||||
|
store.dispatch(addTradeAlert(data.payload));
|
||||||
|
break;
|
||||||
|
case 'risk_warning':
|
||||||
|
store.dispatch(addRiskWarning(data.payload));
|
||||||
|
break;
|
||||||
|
case 'chain_event':
|
||||||
|
store.dispatch(updateChainStatus(data.payload));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. 测试策略
|
||||||
|
|
||||||
|
| 类型 | 工具 | 覆盖 |
|
||||||
|
|------|------|------|
|
||||||
|
| 单元测试 | Vitest | Redux slices、工具函数、Hooks |
|
||||||
|
| 组件测试 | React Testing Library | 关键表单、表格、弹窗 |
|
||||||
|
| E2E测试 | Playwright | 审核流程、配置变更、报表导出 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. 部署
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Next.js部署配置
|
||||||
|
# Docker + Kubernetes
|
||||||
|
FROM node:20-alpine AS builder
|
||||||
|
WORKDIR /app
|
||||||
|
COPY package*.json ./
|
||||||
|
RUN npm ci
|
||||||
|
COPY . .
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
FROM node:20-alpine
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --from=builder /app/.next ./.next
|
||||||
|
COPY --from=builder /app/public ./public
|
||||||
|
COPY --from=builder /app/package.json ./
|
||||||
|
RUN npm ci --production
|
||||||
|
EXPOSE 3000
|
||||||
|
CMD ["npm", "start"]
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*文档版本: v1.0*
|
||||||
|
*基于: Genex 券交易平台 - 软件需求规格说明书 v4.1*
|
||||||
|
*技术栈: React 18 + TypeScript 5 + Next.js 14 + Zustand + Redux Toolkit*
|
||||||
|
|
@ -0,0 +1,322 @@
|
||||||
|
# Genex 小程序 + H5 开发指南
|
||||||
|
|
||||||
|
> 基于 Taro 3.x 的跨端轻量级应用
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. 产品定位
|
||||||
|
|
||||||
|
小程序/H5作为**轻量获客入口**,主要通过社交分享引流,提供核心消费者功能的精简版。完整功能引导下载原生App。
|
||||||
|
|
||||||
|
**覆盖平台**:
|
||||||
|
- 微信小程序(主要)
|
||||||
|
- 支付宝小程序
|
||||||
|
- H5(移动浏览器、App内嵌WebView)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 技术栈
|
||||||
|
|
||||||
|
| 技术 | 版本 | 用途 |
|
||||||
|
|------|------|------|
|
||||||
|
| **Taro** | 3.x | 跨端框架(React语法) |
|
||||||
|
| **React** | 18.x | UI框架 |
|
||||||
|
| **TypeScript** | 5.x | 类型安全 |
|
||||||
|
| **Zustand** | 4.x | 状态管理 |
|
||||||
|
| **Taro UI / NutUI** | 最新 | 跨端UI组件库 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. 项目结构
|
||||||
|
|
||||||
|
```
|
||||||
|
genex-mini/
|
||||||
|
├── src/
|
||||||
|
│ ├── app.ts # 应用入口
|
||||||
|
│ ├── app.config.ts # 全局配置
|
||||||
|
│ ├── pages/
|
||||||
|
│ │ ├── index/ # 首页(券推荐)
|
||||||
|
│ │ ├── coupon-detail/ # 券详情
|
||||||
|
│ │ ├── purchase/ # 购买页
|
||||||
|
│ │ ├── my-coupons/ # 我的券
|
||||||
|
│ │ ├── redeem/ # 券使用(出示券码)
|
||||||
|
│ │ ├── login/ # 登录/注册
|
||||||
|
│ │ └── profile/ # 个人中心
|
||||||
|
│ ├── components/
|
||||||
|
│ │ ├── coupon-card/ # 券卡片组件
|
||||||
|
│ │ ├── ai-guide/ # AI引导气泡
|
||||||
|
│ │ └── share-card/ # 分享卡片
|
||||||
|
│ ├── services/
|
||||||
|
│ │ ├── api.ts # API请求封装
|
||||||
|
│ │ └── auth.ts # 认证服务
|
||||||
|
│ ├── stores/
|
||||||
|
│ │ ├── user-store.ts # 用户状态
|
||||||
|
│ │ └── coupon-store.ts # 券状态
|
||||||
|
│ ├── utils/
|
||||||
|
│ │ ├── share.ts # 分享工具
|
||||||
|
│ │ └── platform.ts # 平台判断
|
||||||
|
│ └── assets/
|
||||||
|
├── config/
|
||||||
|
│ ├── index.ts # Taro编译配置
|
||||||
|
│ ├── dev.ts
|
||||||
|
│ └── prod.ts
|
||||||
|
└── package.json
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. 核心功能(精简版)
|
||||||
|
|
||||||
|
### 4.1 功能矩阵
|
||||||
|
|
||||||
|
| 功能 | 小程序/H5 | 原生App |
|
||||||
|
|------|----------|---------|
|
||||||
|
| 浏览券市场 | ✅ | ✅ |
|
||||||
|
| 购买券 | ✅ | ✅ |
|
||||||
|
| 我的券 | ✅ | ✅ |
|
||||||
|
| 出示券码使用 | ✅ | ✅ |
|
||||||
|
| 二级市场交易 | ❌(引导下载App) | ✅ |
|
||||||
|
| P2P转赠 | ❌(引导下载App) | ✅ |
|
||||||
|
| AI Agent完整对话 | ❌(精简版) | ✅ |
|
||||||
|
| KYC认证 | L0/L1 | L0/L1/L2/L3 |
|
||||||
|
|
||||||
|
### 4.2 首页
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
// src/pages/index/index.tsx
|
||||||
|
import { View, ScrollView } from '@tarojs/components';
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
import { useCouponStore } from '@/stores/coupon-store';
|
||||||
|
import CouponCard from '@/components/coupon-card';
|
||||||
|
import AiGuide from '@/components/ai-guide';
|
||||||
|
|
||||||
|
export default function IndexPage() {
|
||||||
|
const { hotCoupons, fetchHotCoupons } = useCouponStore();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchHotCoupons();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View className="index-page">
|
||||||
|
{/* AI轻量推荐条 */}
|
||||||
|
<AiGuide type="recommendation" />
|
||||||
|
|
||||||
|
{/* 搜索栏 */}
|
||||||
|
<SearchBar placeholder="搜索券..." />
|
||||||
|
|
||||||
|
{/* 分类标签 */}
|
||||||
|
<CategoryTabs />
|
||||||
|
|
||||||
|
{/* 券列表 */}
|
||||||
|
<ScrollView scrollY>
|
||||||
|
{hotCoupons.map((coupon) => (
|
||||||
|
<CouponCard key={coupon.id} coupon={coupon} />
|
||||||
|
))}
|
||||||
|
</ScrollView>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.3 购买流程
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
// src/pages/purchase/index.tsx
|
||||||
|
export default function PurchasePage() {
|
||||||
|
const { id } = useRouter().params;
|
||||||
|
const coupon = useCouponDetail(id!);
|
||||||
|
|
||||||
|
const handlePurchase = async () => {
|
||||||
|
// 微信小程序:调用微信支付
|
||||||
|
// H5:调用支付宝/银联等H5支付
|
||||||
|
const paymentResult = await Taro.requestPayment({
|
||||||
|
...paymentParams,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (paymentResult.errMsg === 'requestPayment:ok') {
|
||||||
|
// 后端自动完成:法币→稳定币→链上原子交换
|
||||||
|
await api.confirmPurchase(orderId);
|
||||||
|
Taro.navigateTo({ url: '/pages/purchase-success/index' });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
<CouponDetailCard coupon={coupon} />
|
||||||
|
<PriceSection price={coupon.currentPrice} faceValue={coupon.faceValue} />
|
||||||
|
<Button onClick={handlePurchase}>立即购买</Button>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.4 出示券码
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
// src/pages/redeem/index.tsx
|
||||||
|
export default function RedeemPage() {
|
||||||
|
const { couponId } = useRouter().params;
|
||||||
|
const qrCode = useRedeemCode(couponId!);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View className="redeem-page">
|
||||||
|
<Text>出示给商户扫码</Text>
|
||||||
|
<QRCode value={qrCode.data} size={200} />
|
||||||
|
<Text className="coupon-code">{qrCode.numericCode}</Text>
|
||||||
|
<BrightnessMaxWidget /> {/* 自动调高亮度 */}
|
||||||
|
<CountdownTimer expiry={qrCode.expiresAt} />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. 社交分享
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// src/utils/share.ts
|
||||||
|
export function configShare(coupon: Coupon) {
|
||||||
|
return {
|
||||||
|
title: `${coupon.issuerName} ${coupon.faceValue}元券 仅${coupon.currentPrice}元`,
|
||||||
|
path: `/pages/coupon-detail/index?id=${coupon.id}&from=share`,
|
||||||
|
imageUrl: coupon.shareImage || coupon.imageUrl,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 小程序页面配置
|
||||||
|
export default {
|
||||||
|
onShareAppMessage() {
|
||||||
|
return configShare(currentCoupon);
|
||||||
|
},
|
||||||
|
onShareTimeline() {
|
||||||
|
return {
|
||||||
|
title: `限时折扣券`,
|
||||||
|
query: `id=${currentCoupon.id}`,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. AI Agent(精简版)
|
||||||
|
|
||||||
|
小程序/H5中AI Agent以轻量形式集成:
|
||||||
|
|
||||||
|
| 组件 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| 推荐条 | 首页顶部横向滚动AI推荐标签 |
|
||||||
|
| 购买引导 | 新用户首次进入时的对话气泡引导 |
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
// src/components/ai-guide/index.tsx
|
||||||
|
export default function AiGuide({ type }: { type: 'recommendation' | 'purchase' }) {
|
||||||
|
const suggestions = useAiSuggestions(type);
|
||||||
|
|
||||||
|
if (type === 'recommendation') {
|
||||||
|
return (
|
||||||
|
<ScrollView scrollX className="ai-suggest-bar">
|
||||||
|
{suggestions.map((s) => (
|
||||||
|
<Tag key={s.id} onClick={() => navigateToCoupon(s.couponId)}>
|
||||||
|
{s.text}
|
||||||
|
</Tag>
|
||||||
|
))}
|
||||||
|
</ScrollView>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return <ChatBubble message={suggestions[0]?.text} />;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. 平台适配
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// src/utils/platform.ts
|
||||||
|
import Taro from '@tarojs/taro';
|
||||||
|
|
||||||
|
export function getPlatform(): 'weapp' | 'alipay' | 'h5' {
|
||||||
|
return Taro.getEnv() as any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getPaymentMethod() {
|
||||||
|
switch (getPlatform()) {
|
||||||
|
case 'weapp': return 'wechat_pay';
|
||||||
|
case 'alipay': return 'alipay';
|
||||||
|
case 'h5': return 'h5_pay';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 条件编译
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Taro支持条件编译
|
||||||
|
// #ifdef WEAPP
|
||||||
|
// 微信小程序专用代码
|
||||||
|
wx.login({ success: (res) => { /* ... */ } });
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef H5
|
||||||
|
// H5专用代码
|
||||||
|
window.location.href = authUrl;
|
||||||
|
// #endif
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. 性能优化
|
||||||
|
|
||||||
|
| 策略 | 实现 |
|
||||||
|
|------|------|
|
||||||
|
| 分包加载 | 主包只含首页+登录,其余分包 |
|
||||||
|
| 图片优化 | WebP格式 + CDN + 懒加载 |
|
||||||
|
| 数据预拉取 | `onPrefetch` 预加载详情页数据 |
|
||||||
|
| 骨架屏 | 关键页面skeleton loading |
|
||||||
|
| 缓存策略 | 券列表本地缓存,增量更新 |
|
||||||
|
|
||||||
|
### 分包配置
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// src/app.config.ts
|
||||||
|
export default defineAppConfig({
|
||||||
|
pages: [
|
||||||
|
'pages/index/index',
|
||||||
|
'pages/login/index',
|
||||||
|
],
|
||||||
|
subPackages: [
|
||||||
|
{
|
||||||
|
root: 'pages/coupon-detail',
|
||||||
|
pages: ['index'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
root: 'pages/purchase',
|
||||||
|
pages: ['index'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
root: 'pages/my-coupons',
|
||||||
|
pages: ['index'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. 测试与发布
|
||||||
|
|
||||||
|
| 平台 | 发布流程 |
|
||||||
|
|------|---------|
|
||||||
|
| 微信小程序 | 开发版 → 体验版 → 审核 → 正式版 |
|
||||||
|
| 支付宝小程序 | 开发版 → 灰度 → 审核 → 正式版 |
|
||||||
|
| H5 | CI/CD自动部署至CDN |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*文档版本: v1.0*
|
||||||
|
*基于: Genex 券交易平台 - 软件需求规格说明书 v4.1*
|
||||||
|
*技术栈: Taro 3.x + React 18 + TypeScript*
|
||||||
|
|
@ -0,0 +1,456 @@
|
||||||
|
# Genex 后端开发指南
|
||||||
|
|
||||||
|
> DDD + Clean Architecture + 微服务 | NestJS + Go + Kong + PostgreSQL
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. 技术栈总览
|
||||||
|
|
||||||
|
| 层级 | 技术 | 用途 |
|
||||||
|
|------|------|------|
|
||||||
|
| **API网关** | Kong | 限流、认证、路由、负载均衡 |
|
||||||
|
| **主要业务服务** | NestJS (TypeScript) | 业务逻辑微服务 |
|
||||||
|
| **高性能服务** | Go | 撮合引擎、链上事件监听、高频任务 |
|
||||||
|
| **翻译层** | Go + Redis | 地址映射、Gas代付、术语翻译 |
|
||||||
|
| **数据库** | PostgreSQL 15+ | 核心业务数据 |
|
||||||
|
| **时序数据库** | TimescaleDB | 行情数据、监控指标 |
|
||||||
|
| **缓存** | Redis Cluster | 热点数据、会话、订单簿缓存 |
|
||||||
|
| **消息队列** | Kafka | 事件驱动、链上事件监听 |
|
||||||
|
| **搜索** | Elasticsearch | 全文检索、日志分析 |
|
||||||
|
| **AI/ML** | FastAPI (Python) | 信用评分、价格预测、异常检测 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 架构设计:三层五域
|
||||||
|
|
||||||
|
### 2.1 五大业务域
|
||||||
|
|
||||||
|
| 域 | 服务名 | 语言 | 职责 |
|
||||||
|
|----|--------|------|------|
|
||||||
|
| D1 发行域 | `issuer-service` | NestJS | 发行方入驻、券管理、发行审批 |
|
||||||
|
| D2 交易域 | `trading-service` | Go | 撮合引擎、订单簿、做市商 |
|
||||||
|
| D3 清算域 | `clearing-service` | NestJS + Go | 链上结算、兑付清算、退款 |
|
||||||
|
| D4 合规域 | `compliance-service` | NestJS | KYC/AML、OFAC、Travel Rule |
|
||||||
|
| D5 AI域 | `ai-service` | FastAPI | 信用评分、定价、异常检测 |
|
||||||
|
| 通用 | `user-service` | NestJS | 用户注册、认证、Profile |
|
||||||
|
| 通用 | `translate-service` | Go | UX翻译层(地址映射、Gas代付) |
|
||||||
|
| 通用 | `notification-service` | NestJS | 消息推送、邮件、短信 |
|
||||||
|
| 通用 | `chain-indexer` | Go | 链上事件监听、数据索引 |
|
||||||
|
|
||||||
|
### 2.2 服务间通信
|
||||||
|
|
||||||
|
```
|
||||||
|
┌──────────────────────────────────────────────┐
|
||||||
|
│ Kong API Gateway │
|
||||||
|
│ 限流 | OAuth 2.1 + JWT | 路由 | 负载均衡 │
|
||||||
|
├──────────────────────────────────────────────┤
|
||||||
|
│ │
|
||||||
|
│ ┌─────────┐ ┌──────────┐ ┌────────────┐ │
|
||||||
|
│ │ user │ │ issuer │ │ trading │ │
|
||||||
|
│ │ service │ │ service │ │ service(Go)│ │
|
||||||
|
│ └────┬────┘ └────┬─────┘ └─────┬──────┘ │
|
||||||
|
│ │ │ │ │
|
||||||
|
│ └────────────┼──────────────┘ │
|
||||||
|
│ │ │
|
||||||
|
│ ┌─────┴─────┐ │
|
||||||
|
│ │ Kafka │ │
|
||||||
|
│ └─────┬─────┘ │
|
||||||
|
│ ┌────────────┼───────────────┐ │
|
||||||
|
│ ┌────┴────┐ ┌─────┴──────┐ ┌─────┴─────┐ │
|
||||||
|
│ │clearing │ │compliance │ │ai-service │ │
|
||||||
|
│ │service │ │service │ │(FastAPI) │ │
|
||||||
|
│ └─────────┘ └────────────┘ └───────────┘ │
|
||||||
|
└──────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
- **同步通信**:gRPC(服务间直接调用,如撮合→结算)
|
||||||
|
- **异步通信**:Kafka事件驱动(链上事件、通知、审计日志)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. DDD + Clean Architecture(NestJS服务)
|
||||||
|
|
||||||
|
### 3.1 模块结构(以issuer-service为例)
|
||||||
|
|
||||||
|
```
|
||||||
|
issuer-service/
|
||||||
|
├── src/
|
||||||
|
│ ├── main.ts
|
||||||
|
│ ├── app.module.ts
|
||||||
|
│ ├── domain/ # 领域层(纯业务逻辑,零外部依赖)
|
||||||
|
│ │ ├── entities/
|
||||||
|
│ │ │ ├── issuer.entity.ts # 发行方聚合根
|
||||||
|
│ │ │ ├── coupon-template.entity.ts
|
||||||
|
│ │ │ └── credit-rating.vo.ts # 值对象
|
||||||
|
│ │ ├── repositories/
|
||||||
|
│ │ │ └── issuer.repository.ts # Repository接口
|
||||||
|
│ │ ├── services/
|
||||||
|
│ │ │ ├── issuer-domain.service.ts
|
||||||
|
│ │ │ └── credit-scoring.service.ts
|
||||||
|
│ │ └── events/
|
||||||
|
│ │ ├── issuer-approved.event.ts
|
||||||
|
│ │ └── coupon-issued.event.ts
|
||||||
|
│ ├── application/ # 应用层(用例编排)
|
||||||
|
│ │ ├── commands/
|
||||||
|
│ │ │ ├── register-issuer.command.ts
|
||||||
|
│ │ │ ├── create-coupon.command.ts
|
||||||
|
│ │ │ └── handlers/
|
||||||
|
│ │ ├── queries/
|
||||||
|
│ │ │ ├── get-issuer.query.ts
|
||||||
|
│ │ │ └── handlers/
|
||||||
|
│ │ └── dto/
|
||||||
|
│ │ ├── create-issuer.dto.ts
|
||||||
|
│ │ └── create-coupon.dto.ts
|
||||||
|
│ ├── infrastructure/ # 基础设施层(外部实现)
|
||||||
|
│ │ ├── persistence/
|
||||||
|
│ │ │ ├── issuer.repository.impl.ts
|
||||||
|
│ │ │ ├── issuer.orm-entity.ts
|
||||||
|
│ │ │ └── typeorm.config.ts
|
||||||
|
│ │ ├── messaging/
|
||||||
|
│ │ │ └── kafka-publisher.ts
|
||||||
|
│ │ └── external/
|
||||||
|
│ │ └── chain-client.ts # 链上交互
|
||||||
|
│ └── interfaces/ # 接口层(HTTP/gRPC)
|
||||||
|
│ ├── http/
|
||||||
|
│ │ ├── issuer.controller.ts
|
||||||
|
│ │ └── coupon.controller.ts
|
||||||
|
│ └── grpc/
|
||||||
|
│ └── issuer.grpc-controller.ts
|
||||||
|
├── test/
|
||||||
|
└── package.json
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.2 领域实体
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// src/domain/entities/issuer.entity.ts
|
||||||
|
export class Issuer {
|
||||||
|
readonly id: string;
|
||||||
|
readonly companyName: string;
|
||||||
|
private _creditRating: CreditRating;
|
||||||
|
private _issuanceQuota: number;
|
||||||
|
private _tier: IssuerTier;
|
||||||
|
private _status: IssuerStatus;
|
||||||
|
|
||||||
|
// 信用评分四因子
|
||||||
|
updateCreditScore(metrics: CreditMetrics): void {
|
||||||
|
const score =
|
||||||
|
0.35 * metrics.redemptionRate +
|
||||||
|
0.25 * (1 - metrics.breakageRatio) +
|
||||||
|
0.20 * Math.log(metrics.marketTenure + 1) / Math.log(37) +
|
||||||
|
0.20 * metrics.userSatisfaction;
|
||||||
|
|
||||||
|
this._creditRating = CreditRating.fromScore(score);
|
||||||
|
this._issuanceQuota = this._creditRating.calculateQuota();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发券校验
|
||||||
|
canIssueCoupon(params: CreateCouponParams): Result<void> {
|
||||||
|
if (this._status !== IssuerStatus.ACTIVE)
|
||||||
|
return Result.fail('发行方状态异常');
|
||||||
|
if (params.totalValue > this.remainingQuota)
|
||||||
|
return Result.fail('超出发行额度');
|
||||||
|
if (params.expiryDays > 365)
|
||||||
|
return Result.fail('Utility Track有效期不得超过12个月');
|
||||||
|
return Result.ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.3 应用层Command
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// src/application/commands/handlers/create-coupon.handler.ts
|
||||||
|
@CommandHandler(CreateCouponCommand)
|
||||||
|
export class CreateCouponHandler {
|
||||||
|
constructor(
|
||||||
|
private issuerRepo: IssuerRepository,
|
||||||
|
private eventBus: EventBus,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async execute(command: CreateCouponCommand): Promise<CouponDraft> {
|
||||||
|
const issuer = await this.issuerRepo.findById(command.issuerId);
|
||||||
|
if (!issuer) throw new NotFoundException('发行方不存在');
|
||||||
|
|
||||||
|
// 领域校验
|
||||||
|
const validation = issuer.canIssueCoupon(command.params);
|
||||||
|
if (validation.isFailure) throw new BadRequestException(validation.error);
|
||||||
|
|
||||||
|
// 创建券草稿(待审核)
|
||||||
|
const draft = CouponDraft.create(issuer, command.params);
|
||||||
|
await this.issuerRepo.saveCouponDraft(draft);
|
||||||
|
|
||||||
|
// 发布领域事件
|
||||||
|
this.eventBus.publish(new CouponDraftCreatedEvent(draft));
|
||||||
|
|
||||||
|
return draft;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Go 高性能服务
|
||||||
|
|
||||||
|
### 4.1 撮合引擎
|
||||||
|
|
||||||
|
```go
|
||||||
|
// trading-service/internal/matching/engine.go
|
||||||
|
type MatchingEngine struct {
|
||||||
|
orderBooks map[string]*OrderBook // couponId → OrderBook
|
||||||
|
mu sync.RWMutex
|
||||||
|
}
|
||||||
|
|
||||||
|
type OrderBook struct {
|
||||||
|
Bids *redblacktree.Tree // 买单:价格降序
|
||||||
|
Asks *redblacktree.Tree // 卖单:价格升序
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *MatchingEngine) SubmitOrder(order *Order) []*Trade {
|
||||||
|
e.mu.Lock()
|
||||||
|
defer e.mu.Unlock()
|
||||||
|
|
||||||
|
book := e.getOrCreateBook(order.CouponID)
|
||||||
|
|
||||||
|
// Utility Track价格校验
|
||||||
|
if order.CouponType == CouponTypeUtility && order.Price > order.FaceValue {
|
||||||
|
return nil // 拒绝溢价单
|
||||||
|
}
|
||||||
|
|
||||||
|
// 撮合:价格优先 → 时间优先
|
||||||
|
trades := book.Match(order)
|
||||||
|
|
||||||
|
// 成交后发布事件到Kafka
|
||||||
|
for _, trade := range trades {
|
||||||
|
e.publisher.Publish("trade.matched", trade)
|
||||||
|
}
|
||||||
|
|
||||||
|
return trades
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.2 链上事件监听
|
||||||
|
|
||||||
|
```go
|
||||||
|
// chain-indexer/internal/indexer/indexer.go
|
||||||
|
type ChainIndexer struct {
|
||||||
|
ethClient *ethclient.Client
|
||||||
|
kafka sarama.SyncProducer
|
||||||
|
contracts map[string]common.Address
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *ChainIndexer) Start(ctx context.Context) {
|
||||||
|
// 监听Genex Chain事件
|
||||||
|
query := ethereum.FilterQuery{
|
||||||
|
Addresses: []common.Address{
|
||||||
|
i.contracts["CouponFactory"],
|
||||||
|
i.contracts["Settlement"],
|
||||||
|
i.contracts["Redemption"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
logs := make(chan types.Log)
|
||||||
|
sub, _ := i.ethClient.SubscribeFilterLogs(ctx, query, logs)
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case log := <-logs:
|
||||||
|
event := i.parseEvent(log)
|
||||||
|
i.kafka.SendMessage(&sarama.ProducerMessage{
|
||||||
|
Topic: "chain.events",
|
||||||
|
Value: sarama.ByteEncoder(event.Marshal()),
|
||||||
|
})
|
||||||
|
case err := <-sub.Err():
|
||||||
|
log.Error("subscription error", "err", err)
|
||||||
|
// 重连逻辑
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. UX翻译层
|
||||||
|
|
||||||
|
> 核心创新:将所有Web3操作翻译为Web2用户可理解的操作。
|
||||||
|
|
||||||
|
```go
|
||||||
|
// translate-service/internal/service/translate.go
|
||||||
|
type TranslateService struct {
|
||||||
|
mappingDB *redis.Client // 手机号→链上地址映射
|
||||||
|
mpcClient MPCClient // MPC钱包服务
|
||||||
|
paymaster PaymasterClient // Gas代付服务
|
||||||
|
}
|
||||||
|
|
||||||
|
// 手机号→链上地址
|
||||||
|
func (s *TranslateService) ResolveAddress(phone string) (common.Address, error) {
|
||||||
|
addr, err := s.mappingDB.Get(ctx, "phone:"+phone).Result()
|
||||||
|
if err == redis.Nil {
|
||||||
|
return common.Address{}, ErrUserNotFound
|
||||||
|
}
|
||||||
|
return common.HexToAddress(addr), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 购买券:法币→链上原子交换
|
||||||
|
func (s *TranslateService) ExecutePurchase(req PurchaseRequest) (*PurchaseResult, error) {
|
||||||
|
// 1. 法币支付确认
|
||||||
|
// 2. 法币→稳定币转换
|
||||||
|
// 3. 调用Settlement合约原子交换(Gas由Paymaster代付)
|
||||||
|
// 4. 返回"订单号"(映射TX Hash)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. API设计
|
||||||
|
|
||||||
|
### 6.1 RESTful规范
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
API规范:
|
||||||
|
风格: RESTful
|
||||||
|
版本控制: URL路径 /api/v1/
|
||||||
|
认证: OAuth 2.1 + JWT
|
||||||
|
限流:
|
||||||
|
普通用户: 100 req/min
|
||||||
|
发行方: 1,000 req/min
|
||||||
|
做市商: 10,000 req/min
|
||||||
|
响应格式: JSON
|
||||||
|
错误处理: RFC 7807 Problem Details
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.2 核心API端点
|
||||||
|
|
||||||
|
| 域 | 路径前缀 | 主要接口 |
|
||||||
|
|-----|---------|---------|
|
||||||
|
| 用户 | `/api/v1/users` | 注册、登录、KYC、资产查询 |
|
||||||
|
| 券 | `/api/v1/coupons` | 发行、查询、转让、核销 |
|
||||||
|
| 交易 | `/api/v1/trades` | 挂单、撤单、成交、历史 |
|
||||||
|
| 支付 | `/api/v1/payments` | 充值、提现、法币转换 |
|
||||||
|
| 发行方 | `/api/v1/issuers` | 入驻、审核、数据统计 |
|
||||||
|
| 合规 | `/api/v1/compliance` | KYC、AML、审计日志 |
|
||||||
|
| 翻译层 | `/api/v1/translate` | 地址映射、Gas代付 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. 数据库设计
|
||||||
|
|
||||||
|
### 7.1 PostgreSQL核心表
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- 用户表
|
||||||
|
CREATE TABLE users (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
phone VARCHAR(20) UNIQUE,
|
||||||
|
email VARCHAR(100) UNIQUE,
|
||||||
|
kyc_level SMALLINT NOT NULL DEFAULT 0,
|
||||||
|
wallet_mode VARCHAR(10) NOT NULL DEFAULT 'standard',
|
||||||
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 发行方表
|
||||||
|
CREATE TABLE issuers (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
company_name VARCHAR(200) NOT NULL,
|
||||||
|
business_license VARCHAR(100),
|
||||||
|
credit_rating VARCHAR(5) NOT NULL DEFAULT 'BBB',
|
||||||
|
credit_score NUMERIC(5,2) NOT NULL DEFAULT 60.00,
|
||||||
|
issuance_quota NUMERIC(15,2) NOT NULL DEFAULT 100000,
|
||||||
|
tier VARCHAR(10) NOT NULL DEFAULT 'silver',
|
||||||
|
status VARCHAR(20) NOT NULL DEFAULT 'pending',
|
||||||
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 券表(链下缓存,权威数据在链上)
|
||||||
|
CREATE TABLE coupons (
|
||||||
|
id UUID PRIMARY KEY,
|
||||||
|
chain_token_id BIGINT UNIQUE, -- 链上Token ID
|
||||||
|
issuer_id UUID REFERENCES issuers(id),
|
||||||
|
face_value NUMERIC(12,2) NOT NULL,
|
||||||
|
current_price NUMERIC(12,2),
|
||||||
|
expiry_date DATE NOT NULL,
|
||||||
|
coupon_type VARCHAR(10) NOT NULL DEFAULT 'utility',
|
||||||
|
status VARCHAR(20) NOT NULL DEFAULT 'available',
|
||||||
|
resale_count SMALLINT NOT NULL DEFAULT 0,
|
||||||
|
max_resale_count SMALLINT NOT NULL DEFAULT 3,
|
||||||
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 地址映射表(翻译层核心)
|
||||||
|
CREATE TABLE address_mappings (
|
||||||
|
user_id UUID REFERENCES users(id),
|
||||||
|
chain_address VARCHAR(42) NOT NULL UNIQUE,
|
||||||
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||||
|
PRIMARY KEY (user_id)
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. 安全规范
|
||||||
|
|
||||||
|
| 领域 | 规范 |
|
||||||
|
|------|------|
|
||||||
|
| 传输 | TLS 1.3 + 服务间mTLS |
|
||||||
|
| 认证 | OAuth 2.1 + JWT(短有效期 + Refresh Token) |
|
||||||
|
| 授权 | RBAC |
|
||||||
|
| 数据加密 | AES-256(敏感字段),HSM管理密钥 |
|
||||||
|
| API安全 | Rate Limiting + CORS + CSRF防护 |
|
||||||
|
| SQL注入 | ORM参数化查询(TypeORM / sqlx) |
|
||||||
|
| 审计 | 全链路操作日志,不可篡改 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. 部署架构
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Kubernetes部署
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: issuer-service
|
||||||
|
spec:
|
||||||
|
replicas: 3
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: issuer-service
|
||||||
|
image: genex/issuer-service:latest
|
||||||
|
resources:
|
||||||
|
requests: { cpu: "250m", memory: "512Mi" }
|
||||||
|
limits: { cpu: "1000m", memory: "1Gi" }
|
||||||
|
env:
|
||||||
|
- name: DB_HOST
|
||||||
|
valueFrom:
|
||||||
|
configMapKeyRef: { name: db-config, key: host }
|
||||||
|
- name: DB_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef: { name: db-secrets, key: password }
|
||||||
|
```
|
||||||
|
|
||||||
|
### 多区域部署
|
||||||
|
|
||||||
|
| 区域 | 部署 | 角色 |
|
||||||
|
|------|------|------|
|
||||||
|
| AWS美国(主) | 全量服务 + 主数据库 + Genex Chain主验证节点 |
|
||||||
|
| AWS新加坡 | 亚太服务 + 灾备数据库 + 区域验证节点 |
|
||||||
|
| 香港 | 监管节点 + 审计接口 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. 监控与可观测性
|
||||||
|
|
||||||
|
| 组件 | 工具 | 用途 |
|
||||||
|
|------|------|------|
|
||||||
|
| 指标 | Prometheus + Grafana | 服务指标、业务指标 |
|
||||||
|
| 日志 | ELK Stack | 日志收集分析 |
|
||||||
|
| 链路追踪 | Jaeger | 分布式调用追踪 |
|
||||||
|
| 告警 | AlertManager + PagerDuty | 异常告警 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*文档版本: v1.0*
|
||||||
|
*基于: Genex 券交易平台 - 软件需求规格说明书 v4.1*
|
||||||
|
*技术栈: NestJS + Go + Kong + PostgreSQL + Kafka + Redis*
|
||||||
|
|
@ -0,0 +1,561 @@
|
||||||
|
# Genex Chain 区块链开发指南
|
||||||
|
|
||||||
|
> 自建EVM兼容应用链 + 智能合约体系
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. 链架构总览
|
||||||
|
|
||||||
|
| 组件 | 技术选型 | 说明 |
|
||||||
|
|------|---------|------|
|
||||||
|
| **链框架** | Cosmos SDK(最新版本) | 200+生产链验证,模块化 |
|
||||||
|
| **共识引擎** | CometBFT(原Tendermint) | 拜占庭容错,**即时终结性** |
|
||||||
|
| **EVM模块** | **cosmos/evm**(官方Cosmos EVM) | Apache 2.0,替代已弃用的Ethermint |
|
||||||
|
| **跨链通信** | IBC | Cosmos生态原生跨链协议 |
|
||||||
|
| **跨链桥** | Axelar(主)/ Wormhole(备) | 稳定币从Ethereum桥入 |
|
||||||
|
| **撮合架构** | 链下内存订单簿 + 链上结算 | 参考dYdX v4 |
|
||||||
|
|
||||||
|
### 参考链
|
||||||
|
|
||||||
|
| 链 | 价值 | 关键参考 |
|
||||||
|
|----|------|---------|
|
||||||
|
| **Cronos** | Cosmos SDK + EVM最成熟实现 | <1s出块、Block-STM并行执行 |
|
||||||
|
| **dYdX v4** | 交易平台专用链标杆 | 链下订单簿+链上结算 |
|
||||||
|
| **Injective** | 金融应用Layer-1 | 链上CLOB、机构级合规 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 链设计参数
|
||||||
|
|
||||||
|
| 参数 | 目标值 |
|
||||||
|
|------|--------|
|
||||||
|
| 共识机制 | CometBFT PoS(初期平台运营验证节点) |
|
||||||
|
| EVM兼容 | 完全兼容(Solidity、Hardhat、MetaMask全套工具链) |
|
||||||
|
| 出块时间 | **≤ 1秒**(CometBFT即时终结性) |
|
||||||
|
| TPS | ≥ 5,000(Block-STM并行执行) |
|
||||||
|
| Gas策略 | 平台前期全额补贴,用户零Gas |
|
||||||
|
| 原生代币 | GNX(Gas + 治理;前期Gas补贴,用户不接触) |
|
||||||
|
| 节点运营 | 平台自营验证节点 + 未来开放合格机构节点 |
|
||||||
|
| 跨链 | IBC连接Cosmos生态 + Axelar桥连接Ethereum |
|
||||||
|
|
||||||
|
### 为什么自建链
|
||||||
|
|
||||||
|
| 维度 | 公链/L2 | Genex Chain |
|
||||||
|
|------|---------|-------------|
|
||||||
|
| Gas控制 | 受市场波动 | 平台完全控制,可设为零 |
|
||||||
|
| 合规执行 | 链层面无法强制 | 链级OFAC/Travel Rule内置 |
|
||||||
|
| 性能调优 | 共享资源 | 独享资源,针对券业务优化 |
|
||||||
|
| 升级自主 | 依赖链治理 | 平台自主决定升级 |
|
||||||
|
| 数据主权 | 完全公开 | 可控可见性 |
|
||||||
|
| 监管对接 | 难以定制 | 专属节点/API |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. 开发环境搭建
|
||||||
|
|
||||||
|
### 3.1 前置依赖
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Go 1.21+
|
||||||
|
go version
|
||||||
|
|
||||||
|
# Node.js 20+(合约开发工具)
|
||||||
|
node --version
|
||||||
|
|
||||||
|
# Foundry(合约开发框架)
|
||||||
|
curl -L https://foundry.paradigm.xyz | bash
|
||||||
|
foundryup
|
||||||
|
|
||||||
|
# Cosmos SDK CLI
|
||||||
|
go install cosmossdk.io/tools/cosmovisor/cmd/cosmovisor@latest
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.2 Genex Chain本地开发
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 克隆Genex Chain仓库
|
||||||
|
git clone https://git.gogenex.com/genex-chain.git
|
||||||
|
cd genex-chain
|
||||||
|
|
||||||
|
# 编译
|
||||||
|
make build
|
||||||
|
|
||||||
|
# 初始化本地测试链
|
||||||
|
./genexd init test-node --chain-id genex-localnet
|
||||||
|
|
||||||
|
# 创建创世账户
|
||||||
|
./genexd keys add validator
|
||||||
|
./genexd genesis add-genesis-account validator 1000000000ugnx
|
||||||
|
|
||||||
|
# 启动本地节点
|
||||||
|
./genexd start
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.3 合约开发环境
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 创建合约工程
|
||||||
|
mkdir genex-contracts && cd genex-contracts
|
||||||
|
|
||||||
|
# 使用Foundry初始化
|
||||||
|
forge init
|
||||||
|
|
||||||
|
# 项目结构
|
||||||
|
genex-contracts/
|
||||||
|
├── src/
|
||||||
|
│ ├── CouponFactory.sol
|
||||||
|
│ ├── Coupon.sol
|
||||||
|
│ ├── Settlement.sol
|
||||||
|
│ ├── Redemption.sol
|
||||||
|
│ ├── Treasury.sol
|
||||||
|
│ ├── Compliance.sol
|
||||||
|
│ └── Governance.sol
|
||||||
|
├── test/
|
||||||
|
│ ├── CouponFactory.t.sol
|
||||||
|
│ ├── Settlement.t.sol
|
||||||
|
│ └── ...
|
||||||
|
├── script/
|
||||||
|
│ └── Deploy.s.sol
|
||||||
|
└── foundry.toml
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. 智能合约体系(7合约系统)
|
||||||
|
|
||||||
|
### 4.1 合约架构
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────┐
|
||||||
|
│ Governance(治理) │
|
||||||
|
│ Gas参数调整 | 紧急冻结多签 | 合约升级管理 │
|
||||||
|
├─────────────────────────────────────────────┤
|
||||||
|
│ │
|
||||||
|
│ ┌──────────────┐ ┌───────────────────┐ │
|
||||||
|
│ │CouponFactory │ │ Compliance │ │
|
||||||
|
│ │ 券发行工厂 │ │ OFAC筛查 │ │
|
||||||
|
│ │ 铸造+类型标记 │ │ Travel Rule │ │
|
||||||
|
│ └──────┬───────┘ │ 紧急冻结 │ │
|
||||||
|
│ │ └───────────────────┘ │
|
||||||
|
│ ┌──────┴───────┐ │
|
||||||
|
│ │ Coupon │ ┌───────────────────┐ │
|
||||||
|
│ │ ERC-721/1155 │ │ Treasury │ │
|
||||||
|
│ │ 所有权+转移 │ │ 资金托管 │ │
|
||||||
|
│ └──────┬───────┘ │ 退款原子交换 │ │
|
||||||
|
│ │ └───────────────────┘ │
|
||||||
|
│ ┌──────┴───────────────────────┐ │
|
||||||
|
│ │ │ │
|
||||||
|
│ │ Settlement Redemption │ │
|
||||||
|
│ │ 交易结算 兑付清算 │ │
|
||||||
|
│ │ 原子交换 券销毁 │ │
|
||||||
|
│ └──────────────────────────────┘ │
|
||||||
|
└─────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.2 CouponFactory — 券发行工厂
|
||||||
|
|
||||||
|
```solidity
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
pragma solidity ^0.8.20;
|
||||||
|
|
||||||
|
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
|
||||||
|
import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
|
||||||
|
|
||||||
|
contract CouponFactory is Initializable, AccessControlUpgradeable {
|
||||||
|
enum CouponType { Utility, Security }
|
||||||
|
|
||||||
|
struct CouponConfig {
|
||||||
|
CouponType couponType; // 券类型(铸造后不可更改)
|
||||||
|
bool transferable; // 是否可转让
|
||||||
|
uint8 maxResaleCount; // 最大转售次数(Utility默认2-3)
|
||||||
|
uint256 maxPrice; // 价格上限(Utility = 面值)
|
||||||
|
uint256 expiryDate; // 到期日
|
||||||
|
uint256 minPurchase; // 最低消费金额
|
||||||
|
bool stackable; // 是否可叠加
|
||||||
|
bytes32[] allowedStores; // 限定门店
|
||||||
|
}
|
||||||
|
|
||||||
|
event CouponBatchMinted(
|
||||||
|
address indexed issuer,
|
||||||
|
uint256 indexed batchId,
|
||||||
|
uint256 faceValue,
|
||||||
|
uint256 quantity,
|
||||||
|
CouponType couponType
|
||||||
|
);
|
||||||
|
|
||||||
|
function mintBatch(
|
||||||
|
address issuer,
|
||||||
|
uint256 faceValue,
|
||||||
|
uint256 quantity,
|
||||||
|
CouponConfig calldata config
|
||||||
|
) external onlyRole(MINTER_ROLE) returns (uint256[] memory tokenIds) {
|
||||||
|
// MVP阶段只允许Utility类型
|
||||||
|
require(config.couponType == CouponType.Utility, "Only Utility Track in MVP");
|
||||||
|
|
||||||
|
// Utility Track强制:价格上限 = 面值
|
||||||
|
if (config.couponType == CouponType.Utility) {
|
||||||
|
require(config.maxPrice <= faceValue, "Utility: maxPrice <= faceValue");
|
||||||
|
require(config.expiryDate <= block.timestamp + 365 days, "Utility: max 12 months");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 铸造逻辑
|
||||||
|
tokenIds = _mintTokens(issuer, faceValue, quantity, config);
|
||||||
|
|
||||||
|
emit CouponBatchMinted(issuer, batchId, faceValue, quantity, config.couponType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.3 Settlement — 交易结算
|
||||||
|
|
||||||
|
```solidity
|
||||||
|
contract Settlement is Initializable, AccessControlUpgradeable {
|
||||||
|
ICoupon public couponContract;
|
||||||
|
IERC20 public stablecoin; // USDC
|
||||||
|
ICompliance public compliance;
|
||||||
|
|
||||||
|
event TradeSettled(
|
||||||
|
uint256 indexed tokenId,
|
||||||
|
address indexed buyer,
|
||||||
|
address indexed seller,
|
||||||
|
uint256 price
|
||||||
|
);
|
||||||
|
|
||||||
|
/// @notice 原子交换:券 ↔ 稳定币 同时转移
|
||||||
|
function executeSwap(
|
||||||
|
uint256 tokenId,
|
||||||
|
address buyer,
|
||||||
|
address seller,
|
||||||
|
uint256 price
|
||||||
|
) external onlyRole(SETTLER_ROLE) {
|
||||||
|
// 合规检查
|
||||||
|
require(!compliance.isBlacklisted(buyer), "Buyer blacklisted");
|
||||||
|
require(!compliance.isBlacklisted(seller), "Seller blacklisted");
|
||||||
|
|
||||||
|
// Utility Track: 价格 ≤ 面值
|
||||||
|
CouponConfig memory config = couponContract.getConfig(tokenId);
|
||||||
|
if (config.couponType == CouponType.Utility) {
|
||||||
|
require(price <= config.maxPrice, "Utility: price exceeds face value");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 转售次数检查
|
||||||
|
require(
|
||||||
|
couponContract.getResaleCount(tokenId) < config.maxResaleCount,
|
||||||
|
"Max resale count exceeded"
|
||||||
|
);
|
||||||
|
|
||||||
|
// 原子交换(要么全部成功,要么全部回滚)
|
||||||
|
stablecoin.transferFrom(buyer, seller, price);
|
||||||
|
couponContract.safeTransferFrom(seller, buyer, tokenId);
|
||||||
|
couponContract.incrementResaleCount(tokenId);
|
||||||
|
|
||||||
|
emit TradeSettled(tokenId, buyer, seller, price);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @notice 退款:反向原子交换
|
||||||
|
function executeRefund(
|
||||||
|
uint256 tokenId,
|
||||||
|
address buyer,
|
||||||
|
address seller,
|
||||||
|
uint256 refundAmount
|
||||||
|
) external onlyRole(SETTLER_ROLE) {
|
||||||
|
couponContract.safeTransferFrom(buyer, seller, tokenId);
|
||||||
|
stablecoin.transferFrom(seller, buyer, refundAmount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.4 Redemption — 兑付合约
|
||||||
|
|
||||||
|
```solidity
|
||||||
|
contract Redemption is Initializable {
|
||||||
|
ICoupon public couponContract;
|
||||||
|
|
||||||
|
event CouponRedeemed(
|
||||||
|
uint256 indexed tokenId,
|
||||||
|
address indexed consumer,
|
||||||
|
address indexed issuer,
|
||||||
|
bytes32 storeId
|
||||||
|
);
|
||||||
|
|
||||||
|
/// @notice 消费者直接与发行方结算,平台不介入
|
||||||
|
function redeem(
|
||||||
|
uint256 tokenId,
|
||||||
|
bytes32 storeId
|
||||||
|
) external {
|
||||||
|
require(couponContract.ownerOf(tokenId) == msg.sender, "Not owner");
|
||||||
|
|
||||||
|
CouponConfig memory config = couponContract.getConfig(tokenId);
|
||||||
|
|
||||||
|
// 验证到期
|
||||||
|
require(block.timestamp <= config.expiryDate, "Coupon expired");
|
||||||
|
|
||||||
|
// 验证门店限定
|
||||||
|
if (config.allowedStores.length > 0) {
|
||||||
|
require(_isAllowedStore(storeId, config.allowedStores), "Store not allowed");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 销毁券(burn)
|
||||||
|
couponContract.burn(tokenId);
|
||||||
|
|
||||||
|
// 通知发行方(event),平台不介入消费数据
|
||||||
|
emit CouponRedeemed(tokenId, msg.sender, config.issuer, storeId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.5 Compliance — 合规合约
|
||||||
|
|
||||||
|
```solidity
|
||||||
|
contract Compliance is Initializable, AccessControlUpgradeable {
|
||||||
|
mapping(address => bool) private _blacklist; // OFAC黑名单
|
||||||
|
|
||||||
|
/// @notice OFAC筛查
|
||||||
|
function isBlacklisted(address account) external view returns (bool) {
|
||||||
|
return _blacklist[account];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @notice Travel Rule(≥$3,000强制)
|
||||||
|
function recordTravelRule(
|
||||||
|
address sender,
|
||||||
|
address receiver,
|
||||||
|
bytes32 senderInfoHash, // 身份信息哈希(明文链下保存)
|
||||||
|
bytes32 receiverInfoHash
|
||||||
|
) external {
|
||||||
|
emit TravelRuleRecorded(sender, receiver, senderInfoHash, receiverInfoHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @notice 紧急冻结(需Governance多签)
|
||||||
|
function freezeAccount(address account) external onlyRole(GOVERNANCE_ROLE) {
|
||||||
|
_blacklist[account] = true;
|
||||||
|
emit AccountFrozen(account);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.6 Governance — 治理合约
|
||||||
|
|
||||||
|
```solidity
|
||||||
|
contract Governance is Initializable {
|
||||||
|
uint256 public constant REQUIRED_SIGNATURES = 3; // 3/5多签
|
||||||
|
uint256 public constant TIMELOCK = 48 hours; // 时间锁
|
||||||
|
uint256 public constant EMERGENCY_TIMELOCK = 4 hours;
|
||||||
|
|
||||||
|
struct Proposal {
|
||||||
|
bytes callData;
|
||||||
|
address target;
|
||||||
|
uint256 executeAfter;
|
||||||
|
uint256 approvalCount;
|
||||||
|
bool executed;
|
||||||
|
mapping(address => bool) approvals;
|
||||||
|
}
|
||||||
|
|
||||||
|
function propose(address target, bytes calldata data) external onlyMultisig {
|
||||||
|
// 创建提案,设置时间锁
|
||||||
|
}
|
||||||
|
|
||||||
|
function approve(uint256 proposalId) external onlyMultisig {
|
||||||
|
// 审批提案
|
||||||
|
}
|
||||||
|
|
||||||
|
function execute(uint256 proposalId) external {
|
||||||
|
Proposal storage p = proposals[proposalId];
|
||||||
|
require(p.approvalCount >= REQUIRED_SIGNATURES, "Not enough approvals");
|
||||||
|
require(block.timestamp >= p.executeAfter, "Timelock not expired");
|
||||||
|
require(!p.executed, "Already executed");
|
||||||
|
|
||||||
|
p.executed = true;
|
||||||
|
(bool success,) = p.target.call(p.callData);
|
||||||
|
require(success, "Execution failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. 合约升级策略
|
||||||
|
|
||||||
|
**模式:Transparent Proxy(透明代理)**
|
||||||
|
|
||||||
|
```
|
||||||
|
用户/前端 → Proxy合约(地址不变)→ Implementation合约(可替换)
|
||||||
|
```
|
||||||
|
|
||||||
|
**升级流程:**
|
||||||
|
```
|
||||||
|
发起升级提案 → 多签审批(3/5)→ 时间锁48h → 自动执行
|
||||||
|
↓
|
||||||
|
紧急通道:4/5多签 → 4h时间锁
|
||||||
|
```
|
||||||
|
|
||||||
|
**不可升级的逻辑(安全红线):**
|
||||||
|
- 券类型标记(Utility/Security)— 不可修改
|
||||||
|
- 所有权记录 — 不可被升级篡改
|
||||||
|
- 链上转售计数器 — 防止绕过Utility Track限制
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. 链级合规能力
|
||||||
|
|
||||||
|
| 能力 | 实现 |
|
||||||
|
|------|------|
|
||||||
|
| 链级OFAC过滤 | 验证节点拒绝处理制裁地址交易 |
|
||||||
|
| 链级Travel Rule | 大额转移必须携带身份哈希,否则拒绝打包 |
|
||||||
|
| 链级监控 | 节点内置异常交易检测模块 |
|
||||||
|
| 监管API | 监管机构专属只读API |
|
||||||
|
| 紧急冻结 | Governance多签冻结涉案地址 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Gas费策略
|
||||||
|
|
||||||
|
### 前期(全额补贴)
|
||||||
|
|
||||||
|
| 操作 | Gas承担方 |
|
||||||
|
|------|----------|
|
||||||
|
| 券发行(铸造) | 平台补贴 |
|
||||||
|
| 一级/二级市场交易 | 平台补贴 |
|
||||||
|
| P2P转移 | 平台补贴 |
|
||||||
|
| 券兑付(消费) | 平台补贴 |
|
||||||
|
|
||||||
|
> 自建链Gas = 平台运营成本(服务器/节点),非公链ETH支付。
|
||||||
|
|
||||||
|
### 技术实现
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# 创世配置
|
||||||
|
[app_state.evm.params]
|
||||||
|
min_gas_price = "0"
|
||||||
|
|
||||||
|
# 或使用ERC-4337 Paymaster
|
||||||
|
```
|
||||||
|
|
||||||
|
Gas参数通过Governance合约动态调整(无需硬分叉)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. 测试策略
|
||||||
|
|
||||||
|
### 8.1 合约测试(Foundry)
|
||||||
|
|
||||||
|
```solidity
|
||||||
|
// test/Settlement.t.sol
|
||||||
|
contract SettlementTest is Test {
|
||||||
|
Settlement settlement;
|
||||||
|
MockCoupon coupon;
|
||||||
|
MockERC20 usdc;
|
||||||
|
|
||||||
|
function setUp() public {
|
||||||
|
usdc = new MockERC20("USDC", "USDC", 6);
|
||||||
|
coupon = new MockCoupon();
|
||||||
|
settlement = new Settlement();
|
||||||
|
settlement.initialize(address(coupon), address(usdc));
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_UtilityCannotExceedFaceValue() public {
|
||||||
|
// 面值100的Utility券,尝试以110价格交易,应被拒绝
|
||||||
|
vm.expectRevert("Utility: price exceeds face value");
|
||||||
|
settlement.executeSwap(tokenId, buyer, seller, 110e6);
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_AtomicSwapSuccess() public {
|
||||||
|
// 正常交易:券和稳定币同时转移
|
||||||
|
settlement.executeSwap(tokenId, buyer, seller, 85e6);
|
||||||
|
assertEq(coupon.ownerOf(tokenId), buyer);
|
||||||
|
assertEq(usdc.balanceOf(seller), 85e6);
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_RefundReverseSwap() public {
|
||||||
|
// 退款:反向原子交换
|
||||||
|
settlement.executeRefund(tokenId, buyer, seller, 85e6);
|
||||||
|
assertEq(coupon.ownerOf(tokenId), seller);
|
||||||
|
assertEq(usdc.balanceOf(buyer), 85e6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 8.2 测试覆盖要求
|
||||||
|
|
||||||
|
| 测试类型 | 覆盖 |
|
||||||
|
|---------|------|
|
||||||
|
| 单元测试 | 每个合约函数 |
|
||||||
|
| Fuzz测试 | 价格边界、数量溢出 |
|
||||||
|
| 集成测试 | 完整发行→交易→核销流程 |
|
||||||
|
| Gas优化 | 批量操作Gas消耗 |
|
||||||
|
| 安全审计 | 第三方审计(上线前必须) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. 部署流程
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 部署到本地测试链
|
||||||
|
forge script script/Deploy.s.sol --rpc-url http://localhost:8545 --broadcast
|
||||||
|
|
||||||
|
# 部署到Genex Chain测试网
|
||||||
|
forge script script/Deploy.s.sol \
|
||||||
|
--rpc-url https://testnet-rpc.gogenex.com \
|
||||||
|
--broadcast \
|
||||||
|
--verify
|
||||||
|
|
||||||
|
# 部署到Genex Chain主网(需多签审批)
|
||||||
|
forge script script/Deploy.s.sol \
|
||||||
|
--rpc-url https://rpc.gogenex.com \
|
||||||
|
--broadcast \
|
||||||
|
--verify \
|
||||||
|
--etherscan-api-key $GENEX_EXPLORER_KEY
|
||||||
|
```
|
||||||
|
|
||||||
|
### 合约验证
|
||||||
|
|
||||||
|
```bash
|
||||||
|
forge verify-contract \
|
||||||
|
--chain-id 8888 \
|
||||||
|
--compiler-version v0.8.20 \
|
||||||
|
$CONTRACT_ADDRESS \
|
||||||
|
src/CouponFactory.sol:CouponFactory
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. GCFN全球清算节点架构
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────┐
|
||||||
|
│ Global Coupon Financial Network (GCFN) │
|
||||||
|
├─────────────────────────────────────────────┤
|
||||||
|
│ ROOT NODE │
|
||||||
|
│ (US / Global Hub) │
|
||||||
|
│ 全球路由 | 跨境清算 | 合规协调 │
|
||||||
|
├──────────────┬──────────────┬───────────────┤
|
||||||
|
│ ASIA-PACIFIC │ EMEA │ AMERICAS │
|
||||||
|
├──────────────┼──────────────┼───────────────┤
|
||||||
|
│ 新加坡(MAS) │ 伦敦(FCA) │ 美国(FinCEN) │
|
||||||
|
│ 香港(SFC) │ 法兰克福 │ │
|
||||||
|
│ 日本(FSA) │ (BaFin) │ │
|
||||||
|
└──────────────┴──────────────┴───────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
| 节点类型 | 职责 |
|
||||||
|
|---------|------|
|
||||||
|
| 根节点 | 全球路由、跨境清算、主验证节点 |
|
||||||
|
| 区域节点 | 区域清算、监管报送、本地化 |
|
||||||
|
| 本地节点 | 用户服务、本地支付、法规遵从 |
|
||||||
|
| 监管节点 | 只读审计、实时监控 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11. 安全规范
|
||||||
|
|
||||||
|
- 所有合约上线前必须通过第三方安全审计
|
||||||
|
- 核心合约采用Transparent Proxy部署
|
||||||
|
- 升级需3/5多签 + 48小时时间锁
|
||||||
|
- Bug Bounty计划:严重漏洞奖励$10K-$100K
|
||||||
|
- MPC/HSM密钥管理
|
||||||
|
- 合约代码开源并在区块浏览器验证
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*文档版本: v1.0*
|
||||||
|
*基于: Genex 券交易平台 - 软件需求规格说明书 v4.1 + 技术架构开发需求 v3.0*
|
||||||
|
*技术栈: Cosmos SDK + cosmos/evm + CometBFT + Solidity + Foundry*
|
||||||
Loading…
Reference in New Issue