...
|
...
|
@@ -44,20 +44,15 @@ |
|
|
<span class="create-group-sub-title">(颜色名称只能填写中文,最多5个汉字。款型编码和条码只能填写英文和数字,不区分大小写)</span>
|
|
|
</div>
|
|
|
<Form-item label="颜色">
|
|
|
<CheckboxColor :select-colors="table.defaultSelectedColors" @on-change="clickColor"></CheckboxColor>
|
|
|
<CheckboxColor :select-colors="table.defaultSelectedColors" @on-change="selectColor"></CheckboxColor>
|
|
|
</Form-item>
|
|
|
<Form-item label="尺寸">
|
|
|
<Checkbox-group v-model='table.selectedSizes'>
|
|
|
<Checkbox v-for="size in sizes"
|
|
|
:key="size"
|
|
|
:label="size.id"
|
|
|
:disabled="size.disabled">
|
|
|
<span>{{size.sizeName}}</span>
|
|
|
</Checkbox>
|
|
|
</Checkbox-group>
|
|
|
<CheckboxSize :sort-id="this.product.smallSortId" :select-sizes="table.defaultSelectedSizes" @on-change="selectSize"></CheckboxSize>
|
|
|
</Form-item>
|
|
|
<Form-item>
|
|
|
<Table ref="sellerGoods" :context="self" :data="table.data" :columns="table.columns" stripe border></Table>
|
|
|
<TableGood ref="tableGood" v-model="table.data"
|
|
|
@on-upload="uploadGoodSzieSuccess"
|
|
|
@on-factory-name="onChangeFactoryCode"></TableGood>
|
|
|
</Form-item>
|
|
|
<div class="create-item-title">商品价格</div>
|
|
|
<Form-item label="吊牌价">
|
...
|
...
|
@@ -74,98 +69,7 @@ |
|
|
<div class="create-item-title">商品颜色主图
|
|
|
<span class="create-group-sub-title">(商品正面图默认为用户选择商品颜色和展示使用。用户从不同频道查看商品,优先展示频道封面图)</span>
|
|
|
</div>
|
|
|
<Row v-for="good,goodIndex in product.goods"
|
|
|
:key="good">
|
|
|
<Col span="4">
|
|
|
<div class="color-item-title">
|
|
|
<span>{{good.goodsName}}({{good.factoryGoodsName}})</span>
|
|
|
</div>
|
|
|
</Col>
|
|
|
|
|
|
<Col span="4">
|
|
|
<div class="upload-item">
|
|
|
<div class="upload-item-img">
|
|
|
<img :src="good.goodsImage[0].imageUrl"
|
|
|
alt=""
|
|
|
width="120px"
|
|
|
height="122px"
|
|
|
v-if="good.goodsImage[0].imageUrl">
|
|
|
</div>
|
|
|
|
|
|
<div class="upload-item-title">
|
|
|
商品正面图*
|
|
|
</div>
|
|
|
</div>
|
|
|
</Col>
|
|
|
|
|
|
<Col span="4">
|
|
|
|
|
|
<div class="upload-item">
|
|
|
<div class="upload-item-img">
|
|
|
<drag-file-upload :default-file="good.goodsImage[1].imageUrl"
|
|
|
:id="{goodIndex, imageIndex: 1}"
|
|
|
@on-success="uploadImageSuccess"
|
|
|
@on-remove="uploadImageRemove">
|
|
|
</drag-file-upload>
|
|
|
</div>
|
|
|
|
|
|
<div class="upload-item-title">
|
|
|
商品反面图
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
</Col>
|
|
|
|
|
|
<Col span="4">
|
|
|
<div class="upload-item">
|
|
|
<div class="upload-item-img">
|
|
|
<drag-file-upload :default-file="good.goodsImage[2].imageUrl"
|
|
|
:id="{goodIndex, imageIndex: 2}"
|
|
|
@on-success="uploadImageSuccess"
|
|
|
@on-remove="uploadImageRemove">
|
|
|
</drag-file-upload>
|
|
|
</div>
|
|
|
|
|
|
<div class="upload-item-title">
|
|
|
模特图
|
|
|
</div>
|
|
|
</div>
|
|
|
</Col>
|
|
|
|
|
|
<Col span="4">
|
|
|
|
|
|
<div class="upload-item">
|
|
|
<div class="upload-item-img">
|
|
|
<drag-file-upload :default-file="good.goodsImage[3].imageUrl"
|
|
|
:id="{goodIndex, imageIndex: 3}"
|
|
|
@on-success="uploadImageSuccess"
|
|
|
@on-remove="uploadImageRemove">
|
|
|
</drag-file-upload>
|
|
|
</div>
|
|
|
|
|
|
<div class="upload-item-title">
|
|
|
男生频道封面图
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
</Col>
|
|
|
|
|
|
<Col span="4">
|
|
|
<div class="upload-item">
|
|
|
<div class="upload-item-img">
|
|
|
<drag-file-upload :default-file="good.goodsImage[4].imageUrl"
|
|
|
:id="{goodIndex, imageIndex: 4}"
|
|
|
@on-success="uploadImageSuccess"
|
|
|
@on-remove="uploadImageRemove">
|
|
|
</drag-file-upload>
|
|
|
</div>
|
|
|
|
|
|
<div class="upload-item-title">
|
|
|
女生频道封面图
|
|
|
</div>
|
|
|
</div>
|
|
|
</Col>
|
|
|
</Row>
|
|
|
<GoodImage v-model="product.goods"></GoodImage>
|
|
|
<div class="create-item-title">商品描述(详情页内容)</div>
|
|
|
<editor :content="product.productIntro"
|
|
|
@change="updateProductDesc"></editor>
|
...
|
...
|
@@ -173,19 +77,19 @@ |
|
|
<Form-item :label="attr.attributeName"
|
|
|
v-for="attr in render.productStandardRelationStr"
|
|
|
:key="attr">
|
|
|
<multi-select v-model="attr.model" :attr="attr"></multi-select>
|
|
|
<MuliSelect v-model="attr.model" :attr="attr"></MuliSelect>
|
|
|
</Form-item>
|
|
|
<Form-item :label="attr.attributeName"
|
|
|
v-for="attr in render.attributeProValuesOne"
|
|
|
:key="attr">
|
|
|
<multi-select v-model="attr.model" :attr="attr"></multi-select>
|
|
|
<MuliSelect v-model="attr.model" :attr="attr"></MuliSelect>
|
|
|
</Form-item>
|
|
|
<Form-item :label="attr.attributeName" v-for="attr in render.attributeProValuesTwo" :key="attr">
|
|
|
<multi-select v-model="attr.model" :attr="attr"></multi-select>
|
|
|
<MuliSelect v-model="attr.model" :attr="attr"></MuliSelect>
|
|
|
</Form-item>
|
|
|
<Form-item v-if="render.productMaterial" :label="render.productMaterial.attributeName">
|
|
|
<shop-material v-model="product.materialList" :idNameList="render.productMaterial.idNameList">
|
|
|
</shop-material>
|
|
|
<Material v-model="product.materialList" :idNameList="render.productMaterial.idNameList">
|
|
|
</Material>
|
|
|
</Form-item>
|
|
|
<Form-item>
|
|
|
<Button type="primary" @click="submit" size="large">保存</Button>
|
...
|
...
|
@@ -194,10 +98,9 @@ |
|
|
</Form>
|
|
|
</template>
|
|
|
<script>
|
|
|
|
|
|
import ShopMaterial from './components/material';
|
|
|
import MuliSelect from './components/muli-select';
|
|
|
import { CheckboxAge, CheckboxColor } from 'components/checkbox';
|
|
|
import _ from 'lodash';
|
|
|
import {Material, MuliSelect, TableGood, GoodImage} from './components';
|
|
|
import { CheckboxAge, CheckboxColor, CheckboxSize } from 'components/checkbox';
|
|
|
import { SelectSeason } from 'components/select';
|
|
|
import { RadioSeason, RadioGender } from 'components/radio';
|
|
|
|
...
|
...
|
@@ -205,138 +108,14 @@ import service from 'product-create/service'; |
|
|
import api from 'product-create/api';
|
|
|
import serial from 'product-create/serialize';
|
|
|
|
|
|
const _ = require('lodash');
|
|
|
const Fn = require('lodash/fp');
|
|
|
|
|
|
export default {
|
|
|
data() {
|
|
|
return {
|
|
|
show: true,
|
|
|
product: null,
|
|
|
self: this,
|
|
|
colors: [],
|
|
|
sizes: [],
|
|
|
table: {
|
|
|
columns: [
|
|
|
{
|
|
|
title: '色系名称',
|
|
|
key: 'goodsName',
|
|
|
render(row, col, index) {
|
|
|
return `<div v-if="isExist(${index})">
|
|
|
<p>{{table.data[${index}].goodsName.name}}</p>
|
|
|
<Radio :value="table.data[${index}].goodsName.isDefault"
|
|
|
@on-change="clickDefault(${index})">主推</Radio>
|
|
|
</div>`;
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
title: '颜色展示名称',
|
|
|
key: 'factoryGoodsName',
|
|
|
render(row, col, index) {
|
|
|
return `<div v-if="isExist(${index})">
|
|
|
<i-input
|
|
|
v-model="row.factoryGoodsName"
|
|
|
:placeholder="row.goodsName.name">
|
|
|
</i-input>
|
|
|
</div>`;
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
title: '色卡图片*',
|
|
|
key: 'goodsColorImage',
|
|
|
width: 170,
|
|
|
render(row, col, index) {
|
|
|
return `<div
|
|
|
:class="{'upload-item': true ,
|
|
|
'upload-item-error':
|
|
|
row.goodsColorImage.showValidate && row.goodsColorImage.validate}"
|
|
|
>
|
|
|
<div class="upload-item-img">
|
|
|
<img v-if="row.goodsColorImage.value"
|
|
|
:src="row.goodsColorImage.value" alt="" width="120px" height="122px">
|
|
|
</div>
|
|
|
<div>
|
|
|
<file-upload :id="{index: ${index}}"
|
|
|
@on-success="uploadSuccess"
|
|
|
@on-error="uploadError"></file-upload>
|
|
|
</div>
|
|
|
<div v-if="row.goodsColorImage.showValidate && row.goodsColorImage.validate"
|
|
|
class="upload-item-tip">
|
|
|
必须上传图片
|
|
|
</div>
|
|
|
</div>`;
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
title: '款型编码',
|
|
|
key: 'factoryCode',
|
|
|
render(row, col, index) {
|
|
|
return `<div v-if="isExist(${index})">
|
|
|
<i-input
|
|
|
v-model="row.factoryCode"
|
|
|
placeholder="请输入..."
|
|
|
>
|
|
|
</i-input>
|
|
|
</div>`;
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
title: '尺码*',
|
|
|
key: 'sizeId',
|
|
|
width: 80,
|
|
|
render() {
|
|
|
return `<div class="size-id">
|
|
|
<div v-for="size in row.sizeId" class="row-span">
|
|
|
{{size.name}}
|
|
|
</div>
|
|
|
</div>`;
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
title: '商品条码*',
|
|
|
key: 'sizeCode',
|
|
|
render() {
|
|
|
return `<div class='size-code'>
|
|
|
<div v-for="size,i in row.sizeCode" class="row-span">
|
|
|
<div style="position: relative">
|
|
|
<div :class="{'size-code-error': size.validate && !size.name}">
|
|
|
<i-input
|
|
|
v-model="size.name"
|
|
|
:disabled="!row.operator[i].value"
|
|
|
placeholder="请输入..."
|
|
|
/>
|
|
|
</div>
|
|
|
<div class="size-code-tip" v-if="size.validate && !size.name">
|
|
|
不能为空
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>`;
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
title: '操作',
|
|
|
key: 'operator',
|
|
|
width: 100,
|
|
|
render(row, col, index) {
|
|
|
return `<template v-if="isExist(${index})">
|
|
|
<div class="size-operator" v-if="table.data[${index}]">
|
|
|
<div v-for="op,i in table.data[${index}].operator" class="row-span">
|
|
|
<i-button v-if="table.data[${index}].operator[i].value"
|
|
|
type="warning"
|
|
|
@click="clickOperator(row, i)">禁用</i-button>
|
|
|
<i-button v-else type="primary"
|
|
|
@click="clickOperator(row, i)">启用</i-button>
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>`;
|
|
|
}
|
|
|
}
|
|
|
],
|
|
|
data: [],
|
|
|
selectedSizes: [],
|
|
|
defaultSelectedSizes: [],
|
|
|
selectedColors: [],
|
|
|
defaultSelectedColors: [],
|
|
|
},
|
|
|
desc: '',
|
...
|
...
|
@@ -360,92 +139,113 @@ export default { |
|
|
created() {
|
|
|
service.getProduct(this.$route.params.id).then((result) => {
|
|
|
_.update(result, 'goodsSeason', (s) => `${s}`);
|
|
|
|
|
|
if (!_.has(result, 'materialList')) {
|
|
|
result.materialList = [];
|
|
|
}
|
|
|
|
|
|
this.product = result;
|
|
|
}).then(() => {
|
|
|
return Promise.all([
|
|
|
this.getSize(),
|
|
|
this.getAllAttr(this.product.smallSortId, this.product.maxSortId)
|
|
|
]);
|
|
|
return this.getAllAttr(this.product.smallSortId, this.product.maxSortId);
|
|
|
}).then(() => {
|
|
|
this.init();
|
|
|
this.show = false;
|
|
|
});
|
|
|
},
|
|
|
methods: {
|
|
|
clickOperator(row, itemIndex) {
|
|
|
this.refreshTable();
|
|
|
row.operator[itemIndex].value = row.operator[itemIndex].value ? false : true;
|
|
|
|
|
|
if (row.operator[itemIndex].value) {
|
|
|
row.sizeCode[itemIndex].name = '';
|
|
|
row.sizeCode[itemIndex].validate = true;
|
|
|
} else {
|
|
|
row.sizeCode[itemIndex].name = '';
|
|
|
row.sizeCode[itemIndex].validate = false;
|
|
|
}
|
|
|
},
|
|
|
clickColor(selectColors, color) {
|
|
|
this.addColor(color);
|
|
|
selectColor(selectColors) {
|
|
|
this.table.defaultSelectedColors = selectColors;
|
|
|
this.refreshGoods();
|
|
|
},
|
|
|
changeSizeCode(row, rowIndex, sizeIndex) {
|
|
|
this.table.data[rowIndex].sizeCode[sizeIndex].name = row.sizeCode[sizeIndex].name;
|
|
|
selectSize(selcetSize) {
|
|
|
this.table.defaultSelectedSizes = selcetSize;
|
|
|
this.refreshGoods();
|
|
|
},
|
|
|
changeFactoryGoodsName(row, index) {
|
|
|
this.table.data[index].factoryGoodsName = row.factoryGoodsName;
|
|
|
this.onChangeFactoryCode(index, row.factoryGoodsName);
|
|
|
},
|
|
|
changeFactoryCode(row, index) {
|
|
|
this.table.data[index].factoryCode = row.factoryCode;
|
|
|
},
|
|
|
uploadSuccess(attach, files) {
|
|
|
this.refreshTable();
|
|
|
this.table.data[attach.index].goodsColorImage.value = files[0];
|
|
|
this.onUploadGoodImage(attach, files[0]);
|
|
|
refreshGoods() {
|
|
|
this.$refs.tableGood.syncData();
|
|
|
|
|
|
this.table.data[attach.index].goodsColorImage.validate = true;
|
|
|
if (this.table.data[attach.index].goodsColorImage.value) {
|
|
|
this.table.data[attach.index].goodsColorImage.showValidate = false;
|
|
|
} else {
|
|
|
this.table.data[attach.index].goodsColorImage.showValidate = true;
|
|
|
}
|
|
|
},
|
|
|
uploadError() {
|
|
|
},
|
|
|
uploadImageSuccess(data, file) {
|
|
|
let colorIndex = data.goodIndex;
|
|
|
let imageIndex = data.imageIndex;
|
|
|
let rmCidIndex = _.map(this.table.data, (goodColor, index) => {
|
|
|
if (_.some(this.table.defaultSelectedColors, color => color.id === goodColor.colorId)) {
|
|
|
return -1;
|
|
|
}
|
|
|
return index;
|
|
|
}).filter(inx => inx >= 0);
|
|
|
|
|
|
_.remove(this.table.data, (good, index) => _.some(rmCidIndex, inx => inx === index));
|
|
|
_.remove(this.product.goods, (good, index) => _.some(rmCidIndex, inx => inx === index));
|
|
|
_.each(this.table.defaultSelectedColors, color => {
|
|
|
let colorGood = _.find(this.table.data, good => good.colorId === color.id);
|
|
|
|
|
|
if (colorGood) {
|
|
|
let rmSidIndexs = _.map(colorGood.sizeId, (goodSize, index) => {
|
|
|
if (_.some(this.table.defaultSelectedSizes, size => size.id === goodSize.id)) {
|
|
|
return -1;
|
|
|
}
|
|
|
return index;
|
|
|
}).filter(inx => inx >= 0);
|
|
|
|
|
|
this.product.goods[colorIndex].goodsImage[imageIndex].imageUrl = file.url;
|
|
|
},
|
|
|
uploadImageRemove(data) {
|
|
|
let colorIndex = data.goodIndex;
|
|
|
let imageIndex = data.imageIndex;
|
|
|
_.remove(colorGood.sizeId, (sid, index) => _.some(rmSidIndexs, inx => inx === index));
|
|
|
_.remove(colorGood.sizeCode, (code, index) => _.some(rmSidIndexs, inx => inx === index));
|
|
|
_.remove(colorGood.operator, (op, index) => _.some(rmSidIndexs, inx => inx === index));
|
|
|
|
|
|
this.product.goods[colorIndex].goodsImage[imageIndex].imageUrl = '';
|
|
|
},
|
|
|
clickDefault(index) {
|
|
|
this.refreshTable();
|
|
|
let color = this.table.data[index];
|
|
|
let addSizeList = this.table.defaultSelectedSizes
|
|
|
.filter(size => !_.some(colorGood.sizeId, goodSize => size.id === goodSize.id));
|
|
|
|
|
|
color.goodsName.isDefault = true;
|
|
|
this.table.data.forEach((c) => {
|
|
|
if (c.colorId !== color.colorId) {
|
|
|
c.goodsName.isDefault = false;
|
|
|
_.each(addSizeList, size => this.addSizeItem(colorGood, size));
|
|
|
} else {
|
|
|
let newGood = {
|
|
|
goodsName: {
|
|
|
name: color.colorName,
|
|
|
isDefault: false,
|
|
|
},
|
|
|
factoryGoodsName: '',
|
|
|
goodsColorImage: {
|
|
|
value: '',
|
|
|
showValidate: false,
|
|
|
validate: false
|
|
|
},
|
|
|
factoryCode: '',
|
|
|
colorId: color.id,
|
|
|
sizeId: [],
|
|
|
sizeCode: [],
|
|
|
operator: []
|
|
|
};
|
|
|
|
|
|
_.each(this.table.defaultSelectedSizes, size => this.addSizeItem(newGood, size));
|
|
|
this.table.data.push(newGood);
|
|
|
this.product.goods.push(service.handleGoods({
|
|
|
goodsName: color.colorName,
|
|
|
productSkn: this.product.productSkn,
|
|
|
factoryGoodsName: ''
|
|
|
}));
|
|
|
}
|
|
|
});
|
|
|
},
|
|
|
getSize() {
|
|
|
return api.getSize(this.product.smallSortId).then((result) => {
|
|
|
if (result.code === 200) {
|
|
|
this.sizes = result.data;
|
|
|
}
|
|
|
addSizeItem(colorGood, size) {
|
|
|
colorGood.sizeId.push({
|
|
|
id: size.id,
|
|
|
name: size.sizeName
|
|
|
});
|
|
|
colorGood.sizeCode.push({
|
|
|
name: '',
|
|
|
showValidate: false,
|
|
|
validate: false
|
|
|
});
|
|
|
colorGood.operator.push({
|
|
|
value: true
|
|
|
});
|
|
|
},
|
|
|
onChangeFactoryCode(index, code) {
|
|
|
let goods = this.product.goods[index];
|
|
|
|
|
|
goods.factoryGoodsName = code;
|
|
|
|
|
|
// 同步图片中的factoryGoodsName 的值
|
|
|
goods.goodsImage.forEach((image) => {
|
|
|
image.factoryGoodsName = code || goods.goodsName;
|
|
|
});
|
|
|
},
|
|
|
uploadGoodSzieSuccess(attach, file) {
|
|
|
this.product.goods[attach.index].goodsImage[0].imageUrl = file;
|
|
|
},
|
|
|
getAllAttr(smallSortId, maxSortId) {
|
|
|
return api.getAllAttr(smallSortId, maxSortId).then((result) => {
|
|
|
this.render.productStandardRelationStr = service.addNoneItem(result[0] || []);
|
...
|
...
|
@@ -487,28 +287,28 @@ export default { |
|
|
this.initDefaultSelectedSize();
|
|
|
this.initTableData();
|
|
|
this.initImage();
|
|
|
this.initAttr();
|
|
|
},
|
|
|
initDefaultSelectedColor() {
|
|
|
this.table.defaultSelectedColors = _.map(this.product.sellerGoodList, good => {
|
|
|
return {
|
|
|
id: good.colorId,
|
|
|
selected: false,
|
|
|
disable: true
|
|
|
disabled: true
|
|
|
};
|
|
|
});
|
|
|
},
|
|
|
initDefaultSelectedSize() {
|
|
|
let goodsSizeList = Fn.props('goodsSizeList');
|
|
|
let uniqSize = Fn.uniqBy((s) => s.sizeId);
|
|
|
let allHandleItem = _.flow(Fn.map(goodsSizeList), _.flattenDeep, uniqSize)(this.product.sellerGoodList);
|
|
|
|
|
|
let selectSize = Fn.filter(s => _.find(allHandleItem, (selectedItem) => selectedItem.sizeId === s.id));
|
|
|
|
|
|
this.table.selectedSizes = selectSize(this.sizes).map((s) => {
|
|
|
s.disabled = true;
|
|
|
return s.id;
|
|
|
});
|
|
|
let goodFirst = _.first(this.product.sellerGoodList);
|
|
|
|
|
|
if (goodFirst) {
|
|
|
this.table.defaultSelectedSizes = _.map(goodFirst.goodsSizeList, size => {
|
|
|
return {
|
|
|
id: size.sizeId,
|
|
|
sizeName: size.sizeName,
|
|
|
disabled: true
|
|
|
};
|
|
|
});
|
|
|
}
|
|
|
},
|
|
|
initTableData() {
|
|
|
let goodsList = this.product.sellerGoodList;
|
...
|
...
|
@@ -522,8 +322,6 @@ export default { |
|
|
initImage() {
|
|
|
this.product.goods = this.product.sellerGoodsImagesList.map(service.handleGoodsImage);
|
|
|
},
|
|
|
initAttr() {
|
|
|
},
|
|
|
handleItem(goods, goodsImage) {
|
|
|
let newGoods = {};
|
|
|
|
...
|
...
|
@@ -545,261 +343,38 @@ export default { |
|
|
newGoods.sizeId = [];
|
|
|
newGoods.sizeCode = [];
|
|
|
newGoods.operator = [];
|
|
|
|
|
|
this.table.selectedSizes.forEach((s) => {
|
|
|
let sizeObj = _.find(this.sizes, { id: s });
|
|
|
|
|
|
if (!sizeObj) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
this.table.defaultSelectedSizes.forEach(size => {
|
|
|
newGoods.sizeId.push({
|
|
|
id: sizeObj.id,
|
|
|
name: sizeObj.sizeName,
|
|
|
id: size.id,
|
|
|
name: size.sizeName,
|
|
|
productSku: '',
|
|
|
});
|
|
|
|
|
|
newGoods.sizeCode.push({
|
|
|
name: '',
|
|
|
validate: false,
|
|
|
showValidate: false
|
|
|
});
|
|
|
|
|
|
newGoods.operator.push({
|
|
|
value: false
|
|
|
});
|
|
|
});
|
|
|
|
|
|
goods.goodsSizeList.forEach((s) => {
|
|
|
let index = _.findIndex(newGoods.sizeId, { id: s.sizeId });
|
|
|
|
|
|
if (index === -1) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
newGoods.sizeId[index].productSku = s.productSku;
|
|
|
|
|
|
if (s.factoryCode) {
|
|
|
newGoods.sizeCode[index].name = s.factoryCode;
|
|
|
newGoods.operator[index].value = true;
|
|
|
}
|
|
|
});
|
|
|
|
|
|
return newGoods;
|
|
|
},
|
|
|
updateProductDesc(c) {
|
|
|
this.product.productIntro = c;
|
|
|
},
|
|
|
beforeSave() {
|
|
|
let newProduct = {};
|
|
|
|
|
|
this.refreshTable();
|
|
|
|
|
|
newProduct.productSkn = this.product.productSkn;
|
|
|
newProduct.id = this.product.id;
|
|
|
newProduct.productName = this.product.productName;
|
|
|
newProduct.gender = this.product.gender;
|
|
|
newProduct.factoryCode = this.product.factoryCode;
|
|
|
newProduct.goodsYears = this.product.goodsYears;
|
|
|
newProduct.phrase = this.product.phrase;
|
|
|
newProduct.goodsSeason = this.product.goodsSeason;
|
|
|
newProduct.ageLevel = this.product.ageLevel;
|
|
|
newProduct.seasons = this.product.seasons;
|
|
|
newProduct.expectSaleTimeStr = this.product.expectSaleTimeStr;
|
|
|
|
|
|
newProduct.sellerGoodsInfoStr = JSON.stringify(this.handleColor());
|
|
|
newProduct.goodsImagesReqStr = JSON.stringify(this.handleImage());
|
|
|
newProduct.productStandardRelationStr = JSON.stringify(this.handleRelation());
|
|
|
newProduct.attributeProValuesOne = JSON.stringify(this.handleOne());
|
|
|
newProduct.attributeProValuesTwo = JSON.stringify(this.handleTwo());
|
|
|
|
|
|
newProduct.productMaterial = this.product.materialList.map(s => s.id).join(',');
|
|
|
newProduct.productIntro = this.product.productIntro;
|
|
|
|
|
|
return newProduct;
|
|
|
},
|
|
|
save() {
|
|
|
let newProduct = this.beforeSave();
|
|
|
|
|
|
this.$Loading.start();
|
|
|
console.log(JSON.stringify(newProduct));
|
|
|
return;
|
|
|
|
|
|
// return api.updateProductAllInfo(newProduct).then((result) => {
|
|
|
// this.$Loading.finish();
|
|
|
|
|
|
// if (result.code === 200) {
|
|
|
// this.$Notice.success({
|
|
|
// title: '修改成功',
|
|
|
// desc: '该商品保存成功!'
|
|
|
// });
|
|
|
|
|
|
// this.$router.push({ name: 'product.offsale' });
|
|
|
// } else {
|
|
|
// this.$Notice.error({
|
|
|
// title: '保存错误',
|
|
|
// desc: result.message
|
|
|
// });
|
|
|
|
|
|
// }
|
|
|
// });
|
|
|
},
|
|
|
submit() {
|
|
|
this.validate()
|
|
|
.then(([r1, r2]) => {
|
|
|
if (r1 & r2) {
|
|
|
return Promise.resolve();
|
|
|
} else {
|
|
|
this.$Message.error('验证未通过');
|
|
|
return Promise.reject();
|
|
|
}
|
|
|
})
|
|
|
.then(this.save).catch(() => this.$Loading.error());
|
|
|
},
|
|
|
isExist(index) {
|
|
|
let row = this.table.data[index];
|
|
|
|
|
|
if (row) {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
},
|
|
|
addColor(color) {
|
|
|
this.refreshTable();
|
|
|
|
|
|
if (color.disabled) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
let findColorIndex = this.table.selectedColors.findIndex((c) => {
|
|
|
return c.id === color.id;
|
|
|
});
|
|
|
|
|
|
if (findColorIndex !== -1) {
|
|
|
this.removeColorData(color);
|
|
|
this.table.selectedColors.splice(findColorIndex, 1);
|
|
|
color.selected = false;
|
|
|
} else {
|
|
|
this.addColorData(color);
|
|
|
this.table.selectedColors.push(color);
|
|
|
color.selected = true;
|
|
|
}
|
|
|
},
|
|
|
addColorData(color) {
|
|
|
let newColor = {
|
|
|
goodsName: {
|
|
|
name: color.colorName,
|
|
|
isDefault: false,
|
|
|
},
|
|
|
factoryGoodsName: '',
|
|
|
goodsColorImage: {
|
|
|
value: '',
|
|
|
showValidate: false,
|
|
|
validate: false
|
|
|
},
|
|
|
factoryCode: '',
|
|
|
colorId: color.id,
|
|
|
sizeId: [],
|
|
|
sizeCode: [],
|
|
|
operator: []
|
|
|
};
|
|
|
|
|
|
if (this.table.selectedSizes.length > 0) {
|
|
|
this.table.selectedSizes.forEach((sizeId) => {
|
|
|
this.addSize(newColor, sizeId);
|
|
|
});
|
|
|
}
|
|
|
|
|
|
this.table.data.push(newColor);
|
|
|
this.onAddColor({ goodsName: color.colorName, productSkn: this.product.productSkn });
|
|
|
},
|
|
|
removeColorData(color) {
|
|
|
let index = this.table.data.findIndex((d) => {
|
|
|
return d.colorId === color.id;
|
|
|
});
|
|
|
|
|
|
this.table.data.splice(index, 1);
|
|
|
this.onRemoveColor(index);
|
|
|
},
|
|
|
addSize(color, sizeId) {
|
|
|
let findSize = this.findSize(sizeId);
|
|
|
|
|
|
if (!findSize) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
color.sizeId.push({
|
|
|
id: findSize.id,
|
|
|
name: findSize.sizeName
|
|
|
});
|
|
|
|
|
|
color.sizeCode.push({
|
|
|
name: '',
|
|
|
showValidate: false,
|
|
|
validate: false
|
|
|
});
|
|
|
|
|
|
color.operator.push({
|
|
|
value: true
|
|
|
});
|
|
|
},
|
|
|
findSize(sizeId) {
|
|
|
let index = this.sizes.findIndex((sizeObj) => {
|
|
|
return sizeObj.id === sizeId;
|
|
|
});
|
|
|
|
|
|
if (index !== -1) {
|
|
|
return this.sizes[index];
|
|
|
}
|
|
|
|
|
|
return null;
|
|
|
},
|
|
|
removeSize(color, sizeId) {
|
|
|
|
|
|
let index = color.sizeId.findIndex((s) => {
|
|
|
return s.id === sizeId;
|
|
|
});
|
|
|
|
|
|
if (index !== -1) {
|
|
|
color.sizeId.splice(index, 1);
|
|
|
color.sizeCode.splice(index, 1);
|
|
|
color.operator.splice(index, 1);
|
|
|
}
|
|
|
},
|
|
|
isInColorSize(s) {
|
|
|
let sizeId = (this.table.data[0] || {}).sizeId || [];
|
|
|
|
|
|
let id = sizeId.map(si => si.id);
|
|
|
|
|
|
return _.includes(id, s);
|
|
|
},
|
|
|
onAddColor(newGoods) {
|
|
|
this.product.goods.push(service.handleGoods(newGoods));
|
|
|
},
|
|
|
onRemoveColor(index) {
|
|
|
this.product.goods.splice(index, 1);
|
|
|
},
|
|
|
onUploadGoodImage(attach, file) {
|
|
|
let index = attach.index;
|
|
|
|
|
|
// 注意这里vue 没有办法监听到,手动添加监听
|
|
|
this.$set(this.product, `goods[${index}].goodsImage[0].imageUrl`, file);
|
|
|
this.product.goods[index].goodsImage[0].imageUrl = file;
|
|
|
},
|
|
|
onChangeFactoryCode(index, code) {
|
|
|
// 注意这里vue 没有办法监听到,手动添加监听
|
|
|
this.$set(this.product, `goods[${index}].factoryGoodsName`, code);
|
|
|
|
|
|
let goods = this.product.goods[index];
|
|
|
|
|
|
goods.factoryGoodsName = code;
|
|
|
|
|
|
// 同步图片中的factoryGoodsName 的值
|
|
|
goods.goodsImage.forEach((image) => {
|
|
|
image.factoryGoodsName = code || goods.goodsName;
|
|
|
});
|
|
|
},
|
|
|
validate() {
|
|
|
return Promise.all([this.validateProduct(), this.validateTable()]);
|
|
|
},
|
...
|
...
|
@@ -815,7 +390,7 @@ export default { |
|
|
});
|
|
|
},
|
|
|
validateTable() {
|
|
|
this.refreshTable();
|
|
|
this.$refs.tableGood.syncData();
|
|
|
let errors = [];
|
|
|
|
|
|
this.table.data.forEach((color) => {
|
...
|
...
|
@@ -846,36 +421,89 @@ export default { |
|
|
return Promise.resolve(false);
|
|
|
}
|
|
|
},
|
|
|
refreshTable() {
|
|
|
this.table.data = this.$refs.sellerGoods.rebuildData;
|
|
|
},
|
|
|
handleColor() {
|
|
|
return this.table.data.map(this._handleColor);
|
|
|
beforeSave() {
|
|
|
let newProduct = {};
|
|
|
|
|
|
this.$refs.tableGood.syncData();
|
|
|
|
|
|
newProduct.productSkn = this.product.productSkn;
|
|
|
newProduct.id = this.product.id;
|
|
|
newProduct.productName = this.product.productName;
|
|
|
newProduct.gender = this.product.gender;
|
|
|
newProduct.factoryCode = this.product.factoryCode;
|
|
|
newProduct.goodsYears = this.product.goodsYears;
|
|
|
newProduct.phrase = this.product.phrase;
|
|
|
newProduct.goodsSeason = this.product.goodsSeason;
|
|
|
newProduct.ageLevel = this.product.ageLevel;
|
|
|
newProduct.seasons = this.product.seasons;
|
|
|
newProduct.expectSaleTimeStr = this.product.expectSaleTimeStr;
|
|
|
|
|
|
newProduct.sellerGoodsInfoStr =
|
|
|
JSON.stringify(this.handleColor());
|
|
|
newProduct.goodsImagesReqStr =
|
|
|
JSON.stringify(service.handleEditColorImage(this.product));
|
|
|
newProduct.productStandardRelationStr =
|
|
|
JSON.stringify(serial.handleRelation(this.render.productStandardRelationStr));
|
|
|
newProduct.attributeProValuesOne =
|
|
|
JSON.stringify(serial.handleOne(this.product.productSkn, this.render.attributeProValuesOne));
|
|
|
newProduct.attributeProValuesTwo =
|
|
|
JSON.stringify(serial.handleTwo(this.product.productSkn, this.render.attributeProValuesTwo));
|
|
|
|
|
|
newProduct.productMaterial = this.product.materialList.map(s => s.id).join(',');
|
|
|
newProduct.productIntro = this.product.productIntro;
|
|
|
|
|
|
return newProduct;
|
|
|
},
|
|
|
_handleColor(tableColor) {
|
|
|
let newColor = {
|
|
|
factoryCode: '',
|
|
|
factoryGoodsName: '',
|
|
|
isDefault: '',
|
|
|
goodsColorImage: '',
|
|
|
productSkc: '',
|
|
|
id: '',
|
|
|
goodsName: '',
|
|
|
colorId: '',
|
|
|
goodsSizeList: []
|
|
|
};
|
|
|
save() {
|
|
|
let newProduct = this.beforeSave();
|
|
|
|
|
|
this.$Loading.start();
|
|
|
|
|
|
newColor.factoryCode = tableColor.factoryCode;
|
|
|
newColor.factoryGoodsName = tableColor.factoryGoodsName || tableColor.goodsName.name;
|
|
|
newColor.isDefault = tableColor.goodsName.isDefault ? 'Y' : 'N';
|
|
|
newColor.goodsColorImage = tableColor.goodsColorImage.value;
|
|
|
newColor.productSkc = tableColor.productSkc;
|
|
|
newColor.id = tableColor.id;
|
|
|
newColor.goodsName = tableColor.goodsName.name;
|
|
|
newColor.colorId = tableColor.colorId;
|
|
|
newColor.goodsSizeList = this.handleSize(tableColor);
|
|
|
return api.updateProductAllInfo(newProduct).then((result) => {
|
|
|
this.$Loading.finish();
|
|
|
|
|
|
if (result.code === 200) {
|
|
|
this.$Notice.success({
|
|
|
title: '修改成功',
|
|
|
desc: '该商品保存成功!'
|
|
|
});
|
|
|
|
|
|
this.$router.push({ name: 'product.offsale' });
|
|
|
} else {
|
|
|
this.$Notice.error({
|
|
|
title: '保存错误',
|
|
|
desc: result.message
|
|
|
});
|
|
|
|
|
|
return newColor;
|
|
|
}
|
|
|
});
|
|
|
},
|
|
|
submit() {
|
|
|
this.validate()
|
|
|
.then(([r1, r2]) => {
|
|
|
if (r1 & r2) {
|
|
|
return Promise.resolve();
|
|
|
} else {
|
|
|
this.$Message.error('验证未通过');
|
|
|
return Promise.reject();
|
|
|
}
|
|
|
})
|
|
|
.then(this.save).catch(() => this.$Loading.error());
|
|
|
},
|
|
|
handleColor() {
|
|
|
return this.table.data.map(tableColor => {
|
|
|
return {
|
|
|
factoryCode: tableColor.factoryCode,
|
|
|
factoryGoodsName: tableColor.factoryGoodsName || tableColor.goodsName.name,
|
|
|
isDefault: tableColor.goodsName.isDefault ? 'Y' : 'N',
|
|
|
goodsColorImage: tableColor.goodsColorImage.value,
|
|
|
productSkc: tableColor.productSkc,
|
|
|
id: tableColor.id,
|
|
|
goodsName: tableColor.goodsName.name,
|
|
|
colorId: tableColor.colorId,
|
|
|
goodsSizeList: this.handleSize(tableColor)
|
|
|
};
|
|
|
});
|
|
|
},
|
|
|
handleSize(color) {
|
|
|
return color.sizeId.reduce((total, cur, i) => {
|
...
|
...
|
@@ -889,51 +517,19 @@ export default { |
|
|
|
|
|
return total;
|
|
|
}, []);
|
|
|
},
|
|
|
handleImage() {
|
|
|
return service.handleEditColorImage(this.product);
|
|
|
},
|
|
|
handleRelation() {
|
|
|
return serial.handleRelation(this.render.productStandardRelationStr);
|
|
|
},
|
|
|
handleOne() {
|
|
|
return serial.handleOne(this.product.productSkn, this.render.attributeProValuesOne);
|
|
|
},
|
|
|
handleTwo() {
|
|
|
return serial.handleTwo(this.product.productSkn, this.render.attributeProValuesTwo);
|
|
|
},
|
|
|
}
|
|
|
},
|
|
|
components: {
|
|
|
'shop-material': ShopMaterial,
|
|
|
'multi-select': MuliSelect,
|
|
|
Material,
|
|
|
MuliSelect,
|
|
|
TableGood,
|
|
|
CheckboxAge,
|
|
|
RadioSeason,
|
|
|
RadioGender,
|
|
|
SelectSeason,
|
|
|
CheckboxColor
|
|
|
},
|
|
|
watch: {
|
|
|
'table.selectedSizes'(newVal, oldVal) {
|
|
|
let addSize = _.differenceWith(newVal, oldVal, (left, right) => {
|
|
|
return left === right;
|
|
|
});
|
|
|
|
|
|
let removeSize = _.differenceWith(oldVal, newVal, (left, right) => {
|
|
|
return left === right;
|
|
|
});
|
|
|
|
|
|
addSize = addSize.filter(s => !this.isInColorSize(s));
|
|
|
|
|
|
_.forEach(this.table.data, (color) => {
|
|
|
if (!_.isEmpty(addSize)) {
|
|
|
addSize.forEach(s => this.addSize(color, s));
|
|
|
}
|
|
|
|
|
|
if (!_.isEmpty(removeSize)) {
|
|
|
removeSize.forEach(s => this.removeSize(color, s));
|
|
|
}
|
|
|
});
|
|
|
},
|
|
|
CheckboxColor,
|
|
|
CheckboxSize,
|
|
|
GoodImage
|
|
|
}
|
|
|
};
|
|
|
</script>
|
...
|
...
|
@@ -984,90 +580,4 @@ export default { |
|
|
margin-top: 20px;
|
|
|
}
|
|
|
|
|
|
@mixin row-span {
|
|
|
min-height: 30px;
|
|
|
|
|
|
.row-span {
|
|
|
min-height: 30px;
|
|
|
border-bottom: 1px solid #e3e8ee;
|
|
|
padding-top: 20px;
|
|
|
padding-bottom: 20px;
|
|
|
margin-left: -18px;
|
|
|
margin-right: -18px;
|
|
|
padding-left: 18px;
|
|
|
padding-right: 18px;
|
|
|
|
|
|
&:last-child {
|
|
|
border-bottom: none;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
.size-code {
|
|
|
@include row-span;
|
|
|
|
|
|
&-error {
|
|
|
border: 1px solid #f30;
|
|
|
}
|
|
|
|
|
|
&-tip {
|
|
|
position: absolute;
|
|
|
line-height: 1;
|
|
|
padding-top: 6px;
|
|
|
color: #f30;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.size-id {
|
|
|
@include row-span;
|
|
|
text-align: center;
|
|
|
}
|
|
|
|
|
|
.size-operator {
|
|
|
@include row-span;
|
|
|
text-align: center;
|
|
|
}
|
|
|
|
|
|
.upload-item {
|
|
|
display: inline-block;
|
|
|
height: 180px;
|
|
|
width: 130px;
|
|
|
text-align: center;
|
|
|
margin: 10px 0;
|
|
|
}
|
|
|
|
|
|
.color-item-title {
|
|
|
text-align: center;
|
|
|
margin: 50px 0;
|
|
|
}
|
|
|
|
|
|
.upload-item {
|
|
|
display: inline-block;
|
|
|
height: 200px;
|
|
|
width: 130px;
|
|
|
text-align: center;
|
|
|
margin: 30px 0;
|
|
|
}
|
|
|
|
|
|
.upload-item-error {
|
|
|
border: 1px solid #f30;
|
|
|
position: relative;
|
|
|
}
|
|
|
|
|
|
.upload-item-tip {
|
|
|
position: absolute;
|
|
|
line-height: 1;
|
|
|
padding-top: 6px;
|
|
|
color: #f30;
|
|
|
top: 100%;
|
|
|
}
|
|
|
|
|
|
.upload-item-img {
|
|
|
display: inline-block;
|
|
|
height: 126px;
|
|
|
width: 124px;
|
|
|
border: 2px solid #e8e8e8;
|
|
|
box-sizing: border-box;
|
|
|
}
|
|
|
</style> |
...
|
...
|
|