From da1e3dbfc622f7f581d19a56c7e4d3abe13563e1 Mon Sep 17 00:00:00 2001
From: xiangpei <xiangpei@timesnew.cn>
Date: 星期三, 09 七月 2025 18:02:59 +0800
Subject: [PATCH] 上家发布商品功能

---
 pages/supplier/publish-goods/goodsInfo.vue      |  877 +++++++++++++++++++++++++++++++++++++++++++++++++++
 pages/supplier/publish-goods/chooseCategery.vue |    7 
 pages.json                                      |    9 
 pages/goods-manager/goodsList/goodsList.vue     |    2 
 api/store.js                                    |   32 +
 pages/tabbar/index/home.vue                     |    3 
 pages/supplier/publish-goods/publishGoods.vue   |   60 +++
 7 files changed, 981 insertions(+), 9 deletions(-)

diff --git a/api/store.js b/api/store.js
index 61c57b8..6edae68 100644
--- a/api/store.js
+++ b/api/store.js
@@ -67,5 +67,37 @@
   });
 }
 
+/**
+ * 鑾峰彇鐗╂祦妯℃澘
+ *
+ */
+ export function getFreightTemplate() {
+  return http.request({
+    url: `/store/store/freightTemplate`,
+    method: Method.GET
+  });
+}
 
+/**
+ * 鑾峰彇璁¢噺鍗曚綅
+ *
+ */
+ export function getGoodsUnit(param) {
+  return http.request({
+    url: `/store/store/goods/unit`,
+    method: Method.GET,
+	param: param
+  });
+}
 
+/**
+ * 鍙戝竷鍟嗗搧
+ *
+ */
+ export function createGoods(data) {
+  return http.request({
+    url: `/store/store/goods/create`,
+    method: Method.POST,
+	data: data
+  });
+}
diff --git a/pages.json b/pages.json
index 869ae4a..a13330e 100644
--- a/pages.json
+++ b/pages.json
@@ -240,7 +240,7 @@
 			}
 		},
 		{
-			"path": "pages/goods-manager/addGoods/addGoods",
+			"path": "pages/supplier/publish-goods/publishGoods",
 			"style": {
 				"enablePullDownRefresh": true,
 				"navigationBarTitleText": "鏂板鍟嗗搧",
@@ -366,6 +366,13 @@
 					"u-switch": "view"
 				}
 			}
+		},
+		{
+			"path" : "pages/supplier/publish-goods/goodsInfo",
+			"style" : 
+			{
+				"navigationBarTitleText" : ""
+			}
 		}
 	],
 	"subPackages": [
diff --git a/pages/goods-manager/goodsList/goodsList.vue b/pages/goods-manager/goodsList/goodsList.vue
index 9e62ee5..761771f 100644
--- a/pages/goods-manager/goodsList/goodsList.vue
+++ b/pages/goods-manager/goodsList/goodsList.vue
@@ -158,7 +158,7 @@
 		},
 		addGoods(id) {
 			uni.navigateTo({
-				url: `/pages/goods-manager/addGoods/addGoods${id ? "?id=" + id : ""}`,
+				url: `/pages/supplier/publish-goods/publishGoods`,
 			});
 		}
 
