RUA宠物-积分商城设计方案

积分商城设计方案

状态:评审稿,未开始实施。承接积分模块(已有 points_account/points_log/points_expire_batch/points_rule 与 PointsService)。 与积分模块约定一致:积分扣/退走** PointsService::deduct(FIFO);成长值不动;后台接口进「需登录」分组带 allowCrossDomain;图片走 **/admin/upload


1. 定位与范围

积分商城 = 用户用可用积分兑换虚拟券 / 实物商品。

  • 虚拟商品:兑换后发放一张(兑换码/权益),用户有**「我的券」入口查看券列表与使用期限。券有使用期限**(发布时可选天数,也可永不过期)。
  • 实物商品:需收货地址 +** **邮寄,分包邮运费到付(到付运费由物流收货时向用户收取,不在线支付、不扣积分)。后台发货物流单号,发货同时更新订单详情并发送通知
  • 后台提供商品管理兑换订单管理(发货 + 可取消,取消可填原因并选择是否返还积分)。

本期不做:微信支付/退款到账、运费在线支付、优惠券叠加、评价等。

2. 核心规则

  • 扣减:下单原子扣积分(PointsService::deduct FIFO),余额不足→失败。实扣积分=单价×数量(不含运费,到付运费由物流收取)。
  • 库存:实物/虚拟均计库存,WHERE stock >= qty 原子减库存,售罄拒绝。
  • 限购:商品可配「每用户累计限兑数」,默认 1,发布时可改。
  • 运费:实物二选一——shipping_mode=free(包邮)或** **pay运费到付,不扣积分、不在线支付)。
  • SKU:商品可选配置** **1 个 SKU(默认不设;有则下单必选)。
  • 券时效:虚拟商品发布时选** voucher_expire_type——0=永不过期;N=自兑得日起 N 天内有效(券记录带 **expire_at)。
  • 取消(后台):后台任意状态订单可取消,填写取消原因 + 选择是否返还积分已发货订单默认返还;选择不返还则积分直接作废)。仅「待发货」且商品** **allow_cancel 允许时,用户可自行取消(自动返还积分)。
  • 发货:后台填快递公司+运单号→实物状态 0→1,同步到订单详情并发站内信通知(复用** **message 表)。
  • 状态机
    • 虚拟:下单即生成券(已完成);可后台取消(作废券、可选返还)。
    • 实物:待发货 →(发货)→ 已发货 → 已完成;待发货可用户取消(若允许),任意状态可后台取消。

3. 数据模型(新增 5 张表)

均为新增。points_order 内嵌收货地址快照;points_voucher 存用户持有券。

3.1 points_product 商品

字段 说明
id / name 商品名
type 1=虚拟(券) 2=实物
points_price 兑换积分价(正整数)
sku 可选 SKU/规格(默认空=不选;有则下单必选,最多 1 个)
shipping_mode 0=包邮 1=运费到付(实物用;到付不扣积分)
per_user_limit 每用户限兑数(默认 1)
allow_cancel 待发货用户是否可自行取消(默认允许)
voucher_expire_type 虚拟用:0=永不过期;1=按发布天数
voucher_valid_days voucher_expire_type=1 时的有效天数
stock / stock_total 剩余库存 / 累计上架量
cover_url / images 封面 / 图集(走 /admin/upload)
description 详情(支持换行/简单富文本)
status / sort / create/update_time 上下架 / 排序 / 时间

虚拟商品不涉及运费与地址;实物必选「包邮/到付」;商品图走** **POST /admin/upload

3.2 points_order 兑换订单

字段 说明
order_no 订单号(唯一)
user_id / nickname(快照) 下单用户
product_id / name / type / cover_url(快照) 商品信息快照
points_price / quantity 单价 / 数量
sku(快照) 所选 SKU/规格(如无则空)
shipping_mode 0=包邮 1=运费到付
total_points 实扣积分 = 单价×数量
addr_name/phone/province/city/district/detail 收货地址快照(实物)
status 0待发货 1已发货 2已完成 3已取消
track_company / track_no / shipped_at 快递公司 / 运单号 / 发货时间
allow_cancel_at 下单时商品是否允许用户取消(快照)
cancel_refund_points: 0/1 后台取消是否返还积分(默认 1;不返还则积分作废)
cancel_reason / cancel_by / cancel_time 取消原因 / 操作人 / 时间
remark 用户备注 / 后台备注
create/update_time 时间

