前言
在开发多个商城系统的过程中,功能模块大多相似,差异较小。以往较少涉及优惠券功能的实现,本文将重点记录优惠券模块的设计与编码过程,涵盖数据库结构设计、用户端领取页面、商家管理界面以及订单结算时优惠券使用的整体逻辑。
实现效果预览
用户领取优惠券页面:
商家发布优惠券页面:
订单中使用优惠券的界面:
核心业务流程说明
主要需求如下:管理员可在后台创建并发布满减或立减类型的优惠券;用户在前端完成领取,并在商品结算时选择可用优惠券进行抵扣。
1. 优惠券领取流程
用户点击领取 →检查优惠券模板是否有效 →检查是否库存不足 →检查用户是否领取 →扣减库存 →生成用户优惠券记录 →返回成功
2. 下单及使用优惠券流程
- 用户下单时选择一张优惠券
- 系统校验该优惠券的有效性(包括适用范围、有效时间、当前状态等)
- 根据规则计算可减免金额
- 确认无误后锁定该优惠券(仅在订单提交成功后生效)
- 若订单被取消,则释放已锁定的优惠券
→
- 当订单完成支付后,系统标记该优惠券为“已使用”状态
数据库设计
数据库表结构设计
① 优惠券基本信息表(coupon)
用于存储管理员发布的各类优惠券基础信息。
| 字段 | 类型 | 说明 |
|---|---|---|
| coupon_id | bigint | 主键 |
| name | varchar | 优惠券名称 |
| type | tinyint | 类型:1 表示满减,2 表示立减 |
| quota | decimal | 面值,例如减20元 |
| threshold | decimal | 满足多少金额方可使用 |
| stock | int | 可领取数量,即库存 |
| valid_start | datetime | 有效期起始时间 |
| valid_end | datetime | 有效期截止时间 |
| status | tinyint | 上架或下架状态 |
② 用户优惠券持有表(user_coupon)
记录每个用户所领取的优惠券及其使用状态和时间节点。
| 字段 | 类型 | 说明 |
|---|---|---|
| id | bigint | 主键 |
| coupon_id | bigint | 关联优惠券主键 |
| user_id | bigint | 用户唯一标识 |
| status | tinyint | 状态:0-未使用,1-已使用,2-已过期 |
| obtain_time | datetime | 领取时间 |
| use_time | datetime | 使用时间 |
| expire_time | datetime | 到期时间 |
前端页面设计
前端页面代码片段(Vue模板)
<template>
<div class="coupon-page">
<!-- 顶部导航栏 -->
<MallHeader />
<div class="coupon-container">
<div class="coupon-header">
<h2 class="page-title">优惠券中心</h2>
</div>
<!-- 主体内容区域 -->
<div class="coupon-main">
<div class="coupon-grid">
<div
v-for="item in couponList"
:key="item.id"
class="coupon-card"
:class="cardClass(item)"
>
<!-- 左侧金额展示区 -->
<div class="coupon-left">
<div class="amount">
<span v-if="item.couponType === 0">
满{{ item.threshold }}减{{ item.couponQuota }}
</span>
<span v-else-if="item.couponType === 1">
立减{{ item.couponQuota }}
</span>
</div>
</div>
<!-- 右侧信息区 -->
<div class="coupon-right">
<div class="name">{{ item.name }}</div>
<div class="valid">
有效期:<br />
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
{{ item.validStart }} - {{ item.validEnd }}
剩余:
{{ item.couponStock }}
{{ formatCountdown(item.remainingTime) }}


雷达卡


京公网安备 11010802022788号







