<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 版本至少需要v1.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);
|
// 处理安卓可能的URI编码
|
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
|
})
|
|
// 保留已有的SKU数据
|
const existingSkus = this.formData.skuList || []
|
const newSkuList = combinations.map(comb => {
|
// 查找匹配的现有SKU(同时检查specValues和规格键值对)
|
const existingSku = existingSkus.find(sku => {
|
// 检查specValues数组是否匹配
|
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>
|