扫码领券功能需求分析
一、需求概述
扫描活动二维码(格式:https://appdownload.iweilaixi.com/app/download?promotionAd=*****),跳转到领券页面(新增),使用 promotionAd 访问活动详情(新接口),获取活动详情信息展示。用户点击领取,调用领取接口(新增)。领取成功后,弹窗提示领取成功,并引导用户去使用设备。
二、相关页面梳理
1. 扫码逻辑页面
- 文件路径 :
lib/app/service/scanDevice.dart - 功能:处理扫码逻辑,需要新增对活动二维码格式的识别
- 修改点 :添加对
https://appdownload.iweilaixi.com/app/download?promotionAd=*****格式的识别
2. 领券页面(新增)
-
建议路径 :
lib/app/pages/promotion/redeemCoupon/ -
功能:
- 展示活动详情信息(活动标题、描述、图片、优惠规则等)
- 提供领取按钮
- 领取成功后展示成功弹窗
- 引导用户去使用设备
3. 活动详情页面(可能复用)
- 现有页面 :
lib/app/pages/coupon/couponCenter/(优惠套餐页面) - 功能:可参考现有的优惠套餐展示方式
4. 领取成功弹窗(新增组件)
-
建议路径 :
lib/app/components/promotion/ -
功能:
- 展示领取成功信息
- 提供"去使用设备"按钮
- 引导用户跳转到设备使用页面
三、相关接口梳理
1. 活动详情接口(新接口)
-
接口路径 :待定(建议
/promotion/getDetail或/promotion/getByPromotionAd) -
API文件 :需新建(建议
lib/app/api/promotion/目录) -
请求参数 :
promotionAd(活动广告标识) -
返回数据:活动详情信息,包括:
- 活动ID
- 活动标题
- 活动描述
- 活动图片
- 优惠规则(金额、使用条件等)
- 活动状态(是否可领取等)
2. 领取接口(新接口)
-
接口路径 :待定(建议
/promotion/receive或/coupon/receiveByPromotion) -
API文件:与活动详情接口同文件
-
请求参数:
promotionId:活动IDuserId:用户ID(可自动获取)
-
返回数据:
- 领取状态(成功/失败)
- 优惠券信息(可选)
- 错误信息(失败时)
四、功能流程梳理
1. 扫码领券完整流程
scss
用户扫描活动二维码 → scanDevice() → 识别活动二维码格式 → 提取promotionAd参数
→ 跳转到领券页面 → 请求活动详情接口 → 展示活动详情
→ 用户点击领取按钮 → 调用领取接口 → 领取成功
→ 展示领取成功弹窗 → 用户点击"去使用设备" → 跳转到设备使用页面
2. 具体实现步骤
- 修改扫码逻辑 :在
scanDevice.dart中添加对活动二维码格式的识别 - 创建活动API:定义活动详情和领取接口
- 创建活动Model:定义活动详情数据结构
- 创建领券页面:设计活动详情展示和领取交互
- 创建领取成功弹窗:设计成功提示和引导跳转
- 添加路由配置:注册新页面路由
五、页面交互设计建议
1. 领券页面设计
- 顶部:活动图片/横幅
- 中部:活动详情(标题、描述、优惠规则)
- 底部:领取按钮(固定在底部)
- 交互:点击领取按钮后,按钮状态变为"领取中",成功后变为"已领取"
2. 领取成功弹窗设计
-
内容:
- 成功图标/动画
- "领取成功!" 标题
- 优惠券信息摘要
- "去使用设备" 按钮
- "关闭" 或 "稍后再说" 按钮
-
交互:
- 点击"去使用设备"跳转到设备使用页面(如首页或设备列表页)
- 点击"关闭"关闭弹窗
3. 错误处理
- 网络请求失败:展示错误提示,提供重试按钮
- 活动已结束:展示活动已结束提示
- 已领取过:展示已领取提示,引导去使用
六、技术实现要点
1. 扫码逻辑修改
kotlin
// 在scanDevice.dart中添加活动二维码识别
scanCallBack(scanResult) {
// 识别活动二维码格式
if (scanResult.contains('appdownload.iweilaixi.com/app/download') &&
scanResult.contains('promotionAd=')) {
// 提取promotionAd参数
final uri = Uri.parse(scanResult);
final promotionAd = uri.queryParameters['promotionAd'];
if (promotionAd != null) {
// 跳转到领券页面
Get.toNamed('/promotion-redeem', arguments: {'promotionAd': promotionAd});
return;
}
}
// 原有设备二维码处理逻辑...
}
2. 活动API创建
dart
// 新建活动API类
class PromotionApi {
// 获取活动详情
static Future<PromotionDetailModel> getDetail(String promotionAd) async {
final response = await HttpUtils.post(
path: "/promotion/getDetail",
data: {'promotionAd': promotionAd});
final PromotionDetailModel result = PromotionDetailModel.fromJson(response);
return result;
}
// 领取优惠券
static Future<bool> receiveCoupon(String promotionId) async {
final response = await HttpUtils.post(
path: "/promotion/receive",
data: {'promotionId': promotionId});
return response['success'] == true;
}
}
3. 领券页面控制器
ini
class RedeemCouponController extends GetxController {
RxString promotionAd = ''.obs;
Rx<PromotionDetailModel?> promotionDetail = Rx<PromotionDetailModel?>(null);
RxBool isLoading = true.obs;
RxBool isReceiving = false.obs;
@override
void onInit() {
super.onInit();
promotionAd.value = Get.arguments['promotionAd'];
loadPromotionDetail();
}
void loadPromotionDetail() async {
isLoading.value = true;
try {
promotionDetail.value = await PromotionApi.getDetail(promotionAd.value);
} catch (e) {
// 错误处理
} finally {
isLoading.value = false;
}
}
void receiveCoupon() async {
if (promotionDetail.value == null) return;
isReceiving.value = true;
try {
final success = await PromotionApi.receiveCoupon(
promotionDetail.value!.id.toString());
if (success) {
// 展示领取成功弹窗
showSuccessDialog();
} else {
// 展示失败提示
}
} catch (e) {
// 错误处理
} finally {
isReceiving.value = false;
}
}
void showSuccessDialog() {
// 展示领取成功弹窗
Get.dialog(PromotionSuccessDialog(
promotionDetail: promotionDetail.value!,
onUseDevice: () {
// 跳转到设备使用页面
Get.offAllNamed('/home');
},
));
}
}
七、测试要点
- 扫码识别测试:测试不同格式的活动二维码识别
- 页面展示测试:测试活动详情页面的展示效果
- 领取流程测试:测试领取按钮点击、领取中状态、领取成功/失败处理
- 弹窗交互测试:测试领取成功弹窗的展示和交互
- 跳转逻辑测试:测试从弹窗跳转到设备使用页面
- 错误场景测试:网络失败、活动已结束、已领取等场景
八、注意事项
- 二维码格式兼容:确保能正确识别各种可能的活动二维码格式
- 用户体验:领取过程中应有加载状态提示,避免用户重复点击
- 数据缓存:活动详情可适当缓存,减少重复请求
- 错误处理:所有网络请求都应有错误处理和用户提示
- 埋点统计:关键操作(扫码、领取、跳转)应添加埋点统计
- 安全性:确保 promotionAd 参数的校验和防刷机制
九、页面结构建议
1. 领券页面结构
bash
lib/app/pages/promotion/
├── redeemCoupon/
│ ├── bindings/
│ │ └── redeem_coupon_binding.dart
│ ├── controllers/
│ │ └── redeem_coupon_controller.dart
│ └── views/
│ └── redeem_coupon_view.dart
└── index.dart
2. 组件结构
bash
lib/app/components/promotion/
├── promotion_success_dialog.dart # 领取成功弹窗
├── promotion_card.dart # 活动卡片组件
└── index.dart
3. API结构
bash
lib/app/api/promotion/
├── promotion_api.dart # 活动相关API
└── index.dart
4. Model结构
bash
lib/app/model/promotion/
├── promotion_detail_model.dart # 活动详情模型
└── index.dart