소스 검색

营销活动相关代码提交·

yjwang 10 시간 전
부모
커밋
d0159c6b70

+ 3 - 3
.env.prod-bjyjb

@@ -1,9 +1,9 @@
 # 页面标题
-VUE_APP_TITLE =医健宝医药管理系统
+VUE_APP_TITLE =鸿良
 # 首页菜单标题
-VUE_APP_TITLE_INDEX =医健宝医药
+VUE_APP_TITLE_INDEX =鸿良
 # 公司名称
-VUE_APP_COMPANY_NAME =医健宝智慧(北京)医药科技有限公司
+VUE_APP_COMPANY_NAME =鸿良
 # ICP备案号
 VUE_APP_ICP_RECORD =京ICP备2025133930号-2
 # ICP网站访问地址

+ 70 - 0
docs/miniapp-store-promotion-api-flow.md

@@ -0,0 +1,70 @@
+# 小程序满减/折扣 — 对接说明
+
+> 基础路径:`/store/app/storeOrder`  
+> **无需新增接口、无需新增请求/响应字段**,沿用原有 `confirm` → `computed` → `create` → 支付。
+
+---
+
+## 流程
+
+```
+confirm → computed → create → 支付
+```
+
+后端在 **`computed` / `create` 内部**按购物车商品 + 活动表配置**自动匹配**满减/折扣,直接体现在 `payPrice` 里。
+
+---
+
+## 前端
+
+与改造前完全一致,**不用传活动 ID**,**不用调** `/promotion/list` 等接口。
+
+```javascript
+// 算价
+const res = await computed({
+  orderKey,
+  addressId,
+  useIntegral,
+  couponUserId,
+})
+this.payPrice = res.data.payPrice
+
+// 下单
+await create({ orderKey, addressId, payType, useIntegral, couponUserId, mark })
+```
+
+多店仍用 `confirmMultiStore` → `computedMultiStore` → `createMultiStore`,参数不变。
+
+---
+
+## 自动匹配规则(后端)
+
+`IFsStorePromotionComputeService.autoApplyBestPromotion`:
+
+| 活动表配置 | 处理 |
+|-----------|------|
+| `manual_status=1` 且时间在有效期内 | 才参与 |
+| `scope_type` 1/2/3 | 全场 / 分类 / 指定商品 |
+| `tier_type` 1 | 金额满减(可 `is_capped` 上不封顶) |
+| `tier_type` 2 | 件数折扣 |
+| `limit_per_user` | 仅统计已支付 usage |
+| `is_stackable=0` | 已选优惠券时跳过该活动 |
+
+在可用活动中取**优惠金额最大**的一条,扣减顺序:**积分 → 满减 → 优惠券**。
+
+---
+
+## 代码位置
+
+| 模块 | 类 |
+|------|-----|
+| 小程序入口 | `fs-user-app` → `StoreOrderScrmAmountService` |
+| 算价扣减 | `FsStoreOrderScrmServiceImpl.subtractAutoPromotionDiscount` |
+| 自动匹配 | `FsStorePromotionComputeServiceImpl.autoApplyBestPromotion` |
+| 下单落库 | `createOrder` 写订单 `promotion_*` + usage |
+
+---
+
+## 前置条件
+
+执行 `docs/sql/fs_store_promotion_init.sql`(活动表 + 订单扩展字段)。

+ 42 - 19
docs/multi-store-tiered-promotion-design.md

@@ -19,13 +19,33 @@
 | 管理端 Controller | ✅ 已完成 | `fs-admin/.../FsStorePromotionController.java` |
 | 管理端 API | ✅ 已完成 | `src/api/hisStore/storePromotion.js` |
 | 管理端列表 + 新增/编辑/详情 | ✅ 已完成 | `src/views/hisStore/storePromotion/index.vue`(Dialog 模式) |