diff --git a/pages/supplier/publish-goods/chooseCategery.vue b/pages/supplier/publish-goods/chooseCategery.vue
index fe09eff..c32acea 100644
--- a/pages/supplier/publish-goods/chooseCategery.vue
+++ b/pages/supplier/publish-goods/chooseCategery.vue
@@ -16,7 +16,7 @@
 <script>
 	import {
 		getMyActivityList
-	} from '@/api/merchant.js'
+	} from '@/api/supplier.js'
 	export default {
 		data() {
 			return {
@@ -27,9 +27,14 @@
 			}
 		},
 		methods:{
+			// 鐖剁粍浠惰幏鍙栭�夋嫨鐨勫垎绫�
+			getCategery() {
+				return this.chooseCategeryId
+			},
 			chooseCategery(id,name){
 				this.chooseCategeryId =id
 				this.categeryName = name
+				this.$emit("choose", this.chooseCategeryId)
 			}
 		},
 		async mounted() {
diff --git a/pages/supplier/publish-goods/goodsInfo.vue b/pages/supplier/publish-goods/goodsInfo.vue
new file mode 100644
index 0000000..99ffcf2
--- /dev/null
+++ b/pages/supplier/publish-goods/goodsInfo.vue
@@ -0,0 +1,877 @@
+<template>
+  <view class="add-product-container">
+    <scroll-view scroll-y class="scroll-view">
+      <view class="form-section">
+        <!-- 鍩烘湰淇℃伅 -->
+        <view class="section-title">鍩烘湰淇℃伅</view>
+        <view class="form-item">
+          <text class="label">鍟嗗搧鍚嶇О</text>
+          <input v-model="formData.goodsName" placeholder="璇疯緭鍏ュ晢鍝佸悕绉�" class="input" />
+        </view>
+        
+        <view class="form-item">
+          <text class="label">鍟嗗搧浠锋牸</text>
+		  <view style="display: flex;align-items: center;">
+			  <input v-model="formData.price" type="number" placeholder="璇疯緭鍏ュ晢鍝佷环鏍�" class="input" />
+			  <text class="unit">鍏�</text>
+		  </view>
+        </view>
+        
+        <view class="form-item">
+          <text class="label">鎶芥垚姣斾緥</text>
+		  <view style="display: flex;align-items: center;">
+			  <input v-model="formData.commission" type="number" placeholder="璇疯緭鍏ユ娊鎴愭瘮渚�" class="input" />
+			  <text class="unit">%</text>
+		  </view>
+          
+        </view>
+        
+        <view class="form-item">
+          <text class="label">鍟嗗搧鍗栫偣鎻忚堪</text>
+          <textarea v-model="formData.sellingPoint" placeholder="璇疯緭鍏ュ晢鍝佸崠鐐规弿杩�" class="textarea" />
+        </view>
+        
+        <view class="form-item">
+          <text class="label">璁¢噺鍗曚綅</text>
+          <picker @change="onUnitChange" :value="unitIndex" :range="unitOptions" range-key="name" class="picker">
+            <view class="picker-text">{{goodsUnit ? goodsUnit.name : '璇烽�夋嫨璁¢噺鍗曚綅'}}</view>
+          </picker>
+        </view>
+        
+        <view class="form-item">
+          <text class="label">閿�鍞ā寮�</text>
+          <radio-group @change="onSalesModeChange" class="radio-group">
+            <label class="radio-label">
+              <radio value="RETAIL" :checked="formData.salesModel === 'RETAIL'" /> 闆跺敭
+            </label>
+            <label class="radio-label">
+              <radio value="PRESALE" :checked="formData.salesModel === 'PRESALE'" /> 棰勫敭
+            </label>
+          </radio-group>
+        </view>
+        
+        <view class="form-item" v-if="formData.salesModel === 'PRESALE'">
+          <text class="label">棰勫敭鏃堕棿娈�</text>
+		  <view class="date-range-picker">
+			<view class="date-picker-item">
+			  <text class="date-label">寮�濮嬫棩鏈�</text>
+			  <picker mode="date" @change="onPresaleStartDateChange" class="picker">
+				<view class="picker-text">{{formData.presaleStartDate || '璇烽�夋嫨寮�濮嬫棩鏈�'}}</view>
+			  </picker>
+			</view>
+			<view class="date-picker-item">
+			  <text class="date-label">缁撴潫鏃ユ湡</text>
+			  <picker mode="date" @change="onPresaleEndDateChange" class="picker">
+				<view class="picker-text">{{formData.presaleEndDate || '璇烽�夋嫨缁撴潫鏃ユ湡'}}</view>
+			  </picker>
+			</view>
+		  </view>
+        </view>
+        
+        <!-- 鍟嗗搧涓诲浘 -->
+        <view class="form-item">
+          <text class="label">鍟嗗搧涓诲浘</text>
+          <view class="upload-container">
+            <image v-for="img in formData.goodsGalleryList" :key="img" :src="endpoint + '/' + img" class="uploaded-image" mode="aspectFill" />
+            <view class="upload-btn" @click="uploadMainImage">
+              <uni-icons type="plusempty" size="30" color="#999"></uni-icons>
+              <text class="upload-text">{{formData.goodsGalleryList.length < 1 ? '涓婁紶涓诲浘' : '閲嶆柊涓婁紶'}}</text>
+            </view>
+          </view>
+        </view>
+        
+        <!-- 鍟嗗搧瑙嗛 -->
+        <view class="form-item">
+          <text class="label">鍟嗗搧瑙嗛</text>
+          <view class="upload-container">
+            <video v-show="formData.goodsVideo" :src="endpoint + '/' + formData.goodsVideo" class="uploaded-video" controls></video>
+            <view class="upload-btn" @click="uploadVideo">
+              <uni-icons type="videocam" size="30" color="#999"></uni-icons>
+              <text class="upload-text">{{formData.goodsVideo ? '閲嶆柊涓婁紶' : '涓婁紶瑙嗛'}}</text>
+            </view>
+			<progress v-show="videoUploading" style="width: 100%;" :percent="videoUploadProgress" active-mode="forwards" show-info stroke-width="6" :active="true" active-color="#ff573e" />
+          </view>
+        </view>
+        
+        <!-- 瑙勬牸璁剧疆 -->
+        <view class="section-title">瑙勬牸璁剧疆</view>
+        <view class="specs-container">
+          <view class="spec-item" v-for="(spec, specIndex) in formData.specs" :key="specIndex">
+            <view class="spec-header">
+              <input v-model="spec.name" placeholder="瑙勬牸椤瑰悕绉�" class="spec-input" />
+              <uni-icons type="trash" size="20" color="#f56c6c" @click="removeSpec(specIndex)"></uni-icons>
+            </view>
+            <view class="spec-values">
+              <view class="spec-value-tag" v-for="(value, valueIndex) in spec.values" :key="valueIndex">
+                <input v-model="spec.values[valueIndex]" placeholder="瑙勬牸鍊�" class="value-input" />
+                <uni-icons type="clear" size="16" color="#999" @click="removeSpecValue(specIndex, valueIndex)"></uni-icons>
+              </view>
+              <view class="add-value-btn" @click="addSpecValue(specIndex)">
+                <uni-icons type="plusempty" size="16" color="#409eff"></uni-icons>
+                <text>娣诲姞瑙勬牸鍊�</text>
+              </view>
+            </view>
+          </view>
+          
+          <view class="add-spec-btn" @click="addSpec">
+            <uni-icons type="plusempty" size="16" color="#409eff"></uni-icons>
+            <text>娣诲姞瑙勬牸椤�</text>
+          </view>
+        </view>
+        
+        <!-- 瑙勬牸缁勫悎 -->
+        <view class="section-title" v-if="hasSpecs">瑙勬牸缁勫悎</view>
+        <view class="sku-container" v-if="hasSpecs">
+          <view class="sku-item" v-for="(sku, skuIndex) in formData.skuList" :key="skuIndex">
+            <view class="sku-title">{{sku.specValues.join(' / ')}}</view>
+            <view class="sku-form">
+              <view class="sku-form-item">
+                <text class="sku-label">浠锋牸</text>
+				<view style="display: flex;align-items: center;">
+					<input v-model="sku.price" type="number" placeholder="浠锋牸" class="sku-input" />
+					<text class="sku-unit">鍏�</text>
+				</view>
+              </view>
+              <view class="sku-form-item">
+                <text class="sku-label">閲嶉噺</text>
+				<view style="display: flex;align-items: center;">
+					<input v-model="sku.weight" type="number" placeholder="閲嶉噺" class="sku-input" />
+					<text class="sku-unit">鍏�</text>
+				</view>
+              </view>
+              <view class="sku-form-item">
+                <text class="sku-label">搴撳瓨</text>
+				<view style="display: flex;align-items: center;">
+					<input v-model="sku.quantity" type="number" placeholder="搴撳瓨" class="sku-input" />
+					<text class="sku-unit">浠�</text>
+				</view>
+              </view>
+              <view class="sku-form-item">
+                <text class="sku-label">璐у彿</text>
+                <input v-model="sku.sn" placeholder="璐у彿" class="sku-input" />
+              </view>
+            </view>
+          </view>
+        </view>
+        
+        <!-- 鍟嗗搧鎻忚堪 -->
+        <view class="section-title">鍟嗗搧鎻忚堪</view>
+        <view class="form-item">
+          <editor 
+            id="editor" 
+            class="editor" 
+            placeholder="璇疯緭鍏ュ晢鍝佽缁嗘弿杩�" 
+            @ready="onEditorReady"
+            @input="onEditorInput">
+          </editor>
+        </view>
+        
+        <!-- 鐗╂祦妯℃澘 -->
+        <view class="section-title">鐗╂祦妯℃澘</view>
+        <view class="form-item">
+          <picker @change="onTemplateChange" :value="templateIndex" :range="templateOptions" range-key="name" class="picker">
+            <view class="picker-text">{{shippingTemplate ? shippingTemplate.name : '璇烽�夋嫨鐗╂祦妯℃澘'}}</view>
+          </picker>
+        </view>
+      </view>
+      
+      <view class="submit-btn-container">
+        <button type="primary" class="submit-btn" @click="submitForm">鎻愪氦鍟嗗搧</button>
+      </view>
+    </scroll-view>
+  </view>
+</template>
+
+<script>
+	import { getFreightTemplate, getGoodsUnit } from "@/api/store.js"
+	import { getSTSToken } from "@/api/common.js";
+	import { getFileKey } from "@/utils/file.js";
+export default {
+  data() {
+    return {
+      formData: {
+		goodsType: "PHYSICAL_GOODS",
+		updateSku: true,
+		regeneratorSkuFlag: true,
+        goodsName: '', // 鍟嗗搧鍚嶇О
+        price: '', // 鍟嗗搧浠锋牸
+        commission: '', // 鎶芥垚姣斾緥
+        sellingPoint: '', // 鍗栫偣鎻忚堪
+        goodsUnit: '', // 璁¢噺鍗曚綅
+        salesModel: 'RETAIL', // 閿�鍞ā寮�
+		preSaleTime: [], // 棰勫敭鏃堕棿
+        presaleStartDate: '', // 棰勫敭寮�濮嬫棩鏈�
+		presaleEndDate: '', // 棰勫敭缁撴潫鏃ユ湡
+        goodsGalleryList: [], // 涓诲浘
+        goodsVideo: '', // 瑙嗛
+        specs: [], // 瑙勬牸椤�
+        skuList: [], // SKU鍒楄〃
+        mobileIntro: '', // 鍟嗗搧鎻忚堪
+        templateId: null, // 鐗╂祦妯℃澘
+		release: true, // 绔嬪嵆鍙戝竷
+		recommend: false,
+      },
+	  shippingTemplate: null, // 閫変腑鐨勭墿娴佹ā鏉�
+	  goodsUnit: null, // 閫変腑鐨勮閲忓崟浣�
+      unitOptions: [],
+      unitIndex: -1,
+      templateOptions: [], // 鐗╂祦妯℃澘閫夐」
+      templateIndex: -1,
+      editorCtx: null,
+	  cosClient: null,
+	  bucket: '',
+	  region: '',
+	  endpoint: '',
+	  videoUploadProgress: 0,
+	  videoUploading: false
+    }
+  },
+  computed: {
+    hasSpecs() {
+      return this.formData.specs.length > 0
+    }
+  },
+  mounted() {
+    this.loadShippingTemplates()
+    this.loadGoodsUnit()
+	this.initCOS()
+  },
+  methods: {
+	// 鍒濆鍖栬吘璁簯cos瀹㈡埛绔�
+	async initCOS() {
+		  // 璋冪敤鍚庣鑾峰彇sts涓存椂璁块棶鍑瘉
+		  getSTSToken().then(res => {
+			  const COS = require('@/lib/cos-wx-sdk-v5.js'); // 寮�鍙戞椂浣跨敤
+			  // const COS = require('./lib/cos-wx-sdk-v5.min.js'); // 涓婄嚎鏃朵娇鐢ㄥ帇缂╁寘
+
+			  // console.log(COS.version);  sdk 鐗堟湰闇�瑕佷笉浣庝簬 1.7.2
+			  this.cosClient = new COS({
+				  SecretId: res.data.data.tmpSecretId, // sts 鏈嶅姟涓嬪彂鐨勪复鏃� secretId
+				  SecretKey: res.data.data.tmpSecretKey, // sts 鏈嶅姟涓嬪彂鐨勪复鏃� secretKey
+				  SecurityToken: res.data.data.sessionToken, // sts 鏈嶅姟涓嬪彂鐨勪复鏃� SessionToken
+				  StartTime: res.data.data.stsStartTime, // 寤鸿浼犲叆鏈嶅姟绔椂闂达紝鍙伩鍏嶅鎴风鏃堕棿涓嶅噯瀵艰嚧鐨勭鍚嶉敊璇�
+				  ExpiredTime: res.data.data.stsEndTime, // 涓存椂瀵嗛挜杩囨湡鏃堕棿
+				  SimpleUploadMethod: 'putObject', // 寮虹儓寤鸿锛岄珮绾т笂浼犮�佹壒閲忎笂浼犲唴閮ㄥ灏忔枃浠跺仛绠�鍗曚笂浼犳椂浣跨敤 putObject,sdk 鐗堟湰鑷冲皯闇�瑕乿1.3.0
+			   });
+			   this.bucket = res.data.data.bucket
+			   this.region = res.data.data.region
+			   this.endpoint = res.data.data.endpoint
+		  })
+	},
+    // 鍔犺浇鐗╂祦妯℃澘
+    async loadShippingTemplates() {
+      getFreightTemplate().then(res => {
+		  this.templateOptions = res.data.result
+	  })
+    },
+	// 鍔犺浇璁¢噺鍗曚綅
+    async loadGoodsUnit() {
+		getGoodsUnit({pageNumber: 1, pageSize: 1000}).then(res => {
+			console.log("璁¢噺鍗曚綅缁撴灉", res.data.result);
+			this.unitOptions = res.data.result.records
+		})
+	},
+    // 璁¢噺鍗曚綅閫夋嫨
+    onUnitChange(e) {
+      this.unitIndex = e.detail.value
+      this.goodsUnit = this.unitOptions[this.unitIndex]
+    },
+    
+    // 閿�鍞ā寮忛�夋嫨
+    onSalesModeChange(e) {
+      this.formData.salesModel = e.detail.value
+    },
+    
+	// 棰勫敭寮�濮嬫棩鏈熼�夋嫨
+	onPresaleStartDateChange(e) {
+	  this.formData.presaleStartDate = e.detail.value
+	  this.validateDateRange()
+	},
+	
+	// 棰勫敭缁撴潫鏃ユ湡閫夋嫨
+	onPresaleEndDateChange(e) {
+	  this.formData.presaleEndDate = e.detail.value
+	  this.validateDateRange()
+	},
+	
+	// 楠岃瘉鏃ユ湡鑼冨洿
+	validateDateRange() {
+	  if (this.formData.presaleStartDate && this.formData.presaleEndDate) {
+		const start = new Date(this.formData.presaleStartDate)
+		const end = new Date(this.formData.presaleEndDate)
+		
+		if (start > end) {
+		  uni.showToast({
+			title: '缁撴潫鏃ユ湡涓嶈兘鏃╀簬寮�濮嬫棩鏈�',
+			icon: 'none'
+		  })
+		  this.formData.presaleEndDate = ''
+		}
+	  }
+	},
+    
+    // 涓婁紶涓诲浘
+    uploadMainImage() {
+      uni.chooseImage({
+        count: 9,
+        sizeType: ['compressed'],
+        sourceType: ['album', 'camera'],
+        success: (res) => {
+		  this.formData.goodsGalleryList = []
+          res.tempFilePaths.forEach(tmpImg => {
+			  let fileName = tmpImg.substring(tmpImg.lastIndexOf('/') + 1);
+			  // 澶勭悊瀹夊崜鍙兘鐨刄RI缂栫爜
+			  if(fileName.indexOf('%') > -1) {
+				fileName = decodeURIComponent(fileName);
+			  }
+			  const fileKey = getFileKey(fileName);
+			  this.cosClient.uploadFile({
+				   Bucket: this.bucket,
+				   Region: this.region,
+				   Key: fileKey,
+				   FilePath: tmpImg,
+				   SliceSize: 1024 * 1024 * 5     /* 瑙﹀彂鍒嗗潡涓婁紶鐨勯槇鍊�,5M */
+			   }, (err, data) => {
+				   if (err) {
+					 console.log('涓婁紶澶辫触', err);
+				   } else {
+					 this.formData.goodsGalleryList.push(fileKey);
+				   }
+			   });
+          })
+        }
+      })
+    },
+    
+    // 涓婁紶瑙嗛
+    uploadVideo() {
+      uni.chooseVideo({
+        sourceType: ['album', 'camera'],
+        compressed: true,
+        maxDuration: 30,
+        success: (res) => {
+          const tempFilePath = res.tempFilePath
+		  let fileName = tempFilePath.substring(tempFilePath.lastIndexOf('/') + 1);
+		  const fileKey = getFileKey(fileName);
+		  this.videoUploading = true
+          this.cosClient.uploadFile({
+               Bucket: this.bucket,
+               Region: this.region,
+               Key: fileKey,
+               FilePath: tempFilePath,
+               SliceSize: 1024 * 1024 * 5,     /* 瑙﹀彂鍒嗗潡涓婁紶鐨勯槇鍊�,5M */
+               onProgress: (progressData) => {
+					console.log(progressData.percent);
+					this.videoUploadProgress = progressData.percent * 100
+               }
+           }, (err, data) => {
+               if (err) {
+                console.log('涓婁紶澶辫触', err);
+               } else {
+          		this.formData.goodsVideo = fileKey
+               }
+			   this.videoUploading = false
+           });
+        }
+      })
+    },
+    
+    // 娣昏鏍奸」
+    addSpec() {
+      this.formData.specs.push({
+        name: '',
+        values: ['']
+      })
+    },
+    
+    // 鍒犻櫎瑙勬牸椤�
+    removeSpec(index) {
+      this.formData.specs.splice(index, 1)
+      this.generateSkuList()
+    },
+    
+    // 娣诲姞瑙勬牸鍊�
+    addSpecValue(specIndex) {
+      this.formData.specs[specIndex].values.push('')
+    },
+    
+    // 鍒犻櫎瑙勬牸鍊�
+    removeSpecValue(specIndex, valueIndex) {
+      this.formData.specs[specIndex].values.splice(valueIndex, 1)
+      if (this.formData.specs[specIndex].values.length === 0) {
+        this.removeSpec(specIndex)
+      } else {
+        this.generateSkuList()
+      }
+    },
+    
+	// 鐢熸垚SKU鍒楄〃
+	generateSkuList() {
+	  // 鍏堣繃婊ゆ帀娌℃湁鍚嶇О鐨勮鏍奸」鍜屾病鏈夊�肩殑瑙勬牸鍊�
+	  const validSpecs = this.formData.specs.filter(spec => 
+		spec.name && spec.values.filter(v => v).length > 0
+	  )
+	  
+	  if (validSpecs.length === 0) {
+		this.formData.skuList = []
+		return
+	  }
+	  
+	  // 鐢熸垚鎵�鏈夊彲鑳界殑缁勫悎
+	  let combinations = [{
+		price: '',
+		weight: '',
+		quantity: '',
+		sn: '',
+		specValues: []  // 淇濈暀specValues鏁扮粍
+	  }]
+	  
+	  validSpecs.forEach(spec => {
+		const newCombinations = []
+		combinations.forEach(combination => {
+		  spec.values.filter(v => v).forEach(value => {
+			// 鍒涘缓鏂扮殑缁勫悎瀵硅薄
+			const newCombination = {
+			  ...combination,
+			  [spec.name]: value,  // 娣诲姞瑙勬牸閿�煎
+			  specValues: [...combination.specValues, value]  // 淇濈暀瑙勬牸鍊兼暟缁�
+			}
+			newCombinations.push(newCombination)
+		  })
+		})
+		combinations = newCombinations
+	  })
+	  
+	  // 淇濈暀宸叉湁鐨凷KU鏁版嵁
+	  const existingSkus = this.formData.skuList || []
+	  const newSkuList = combinations.map(comb => {
+		// 鏌ユ壘鍖归厤鐨勭幇鏈塖KU锛堝悓鏃舵鏌pecValues鍜岃鏍奸敭鍊煎锛�
+		const existingSku = existingSkus.find(sku => {
+		  // 妫�鏌pecValues鏁扮粍鏄惁鍖归厤
+		  const specValuesMatch = sku.specValues && comb.specValues &&
+			sku.specValues.length === comb.specValues.length &&
+			sku.specValues.every((v, i) => v === comb.specValues[i])
+		  
+		  // 妫�鏌ユ墍鏈夎鏍奸敭鏄惁鍖归厤
+		  const specsMatch = validSpecs.every(spec => {
+			return sku[spec.name] === comb[spec.name]
+		  })
+		  
+		  return specValuesMatch && specsMatch
+		})
+		return existingSku || comb
+	  })
+	  
+	  this.formData.skuList = newSkuList
+	},
+    
+    // 鐗╂祦妯℃澘閫夋嫨
+    onTemplateChange(e) {
+      this.templateIndex = e.detail.value
+	  console.log("閫変腑鐨勭墿娴佹ā鏉�", this.templateOptions[this.templateIndex]);
+      this.shippingTemplate = this.templateOptions[this.templateIndex]
+    },
+    
+    // 缂栬緫鍣ㄥ噯澶囧氨缁�
+    onEditorReady() {
+      uni.createSelectorQuery().select('#editor').context((res) => {
+        this.editorCtx = res.context
+      }).exec()
+    },
+    
+    // 缂栬緫鍣ㄥ唴瀹瑰彉鍖�
+    onEditorInput(e) {
+      this.formData.mobileIntro = e.detail.html
+    },
+    
+    // 琛ㄥ崟楠岃瘉
+    validateForm() {
+      if (!this.formData.goodsName) {
+        uni.showToast({ title: '璇疯緭鍏ュ晢鍝佸悕绉�', icon: 'none' })
+        return false
+      }
+      
+      if (!this.formData.price) {
+        uni.showToast({ title: '璇疯緭鍏ュ晢鍝佷环鏍�', icon: 'none' })
+        return false
+      }
+      
+      if (!this.formData.commission) {
+        uni.showToast({ title: '璇疯緭鍏ユ娊鎴愭瘮渚�', icon: 'none' })
+        return false
+      }
+      
+      if (!this.goodsUnit) {
+        uni.showToast({ title: '璇烽�夋嫨璁¢噺鍗曚綅', icon: 'none' })
+        return false
+      }
+      
+      if (this.formData.salesModel === 'PRESALE' && !this.formData.presaleEndDate) {
+        uni.showToast({ title: '璇烽�夋嫨棰勫敭鎴鏃ユ湡', icon: 'none' })
+        return false
+      }
+      
+      if (!this.formData.goodsGalleryList) {
+        uni.showToast({ title: '璇蜂笂浼犲晢鍝佷富鍥�', icon: 'none' })
+        return false
+      }
+	  
+	  if (!this.formData.goodsVideo) {
+	    uni.showToast({ title: '璇蜂笂浼犲晢鍝佽棰�', icon: 'none' })
+	    return false
+	  }
+      
+      // 楠岃瘉瑙勬牸椤�
+      for (const spec of this.formData.specs) {
+        if (!spec.name) {
+          uni.showToast({ title: '璇峰~鍐欒鏍奸」鍚嶇О', icon: 'none' })
+          return false
+        }
+        
+        if (spec.values.filter(v => v).length === 0) {
+          uni.showToast({ title: '姣忎釜瑙勬牸椤硅嚦灏戦渶瑕佷竴涓鏍煎��', icon: 'none' })
+          return false
+        }
+      }
+      
+      // 楠岃瘉SKU
+      if (this.formData.skuList.length > 0) {
+        for (const sku of this.formData.skuList) {
+          if (!sku.price) {
+            uni.showToast({ title: '璇峰~鍐欐墍鏈夎鏍肩殑浠锋牸', icon: 'none' })
+            return false
+          }
+          
+          if (!sku.quantity) {
+            uni.showToast({ title: '璇峰~鍐欐墍鏈夎鏍肩殑搴撳瓨', icon: 'none' })
+            return false
+          }
+        }
+      }
+      
+      if (!this.shippingTemplate) {
+        uni.showToast({ title: '璇烽�夋嫨鐗╂祦妯℃澘', icon: 'none' })
+        return false
+      }
+      
+      return true
+    },
+    
+    // 鎻愪氦琛ㄥ崟
+    submitForm() {
+      if (!this.validateForm()) return
+      const data = this.formData
+	  if (data.skuList) {
+		  data.skuList.forEach(sku => {
+			  sku['cost'] = 1
+			  sku['images'] = []
+		  })
+	  }
+	  data.preSaleTime = [this.formData.presaleStartDate, this.formData.presaleEndDate]
+	  data.templateId = this.shippingTemplate.id
+	  data.goodsUnit = this.goodsUnit.name
+      this.$emit("submit", data)
+    }
+  },
+  
+  watch: {
+    'formData.specs': {
+      deep: true,
+      handler() {
+        this.generateSkuList()
+      }
+    }
+  }
+}
+</script>
+
+<style scoped>
+.add-product-container {
+  height: 100vh;
+  display: flex;
+  flex-direction: column;
+  background-color: #f5f5f5;
+}
+
+.scroll-view {
+  flex: 1;
+  height: 100%;
+}
+
+.form-section {
+  padding: 20rpx 0rpx;
+}
+
+.section-title {
+  font-size: 32rpx;
+  font-weight: bold;
+  margin: 30rpx 0 20rpx;
+  color: #333;
+  padding-left: 10rpx;
+  border-left: 6rpx solid #409eff;
+}
+
+.form-item {
+  background-color: #fff;
+  padding: 25rpx;
+  margin-bottom: 20rpx;
+  border-radius: 12rpx;
+  box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
+}
+
+.label {
+  display: block;
+  font-size: 28rpx;
+  color: #666;
+  margin-bottom: 15rpx;
+}
+
+.input {
+  height: 80rpx;
+  font-size: 28rpx;
+  border: 1rpx solid #eee;
+  border-radius: 8rpx;
+  padding: 0 20rpx;
+  background-color: #f9f9f9;
+}
+
+.textarea {
+  height: 150rpx;
+  font-size: 28rpx;
+  border: 1rpx solid #eee;
+  border-radius: 8rpx;
+  padding: 20rpx;
+  background-color: #f9f9f9;
+}
+
+.unit {
+  margin-left: 10rpx;
+  color: #999;
+}
+
+.picker {
+  height: 80rpx;
+  line-height: 80rpx;
+  font-size: 28rpx;
+  border: 1rpx solid #eee;
+  border-radius: 8rpx;
+  padding: 0 20rpx;
+  background-color: #f9f9f9;
+}
+
+.picker-text {
+  color: #333;
+}
+
+
+.date-range-picker {
+  display: flex;
+  justify-content: space-between;
+}
+
+.date-picker-item {
+  width: 48%;
+}
+
+.date-label {
+  display: block;
+  font-size: 26rpx;
+  color: #666;
+  margin-bottom: 10rpx;
+}
+
+.date-range-hint {
+  font-size: 24rpx;
+  color: #999;
+  margin-top: 10rpx;
+  text-align: right;
+}
+
+.radio-group {
+  display: flex;
+}
+
+.radio-label {
+  margin-right: 40rpx;
+  font-size: 28rpx;
+}
+
+.upload-container {
+  margin-top: 15rpx;
+}
+
+.upload-btn {
+  width: 200rpx;
+  height: 200rpx;
+  border: 1rpx dashed #ccc;
+  border-radius: 8rpx;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  color: #999;
+}
+
+.upload-text {
+  margin-top: 10rpx;
+  font-size: 24rpx;
+}
+
+.uploaded-image {
+  width: 200rpx;
+  height: 200rpx;
+  border-radius: 8rpx;
+}
+
+.uploaded-video {
+  width: 100%;
+  height: 400rpx;
+  border-radius: 8rpx;
+}
+
+.specs-container {
+  margin-bottom: 30rpx;
+}
+
+.spec-item {
+  background-color: #fff;
+  padding: 20rpx;
+  margin-bottom: 20rpx;
+  border-radius: 12rpx;
+  box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
+}
+
+.spec-header {
+  display: flex;
+  align-items: center;
+  margin-bottom: 20rpx;
+}
+
+.spec-input {
+  flex: 1;
+  height: 70rpx;
+  font-size: 28rpx;
+  border: 1rpx solid #eee;
+  border-radius: 8rpx;
+  padding: 0 20rpx;
+  background-color: #f9f9f9;
+  margin-right: 20rpx;
+}
+
+.spec-values {
+  display: flex;
+  flex-wrap: wrap;
+}
+
+.spec-value-tag {
+  display: flex;
+  align-items: center;
+  background-color: #f5f7fa;
+  padding: 10rpx 20rpx;
+  border-radius: 40rpx;
+  margin-right: 15rpx;
+  margin-bottom: 15rpx;
+}
+
+.value-input {
+  width: 120rpx;
+  font-size: 26rpx;
+  background-color: transparent;
+  margin-right: 10rpx;
+}
+
+.add-value-btn {
+  display: flex;
+  align-items: center;
+  color: #409eff;
+  font-size: 26rpx;
+  padding: 10rpx 15rpx;
+}
+
+.add-spec-btn {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  color: #409eff;
+  font-size: 28rpx;
+  padding: 20rpx;
+  border: 1rpx dashed #409eff;
+  border-radius: 8rpx;
+  margin-top: 10rpx;
+}
+
+.sku-container {
+  margin-bottom: 30rpx;
+}
+
+.sku-item {
+  background-color: #fff;
+  padding: 20rpx;
+  margin-bottom: 20rpx;
+  border-radius: 12rpx;
+  box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
+}
+
+.sku-title {
+  font-size: 28rpx;
+  color: #333;
+  margin-bottom: 20rpx;
+  font-weight: bold;
+}
+
+.sku-form {
+  display: flex;
+  flex-wrap: wrap;
+  justify-content: space-between;
+}
+
+.sku-form-item {
+  width: 48%;
+  margin-bottom: 15rpx;
+}
+
+.sku-label {
+  display: block;
+  font-size: 26rpx;
+  color: #666;
+  margin-bottom: 10rpx;
+}
+
+.sku-input {
+  height: 70rpx;
+  font-size: 26rpx;
+  border: 1rpx solid #eee;
+  border-radius: 8rpx;
+  padding: 0 20rpx;
+  background-color: #f9f9f9;
+  width: 100%;
+}
+
+.sku-unit {
+  margin-left: 10rpx;
+  color: #999;
+  font-size: 26rpx;
+}
+
+.editor {
+  height: 400rpx;
+  background-color: #f9f9f9;
+  border: 1rpx solid #eee;
+  border-radius: 8rpx;
+  padding: 20rpx;
+}
+
+.submit-btn-container {
+  padding-bottom: 150px;
+  background-color: #fff;
+}
+
+.submit-btn {
+  width: 100%;
+  height: 90rpx;
+  line-height: 90rpx;
+  font-size: 32rpx;
+  border-radius: 45rpx;
+  background-color: #409eff;
+}
+</style>
\ No newline at end of file
diff --git a/pages/supplier/publish-goods/publishGoods.vue b/pages/supplier/publish-goods/publishGoods.vue
index beadba3..8b0daeb 100644
--- a/pages/supplier/publish-goods/publishGoods.vue
+++ b/pages/supplier/publish-goods/publishGoods.vue
@@ -1,30 +1,78 @@
 <template>
 	<view class="container">
 		<uni-steps :options="publishSteps" :active="currentStep" active-color='#f31947'></uni-steps>
-		<choose-categery v-if="currentStep===0"></choose-categery>
+		<choose-categery @choose="chooseCategrey" v-show="currentStep === 0"></choose-categery>
+		<goods-info @submit="submit" v-show="currentStep === 1"></goods-info>
+		<view style="position: fixed;bottom: 80px;display: flex;width: calc(100% - 70rpx);">
+			<button :disabled="currentStep === 0" @click="lastStep" size="mini" style="flex: 1;font-size: 32rpx;margin-right: 3rpx;" type="primary">涓婁竴姝�</button>
+			<button :disabled="currentStep === 1" @click="nextStep" size="mini" style="flex: 1;font-size: 32rpx;margin-left: 3rpx;" type="primary">涓嬩竴姝�</button>
+		</view>
 	</view>
 </template>
 
 <script>
 	import chooseCategery from './chooseCategery.vue';
+	import goodsInfo from './goodsInfo.vue';
+	import {createGoods} from "@/api/store.js"
 	export default {
-		components: { chooseCategery },
+		components: { chooseCategery, goodsInfo },
 		data() {
 			return {
+				goods: {
+					
+				},
+				categoryPath: '',
 				currentStep:0,
 				publishSteps: [{
 						title: ' 閫夋嫨鍟嗗搧鍝佺被'
 					},
 					{
 						title: ' 濉啓鍟嗗搧璇︽儏'
-					},
-					{
-						title: ' 鍟嗗搧鍙戝竷鎴愬姛'
 					}
 				],
 			}
+		},
+		methods: {
+			// 鑾峰彇閫夋嫨鐨勫晢鍝佸垎绫�
+			chooseCategrey(categreyId) {
+				this.categoryPath = categreyId + ",,"
+			},
+			submit(data) {
+				if (! this.categoryPath) {
+					uni.showToast({ title: '璇烽�変腑鍟嗗搧鍒嗙被', icon: 'none' })
+					return
+				}
+				data['categoryPath'] = this.categoryPath
+				if (data.skuList) {
+					data.skuList.forEach(sku => {
+						delete sku.specValues
+					})
+				}
+				delete data.specs
+				// 鍙戝竷鍟嗗搧
+				console.log("鍟嗗搧鏁版嵁", data);
+				createGoods(data).then(res => {
+					uni.showToast({ title: '鍟嗗搧宸叉彁浜ゅ鏍�', icon: 'success' })
+					setTimeout(() => {
+						uni.navigateBack({
+							delta: 1
+						});
+					}, 2000)
+				})
+			},
+			// 涓婁竴姝�
+			lastStep() {
+				if (this.currentStep > 0) {
+					this.currentStep--
+				}
+			},
+			// 涓嬩竴姝�
+			nextStep() {
+				if (this.currentStep < 1) {
+					this.currentStep++
+				}
+			}
 		}
-
 	}
 </script>
 
diff --git a/pages/tabbar/index/home.vue b/pages/tabbar/index/home.vue
index 3f07dde..d9d53cd 100644
--- a/pages/tabbar/index/home.vue
+++ b/pages/tabbar/index/home.vue
@@ -367,6 +367,9 @@
 	  // } else {
 	  // 	  this.loadVideos();
 	  // }
+	  if (this.videoList.length < 1) {
+		  this.loadVideos();
+	  }
 	  // 濡傛灉瑙嗛鎸変笅鏆傚仠鍚庡垏鎹㈤〉闈㈠啀鍥炲埌椤甸潰鏃讹紝鍙畻鏆傚仠鏃堕棿锛堝洜涓烘殏鍋滄椂闂村拰绂诲紑椤甸潰鏃堕棿鏄噸澶嶇殑锛屽彧绠椾竴涓級
 	  if(this.startHidenTime !== 0 && this.currentVideoIsPlaying) {
 		  const duration = Date.now() - this.startHidenTime

--
Gitblit v1.8.0