543 lines
16 KiB
Markdown
543 lines
16 KiB
Markdown
# 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,不同签名)
|
||
|
||
---
|
||
|
||
## 9. 财务管理增强
|
||
|
||
### 9.1 保证金与冻结销售款
|
||
|
||
```dart
|
||
// 发行方可选:缴纳保证金以快速提升额度
|
||
@freezed
|
||
class GuaranteeFund with _$GuaranteeFund {
|
||
const factory GuaranteeFund({
|
||
required double deposited, // 已缴纳保证金
|
||
required double frozenSales, // 冻结的销售款(自愿开启)
|
||
required bool autoFreezeEnabled, // 是否开启销售款自动冻结
|
||
required double freezePercent, // 冻结比例(如20%销售额)
|
||
}) = _GuaranteeFund;
|
||
}
|
||
|
||
// 财务管理增强视图
|
||
@freezed
|
||
class FinanceDetailView with _$FinanceDetailView {
|
||
const factory FinanceDetailView({
|
||
required double salesRevenue, // 销售收入
|
||
required double breakageIncome, // Breakage收入(过期券)
|
||
required double platformFees, // 平台手续费支出
|
||
required double pendingSettlement, // 待结算
|
||
required double withdrawable, // 可提现
|
||
required double totalWithdrawn, // 已提现
|
||
required double guaranteeDeposit, // 保证金
|
||
required double frozenSales, // 冻结销售款
|
||
}) = _FinanceDetailView;
|
||
}
|
||
```
|
||
|
||
### 9.2 对账报表
|
||
|
||
```dart
|
||
// 日/月对账单
|
||
class ReconciliationReport {
|
||
final DateTime periodStart;
|
||
final DateTime periodEnd;
|
||
final List<TransactionEntry> entries;
|
||
final double totalIncome;
|
||
final double totalExpense;
|
||
final double netBalance;
|
||
|
||
// 导出为CSV/PDF
|
||
Future<File> exportAsCsv() async { /* ... */ }
|
||
Future<File> exportAsPdf() async { /* ... */ }
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 10. 发行方数据分析增强
|
||
|
||
### 10.1 二级市场分析
|
||
|
||
```dart
|
||
@freezed
|
||
class SecondaryMarketAnalysis with _$SecondaryMarketAnalysis {
|
||
const factory SecondaryMarketAnalysis({
|
||
required int listedCount, // 二级市场挂单数
|
||
required double avgResalePrice, // 平均转售价
|
||
required double avgDiscount, // 平均折扣率
|
||
required int resaleVolume, // 转售成交量
|
||
required double resaleRevenue, // 转售成交额
|
||
required List<PricePoint> priceHistory, // 价格历史(K线数据)
|
||
}) = _SecondaryMarketAnalysis;
|
||
}
|
||
```
|
||
|
||
### 10.2 融资效果分析
|
||
|
||
```dart
|
||
@freezed
|
||
class FinancingEffectReport with _$FinancingEffectReport {
|
||
const factory FinancingEffectReport({
|
||
required double cashAdvanced, // 现金提前回笼总额
|
||
required double avgAdvanceDays, // 平均提前回笼天数
|
||
required double financingCost, // 融资成本(平台手续费+折扣损失)
|
||
required double effectiveRate, // 等效年利率
|
||
required List<CashFlowPoint> cashFlowTimeline, // 现金流时序图
|
||
}) = _FinancingEffectReport;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 11. 退款窗口配置
|
||
|
||
```dart
|
||
// 发行方可配置退款期限
|
||
@freezed
|
||
class RefundPolicy with _$RefundPolicy {
|
||
const factory RefundPolicy({
|
||
required int refundWindowDays, // 退款窗口(天,默认7天)
|
||
required bool autoRefundEnabled, // 是否自动退款
|
||
required String refundConditions, // 退款条件说明
|
||
}) = _RefundPolicy;
|
||
}
|
||
|
||
// 创建券时配置退款策略
|
||
class CreateCouponWithRefundPolicy {
|
||
Widget buildRefundSection() {
|
||
return Column(children: [
|
||
Text('退款策略'),
|
||
NumberPicker(
|
||
label: '退款窗口(天)',
|
||
min: 0, max: 30, initial: 7,
|
||
onChanged: (days) => _refundDays = days,
|
||
),
|
||
SwitchListTile(
|
||
title: Text('允许自动退款'),
|
||
subtitle: Text('窗口期内用户可直接退款无需审核'),
|
||
value: _autoRefund,
|
||
onChanged: (v) => setState(() => _autoRefund = v),
|
||
),
|
||
]);
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 12. 批量操作
|
||
|
||
```dart
|
||
// 批量发行、批量核销、批量导出
|
||
class BatchOperationsService {
|
||
// 批量发行(一次创建多种券模板)
|
||
Future<Either<Failure, List<CouponDraft>>> batchCreate(
|
||
List<CreateCouponParams> paramsList
|
||
) async {
|
||
return _repo.batchSubmitDrafts(paramsList);
|
||
}
|
||
|
||
// 批量核销
|
||
Future<Either<Failure, BatchRedeemResult>> batchRedeem(
|
||
List<String> couponCodes
|
||
) async {
|
||
return _repo.batchRedeem(couponCodes);
|
||
}
|
||
|
||
// 批量数据导出
|
||
Future<File> exportData({
|
||
required ExportType type, // coupons / transactions / reconciliation
|
||
required DateRange range,
|
||
required ExportFormat format, // csv / xlsx / pdf
|
||
}) async {
|
||
return _repo.exportBatchData(type, range, format);
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 13. 券召回与下架
|
||
|
||
```dart
|
||
// 券召回流程
|
||
class CouponRecallService {
|
||
/// 召回未售出的券(链上销毁)
|
||
Future<Either<Failure, RecallResult>> recallUnsold(String couponBatchId) async {
|
||
return _repo.recallUnsoldCoupons(couponBatchId);
|
||
}
|
||
|
||
/// 问题券紧急下架
|
||
Future<Either<Failure, void>> emergencyDelist(String couponId, String reason) async {
|
||
return _repo.delistCoupon(couponId, reason);
|
||
}
|
||
|
||
/// 已售出券的退款处理
|
||
Future<Either<Failure, void>> initiateRefundForSold(
|
||
String couponBatchId, String refundReason
|
||
) async {
|
||
return _repo.initiateRefundForSoldCoupons(couponBatchId, refundReason);
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 14. 多门店管理增强
|
||
|
||
```dart
|
||
// 门店层级管理
|
||
@freezed
|
||
class StoreHierarchy with _$StoreHierarchy {
|
||
const factory StoreHierarchy({
|
||
required String id,
|
||
required String name,
|
||
required StoreLevel level, // headquarters / regional / store
|
||
String? parentId, // 上级ID
|
||
required List<StoreHierarchy> children,
|
||
required StorePermissions permissions,
|
||
}) = _StoreHierarchy;
|
||
}
|
||
|
||
enum StoreLevel { headquarters, regional, store }
|
||
|
||
// 门店员工管理
|
||
@freezed
|
||
class StoreEmployee with _$StoreEmployee {
|
||
const factory StoreEmployee({
|
||
required String id,
|
||
required String name,
|
||
required String phone,
|
||
required StoreRole role, // cashier / manager / admin
|
||
required List<String> storeIds, // 可操作的门店
|
||
}) = _StoreEmployee;
|
||
}
|
||
|
||
enum StoreRole {
|
||
cashier, // 收银员:仅核销权限
|
||
manager, // 店长:核销 + 数据查看
|
||
admin, // 管理员:全部权限
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 15. 专属客服通道
|
||
|
||
```dart
|
||
// 铂金/钻石层级发行方专属客服
|
||
class DedicatedSupportWidget extends ConsumerWidget {
|
||
@override
|
||
Widget build(BuildContext context, WidgetRef ref) {
|
||
final issuer = ref.watch(issuerProfileProvider);
|
||
|
||
if (['platinum', 'diamond'].contains(issuer.tier.name)) {
|
||
return Card(
|
||
child: ListTile(
|
||
leading: Icon(Icons.headset_mic, color: Colors.amber),
|
||
title: Text('专属客服'),
|
||
subtitle: Text('1小时内响应 | 您的客户经理:${issuer.accountManager}'),
|
||
onTap: () => _openDedicatedChat(context),
|
||
),
|
||
);
|
||
}
|
||
|
||
return Card(
|
||
child: ListTile(
|
||
leading: Icon(Icons.support_agent),
|
||
title: Text('在线客服'),
|
||
subtitle: Text('24小时内响应'),
|
||
onTap: () => _openSupportTicket(context),
|
||
),
|
||
);
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
*文档版本: v2.0*
|
||
*基于: Genex 券交易平台 - 软件需求规格说明书 v4.1*
|
||
*技术栈: Flutter 3.x + Riverpod + Clean Architecture*
|
||
*更新: 补充保证金/冻结销售款/对账报表/二级市场分析/融资效果/退款窗口/批量操作/券召回/多门店增强/专属客服*
|