-| 用户端 settlement 查询接口 | ⬜ 未做 | `POST /store/app/storeOrder/promotion/list` 等(见 5.2.1) |
-| 订单 computed/create 满减 | ⬜ 未做 | `FsStoreOrderScrmServiceImpl` |
-| APP / 小程序结算页 | ⬜ 未做 | 见 1.4 节 |
-| usage 支付联动 / 定时 Job / Redis 缓存 | ⬜ 未做 | 见第 6 章 |
+| 用户端 settlement 查询接口 | ⚪ 可选 | `/promotion/list` 仅展示规则;算价不依赖 |
+| 活动金额/件数折扣计算 Service | ✅ 已完成 | `autoApplyBestPromotion` 自动匹配最优活动 |
+| 订单 computed/create 满减 | ✅ 已接入 | computed/create 自动扣减 + 写订单 + usage |
+| APP / 小程序结算页 | ⬜ 未做 | 只需调 computed/create,见 `miniapp-store-promotion-api-flow.md` |
+| usage 支付联动 / 定时 Job / Redis 缓存 | ⚠️ 部分完成 | payConfirm 确认 usage ✅;cancelOrder 回滚 ✅ |
 
 **图例**:✅ 已完成 ⬜ 未做
 
+### 用户端活动计算规则(v1.2.1 已实现)
+
+实现类:`fs-service/.../support/FsStorePromotionTierCalculator.java`,由 `FsStorePromotionComputeServiceImpl` 调用。
+
+| 阶梯类型 `tier_type` | 门槛依据 | 优惠计算 |
+|---------------------|---------|---------|
+| **1 金额** | 当前店铺购物车中**活动适用商品**金额小计(`price × cartNum` 累加) | 按档位 `threshold_amount`(满 X 元)匹配最高档,优惠 = 该档 `discount_amount`(减 Y 元);`is_capped=1` 时超出末档部分按末档规则循环减(上不封顶) |
+| **2 折扣** | 当前店铺购物车中**活动适用商品**件数合计 | 按档位 `threshold_amount`(满 X **件**,取整)匹配最高档,优惠 = 适用商品金额 × (1 − 折扣/10),如 8.5 折即 `eligibleAmount × 0.15` |
+
+**限购**:`fs_store_promotion_usage` 中 `usage_status=1` 计数,与 `limit_per_user` 比较;`limit_per_user=0` 不限。
+
+**叠加券**:`is_stackable=0` 且请求带 `couponUserId` 时活动标记不可用。
+
+**接口**:
+
+- `POST /store/app/storeOrder/promotion/list` — 单店可用活动列表 + 预估优惠
+- `POST /store/app/storeOrder/promotion/listMultiStore` — 多店
+- `POST /store/app/storeOrder/promotion/compute` — 选中活动精确计算优惠金额
+
 ---
 
 ## 0. 评审结论与实施计划
@@ -68,12 +88,9 @@
 ```
 购物车确认 → confirmOrder / confirmOrderMultiStore
      ↓  返回 orderKey、carts、address
-结算页进入 → POST /store/app/storeOrder/promotion/list(或 listMultiStore)★新增
-     ↓  返回当前店铺可参与的满减活动列表 + 推荐活动 + 档位说明
-     ↓  用户选择活动(或采用推荐活动;可不选=不参与满减)
 结算页计算 → POST /store/app/storeOrder/computed(或 computedMultiStore)
-     ↓  传 promotionActivityId + 现有 couponUserId / useIntegral
-     ↓  查即验证 → 计算满减 → 返回 payPrice、promotionDiscountAmount 等
+     ↓  服务端按商品+活动配置**自动匹配最优满减**,无需用户选活动、无需传 promotionActivityId
+     ↓  返回 payPrice、promotionDiscountAmount、promotionTitle 等
 提交订单 → POST /store/app/storeOrder/create(或 createMultiStore)
      ↓  服务端重算 → 写 fs_store_order_scrm.promotion_* → usage 待支付
 ```
@@ -1657,20 +1674,26 @@ fs-admin/src/main/java/com/fs/hisStore/controller/
 fs-service/src/main/java/com/fs/hisStore/
 ├── domain/ ...(同前)
 ├── param/
-│   ├── FsStorePromotionListParam.java           ← 结算页 list 入参
-│   ├── FsStorePromotionListMultiStoreParam.java
-│   └── PromotionStoreActivityParam.java         ← 多店选中活动
+│   ├── FsStorePromotionListParam.java           ← ✅ 结算页 list 入参
+│   ├── FsStorePromotionListMultiStoreParam.java ← ✅
+│   ├── FsStorePromotionComputeParam.java        ← ✅ 选中活动计算入参
+│   └── PromotionStoreActivityParam.java         ← 多店选中活动(computed/create 扩展待做)
 ├── vo/
