You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在线药店网站灵活折扣系统实现:需求与技术疑问咨询

在线药店折扣/优惠系统设计方案

一、需求梳理

你需要实现的折扣系统包含以下类型:

  • 指定商品百分比折扣(如指定药品享20%优惠)
  • 买X赠Y活动
  • 品类专属折扣(如所有维生素享10%优惠)
  • 优惠券代码(如SAVE10)
  • 限时优惠(含开始与结束日期)

折扣需在Product page、Cart、Invoice三个页面正确展示。

二、核心疑问解答

1. 优惠系统的最佳数据库结构设计方案

采用分层+类型区分的设计,核心表结构如下:

主表:discounts(优惠主信息)

字段名类型说明
idINT(11)主键,优惠ID
discount_typeVARCHAR(50)优惠类型:PERCENT_PRODUCT(指定商品折扣)、BUY_X_GET_Y(买赠)、CATEGORY_PERCENT(品类折扣)、COUPON(优惠券)
nameVARCHAR(100)优惠名称(如"维生素10%折扣")
descriptionTEXT优惠描述
start_dateDATETIME开始时间(限时优惠必填)
end_dateDATETIME结束时间(限时优惠必填)
is_activeTINYINT(1)是否启用
priorityINT(11)优惠优先级(解决冲突时用,数值越高优先级越高)
exclusive_groupVARCHAR(50)互斥组标识(同一组内优惠只能选一个)

关联表(按类型拆分,避免冗余)

  • 指定商品/品类折扣表discount_product_category

    字段名类型说明
    discount_idINT(11)关联discounts.id
    target_typeVARCHAR(20)目标类型:PRODUCT(指定商品)、CATEGORY(品类)
    target_idINT(11)商品ID/品类ID
    discount_valueDECIMAL(5,2)折扣百分比(如20代表20%)
  • 买赠活动表discount_buy_x_get_y

    字段名类型说明
    discount_idINT(11)关联discounts.id
    buy_product_idINT(11)需购买的商品ID
    buy_quantityINT(11)需购买的数量
    get_product_idINT(11)赠送的商品ID
    get_quantityINT(11)赠送的数量
    max_getINT(11)单次订单最多赠送数量(可选)
  • 优惠券表discount_coupon

    字段名类型说明
    discount_idINT(11)关联discounts.id
    coupon_codeVARCHAR(50)优惠券代码(如SAVE10)
    discount_valueDECIMAL(10,2)折扣值(可以是百分比或固定金额,需结合类型判断)
    discount_modeVARCHAR(20)折扣模式:PERCENT(百分比)、FIXED(固定金额)
    min_order_amountDECIMAL(10,2)最低订单金额限制(可选)
    usage_limitINT(11)总使用次数限制(可选)
    user_usage_limitINT(11)单用户使用次数限制(可选)

订单关联表order_discounts

记录订单实际使用的优惠,用于对账和发票展示:

字段名类型说明
idINT(11)主键
order_idINT(11)关联订单ID
discount_idINT(11)关联discounts.id
discount_amountDECIMAL(10,2)实际抵扣金额
detailsTEXT优惠使用详情(如"买2赠1:赠送XX药品1盒")

2. 折扣计算应在前端还是后端执行?

核心计算必须在后端执行,前端仅做展示和预计算:

  • 后端:负责所有优惠规则校验、计算逻辑、最终金额确认,确保数据安全,避免前端篡改金额。比如优惠券有效性、限时优惠时间判断、买赠规则匹配等,都必须在后端完成。
  • 前端:仅做用户友好的预展示,比如商品页显示当前可享的折扣、购物车实时展示预估优惠金额,但最终提交订单时必须以后端返回的计算结果为准。

3. 如何避免多种优惠之间的冲突?

通过优先级+互斥规则解决:

  1. 优先级判断:根据discounts表的priority字段,数值越高优先级越高,优先应用高优先级优惠。比如优惠券优先级高于品类折扣,品类折扣高于指定商品折扣。
  2. 互斥组限制:同一exclusive_group下的优惠只能选一个,比如"全场8折优惠券"和"品类10%折扣"属于同一互斥组,用户只能二选一。
  3. 明确叠加规则:提前定义允许叠加的优惠类型,比如:
    • 允许叠加:指定商品折扣 + 买赠活动(买指定打折商品同时享受买赠)
    • 禁止叠加:优惠券 + 品类折扣(同一订单只能用一种)
  4. 计算顺序控制:先匹配所有符合条件的优惠,再按优先级排序,处理互斥逻辑,最后计算最终金额。

4. 如何构建清晰且可扩展的优惠逻辑架构?

采用策略模式+规则管理器的架构:

  1. 抽象优惠策略接口:定义统一的DiscountStrategy接口,包含isEligible()(判断订单是否符合优惠条件)、calculateDiscount()(计算折扣金额)、applyToOrder()(将优惠应用到订单)三个核心方法。
  2. 按类型实现策略类:
    • PercentProductDiscountStrategy:处理指定商品百分比折扣
    • BuyXGetYDiscountStrategy:处理买赠活动
    • CategoryPercentDiscountStrategy:处理品类折扣
    • CouponDiscountStrategy:处理优惠券
  3. 优惠规则管理器:负责加载所有可用优惠策略、根据订单信息匹配符合条件的优惠、处理优先级和互斥逻辑、计算最终优惠金额。
  4. 可扩展设计:新增优惠类型时,只需新增对应的策略类并注册到管理器即可,无需修改核心逻辑。比如未来要加"满减优惠",只需实现FullReductionDiscountStrategy即可。

业务层分层设计:

  • 数据访问层(DAO):负责数据库交互,获取优惠配置
  • 业务逻辑层(Service):调用规则管理器处理优惠计算
  • 控制器层(Controller):接收前端请求,返回计算结果

内容的提问来源于stack exchange,提问作者منصور انور

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.11 13:05:03