| | |
| | | |
| | | <view class="form-item" v-if="form.model.is_preview === 1"> |
| | | <view class="item-label">预告开启购买时间</view> |
| | | <picker mode="datetime" class="item-picker" @change="previewTimeChange" :value="previewTimeArray"> |
| | | <uni-datetime-picker class="item-picker" |
| | | :value="previewTime" |
| | | @change="previewTimeChange" |
| | | :start="'1970-01-01'" |
| | | :end="'2030-12-31'"> |
| | | <view class="picker-text">{{ previewTimeText || '请选择预告时间' }}</view> |
| | | </picker> |
| | | </uni-datetime-picker> |
| | | </view> |
| | | |
| | | <view class="form-item"> |
| | |
| | | @click="form.model.is_virtual = 1">虚拟商品</view> |
| | | <view class="radio-item" :class="{ active: form.model.is_virtual === 2 }" |
| | | @click="form.model.is_virtual = 2">券商品</view> |
| | | <view class="radio-item" :class="{ active: form.model.is_virtual === 3 }" |
| | | @click="form.model.is_virtual = 3">服务商品</view> |
| | | </view> |
| | | </view> |
| | | |
| | |
| | | </view> |
| | | |
| | | <!-- 虚拟商品设置 --> |
| | | <view class="form-item" v-if="form.model.is_virtual === 1"> |
| | | <view class="form-item" v-if="form.model.is_virtual === 1 || form.model.is_virtual === 3"> |
| | | <view class="item-label">发货类型</view> |
| | | <view class="radio-group"> |
| | | <view class="radio-item" :class="{ active: form.model.virtual_auto === 1 }" |
| | |
| | | </view> |
| | | </view> |
| | | |
| | | <view class="form-item" v-if="form.model.is_virtual === 1"> |
| | | <view class="form-item" v-if="form.model.is_virtual === 1 "> |
| | | <view class="item-label">虚拟内容</view> |
| | | <input class="item-input" v-model="form.model.virtual_content" placeholder="请输入虚拟物品内容" /> |
| | | </view> |
| | | |
| | | <view class="form-item" v-if="form.model.is_virtual === 1 && form.model.virtual_auto === 0"> |
| | | <view class="form-item" v-if=" form.model.is_virtual === 3"> |
| | | <view class="item-label">服务商品内容</view> |
| | | <input class="item-input" v-model="form.model.service_content" placeholder="请输入服务商品内容" /> |
| | | </view> |
| | | |
| | | <view class="form-item" v-if="(form.model.is_virtual === 1 || form.model.is_virtual === 3) && form.model.virtual_auto === 0"> |
| | | <view class="item-label">支持线下核销</view> |
| | | <view class="radio-group"> |
| | | <view class="radio-item" :class="{ active: form.model.is_verify === 1 }" |
| | |
| | | </view> |
| | | |
| | | <view class="form-item" |
| | | v-if="form.model.is_virtual === 1 && form.model.virtual_auto === 0 && form.model.is_verify === 1"> |
| | | v-if="(form.model.is_virtual === 1 || form.model.is_virtual === 3) && form.model.virtual_auto === 0 && form.model.is_verify === 1"> |
| | | <view class="item-label">核销到期类型</view> |
| | | <view class="radio-group"> |
| | | <view class="radio-item" :class="{ active: form.model.verify_type === 10 }" |
| | |
| | | </view> |
| | | |
| | | <view class="form-item" |
| | | v-if="form.model.is_virtual === 1 && form.model.virtual_auto === 0 && form.model.is_verify === 1 && form.model.verify_type === 10"> |
| | | v-if="(form.model.is_virtual === 1 || form.model.is_virtual === 3) && form.model.virtual_auto === 0 && form.model.is_verify === 1 && form.model.verify_type === 10"> |
| | | <view class="item-label">核销有效天数</view> |
| | | <input class="item-input" v-model="form.model.verify_day" placeholder="请输入有效天数,0或留空表示永久有效" |
| | | type="number" /> |
| | | </view> |
| | | |
| | | <view class="form-item" |
| | | v-if="form.model.is_virtual === 1 && form.model.virtual_auto === 0 && form.model.is_verify === 1 && form.model.verify_type === 20"> |
| | | v-if="(form.model.is_virtual === 1 || form.model.is_virtual === 3) && form.model.virtual_auto === 0 && form.model.is_verify === 1 && form.model.verify_type === 20"> |
| | | <view class="item-label">核销有效时间</view> |
| | | <picker mode="daterange" class="item-picker" @change="verifyTimeChange" :value="verifyTimeArray"> |
| | | <view class="picker-text">{{ verifyTimeText || '请选择核销有效时间' }}</view> |
| | |
| | | <view class="item-label">SKU列表</view> |
| | | <view class="sku-list"> |
| | | <view class="sku-item" v-for="(sku, index) in form.model.spec_many.spec_list" :key="index"> |
| | | <view class="sku-info">{{ sku.spec_text }}</view> |
| | | <view class="sku-info"> |
| | | <text v-for="(row, rowIdx) in sku.rows" :key="rowIdx">{{ row.spec_value }}{{ rowIdx < sku.rows.length - 1 ? ' ' : '' }}</text> |
| | | </view> |
| | | <view class="form-item"> |
| | | <view class="item-label">规格图片</view> |
| | | <view class="uploader"> |
| | |
| | | <view class="form-item"> |
| | | <view class="item-label">详情类型</view> |
| | | <view class="radio-group"> |
| | | <view class="radio-item" :class="{ active: form.model.content_type === 10 }" |
| | | @click="form.model.content_type = 10">图文</view> |
| | | <view class="radio-item" :class="{ active: form.model.content_type === 20 }" |
| | | @click="form.model.content_type = 20">纯图</view> |
| | | <view class="radio-item" :class="{ active: form.model.is_picture == 0 }" |
| | | @click="form.model.is_picture = 0">图文</view> |
| | | <view class="radio-item" :class="{ active: form.model.is_picture == 1 }" |
| | | @click="form.model.is_picture = 1">纯图</view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 图文类型 --> |
| | | <view v-if="form.model.content_type === 10" class="form-item"> |
| | | <view v-if="form.model.is_picture == 0" class="form-item"> |
| | | <view class="item-label">商品详情</view> |
| | | <view class="editor"> |
| | | <!-- 富文本编辑器 --> |
| | |
| | | </view> |
| | | |
| | | <!-- 纯图类型 --> |
| | | <view v-else-if="form.model.content_type === 20" class="form-item"> |
| | | <view v-else-if="form.model.is_picture == 1" class="form-item"> |
| | | <view class="item-label">商品详情图片</view> |
| | | <view class="uploader"> |
| | | <view class="uploader-item" v-for="(item, index) in form.model.contentImage" :key="index"> |
| | |
| | | <view class="item-label">积分设置</view> |
| | | <view class="switch-item"> |
| | | <view class="switch-label">开启积分赠送</view> |
| | | <switch v-model="form.model.is_points_gift" /> |
| | | <switch :checked="form.model.is_points_gift" v-model="form.model.is_points_gift" /> |
| | | </view> |
| | | <view class="switch-item"> |
| | | <view class="switch-label">允许积分抵扣</view> |
| | |
| | | <view class="item-label">团队分红设置</view> |
| | | <view class="switch-item"> |
| | | <view class="switch-label">是否参与团队分红</view> |
| | | <switch checked v-model="form.model.is_enable_team" /> |
| | | <switch :checked="form.model.is_enable_team==1?true:false" v-model="form.model.is_enable_team" /> |
| | | </view> |
| | | </view> |
| | | </view> |
| | |
| | | deliveryIndex: 0, |
| | | // 预告时间相关 |
| | | previewTimeArray: [now.getFullYear(), now.getMonth(), now.getDate(), now.getHours(), now.getMinutes()], |
| | | previewTime: '', |
| | | previewTimeText: '', |
| | | // 核销时间相关 |
| | | verifyTimeArray: [], |
| | |
| | | selling_point: '', |
| | | spec_type: 10, |
| | | deduct_stock_type: 20, |
| | | content_type: 10, |
| | | is_picture: 0, |
| | | sku: { |
| | | product_no: '', |
| | | product_price: '', |
| | |
| | | deduction_price: 0, |
| | | virtual_auto: 0, |
| | | virtual_content: '', |
| | | service_content: '', |
| | | is_preview: 0, |
| | | preview_time: '', |
| | | is_verify: 0, |
| | |
| | | product_id: self.productId |
| | | }, (res) => { |
| | | // 合并默认值和后端返回的数据,确保 spec_many 字段始终存在 |
| | | Object.assign(self.form, res.data); |
| | | self.form.model = Object.assign({ |
| | | spec_many: { |
| | | spec_attr: [], |
| | | spec_list: [] |
| | | } |
| | | }, res.data.model); |
| | | |
| | | // 处理单规格商品的 sku 字段,后端返回的是数组,前端需要对象 |
| | | if (self.form.model.spec_type === 10 && Array.isArray(self.form.model.sku) && self.form.model.sku.length > 0) { |
| | | self.form.model.sku = self.form.model.sku[0]; |
| | | } |
| | | self.form.model.product_status = res.data.model.product_status.value; |
| | | if(self.form.model.delivery_id == 0){ |
| | | self.$set(self.form.model, 'is_delivery_free', 0); |
| | | }else{ |
| | | self.$set(self.form.model, 'is_delivery_free', 1); |
| | | } |
| | | if(self.form.model.notice == null){ |
| | | self.form.model.notice = []; |
| | | } |
| | | //修改时审核状态 |
| | | if(self.form.audit_setting.edit_audit == 1 && self.form.scene != 'add'){ |
| | | self.form.model.audit_status = 0; |
| | | } |
| | | if (self.form.model.content) { |
| | | setTimeout(function(){ |
| | | self.editorCtx.setContents({ |
| | | html: self.form.model.content |
| | | }); |
| | | },1000) |
| | | } |
| | | // 设置分类索引 |
| | | self.categoryIndex = self.form.category.findIndex(item => item.category_id === self.form |
| | | .model.category_id); |
| | | self.selectedCategory = self.form.category[self.categoryIndex]?.category_name; |
| | | self.selectedCategory = self.form.category[self.categoryIndex]?.name; |
| | | // 设置运费模板索引 |
| | | self.deliveryIndex = self.form.delivery.findIndex(item => item.delivery_id === self.form |
| | | .model.delivery_id); |
| | | self.selectedDelivery = self.form.delivery[self.deliveryIndex]?.delivery_name; |
| | | self.selectedDelivery = self.form.delivery[self.deliveryIndex]?.name; |
| | | // 设置预告时间 |
| | | if (self.form.model.is_preview === 1 && self.form.model.preview_time) { |
| | | const previewDate = new Date(self.form.model.preview_time * 1000); |
| | | self.previewTime = previewDate.toISOString().slice(0, 16); |
| | | self.previewTimeText = self.previewTime; |
| | | } |
| | | self.loading = false; |
| | | }); |
| | | }, |
| | |
| | | // 选择预告时间 |
| | | previewTimeChange(e) { |
| | | const date = new Date(e.detail.value); |
| | | this.form.model.preview_time = date.toISOString().slice(0, 19).replace('T', ' '); |
| | | this.previewTimeText = |
| | | `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')} ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`; |
| | | this.form.model.preview_time = Math.floor(date.getTime() / 1000); |
| | | this.previewTime = e.detail.value; |
| | | this.previewTimeText = e.detail.value; |
| | | }, |
| | | |
| | | // 选择视频 |
| | |
| | | placeholderText: '例如:颜色', |
| | | success: (res) => { |
| | | if (res.confirm && res.content.trim()) { |
| | | this.form.model.spec_many.spec_attr.push({ |
| | | name: res.content.trim(), |
| | | values: [] |
| | | const specName = res.content.trim(); |
| | | // 继续输入第一个规格值 |
| | | uni.showModal({ |
| | | title: '添加第一个规格值', |
| | | content: '', |
| | | editable: true, |
| | | placeholderText: '例如:红色', |
| | | success: (valueRes) => { |
| | | if (valueRes.confirm && valueRes.content.trim()) { |
| | | const specValue = valueRes.content.trim(); |
| | | // 调用API添加规格组和第一个规格值 |
| | | this._post('supplier.product.spec/addSpec', { |
| | | spec_name: specName, |
| | | spec_value: specValue |
| | | }, (response) => { |
| | | if (response.code === 1 && response.data) { |
| | | this.form.model.spec_many.spec_attr.push({ |
| | | group_id: response.data.spec_id, |
| | | name: specName, |
| | | values: [specValue], |
| | | items: [{ |
| | | item_id: response.data.spec_value_id, |
| | | spec_value: specValue |
| | | }] |
| | | }); |
| | | // 生成SKU列表 |
| | | this.generateSkuList(); |
| | | uni.showToast({ |
| | | title: '添加成功', |
| | | icon: 'success' |
| | | }); |
| | | } else { |
| | | uni.showToast({ |
| | | title: response.msg || '添加失败', |
| | | icon: 'none' |
| | | }); |
| | | } |
| | | }); |
| | | } else if (valueRes.confirm) { |
| | | uni.showToast({ |
| | | title: '请输入规格值', |
| | | icon: 'none' |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | // 生成SKU列表 |
| | | this.generateSkuList(); |
| | | } |
| | | } |
| | | }); |
| | |
| | | placeholderText: '例如:红色', |
| | | success: (res) => { |
| | | if (res.confirm && res.content.trim()) { |
| | | const specValue = res.content.trim(); |
| | | const attr = this.form.model.spec_many.spec_attr[attrIndex]; |
| | | attr.values.push(res.content.trim()); |
| | | // 重新生成SKU列表 |
| | | this.generateSkuList(); |
| | | // 调用API添加规格值 |
| | | this._post('supplier.product.spec/addSpecValue', { |
| | | spec_id: attr.group_id, |
| | | spec_value: specValue |
| | | }, (response) => { |
| | | if (response.code === 1 && response.data) { |
| | | attr.values.push(specValue); |
| | | attr.items.push({ |
| | | item_id: response.data.spec_value_id, |
| | | spec_value: specValue |
| | | }); |
| | | // 重新生成SKU列表 |
| | | this.generateSkuList(); |
| | | uni.showToast({ |
| | | title: '添加成功', |
| | | icon: 'success' |
| | | }); |
| | | } else { |
| | | uni.showToast({ |
| | | title: response.msg || '添加失败', |
| | | icon: 'none' |
| | | }); |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | |
| | | // 删除规格值 |
| | | deleteSpecValue(attrIndex, valueIndex) { |
| | | const attr = this.form.model.spec_many.spec_attr[attrIndex]; |
| | | if (attr.values.length > 1) { |
| | | attr.values.splice(valueIndex, 1); |
| | | // 重新生成SKU列表 |
| | | this.generateSkuList(); |
| | | attr.values.splice(valueIndex, 1); |
| | | if (attr.items && attr.items.length > valueIndex) { |
| | | |
| | | attr.items.splice(valueIndex, 1); |
| | | } |
| | | // 重新生成SKU列表 |
| | | this.generateSkuList(); |
| | | }, |
| | | |
| | | // 生成SKU列表 |
| | |
| | | |
| | | // 生成SKU列表 |
| | | const skuList = combinations.map(comb => { |
| | | const spec_text = comb.map((val, idx) => `${attrs[idx].name}:${val}`).join('; '); |
| | | const rows = []; |
| | | const specSkuIdAttr = []; |
| | | |
| | | comb.forEach((val, idx) => { |
| | | const attr = attrs[idx]; |
| | | // 查找对应的 item_id |
| | | const itemIndex = attr.values.indexOf(val); |
| | | const itemId = (attr.items && attr.items[itemIndex]) ? attr.items[itemIndex].item_id : 0; |
| | | |
| | | rows.push({ |
| | | item_id: itemId, |
| | | spec_value: val |
| | | }); |
| | | specSkuIdAttr.push(itemId); |
| | | }); |
| | | |
| | | const spec_sku_id = specSkuIdAttr.join('_'); |
| | | |
| | | return { |
| | | spec_text, |
| | | product_sku_id: 0, |
| | | spec_sku_id, |
| | | rows, |
| | | image: [], |
| | | product_no: '', |
| | | price: '', |
| | | line_price: '', |
| | | stock: '', |
| | | weight: '', |
| | | cost_price: '', |
| | | bar_code: '' |
| | | spec_form: { |
| | | product_no: '', |
| | | product_price: '', |
| | | line_price: '', |
| | | stock_num: '', |
| | | product_weight: '', |
| | | bar_code: '' |
| | | } |
| | | }; |
| | | }); |
| | | |
| | |
| | | save() { |
| | | let self = this; |
| | | // 先获取富文本编辑器内容 |
| | | if (self.form.model.content_type === 10 && self.editorCtx) { |
| | | if (self.form.model.is_picture == 0 && self.editorCtx) { |
| | | // 图文类型,获取编辑器内容 |
| | | self.editorCtx.getContents({ |
| | | success: (res) => { |
| | |
| | | } |
| | | |
| | | // 根据详情类型验证内容 |
| | | if (self.form.model.content_type === 10) { |
| | | if (self.form.model.is_picture == 0) { |
| | | // 图文类型,验证富文本内容 |
| | | if (!self.form.model.content || self.form.model.content.trim() === '') { |
| | | uni.showToast({ |
| | |
| | | }); |
| | | return; |
| | | } |
| | | } else if (self.form.model.content_type === 20) { |
| | | } else if (self.form.model.is_picture == 1) { |
| | | // 纯图类型,验证详情图片 |
| | | if (self.form.model.contentImage.length === 0) { |
| | | uni.showToast({ |
| | |
| | | } |
| | | } |
| | | |
| | | // 转换spec_attr数据格式为后端期望的格式 |
| | | let submitData = JSON.parse(JSON.stringify(self.form.model)); |
| | | if (submitData.spec_type == 20 && submitData.spec_many && submitData.spec_many.spec_attr) { |
| | | submitData.spec_many.spec_attr = submitData.spec_many.spec_attr.map(attr => { |
| | | return { |
| | | group_id: attr.group_id || 0, |
| | | name: attr.name, |
| | | spec_items: attr.values.map((val, idx) => ({ |
| | | item_id: (attr.items && attr.items[idx] && attr.items[idx].item_id) ? attr.items[idx].item_id : 0, |
| | | spec_value: val |
| | | })) |
| | | }; |
| | | }); |
| | | } |
| | | |
| | | self.loading = true; |
| | | self._post('supplier.product/edit', { |
| | | product_id: self.productId, |
| | | params: JSON.stringify(self.form.model) |
| | | params: JSON.stringify(submitData) |
| | | }, (res) => { |
| | | if (res.code === 0) { |
| | | if (res.code === 1) { |
| | | uni.showToast({ |
| | | title: '保存成功' |
| | | }); |
| | |
| | | |
| | | .radio-group { |
| | | display: flex; |
| | | gap: 40rpx; |
| | | gap: 15rpx; |
| | | flex-wrap: wrap; |
| | | } |
| | | |
| | | .radio-item { |