26 KiB
PRD:优惠券功能
版本: v1.2 日期: 2026-03-04 项目: 万车充运营管理平台 状态: 草稿
变更记录
| 版本 | 日期 | 变更内容 |
|---|---|---|
| v1.0 | 2026-03-03 | 初稿:积分兑换洗车券功能 |
| v1.1 | 2026-03-03 | 新增:券创建权限体系(平台人员 vs 运营商人员);新增充电折扣券规划;更新数据库设计与业务规则 |
| v1.2 | 2026-03-04 | 补全遗漏点:修复 scope 规则自相矛盾;统一 member_id/积分字段类型与现网一致;新增幂等键字段、核销日志表、scope 反向索引;补齐接口分页与安全参数;完善业务规则(字段冻结、过期边界、核销 scope 校验、时区规定);为 v1.2 折扣券预埋扩展字段 |
| v1.3 | 2026-03-04 | 新增 total_limit(单用户累计兑换上限)字段,补全领券限制覆盖场景说明 |
一、背景与目标
背景
平台现有积分系统(member_points_info)支持充电消费奖励积分,但积分使用场景单一(仅支持抵扣充电费用)。为提升用户留存与活跃度,引入优惠券体系,首期以「积分兑换洗车券」为切入点,同时建立支持平台与运营商双层管理的券权限体系,为后续充电折扣券等功能奠定基础。
目标
- 为用户提供积分消耗渠道,提升积分价值感知
- 通过洗车权益与充电绑定,增强用户充电粘性
- 建立可扩展的优惠券基础架构,支持后续更多券类型
- 建立平台与运营商双层券管理权限,支持精细化运营
成功指标
- 积分兑换率(兑换用户数 / 持有积分用户数)≥ 15%
- 洗车券核销率 ≥ 60%
- 功能上线后次月充电频次同比提升 ≥ 5%
二、用户角色
| 角色 | 类型 | 说明 |
|---|---|---|
| 平台管理员 | 创券方 | 平台运营人员,可创建全平台范围或指定运营商范围的优惠券 |
| 运营商管理员 | 创券方 | 运营商后台人员,只能创建本运营商范围内可用的优惠券 |
| 会员用户 | 使用方 | 通过充电获得积分,在 App/小程序中兑换并使用券 |
| 合作洗车商 | 核销方 | 扫码核销洗车券(可通过独立 H5 页面或 API 对接) |
三、券可用范围权限设计
3.1 核心规则
| 创建人角色 | 可设置的最大可用范围 | 说明 |
|---|---|---|
| 平台管理员 | 全平台 | 可选:全平台 / 指定运营商 / 指定站点 |
| 运营商管理员 | 本运营商 | 可选:本运营商全部站点 / 指定站点(仅限本运营商下) |
3.2 可用范围枚举
| 范围值 | 说明 | 可创建角色 |
|---|---|---|
1 - 全平台 |
所有运营商、所有站点均可使用 | 仅平台管理员 |
2 - 指定运营商 |
仅指定运营商下的站点可使用 | 平台管理员(可多选);运营商管理员(固定为本运营商) |
3 - 指定站点 |
仅指定站点可使用 | 平台管理员;运营商管理员(仅限本运营商下的站点) |
3.3 业务规则
- 运营商管理员创建券时,
scope_type可选范围为{2, 3},不能选1(全平台) - 运营商管理员选择
scope_type=3(指定站点)时,后端强制校验所选站点必须属于本运营商,不可选其他运营商站点;coupon_template_scope中记录的scope_id均需经过此校验 - 平台管理员可查看所有运营商的券;运营商管理员只能查看和管理本运营商(
creator_merchant_id匹配)创建的券 - 用户兑换券时,系统根据券的
scope_type及关联数据校验用户资格:用户资格判定优先级:当前所在充电站 > 最近一次充电站 > 不做限制(兜底) - 核销时必须传入
storeId/stationId,后端校验核销门店是否在券的scope范围内;不在范围内的核销请求拒绝 - 充电折扣券使用时额外校验:本次充电所在站点是否在券的可用范围内(v1.2 实现)
四、功能范围(首期 v1.0)
4.1 功能清单
| 模块 | 功能点 | 优先级 |
|---|---|---|
| 券模板管理 | 平台管理员创建/编辑/下架洗车券模板 | P0 |
| 券模板管理 | 运营商管理员创建/编辑/下架洗车券模板 | P0 |
| 券模板管理 | 设置券可用范围(全平台 / 指定运营商 / 指定站点) | P0 |
| 券模板管理 | 设置积分兑换比例(N 积分 = 1 张券) | P0 |
| 券模板管理 | 设置券有效期(固定日期 / 领取后 N 天) | P0 |
| 积分兑换 | 用户查看可兑换券列表 | P0 |
| 积分兑换 | 用户用积分兑换洗车券 | P0 |
| 积分兑换 | 兑换记录查询 | P0 |
| 我的券包 | 查看持有的洗车券(未使用/已使用/已过期) | P0 |
| 券核销 | 展示券码(二维码 / 核销码) | P0 |
| 券核销 | 合作商扫码核销 | P0 |
| 数据看板 | 兑换量、核销量、积分消耗统计 | P1 |
| 运营配置 | 单用户每日/每月兑换上限 | P1 |
| 运营配置 | 券库存上限控制 | P1 |
4.2 首期不包含
- 现金购买券
- 券转赠
- 充电折扣券(规划于 v1.2)
- 第三方洗车平台 API 对接(仅本地核销)
五、业务流程
5.1 创建券模板流程
管理员进入券模板管理页
→ 选择券类型(首期仅洗车券)
→ 系统根据登录角色自动限制可用范围选项
├─ 平台管理员:可选 全平台 / 指定运营商 / 指定站点
└─ 运营商管理员:可选 本运营商 / 本运营商下指定站点
→ 填写积分兑换价格、库存、有效期、兑换限额等配置
→ 提交 → 系统二次校验 scope 权限边界
→ 保存,默认下架状态,手动上架后对用户可见
5.2 积分兑换流程
用户进入积分商城
→ 系统查询该用户可见的洗车券列表
(过滤逻辑:券为上架状态 + 未过期 + 有库存 + 用户所在运营商/站点在券可用范围内)
→ 用户查看洗车券兑换入口(展示所需积分、库存、有效期)
→ 确认兑换
→ 系统校验:积分是否足够 + 库存是否充足 + 兑换限额检查
→ 原子操作:扣减积分 + 生成用户券记录
→ 写入积分变更日志(member_points_record,类型=积分兑换消耗)
→ 返回兑换成功,展示券码
5.3 洗车券核销流程
用户出示洗车券二维码(短时签名 token,有效期 5 分钟)
→ 洗车商扫码 → 调用核销接口(携带 storeId + requestId + sign)
→ 系统校验:
① token 有效性(后端换取真实 couponNo,防止直接暴露)
② 券状态是否为「未使用」
③ 是否在有效期内
④ 核销门店是否在券的 scope 范围内
→ 原子更新:UPDATE member_coupon SET status=1 WHERE coupon_no=? AND status=0
(原子更新保证并发核销幂等,更新行数=0 则返回"已核销")
→ 写入核销日志 coupon_verify_record(成功/失败均记录)
→ 核销成功响应
六、数据库设计
6.1 券模板表 coupon_template
| 字段 | 类型 | 说明 |
|---|---|---|
id |
bigint PK | 主键 |
name |
varchar(50) | 券名称,如"洗车券" |
type |
tinyint | 券类型:1=洗车券 2=充电折扣券 |
creator_type |
tinyint | 创建人类型:1=平台管理员 2=运营商管理员 |
creator_merchant_id |
bigint | 创建人所属运营商 ID(平台管理员为 NULL) |
scope_type |
tinyint | 可用范围:1=全平台 2=指定运营商 3=指定站点 |
points_cost |
decimal(10,2) | 兑换所需积分(洗车券用,与现网积分精度一致) |
discount_rate |
decimal(4,2) | 折扣比例(充电折扣券用,如 0.85 表示 85 折) |
min_charge_amount |
decimal(10,2) | 充电最低消费金额门槛(折扣券,v1.2) |
max_discount_amount |
decimal(10,2) | 单次最大抵扣金额上限(折扣券,v1.2) |
exchange_start_time |
datetime | 兑换活动开始时间(NULL=不限) |
exchange_end_time |
datetime | 兑换活动结束时间(NULL=不限) |
stock_total |
int | 总库存(-1 表示不限制) |
stock_remain |
int | 剩余库存(-1 表示不限制) |
validity_type |
tinyint | 有效期类型:1=固定日期 2=领取后N天 |
valid_start_time |
datetime | 固定有效期开始(validity_type=1) |
valid_end_time |
datetime | 固定有效期结束(validity_type=1) |
valid_days |
int | 领取后有效天数(validity_type=2) |
daily_limit |
int | 单用户每日兑换上限(0=不限,以 Asia/Shanghai 自然日计算) |
monthly_limit |
int | 单用户每月兑换上限(0=不限,以 Asia/Shanghai 自然月计算) |
total_limit |
int | 单用户累计兑换上限(0=不限,如设为 1 则每人终身只能兑换 1 张) |
status |
tinyint | 状态:0=下架 1=上架 |
description |
varchar(500) | 券使用说明 |
update_by |
varchar(64) | 最后修改人账号 |
create_by |
varchar(64) | 创建人账号 |
create_time |
datetime | 创建时间 |
update_time |
datetime | 更新时间 |
del_flag |
char(1) | 删除标志 |
6.2 券可用范围明细表 coupon_template_scope
用于存储
scope_type=2(指定运营商)或scope_type=3(指定站点)时的具体关联数据
| 字段 | 类型 | 说明 |
|---|---|---|
id |
bigint PK | 主键 |
template_id |
bigint | 关联券模板 ID |
scope_type |
tinyint | 范围类型:2=运营商 3=站点 |
scope_id |
bigint | 运营商 ID 或站点 ID |
新增索引
idx_scope_lookup(scope_type, scope_id, template_id)支持"按门店/运营商反查可用券模板"的高频查询
6.3 用户券表 member_coupon
| 字段 | 类型 | 说明 |
|---|---|---|
id |
bigint PK | 主键 |
coupon_no |
varchar(32) | 券编号(唯一,内部使用) |
exchange_request_id |
varchar(64) | 兑换幂等键(客户端 requestId,唯一索引) |
template_id |
bigint | 关联券模板 ID |
member_id |
varchar(64) | 关联会员 ID(与现有 member_points_info.memberId 类型一致,varchar) |
coupon_type |
tinyint | 券类型快照:1=洗车券 2=充电折扣券 |
points_cost |
decimal(10,2) | 兑换时消耗的积分(快照,与现网积分精度一致) |
discount_rate |
decimal(4,2) | 折扣比例快照(洗车券为 NULL) |
status |
tinyint | 状态:0=未使用 1=已使用 2=已过期 |
source |
tinyint | 来源:1=积分兑换 |
exchange_time |
datetime | 兑换时间 |
expire_time |
datetime | 过期时间 |
use_time |
datetime | 核销时间 |
use_store_id |
bigint | 核销门店/站点 ID |
use_operator |
varchar(64) | 核销操作人 |
create_time |
datetime | 创建时间 |
del_flag |
char(1) | 删除标志 |
6.4 核销日志表 coupon_verify_record
记录每次核销请求(成功/失败均记录),用于风控、追溯与幂等保障
| 字段 | 类型 | 说明 |
|---|---|---|
id |
bigint PK | 主键 |
coupon_no |
varchar(32) | 券编号 |
request_id |
varchar(64) | 核销请求幂等键 |
store_id |
bigint | 核销门店 ID |
operator_id |
varchar(64) | 核销操作人 |
result |
tinyint | 核销结果:1=成功 2=失败 |
fail_reason |
varchar(200) | 失败原因(result=2 时记录) |
create_time |
datetime | 请求时间 |
6.5 依赖现有表
member_points_info:积分余额更新(totalPoints为BigDecimal,memberId为String)member_points_record:新增消耗类型(type=3积分兑换)pile_merchant_info:运营商信息(校验 creator_merchant_id)pile_station_info:站点信息(校验 scope 范围、反查站点所属运营商)
七、接口设计
App/小程序端
| 接口 | 方法 | 说明 |
|---|---|---|
/coupon/template/list |
GET | 获取用户可兑换券模板列表;入参:stationId(当前所在站点,用于 scope 过滤)、pageNum、pageSize |
/coupon/exchange |
POST | 积分兑换;入参:templateId、requestId(客户端幂等键) |
/coupon/my/list |
GET | 我的券包列表;入参:status(0/1/2)、pageNum、pageSize |
/coupon/my/detail/{couponNo} |
GET | 券详情(含短时签名二维码 token,有效期 5 分钟) |
管理后台
| 接口 | 方法 | 说明 |
|---|---|---|
/admin/coupon/template/list |
GET | 券模板列表;入参:pageNum、pageSize;运营商管理员仅返回本运营商数据 |
/admin/coupon/template/add |
POST | 新增券模板(含 scope 权限校验) |
/admin/coupon/template/edit |
PUT | 编辑券模板(已有兑换记录时冻结核心字段,后端校验) |
/admin/coupon/template/changeStatus |
PUT | 上下架 |
/admin/coupon/record/list |
GET | 兑换记录查询;入参:pageNum、pageSize;运营商管理员仅查本运营商数据 |
/admin/coupon/verify |
POST | 核销券;入参:couponNo(或签名 token)、storeId、requestId(幂等键)、operatorId |
/admin/coupon/stats |
GET | 数据统计;运营商管理员仅查本运营商数据 |
/admin/coupon/invalidate |
POST | 人工作废券(需审计日志);入参:couponNo、reason |
八、关键业务规则
-
原子性保障:扣减积分与生成券记录必须在同一事务中完成,防止积分扣了但券没生成
-
库存防超卖:主方案为数据库原子更新(
UPDATE coupon_template SET stock_remain = stock_remain - 1 WHERE id=? AND stock_remain >= 1);stock_remain=-1表示不限库存,跳过此校验。不采用乐观锁版本号,避免重试逻辑复杂化 -
幂等兑换:前端每次兑换请求携带
requestId(客户端生成 UUID),后端在member_coupon表的exchange_request_id字段建唯一索引;重复请求命中唯一索引冲突时直接返回已有结果,不报错 -
券码安全:
coupon_no使用 UUID,不直接暴露给核销方;二维码内容为短时签名 token(有效期 5 分钟),后端解析 token 后取真实coupon_no执行核销 -
过期处理:查询侧(我的券包、兑换列表)按
expire_time < now()动态判定过期状态;Quartz 定时任务每日凌晨仅做批量归档修正(将已过期但状态仍为 0 的券更新为 2),避免状态滞后影响用户体验 -
积分变更日志:兑换成功后写入
member_points_record,type=3(积分兑换消耗),确保积分流水可追溯 -
Scope 权限隔离:
- 运营商管理员提交创建/编辑接口时,后端强制校验
scope_type ∈ {2,3}(不能为 1),且creator_merchant_id必须与登录账号所属运营商一致,防止越权 scope_type=3时,后端逐一校验coupon_template_scope中的scope_id均属于本运营商站点- 运营商管理员只能查看和操作本运营商创建的券模板,列表接口自动按
creator_merchant_id过滤
- 运营商管理员提交创建/编辑接口时,后端强制校验
-
模板字段冻结规则:券模板一旦有用户完成兑换(
member_coupon存在对应记录),以下字段不可修改:type、points_cost、validity_type、valid_days(防止已兑换用户权益受损);可修改字段:name、description、stock_total、daily_limit、monthly_limit、status -
兑换限额时区:每日/每月兑换上限以
Asia/Shanghai自然日/自然月计算 -
领券限制优先级与校验顺序(每次兑换按序执行):
- 券模板状态:
status=1(上架) - 兑换时间段:
exchange_start_time <= now() <= exchange_end_time(NULL 表示不限) - 全局库存:
stock_remain >= 1(-1 表示不限,跳过此步) - 单用户累计上限:
total_limit > 0时,查询member_coupon该用户对该模板的历史兑换总数,达上限则拒绝 - 单用户每月上限:
monthly_limit > 0时,查询本月兑换数 - 单用户每日上限:
daily_limit > 0时,查询今日兑换数 - 积分余额:用户当前积分 >=
points_cost
全部通过后执行原子操作:
UPDATE stock_remain - 1(有库存限制时)+ 插入member_coupon典型场景覆盖:
场景 配置示例 不限量、不限人 stock_total=-1,三个 limit 均为 0总量 50 张,不限人 stock_total=50,三个 limit 均为 0总量 50 张,每人限 1 张 stock_total=50,total_limit=1活动期间(3月)每人每天限 1 张 exchange_start/end_time设活动期,daily_limit=1每人每月最多 3 张、每天最多 1 张 monthly_limit=3,daily_limit=1 - 券模板状态:
-
核销 Scope 校验:核销接口必须传入
storeId,后端校验该门店是否在券的scope范围内;核销结果(成功/失败)写入coupon_verify_record日志表 -
折扣券使用校验(v1.2 实现):充电结算时校验充电站是否在折扣券的
scope范围内,不在范围内的券不可抵扣
九、非功能需求
| 项目 | 要求 |
|---|---|
| 性能 | 兑换接口 P99 < 500ms |
| 并发 | 支持同一券模板 100 QPS 并发兑换 |
| 可靠性 | 积分扣减与券生成保证原子性 |
| 安全 | 核销接口需鉴权;创券接口需强制 scope 边界校验,防止运营商越权 |
十、数据库建表语句
-- ----------------------------
-- 券模板表
-- ----------------------------
CREATE TABLE `coupon_template` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` VARCHAR(50) NOT NULL COMMENT '券名称,如洗车券',
`type` TINYINT NOT NULL DEFAULT 1 COMMENT '券类型:1=洗车券 2=充电折扣券',
`creator_type` TINYINT NOT NULL DEFAULT 1 COMMENT '创建人类型:1=平台管理员 2=运营商管理员',
`creator_merchant_id` BIGINT DEFAULT NULL COMMENT '创建人所属运营商ID,平台管理员为NULL',
`scope_type` TINYINT NOT NULL DEFAULT 1 COMMENT '可用范围:1=全平台 2=指定运营商 3=指定站点',
`points_cost` DECIMAL(10,2) DEFAULT NULL COMMENT '兑换所需积分(洗车券使用,与现网积分精度一致)',
`discount_rate` DECIMAL(4, 2) DEFAULT NULL COMMENT '折扣比例(充电折扣券使用,如0.85表示85折)',
`min_charge_amount` DECIMAL(10,2) DEFAULT NULL COMMENT '充电最低消费金额门槛(折扣券,v1.2预留)',
`max_discount_amount` DECIMAL(10,2) DEFAULT NULL COMMENT '单次最大抵扣金额上限(折扣券,v1.2预留)',
`exchange_start_time` DATETIME DEFAULT NULL COMMENT '兑换活动开始时间,NULL=不限',
`exchange_end_time` DATETIME DEFAULT NULL COMMENT '兑换活动结束时间,NULL=不限',
`stock_total` INT NOT NULL DEFAULT -1 COMMENT '总库存,-1表示不限制',
`stock_remain` INT NOT NULL DEFAULT -1 COMMENT '剩余库存,-1表示不限制',
`validity_type` TINYINT NOT NULL DEFAULT 2 COMMENT '有效期类型:1=固定日期 2=领取后N天',
`valid_start_time` DATETIME DEFAULT NULL COMMENT '固定有效期开始时间(validity_type=1时有效)',
`valid_end_time` DATETIME DEFAULT NULL COMMENT '固定有效期结束时间(validity_type=1时有效)',
`valid_days` INT DEFAULT NULL COMMENT '领取后有效天数(validity_type=2时有效)',
`daily_limit` INT NOT NULL DEFAULT 0 COMMENT '单用户每日兑换上限,0=不限,按Asia/Shanghai自然日计算',
`monthly_limit` INT NOT NULL DEFAULT 0 COMMENT '单用户每月兑换上限,0=不限,按Asia/Shanghai自然月计算',
`total_limit` INT NOT NULL DEFAULT 0 COMMENT '单用户累计兑换上限,0=不限,如1=每人终身限1张',
`status` TINYINT NOT NULL DEFAULT 0 COMMENT '状态:0=下架 1=上架',
`description` VARCHAR(500) DEFAULT NULL COMMENT '券使用说明',
`update_by` VARCHAR(64) DEFAULT '' COMMENT '最后修改人账号',
`create_by` VARCHAR(64) DEFAULT '' COMMENT '创建人账号',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`del_flag` CHAR(1) NOT NULL DEFAULT '0' COMMENT '删除标志:0=存在 2=删除',
PRIMARY KEY (`id`),
KEY `idx_creator_merchant` (`creator_merchant_id`, `status`, `del_flag`),
KEY `idx_scope_type` (`scope_type`, `status`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COMMENT = '优惠券模板表';
-- ----------------------------
-- 券可用范围明细表(scope_type=2 或 3 时使用)
-- ----------------------------
CREATE TABLE `coupon_template_scope` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
`template_id` BIGINT NOT NULL COMMENT '关联券模板ID',
`scope_type` TINYINT NOT NULL COMMENT '范围类型:2=运营商 3=站点',
`scope_id` BIGINT NOT NULL COMMENT '运营商ID 或 站点ID',
PRIMARY KEY (`id`),
KEY `idx_template_id` (`template_id`),
UNIQUE KEY `uk_template_scope` (`template_id`, `scope_type`, `scope_id`),
KEY `idx_scope_lookup` (`scope_type`, `scope_id`, `template_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COMMENT = '优惠券可用范围明细表';
-- ----------------------------
-- 用户券表
-- ----------------------------
CREATE TABLE `member_coupon` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
`coupon_no` VARCHAR(32) NOT NULL COMMENT '券编号(唯一,内部使用)',
`exchange_request_id` VARCHAR(64) DEFAULT NULL COMMENT '兑换幂等键(客户端requestId),唯一索引防重复兑换',
`template_id` BIGINT NOT NULL COMMENT '关联券模板ID',
`member_id` VARCHAR(64) NOT NULL COMMENT '关联会员ID(与member_points_info.memberId类型一致)',
`coupon_type` TINYINT NOT NULL COMMENT '券类型快照:1=洗车券 2=充电折扣券',
`points_cost` DECIMAL(10,2) NOT NULL DEFAULT 0 COMMENT '兑换时消耗的积分快照,与现网积分精度一致',
`discount_rate` DECIMAL(4, 2) DEFAULT NULL COMMENT '折扣比例快照,洗车券为NULL',
`status` TINYINT NOT NULL DEFAULT 0 COMMENT '状态:0=未使用 1=已使用 2=已过期',
`source` TINYINT NOT NULL DEFAULT 1 COMMENT '来源:1=积分兑换',
`exchange_time` DATETIME DEFAULT NULL COMMENT '兑换时间',
`expire_time` DATETIME NOT NULL COMMENT '过期时间',
`use_time` DATETIME DEFAULT NULL COMMENT '核销时间',
`use_store_id` BIGINT DEFAULT NULL COMMENT '核销门店/站点ID',
`use_operator` VARCHAR(64) DEFAULT NULL COMMENT '核销操作人',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`del_flag` CHAR(1) NOT NULL DEFAULT '0' COMMENT '删除标志:0=存在 2=删除',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_coupon_no` (`coupon_no`),
UNIQUE KEY `uk_exchange_request` (`exchange_request_id`),
KEY `idx_member_id` (`member_id`, `status`),
KEY `idx_template_id` (`template_id`),
KEY `idx_expire_time` (`expire_time`, `status`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COMMENT = '会员优惠券表';
-- ----------------------------
-- 核销日志表
-- ----------------------------
CREATE TABLE `coupon_verify_record` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
`coupon_no` VARCHAR(32) NOT NULL COMMENT '券编号',
`request_id` VARCHAR(64) DEFAULT NULL COMMENT '核销请求幂等键',
`store_id` BIGINT DEFAULT NULL COMMENT '核销门店ID',
`operator_id` VARCHAR(64) DEFAULT NULL COMMENT '核销操作人',
`result` TINYINT NOT NULL COMMENT '核销结果:1=成功 2=失败',
`fail_reason` VARCHAR(200) DEFAULT NULL COMMENT '失败原因',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '请求时间',
PRIMARY KEY (`id`),
KEY `idx_coupon_no` (`coupon_no`),
KEY `idx_request_id` (`request_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COMMENT = '优惠券核销日志表';
索引说明
coupon_template.idx_creator_merchant:运营商管理员查看本运营商券模板列表的高频查询coupon_template_scope.uk_template_scope:防止同一模板下重复添加相同范围记录coupon_template_scope.idx_scope_lookup:按门店/运营商反查可用券模板(兑换列表过滤高频查询)member_coupon.uk_exchange_request:兑换幂等保障,重复提交命中唯一索引冲突直接返回member_coupon.idx_expire_time:供 Quartz 定时任务扫描过期券使用member_coupon.uk_coupon_no:唯一索引防止重复券码、保证核销安全
十一、后续迭代规划
| 阶段 | 功能 |
|---|---|
| v1.1 | 第三方洗车平台 API 对接(自动核销) |
| v1.2 | 充电折扣券:运营商/平台创建折扣券,充电结算时自动抵扣,校验站点范围 |
| v1.3 | 运营活动:充电满额赠券、节日送券 |
| v2.0 | 积分商城完整体验(多商品、排行榜) |