|
@@ -34,7 +34,7 @@
|
|
|
<el-row :gutter="40">
|
|
|
<el-col :span="23">
|
|
|
<el-form-item label="启用多SKU:" prop="multiSku">
|
|
|
- <!-- <el-switch
|
|
|
+ <el-switch
|
|
|
v-model="addData.multiSku"
|
|
|
active-color="#13ce66"
|
|
|
inactive-color="#ff4949"
|
|
@@ -42,15 +42,12 @@
|
|
|
:inactive-value="0"
|
|
|
active-text="是"
|
|
|
inactive-text="否"
|
|
|
- /> -->
|
|
|
- <el-radio-group v-model="addData.multiSku">
|
|
|
- <el-radio-button :label="0">单规格</el-radio-button>
|
|
|
- <el-radio-button :label="1">多规格</el-radio-button>
|
|
|
- </el-radio-group>
|
|
|
+ />
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
</el-row>
|
|
|
- <el-row v-if="!multipleSpec" :gutter="40">
|
|
|
+ <Spec :multiSku="addData.multiSku" />
|
|
|
+ <el-row v-if="addData.multiSku === 0" :gutter="40">
|
|
|
<el-col :span="23">
|
|
|
<el-form-item label="价格:" prop="value">
|
|
|
<el-input v-model="addData.value" type="number" placeholder="请输入商品价格">
|
|
@@ -59,117 +56,36 @@
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
<el-col :span="23">
|
|
|
- <el-form-item label="成本:" prop="cost">
|
|
|
- <el-input v-model.number="addData.cost" type="number" placeholder="请输入商品成本">
|
|
|
- <template slot="append">元</template>
|
|
|
+ <el-form-item label="兑换价格:" prop="exchangePrice">
|
|
|
+ <el-input v-model="addData.exchangePrice" type="number" placeholder="请输入兑换价格">
|
|
|
+ <template slot="append">盲豆</template>
|
|
|
</el-input>
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
- <!-- <el-col :span="23">
|
|
|
- <el-form-item label="原兑换价格:" prop="originPrice">
|
|
|
- <el-input v-model="addData.originPrice" type="number" placeholder="请输入原兑换价格">
|
|
|
+ <el-col :span="23">
|
|
|
+ <el-form-item label="成本:" prop="cost">
|
|
|
+ <el-input v-model.number="addData.cost" type="number" placeholder="请输入商品成本">
|
|
|
<template slot="append">元</template>
|
|
|
</el-input>
|
|
|
</el-form-item>
|
|
|
- </el-col> -->
|
|
|
+ </el-col>
|
|
|
<el-col :span="23">
|
|
|
- <el-form-item label="兑换价格:" prop="exchangePrice">
|
|
|
- <el-input v-model="addData.exchangePrice" type="number" placeholder="请输入兑换价格">
|
|
|
- <template slot="append">元</template>
|
|
|
+ <el-form-item label="库存:" prop="quantity">
|
|
|
+ <el-input v-model="addData.quantity" type="number" placeholder="请输入商品库存">
|
|
|
+ <template slot="append">件</template>
|
|
|
</el-input>
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
+ </el-row>
|
|
|
+ <el-divider content-position="left">商品详情</el-divider>
|
|
|
+ <el-row>
|
|
|
<el-col :span="23">
|
|
|
- <el-form-item label="库存:" prop="quantity">
|
|
|
- <el-input-number v-model="addData.quantity" placeholder="请输入商品库存" />
|
|
|
+ <el-form-item prop="description">
|
|
|
+ <TinyEditor v-model="addData.description" />
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
</el-row>
|
|
|
</el-form>
|
|
|
- <div v-if="multipleSpec">
|
|
|
- <div style="margin-bottom: 16px">
|
|
|
- <el-button :plain="true" type="primary" size="small" @click="handleSpecificationShow">添加规格</el-button>
|
|
|
- </div>
|
|
|
- <el-table :data="specifications">
|
|
|
- <el-table-column property="specification" label="规格名"/>
|
|
|
- <el-table-column property="value" label="规格值">
|
|
|
- <template slot-scope="scope">
|
|
|
- <el-tag type="primary">
|
|
|
- {{ scope.row.value }}
|
|
|
- </el-tag>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- <el-table-column align="center" label="操作" width="120">
|
|
|
- <template slot-scope="scope">
|
|
|
- <el-button type="danger" size="small" @click="handleSpecificationDelete(scope.row)">删除</el-button>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- </el-table>
|
|
|
- </div>
|
|
|
- <el-dialog :visible.sync="specVisiable" title="设置规格" :close-on-click-modal="false" width="400px">
|
|
|
- <el-form ref="specForm" :model="specForm" label-width="80px">
|
|
|
- <el-form-item label="规格名:" prop="specification">
|
|
|
- <el-input v-model="specForm.specification"/>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="规格值:" prop="value">
|
|
|
- <el-input v-model="specForm.value"/>
|
|
|
- <div class="tip">多个规格值请用逗号隔开</div>
|
|
|
- </el-form-item>
|
|
|
- </el-form>
|
|
|
- <div slot="footer" class="dialog-footer">
|
|
|
- <el-button @click="specVisiable = false">取消</el-button>
|
|
|
- <el-button type="primary" @click="handleSpecificationAdd">确定</el-button>
|
|
|
- </div>
|
|
|
- </el-dialog>
|
|
|
- <br>
|
|
|
- <el-table v-if="multipleSpec" :data="products">
|
|
|
- <el-table-column property="name" label="sku名称" />
|
|
|
- <el-table-column property="picUrl" width="100" label="商品图片">
|
|
|
- <template slot-scope="scope">
|
|
|
- <img v-if="scope.row.picUrl" :src="IMG_URL+scope.row.picUrl" width="40">
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- <el-table-column property="value" label="价格"/>
|
|
|
- <!-- <el-table-column property="originPrice" label="原兑换价格"/> -->
|
|
|
- <el-table-column property="exchangePrice" label="兑换价格"/>
|
|
|
- <el-table-column property="cost" label="成本"/>
|
|
|
- <el-table-column property="quantity" label="库存数量"/>
|
|
|
- <el-table-column align="center" label="操作" width="120">
|
|
|
- <template slot-scope="scope">
|
|
|
- <el-button type="primary" size="mini" @click="handleProductShow(scope.row)">设置</el-button>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- </el-table>
|
|
|
-
|
|
|
- <el-dialog :visible.sync="productVisiable" title="设置商品" :close-on-click-modal="false" width="400px">
|
|
|
- <el-form ref="productForm" :model="productForm" label-width="100px">
|
|
|
- <el-form-item label="sku名称:" prop="name">
|
|
|
- <el-input v-model="productForm.name" />
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="价格:" prop="value">
|
|
|
- <el-input-number v-model="productForm.value" />
|
|
|
- </el-form-item>
|
|
|
- <!-- <el-form-item label="原兑换价格:" prop="originPrice">
|
|
|
- <el-input-number v-model="productForm.originPrice"/>
|
|
|
- </el-form-item> -->
|
|
|
- <el-form-item label="兑换价格:" prop="exchangePrice">
|
|
|
- <el-input-number v-model="productForm.exchangePrice"/>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="成本:" prop="cost">
|
|
|
- <el-input-number v-model="productForm.cost"/>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="库存数量:" prop="quantity">
|
|
|
- <el-input-number v-model="productForm.quantity"/>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="商品图片:" prop="picUrl">
|
|
|
- <Upload :value="productForm.picUrl ? [{ fileName: productForm.picUrl }] : []" @input="productForm.picUrl = $event[0] ? $event[0].fileName : ''" :limit="1" />
|
|
|
- </el-form-item>
|
|
|
- </el-form>
|
|
|
- <div slot="footer" class="dialog-footer">
|
|
|
- <el-button @click="productVisiable = false">取消</el-button>
|
|
|
- <el-button type="primary" @click="handleProductEdit">确定</el-button>
|
|
|
- </div>
|
|
|
- </el-dialog>
|
|
|
<br>
|
|
|
<el-row>
|
|
|
<el-col :span="24" style="text-align: right">
|
|
@@ -181,37 +97,50 @@
|
|
|
</template>
|
|
|
<script>
|
|
|
import Upload from '@/components/ImageUpload'
|
|
|
+import Spec from './components/spec'
|
|
|
+import TinyEditor from '@/components/TinyEditor'
|
|
|
import { getGoodsDetail, addGoods } from '@/api/business/goods'
|
|
|
import { publicFileGetUrl } from "@/api/common"
|
|
|
export default {
|
|
|
components: {
|
|
|
- Upload
|
|
|
+ TinyEditor,
|
|
|
+ Upload,
|
|
|
+ Spec
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
IMG_URL: publicFileGetUrl,
|
|
|
id: this.$route.query.id,
|
|
|
addData: {
|
|
|
- multiSku: 0
|
|
|
+ multiSku: 0,
|
|
|
+ description: ''
|
|
|
},
|
|
|
rules: {
|
|
|
- title: [{ required: true, message: '请输入商品名称', trigger: 'blur' }]
|
|
|
- },
|
|
|
- dragOptions: {
|
|
|
- animation: 100,
|
|
|
- },
|
|
|
- specifications: [],
|
|
|
- products: [],
|
|
|
- specVisiable: false, // 规格弹窗
|
|
|
- specForm: {}, // 规格暂存
|
|
|
- productVisiable: false,
|
|
|
- productForm: {},
|
|
|
+ title: [{ required: true, message: '请输入商品名称', trigger: 'blur' }],
|
|
|
+ picUrl: [{ required: true, message: '请上传商品图片', trigger: 'change' }],
|
|
|
+ exchangeShow: [{ required: true, message: '请选择是否支持盲豆兑换', trigger: 'change' }],
|
|
|
+ multiSku: [{ required: true, message: '请选择SKU类型', trigger: 'change' }],
|
|
|
+ value: [
|
|
|
+ { required: true, message: '请输入商品价格', trigger: 'blur' },
|
|
|
+ { pattern: /^([1-9]\d*(\.\d{1,2})?|([0](\.([0][1-9]|[1-9]\d{0,1}))))$/, message: "请输入正确的金额,最多两位小数", trigger: ["blur", "change"] }
|
|
|
+ ],
|
|
|
+ exchangePrice: [
|
|
|
+ { required: true, message: '请输入兑换价格', trigger: 'blur' },
|
|
|
+ { pattern: /^([1-9]\d*)$/, message: "请输入正确的数字", trigger: ["blur", "change"] }
|
|
|
+ ],
|
|
|
+ cost: [
|
|
|
+ { required: true, message: '请输入成本', trigger: 'blur' },
|
|
|
+ { pattern: /^([1-9]\d*(\.\d{1,2})?|([0](\.([0][1-9]|[1-9]\d{0,1}))))$/, message: "请输入正确的金额,最多两位小数", trigger: ["blur", "change"] }
|
|
|
+ ],
|
|
|
+ quantity: [
|
|
|
+ { required: true, message: '请输入库存', trigger: 'blur' },
|
|
|
+ { pattern: /^([1-9]\d*)$/, message: "请输入正确的数字", trigger: ["blur", "change"] }
|
|
|
+ ],
|
|
|
+ description: [{ required: true, message: '请输入商品详情', trigger: 'blur' }]
|
|
|
+ }
|
|
|
}
|
|
|
},
|
|
|
computed: {
|
|
|
- multipleSpec() {
|
|
|
- return this.addData.multiSku === 1
|
|
|
- },
|
|
|
mainPicUrl: {
|
|
|
get() {
|
|
|
return this.addData.picUrl ? this.addData.picUrl.split(',').map(item => {
|
|
@@ -221,153 +150,25 @@ export default {
|
|
|
}) : []
|
|
|
},
|
|
|
set(val) {
|
|
|
- this.addData.picUrl = val.map(item => { return item.fileName }).toString()
|
|
|
+ this.$set(this.addData, 'picUrl', val.map(item => { return item.fileName }).toString())
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
created() {
|
|
|
if (this.id) {
|
|
|
getGoodsDetail(this.id).then(res => {
|
|
|
- this.addData = res.data
|
|
|
+ const { goodsId, title, picUrl, exchangeShow, multiSku, value, exchangePrice, cost, quantity, description } = res.data
|
|
|
+ this.addData = { goodsId, title, picUrl, exchangeShow, multiSku, value, exchangePrice, cost, quantity, description }
|
|
|
})
|
|
|
}
|
|
|
},
|
|
|
methods: {
|
|
|
- beforeUpload(e) {
|
|
|
- if (e.size > 1024000) {
|
|
|
- this.$message({
|
|
|
- message: '图片过大,请调整大小确保不超过1M!',
|
|
|
- type: 'warning'
|
|
|
- });
|
|
|
- return false
|
|
|
- }
|
|
|
- },
|
|
|
- handleSpecificationShow() {
|
|
|
- this.specForm = {}
|
|
|
- this.specVisiable = true
|
|
|
- },
|
|
|
- handleSpecificationDelete(row) {
|
|
|
- const index = this.specifications.indexOf(row)
|
|
|
- this.specifications.splice(index, 1)
|
|
|
- this.specToProduct()
|
|
|
- },
|
|
|
- specToProduct() {
|
|
|
- if (this.specifications.length === 0) {
|
|
|
- return
|
|
|
- }
|
|
|
- // 根据specifications创建临时规格列表
|
|
|
- var specValues = []
|
|
|
- var spec = this.specifications[0].specification
|
|
|
- var values = []
|
|
|
- values.push(0)
|
|
|
-
|
|
|
- for (var i = 1; i < this.specifications.length; i++) {
|
|
|
- const aspec = this.specifications[i].specification
|
|
|
-
|
|
|
- if (aspec === spec) {
|
|
|
- values.push(i)
|
|
|
- } else {
|
|
|
- specValues.push(values)
|
|
|
- spec = aspec
|
|
|
- values = []
|
|
|
- values.push(i)
|
|
|
- }
|
|
|
- }
|
|
|
- specValues.push(values)
|
|
|
-
|
|
|
- // 根据临时规格列表生产商品规格
|
|
|
- // 算法基于 https://blog.csdn.net/tyhj_sf/article/details/53893125
|
|
|
- var productsIndex = 0
|
|
|
- var products = []
|
|
|
- var combination = []
|
|
|
- var n = specValues.length
|
|
|
- for (var s = 0; s < n; s++) {
|
|
|
- combination[s] = 0
|
|
|
- }
|
|
|
- var index = 0
|
|
|
- var isContinue = false
|
|
|
- do {
|
|
|
- var specifications = []
|
|
|
- var properties = ''
|
|
|
- for (var x = 0; x < n; x++) {
|
|
|
- var z = specValues[x][combination[x]]
|
|
|
- specifications.push(this.specifications[z].value)
|
|
|
- properties = `${properties ? (properties + ';') : ''}${this.specifications[z].specification}:${this.specifications[z].value}`
|
|
|
- }
|
|
|
- products[productsIndex] = {
|
|
|
- idx: productsIndex,
|
|
|
- name: specifications.toString(),
|
|
|
- picUrl: '',
|
|
|
- originPrice: 0.00,
|
|
|
- exchangePrice: 0.00,
|
|
|
- value: 0.00,
|
|
|
- cost: 0.00,
|
|
|
- quantity: 0,
|
|
|
- properties
|
|
|
- }
|
|
|
- productsIndex++
|
|
|
-
|
|
|
- index++
|
|
|
- combination[n - 1] = index
|
|
|
- for (var j = n - 1; j >= 0; j--) {
|
|
|
- if (combination[j] >= specValues[j].length) {
|
|
|
- combination[j] = 0
|
|
|
- index = 0
|
|
|
- if (j - 1 >= 0) {
|
|
|
- combination[j - 1] = combination[j - 1] + 1
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- isContinue = false
|
|
|
- for (var p = 0; p < n; p++) {
|
|
|
- if (combination[p] !== 0) {
|
|
|
- isContinue = true
|
|
|
- }
|
|
|
- }
|
|
|
- } while (isContinue)
|
|
|
-
|
|
|
- this.products = products
|
|
|
- },
|
|
|
- handleSpecificationAdd() {
|
|
|
- const valueArr = this.specForm.value.replace(/,/ig,',').replace(/\s*/g,"").split(',') // 替换所有的中文逗号为英文逗号并去空格
|
|
|
- valueArr.forEach(element => {
|
|
|
- let index = this.specifications.length - 1
|
|
|
- for (var i = 0; i < this.specifications.length; i++) {
|
|
|
- const v = this.specifications[i]
|
|
|
- if (v.specification === this.specForm.specification) {
|
|
|
- if (v.value !== element) {
|
|
|
- index = i
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- this.specifications.splice(index + 1, 0, {
|
|
|
- specification: this.specForm.specification,
|
|
|
- value: element
|
|
|
- })
|
|
|
-
|
|
|
- });
|
|
|
- this.specToProduct()
|
|
|
- this.specVisiable = false
|
|
|
- },
|
|
|
- handleProductShow(row) {
|
|
|
- this.productForm = Object.assign({}, row)
|
|
|
- this.productVisiable = true
|
|
|
- },
|
|
|
- handleProductEdit() {
|
|
|
- for (var i = 0; i < this.products.length; i++) {
|
|
|
- const v = this.products[i]
|
|
|
- if (v.idx === this.productForm.idx) {
|
|
|
- this.products.splice(i, 1, this.productForm)
|
|
|
- break
|
|
|
- }
|
|
|
- }
|
|
|
- this.productVisiable = false
|
|
|
- },
|
|
|
updateItem() {
|
|
|
this.$refs.addItem.validate((valid, items) => {
|
|
|
if (valid) {
|
|
|
this.addData.skuList = this.products
|
|
|
- addGoods(this.addData).then(res => {
|
|
|
+ const { description, ...rest } = this.addData
|
|
|
+ addGoods({...rest, ...{description: encodeURI(description) }}).then(res => {
|
|
|
if (res.code === 0) {
|
|
|
this.$message({
|
|
|
message: this.addData.goodsId ? '修改成功!' : '添加成功!',
|
|
@@ -383,12 +184,9 @@ export default {
|
|
|
type: 'warning'
|
|
|
})
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
})
|
|
|
- },
|
|
|
-
|
|
|
-
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
</script>
|
|
@@ -406,55 +204,5 @@ export default {
|
|
|
left: 10px;
|
|
|
}
|
|
|
}
|
|
|
- .flip-list-move {
|
|
|
- transition: transform 0.5s;
|
|
|
- }
|
|
|
- .no-move {
|
|
|
- transition: transform 0s;
|
|
|
- }
|
|
|
- .ghost {
|
|
|
- opacity: 0.5;
|
|
|
- background: #c8ebfb;
|
|
|
- }
|
|
|
- .list-group {
|
|
|
- min-height: 120px;
|
|
|
- padding: 20px;
|
|
|
- border: 1px solid #EEE;
|
|
|
- }
|
|
|
- .list-empty {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- font-size: 14px;
|
|
|
- color: #888;
|
|
|
- height: 100px;
|
|
|
- }
|
|
|
- .list-group-item, .list-group-header {
|
|
|
- padding: 0 16px;
|
|
|
- height: 40px;
|
|
|
- border-bottom: 1px solid #EBEEF5;
|
|
|
- cursor: move;
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- font-size: 14px;
|
|
|
- color: #606266;
|
|
|
- justify-content: space-between;
|
|
|
- .f1 {
|
|
|
- flex: 1;
|
|
|
- }
|
|
|
- .f2 {
|
|
|
- flex: 2;
|
|
|
- }
|
|
|
- .tr {
|
|
|
- text-align: right;
|
|
|
- }
|
|
|
- }
|
|
|
- .list-group-header {
|
|
|
- cursor: default;
|
|
|
- background: #EBEEF5;
|
|
|
- }
|
|
|
- .list-group-item:hover {
|
|
|
- background: #F3F6F9;
|
|
|
- }
|
|
|
}
|
|
|
</style>
|