Authored by htoooth

fix

... ... @@ -17,19 +17,21 @@
</Row>
<Row>
<Col span="8">
<Form-item label="品牌">
<div class="ivu-form-item ivu-form-item-required">
<label class="ivu-form-item-label" style="width: 70px;">品牌</label>
<div style="float: left; line-height: 1; padding: 10px 12px 10px 0; box-sizing: border-box;">
<span>{{product.brandName}}</span>
</Form-item>
</Col>
</div>
</div>
</Row>
<Row>
<Col span="8">
<Form-item label="类目">
<div class="ivu-form-item ivu-form-item-required">
<label class="ivu-form-item-label" style="width: 70px;">类目</label>
<span style="float: left; line-height: 1; padding: 10px 12px 10px 0; box-sizing: border-box;">
<span>{{sortName}}</span>
</Form-item>
</Col>
</span>
</div>
</Row>
<Row>
... ... @@ -103,30 +105,38 @@
</Row>
<Row>
<Form-item label="颜色">
<span class='squre'
v-for="color in colors"
@click="clickColor(color)"
:class="{
'squre-selected': color.selected,
'squre-disabled': color.disabled
}">
<span class="squre-color"
:style="{ 'background-color': '#' + color.colorCode}">
<div class="ivu-form-item ivu-form-item-required">
<label class="ivu-form-item-label" style="width: 70px;"> 颜色</label>
<div :class="{'product-table-error' : table.showValidateColor}" style="margin-left: 70px;">
<span class='squre'
v-for="color in colors"
@click="clickColor(color)"
:class="{
'squre-selected': color.selected,
'squre-disabled': color.disabled
}">
<span class="squre-color"
:style="{ 'background-color': '#' + color.colorCode}">
</span>
<span class="squre-name">{{color.colorName}}</span>
</span>
<span class="squre-name">{{color.colorName}}</span>
</span>
</Form-item>
</div>
<div class="product-table-tip" v-if="table.showValidateColor">颜色必须选择</div>
</div>
</Row>
<Row>
<Form-item label="尺寸">
<Checkbox-group v-model='table.selectedSizes'>
<Checkbox v-for="size in sizes" :key="size" :label="size.id" >
<span>{{size.sizeName}}</span>
</Checkbox>
</Checkbox-group>
</Form-item>
<div class="ivu-form-item ivu-form-item-required">
<label class="ivu-form-item-label" style="width: 70px;">尺寸</label>
<div :class="{'product-table-error': table.showValidateSize}" style="margin-left: 70px;">
<Checkbox-group v-model='table.selectedSizes'>
<Checkbox v-for="size in sizes" :key="size" :label="size.id" >
<span>{{size.sizeName}}</span>
</Checkbox>
</Checkbox-group>
</div>
<div class="product-table-tip" v-if="table.showValidateSize">尺码必须选择</div>
</div>
</Row>
<Row>
... ... @@ -194,6 +204,8 @@ const makeColor = () => {
};
};
export default {
props: ['step', 'product'],
data() {
... ... @@ -237,7 +249,7 @@ export default {
return {
self: this,
colors: [],
selectedColors: [],
sizes: [],
table: {
columns: [
... ... @@ -259,8 +271,7 @@ export default {
return `<div v-if="isExist(${index})">
<i-input
v-model="row.factoryGoodsName"
placeholder="请输入..."
style="width: 100px">
:placeholder="row.goodsName.name">
</i-input>
</div>`;
}
... ... @@ -268,12 +279,26 @@ export default {
{
title: '色卡图片*',
key: 'goodsColorImage',
width: 170,
render(row, col, index) {
return `<img v-if="row.goodsColorImage"
:src="row.goodsColorImage" alt="" width="120px" height="120px">
<yoho-upload :id="{index: ${index}}"
@on-success="uploadSuccess"
@on-error="uploadError"></yoho-upload>`;
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>
<yoho-upload :id="{index: ${index}}"
@on-success="uploadSuccess"
@on-error="uploadError"></yoho-upload>
</div>
<div v-if="row.goodsColorImage.showValidate && row.goodsColorImage.validate"
class="upload-item-tip">
必须上传图片
</div>
</div>`;
}
},
{
... ... @@ -283,15 +308,15 @@ export default {
return `<div v-if="isExist(${index})">
<i-input
v-model="row.factoryCode"
placeholder="请输入..."
style="width: 100px">
placeholder="请输入..." >
</i-input>
</div>`;
}
},
{
title: '尺码*',
title: '尺码',
key: 'sizeId',
width: 80,
render(row, col, index) {
return `<div class="size-id">
<div v-for="size in row.sizeId" class="row-span">
... ... @@ -306,11 +331,18 @@ export default {
render(row, col, index) {
return `<div class='size-code'>
<div v-for="size,i in row.sizeCode" class="row-span">
<i-input
v-model="size.name"
:disabled="!row.operator[i].value"
placeholder="请输入..."
style="width: 100px"/>
<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>`;
}
... ... @@ -318,6 +350,7 @@ export default {
{
title: '操作',
key: 'operator',
width: 100,
render(row, col, index) {
return `<template v-if="isExist(${index})">
<div class="size-operator">
... ... @@ -335,9 +368,12 @@ export default {
],
data: [],
selectedSizes: [],
selectedColors: []
selectedColors: [],
showValidateColor: false,
showValidateSize: false,
showValidateOtherProp: false,
showValidateTable: false,
},
ageLevel: [],
ruleValidate: {
productName: [
{ required: true, message: '商品名不能为空', trigger: 'blur'}
... ... @@ -376,19 +412,49 @@ export default {
};
},
mounted: function() {
this.getColor();
this.getSize();
this.getColorAsync();
this.getSizeAsync();
},
methods: {
validate: function() {
return new Promise((resolve, reject) => {
this.$refs['product'].validate((valid) => {
if (valid) {
resolve();
} else {
reject();
beforeSubmit: function() {
const handleColor = (color) => {
let newColor = makeColor();
newColor.goodsName = color.goodsName.name;
newColor.isDefault = color.goodsName.isDefault ? 'Y' : 'N';
newColor.factoryGoodsName = color.factoryGoodsName || color.goodsName.name;
newColor.factoryCode = color.factoryCode;
newColor.goodsColorImage = color.goodsColorImage.value;
newColor.colorId = color.colorId;
let goodsSizeList = [];
color.operator.forEach((op, i) => {
if (!op.value) {
return;
}
})
let goodsSize = {};
goodsSize.sizeId = color.sizeId[i].id;
goodsSize.factoryCode = color.sizeCode[i].name;
goodsSizeList.push(goodsSize);
});
newColor.goodsSizeList = goodsSizeList;
return newColor;
};
this.refreshTable();
this.product.sellerGoodsInfoStr = JSON.stringify(this.table.data.map(handleColor));
},
submit: function() {
return this.validate().then(() => {
this.beforeSubmit();
return api.saveBaseProductInfo(this.product);
});
},
nextStep: function() {
... ... @@ -424,14 +490,14 @@ export default {
this.step.value = 0;
this.$router.push({name: 'product.create.step1'});
},
getColor: function() {
getColorAsync: function() {
return api.getColor().then((result) => {
if (result.code === 200) {
this.colors = result.data;
}
});
},
getSize: function() {
getSizeAsync: function() {
return api.getSize(this.product.smallSortId).then((result) => {
if (result.code === 200) {
this.sizes = result.data;
... ... @@ -441,21 +507,6 @@ export default {
clickColor: function(color) {
this.addColor(color);
},
changeFactoryGoodsName: function(row, index) {
this.table.data[index].factoryGoodsName = row.factoryGoodsName;
},
changeFactoryCode: function(row, index) {
this.table.data[index].factoryCode = row.factoryCode;
},
changeUploadFileSuccess: function(row, index) {
this.table.data[index].goodsColorImage = row.goodsColorImage;
},
changeUploadFileFail: function(row, index) {
},
changeSizeCode: function(row, rowIndex, sizeIndex) {
this.table.data[rowIndex].sizeCode[sizeIndex].name = row.sizeCode[sizeIndex].name;
},
clickDefault: function(index) {
this.refreshTable();
let color = this.table.data[index];
... ... @@ -471,6 +522,15 @@ export default {
clickOperator: function(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;
}
},
clickGoodsYear: function(value) {
this.product.goodsYears = value;
... ... @@ -493,6 +553,22 @@ export default {
_.first(this.table.data).goodsName.isDefault = true;
},
changeFactoryGoodsName: function(row, index) {
this.table.data[index].factoryGoodsName = row.factoryGoodsName;
},
changeFactoryCode: function(row, index) {
this.table.data[index].factoryCode = row.factoryCode;
},
changeSizeCode: function(row, rowIndex, sizeIndex) {
this.table.data[rowIndex].sizeCode[sizeIndex].name = row.sizeCode[sizeIndex].name;
this.table.data[rowIndex].sizeCode[sizeIndex].validate = true;
if (this.table.data[rowIndex].sizeCode[sizeIndex].name) {
this.table.data[rowIndex].sizeCode[sizeIndex].showValidate = false;
} else {
this.table.data[rowIndex].sizeCode[sizeIndex].showValidate = true;
}
},
addColor: function(color) {
this.refreshTable();
let findColorIndex = this.table.selectedColors.findIndex((c) => {
... ... @@ -511,39 +587,6 @@ export default {
this.initDefault();
},
addSize: function(color, sizeId) {
this.refreshTable();
let findSize = this.findSize(sizeId);
if (!findSize) {
return;
}
color.sizeId.push({
id: findSize.id,
name: findSize.sizeName
});
color.sizeCode.push({
name: ''
});
color.operator.push({
value: false
});
},
removeSize: function(color, sizeId) {
this.refreshTable();
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);
}
},
addColorData: function(color) {
let newColor = {
goodsName: {
... ... @@ -551,7 +594,11 @@ export default {
isDefault: false,
},
factoryGoodsName: '',
goodsColorImage: '',
goodsColorImage: {
value: '',
showValidate: false,
validate: false
},
factoryCode: '',
colorId: color.id,
sizeId: [],
... ... @@ -574,6 +621,41 @@ export default {
this.table.data.splice(index, 1);
},
removeSize: function(color, sizeId) {
this.refreshTable();
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);
}
},
addSize: function(color, sizeId) {
this.refreshTable();
let findSize = this.findSize(sizeId);
if (!findSize) {
return;
}
color.sizeId.push({
id: findSize.id,
name: findSize.sizeName
});
color.sizeCode.push({
name: '',
validate: false,
showValidate: false
});
color.operator.push({
value: true
});
},
findSize: function(sizeId) {
let index = this.sizes.findIndex((sizeObj) => {
return sizeObj.id === sizeId;
... ... @@ -594,55 +676,119 @@ export default {
return false;
},
submit: function() {
return this.validate().then(() => {
this.beforeSubmit();
return api.saveBaseProductInfo(this.product);
});
},
beforeSubmit: function() {
const handleColor = (color) => {
let newColor = makeColor();
newColor.goodsName = color.goodsName.name;
newColor.isDefault = color.goodsName.isDefault ? 'Y' : 'N';
newColor.factoryGoodsName = color.factoryGoodsName;
newColor.factoryCode = color.factoryCode;
newColor.goodsColorImage = color.goodsColorImage;
newColor.colorId = color.colorId;
uploadSuccess: function(attach, files) {
this.refreshTable();
this.table.data[attach.index].goodsColorImage.value = files[0];
let goodsSizeList = [];
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;
}
},
refreshTable() {
this.table.data = this.$refs.sellerGoods.rebuildData;
},
uploadError: function(attach, err) {
},
validateOtherProps: function() {
return new Promise((resolve, reject) => {
this.$refs['product'].validate((valid) => {
if (valid) {
this.table.showValidateOtherProps = false;
resolve();
} else {
this.table.showValidateOtherProps = true;
reject();
}
})
}).catch(() => {});
},
validateTable: function() {
let _this = this;
return new Promise(function(resolve, reject) {
let errors = [];
_this.table.data.forEach((color, i) => {
let operators = color.operator;
let sizeCodes = color.sizeCode;
operators.forEach((o, j) => {
if (o.value) {
if (!sizeCodes[j].name) {
sizeCodes[j].showValidate = true;
sizeCodes[j].validate = true;
errors.push({row: i, index: j, message: '不能为空'});
} else {
sizeCodes[j].showValidate = false;
}
}
});
color.operator.forEach((op, i) => {
if (!op.value) {
return;
if (!color.goodsColorImage.value) {
color.goodsColorImage.showValidate = true;
color.goodsColorImage.validate = true;
errors.push({row: i, message: '商品封面不能为空', field: 'goodsColorImage.name'});
} else {
color.goodsColorImage.showValidate = false;
}
});
let goodsSize = {};
if (errors.length !== 0) {
_this.table.showValidateTable = false;
return resolve();
} else {
_this.table.showValidateTable = true;
return reject(errors);
}
goodsSize.sizeId = color.sizeId[i].id;
goodsSize.factoryCode = color.sizeCode[i].name;
goodsSizeList.push(goodsSize);
});
}).catch((err) => {
});
},
validateColor: function() {
let _this = this;
newColor.goodsSizeList = goodsSizeList;
return new Promise((resolve, reject) => {
if (_this.table.selectedColors.length === 0) {
this.table.showValidateColor = true;
return reject({message: '颜色不能为空'})
}
return newColor;
};
this.table.showValidateColor = false;
return resolve();
}).catch((err) => {
});
this.refreshTable();
this.product.sellerGoodsInfoStr = JSON.stringify(this.table.data.map(handleColor));
},
uploadSuccess: function(attach, files) {
this.refreshTable();
this.table.data[attach.index].goodsColorImage = files[0];
},
refreshTable() {
this.table.data = this.$refs.sellerGoods.rebuildData;
validateSize: function() {
return new Promise((resolve, reject) => {
if (this.table.selectedSizes.length === 0) {
this.table.showValidateSize = true;
return reject({message: '尺码不能为空'});
}
this.table.showValidateSize = false;
return resolve();
}).catch(() => {
});
},
uploadError: function(attach, err) {
validate: function() {
return this.validateOtherProps()
.then(this.validateColor)
.then(this.validateSize)
.then(this.validateTable)
.then(() => {
if (!this.showValidateColor
&& !this.showValidateSize
&& !this.showValidateOtherProp
&& !this.showValidateTable) {
return Promise.resolve();
} else {
return Promise.reject();
}
});
}
},
computed: {
... ... @@ -670,7 +816,20 @@ export default {
this.removeSize(color, removeSize[0]);
}
});
if (newVal.length === 0) {
this.table.showValidateSize = true;
} else {
this.table.showValidateSize = false;
}
},
'table.selectedColors': function(newVal) {
if (newVal.length === 0) {
this.table.showValidateColor = true;
} else {
this.table.showValidateColor = false;
}
}
},
components: {
'product-age': Age,
... ... @@ -735,6 +894,17 @@ export default {
.size-code {
@include row-span;
&-error {
border: 1px solid #f30;
}
&-tip {
position: absolute;
line-height: 1;
padding-top: 6px;
color: #f30;
}
}
.size-id {
... ... @@ -747,4 +917,45 @@ export default {
text-align: center;
}
.product-table-error {
border: 1px solid #f30;
}
.product-table-tip {
position: absolute;
line-height: 1;
padding-top: 6px;
color: #f30;
left: 70px;
}
.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>
... ...