Authored by 陈峰

Merge branch 'release/1.0' of http://git.yoho.cn/fe/yoho-shop-manage into release/1.0

... ... @@ -7,8 +7,11 @@ export default () => {
brandId: '',
brandName: '',
maxSortId: '',
maxSortName: '',
middleSortId: '',
middleSortName: '',
smallSortId: '',
smallSortName: '',
sortName: '',
productName: '',
phrase: '',
... ... @@ -18,7 +21,7 @@ export default () => {
gender: '',
seasons: '',
expectSaleTimeStr: '',
ageLevel: [],
ageLevel: '',
retailPrice: '',
salesPrice: '',
sellerGoodsInfoStr: ''
... ...
<template>
<Checkbox-group :value="handleValue" @input="updateValue" style="width: 350px;" >
<Checkbox label="1">
<span>成人</span>
</Checkbox>
<Checkbox label="2" >
<span>大童</span>
</Checkbox>
<Checkbox label="4">
<span>中童</span>
</Checkbox>
<Checkbox label="3">
<span>小童</span>
</Checkbox>
<Checkbox label="5">
<span>幼童 </span>
</Checkbox>
</Checkbox-group>
</template>
<script>
export default {
props: ['value'],
data() {
let _this = this;
return {
handleValue: _this.value.split('|')
};
},
methods: {
updateValue(newValue) {
let nValue = newValue.join('|');
this.$emit('input', nValue);
}
},
watch: {
value(newValue) {
this.handleValue = newValue.split('|');
}
}
};
</script>
<style>
</style>
... ...
<template>
<Radio-group :value="handleValue" @input="updateValue" style="width: 350px;">
<Radio label="1">
<span>男</span>
</Radio>
<Radio label="2">
<span>女</span>
</Radio>
<Radio label="3">
<span>通用</span>
</Radio>
</Radio-group>
</template>
<script>
export default {
props: ['value'],
data() {
let _this = this;
return {
handleValue: _this.value
};
},
methods: {
updateValue(newValue) {
let nValue = newValue;
this.$emit('input', nValue);
}
},
watch: {
value(newValue) {
this.handleValue = newValue;
}
},
};
</script>
<style>
</style>
... ...
<template>
<Select :value="handleValue" @input="updateValue" placeholder="请选择" style="width: 350px;">
<Option value="1">春季</Option>
<Option value="2">夏季</Option>
<Option value="3">秋季</Option>
<Option value="4">冬季</Option>
<Option value="5">春夏季</Option>
<Option value="6">秋冬季</Option>
</Select>
</template>
<script>
export default {
name: 'product-goods-season',
props: ['value'],
data() {
let _this = this;
return {
handleValue: _this.value
};
},
methods: {
updateValue(newValue) {
let nValue = newValue;
this.$emit('input', nValue);
}
},
watch: {
value(newValue) {
this.handleValue = newValue;
}
}
};
</script>
<style>
</style>
... ...
<template>
<Radio-group :value="handleValue" @input="updateValue" style="width: 350px;">
<Radio label="spring">
<span>春秋</span>
</Radio>
<Radio label="summer">
<span>夏</span>
</Radio>
<Radio label="winter">
<span>冬</span>
</Radio>
<Radio label="seasons">
<span>四季</span>
</Radio>
</Radio-group>
</template>
<script>
export default {
props: ['value'],
data() {
let _this = this;
return {
handleValue: _this.value
};
},
methods: {
updateValue(newValue) {
let nValue = newValue;
this.$emit('input', nValue);
}
},
watch: {
value(newValue) {
this.handleValue = newValue;
}
}
};
</script>
<style>
</style>
... ...
... ... @@ -82,16 +82,6 @@ export default {
2: [],
3: []
},
pickedSortId: {
1: '',
2: '',
3: ''
},
pickedLabel: {
1: '',
2: '',
3: ''
},
show: {
1: true,
2: false,
... ... @@ -136,7 +126,7 @@ export default {
selectSort1: function(value) {
this.level = 2;
this.sortId = this.product.maxSortId;
this.pickedLabel[1] = value.label;
this.product.maxSortName = value.label;
this.sorts[2] = [];
this.sorts[3] = [];
this.getSort();
... ... @@ -144,12 +134,12 @@ export default {
selectSort2: function(value) {
this.level = 3;
this.sortId = this.product.middleSortId;
this.pickedLabel[2] = value.label;
this.product.middleSortName = value.label;
this.getSort();
},
selectSort3: function(value) {
this.sortId = this.product.smallSortId;
this.pickedLabel[3] = value.label;
this.product.smallSortName = value.label;
},
selectBrand: function(value) {
this.product.brandName = value.label;
... ... @@ -179,9 +169,6 @@ export default {
this.level = 1;
this.sortId = '';
this.getSort();
},
'pickedLabel.3': function() {
this.product.sortName = `${this.pickedLabel[1]}/${this.pickedLabel[2]}/${this.pickedLabel[3]}`;
}
}
};
... ...
<template>
<div>
<Form :model="product" :label-width="70">
<Form ref="product" :model="product" :label-width="70" :rules="ruleValidate">
<Row>
<div class="create-group">
... ... @@ -12,13 +12,13 @@
<Row>
<Col>
<div class="create-item-title">商品基本信息</div>
<div class="create-item-title">商品基本信息</div>
</Col>
</Row>
<Row>
<Col span="8">
<Form-item label="品牌*">
<Form-item label="品牌">
<span>{{product.brandName}}</span>
</Form-item>
</Col>
... ... @@ -26,15 +26,15 @@
<Row>
<Col span="8">
<Form-item label="类目*">
<span>{{product.sortName}}</span>
<Form-item label="类目">
<span>{{sortName}}</span>
</Form-item>
</Col>
</Row>
<Row>
<Col span="8">
<Form-item label="商品名称*">
<Form-item label="商品名称" prop="productName">
<Input v-model="product.productName" placeholder="请输入..."/>
</Form-item>
</Col>
... ... @@ -42,7 +42,7 @@
<Row>
<Col span="8">
<Form-item label="商品卖点*">
<Form-item label="商品卖点" prop="phrase">
<Input v-model="product.phrase" type="textarea" :rows="4" placeholder="请输入..."/>
</Form-item>
</Col>
... ... @@ -50,7 +50,7 @@
<Row>
<Col span="8">
<Form-item label="商品编码*">
<Form-item label="商品编码" prop="factoryCode">
<Input v-model="product.factoryCode" placeholder="请输入..."/>
</Form-item>
</Col>
... ... @@ -58,7 +58,7 @@
<Row>
<Col span="8">
<Form-item label="货品年*">
<Form-item label="货品年" prop="goodsYears">
<Date-picker :value="product.goodsYears" @on-change="clickGoodsYear" type="year" placeholder="选择年" style="width: 200px">
</Date-picker>
</Form-item>
... ... @@ -67,77 +67,31 @@
<Row>
<Col span="8">
<Form-item label="货品季*">
<Select v-model="product.goodsSeason" placeholder="请选择">
<Option value="1">春季</Option>
<Option value="2">夏季</Option>
<Option value="3">秋季</Option>
<Option value="4">冬季</Option>
<Option value="5">春夏季</Option>
<Option value="6">秋冬季</Option>
</Select>
<Form-item label="货品季" prop="goodsSeason">
<product-goods-season v-model="product.goodsSeason"></product-goods-season>
</Form-item>
</Col>
</Row>
<Row>
<Col span="8">
<Form-item label="上市日期*">
<Form-item label="上市日期" prop="expectSaleTimeStr">
<Date-picker :value="product.expectSaleTimeStr" @on-change="clickSaleDate" type="date" placeholder="选择日期" style="width: 200px"></Date-picker>
</Form-item>
</Col>
</Row>
<Form-item label="性别*">
<Radio-group v-model="product.gender">
<Radio label="1">
<span>男</span>
</Radio>
<Radio label="2">
<span>女</span>
</Radio>
<Radio label="3">
<span>通用</span>
</Radio>
</Radio-group>
<Form-item label="性别" prop="gender">
<product-gender v-model="product.gender"></product-gender>
</Form-item>
<Form-item label="适销季*">
<Radio-group v-model="product.seasons">
<Radio label="spring">
<span>春秋</span>
</Radio>
<Radio label="summer">
<span>夏</span>
</Radio>
<Radio label="winter">
<span>冬</span>
</Radio>
<Radio label="seasons">
<span>四季</span>
</Radio>
</Radio-group>
<Form-item label="适销季" prop="seasons">
<product-season v-model="product.seasons"></product-season>
</Form-item>
<Form-item label="年龄层*">
<Checkbox-group v-model="ageLevel">
<Checkbox label="1">
<span>成人</span>
</Checkbox>
<Checkbox label="2">
<span>大童</span>
</Checkbox>
<Checkbox label="4">
<span>中童</span>
</Checkbox>
<Checkbox label="3">
<span>小童</span>
</Checkbox>
<Checkbox label="5">
<span>幼童 </span>
</Checkbox>
</Checkbox-group>
<Form-item label="年龄层" prop="ageLevel">
<product-age v-model="product.ageLevel"></product-age>
</Form-item>
<Row>
... ... @@ -149,11 +103,16 @@
</Row>
<Row>
<Form-item label="颜色*">
<span class='squre' v-for="color in colors" @click="clickColor(color)">
<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}"
:class="{ 'squre-color-selected': color.selected}">
:style="{ 'background-color': '#' + color.colorCode}">
</span>
<span class="squre-name">{{color.colorName}}</span>
</span>
... ... @@ -161,7 +120,7 @@
</Row>
<Row>
<Form-item label="尺寸*">
<Form-item label="尺寸">
<Checkbox-group v-model='table.selectedSizes'>
<Checkbox v-for="size in sizes" :key="size" :label="size.id" >
<span>{{size.sizeName}}</span>
... ... @@ -184,17 +143,17 @@
<Row>
<Col span="8">
<Form-item label="吊牌价*">
<Input v-model="product.retailPrice" placeholder="请输入..."/>
</Form-item>
<Form-item label="吊牌价" prop="retailPrice">
<Input v-model="product.retailPrice" :number="true" placeholder="请输入..."/>
</Form-item>
</Col>
</Row>
<Row>
<Col span="8">
<Form-item label="销售价*">
<Input v-model="product.salesPrice" placeholder="请输入..."/>
<Form-item label="销售价" prop="salesPrice">
<Input v-model="product.salesPrice" :number="true" placeholder="请输入..."/>
</Form-item>
</Col>
</Row>
... ... @@ -202,9 +161,11 @@
</Form>
<Row>
<Col span="6" offset="10" class="text-center">
<Button type="primary" @click="backStep">上一步</Button>
<Button type="primary" @click="nextStep">下一步</Button>
<Col>
<div style="text-align: center">
<Button type="primary" @click="backStep" size="large">上一步</Button>
<Button type="primary" @click="nextStep" size="large">下一步</Button>
</div>
</Col>
</Row>
</div>
... ... @@ -216,6 +177,11 @@ import api from '../api';
import service from '../service';
const _ = require('lodash');
import Age from './age';
import Season from './season';
import Gender from './gender';
import GoodsSeason from './goods-season';
const makeColor = () => {
return {
factoryCode: '',
... ... @@ -231,9 +197,47 @@ const makeColor = () => {
export default {
props: ['step', 'product'],
data() {
const validateEmpty = (rule, value, callback) => {
if (!value) {
return callback(new Error());
} else {
return callback()
}
};
const validateMustLessRetailPrice = (rule, value, callback) => {
if (!value) {
return callback(new Error('不能为空'));
}
if (!Number.isInteger(value)) {
callback(new Error('请输入数字值'));
} else {
if (value > +this.product.retailPrice) {
callback(new Error('必须小于等于吊牌价'));
} else {
callback();
}
}
};
const validateRetailPrice = (rule, value, callback) => {
if (!value) {
return callback(new Error('不能为空'));
}
if (!Number.isInteger(value)) {
callback(new Error('请输入数字值'));
} else {
callback();
}
};
return {
self: this,
colors: [],
selectedColors: [],
sizes: [],
table: {
columns: [
... ... @@ -249,7 +253,7 @@ export default {
}
},
{
title: '颜色展示名称*',
title: '颜色展示名称',
key: 'factoryGoodsName',
render(row, col, index) {
return `<div v-if="isExist(${index})">
... ... @@ -334,6 +338,41 @@ export default {
selectedColors: []
},
ageLevel: [],
ruleValidate: {
productName: [
{ required: true, message: '商品名不能为空', trigger: 'blur'}
],
phrase: [
{ required: true, message: '商品卖点不能为空', trigger: 'blur'}
],
factoryCode: [
{ required: true, message: '商品编码不能为空', trigger: 'blur'}
],
goodsYears: [
{ required: true, message: '货品年不能为空', trigger: 'change', type: 'string'}
],
goodsSeason: [
{ required: true, message: '货品季不能为空', trigger: 'change', validator: validateEmpty}
],
expectSaleTimeStr: [
{ required: true, message: '请选择日期', trigger: 'change', type: 'string'}
],
gender: [
{ required: true, message: '请选择性别', trigger: 'change'}
],
seasons: [
{ required: true, message: '不能为空', trigger: 'change'}
],
ageLevel: [
{ required: true, message: '不能为空', trigger: 'change'}
],
retailPrice: [
{ required: true, trigger: 'blur', validator: validateRetailPrice},
],
salesPrice: [
{ required: true, trigger: 'blur', validator: validateMustLessRetailPrice},
]
}
};
},
mounted: function() {
... ... @@ -341,6 +380,17 @@ export default {
this.getSize();
},
methods: {
validate: function() {
return new Promise((resolve, reject) => {
this.$refs['product'].validate((valid) => {
if (valid) {
resolve();
} else {
reject();
}
})
});
},
nextStep: function() {
this.$Loading.start();
this.submit().then((result) => {
... ... @@ -355,16 +405,21 @@ export default {
this.product.productSkn = result.data.productSkn;
this.product.goods = result.data.sellerGoodList.map(service.handleGoods);
this.step.value = 2;
this.$router.push({name: 'product.create.step3'});
this.goNext();
} else {
this.$Notice.error({
title: result.message,
desc: result.data.join('\n')
});
}
}).catch(() => {
this.$Loading.finish();
});
},
goNext: function() {
this.step.value = 2;
this.$router.push({name: 'product.create.step3'});
},
backStep: function() {
this.step.value = 0;
this.$router.push({name: 'product.create.step1'});
... ... @@ -378,7 +433,6 @@ export default {
},
getSize: function() {
return api.getSize(this.product.smallSortId).then((result) => {
// return api.getSize(129).then((result) => {
if (result.code === 200) {
this.sizes = result.data;
}
... ... @@ -520,13 +574,6 @@ export default {
this.table.data.splice(index, 1);
},
tail: function(array) {
if (array.length === 1 || array.length === 0) {
return [];
}
return array.slice(1);
},
findSize: function(sizeId) {
let index = this.sizes.findIndex((sizeObj) => {
return sizeObj.id === sizeId;
... ... @@ -538,17 +585,6 @@ export default {
return null;
},
findColor: function(color) {
let index = this.colors.findIndex((colorObj) => {
return color.colorId === colorObj.colorId;
});
if (index !== -1) {
return this.colors[index];
}
return null;
},
isExist: function(index) {
let row = this.table.data[index];
... ... @@ -559,8 +595,10 @@ export default {
return false;
},
submit: function() {
this.beforeSubmit();
return api.saveBaseProductInfo(this.product);
return this.validate().then(() => {
this.beforeSubmit();
return api.saveBaseProductInfo(this.product);
});
},
beforeSubmit: function() {
const handleColor = (color) => {
... ... @@ -607,6 +645,11 @@ export default {
uploadError: function(attach, err) {
}
},
computed: {
sortName: function() {
return this.product.maxSortName + '/' + this.product.middleSortName + '/' + this.product.smallSortName;
}
},
watch: {
'table.selectedSizes': function(newVal, oldVal) {
this.refreshTable();
... ... @@ -628,67 +671,80 @@ export default {
}
});
},
ageLevel: function() {
this.product.ageLevel = this.ageLevel.join('|');
}
},
components: {
'product-age': Age,
'product-season': Season,
'product-gender': Gender,
'product-goods-season': GoodsSeason,
}
};
</script>
<style lang="scss">
@mixin row-span{
min-height: 30px;
@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;
}
.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;
}
}
.squre {
display: inline-block;
height: 30px;
margin-right: 10px;
cursor: pointer;
}
.squre-color {
display: inline-block;
height: 30px;
width: 30px;
}
.squre-color-selected {
border: 2px solid black;
}
.squre-name {
display: inline-block;
height: 30px;
line-height: 30px;
vertical-align: top;
}
.size-code {
@include row-span;
}
.size-id {
@include row-span;
}
.size-operator {
@include row-span;
}
}
.squre {
display: inline-block;
height: 30px;
margin-right: 10px;
cursor: pointer;
border: 1px solid white;
}
.squre-selected {
border: 1px solid black;
}
.squre-disabled {
color: gray;
opacity: 0.5;
cursor: not-allowed;
border: 1px solid gray;
}
.squre-color {
display: inline-block;
height: 28px;
width: 28px;
}
.squre-name {
display: inline-block;
height: 30px;
line-height: 30px;
vertical-align: top;
}
.size-code {
@include row-span;
}
.size-id {
@include row-span;
text-align: center;
}
.size-operator {
@include row-span;
text-align: center;
}
</style>
... ...
... ... @@ -200,9 +200,11 @@
</Row>
<Row>
<Col span="6" offset="10" class="text-center">
<Button type="primary" @click="backStep">上一步</Button>
<Button type="primary" @click="nextStep">保存</Button>
<Col>
<div style="text-align: center">
<Button type="primary" @click="backStep" size="large">上一步</Button>
<Button type="primary" @click="nextStep" size="large">保存</Button>
</div>
</Col>
</Row>
</div>
... ... @@ -350,29 +352,30 @@ export default {
<style lang="scss">
.upload-item {
display: inline-block;
height: 200px;
width: 130px;
text-align: center;
}
.color-item-title {
text-align: center;
margin: 50px 0;
}
.upload-item-img {
display: inline-block;
height: 124px;
width: 124px;
border: 2px solid #e8e8e8;
box-sizing: border-box;
}
.upload-item-title {
display: inline-block;
margin-top: 15px;
}
.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-img {
display: inline-block;
height: 126px;
width: 124px;
border: 2px solid #e8e8e8;
box-sizing: border-box;
}
.upload-item-title {
display: inline-block;
margin-top: 15px;
}
</style>
... ...