|
|
@@ -299,6 +299,26 @@
|
|
|
</el-select>
|
|
|
</el-form-item>
|
|
|
|
|
|
+ <el-form-item label="可选赠品">
|
|
|
+ <div style="width: 100%">
|
|
|
+ <div v-for="lv in membershipLevels" :key="lv.levelCode" class="gift-config-level">
|
|
|
+ <div class="gift-config-level-title">{{ lv.levelName }} 赠品</div>
|
|
|
+ <div v-for="(item, idx) in getGiftItems(lv.levelCode)" :key="getGiftItemKey(item, idx)" class="gift-config-item">
|
|
|
+ <el-select v-model="item.giftType" size="mini" style="width: 110px; margin-right: 8px">
|
|
|
+ <el-option label="赠品商品" value="product" />
|
|
|
+ <el-option label="CF值" value="cf" />
|
|
|
+ </el-select>
|
|
|
+ <el-select v-if="item.giftType === 'product'" v-model="item.giftProductId" size="mini" filterable placeholder="选择赠品商品" style="width: 260px; margin-right: 8px">
|
|
|
+ <el-option v-for="p in onShelfProducts" :key="p.id" :label="p.name" :value="p.id" />
|
|
|
+ </el-select>
|
|
|
+ <el-input v-if="item.giftType === 'cf'" v-model.number="item.cfValue" size="mini" placeholder="CF值数量" type="number" style="width: 140px; margin-right: 8px" />
|
|
|
+ <el-button size="mini" type="text" @click="removeGiftItem(lv.levelCode, idx)">删除</el-button>
|
|
|
+ </div>
|
|
|
+ <el-button size="mini" type="text" @click="addGiftItem(lv.levelCode)">+ 添加赠品</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
<el-form-item>
|
|
|
<el-button type="primary" :loading="saving" @click="handleSave">
|
|
|
{{ isEdit ? '保存修改' : '创建商品' }}
|
|
|
@@ -311,7 +331,7 @@
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
-import { getProduct, createProduct, updateProduct, listAllSupplySystems, getPredefinedPurchaseFields, getProductPurchaseFields, saveProductPurchaseFields, getMySupplySystem, saveProductGiftRule, listProductGiftRules, listMembershipLevels, getGrowthArchiveProduct, saveGrowthArchiveProduct, listDeliveryServicePersons, saveDeliveryServicePersons, listDeliveryOnlineSlots, saveDeliveryOnlineSlots, getProductList, getProductSkuList, saveBundleItems, getBundleItems, getApprovedGuides } from '@/api/admin'
|
|
|
+import { getProduct, createProduct, updateProduct, listAllSupplySystems, getPredefinedPurchaseFields, getProductPurchaseFields, saveProductPurchaseFields, getMySupplySystem, saveProductGiftRule, listProductGiftRules, listMembershipLevels, getGrowthArchiveProduct, saveGrowthArchiveProduct, listDeliveryServicePersons, saveDeliveryServicePersons, listDeliveryOnlineSlots, saveDeliveryOnlineSlots, getProductList, getProductSkuList, saveBundleItems, getBundleItems, getApprovedGuides, saveProductGift, getProductGiftList } from '@/api/admin'
|
|
|
import { saveDimensionWeights, getDimensionWeights } from '@/api/dimension-weight'
|
|
|
import DimensionWeightPicker from '@/components/DimensionWeightPicker.vue'
|
|
|
import ProductSkuEditor from './components/ProductSkuEditor.vue'
|
|
|
@@ -362,6 +382,9 @@ export default {
|
|
|
giftRuleEnabled: false,
|
|
|
giftRuleLevel: '',
|
|
|
membershipLevels: [],
|
|
|
+ // 可选赠品配置:{ [levelCode]: [{giftType,giftProductId,cfValue,sortOrder}] }
|
|
|
+ giftConfigsByLevel: {},
|
|
|
+ onShelfProducts: [],
|
|
|
rules: {
|
|
|
name: [{ required: true, message: '请输入商品名称', trigger: 'blur' }],
|
|
|
productType: [{ required: true, message: '请选择商品类型', trigger: 'change' }],
|
|
|
@@ -507,6 +530,8 @@ export default {
|
|
|
mounted() {
|
|
|
this.loadSupplySystems()
|
|
|
this.loadPredefinedFields()
|
|
|
+ this.ensureMembershipLevels()
|
|
|
+ this.loadOnShelfProducts()
|
|
|
if (this.isEdit) {
|
|
|
this.loadProduct(this.$route.query.id)
|
|
|
}
|
|
|
@@ -588,6 +613,7 @@ export default {
|
|
|
this.loadPurchaseFields(p.id)
|
|
|
// 赠送会员规则回显
|
|
|
this.loadGiftRule(p.id)
|
|
|
+ this.loadGiftConfigs(p.id)
|
|
|
// Load growth archive config
|
|
|
this.loadGrowthArchive(p.id)
|
|
|
// Load delivery config (service persons / online slots)
|
|
|
@@ -667,6 +693,94 @@ async loadGiftRule(productId) {
|
|
|
console.warn('加载赠送会员规则失败', e)
|
|
|
}
|
|
|
},
|
|
|
+ getGiftItems(levelCode) {
|
|
|
+ return this.giftConfigsByLevel[levelCode] || []
|
|
|
+ },
|
|
|
+ getGiftItemKey(item, idx) {
|
|
|
+ return (item && item.giftType ? item.giftType : 'item') + '-' + idx
|
|
|
+ },
|
|
|
+ addGiftItem(levelCode) {
|
|
|
+ var arr = this.giftConfigsByLevel[levelCode]
|
|
|
+ if (!arr) {
|
|
|
+ this.$set(this.giftConfigsByLevel, levelCode, [])
|
|
|
+ arr = this.giftConfigsByLevel[levelCode]
|
|
|
+ }
|
|
|
+ arr.push({ giftType: 'product', giftProductId: null, cfValue: 0, sortOrder: arr.length })
|
|
|
+ },
|
|
|
+ removeGiftItem(levelCode, idx) {
|
|
|
+ var arr = this.giftConfigsByLevel[levelCode]
|
|
|
+ if (arr) arr.splice(idx, 1)
|
|
|
+ },
|
|
|
+ async ensureMembershipLevels() {
|
|
|
+ if (this.membershipLevels.length === 0) {
|
|
|
+ try {
|
|
|
+ const lvRes = await listMembershipLevels()
|
|
|
+ if (lvRes.code === 200 && Array.isArray(lvRes.data)) {
|
|
|
+ this.membershipLevels = lvRes.data.filter(l => l.levelCode !== 'FREE')
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ console.warn('加载会员等级失败', e)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async loadOnShelfProducts() {
|
|
|
+ try {
|
|
|
+ const res = await getProductList({ status: 'on_shelf', page: 1, size: 200 })
|
|
|
+ if (res.code === 200) {
|
|
|
+ const data = res.data || {}
|
|
|
+ this.onShelfProducts = data.records || (Array.isArray(data) ? data : [])
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ console.warn('加载上架商品失败', e)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async loadGiftConfigs(productId) {
|
|
|
+ try {
|
|
|
+ await this.ensureMembershipLevels()
|
|
|
+ await this.loadOnShelfProducts()
|
|
|
+ // 初始化每等级空数组
|
|
|
+ var that = this
|
|
|
+ this.membershipLevels.forEach(function(lv) {
|
|
|
+ that.$set(that.giftConfigsByLevel, lv.levelCode, [])
|
|
|
+ })
|
|
|
+ const res = await getProductGiftList(productId)
|
|
|
+ if (res.code === 200 && Array.isArray(res.data)) {
|
|
|
+ res.data.forEach(function(cfg) {
|
|
|
+ if (cfg && cfg.levelCode) {
|
|
|
+ that.$set(that.giftConfigsByLevel, cfg.levelCode, (cfg.items || []).map(function(it) {
|
|
|
+ return {
|
|
|
+ giftType: it.giftType,
|
|
|
+ giftProductId: it.giftProductId,
|
|
|
+ cfValue: it.cfValue || 0,
|
|
|
+ sortOrder: it.sortOrder || 0
|
|
|
+ }
|
|
|
+ }))
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ console.warn('加载赠品配置失败', e)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async saveGiftConfigs(productId) {
|
|
|
+ try {
|
|
|
+ for (var i = 0; i < this.membershipLevels.length; i++) {
|
|
|
+ var lv = this.membershipLevels[i]
|
|
|
+ var items = (this.giftConfigsByLevel[lv.levelCode] || []).map(function(it, idx) {
|
|
|
+ return {
|
|
|
+ giftType: it.giftType,
|
|
|
+ giftProductId: it.giftType === 'product' ? it.giftProductId : null,
|
|
|
+ cfValue: it.giftType === 'cf' ? (it.cfValue || 0) : 0,
|
|
|
+ sortOrder: idx
|
|
|
+ }
|
|
|
+ })
|
|
|
+ var status = items.length > 0 ? 1 : 0
|
|
|
+ await saveProductGift({ productId: productId, levelCode: lv.levelCode, status: status, items: items })
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ console.warn('保存赠品配置失败', e)
|
|
|
+ }
|
|
|
+ },
|
|
|
async loadGrowthArchive(productId) {
|
|
|
try {
|
|
|
const res = await getGrowthArchiveProduct(productId)
|
|
|
@@ -899,6 +1013,14 @@ async loadGiftRule(productId) {
|
|
|
console.warn('保存赠送会员规则失败', e)
|
|
|
}
|
|
|
}
|
|
|
+ // 保存可选赠品配置
|
|
|
+ if (productId) {
|
|
|
+ try {
|
|
|
+ await this.saveGiftConfigs(productId)
|
|
|
+ } catch (e) {
|
|
|
+ console.warn('保存赠品配置失败', e)
|
|
|
+ }
|
|
|
+ }
|
|
|
// Save growth archive config (only for existing products)
|
|
|
if (this.form.id) {
|
|
|
try {
|
|
|
@@ -1089,6 +1211,21 @@ async loadGiftRule(productId) {
|
|
|
color: #ccc;
|
|
|
cursor: move;
|
|
|
}
|
|
|
+.gift-config-level {
|
|
|
+ margin-bottom: 12px;
|
|
|
+ padding: 8px 0;
|
|
|
+ border-bottom: 1px dashed #eee;
|
|
|
+}
|
|
|
+.gift-config-level-title {
|
|
|
+ font-size: 13px;
|
|
|
+ color: #606266;
|
|
|
+ margin-bottom: 6px;
|
|
|
+}
|
|
|
+.gift-config-item {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 6px;
|
|
|
+}
|
|
|
.service-person-card {
|
|
|
border: 1px solid #e8e8e8;
|
|
|
border-radius: 4px;
|