文档目录
促销活动表

简介

本文件面向电商平台开发者,系统化梳理 DouPHP 电商系统中“促销活动”的数据模型与业务流程。重点围绕以下目标展开:

  • 明确活动主表与活动商品关联表的表结构设计(以 dou_promotion、dou_promotion_product 为核心)。
  • 解释活动类型定义、活动时间范围、参与商品、折扣规则、限购策略等关键业务在数据层如何表达。
  • 记录活动状态管理、库存扣减、价格计算等核心流程的落地方式。
  • 提供活动并发控制、性能优化、数据统计的技术方案建议。
  • 为后续扩展或迁移提供完整的数据模型参考。

说明:当前仓库未直接包含 dou_promotion 与 dou_promotion_product 的建表语句;但存在大量“促销价+起止时间”的通用促销字段实践(如 product/chat_package/vip/money 等),以及优惠券折扣计算逻辑。本文将基于这些既有实现,给出可落地的促销表设计建议与流程映射。

项目结构

与促销活动相关的关键位置包括:

  • 系统表结构文档:集中定义了多类商品的促销价与促销时间字段,体现统一的促销数据约定。
  • 前台商品服务:通过定价服务计算最终售价,支撑列表/详情页展示。
  • 模块升级脚本:将旧版促销时间字段统一迁移为更规范的日期时间字段,体现演进方向。
  • 优惠券服务:提供按条件、有效期、上限控制的折扣计算示例,可作为活动折扣计算的参考。
graph TB
A["系统表结构<br/>促销字段规范"] --> B["商品表<br/>含促销价/时间"]
A --> C["聊天套餐表<br/>含促销价/时间"]
D["前台商品服务"] --> E["定价服务<br/>salePrice"]
F["优惠券服务"] --> G["折扣计算<br/>有效期/条件/上限"]
H["模块升级脚本"] --> B
H --> C

核心组件

  • 促销主表(建议:dou_promotion)
    • 职责:承载一次营销活动的元信息,如活动名称、类型、状态、时间范围、适用范围、预算/限额、统计指标等。
    • 关键字段建议:id、name、type、status、start_at、end_at、scope(商品/类目/品牌/全站)、budget、limit_per_user、limit_total、created_at、updated_at。
  • 活动商品关联表(建议:dou_promotion_product)
    • 职责:描述某活动覆盖的具体商品及该商品在活动中的专属规则(如活动价、限购数量、优先级、是否叠加等)。
    • 关键字段建议:id、promotion_id、product_id、promote_price、limit_per_order、priority、is_override、created_at、updated_at。
  • 商品表促销字段(已有)
    • 促销价与促销时间:promote_price、promote_start_time/promote_end_time(部分模块已升级为 promote_start_at/promote_end_at)。
  • 优惠券折扣(已有)
    • 支持按金额门槛、百分比/固定面额、最大减免、有效期校验等,可作为活动折扣计算的参考实现。

架构总览

促销体系由“活动主表 + 活动商品关联表 + 商品促销字段 + 定价服务 + 优惠券折扣”共同构成。前端商品列表/详情通过定价服务获取 salePrice,结合商品自身的促销价与时间范围,决定最终展示价格。后台可通过活动主表统一管理活动生命周期与规则。

sequenceDiagram
participant 前端 as "前端"
participant 商品服务 as "商品服务"
participant 定价服务 as "定价服务"
participant 数据库 as "数据库"
前端->>商品服务 : "请求商品列表/详情"
商品服务->>定价服务 : "计算 salePrice(商品ID, 用户ID)"
定价服务->>数据库 : "读取商品基础价/促销价/时间"
定价服务-->>商品服务 : "返回折后价/原价/活动标识"
商品服务-->>前端 : "返回商品数据含价格信息"

详细组件分析

促销主表(dou_promotion)设计

  • 设计目标
    • 统一管理营销活动,解耦商品级促销配置,支持多活动并行、优先级与互斥。
  • 建议字段
    • id:主键
    • name:活动名称
    • type:活动类型(如满减、折扣、秒杀、阶梯价等)
    • status:状态(草稿/预热/进行中/已结束/已取消)
    • start_at/end_at:活动时间范围
    • scope:适用范围(商品/类目/品牌/全站)
    • budget:活动预算(可选)
    • limit_per_user:每人限购(可选)
    • limit_total:总量限制(可选)
    • created_at/updated_at:时间戳
  • 索引建议
    • (status, start_at, end_at) 用于快速筛选进行中的活动
    • (scope_type, scope_id) 用于按范围查询

活动商品关联表(dou_promotion_product)设计

  • 设计目标
    • 将活动与商品解耦,支持同一商品参与多个活动时的优先级与覆盖策略。
  • 建议字段
    • id:主键
    • promotion_id:关联活动
    • product_id:关联商品
    • promote_price:活动价(可为空,表示沿用商品促销价)
    • limit_per_order:单次限购
    • priority:优先级(数值越小优先级越高)
    • is_override:是否覆盖商品促销价
    • created_at/updated_at:时间戳
  • 索引建议
    • (promotion_id, product_id) 唯一约束,避免重复
    • (product_id, priority) 用于商品维度活动排序

