时里院子市集
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

6.3 KiB

🎯 优惠券API集成更新

📊 后端接口分析

根据后端提供的接口,有三个专门的端点来获取不同状态的优惠券:

🔗 API端点

接口 路径 说明 返回数据
获取可用优惠券 /my/available 获取我的可用优惠券 List<ShopUserCoupon>
获取已使用优惠券 /my/used 获取我的已使用优惠券 List<ShopUserCoupon>
获取已过期优惠券 /my/expired 获取我的已过期优惠券 List<ShopUserCoupon>

🔧 前端API函数实现

新增API函数

/**
 * 获取我的可用优惠券
 */
export async function getMyAvailableCoupons() {
  const res = await request.get<ApiResult<ShopUserCoupon[]>>('/my/available');
  if (res.code === 0 && res.data) {
    return res.data;
  }
  return Promise.reject(new Error(res.message));
}

/**
 * 获取我的已使用优惠券
 */
export async function getMyUsedCoupons() {
  const res = await request.get<ApiResult<ShopUserCoupon[]>>('/my/used');
  if (res.code === 0 && res.data) {
    return res.data;
  }
  return Promise.reject(new Error(res.message));
}

/**
 * 获取我的已过期优惠券
 */
export async function getMyExpiredCoupons() {
  const res = await request.get<ApiResult<ShopUserCoupon[]>>('/my/expired');
  if (res.code === 0 && res.data) {
    return res.data;
  }
  return Promise.reject(new Error(res.message));
}

🚀 业务逻辑更新

1. 订单确认页面 (src/shop/orderConfirm/index.tsx)

更新前

// 使用通用接口 + 状态过滤
const res = await listShopUserCoupon({
  status: 0,
  validOnly: true
})

更新后

// 直接使用专门的可用优惠券接口
const res = await getMyAvailableCoupons()

优势

  • 性能提升:后端直接返回可用优惠券,无需前端过滤
  • 数据准确:后端计算状态,避免前后端逻辑不一致
  • 代码简化:减少前端状态判断逻辑

2. 用户优惠券页面 (src/user/coupon/index.tsx)

更新前

// 使用分页接口 + 复杂的状态过滤
const res = await pageShopUserCoupon({
  page: currentPage,
  limit: 10,
  status: 0,
  isExpire: 0,
  // 其他过滤条件...
})

更新后

// 根据tab直接调用对应接口
switch (tab) {
  case '0': // 可用优惠券
    res = await getMyAvailableCoupons()
    break
  case '1': // 已使用优惠券
    res = await getMyUsedCoupons()
    break
  case '2': // 已过期优惠券
    res = await getMyExpiredCoupons()
    break
}

数据处理优化

// 前端处理搜索和筛选
if (searchValue) {
  filteredList = res.filter((item: any) => 
    item.name?.includes(searchValue) || 
    item.description?.includes(searchValue)
  )
}

// 前端排序
filteredList.sort((a: any, b: any) => {
  const aValue = getValueForSort(a, filters.sortBy)
  const bValue = getValueForSort(b, filters.sortBy)
  return filters.sortOrder === 'asc' ? aValue - bValue : bValue - aValue
})

3. 统计数据更新

更新前

// 使用分页接口获取count
const [availableRes, usedRes, expiredRes] = await Promise.all([
  pageShopUserCoupon({page: 1, limit: 1, status: 0, isExpire: 0}),
  pageShopUserCoupon({page: 1, limit: 1, status: 1}),
  pageShopUserCoupon({page: 1, limit: 1, isExpire: 1})
])

setStats({
  available: availableRes?.count || 0,
  used: usedRes?.count || 0,
  expired: expiredRes?.count || 0
})

更新后

// 直接获取数据并计算长度
const [availableRes, usedRes, expiredRes] = await Promise.all([
  getMyAvailableCoupons(),
  getMyUsedCoupons(),
  getMyExpiredCoupons()
])

setStats({
  available: availableRes?.length || 0,
  used: usedRes?.length || 0,
  expired: expiredRes?.length || 0
})

📈 性能优化效果

网络请求优化

  • 减少请求参数:不需要复杂的状态过滤参数
  • 减少数据传输:后端直接返回目标数据
  • 提高缓存效率:专门的端点更容易缓存

前端处理优化

  • 简化状态管理:不需要复杂的状态过滤逻辑
  • 提高响应速度:减少前端数据处理时间
  • 降低内存占用:只加载需要的数据

🔍 数据流对比

更新前的数据流

前端请求 → 后端分页接口 → 返回所有数据 → 前端状态过滤 → 显示结果

更新后的数据流

前端请求 → 后端专门接口 → 返回目标数据 → 直接显示结果

🧪 测试要点

功能测试

  1. 订单确认页面

    • 优惠券列表正确加载
    • 只显示可用的优惠券
    • 优惠券选择功能正常
  2. 用户优惠券页面

    • 三个tab分别显示对应状态的优惠券
    • 统计数据正确显示
    • 搜索和筛选功能正常
  3. 错误处理

    • 网络异常时的错误提示
    • 空数据时的显示
    • 接口返回异常数据的处理

性能测试

  1. 加载速度

    • 页面初始化速度
    • tab切换响应速度
    • 数据刷新速度
  2. 内存使用

    • 数据加载后的内存占用
    • 页面切换时的内存释放

🚨 注意事项

1. 接口兼容性

  • 确保后端接口已经部署并可用
  • 检查接口返回的数据结构是否符合预期
  • 验证错误码和错误信息的处理

2. 数据一致性

  • 确保三个接口返回的数据状态正确
  • 验证统计数据与列表数据的一致性
  • 检查实时状态更新的准确性

3. 用户体验

  • 保持加载状态的显示
  • 提供合适的错误提示
  • 确保操作反馈及时

🎯 预期收益

开发效率

  • 代码简化:减少复杂的状态判断逻辑
  • 维护便利:业务逻辑更清晰
  • 扩展性强:易于添加新的状态类型

用户体验

  • 响应更快:减少数据处理时间
  • 数据准确:后端计算状态更可靠
  • 功能稳定:减少前端状态判断错误

系统性能

  • 网络优化:减少不必要的数据传输
  • 服务器优化:专门的查询更高效
  • 缓存友好:专门接口更容易缓存

现在优惠券功能已经完全适配后端的专门接口,提供了更好的性能和用户体验! 🎉