From a4b3ee325c7354579d495bc74a777e494e5ec38c Mon Sep 17 00:00:00 2001
From: quanwei <419654421@qq.com>
Date: Fri, 06 Feb 2026 18:18:44 +0800
Subject: [PATCH] 商品可以价格面议 选择走访时显示输入走访企业名 分会添加活动时要总会审核 分类添加人数限制,添加活动选择了填写人数限制的分类时活动名额下显示该分类人数限制为15 同一个企业30天内只能走访一次,在30天内走访同一个企业时提示该企业已被走访xx天后才可以从新走访

---
 mobile/pages/user/my_shop/product_edit.vue |  172 +++++++++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 141 insertions(+), 31 deletions(-)

diff --git a/mobile/pages/user/my_shop/product_edit.vue b/mobile/pages/user/my_shop/product_edit.vue
index 55b3dde..11e09eb 100644
--- a/mobile/pages/user/my_shop/product_edit.vue
+++ b/mobile/pages/user/my_shop/product_edit.vue
@@ -137,6 +137,8 @@
 							@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>
 
@@ -169,7 +171,7 @@
 				</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 }"
@@ -179,12 +181,17 @@
 					</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 }"
@@ -195,7 +202,7 @@
 				</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 }"
@@ -206,14 +213,14 @@
 				</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>
@@ -314,7 +321,9 @@
 						<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">
@@ -588,6 +597,7 @@
 						deduction_price: 0,
 						virtual_auto: 0,
 						virtual_content: '',
+						service_content: '',
 						is_preview: 0,
 						preview_time: '',
 						is_verify: 0,
@@ -904,12 +914,52 @@
 					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();
 						}
 					}
 				});
@@ -931,10 +981,32 @@
 					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'
+									});
+								}
+							});
 						}
 					}
 				});
@@ -943,11 +1015,13 @@
 			// 删除规格值
 			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列表
@@ -963,17 +1037,37 @@
 
 				// 生成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: ''
+						}
 					};
 				});
 
@@ -1174,13 +1268,28 @@
 						return;
 					}
 				}
+
+				// 转换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: '保存成功'
 						});
@@ -1431,7 +1540,8 @@
 
 	.radio-group {
 		display: flex;
-		gap: 40rpx;
+		gap: 15rpx;
+		flex-wrap: wrap;
 	}
 
 	.radio-item {

--
Gitblit v1.9.2