|
|
@@ -1,29 +1,47 @@
|
|
|
<!--
|
|
|
团购商品编辑页
|
|
|
从团购配置页跳转,单选活动商品并填写团购价/成团人数/库存等;通过 groupBuyDraft 与列表页同步。
|
|
|
+ 单规格:一套表单;多规格:按规格数动态生成多套表单,保存时每规格各写一条团购商品(goodsId 用子规格 id)。
|
|
|
+ 自动退款不再可配,统一默认开启(活动结束未拼成自动退款、拼成自动退差价)。
|
|
|
-->
|
|
|
<template>
|
|
|
<view class="page-container">
|
|
|
<view class="module-com input-line-wrap form-card">
|
|
|
<tui-list-cell class="line-cell" :arrow="true" :hover="true" @click="selectGoods">
|
|
|
<view class="tui-title required">活动商品</view>
|
|
|
- <view class="tui-input picker-text" :class="{ placeholder: !goodsForm.name }">
|
|
|
- {{ goodsForm.name || '请选择活动商品' }}
|
|
|
+ <view class="tui-input picker-text" :class="{ placeholder: !goodsBase.name }">
|
|
|
+ {{ goodsBase.name || '请选择活动商品' }}
|
|
|
</view>
|
|
|
</tui-list-cell>
|
|
|
|
|
|
- <tui-list-cell v-if="goodsForm.cover" class="line-cell" :hover="false">
|
|
|
- <image class="preview-cover" :src="imgFullUrl(goodsForm.cover)" mode="aspectFill" />
|
|
|
+ <tui-list-cell v-if="goodsBase.cover" class="line-cell" :hover="false" :last="!specForms.length">
|
|
|
+ <image class="preview-cover" :src="imgFullUrl(goodsBase.cover)" mode="aspectFill" />
|
|
|
</tui-list-cell>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 单规格一套表单;多规格按规格数动态多套 -->
|
|
|
+ <!-- 小程序端:v-for 内不用别名 v-model,事件参数用 data-* 传递避免 data-event-opts 编译失败 -->
|
|
|
+ <view
|
|
|
+ v-for="(item, sIndex) in specForms"
|
|
|
+ :key="sIndex"
|
|
|
+ class="module-com input-line-wrap form-card"
|
|
|
+ >
|
|
|
+ <view v-if="isMultiSpec" class="spec-head">
|
|
|
+ <text class="spec-head-label">规格{{ sIndex + 1 }}</text>
|
|
|
+ <text class="spec-head-name">{{ item.specName || '未命名规格' }}</text>
|
|
|
+ </view>
|
|
|
|
|
|
<tui-list-cell class="line-cell" :hover="false">
|
|
|
<view class="tui-title required">团购价格</view>
|
|
|
<input
|
|
|
- v-model="goodsForm.price"
|
|
|
+ :value="item.price"
|
|
|
class="tui-input"
|
|
|
placeholder-class="phcolor"
|
|
|
placeholder="请输入团购价格"
|
|
|
type="digit"
|
|
|
+ :data-index="sIndex"
|
|
|
+ data-field="price"
|
|
|
+ @input="onSpecInput"
|
|
|
/>
|
|
|
</tui-list-cell>
|
|
|
|
|
|
@@ -34,8 +52,10 @@
|
|
|
v-for="n in groupSizeOptions"
|
|
|
:key="n"
|
|
|
class="segment-tab"
|
|
|
- :class="{ active: goodsForm.groupSize === n }"
|
|
|
- @click="goodsForm.groupSize = n"
|
|
|
+ :class="{ active: item.groupSize === n }"
|
|
|
+ :data-index="sIndex"
|
|
|
+ :data-size="n"
|
|
|
+ @click="onGroupSizeClick"
|
|
|
>{{ n }}人</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
@@ -43,57 +63,70 @@
|
|
|
<tui-list-cell class="line-cell" :hover="false">
|
|
|
<view class="tui-title required">团购库存</view>
|
|
|
<input
|
|
|
- v-model="goodsForm.stock"
|
|
|
+ :value="item.stock"
|
|
|
class="tui-input"
|
|
|
placeholder-class="phcolor"
|
|
|
- :placeholder="stockPlaceholder"
|
|
|
+ :placeholder="item.realStock > 0 ? '不超过实际库存' + item.realStock : '请输入团购库存'"
|
|
|
type="number"
|
|
|
+ :data-index="sIndex"
|
|
|
+ data-field="stock"
|
|
|
+ @input="onSpecInput"
|
|
|
/>
|
|
|
</tui-list-cell>
|
|
|
|
|
|
<tui-list-cell class="line-cell" :hover="false">
|
|
|
<view class="tui-title required">单人限购</view>
|
|
|
<input
|
|
|
- v-model="goodsForm.limit"
|
|
|
+ :value="item.limit"
|
|
|
class="tui-input"
|
|
|
placeholder-class="phcolor"
|
|
|
placeholder="请输入单人限购数量"
|
|
|
type="number"
|
|
|
+ :data-index="sIndex"
|
|
|
+ data-field="limit"
|
|
|
+ @input="onSpecInput"
|
|
|
/>
|
|
|
</tui-list-cell>
|
|
|
|
|
|
<tui-list-cell class="line-cell between" :hover="false">
|
|
|
<view class="tui-title">虚拟成团</view>
|
|
|
<view class="tui-operate switch-wrap">
|
|
|
- <switch :checked="goodsForm.virtualGroup == 1" color="#09C567" @change="onVirtualGroupChange" />
|
|
|
+ <switch
|
|
|
+ :checked="item.virtualGroup == 1"
|
|
|
+ color="#09C567"
|
|
|
+ :data-index="sIndex"
|
|
|
+ @change="onVirtualGroupChange"
|
|
|
+ />
|
|
|
</view>
|
|
|
</tui-list-cell>
|
|
|
|
|
|
- <tui-list-cell v-if="goodsForm.virtualGroup == 1" class="line-cell" :hover="false">
|
|
|
+ <tui-list-cell v-if="item.virtualGroup == 1" class="line-cell" :hover="false">
|
|
|
<view class="tui-title required">虚拟成团时间</view>
|
|
|
<input
|
|
|
- v-model="goodsForm.virtualMinutes"
|
|
|
+ :value="item.virtualMinutes"
|
|
|
class="tui-input"
|
|
|
placeholder-class="phcolor"
|
|
|
placeholder="请输入分钟数"
|
|
|
type="number"
|
|
|
+ :data-index="sIndex"
|
|
|
+ data-field="virtualMinutes"
|
|
|
+ @input="onSpecInput"
|
|
|
/>
|
|
|
<text class="unit-text">分钟</text>
|
|
|
</tui-list-cell>
|
|
|
|
|
|
- <tui-list-cell class="line-cell between" :hover="false" :last="true">
|
|
|
- <view class="tui-title">自动退款</view>
|
|
|
- <view class="tui-operate switch-wrap">
|
|
|
- <switch :checked="goodsForm.autoRefund == 1" color="#09C567" @change="onAutoRefundChange" />
|
|
|
- </view>
|
|
|
+ <tui-list-cell class="line-cell" :hover="false">
|
|
|
+ <view class="tui-title">商品原价格</view>
|
|
|
+ <view class="tui-input real-stock-text">{{ item.originPrice > 0 ? item.originPrice : '--' }}</view>
|
|
|
</tui-list-cell>
|
|
|
- </view>
|
|
|
|
|
|
- <view class="refund-tip">
|
|
|
- 开启后活动结束未拼成自动退款、拼成自动退差价
|
|
|
+ <tui-list-cell class="line-cell" :hover="false" :last="true">
|
|
|
+ <view class="tui-title">商品实际库存</view>
|
|
|
+ <view class="tui-input real-stock-text">{{ item.realStock > 0 ? item.realStock : '--' }}</view>
|
|
|
+ </tui-list-cell>
|
|
|
</view>
|
|
|
|
|
|
- <view v-if="goodsForm.realStock > 0" class="tip-text">商品实际库存:{{ goodsForm.realStock }}</view>
|
|
|
+ <view class="refund-tip">活动结束未拼成自动退款、拼成自动退差价</view>
|
|
|
|
|
|
<view class="bottom-bar">
|
|
|
<button class="admin-button-com big default bottom-btn" @click="cancelFn">取消</button>
|
|
|
@@ -104,24 +137,33 @@
|
|
|
|
|
|
<script>
|
|
|
import TuiListCell from '@/components/plugin/list-cell'
|
|
|
+import { getGoodsDetail } from '@/api/goods'
|
|
|
|
|
|
const DRAFT_KEY = 'groupBuyDraft'
|
|
|
const GROUP_SIZE_OPTIONS = [2, 3, 5]
|
|
|
|
|
|
-const EMPTY_GOODS = () => ({
|
|
|
+/** 空的商品基础信息(名称/封面等,多规格共用) */
|
|
|
+const EMPTY_BASE = () => ({
|
|
|
+ masterGoodsId: 0,
|
|
|
+ name: '',
|
|
|
+ cover: '',
|
|
|
+ status: 1
|
|
|
+})
|
|
|
+
|
|
|
+/** 空的规格填写表单(单规格时只有一项);autoRefund 统一固定为 1,不再由表单配置 */
|
|
|
+const EMPTY_SPEC_FORM = () => ({
|
|
|
+ id: 0, // 活动商品版本 id,编辑已有记录时回传后端
|
|
|
goodsId: 0,
|
|
|
+ specName: '',
|
|
|
price: '',
|
|
|
stock: '',
|
|
|
limit: '',
|
|
|
groupSize: 3,
|
|
|
virtualGroup: 0,
|
|
|
virtualMinutes: '',
|
|
|
- autoRefund: 0,
|
|
|
- status: 1,
|
|
|
- name: '',
|
|
|
- cover: '',
|
|
|
originPrice: 0,
|
|
|
- realStock: 0
|
|
|
+ realStock: 0,
|
|
|
+ cover: ''
|
|
|
})
|
|
|
|
|
|
export default {
|
|
|
@@ -131,18 +173,13 @@ export default {
|
|
|
return {
|
|
|
constant: this.$constant,
|
|
|
goodsIndex: -1,
|
|
|
- goodsForm: EMPTY_GOODS(),
|
|
|
+ goodsBase: EMPTY_BASE(),
|
|
|
+ // 单规格 1 项;多规格按规格数展开
|
|
|
+ specForms: [EMPTY_SPEC_FORM()],
|
|
|
+ isMultiSpec: false,
|
|
|
groupSizeOptions: GROUP_SIZE_OPTIONS
|
|
|
}
|
|
|
},
|
|
|
- computed: {
|
|
|
- stockPlaceholder() {
|
|
|
- if (this.goodsForm.realStock > 0) {
|
|
|
- return `不超过实际库存${this.goodsForm.realStock}`
|
|
|
- }
|
|
|
- return '请输入团购库存'
|
|
|
- }
|
|
|
- },
|
|
|
onLoad() {
|
|
|
uni.$on('categoryAdGoodsSelected', this.onGoodsSelected)
|
|
|
},
|
|
|
@@ -150,7 +187,10 @@ export default {
|
|
|
uni.$off('categoryAdGoodsSelected', this.onGoodsSelected)
|
|
|
},
|
|
|
methods: {
|
|
|
- /** 解析路由 index,从 groupBuyDraft 加载待编辑商品 */
|
|
|
+ /**
|
|
|
+ * 解析路由 index,从 groupBuyDraft 加载待编辑商品
|
|
|
+ * 编辑态按单条展示(列表中每规格已是独立一条)
|
|
|
+ */
|
|
|
init() {
|
|
|
this.goodsIndex = parseInt(this.option && this.option.index, 10)
|
|
|
if (isNaN(this.goodsIndex)) {
|
|
|
@@ -158,9 +198,33 @@ export default {
|
|
|
}
|
|
|
const draft = uni.getStorageSync(DRAFT_KEY) || {}
|
|
|
if (this.goodsIndex >= 0 && draft.goods && draft.goods[this.goodsIndex]) {
|
|
|
- this.goodsForm = { ...EMPTY_GOODS(), ...draft.goods[this.goodsIndex] }
|
|
|
+ const item = draft.goods[this.goodsIndex]
|
|
|
+ const groupSize = parseInt(item.groupSize, 10)
|
|
|
+ this.goodsBase = {
|
|
|
+ masterGoodsId: item.goodsId || 0,
|
|
|
+ name: item.name || '',
|
|
|
+ cover: item.cover || '',
|
|
|
+ status: item.status == 1 ? 1 : 0
|
|
|
+ }
|
|
|
+ this.isMultiSpec = false
|
|
|
+ this.specForms = [{
|
|
|
+ id: item.id || item.activityGoodsId || 0,
|
|
|
+ goodsId: item.goodsId || 0,
|
|
|
+ specName: item.specName || '',
|
|
|
+ price: item.price !== undefined && item.price !== null ? item.price : '',
|
|
|
+ stock: item.stock !== undefined && item.stock !== null ? item.stock : '',
|
|
|
+ limit: item.limit !== undefined && item.limit !== null ? item.limit : '',
|
|
|
+ groupSize: GROUP_SIZE_OPTIONS.indexOf(groupSize) > -1 ? groupSize : 3,
|
|
|
+ virtualGroup: item.virtualGroup == 1 ? 1 : 0,
|
|
|
+ virtualMinutes: item.virtualMinutes || '',
|
|
|
+ originPrice: item.originPrice || 0,
|
|
|
+ realStock: item.realStock || 0,
|
|
|
+ cover: item.cover || ''
|
|
|
+ }]
|
|
|
} else {
|
|
|
- this.goodsForm = EMPTY_GOODS()
|
|
|
+ this.goodsBase = EMPTY_BASE()
|
|
|
+ this.specForms = [EMPTY_SPEC_FORM()]
|
|
|
+ this.isMultiSpec = false
|
|
|
}
|
|
|
},
|
|
|
imgFullUrl(path) {
|
|
|
@@ -169,91 +233,192 @@ export default {
|
|
|
const base = (this.constant.imgUrl || '').replace(/\/$/, '')
|
|
|
return `${base}/${String(path).replace(/^\//, '')}`
|
|
|
},
|
|
|
+ /**
|
|
|
+ * 规格表单字段输入(小程序端 v-for 内不能直接 v-model 别名)
|
|
|
+ * 下标/字段名通过 data-index、data-field 传入
|
|
|
+ */
|
|
|
+ onSpecInput(e) {
|
|
|
+ const dataset = (e && e.currentTarget && e.currentTarget.dataset) || {}
|
|
|
+ const index = parseInt(dataset.index, 10)
|
|
|
+ const field = dataset.field
|
|
|
+ const value = e && e.detail ? e.detail.value : ''
|
|
|
+ if (isNaN(index) || !field || !this.specForms[index]) return
|
|
|
+ this.$set(this.specForms[index], field, value)
|
|
|
+ },
|
|
|
+ /** 选择成团人数:通过 data-index / data-size 更新对应规格表单 */
|
|
|
+ onGroupSizeClick(e) {
|
|
|
+ const dataset = (e && e.currentTarget && e.currentTarget.dataset) || {}
|
|
|
+ const index = parseInt(dataset.index, 10)
|
|
|
+ const size = parseInt(dataset.size, 10)
|
|
|
+ if (isNaN(index) || !this.specForms[index]) return
|
|
|
+ if (GROUP_SIZE_OPTIONS.indexOf(size) === -1) return
|
|
|
+ this.$set(this.specForms[index], 'groupSize', size)
|
|
|
+ },
|
|
|
+ /** 切换虚拟成团开关;关闭时清空虚拟成团分钟数 */
|
|
|
+ onVirtualGroupChange(e) {
|
|
|
+ const dataset = (e && e.currentTarget && e.currentTarget.dataset) || {}
|
|
|
+ const index = parseInt(dataset.index, 10)
|
|
|
+ if (isNaN(index) || !this.specForms[index]) return
|
|
|
+ const checked = e && e.detail ? !!e.detail.value : false
|
|
|
+ this.$set(this.specForms[index], 'virtualGroup', checked ? 1 : 0)
|
|
|
+ if (!checked) {
|
|
|
+ this.$set(this.specForms[index], 'virtualMinutes', '')
|
|
|
+ }
|
|
|
+ },
|
|
|
+ /** 跳转花束商品单选页(列表为主商品 masterId=0) */
|
|
|
selectGoods() {
|
|
|
+ const selectedId = this.goodsBase.masterGoodsId || (this.specForms[0] && this.specForms[0].goodsId) || ''
|
|
|
uni.navigateTo({
|
|
|
- url: `/admin/goods/ad-goods-select?mode=single&selectedIds=${this.goodsForm.goodsId || ''}`
|
|
|
+ url: `/admin/goods/ad-goods-select?mode=single&selectedIds=${selectedId}`
|
|
|
})
|
|
|
},
|
|
|
+ /**
|
|
|
+ * 接收商品选择结果:拉详情判断是否多规格,动态生成填写表单
|
|
|
+ * 多规格时每条子规格用自己的 goodsId/库存/原价
|
|
|
+ */
|
|
|
onGoodsSelected(payload) {
|
|
|
const g = (payload.goodsList || [])[0]
|
|
|
if (!g) return
|
|
|
- this.goodsForm.goodsId = g.id
|
|
|
- this.goodsForm.name = g.name || ''
|
|
|
- this.goodsForm.cover = g.cover || ''
|
|
|
- this.goodsForm.originPrice = g.price || 0
|
|
|
- this.goodsForm.realStock = parseInt(g.stock, 10) || 0
|
|
|
- },
|
|
|
- onVirtualGroupChange(e) {
|
|
|
- this.goodsForm.virtualGroup = e.detail.value ? 1 : 0
|
|
|
- if (!this.goodsForm.virtualGroup) {
|
|
|
- this.goodsForm.virtualMinutes = ''
|
|
|
- }
|
|
|
+ this.goodsBase.masterGoodsId = g.id
|
|
|
+ this.goodsBase.name = g.name || ''
|
|
|
+ this.goodsBase.cover = g.cover || ''
|
|
|
+ // 先用列表快照填一套单规格表单,详情返回后再按规格覆盖
|
|
|
+ this.isMultiSpec = false
|
|
|
+ this.specForms = [{
|
|
|
+ ...EMPTY_SPEC_FORM(),
|
|
|
+ goodsId: g.id,
|
|
|
+ originPrice: g.price || 0,
|
|
|
+ realStock: parseInt(g.stock, 10) || 0,
|
|
|
+ cover: g.cover || ''
|
|
|
+ }]
|
|
|
+ this.loadGoodsSpecs(g.id)
|
|
|
},
|
|
|
- onAutoRefundChange(e) {
|
|
|
- this.goodsForm.autoRefund = e.detail.value ? 1 : 0
|
|
|
+ /**
|
|
|
+ * 拉取商品详情,多规格则按 specList 展开多套表单
|
|
|
+ * @param {number} goodsId 主商品 id
|
|
|
+ */
|
|
|
+ loadGoodsSpecs(goodsId) {
|
|
|
+ if (!goodsId) return
|
|
|
+ getGoodsDetail({ id: goodsId }).then((res) => {
|
|
|
+ if (res.code !== 1 || !res.data) return
|
|
|
+ // 若用户已切换到其他商品,忽略过期回调
|
|
|
+ if (parseInt(goodsId, 10) !== parseInt(this.goodsBase.masterGoodsId, 10)) return
|
|
|
+ const data = res.data
|
|
|
+ const cover = data.shortCover || data.cover || this.goodsBase.cover || ''
|
|
|
+ this.goodsBase.name = data.name || this.goodsBase.name
|
|
|
+ this.goodsBase.cover = cover
|
|
|
+ const specList = Array.isArray(data.specList) ? data.specList : []
|
|
|
+ // 启用多规格且存在子规格:一套规格一张填写表单
|
|
|
+ if (Number(data.specEnabled) === 1 && specList.length > 0) {
|
|
|
+ this.isMultiSpec = true
|
|
|
+ this.specForms = specList.map((spec) => ({
|
|
|
+ ...EMPTY_SPEC_FORM(),
|
|
|
+ goodsId: spec.id || 0,
|
|
|
+ specName: spec.specName || '',
|
|
|
+ originPrice: spec.price || 0,
|
|
|
+ realStock: parseInt(spec.stock, 10) || 0,
|
|
|
+ cover: spec.shortCover || spec.cover || cover
|
|
|
+ }))
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.isMultiSpec = false
|
|
|
+ this.specForms = [{
|
|
|
+ ...EMPTY_SPEC_FORM(),
|
|
|
+ goodsId: data.id || goodsId,
|
|
|
+ originPrice: data.price || 0,
|
|
|
+ realStock: parseInt(data.stock, 10) || 0,
|
|
|
+ cover
|
|
|
+ }]
|
|
|
+ })
|
|
|
},
|
|
|
cancelFn() {
|
|
|
uni.navigateBack()
|
|
|
},
|
|
|
- /** 校验后写回 groupBuyDraft 并返回列表页 */
|
|
|
+ /**
|
|
|
+ * 校验全部规格表单后写回 groupBuyDraft
|
|
|
+ * 多规格保存为多条;autoRefund 统一写 1(产品要求默认自动退款)
|
|
|
+ */
|
|
|
saveFn() {
|
|
|
- const goodsId = parseInt(this.goodsForm.goodsId, 10) || 0
|
|
|
- const price = parseFloat(this.goodsForm.price)
|
|
|
- const stock = parseInt(this.goodsForm.stock, 10)
|
|
|
- const limit = parseInt(this.goodsForm.limit, 10)
|
|
|
- const groupSize = parseInt(this.goodsForm.groupSize, 10)
|
|
|
- const virtualMinutes = parseInt(this.goodsForm.virtualMinutes, 10)
|
|
|
- if (!goodsId) {
|
|
|
+ if (!this.goodsBase.masterGoodsId && !(this.specForms[0] && this.specForms[0].goodsId)) {
|
|
|
this.$msg('请选择活动商品')
|
|
|
return
|
|
|
}
|
|
|
- if (!price || price <= 0) {
|
|
|
- this.$msg('请输入团购价格')
|
|
|
- return
|
|
|
- }
|
|
|
- if (GROUP_SIZE_OPTIONS.indexOf(groupSize) === -1) {
|
|
|
- this.$msg('请选择成团人数')
|
|
|
- return
|
|
|
- }
|
|
|
- if (!stock || stock <= 0) {
|
|
|
- this.$msg('请输入团购库存')
|
|
|
- return
|
|
|
- }
|
|
|
- if (this.goodsForm.realStock > 0 && stock > this.goodsForm.realStock) {
|
|
|
- this.$msg(`团购库存不能超过实际库存(${this.goodsForm.realStock})`)
|
|
|
- return
|
|
|
- }
|
|
|
- if (!limit || limit <= 0) {
|
|
|
- this.$msg('请输入单人限购')
|
|
|
- return
|
|
|
- }
|
|
|
- if (this.goodsForm.virtualGroup == 1 && (!virtualMinutes || virtualMinutes <= 0)) {
|
|
|
- this.$msg('请填写虚拟成团时间')
|
|
|
- return
|
|
|
+ const items = []
|
|
|
+ for (let i = 0; i < this.specForms.length; i++) {
|
|
|
+ const form = this.specForms[i]
|
|
|
+ const label = this.isMultiSpec
|
|
|
+ ? `规格「${form.specName || (i + 1)}」`
|
|
|
+ : ''
|
|
|
+ const goodsId = parseInt(form.goodsId, 10) || 0
|
|
|
+ const price = parseFloat(form.price)
|
|
|
+ const stock = parseInt(form.stock, 10)
|
|
|
+ const limit = parseInt(form.limit, 10)
|
|
|
+ const groupSize = parseInt(form.groupSize, 10)
|
|
|
+ const virtualMinutes = parseInt(form.virtualMinutes, 10)
|
|
|
+ if (!goodsId) {
|
|
|
+ this.$msg(label ? `${label}商品无效,请重新选择` : '请选择活动商品')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (!price || price <= 0) {
|
|
|
+ this.$msg(label ? `请输入${label}团购价格` : '请输入团购价格')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (GROUP_SIZE_OPTIONS.indexOf(groupSize) === -1) {
|
|
|
+ this.$msg(label ? `请选择${label}成团人数` : '请选择成团人数')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (!stock || stock <= 0) {
|
|
|
+ this.$msg(label ? `请输入${label}团购库存` : '请输入团购库存')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // 团购库存不得超过该规格实际库存
|
|
|
+ if (form.realStock > 0 && stock > form.realStock) {
|
|
|
+ this.$msg(
|
|
|
+ label
|
|
|
+ ? `${label}团购库存不能超过实际库存(${form.realStock})`
|
|
|
+ : `团购库存不能超过实际库存(${form.realStock})`
|
|
|
+ )
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (!limit || limit <= 0) {
|
|
|
+ this.$msg(label ? `请输入${label}单人限购` : '请输入单人限购')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (form.virtualGroup == 1 && (!virtualMinutes || virtualMinutes <= 0)) {
|
|
|
+ this.$msg(label ? `请填写${label}虚拟成团时间` : '请填写虚拟成团时间')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // 列表展示名带规格后缀,便于区分同商品多规格
|
|
|
+ const displayName = form.specName
|
|
|
+ ? `${this.goodsBase.name}(${form.specName})` : this.goodsBase.name
|
|
|
+ items.push({
|
|
|
+ id: parseInt(form.id, 10) || 0,
|
|
|
+ goodsId,
|
|
|
+ price,
|
|
|
+ stock,
|
|
|
+ limit,
|
|
|
+ groupSize,
|
|
|
+ virtualGroup: form.virtualGroup == 1 ? 1 : 0,
|
|
|
+ virtualMinutes: form.virtualGroup == 1 ? virtualMinutes : 0,
|
|
|
+ // 自动退款统一开启,前端不再提供开关
|
|
|
+ autoRefund: 1,
|
|
|
+ status: this.goodsBase.status == 1 ? 1 : 0,
|
|
|
+ name: displayName,
|
|
|
+ cover: form.cover || this.goodsBase.cover,
|
|
|
+ originPrice: parseFloat(form.originPrice) || 0,
|
|
|
+ realStock: form.realStock || 0,
|
|
|
+ specName: form.specName || ''
|
|
|
+ })
|
|
|
}
|
|
|
const draft = uni.getStorageSync(DRAFT_KEY) || { goods: [] }
|
|
|
if (!Array.isArray(draft.goods)) {
|
|
|
draft.goods = []
|
|
|
}
|
|
|
- const item = {
|
|
|
- goodsId,
|
|
|
- price,
|
|
|
- stock,
|
|
|
- limit,
|
|
|
- groupSize,
|
|
|
- virtualGroup: this.goodsForm.virtualGroup == 1 ? 1 : 0,
|
|
|
- virtualMinutes: this.goodsForm.virtualGroup == 1 ? virtualMinutes : 0,
|
|
|
- autoRefund: this.goodsForm.autoRefund == 1 ? 1 : 0,
|
|
|
- status: this.goodsForm.status == 1 ? 1 : 0,
|
|
|
- name: this.goodsForm.name,
|
|
|
- cover: this.goodsForm.cover,
|
|
|
- originPrice: parseFloat(this.goodsForm.originPrice) || 0,
|
|
|
- realStock: this.goodsForm.realStock
|
|
|
- }
|
|
|
+ // 编辑态:用本次结果替换原位置(多规格重选时可能 1 变 N)
|
|
|
if (this.goodsIndex >= 0) {
|
|
|
- this.$set(draft.goods, this.goodsIndex, item)
|
|
|
+ draft.goods.splice(this.goodsIndex, 1, ...items)
|
|
|
} else {
|
|
|
- draft.goods.push(item)
|
|
|
+ draft.goods.push(...items)
|
|
|
}
|
|
|
draft._goodsUpdated = true
|
|
|
uni.setStorageSync(DRAFT_KEY, draft)
|
|
|
@@ -298,6 +463,27 @@ export default {
|
|
|
background: #f5f5f5;
|
|
|
}
|
|
|
|
|
|
+.spec-head {
|
|
|
+ @include disFlex(center, flex-start);
|
|
|
+ padding: 24upx 30upx 8upx;
|
|
|
+}
|
|
|
+
|
|
|
+.spec-head-label {
|
|
|
+ flex-shrink: 0;
|
|
|
+ font-size: 26upx;
|
|
|
+ color: $fontColor3;
|
|
|
+ margin-right: 12upx;
|
|
|
+}
|
|
|
+
|
|
|
+.spec-head-name {
|
|
|
+ font-size: 28upx;
|
|
|
+ color: #333;
|
|
|
+ font-weight: 500;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ white-space: nowrap;
|
|
|
+}
|
|
|
+
|
|
|
.segment-row {
|
|
|
padding: 26upx 30upx;
|
|
|
border-bottom: 1px solid $borderColor;
|
|
|
@@ -348,6 +534,11 @@ export default {
|
|
|
color: $fontColor3;
|
|
|
}
|
|
|
|
|
|
+.real-stock-text {
|
|
|
+ text-align: right;
|
|
|
+ color: $fontColor2;
|
|
|
+}
|
|
|
+
|
|
|
.refund-tip {
|
|
|
padding: 16upx 30upx 0;
|
|
|
font-size: 24upx;
|
|
|
@@ -355,12 +546,6 @@ export default {
|
|
|
line-height: 1.5;
|
|
|
}
|
|
|
|
|
|
-.tip-text {
|
|
|
- padding: 20upx 30upx;
|
|
|
- font-size: 24upx;
|
|
|
- color: $fontColor3;
|
|
|
-}
|
|
|
-
|
|
|
.bottom-bar {
|
|
|
position: fixed;
|
|
|
left: 0;
|