-│   ├── FsStorePromotionListVO.java
-│   └── FsStorePromotionActivityItemVO.java
+│   ├── FsStorePromotionListVO.java              ← ✅
+│   ├── FsStorePromotionActivityItemVO.java      ← ✅
+│   ├── FsStorePromotionComputeResultVO.java     ← ✅
+│   ├── FsStorePromotionTierItemVO.java          ← ✅
+│   └── FsStorePromotionTierMatchVO.java         ← ✅
+├── support/
+│   └── FsStorePromotionTierCalculator.java      ← ✅ 金额满减/件数折扣纯计算
 ├── service/
-│   ├── IFsStorePromotionComputeService.java     ← list + 计算共用
-│   └── impl/FsStorePromotionComputeServiceImpl.java
+│   ├── IFsStorePromotionComputeService.java     ← list + 计算共用
+│   └── impl/FsStorePromotionComputeServiceImpl.java ← ✅
 └── ...
 
-fs-service/.../FsStoreOrderScrmServiceImpl.java  ← computedOrder / createOrder 调用 ComputeService
+fs-service/.../FsStoreOrderScrmServiceImpl.java  ← ✅ computedOrder / computedOrderMultiStore 已接入满减;createOrder 待扩展
 
-fs-user-app/.../StoreOrderScrmController.java    ← 新增 promotion/list、listMultiStore;扩展 computed/create
+fs-user-app/.../StoreOrderScrmController.java    ← ✅ promotion/list、listMultiStore、compute
 ```
 
 **用户端 uni-app(APP / 小程序,工程路径以各环境仓库为准)**:
@@ -1737,4 +1760,4 @@ public enum PromotionDisplayStatusEnum {
 
 ---
 
-> **文档结束** — v1.2.1 管理端后台已实现;用户端与下单链路见「实现进度追踪」待办项
+> **文档结束** — v1.2.1 管理端后台已实现;用户端 settlement 查询与活动计算已实现(`promotion/list`、`listMultiStore`、`compute`);订单 computed/create 满减联动待扩展

+ 27 - 1
docs/sql/fs_store_promotion_init.sql

@@ -21,6 +21,7 @@ CREATE TABLE IF NOT EXISTS `fs_store_promotion_activity` (
   `start_time` DATETIME NOT NULL COMMENT '活动开始时间',
   `end_time` DATETIME NOT NULL COMMENT '活动结束时间',
   `scope_type` TINYINT(2) NOT NULL DEFAULT 1 COMMENT '适用范围:1全场 2指定分类 3指定商品',
+  `tier_type` TINYINT(2) NOT NULL DEFAULT 1 COMMENT '阶梯类型:1金额 2折扣',
   `is_stackable` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否可叠加优惠券:0否 1是',
   `is_capped` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否上不封顶:0否 1是',
   `limit_per_user` INT(11) NOT NULL DEFAULT 0 COMMENT '每人限参与次数,0=不限',
@@ -45,7 +46,7 @@ CREATE TABLE IF NOT EXISTS `fs_store_promotion_tier` (
   `activity_id` BIGINT(20) NOT NULL COMMENT '活动ID',
   `sort_order` INT(11) NOT NULL DEFAULT 1 COMMENT '档位序号',
   `threshold_amount` DECIMAL(10,2) NOT NULL COMMENT '门槛金额(元)',
-  `discount_amount` DECIMAL(10,2) NOT NULL COMMENT '减扣金额(元)',
+  `discount_amount` DECIMAL(10,2) NOT NULL COMMENT '减扣金额(元)/折扣(折),含义由活动 tier_type 决定',
   `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
   `update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
   PRIMARY KEY (`id`),
@@ -141,6 +142,31 @@ PREPARE stmt FROM @sql_add_promotion_discount_amount;
 EXECUTE stmt;
 DEALLOCATE PREPARE stmt;
 
+-- ============================================================
+-- 二点五、活动主表 tier_type 字段(旧库增量,可重复执行)
+-- 说明:CREATE TABLE IF NOT EXISTS 不会给已存在的表加新字段,旧环境必须执行本段
+-- ============================================================
+
+SET @sql_add_tier_type = (
+  SELECT IF(
+    EXISTS(
+      SELECT 1 FROM information_schema.COLUMNS
+      WHERE TABLE_SCHEMA = @db_name
+        AND TABLE_NAME = 'fs_store_promotion_activity'
+        AND COLUMN_NAME = 'tier_type'
+    ),
+    'SELECT ''skip: tier_type exists'' AS msg',
+    'ALTER TABLE `fs_store_promotion_activity` ADD COLUMN `tier_type` TINYINT(2) NOT NULL DEFAULT 1 COMMENT ''阶梯类型:1金额 2折扣'' AFTER `scope_type`'
+  )
+);
+PREPARE stmt FROM @sql_add_tier_type;
+EXECUTE stmt;
+DEALLOCATE PREPARE stmt;
+
+UPDATE `fs_store_promotion_activity`
+SET `tier_type` = 1
+WHERE `tier_type` IS NULL OR `tier_type` = 0;
+
 -- ============================================================
 -- 三、参与记录表索引补全(旧库若已建表但缺 idx_usage_time 可执行)
 -- ============================================================

+ 46 - 0
docs/sql/fs_store_promotion_tier_type.sql

@@ -0,0 +1,46 @@
+-- ============================================================
+-- 阶梯满减活动 - 新增阶梯类型字段 tier_type(增量,可重复执行)
+--
+-- 注意:
+--   1. 请先 USE 你的业务库,再执行本脚本(否则 DATABASE() 为空会导致判断失效)
+--   2. 若之前只执行过 fs_store_promotion_init.sql 的建表段,旧表不会自动加字段,必须执行本脚本
+--   3. 执行后请运行文末「验证 SQL」确认字段已存在
+-- ============================================================
+
+USE `你的数据库名`;  -- ★ 请改成实际库名,或客户端里先选中数据库后删除本行
+
+SET @db_name = DATABASE();
+
+-- 1. 活动主表新增 tier_type(单行 ALTER,避免 PREPARE 多行语句兼容问题)
+SET @sql_add_tier_type = (
+  SELECT IF(
+    EXISTS(
+      SELECT 1 FROM information_schema.COLUMNS
+      WHERE TABLE_SCHEMA = @db_name
+        AND TABLE_NAME = 'fs_store_promotion_activity'
+        AND COLUMN_NAME = 'tier_type'
+    ),
+    'SELECT ''skip: tier_type exists'' AS msg',
+    'ALTER TABLE `fs_store_promotion_activity` ADD COLUMN `tier_type` TINYINT(2) NOT NULL DEFAULT 1 COMMENT ''阶梯类型:1金额 2折扣'' AFTER `scope_type`'
+  )
+);
+PREPARE stmt FROM @sql_add_tier_type;
+EXECUTE stmt;
+DEALLOCATE PREPARE stmt;
+
+-- 2. 历史数据默认金额阶梯
+UPDATE `fs_store_promotion_activity`
+SET `tier_type` = 1
+WHERE `tier_type` IS NULL OR `tier_type` = 0;
+
+-- 3. 档位表字段注释(表结构不变)
+ALTER TABLE `fs_store_promotion_tier`
+  MODIFY COLUMN `threshold_amount` DECIMAL(10,2) NOT NULL COMMENT '门槛金额(元)',
+  MODIFY COLUMN `discount_amount` DECIMAL(10,2) NOT NULL COMMENT '减扣金额(元)/折扣(折),含义由活动 tier_type 决定';
+
+-- ============================================================
+-- 验证 SQL(执行后应能看到 tier_type 一行)
+-- ============================================================
+-- SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, COLUMN_TYPE, COLUMN_DEFAULT, COLUMN_COMMENT
+-- FROM information_schema.COLUMNS
+-- WHERE TABLE_NAME = 'fs_store_promotion_activity' AND COLUMN_NAME = 'tier_type';

+ 85 - 12
src/views/hisStore/storePromotion/index.vue

@@ -44,6 +44,9 @@
         </template>
       </el-table-column>
       <el-table-column label="档数" align="center" prop="tierCount" width="60"/>
+      <el-table-column label="阶梯类型" align="center" width="90">
+        <template slot-scope="scope">{{ scope.row.tierTypeLabel || (scope.row.tierType === 2 ? '折扣' : '金额') }}</template>
+      </el-table-column>
       <el-table-column label="上不封顶" align="center" width="80">
         <template slot-scope="scope">
           <el-tag size="mini" :type="scope.row.isCapped === 1 ? 'success' : 'info'">{{ scope.row.isCapped === 1 ? '是' : '否' }}</el-tag>
@@ -112,18 +115,51 @@
             <span>满减阶梯</span>
             <el-button v-if="!tierLocked" style="float: right; padding: 3px 0" type="text" @click="addTier">+ 添加一档</el-button>
           </div>
+          <el-form-item label="阶梯类型" prop="tierType">
+            <el-radio-group v-model="form.tierType" :disabled="tierLocked" @change="handleTierTypeChange">
+              <el-radio :label="1">金额</el-radio>
+              <el-radio :label="2">折扣</el-radio>
+            </el-radio-group>
+            <span class="tip-text">{{ form.tierType === 2 ? '满X件打Y折' : '满X元减Y元' }}</span>
+          </el-form-item>
           <el-table :data="form.tiers" border size="mini">
             <el-table-column label="档位" width="60" align="center">
               <template slot-scope="scope">{{ scope.$index + 1 }}</template>
             </el-table-column>
-            <el-table-column label="满(元)" align="center">
+            <el-table-column :label="form.tierType === 2 ? '满(件)' : '满(元)'" align="center">
               <template slot-scope="scope">
-                <el-input-number v-model="scope.row.thresholdAmount" :min="0.01" :precision="2" :disabled="tierLocked" controls-position="right" style="width: 100%"/>
+                <el-input-number
+                  v-model="scope.row.thresholdAmount"
+                  :min="form.tierType === 2 ? 1 : 0.01"
+                  :precision="form.tierType === 2 ? 0 : 2"
+                  :disabled="tierLocked"
+                  controls-position="right"
+                  style="width: 100%"
+                />
               </template>
             </el-table-column>
-            <el-table-column label="减(元)" align="center">
+            <el-table-column :label="form.tierType === 2 ? '折扣(折)' : '减(元)'" align="center">
               <template slot-scope="scope">
-                <el-input-number v-model="scope.row.discountAmount" :min="0.01" :precision="2" :disabled="tierLocked" controls-position="right" style="width: 100%"/>
+                <el-input-number
+                  v-if="form.tierType === 2"
+                  v-model="scope.row.discountAmount"
+                  :min="0.1"
+                  :max="9.9"
+                  :step="0.1"
+                  :precision="1"
+                  :disabled="tierLocked"
+                  controls-position="right"
+                  style="width: 100%"
+                />
+                <el-input-number
+                  v-else
+                  v-model="scope.row.discountAmount"
+                  :min="0.01"
+                  :precision="2"
+                  :disabled="tierLocked"
+                  controls-position="right"
+                  style="width: 100%"
+                />
               </template>
             </el-table-column>
             <el-table-column label="操作" width="70" align="center" v-if="!tierLocked">
@@ -132,7 +168,7 @@
               </template>
             </el-table-column>
           </el-table>
-          <el-form-item label="上不封顶" style="margin-top: 12px">
+          <el-form-item v-if="form.tierType === 1" label="上不封顶" style="margin-top: 12px">
             <el-switch v-model="form.isCapped" :active-value="1" :inactive-value="0"/>
           </el-form-item>
         </el-card>
@@ -193,19 +229,24 @@
         <el-descriptions-item label="状态">{{ detail.displayStatusLabel }}</el-descriptions-item>
         <el-descriptions-item label="开始时间">{{ parseTime(detail.startTime) }}</el-descriptions-item>
         <el-descriptions-item label="结束时间">{{ parseTime(detail.endTime) }}</el-descriptions-item>
+        <el-descriptions-item label="阶梯类型">{{ detail.tierTypeLabel || (detail.tierType === 2 ? '折扣' : '金额') }}</el-descriptions-item>
         <el-descriptions-item label="适用范围">{{ detail.scopeTypeLabel }}</el-descriptions-item>
         <el-descriptions-item label="每人限次">{{ detail.limitPerUser === 0 ? '不限' : detail.limitPerUser }}</el-descriptions-item>
-        <el-descriptions-item label="上不封顶">{{ detail.isCapped === 1 ? '是' : '否' }}</el-descriptions-item>
+        <el-descriptions-item label="上不封顶">{{ detail.tierType === 2 ? '-' : (detail.isCapped === 1 ? '是' : '否') }}</el-descriptions-item>
         <el-descriptions-item label="叠加优惠券">{{ detail.isStackable === 1 ? '是' : '否' }}</el-descriptions-item>
         <el-descriptions-item v-if="detail.remark" label="备注" :span="2">{{ detail.remark }}</el-descriptions-item>
       </el-descriptions>
 
       <div v-if="detail && detail.tiers && detail.tiers.length" class="detail-block">
-        <div class="detail-block-title">满减阶梯</div>
+        <div class="detail-block-title">{{ detail.tierType === 2 ? '折扣阶梯' : '满减阶梯' }}</div>
         <el-table :data="detail.tiers" border size="mini">
           <el-table-column label="档位" prop="sortOrder" width="60" align="center"/>
-          <el-table-column label="满(元)" prop="thresholdAmount" align="center"/>
-          <el-table-column label="减(元)" prop="discountAmount" align="center"/>
+          <el-table-column :label="detail.tierType === 2 ? '满(件)' : '满(元)'" prop="thresholdAmount" align="center"/>
+          <el-table-column :label="detail.tierType === 2 ? '折扣(折)' : '减(元)'" align="center">
+            <template slot-scope="scope">
+              {{ formatTierDiscountValue(scope.row.discountAmount, detail.tierType) }}
+            </template>
+          </el-table-column>
         </el-table>
       </div>
 
@@ -292,7 +333,8 @@ export default {
         storeId: [{ required: true, message: '请选择店铺', trigger: 'change' }],
         startTime: [{ required: true, message: '请选择开始时间', trigger: 'change' }],
         endTime: [{ required: true, message: '请选择结束时间', trigger: 'change' }],
-        scopeType: [{ required: true, message: '请选择适用类型', trigger: 'change' }]
+        scopeType: [{ required: true, message: '请选择适用类型', trigger: 'change' }],
+        tierType: [{ required: true, message: '请选择阶梯类型', trigger: 'change' }]
       }
     }
   },
@@ -321,6 +363,27 @@ export default {
       if (!time) return ''
       return time
     },
+    formatTierDiscountValue(value, tierType) {
+      if (value == null || value === '') {
+        return '-'
+      }
+      return Number(tierType) === 2 ? value + '折' : value
+    },
+    getDefaultTiers(tierType) {
+      if (Number(tierType) === 2) {
+        return [{ sortOrder: 1, thresholdAmount: 3, discountAmount: 9.5 }]
+      }
+      return [{ sortOrder: 1, thresholdAmount: 199, discountAmount: 30 }]
+    },
+    handleTierTypeChange() {
+      if (this.tierLocked) {
+        return
+      }
+      this.form.tiers = this.getDefaultTiers(this.form.tierType)
+      if (Number(this.form.tierType) === 2) {
+        this.form.isCapped = 0
+      }
+    },
     displayStatusTag(status) {
       const map = { 0: 'info', 1: 'warning', 2: 'success', 3: 'info', 4: 'danger' }
       return map[status] || 'info'
@@ -468,12 +531,13 @@ export default {
         startTime: null,
         endTime: null,
         scopeType: 1,
+        tierType: 1,
         scopeIds: [],
         isStackable: 1,
         isCapped: 0,
         limitPerUser: 0,
         remark: null,
-        tiers: [{ sortOrder: 1, thresholdAmount: 199, discountAmount: 30 }]
+        tiers: this.getDefaultTiers(1)
       }
       this.activeEditing = false
       this.productOptions = []
@@ -504,6 +568,7 @@ export default {
           startTime: data.startTime,
           endTime: data.endTime,
           scopeType: data.scopeType,
+          tierType: data.tierType == null ? 1 : data.tierType,
           scopeIds: data.scopeIds || [],
           isStackable: data.isStackable,
           isCapped: data.isCapped,
@@ -513,7 +578,7 @@ export default {
             sortOrder: t.sortOrder,
             thresholdAmount: t.thresholdAmount,
             discountAmount: t.discountAmount
-          })) : [{ sortOrder: 1, thresholdAmount: 199, discountAmount: 30 }]
+          })) : this.getDefaultTiers(data.tierType == null ? 1 : data.tierType)
         }
         this.activeEditing = data.displayStatus === 2
         if (data.scopeType === 3 && data.scopeProducts && data.scopeProducts.length) {
@@ -544,6 +609,14 @@ export default {
         return
       }
       const last = this.form.tiers[this.form.tiers.length - 1]
+      if (Number(this.form.tierType) === 2) {
+        this.form.tiers.push({
+          sortOrder: this.form.tiers.length + 1,
+          thresholdAmount: last ? Number(last.thresholdAmount) + 1 : 3,
+          discountAmount: last ? Math.max(Number(last.discountAmount) - 0.5, 0.1) : 9.5
+        })
+        return
+      }
       this.form.tiers.push({
         sortOrder: this.form.tiers.length + 1,
         thresholdAmount: last ? Number(last.thresholdAmount) + 100 : 100,