From a1c289e7dfc5d9a3b8dc7ca9b05857f276c05f8d Mon Sep 17 00:00:00 2001 From: xiangpei <xiangpei@timesnew.cn> Date: 星期三, 09 七月 2025 18:03:48 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/dev' into dev --- pages/supplier/publish-goods/goodsInfo.vue | 877 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 877 insertions(+), 0 deletions(-) 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 -- Gitblit v1.8.0