商品促销字段与时间迁移

  • 现状
    • 多张商品/套餐表包含促销价与促销时间字段:promote_price、promote_start_time、promote_end_time。
    • 部分模块已将时间字段从整型时间戳迁移为 DATETIME(promote_start_at/promote_end_at),提升可读性与查询效率。
  • 影响
    • 列表/详情页通过定价服务读取促销价与时间,判断是否在有效期内并展示活动价。
  • 建议
    • 统一采用 promote_start_at/promote_end_at 的 DATETIME 字段,便于范围查询与索引优化。
    • 对促销价与时间建立联合索引,加速“进行中活动商品”的检索。

价格计算与活动生效流程

  • 流程要点
    • 商品列表/详情调用定价服务计算 salePrice。
    • 定价服务读取商品基础价与促销价,并结合时间范围判断是否生效。
    • 若存在活动商品关联表,则根据优先级与覆盖策略选择最终活动价。
  • 可视化流程
    flowchart TD
    Start(["进入价格计算"]) --> ReadBase["读取商品基础价/促销价/时间"]
    ReadBase --> CheckActive{"是否在活动时间内?"}
    CheckActive -- 否 --> UseBase["使用基础价或会员价"]
    CheckActive -- 是 --> LoadRules["加载活动规则优先级/覆盖"]
    LoadRules --> ApplyPromo["应用活动价/折扣"]
    ApplyPromo --> Finalize["输出最终售价"]
    UseBase --> Finalize
    Finalize --> End(["结束"])

折扣规则与限购策略(参考优惠券)

  • 折扣规则
    • 支持按订单金额门槛、百分比/固定面额、最大减免额度等计算。
    • 有效期校验:仅当当前时间在活动有效期内且状态启用时生效。
  • 限购策略
    • 可在活动主表设置每人限购与总量限制;在关联表中设置单次限购。
    • 下单时需校验剩余库存与限购计数,防止超卖。
  • 参考实现
    • 优惠券服务展示了有效期、条件、上限的综合折扣计算逻辑,可复用至活动折扣。

活动状态管理与库存扣减

  • 状态管理
    • 活动状态:草稿/预热/进行中/已结束/已取消。
    • 通过 start_at/end_at 与 status 组合控制活动可见性与可用性。
  • 库存扣减
    • 下单时锁定库存,支付成功后正式扣减;超时未支付释放库存。
    • 对于限量活动,需维护活动维度的已售数量与剩余库存。
  • 并发控制
    • 使用数据库行级锁或乐观锁(版本号)保证库存一致性。
    • 高并发场景引入队列异步处理库存扣减与活动统计。

依赖关系分析

  • 商品表与定价服务
    • 商品表提供基础价与促销价;定价服务负责综合计算最终售价。
  • 活动主表与关联表
    • 活动主表定义全局规则;关联表细化到商品级别的价格与限购。
  • 优惠券服务
    • 提供折扣计算与有效期校验的参考实现,可与活动折扣合并或叠加。
graph LR
P["商品表"] --> S["定价服务"]
A["活动主表"] --> R["活动商品关联表"]
R --> S
C["优惠券服务"] --> S

性能考虑

  • 索引优化
    • 对促销价与时间字段建立联合索引,加速“进行中活动商品”的查询。
    • 对活动范围(scope_type, scope_id)建立索引,提升范围匹配效率。
  • 查询优化
    • 使用分页与只读副本分担读压力。
    • 将高频查询结果缓存至 Redis,减少数据库压力。
  • 写入优化
    • 批量更新活动状态与统计指标,减少频繁写库。
    • 使用事务与重试机制确保数据一致性。
  • 监控与告警
    • 对慢查询与热点表进行监控,及时扩容或优化。

故障排查指南

  • 常见问题
    • 活动未生效:检查 start_at/end_at 与 status 是否正确。
    • 价格异常:确认定价服务是否正确读取促销价与活动规则。
    • 库存超卖:检查库存扣减逻辑与并发控制是否到位。
  • 排查步骤
    • 核对活动主表与关联表数据一致性。
    • 查看定价服务日志与数据库查询执行计划。
    • 验证优惠券/活动折扣叠加逻辑是否符合预期。

结论

  • 通过“活动主表 + 活动商品关联表 + 商品促销字段 + 定价服务 + 优惠券折扣”的组合,可实现灵活、可扩展的促销活动体系。
  • 建议统一采用 DATETIME 类型的促销时间字段,提升可读性与查询效率。
  • 在高并发场景下,应重视库存一致性、缓存策略与监控告警,保障系统稳定性。

附录

  • 数据模型图(概念)
    erDiagram
    DOU_PROMOTION {
    int id PK
    varchar name
    enum type
    tinyint status
    datetime start_at
    datetime end_at
    json scope
    decimal budget
    int limit_per_user
    int limit_total
    datetime created_at
    datetime updated_at
    }
    DOU_PROMOTION_PRODUCT {
    int id PK
    int promotion_id FK
    int product_id FK
    decimal promote_price
    int limit_per_order
    tinyint priority
    tinyint is_override
    datetime created_at
    datetime updated_at
    }
    PRODUCT {
    int id PK
    decimal price
    decimal promote_price
    datetime promote_start_at
    datetime promote_end_at
    }
    DOU_PROMOTION ||--o{ DOU_PROMOTION_PRODUCT : "包含"
    PRODUCT ||--o{ DOU_PROMOTION_PRODUCT : "被关联"
添加日期:2026-10-05