|
@@ -1,161 +1,242 @@
|
|
|
<template>
|
|
<template>
|
|
|
- <div class="app-container">
|
|
|
|
|
- <el-card shadow="never">
|
|
|
|
|
- <div slot="header" class="clearfix">
|
|
|
|
|
- <span class="card-title">
|
|
|
|
|
- <i class="el-icon-s-cooperation"></i>
|
|
|
|
|
- 发放积分规则配置
|
|
|
|
|
- </span>
|
|
|
|
|
- <span style="font-size: 13px; color: #909399; margin-left: 12px;">配置消费送积分体系规则</span>
|
|
|
|
|
|
|
+ <div class="app-container points-rule">
|
|
|
|
|
+ <el-card shadow="never" class="main-card">
|
|
|
|
|
+ <!-- 头部 -->
|
|
|
|
|
+ <div slot="header" class="card-header">
|
|
|
|
|
+ <div class="header-left">
|
|
|
|
|
+ <span class="header-icon-bg">
|
|
|
|
|
+ <i class="el-icon-s-cooperation"></i>
|
|
|
|
|
+ </span>
|
|
|
|
|
+ <div class="header-text">
|
|
|
|
|
+ <span class="header-title">发放积分规则配置</span>
|
|
|
|
|
+ <span class="header-sub">消费送积分体系规则管理</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <el-tag :type="form.enabled === 1 ? 'success' : 'info'" size="small" effect="plain">
|
|
|
|
|
+ {{ form.enabled === 1 ? '已启用' : '已禁用' }}
|
|
|
|
|
+ </el-tag>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
- <el-form ref="form" :model="form" :rules="rules" label-width="160px" size="small">
|
|
|
|
|
- <!-- 1. 积分比例 -->
|
|
|
|
|
- <el-divider content-position="left">
|
|
|
|
|
- <i class="el-icon-coin"></i> 积分比例配置
|
|
|
|
|
- </el-divider>
|
|
|
|
|
- <el-form-item label="积分发放比例" prop="rate">
|
|
|
|
|
- <el-col :span="6">
|
|
|
|
|
- <el-input-number
|
|
|
|
|
- v-model="form.rate"
|
|
|
|
|
- :precision="2"
|
|
|
|
|
- :min="0.01"
|
|
|
|
|
- :max="9999"
|
|
|
|
|
- :step="0.1"
|
|
|
|
|
- style="width: 100%;"
|
|
|
|
|
- />
|
|
|
|
|
- </el-col>
|
|
|
|
|
- <span class="form-tip">1元 = {{ form.rate || 0 }} 积分</span>
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
|
|
+ <el-form ref="form" :model="form" :rules="rules" label-width="150px" size="small">
|
|
|
|
|
+ <!-- 1. 积分发放比例 -->
|
|
|
|
|
+ <div class="section-block section-earn">
|
|
|
|
|
+ <div class="section-header">
|
|
|
|
|
+ <span class="section-icon earn"><i class="el-icon-coin"></i></span>
|
|
|
|
|
+ <span class="section-label">积分发放比例配置</span>
|
|
|
|
|
+ <span class="section-desc">设置消费可获得多少积分</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="section-body">
|
|
|
|
|
+ <el-form-item label="积分发放比例" prop="rate">
|
|
|
|
|
+ <el-input-number
|
|
|
|
|
+ v-model="form.rate"
|
|
|
|
|
+ :precision="2"
|
|
|
|
|
+ :min="0.01"
|
|
|
|
|
+ :max="9999"
|
|
|
|
|
+ :step="0.1"
|
|
|
|
|
+ class="input-number-wide"
|
|
|
|
|
+ />
|
|
|
|
|
+ <span class="tip-box tip-success">
|
|
|
|
|
+ <i class="el-icon-info"></i>
|
|
|
|
|
+ 消费 <b>1 元</b> = <b class="highlight">{{ form.rate || 0 }}</b> 积分
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
|
|
|
<!-- 2. 参与范围 -->
|
|
<!-- 2. 参与范围 -->
|
|
|
- <el-divider content-position="left">
|
|
|
|
|
- <i class="el-icon-s-grid"></i> 参与范围限定
|
|
|
|
|
- </el-divider>
|
|
|
|
|
- <el-form-item label="参与范围" prop="scopeType">
|
|
|
|
|
- <el-radio-group v-model="form.scopeType">
|
|
|
|
|
- <el-radio :label="1">全场商品参与送积分</el-radio>
|
|
|
|
|
- <el-radio :label="2">指定商品分类不送积分</el-radio>
|
|
|
|
|
- <el-radio :label="3">指定单个商品不送积分</el-radio>
|
|
|
|
|
- </el-radio-group>
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 指定不送积分的商品分类 -->
|
|
|
|
|
- <el-form-item v-if="form.scopeType === 2" label="不送积分分类" prop="excludeCategoryIds">
|
|
|
|
|
- <el-select
|
|
|
|
|
- v-model="form.excludeCategoryIds"
|
|
|
|
|
- multiple
|
|
|
|
|
- filterable
|
|
|
|
|
- placeholder="请选择商品分类"
|
|
|
|
|
- style="width: 480px;"
|
|
|
|
|
- >
|
|
|
|
|
- <el-option
|
|
|
|
|
- v-for="item in categoryOptions"
|
|
|
|
|
- :key="item.dictValue"
|
|
|
|
|
- :label="item.dictLabel"
|
|
|
|
|
- :value="Number(item.dictValue)"
|
|
|
|
|
- />
|
|
|
|
|
- </el-select>
|
|
|
|
|
- <div style="margin-top: 4px; color: #909399; font-size: 12px;">
|
|
|
|
|
- 已选 {{ (form.excludeCategoryIds || []).length }} 个分类,这些分类下的商品不参与送积分
|
|
|
|
|
|
|
+ <div class="section-block section-scope">
|
|
|
|
|
+ <div class="section-header">
|
|
|
|
|
+ <span class="section-icon scope"><i class="el-icon-s-grid"></i></span>
|
|
|
|
|
+ <span class="section-label">参与范围限定</span>
|
|
|
|
|
+ <span class="section-desc">控制哪些商品可以送积分</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="section-body">
|
|
|
|
|
+ <el-form-item label="参与范围" prop="scopeType">
|
|
|
|
|
+ <el-radio-group v-model="form.scopeType">
|
|
|
|
|
+ <el-radio :label="1">全场商品参与送积分</el-radio>
|
|
|
|
|
+ <el-radio :label="2">指定商品分类不送积分</el-radio>
|
|
|
|
|
+ <el-radio :label="3">指定单个商品不送积分</el-radio>
|
|
|
|
|
+ </el-radio-group>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+
|
|
|
|
|
+ <el-form-item v-if="form.scopeType === 2" label="不送积分分类" prop="excludeCategoryIds">
|
|
|
|
|
+ <el-select
|
|
|
|
|
+ v-model="form.excludeCategoryIds"
|
|
|
|
|
+ multiple
|
|
|
|
|
+ filterable
|
|
|
|
|
+ placeholder="请选择商品分类"
|
|
|
|
|
+ class="select-wide"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-option
|
|
|
|
|
+ v-for="item in categoryOptions"
|
|
|
|
|
+ :key="item.dictValue"
|
|
|
|
|
+ :label="item.dictLabel"
|
|
|
|
|
+ :value="Number(item.dictValue)"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ <span class="tip-box tip-warning">
|
|
|
|
|
+ <i class="el-icon-warning-outline"></i>
|
|
|
|
|
+ 已选 <b>{{ (form.excludeCategoryIds || []).length }}</b> 个分类,这些分类下的商品不参与送积分
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+
|
|
|
|
|
+ <el-form-item v-if="form.scopeType === 3" label="不送积分商品" prop="excludeProductIds">
|
|
|
|
|
+ <el-select
|
|
|
|
|
+ v-model="form.excludeProductIds"
|
|
|
|
|
+ multiple
|
|
|
|
|
+ filterable
|
|
|
|
|
+ placeholder="请选择商品(默认展示10条,可搜索)"
|
|
|
|
|
+ :loading="productLoading"
|
|
|
|
|
+ class="select-wide-x"
|
|
|
|
|
+ @visible-change="onProductSelectVisible"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-option
|
|
|
|
|
+ v-for="item in productOptions"
|
|
|
|
|
+ :key="item.productId"
|
|
|
|
|
+ :label="item.displayName"
|
|
|
|
|
+ :value="item.productId"
|
|
|
|
|
+ >
|
|
|
|
|
+ <div class="product-option">
|
|
|
|
|
+ <img v-if="item.image" :src="item.image" class="product-option-img" />
|
|
|
|
|
+ <span v-else class="product-option-img product-option-img-placeholder"></span>
|
|
|
|
|
+ <span class="product-option-name">{{ item.displayName }}</span>
|
|
|
|
|
+ <span v-if="item.storeName" class="product-option-store">{{ item.storeName }}</span>
|
|
|
|
|
+ <span class="product-option-price">¥{{ item.price }}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </el-option>
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ <span class="tip-box tip-warning">
|
|
|
|
|
+ <i class="el-icon-warning-outline"></i>
|
|
|
|
|
+ 已选 <b>{{ (form.excludeProductIds || []).length }}</b> 个商品,这些商品不参与送积分
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </el-form-item>
|
|
|
</div>
|
|
</div>
|
|
|
- </el-form-item>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 指定不送积分的单个商品 -->
|
|
|
|
|
- <el-form-item v-if="form.scopeType === 3" label="不送积分商品" prop="excludeProductIds">
|
|
|
|
|
- <el-select
|
|
|
|
|
- v-model="form.excludeProductIds"
|
|
|
|
|
- multiple
|
|
|
|
|
- filterable
|
|
|
|
|
- placeholder="请选择商品(默认展示10条,可搜索)"
|
|
|
|
|
- :loading="productLoading"
|
|
|
|
|
- style="width: 560px;"
|
|
|
|
|
- @visible-change="onProductSelectVisible"
|
|
|
|
|
- >
|
|
|
|
|
- <el-option
|
|
|
|
|
- v-for="item in productOptions"
|
|
|
|
|
- :key="item.productId"
|
|
|
|
|
- :label="item.displayName"
|
|
|
|
|
- :value="item.productId"
|
|
|
|
|
- >
|
|
|
|
|
- <div class="product-option">
|
|
|
|
|
- <img v-if="item.image" :src="item.image" class="product-option-img" />
|
|
|
|
|
- <span v-else class="product-option-img product-option-img-placeholder"></span>
|
|
|
|
|
- <span class="product-option-name">{{ item.displayName }}</span>
|
|
|
|
|
- <span v-if="item.storeName" class="product-option-store">{{ item.storeName }}</span>
|
|
|
|
|
- <span class="product-option-price">¥{{ item.price }}</span>
|
|
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 3. 积分抵扣配置 -->
|
|
|
|
|
+ <div class="section-block section-deduct">
|
|
|
|
|
+ <div class="section-header">
|
|
|
|
|
+ <span class="section-icon deduct"><i class="el-icon-s-finance"></i></span>
|
|
|
|
|
+ <span class="section-label">积分抵扣配置</span>
|
|
|
|
|
+ <span class="section-desc">设置积分抵现规则</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="section-body">
|
|
|
|
|
+ <el-form-item label="积分支付比例" prop="payRate">
|
|
|
|
|
+ <el-input-number
|
|
|
|
|
+ v-model="form.payRate"
|
|
|
|
|
+ :precision="0"
|
|
|
|
|
+ :min="1"
|
|
|
|
|
+ :max="99999"
|
|
|
|
|
+ :step="10"
|
|
|
|
|
+ class="input-number-sm"
|
|
|
|
|
+ />
|
|
|
|
|
+ <span class="tip-box tip-primary">
|
|
|
|
|
+ <i class="el-icon-info"></i>
|
|
|
|
|
+ <b class="highlight">{{ form.payRate || 0 }}</b> 积分 = <b>1 元</b>(每 <b>{{ form.payRate || 0 }}</b> 积分可抵现 1 元)
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+
|
|
|
|
|
+ <el-form-item label="最高抵扣积分" prop="maxDeduct">
|
|
|
|
|
+ <el-input-number
|
|
|
|
|
+ v-model="form.maxDeduct"
|
|
|
|
|
+ :min="0"
|
|
|
|
|
+ :max="999999"
|
|
|
|
|
+ :step="10"
|
|
|
|
|
+ class="input-number-sm"
|
|
|
|
|
+ />
|
|
|
|
|
+ <span class="tip-box tip-default">
|
|
|
|
|
+ <i class="el-icon-info"></i>
|
|
|
|
|
+ 每笔订单最多可用 <b>{{ form.maxDeduct || '不限' }}</b> 积分抵扣{{ form.maxDeduct > 0 ? ',超出部分不可使用' : '' }}
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+
|
|
|
|
|
+ <el-form-item label="满减门槛" prop="minDeductAmount">
|
|
|
|
|
+ <el-input-number
|
|
|
|
|
+ v-model="form.minDeductAmount"
|
|
|
|
|
+ :precision="2"
|
|
|
|
|
+ :min="0"
|
|
|
|
|
+ :max="999999"
|
|
|
|
|
+ :step="10"
|
|
|
|
|
+ class="input-number-sm"
|
|
|
|
|
+ />
|
|
|
|
|
+ <span class="tip-box tip-default">
|
|
|
|
|
+ <i class="el-icon-info"></i>
|
|
|
|
|
+ {{ form.minDeductAmount > 0 ? '订单满 ' + form.minDeductAmount + ' 元才可使用积分抵扣' : '不限制,任意金额均可使用积分抵扣' }}
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 4. 特殊规则 -->
|
|
|
|
|
+ <div class="section-block section-rules">
|
|
|
|
|
+ <div class="section-header">
|
|
|
|
|
+ <span class="section-icon rules"><i class="el-icon-setting"></i></span>
|
|
|
|
|
+ <span class="section-label">特殊规则设置</span>
|
|
|
|
|
+ <span class="section-desc">退款、限额等高级配置</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="section-body">
|
|
|
|
|
+ <el-form-item label="退款扣回积分" prop="refundDeduct">
|
|
|
|
|
+ <el-radio-group v-model="form.refundDeduct">
|
|
|
|
|
+ <el-radio :label="1">是,退款时自动扣回</el-radio>
|
|
|
|
|
+ <el-radio :label="0">否,退款不扣回</el-radio>
|
|
|
|
|
+ </el-radio-group>
|
|
|
|
|
+ <div v-if="form.refundDeduct === 1" class="tip-box tip-success" style="display: inline-flex; vertical-align: middle;">
|
|
|
|
|
+ <i class="el-icon-check"></i> 退款时将自动按比例扣回已发放的积分
|
|
|
</div>
|
|
</div>
|
|
|
- </el-option>
|
|
|
|
|
- </el-select>
|
|
|
|
|
- <div style="margin-top: 4px; color: #909399; font-size: 12px;">
|
|
|
|
|
- 已选 {{ (form.excludeProductIds || []).length }} 个商品,这些商品不参与送积分
|
|
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+
|
|
|
|
|
+ <el-form-item label="每日积分上限" prop="dailyLimit">
|
|
|
|
|
+ <el-input-number
|
|
|
|
|
+ v-model="form.dailyLimit"
|
|
|
|
|
+ :min="0"
|
|
|
|
|
+ :max="999999"
|
|
|
|
|
+ :step="100"
|
|
|
|
|
+ class="input-number-sm"
|
|
|
|
|
+ />
|
|
|
|
|
+ <span class="tip-box tip-default">
|
|
|
|
|
+ <i class="el-icon-info"></i>
|
|
|
|
|
+ {{ form.dailyLimit > 0 ? '每日最多发放 ' + form.dailyLimit + ' 积分' : '不限制每日积分获取' }}
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+
|
|
|
|
|
+ <el-form-item label="每月积分上限" prop="monthlyLimit">
|
|
|
|
|
+ <el-input-number
|
|
|
|
|
+ v-model="form.monthlyLimit"
|
|
|
|
|
+ :min="0"
|
|
|
|
|
+ :max="999999"
|
|
|
|
|
+ :step="100"
|
|
|
|
|
+ class="input-number-sm"
|
|
|
|
|
+ />
|
|
|
|
|
+ <span class="tip-box tip-default">
|
|
|
|
|
+ <i class="el-icon-info"></i>
|
|
|
|
|
+ {{ form.monthlyLimit > 0 ? '每月最多发放 ' + form.monthlyLimit + ' 积分' : '不限制每月积分获取' }}
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+
|
|
|
|
|
+ <el-form-item label="启用状态" prop="enabled">
|
|
|
|
|
+ <el-switch
|
|
|
|
|
+ v-model="form.enabled"
|
|
|
|
|
+ :active-value="1"
|
|
|
|
|
+ :inactive-value="0"
|
|
|
|
|
+ active-color="#13ce66"
|
|
|
|
|
+ inactive-color="#c0ccda"
|
|
|
|
|
+ active-text="启用"
|
|
|
|
|
+ inactive-text="禁用"
|
|
|
|
|
+ />
|
|
|
|
|
+ <span class="tip-box tip-default" style="margin-left: 12px;">
|
|
|
|
|
+ <i class="el-icon-info"></i> 关闭后所有积分发放将立即停止
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </el-form-item>
|
|
|
</div>
|
|
</div>
|
|
|
- </el-form-item>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 3. 特殊规则 -->
|
|
|
|
|
- <el-divider content-position="left">
|
|
|
|
|
- <i class="el-icon-setting"></i> 特殊规则设置
|
|
|
|
|
- </el-divider>
|
|
|
|
|
- <el-form-item label="退款扣回积分" prop="refundDeduct">
|
|
|
|
|
- <el-radio-group v-model="form.refundDeduct">
|
|
|
|
|
- <el-radio :label="1">是,退款时自动扣回</el-radio>
|
|
|
|
|
- <el-radio :label="0">否,退款不扣回</el-radio>
|
|
|
|
|
- </el-radio-group>
|
|
|
|
|
- <div class="form-tip">开启后,发生退款时将按实退金额比例自动扣回已发放积分</div>
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
-
|
|
|
|
|
- <el-form-item label="每日积分上限" prop="dailyLimit">
|
|
|
|
|
- <el-col :span="4">
|
|
|
|
|
- <el-input-number
|
|
|
|
|
- v-model="form.dailyLimit"
|
|
|
|
|
- :min="0"
|
|
|
|
|
- :max="999999"
|
|
|
|
|
- :step="100"
|
|
|
|
|
- style="width: 100%;"
|
|
|
|
|
- />
|
|
|
|
|
- </el-col>
|
|
|
|
|
- <span class="form-tip">0 = 不限制,超出上限自动不再发放</span>
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
-
|
|
|
|
|
- <el-form-item label="每月积分上限" prop="monthlyLimit">
|
|
|
|
|
- <el-col :span="4">
|
|
|
|
|
- <el-input-number
|
|
|
|
|
- v-model="form.monthlyLimit"
|
|
|
|
|
- :min="0"
|
|
|
|
|
- :max="999999"
|
|
|
|
|
- :step="100"
|
|
|
|
|
- style="width: 100%;"
|
|
|
|
|
- />
|
|
|
|
|
- </el-col>
|
|
|
|
|
- <span class="form-tip">0 = 不限制,超出上限自动不再发放</span>
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
-
|
|
|
|
|
- <el-form-item label="最高抵扣积分" prop="maxDeduct">
|
|
|
|
|
- <el-col :span="4">
|
|
|
|
|
- <el-input-number
|
|
|
|
|
- v-model="form.maxDeduct"
|
|
|
|
|
- :min="0"
|
|
|
|
|
- :max="999999"
|
|
|
|
|
- :step="10"
|
|
|
|
|
- style="width: 100%;"
|
|
|
|
|
- />
|
|
|
|
|
- </el-col>
|
|
|
|
|
- <span class="form-tip">0 = 不限制,用户每笔订单最多可用积分抵扣的数量</span>
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
-
|
|
|
|
|
- <el-form-item label="启用状态" prop="enabled">
|
|
|
|
|
- <el-radio-group v-model="form.enabled">
|
|
|
|
|
- <el-radio :label="1">启用</el-radio>
|
|
|
|
|
- <el-radio :label="0">禁用</el-radio>
|
|
|
|
|
- </el-radio-group>
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
|
|
+ </div>
|
|
|
</el-form>
|
|
</el-form>
|
|
|
|
|
|
|
|
- <div style="text-align: center; margin-top: 24px; padding-top: 20px; border-top: 1px solid #EBEEF5;">
|
|
|
|
|
- <el-button type="primary" :loading="submitLoading" @click="handleSubmit" icon="el-icon-check">
|
|
|
|
|
|
|
+ <!-- 底部操作 -->
|
|
|
|
|
+ <div class="form-footer">
|
|
|
|
|
+ <el-button size="medium" @click="handleReset" icon="el-icon-refresh">重 置</el-button>
|
|
|
|
|
+ <el-button type="primary" size="medium" :loading="submitLoading" @click="handleSubmit" icon="el-icon-check">
|
|
|
保 存 配 置
|
|
保 存 配 置
|
|
|
</el-button>
|
|
</el-button>
|
|
|
- <el-button @click="handleReset" icon="el-icon-refresh">重 置</el-button>
|
|
|
|
|
</div>
|
|
</div>
|
|
|
</el-card>
|
|
</el-card>
|
|
|
</div>
|
|
</div>
|
|
@@ -197,6 +278,7 @@ export default {
|
|
|
productOptions: [],
|
|
productOptions: [],
|
|
|
form: {
|
|
form: {
|
|
|
rate: 1.00,
|
|
rate: 1.00,
|
|
|
|
|
+ payRate: 100,
|
|
|
scopeType: 1,
|
|
scopeType: 1,
|
|
|
excludeCategoryIds: [],
|
|
excludeCategoryIds: [],
|
|
|
excludeProductIds: [],
|
|
excludeProductIds: [],
|
|
@@ -204,6 +286,7 @@ export default {
|
|
|
dailyLimit: 0,
|
|
dailyLimit: 0,
|
|
|
monthlyLimit: 0,
|
|
monthlyLimit: 0,
|
|
|
maxDeduct: 0,
|
|
maxDeduct: 0,
|
|
|
|
|
+ minDeductAmount: 0,
|
|
|
enabled: 1
|
|
enabled: 1
|
|
|
},
|
|
},
|
|
|
rules: {
|
|
rules: {
|
|
@@ -211,6 +294,9 @@ export default {
|
|
|
{ required: true, message: '请输入积分发放比例', trigger: 'blur' },
|
|
{ required: true, message: '请输入积分发放比例', trigger: 'blur' },
|
|
|
{ validator: validateRate, trigger: 'blur' }
|
|
{ validator: validateRate, trigger: 'blur' }
|
|
|
],
|
|
],
|
|
|
|
|
+ payRate: [
|
|
|
|
|
+ { required: true, message: '请输入积分支付比例', trigger: 'blur' }
|
|
|
|
|
+ ],
|
|
|
scopeType: [
|
|
scopeType: [
|
|
|
{ required: true, message: '请选择参与范围', trigger: 'change' }
|
|
{ required: true, message: '请选择参与范围', trigger: 'change' }
|
|
|
],
|
|
],
|
|
@@ -232,6 +318,9 @@ export default {
|
|
|
maxDeduct: [
|
|
maxDeduct: [
|
|
|
{ required: true, message: '请输入最高抵扣积分', trigger: 'blur' }
|
|
{ required: true, message: '请输入最高抵扣积分', trigger: 'blur' }
|
|
|
],
|
|
],
|
|
|
|
|
+ minDeductAmount: [
|
|
|
|
|
+ { required: true, message: '请输入满减门槛', trigger: 'blur' }
|
|
|
|
|
+ ],
|
|
|
enabled: [
|
|
enabled: [
|
|
|
{ required: true, message: '请选择启用状态', trigger: 'change' }
|
|
{ required: true, message: '请选择启用状态', trigger: 'change' }
|
|
|
]
|
|
]
|
|
@@ -243,22 +332,20 @@ export default {
|
|
|
this.loadConfig()
|
|
this.loadConfig()
|
|
|
},
|
|
},
|
|
|
methods: {
|
|
methods: {
|
|
|
- /** 加载商品分类字典 */
|
|
|
|
|
loadCategoryDict() {
|
|
loadCategoryDict() {
|
|
|
this.getDicts('store_product_type').then(response => {
|
|
this.getDicts('store_product_type').then(response => {
|
|
|
this.categoryOptions = response.data || []
|
|
this.categoryOptions = response.data || []
|
|
|
})
|
|
})
|
|
|
},
|
|
},
|
|
|
- /** 加载配置 */
|
|
|
|
|
loadConfig() {
|
|
loadConfig() {
|
|
|
getConfigByKey('points.grantRule').then(response => {
|
|
getConfigByKey('points.grantRule').then(response => {
|
|
|
if (response.data && response.data.configValue) {
|
|
if (response.data && response.data.configValue) {
|
|
|
const configValue = response.data.configValue
|
|
const configValue = response.data.configValue
|
|
|
let config = typeof configValue === 'string' ? JSON.parse(configValue) : configValue
|
|
let config = typeof configValue === 'string' ? JSON.parse(configValue) : configValue
|
|
|
this.configId = response.data.configId
|
|
this.configId = response.data.configId
|
|
|
- // 合并已保存的值,保留默认值兜底
|
|
|
|
|
this.form = {
|
|
this.form = {
|
|
|
rate: config.rate ?? 1.00,
|
|
rate: config.rate ?? 1.00,
|
|
|
|
|
+ payRate: config.payRate ?? 100,
|
|
|
scopeType: config.scopeType ?? 1,
|
|
scopeType: config.scopeType ?? 1,
|
|
|
excludeCategoryIds: config.excludeCategoryIds || [],
|
|
excludeCategoryIds: config.excludeCategoryIds || [],
|
|
|
excludeProductIds: config.excludeProductIds || [],
|
|
excludeProductIds: config.excludeProductIds || [],
|
|
@@ -266,9 +353,9 @@ export default {
|
|
|
dailyLimit: config.dailyLimit ?? 0,
|
|
dailyLimit: config.dailyLimit ?? 0,
|
|
|
monthlyLimit: config.monthlyLimit ?? 0,
|
|
monthlyLimit: config.monthlyLimit ?? 0,
|
|
|
maxDeduct: config.maxDeduct ?? 0,
|
|
maxDeduct: config.maxDeduct ?? 0,
|
|
|
|
|
+ minDeductAmount: config.minDeductAmount ?? 0,
|
|
|
enabled: config.enabled ?? 1
|
|
enabled: config.enabled ?? 1
|
|
|
}
|
|
}
|
|
|
- // 回填已选商品 options
|
|
|
|
|
if (config.excludeProductIds && config.excludeProductIds.length > 0) {
|
|
if (config.excludeProductIds && config.excludeProductIds.length > 0) {
|
|
|
this.loadSelectedProducts(config.excludeProductIds)
|
|
this.loadSelectedProducts(config.excludeProductIds)
|
|
|
}
|
|
}
|
|
@@ -280,7 +367,6 @@ export default {
|
|
|
})
|
|
})
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
- /** 回填已选商品名称 */
|
|
|
|
|
loadSelectedProducts(ids) {
|
|
loadSelectedProducts(ids) {
|
|
|
listStoreProduct({ pageSize: 999 }).then(response => {
|
|
listStoreProduct({ pageSize: 999 }).then(response => {
|
|
|
const rows = response.data || response.rows || []
|
|
const rows = response.data || response.rows || []
|
|
@@ -288,7 +374,6 @@ export default {
|
|
|
}).catch(() => {})
|
|
}).catch(() => {})
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
- /** 构建商品选项对象 */
|
|
|
|
|
buildProductOption(item) {
|
|
buildProductOption(item) {
|
|
|
const name = item.productName && item.productName !== '-' ? item.productName : (item.commonName || '')
|
|
const name = item.productName && item.productName !== '-' ? item.productName : (item.commonName || '')
|
|
|
return {
|
|
return {
|
|
@@ -301,22 +386,6 @@ export default {
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
- /** 加载商品分类选项(默认10条) */
|
|
|
|
|
- loadCategoryOptions() {
|
|
|
|
|
- this.categoryLoading = true
|
|
|
|
|
- listCategory({ pageSize: 10 }).then(response => {
|
|
|
|
|
- const rows = response.data || response.rows || []
|
|
|
|
|
- this.categoryOptions = rows.map(item => ({
|
|
|
|
|
- categoryId: item.categoryId,
|
|
|
|
|
- categoryName: item.categoryName || item.name
|
|
|
|
|
- }))
|
|
|
|
|
- this.categoryLoading = false
|
|
|
|
|
- }).catch(() => {
|
|
|
|
|
- this.categoryLoading = false
|
|
|
|
|
- })
|
|
|
|
|
- },
|
|
|
|
|
-
|
|
|
|
|
- /** 加载商品选项(默认10条) */
|
|
|
|
|
loadProductOptions() {
|
|
loadProductOptions() {
|
|
|
this.productLoading = true
|
|
this.productLoading = true
|
|
|
listStoreProduct({ pageSize: 10 }).then(response => {
|
|
listStoreProduct({ pageSize: 10 }).then(response => {
|
|
@@ -328,27 +397,17 @@ export default {
|
|
|
})
|
|
})
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
- /** 分类下拉展开时加载数据 */
|
|
|
|
|
- onCategorySelectVisible(visible) {
|
|
|
|
|
- if (visible && this.categoryOptions.length === 0) {
|
|
|
|
|
- this.loadCategoryOptions()
|
|
|
|
|
- }
|
|
|
|
|
- },
|
|
|
|
|
-
|
|
|
|
|
- /** 商品下拉展开时加载数据 */
|
|
|
|
|
onProductSelectVisible(visible) {
|
|
onProductSelectVisible(visible) {
|
|
|
if (visible && this.productOptions.length === 0) {
|
|
if (visible && this.productOptions.length === 0) {
|
|
|
this.loadProductOptions()
|
|
this.loadProductOptions()
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
- /** 提交保存 */
|
|
|
|
|
handleSubmit() {
|
|
handleSubmit() {
|
|
|
this.$refs.form.validate(valid => {
|
|
this.$refs.form.validate(valid => {
|
|
|
if (!valid) return
|
|
if (!valid) return
|
|
|
this.submitLoading = true
|
|
this.submitLoading = true
|
|
|
const configValue = JSON.stringify(this.form)
|
|
const configValue = JSON.stringify(this.form)
|
|
|
- // configId 不存在则新增,存在则更新
|
|
|
|
|
let request
|
|
let request
|
|
|
if (this.configId) {
|
|
if (this.configId) {
|
|
|
request = updateConfigByKey({
|
|
request = updateConfigByKey({
|
|
@@ -378,7 +437,6 @@ export default {
|
|
|
})
|
|
})
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
- /** 重置为默认值 */
|
|
|
|
|
handleReset() {
|
|
handleReset() {
|
|
|
this.$confirm('确认重置为默认值?已保存的配置将丢失。', '提示', {
|
|
this.$confirm('确认重置为默认值?已保存的配置将丢失。', '提示', {
|
|
|
confirmButtonText: '确定',
|
|
confirmButtonText: '确定',
|
|
@@ -387,6 +445,7 @@ export default {
|
|
|
}).then(() => {
|
|
}).then(() => {
|
|
|
this.form = {
|
|
this.form = {
|
|
|
rate: 1.00,
|
|
rate: 1.00,
|
|
|
|
|
+ payRate: 100,
|
|
|
scopeType: 1,
|
|
scopeType: 1,
|
|
|
excludeCategoryIds: [],
|
|
excludeCategoryIds: [],
|
|
|
excludeProductIds: [],
|
|
excludeProductIds: [],
|
|
@@ -394,6 +453,7 @@ export default {
|
|
|
dailyLimit: 0,
|
|
dailyLimit: 0,
|
|
|
monthlyLimit: 0,
|
|
monthlyLimit: 0,
|
|
|
maxDeduct: 0,
|
|
maxDeduct: 0,
|
|
|
|
|
+ minDeductAmount: 0,
|
|
|
enabled: 1
|
|
enabled: 1
|
|
|
}
|
|
}
|
|
|
this.categoryOptions = []
|
|
this.categoryOptions = []
|
|
@@ -406,25 +466,188 @@ export default {
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped>
|
|
<style scoped>
|
|
|
-.card-title {
|
|
|
|
|
- font-size: 16px;
|
|
|
|
|
|
|
+/* ===== 主卡片 ===== */
|
|
|
|
|
+.main-card {
|
|
|
|
|
+ border-radius: 8px;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+}
|
|
|
|
|
+.main-card >>> .el-card__header {
|
|
|
|
|
+ padding: 0;
|
|
|
|
|
+ border-bottom: none;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* ===== 卡片头部 ===== */
|
|
|
|
|
+.card-header {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ padding: 20px 24px;
|
|
|
|
|
+ background: linear-gradient(135deg, #f5f7fa 0%, #e8edf3 100%);
|
|
|
|
|
+}
|
|
|
|
|
+.header-left {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 14px;
|
|
|
|
|
+}
|
|
|
|
|
+.header-icon-bg {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ width: 44px;
|
|
|
|
|
+ height: 44px;
|
|
|
|
|
+ border-radius: 10px;
|
|
|
|
|
+ background: linear-gradient(135deg, #409EFF 0%, #337ECC 100%);
|
|
|
|
|
+ color: #fff;
|
|
|
|
|
+ font-size: 22px;
|
|
|
|
|
+ box-shadow: 0 2px 8px rgba(64, 158, 255, 0.3);
|
|
|
|
|
+}
|
|
|
|
|
+.header-text {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ gap: 2px;
|
|
|
|
|
+}
|
|
|
|
|
+.header-title {
|
|
|
|
|
+ font-size: 17px;
|
|
|
font-weight: 600;
|
|
font-weight: 600;
|
|
|
color: #303133;
|
|
color: #303133;
|
|
|
}
|
|
}
|
|
|
-.card-title i {
|
|
|
|
|
- margin-right: 6px;
|
|
|
|
|
- color: #409EFF;
|
|
|
|
|
|
|
+.header-sub {
|
|
|
|
|
+ font-size: 13px;
|
|
|
|
|
+ color: #909399;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* ===== 分区块 ===== */
|
|
|
|
|
+.section-block {
|
|
|
|
|
+ margin: 0 24px 16px;
|
|
|
|
|
+ border-radius: 8px;
|
|
|
|
|
+ border: 1px solid #EBEEF5;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ transition: box-shadow 0.2s;
|
|
|
|
|
+}
|
|
|
|
|
+.section-block:hover {
|
|
|
|
|
+ box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.section-header {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 10px;
|
|
|
|
|
+ padding: 12px 20px;
|
|
|
|
|
+ background: #fafbfc;
|
|
|
|
|
+ border-bottom: 1px solid #EBEEF5;
|
|
|
|
|
+}
|
|
|
|
|
+.section-icon {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ width: 28px;
|
|
|
|
|
+ height: 28px;
|
|
|
|
|
+ border-radius: 6px;
|
|
|
|
|
+ color: #fff;
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
}
|
|
}
|
|
|
-.form-tip {
|
|
|
|
|
|
|
+.section-icon.earn { background: linear-gradient(135deg, #67C23A, #529b2e); }
|
|
|
|
|
+.section-icon.scope { background: linear-gradient(135deg, #409EFF, #337ECC); }
|
|
|
|
|
+.section-icon.deduct { background: linear-gradient(135deg, #E6A23C, #cf9236); }
|
|
|
|
|
+.section-icon.rules { background: linear-gradient(135deg, #9B59B6, #7d3c98); }
|
|
|
|
|
+
|
|
|
|
|
+.section-label {
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ color: #303133;
|
|
|
|
|
+}
|
|
|
|
|
+.section-desc {
|
|
|
font-size: 12px;
|
|
font-size: 12px;
|
|
|
color: #909399;
|
|
color: #909399;
|
|
|
- margin-left: 12px;
|
|
|
|
|
|
|
+ margin-left: 4px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.section-body {
|
|
|
|
|
+ padding: 16px 20px 4px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* ===== 表单优化 ===== */
|
|
|
|
|
+.section-body >>> .el-form-item {
|
|
|
|
|
+ margin-bottom: 18px;
|
|
|
|
|
+}
|
|
|
|
|
+.section-body >>> .el-form-item__label {
|
|
|
|
|
+ font-weight: 500;
|
|
|
|
|
+ color: #606266;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* ===== 输入框 ===== */
|
|
|
|
|
+.input-number-wide {
|
|
|
|
|
+ width: 200px;
|
|
|
|
|
+}
|
|
|
|
|
+.input-number-sm {
|
|
|
|
|
+ width: 160px;
|
|
|
|
|
+}
|
|
|
|
|
+.select-wide {
|
|
|
|
|
+ width: 480px;
|
|
|
|
|
+}
|
|
|
|
|
+.select-wide-x {
|
|
|
|
|
+ width: 580px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* ===== 提示标签 ===== */
|
|
|
|
|
+.tip-box {
|
|
|
|
|
+ display: inline-flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 5px;
|
|
|
|
|
+ margin-left: 14px;
|
|
|
|
|
+ padding: 4px 12px;
|
|
|
|
|
+ border-radius: 4px;
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ line-height: 1.8;
|
|
|
|
|
+ vertical-align: middle;
|
|
|
|
|
+}
|
|
|
|
|
+.tip-box i { font-size: 13px; }
|
|
|
|
|
+.tip-box b { font-weight: 600; }
|
|
|
|
|
+.tip-box b.highlight {
|
|
|
|
|
+ color: inherit;
|
|
|
|
|
+ font-size: 15px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.tip-success {
|
|
|
|
|
+ background: #f0f9eb;
|
|
|
|
|
+ color: #67C23A;
|
|
|
|
|
+ border: 1px solid #e1f3d8;
|
|
|
|
|
+}
|
|
|
|
|
+.tip-primary {
|
|
|
|
|
+ background: #ecf5ff;
|
|
|
|
|
+ color: #409EFF;
|
|
|
|
|
+ border: 1px solid #d9ecff;
|
|
|
|
|
+}
|
|
|
|
|
+.tip-warning {
|
|
|
|
|
+ display: block;
|
|
|
|
|
+ margin: 6px 0 0 0;
|
|
|
|
|
+ background: #fdf6ec;
|
|
|
|
|
+ color: #E6A23C;
|
|
|
|
|
+ border: 1px solid #faecd8;
|
|
|
|
|
+}
|
|
|
|
|
+.tip-default {
|
|
|
|
|
+ background: #f5f7fa;
|
|
|
|
|
+ color: #909399;
|
|
|
|
|
+ border: 1px solid #e4e7ed;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* ===== 底部操作栏 ===== */
|
|
|
|
|
+.form-footer {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ gap: 16px;
|
|
|
|
|
+ margin: 0 24px 8px;
|
|
|
|
|
+ padding: 20px 0;
|
|
|
|
|
+ border-top: 1px solid #EBEEF5;
|
|
|
}
|
|
}
|
|
|
-.el-divider i {
|
|
|
|
|
- margin-right: 6px;
|
|
|
|
|
|
|
+.form-footer .el-button {
|
|
|
|
|
+ min-width: 120px;
|
|
|
|
|
+ border-radius: 6px;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/* 商品选项样式 */
|
|
|
|
|
|
|
+/* ===== 商品下拉选项 ===== */
|
|
|
.product-option {
|
|
.product-option {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
align-items: center;
|
|
align-items: center;
|