docs(genex-mobile): 完善邀请分享模块注释与说明
SharePage: - 文件头注释:完整功能概述、支持的分享场景、数据来源、URL格式、依赖包说明 - 类注释:生命周期描述、Widget 树结构图(ASCII) - 状态变量:详细说明 _info/_loading/_error/_baseInviteUrl - _inviteLink:注释已加载/未加载两种输出示例 - _loadInfo:成功/失败两条路径说明 - _showCopied:SnackBar 样式描述 - _copyCode/_copyLink:示例复制内容 - _shareNative:iOS/Android 行为说明 + 文案模板示例 - _buildHeroCard:视觉层次注释 + QR 参数说明 - _buildStatsCard:布局描述 + 数据来源注释 - _buildShareActions:三项操作的点击行为说明 ReferralService: - 文件头:完整端点一览、推荐码格式、推荐链规则 - ReferralInfo:字段含义 + 后端响应 JSON 示例 - getMyInfo:登录要求说明 - validateCode:用途说明 + 返回值降级策略 - getDirectReferrals:分页参数范围 + 响应 JSON 示例 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
46d2404d19
commit
1c36c849e2
|
|
@ -1,14 +1,54 @@
|
|||
import '../network/api_client.dart';
|
||||
|
||||
/// 推荐关系信息
|
||||
// ============================================================
|
||||
// ReferralService — 推荐/邀请系统客户端
|
||||
//
|
||||
// 对接后端 referral-service(端口 3013,经 Kong 网关 :8080 转发)
|
||||
//
|
||||
// 端点一览:
|
||||
// GET /api/v1/referral/my 获取当前用户的推荐信息(需 JWT)
|
||||
// GET /api/v1/referral/validate 验证推荐码是否有效(公开)
|
||||
// GET /api/v1/referral/direct 获取直接推荐列表(需 JWT)
|
||||
//
|
||||
// 推荐码格式:GNX + 5 位无歧义字符(排除 0/O/I/1),示例:GNXAB2C3
|
||||
// 推荐链:每个用户拥有唯一推荐码,可追溯至多 50 层祖先节点
|
||||
// ============================================================
|
||||
|
||||
/// 当前用户的推荐关系数据
|
||||
///
|
||||
/// 对应后端 [GET /api/v1/referral/my] 返回的 `data` 字段。
|
||||
///
|
||||
/// 后端响应示例:
|
||||
/// ```json
|
||||
/// {
|
||||
/// "code": 0,
|
||||
/// "data": {
|
||||
/// "userId": "uuid-...",
|
||||
/// "referralCode": "GNXAB2C3",
|
||||
/// "referrerId": "uuid-... | null",
|
||||
/// "usedCode": "GNXPARENT | null",
|
||||
/// "directReferralCount": 5,
|
||||
/// "totalTeamCount": 23
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
class ReferralInfo {
|
||||
/// 本用户的专属推荐码(格式:GNXxxxxx,固定 8 位大写)
|
||||
final String referralCode;
|
||||
|
||||
/// 直接推荐人数(通过本人推荐码注册的用户数量)
|
||||
final int directReferralCount;
|
||||
|
||||
/// 团队总人数(整条推荐链下的所有层级用户总数)
|
||||
final int totalTeamCount;
|
||||
|
||||
/// 推荐人 userId(若无人推荐则为 null)
|
||||
final String? referrerId;
|
||||
|
||||
/// 注册时填写的推荐码(即 referrerId 对应的 referralCode,冗余存储方便展示)
|
||||
final String? usedCode;
|
||||
|
||||
ReferralInfo({
|
||||
const ReferralInfo({
|
||||
required this.referralCode,
|
||||
required this.directReferralCount,
|
||||
required this.totalTeamCount,
|
||||
|
|
@ -25,9 +65,22 @@ class ReferralInfo {
|
|||
usedCode: json['usedCode'] as String?,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() =>
|
||||
'ReferralInfo(code=$referralCode, direct=$directReferralCount, team=$totalTeamCount)';
|
||||
}
|
||||
|
||||
/// Referral Service — 对接 referral-service API
|
||||
/// 推荐服务 — 单例
|
||||
///
|
||||
/// 用法:
|
||||
/// ```dart
|
||||
/// final info = await ReferralService.instance.getMyInfo();
|
||||
/// print(info.referralCode); // e.g. GNXAB2C3
|
||||
/// ```
|
||||
///
|
||||
/// 注意:所有方法均需要 ApiClient 携带有效 JWT;
|
||||
/// 若未登录或 token 过期,将抛出 DioException(401)。
|
||||
class ReferralService {
|
||||
static final ReferralService _instance = ReferralService._();
|
||||
static ReferralService get instance => _instance;
|
||||
|
|
@ -35,14 +88,56 @@ class ReferralService {
|
|||
|
||||
final _api = ApiClient.instance;
|
||||
|
||||
/// 获取当前用户的推荐信息(需登录)
|
||||
// ── 查询 ─────────────────────────────────────────────────────────────────
|
||||
|
||||
/// 获取当前用户的推荐信息
|
||||
///
|
||||
/// 包含:专属推荐码、直接推荐人数、团队总人数、是否被推荐等。
|
||||
///
|
||||
/// - 需要登录(请求头携带 Bearer Token)
|
||||
/// - 首次登录即自动在后端创建推荐档案(由 Kafka 事件触发)
|
||||
///
|
||||
/// Throws [DioException] on network error or 401/403.
|
||||
Future<ReferralInfo> getMyInfo() async {
|
||||
final resp = await _api.get('/api/v1/referral/my');
|
||||
final data = resp.data['data'] as Map<String, dynamic>;
|
||||
return ReferralInfo.fromJson(data);
|
||||
}
|
||||
|
||||
/// 获取直接推荐列表
|
||||
/// 验证推荐码是否有效(公开接口,无需登录)
|
||||
///
|
||||
/// 用于注册页实时校验邀请码。
|
||||
///
|
||||
/// 后端响应:`{ "code": 0, "data": { "valid": true/false } }`
|
||||
///
|
||||
/// Returns `false` on any error (avoid blocking registration flow).
|
||||
Future<bool> validateCode(String code) async {
|
||||
try {
|
||||
final resp = await _api.get(
|
||||
'/api/v1/referral/validate',
|
||||
queryParameters: {'code': code.toUpperCase()},
|
||||
);
|
||||
final data = resp.data['data'] as Map<String, dynamic>;
|
||||
return data['valid'] == true;
|
||||
} catch (_) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取直接推荐列表(分页)
|
||||
///
|
||||
/// 每条记录包含被推荐用户的 userId、注册时间、推荐码等基本信息。
|
||||
///
|
||||
/// - [offset] 分页偏移,从 0 开始
|
||||
/// - [limit] 每页条数,最大 50
|
||||
///
|
||||
/// 后端响应 `data` 字段示例:
|
||||
/// ```json
|
||||
/// {
|
||||
/// "items": [ { "userId": "...", "referralCode": "...", "createdAt": "..." } ],
|
||||
/// "total": 5
|
||||
/// }
|
||||
/// ```
|
||||
Future<List<Map<String, dynamic>>> getDirectReferrals({
|
||||
int offset = 0,
|
||||
int limit = 20,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,35 @@
|
|||
// ============================================================
|
||||
// SharePage — 邀请好友 / 推广分享页
|
||||
//
|
||||
// 路由:/share(从 ProfilePage「邀请好友」横幅入口跳转)
|
||||
//
|
||||
// 功能概述:
|
||||
// 1. Hero Card — 紫色渐变卡片,包含:
|
||||
// · 专属二维码(qr_flutter 生成,编码邀请落地页 URL)
|
||||
// · 推荐码胶囊(可点击一键复制)
|
||||
// 2. 邀请进度 — 显示直接推荐人数 + 团队总人数
|
||||
// 3. 分享操作列表 — 三种快捷方式:复制推荐码 / 复制链接 / 原生分享
|
||||
// 4. 主操作按钮 — 「分享给好友」触发系统原生分享弹层
|
||||
//
|
||||
// 支持的分享场景(取决于用户设备安装的 App):
|
||||
// 微信 / QQ / WhatsApp / Telegram / Line / Twitter/X
|
||||
// 短信 / 邮件 / AirDrop / 复制到剪贴板 / 保存至文件……
|
||||
//
|
||||
// 数据来源:
|
||||
// GET /api/v1/referral/my → ReferralService.getMyInfo()
|
||||
// 推荐码通过 Kafka 事件在用户注册时自动生成,首次打开此页若
|
||||
// 数据尚未就绪,将显示 Loading → 加载失败 → 重试 流程。
|
||||
//
|
||||
// 邀请链接格式:
|
||||
// https://app.gogenex.com/download?ref={referralCode}
|
||||
// 落地页检测设备后分别跳转 App Store / Google Play / 浏览器下载。
|
||||
// ref 参数由注册流程自动读取并预填推荐码输入框。
|
||||
//
|
||||
// 依赖包:
|
||||
// qr_flutter ^4.1.0 — 本地生成二维码,无网络依赖
|
||||
// share_plus ^10.0.2 — 调用系统原生分享弹层(iOS Share Sheet / Android Sharesheet)
|
||||
// ============================================================
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:qr_flutter/qr_flutter.dart';
|
||||
|
|
@ -11,11 +43,18 @@ import '../../../../app/i18n/app_localizations.dart';
|
|||
|
||||
/// A9. 邀请好友 / 推广分享页
|
||||
///
|
||||
/// 功能:
|
||||
/// - 专属推荐码二维码(扫码跳转到 App 下载页并自动填入推荐码)
|
||||
/// - 一键复制推荐码 / 复制链接
|
||||
/// - 系统原生分享(微信、WhatsApp、Telegram、短信、邮件……)
|
||||
/// - 邀请进度(直接推荐人数 + 团队总人数)
|
||||
/// 页面生命周期:
|
||||
/// initState → _loadInfo() → [Loading] → [Content | Error]
|
||||
///
|
||||
/// Widget 树概览:
|
||||
/// ```
|
||||
/// Scaffold
|
||||
/// └── SingleChildScrollView
|
||||
/// ├── _buildHeroCard() 渐变卡片:QR 码 + 推荐码
|
||||
/// ├── _buildStatsCard() 邀请进度:直接推荐 | 团队人数
|
||||
/// ├── _buildShareActions() 操作列表:复制码 / 复制链 / 系统分享
|
||||
/// └── GenexButton 主按钮:「分享给好友」
|
||||
/// ```
|
||||
class SharePage extends StatefulWidget {
|
||||
const SharePage({super.key});
|
||||
|
||||
|
|
@ -24,23 +63,52 @@ class SharePage extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _SharePageState extends State<SharePage> {
|
||||
// ── 状态 ────────────────────────────────────────────────────────────────
|
||||
|
||||
/// 从 referral-service 加载的推荐信息;加载完成前为 null
|
||||
ReferralInfo? _info;
|
||||
|
||||
/// 正在请求后端数据
|
||||
bool _loading = true;
|
||||
|
||||
/// 请求失败时的错误信息(用于展示重试按钮)
|
||||
String? _error;
|
||||
|
||||
/// App 下载落地页(带推荐码参数)
|
||||
// ── 常量 ────────────────────────────────────────────────────────────────
|
||||
|
||||
/// App 下载落地页基础地址
|
||||
///
|
||||
/// 落地页职责:
|
||||
/// 1. 检测 UA(iOS / Android / 其他)
|
||||
/// 2. iOS → 跳转 App Store
|
||||
/// 3. Android → 跳转 Google Play 或直接下载 APK
|
||||
/// 4. 读取 `ref` 参数并存入 localStorage,注册页自动填充推荐码
|
||||
static const String _baseInviteUrl = 'https://app.gogenex.com/download';
|
||||
|
||||
// ── 计算属性 ─────────────────────────────────────────────────────────────
|
||||
|
||||
/// 完整邀请链接(二维码内容 + 分享文案使用)
|
||||
///
|
||||
/// 已加载:https://app.gogenex.com/download?ref=GNXAB2C3
|
||||
/// 未加载:https://app.gogenex.com/download
|
||||
String get _inviteLink => _info != null
|
||||
? '$_baseInviteUrl?ref=${_info!.referralCode}'
|
||||
: _baseInviteUrl;
|
||||
|
||||
// ── 生命周期 ─────────────────────────────────────────────────────────────
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_loadInfo();
|
||||
}
|
||||
|
||||
// ── 数据加载 ─────────────────────────────────────────────────────────────
|
||||
|
||||
/// 从 referral-service 拉取当前用户的推荐信息
|
||||
///
|
||||
/// 成功:更新 [_info],隐藏 loading
|
||||
/// 失败:记录 [_error],显示重试界面
|
||||
Future<void> _loadInfo() async {
|
||||
setState(() {
|
||||
_loading = true;
|
||||
|
|
@ -54,6 +122,9 @@ class _SharePageState extends State<SharePage> {
|
|||
}
|
||||
}
|
||||
|
||||
// ── 用户操作 ─────────────────────────────────────────────────────────────
|
||||
|
||||
/// 复制成功后展示浮动 SnackBar(紫色背景 + 勾号图标)
|
||||
void _showCopied(String message) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
|
|
@ -74,17 +145,33 @@ class _SharePageState extends State<SharePage> {
|
|||
);
|
||||
}
|
||||
|
||||
/// 复制推荐码到剪贴板
|
||||
///
|
||||
/// 示例复制内容:GNXAB2C3
|
||||
Future<void> _copyCode() async {
|
||||
if (_info == null) return;
|
||||
await Clipboard.setData(ClipboardData(text: _info!.referralCode));
|
||||
if (mounted) _showCopied(context.t('share.codeCopied'));
|
||||
}
|
||||
|
||||
/// 复制完整邀请链接到剪贴板
|
||||
///
|
||||
/// 示例:https://app.gogenex.com/download?ref=GNXAB2C3
|
||||
Future<void> _copyLink() async {
|
||||
await Clipboard.setData(ClipboardData(text: _inviteLink));
|
||||
if (mounted) _showCopied(context.t('share.linkCopied'));
|
||||
}
|
||||
|
||||
/// 调用系统原生分享弹层
|
||||
///
|
||||
/// 分享内容:多行文案(包含推荐码 + 邀请链接)
|
||||
///
|
||||
/// iOS → Share Sheet(AirDrop、微信、邮件、短信……)
|
||||
/// Android → Sharesheet(微信、WhatsApp、Telegram……)
|
||||
///
|
||||
/// 分享文案模板(zh-CN):
|
||||
/// 我在用 Genex 玩数字券金融!使用我的推荐码 {code} 注册,立享专属福利。
|
||||
/// 下载链接:https://app.gogenex.com/download?ref={code}
|
||||
Future<void> _shareNative() async {
|
||||
final code = _info?.referralCode ?? '';
|
||||
final text = context
|
||||
|
|
@ -94,6 +181,8 @@ class _SharePageState extends State<SharePage> {
|
|||
await Share.share(text, subject: context.t('share.nativeShareTitle'));
|
||||
}
|
||||
|
||||
// ── Build ────────────────────────────────────────────────────────────────
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
|
|
@ -116,6 +205,8 @@ class _SharePageState extends State<SharePage> {
|
|||
);
|
||||
}
|
||||
|
||||
// ── 加载态 ───────────────────────────────────────────────────────────────
|
||||
|
||||
Widget _buildLoading() {
|
||||
return Center(
|
||||
child: Column(
|
||||
|
|
@ -132,6 +223,9 @@ class _SharePageState extends State<SharePage> {
|
|||
);
|
||||
}
|
||||
|
||||
// ── 错误态 ───────────────────────────────────────────────────────────────
|
||||
|
||||
/// 加载失败界面:图标 + 描述文本 + 重试按钮
|
||||
Widget _buildError() {
|
||||
return Center(
|
||||
child: Padding(
|
||||
|
|
@ -159,19 +253,21 @@ class _SharePageState extends State<SharePage> {
|
|||
);
|
||||
}
|
||||
|
||||
// ── 主内容 ───────────────────────────────────────────────────────────────
|
||||
|
||||
Widget _buildContent() {
|
||||
return SingleChildScrollView(
|
||||
padding: AppSpacing.pagePadding,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
_buildHeroCard(),
|
||||
_buildHeroCard(), // QR 码 + 推荐码
|
||||
const SizedBox(height: 16),
|
||||
_buildStatsCard(),
|
||||
_buildStatsCard(), // 邀请进度统计
|
||||
const SizedBox(height: 16),
|
||||
_buildShareActions(),
|
||||
_buildShareActions(), // 快捷操作列表
|
||||
const SizedBox(height: 24),
|
||||
GenexButton(
|
||||
GenexButton( // 主操作按钮
|
||||
label: context.t('share.shareToFriend'),
|
||||
onPressed: _shareNative,
|
||||
),
|
||||
|
|
@ -181,7 +277,18 @@ class _SharePageState extends State<SharePage> {
|
|||
);
|
||||
}
|
||||
|
||||
// ── Hero Card: QR 码 + 推荐码 ─────────────────────────────────────────────
|
||||
// ── Hero Card:二维码 + 推荐码 ────────────────────────────────────────────
|
||||
//
|
||||
// 视觉层次(由外到内):
|
||||
// Container[渐变背景 + 圆角20 + 阴影]
|
||||
// └── Column
|
||||
// ├── 标题行(星形图标 + "扫码下载 Genex")
|
||||
// ├── "Genex" 大字(字间距 3,FontWeight.w800)
|
||||
// ├── Container[白色背景] → QrImageView(180×180,紫色点阵)
|
||||
// └── 推荐码胶囊(半透明白底 + 复制按钮)
|
||||
//
|
||||
// QR 码内容:_inviteLink(如 https://app.gogenex.com/download?ref=GNXAB2C3)
|
||||
// QR 码颜色:eye=深紫 #4834D4,module=主紫 #6C5CE7,背景=白色
|
||||
|
||||
Widget _buildHeroCard() {
|
||||
return Container(
|
||||
|
|
@ -200,7 +307,7 @@ class _SharePageState extends State<SharePage> {
|
|||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 28),
|
||||
child: Column(
|
||||
children: [
|
||||
// 顶部标题
|
||||
// ── 顶部标题 ────────────────────────────────────────────────────
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
|
|
@ -223,7 +330,8 @@ class _SharePageState extends State<SharePage> {
|
|||
),
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// QR 码卡片
|
||||
// ── 二维码 ──────────────────────────────────────────────────────
|
||||
// 白色衬底卡片包裹 QrImageView,确保二维码在任何背景下均可扫描
|
||||
Container(
|
||||
padding: const EdgeInsets.all(14),
|
||||
decoration: BoxDecoration(
|
||||
|
|
@ -238,14 +346,16 @@ class _SharePageState extends State<SharePage> {
|
|||
],
|
||||
),
|
||||
child: QrImageView(
|
||||
data: _inviteLink,
|
||||
version: QrVersions.auto,
|
||||
data: _inviteLink, // 编码完整邀请 URL
|
||||
version: QrVersions.auto, // 自动选择最小版本
|
||||
size: 180,
|
||||
backgroundColor: Colors.white,
|
||||
// 定位图案(三个角的方框)用深紫色
|
||||
eyeStyle: const QrEyeStyle(
|
||||
eyeShape: QrEyeShape.square,
|
||||
color: Color(0xFF4834D4),
|
||||
),
|
||||
// 数据模块用主紫色
|
||||
dataModuleStyle: const QrDataModuleStyle(
|
||||
dataModuleShape: QrDataModuleShape.square,
|
||||
color: Color(0xFF6C5CE7),
|
||||
|
|
@ -254,7 +364,8 @@ class _SharePageState extends State<SharePage> {
|
|||
),
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// 推荐码
|
||||
// ── 推荐码胶囊 ─────────────────────────────────────────────────
|
||||
// 点击整个胶囊即可复制,内嵌「复制推荐码」小按钮提示可交互
|
||||
Text(
|
||||
context.t('share.myReferralCode'),
|
||||
style: AppTypography.caption.copyWith(color: Colors.white60),
|
||||
|
|
@ -265,13 +376,14 @@ class _SharePageState extends State<SharePage> {
|
|||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white.withOpacity(0.15),
|
||||
color: Colors.white.withOpacity(0.15), // 半透明白底
|
||||
borderRadius: BorderRadius.circular(40),
|
||||
border: Border.all(color: Colors.white30),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
// 推荐码文字:等宽字体 + 字间距 4,视觉更清晰
|
||||
Text(
|
||||
_info?.referralCode ?? '------',
|
||||
style: AppTypography.h2.copyWith(
|
||||
|
|
@ -282,6 +394,7 @@ class _SharePageState extends State<SharePage> {
|
|||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
// 内嵌复制提示按钮
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
|
|
@ -313,7 +426,14 @@ class _SharePageState extends State<SharePage> {
|
|||
);
|
||||
}
|
||||
|
||||
// ── 邀请进度 ──────────────────────────────────────────────────────────────
|
||||
// ── 邀请进度统计卡片 ─────────────────────────────────────────────────────
|
||||
//
|
||||
// 布局:白色圆角卡片,水平等分两格,中间细竖线分隔
|
||||
// 左:直接推荐人数(Icons.people)
|
||||
// 右:团队总人数(Icons.groups)
|
||||
//
|
||||
// 数据来源:ReferralInfo.directReferralCount / totalTeamCount
|
||||
// 加载前显示 0,刷新后实时更新
|
||||
|
||||
Widget _buildStatsCard() {
|
||||
return Container(
|
||||
|
|
@ -333,6 +453,7 @@ class _SharePageState extends State<SharePage> {
|
|||
label: context.t('share.directReferrals'),
|
||||
),
|
||||
),
|
||||
// 分隔线
|
||||
Container(width: 1, height: 44, color: AppColors.borderLight),
|
||||
Expanded(
|
||||
child: _buildStatItem(
|
||||
|
|
@ -346,6 +467,7 @@ class _SharePageState extends State<SharePage> {
|
|||
);
|
||||
}
|
||||
|
||||
/// 单个统计格:图标 + 数值 + 标签
|
||||
Widget _buildStatItem({
|
||||
required IconData icon,
|
||||
required String value,
|
||||
|
|
@ -358,22 +480,27 @@ class _SharePageState extends State<SharePage> {
|
|||
children: [
|
||||
Icon(icon, size: 16, color: AppColors.primary),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
value,
|
||||
style: AppTypography.h2.copyWith(color: AppColors.primary),
|
||||
),
|
||||
Text(value, style: AppTypography.h2.copyWith(color: AppColors.primary)),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
label,
|
||||
style: AppTypography.caption.copyWith(color: AppColors.textSecondary),
|
||||
),
|
||||
Text(label, style: AppTypography.caption.copyWith(color: AppColors.textSecondary)),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
// ── 分享操作列表 ───────────────────────────────────────────────────────────
|
||||
// ── 分享操作列表 ─────────────────────────────────────────────────────────
|
||||
//
|
||||
// 白色圆角卡片,ListTile 列表(Divider 分隔):
|
||||
//
|
||||
// [紫色图标] 复制推荐码 副文本:GNXAB2C3 >
|
||||
// [蓝色图标] 复制链接 副文本:https://... >
|
||||
// [绿色图标] 分享给好友 副文本:通过微信/WhatsApp >
|
||||
//
|
||||
// 每项点击行为:
|
||||
// 复制推荐码 → _copyCode() → 剪贴板 + SnackBar
|
||||
// 复制链接 → _copyLink() → 剪贴板 + SnackBar
|
||||
// 分享给好友 → _shareNative() → 系统原生分享弹层
|
||||
|
||||
Widget _buildShareActions() {
|
||||
return Column(
|
||||
|
|
@ -395,6 +522,7 @@ class _SharePageState extends State<SharePage> {
|
|||
),
|
||||
child: Column(
|
||||
children: [
|
||||
// 复制推荐码
|
||||
_buildActionTile(
|
||||
icon: Icons.qr_code_rounded,
|
||||
iconBg: AppColors.primaryContainer,
|
||||
|
|
@ -404,6 +532,7 @@ class _SharePageState extends State<SharePage> {
|
|||
onTap: _copyCode,
|
||||
),
|
||||
const Divider(indent: 60, height: 1),
|
||||
// 复制链接
|
||||
_buildActionTile(
|
||||
icon: Icons.link_rounded,
|
||||
iconBg: AppColors.infoLight,
|
||||
|
|
@ -413,6 +542,7 @@ class _SharePageState extends State<SharePage> {
|
|||
onTap: _copyLink,
|
||||
),
|
||||
const Divider(indent: 60, height: 1),
|
||||
// 系统原生分享
|
||||
_buildActionTile(
|
||||
icon: Icons.share_rounded,
|
||||
iconBg: AppColors.successLight,
|
||||
|
|
@ -428,6 +558,10 @@ class _SharePageState extends State<SharePage> {
|
|||
);
|
||||
}
|
||||
|
||||
/// 操作列表项
|
||||
///
|
||||
/// - [iconBg] 图标容器背景色(使用语义色的浅色版本)
|
||||
/// - [subtitle] 单行截断,防止链接/代码过长破坏布局
|
||||
Widget _buildActionTile({
|
||||
required IconData icon,
|
||||
required Color iconBg,
|
||||
|
|
|
|||
Loading…
Reference in New Issue