3.3 points_voucher 用户券

字段 说明
id / voucher_code 券ID / 券码
user_id / name(快照) 归属用户 / 券名
product_id 兑换来源商品
order_id / order_no 来源订单
content 券内容(兑换码/权益/链接)
expire_at 使用期限(NULL=永不过期)
status 0有效 1已使用 2已作废 / 过期
used_at / order时间 使用/核销时间
create_time 时间

3.4 points_order_log 操作流水

记录取消、发货等状态变更(含是否返还积分、原因),便于后台追溯。

4. 兑换时序(小程序下单)

  1. 用户选商品 → 有 SKU 则选 → 实物选收货地址(复用 user_address)。
  2. POST /api/points/mall/order:事务内校验(上架/限购/SKU/实物地址)→ 原子减库存 →** PointsService::deduct(单价×数量,'mall',...)(运费到付不计入)→ 生成订单;虚拟同时生成一张券(points_voucher,按发布时效写 **expire_at)。
  3. 返回订单;虚拟商品可在「我的券」立即看到该券及使用期限。

5. 后台管理

商品管理 /admin/points/product/*

  • list(分页+关键字+type+状态筛选)、save(新增/编辑)、status(上下架)、delete(逻辑删)
  • 字段:type、points_price、sku、shipping_mode(包邮/到付)、per_user_limit(默认1)、allow_cancel、voucher_expire_type/valid_days(虚拟时效,可永不过期)、stock、cover/images
  • 前端:商品列表页;新增/编辑表单(类型切换→虚拟才显示时效;实物才显示运费;SKU 可选填1个;上传图片、库存、限购默认1、允许取消开关、上下架、排序)

订单管理 /admin/points/order/*

  • list(分页+status+user_id/product 筛选)、detail、ship(发货:填快递+运单号,实物 0→1,发站内信)、cancel(后台取消:填原因 + 选择是否返还积分,已发货默认返还,不返还则积分作废;虚拟作废券)
  • 前端:订单列表页(用户/商品/类型/实扣积分/状态/地址;发货弹窗填单号;取消弹窗填原因+返还积分开关默认开、提示不返还则积分作废)、订单详情、券列表

券管理 /admin/points/voucher/*

  • list(按用户/状态/商品筛选)、作废(手动核销/作废一张券)

6. 小程序接口(新增)

接口 说明
GET /api/points/mall/products 商品列表(上架,可 type/关键字)
GET /api/points/mall/product/:id 商品详情
POST /api/points/mall/order 兑换下单(实物传 address_id)
GET /api/points/orders 我的兑换订单(分页)
GET /api/points/order/:id 订单详情(含地址/物流/通知状态)
POST /api/points/order/cancel 待发货取消(商品允许时),返还积分
GET /api/points/vouchers 我的券列表(含有效/已用/已过期,使用期限)
GET /api/points/voucher/:id 券详情(内容/期限/核销状态)

发货通知:后台发货发站内信message 表);小程序订单详情实时展示物流单号。

7. 与现有模块衔接

  • 复用:user_address(地址)、PointsService::deduct(扣/退)、/admin/upload(图片)、OssService(双模式)、message 表(站内信,用于发货/后台取消通知)。
  • 成长值:兑换不加成长值;发货不涉及成长值。
  • 过期批次:返还的积分重建不过期批次;取消选择不返还则积分直接作废(写过期/作废流水);券时效独立(points_voucher.expire_at),与积分过期无关。

8. 分阶段实施

  • P1:建 5 表 SQL + 商品 model/service + 后台商品 CRUD + 小程序商品列表/详情
  • P2:下单(扣积分/减库存/限购/地址快照/生成券)+ 我的订单/券列表 + 后台订单/券列表
  • P3:发货(通知+物流同步)、后台取消(原因+是否返还积分)、用户自行取消 + 文档(admin/miniapp/对接)+ 后台前端功能说明
  • P4:通知设施接入确认、券核销/作废、可选优化