扫码领券功能需求分析

扫码领券功能需求分析

一、需求概述

扫描活动二维码(格式: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:活动ID
    • userId:用户ID(可自动获取)
  • 返回数据

    • 领取状态(成功/失败)
    • 优惠券信息(可选)
    • 错误信息(失败时)

四、功能流程梳理

1. 扫码领券完整流程

scss 复制代码
用户扫描活动二维码 → scanDevice() → 识别活动二维码格式 → 提取promotionAd参数
→ 跳转到领券页面 → 请求活动详情接口 → 展示活动详情
→ 用户点击领取按钮 → 调用领取接口 → 领取成功
→ 展示领取成功弹窗 → 用户点击"去使用设备" → 跳转到设备使用页面

2. 具体实现步骤

  1. 修改扫码逻辑 :在 scanDevice.dart 中添加对活动二维码格式的识别
  2. 创建活动API:定义活动详情和领取接口
  3. 创建活动Model:定义活动详情数据结构
  4. 创建领券页面:设计活动详情展示和领取交互
  5. 创建领取成功弹窗:设计成功提示和引导跳转
  6. 添加路由配置:注册新页面路由

五、页面交互设计建议

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');
      },
    ));
  }
}

七、测试要点

  1. 扫码识别测试:测试不同格式的活动二维码识别
  2. 页面展示测试:测试活动详情页面的展示效果
  3. 领取流程测试:测试领取按钮点击、领取中状态、领取成功/失败处理
  4. 弹窗交互测试:测试领取成功弹窗的展示和交互
  5. 跳转逻辑测试:测试从弹窗跳转到设备使用页面
  6. 错误场景测试:网络失败、活动已结束、已领取等场景

八、注意事项

  1. 二维码格式兼容:确保能正确识别各种可能的活动二维码格式
  2. 用户体验:领取过程中应有加载状态提示,避免用户重复点击
  3. 数据缓存:活动详情可适当缓存,减少重复请求
  4. 错误处理:所有网络请求都应有错误处理和用户提示
  5. 埋点统计:关键操作(扫码、领取、跳转)应添加埋点统计
  6. 安全性:确保 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
相关推荐
前端拷贝猿1 小时前
设备活动弹窗功能需求分析
前端
飞天狗1111 小时前
零基础JavaWeb入门——第五课第一小节:九大内置对象 · 第1个:request(请求对象)
java·开发语言·前端·后端·servlet
a15108416931 小时前
记一次大模型探索
java·服务器·前端
石山代码1 小时前
变量与解构
开发语言·前端·javascript
888CC++2 小时前
箭头函数(ES6)
前端·javascript·es6
qq_419854052 小时前
css filter
前端·javascript·css
Agatha方艺璇2 小时前
VUE复习笔记
前端·vue.js
大家的林语冰2 小时前
npm 不忍了,正式上线“阶段式发布“的新功能,进一步对抗频繁的供应链攻击!
前端·javascript·node.js
by————组态3 小时前
Ricon组态技术架构 - 企业级Web组态解决方案
运维·服务器·前端·物联网·架构·组态·组态软件