|
|
|
@ -0,0 +1,799 @@
|
|
|
|
|
<template>
|
|
|
|
|
<div class="app-container">
|
|
|
|
|
<el-row>
|
|
|
|
|
<el-col :span="24">
|
|
|
|
|
<el-steps :active="step" finish-status="success">
|
|
|
|
|
<el-step title="基本信息"></el-step>
|
|
|
|
|
<el-step title="规格参数"></el-step>
|
|
|
|
|
<el-step title="销售属性"></el-step>
|
|
|
|
|
<el-step title="SKU信息"></el-step>
|
|
|
|
|
<el-step title="保存完成"></el-step>
|
|
|
|
|
</el-steps>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :span="24" v-show="step===0">
|
|
|
|
|
<el-card class="box-card" style="width:80%;margin:20px auto">
|
|
|
|
|
<el-form ref="spuBaseForm" :model="spu" label-width="120px" :rules="spuBaseInfoRules">
|
|
|
|
|
<el-form-item label="商品名称" prop="spuName">
|
|
|
|
|
<el-input v-model="spu.spuName"></el-input>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="商品描述" prop="spuDescription">
|
|
|
|
|
<el-input v-model="spu.spuDescription"></el-input>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="选择分类" prop="catalogId">
|
|
|
|
|
<category-cascader></category-cascader>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="选择品牌" prop="brandId">
|
|
|
|
|
<brand-select></brand-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="商品重量(Kg)" prop="weight">
|
|
|
|
|
<el-input-number v-model.number="spu.weight" :min="0" :precision="3" :step="0.1"></el-input-number>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="设置积分" prop="bounds">
|
|
|
|
|
<label>金币</label>
|
|
|
|
|
<el-input-number
|
|
|
|
|
style="width:130px"
|
|
|
|
|
placeholder="金币"
|
|
|
|
|
v-model="spu.bounds.buyBounds"
|
|
|
|
|
:min="0"
|
|
|
|
|
controls-position="right"
|
|
|
|
|
></el-input-number>
|
|
|
|
|
<label style="margin-left:15px">成长值</label>
|
|
|
|
|
<el-input-number
|
|
|
|
|
style="width:130px"
|
|
|
|
|
placeholder="成长值"
|
|
|
|
|
v-model="spu.bounds.growBounds"
|
|
|
|
|
:min="0"
|
|
|
|
|
controls-position="right"
|
|
|
|
|
>
|
|
|
|
|
<template slot="prepend">成长值</template>
|
|
|
|
|
</el-input-number>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="商品介绍" prop="decript">
|
|
|
|
|
<multi-upload v-model="spu.decript"></multi-upload>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
|
|
<el-form-item label="商品图集" prop="images">
|
|
|
|
|
<multi-upload v-model="spu.images"></multi-upload>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item>
|
|
|
|
|
<el-button type="success" @click="collectSpuBaseInfo">下一步:设置基本参数</el-button>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-form>
|
|
|
|
|
</el-card>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :span="24" v-show="step===1">
|
|
|
|
|
<el-card class="box-card" style="width:80%;margin:20px auto">
|
|
|
|
|
<el-tabs tab-position="left" style="width:98%">
|
|
|
|
|
<el-tab-pane
|
|
|
|
|
:label="group.attrGroupName"
|
|
|
|
|
v-for="(group,gidx) in dataResp.attrGroups"
|
|
|
|
|
:key="group.attrGroupId"
|
|
|
|
|
>
|
|
|
|
|
<!-- 遍历属性,每个tab-pane对应一个表单,每个属性是一个表单项 spu.baseAttrs[0] = [{attrId:xx,val:}]-->
|
|
|
|
|
<el-form ref="form" :model="spu">
|
|
|
|
|
<el-form-item
|
|
|
|
|
label-width="90px"
|
|
|
|
|
:label="attr.attrName"
|
|
|
|
|
v-for="(attr,aidx) in group.attrs"
|
|
|
|
|
:key="attr.attrId"
|
|
|
|
|
>
|
|
|
|
|
<el-input
|
|
|
|
|
v-model="dataResp.baseAttrs[gidx][aidx].attrId"
|
|
|
|
|
type="hidden"
|
|
|
|
|
v-show="false"
|
|
|
|
|
></el-input>
|
|
|
|
|
<el-select
|
|
|
|
|
v-model="dataResp.baseAttrs[gidx][aidx].attrValues"
|
|
|
|
|
:multiple="attr.valueType === 1"
|
|
|
|
|
filterable
|
|
|
|
|
allow-create
|
|
|
|
|
default-first-option
|
|
|
|
|
placeholder="请选择或输入值"
|
|
|
|
|
>
|
|
|
|
|
<el-option
|
|
|
|
|
v-for="(val,vidx) in attr.valueSelect.split(';')"
|
|
|
|
|
:key="vidx"
|
|
|
|
|
:label="val"
|
|
|
|
|
:value="val"
|
|
|
|
|
></el-option>
|
|
|
|
|
</el-select>
|
|
|
|
|
<el-checkbox
|
|
|
|
|
style="margin-left: 20px"
|
|
|
|
|
v-model="dataResp.baseAttrs[gidx][aidx].showDesc"
|
|
|
|
|
:true-label="1"
|
|
|
|
|
:false-label="0"
|
|
|
|
|
>快速展示
|
|
|
|
|
</el-checkbox>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-form>
|
|
|
|
|
</el-tab-pane>
|
|
|
|
|
</el-tabs>
|
|
|
|
|
<div style="margin-top: 20px">
|
|
|
|
|
<el-button type="primary" @click="step = 0">上一步</el-button>
|
|
|
|
|
<el-button type="success" @click="generateSaleAttrs">下一步:设置销售属性</el-button>
|
|
|
|
|
</div>
|
|
|
|
|
</el-card>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :span="24" v-show="step===2">
|
|
|
|
|
<el-card class="box-card" style="width:80%;margin:20px auto">
|
|
|
|
|
<el-card class="box-card">
|
|
|
|
|
<div slot="header" class="clearfix">
|
|
|
|
|
<span style="font-size: 15px;font-weight: 800">选择销售属性</span>
|
|
|
|
|
<el-form ref="saleform" :model="spu">
|
|
|
|
|
<el-form-item
|
|
|
|
|
label-width="90px"
|
|
|
|
|
:label="attr.attrName"
|
|
|
|
|
v-for="(attr,aidx) in dataResp.saleAttrs"
|
|
|
|
|
:key="attr.attrId"
|
|
|
|
|
>
|
|
|
|
|
<el-input
|
|
|
|
|
v-model="dataResp.tempSaleAttrs[aidx].attrId"
|
|
|
|
|
type="hidden"
|
|
|
|
|
v-show="false"
|
|
|
|
|
></el-input>
|
|
|
|
|
<el-checkbox-group v-model="dataResp.tempSaleAttrs[aidx].attrValues">
|
|
|
|
|
<el-checkbox
|
|
|
|
|
v-if="dataResp.saleAttrs[aidx].valueSelect !== ''"
|
|
|
|
|
:label="val"
|
|
|
|
|
v-for="val in dataResp.saleAttrs[aidx].valueSelect.split(';')"
|
|
|
|
|
:key="val"
|
|
|
|
|
></el-checkbox>
|
|
|
|
|
<div style="margin-left:20px;display:inline">
|
|
|
|
|
<el-button
|
|
|
|
|
v-show="!inputVisible[aidx].view"
|
|
|
|
|
class="button-new-tag"
|
|
|
|
|
size="mini"
|
|
|
|
|
@click="showInput(aidx)"
|
|
|
|
|
>+自定义
|
|
|
|
|
</el-button>
|
|
|
|
|
<el-input
|
|
|
|
|
v-show="inputVisible[aidx].view"
|
|
|
|
|
v-model="inputValue[aidx].val"
|
|
|
|
|
:ref="'saveTagInput'+aidx"
|
|
|
|
|
size="mini"
|
|
|
|
|
style="width:150px"
|
|
|
|
|
@keyup.enter.native="handleInputConfirm(aidx)"
|
|
|
|
|
@blur="handleInputConfirm(aidx)"
|
|
|
|
|
></el-input>
|
|
|
|
|
</div>
|
|
|
|
|
</el-checkbox-group>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-form>
|
|
|
|
|
</div>
|
|
|
|
|
<el-button type="primary" @click="step = 1">上一步</el-button>
|
|
|
|
|
<el-button type="success" @click="generateSkus">下一步:设置SKU信息</el-button>
|
|
|
|
|
</el-card>
|
|
|
|
|
</el-card>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :span="24" v-show="step===3">
|
|
|
|
|
<el-card class="box-card" style="width:80%;margin:20px auto">
|
|
|
|
|
<el-table :data="spu.skus" style="width: 100%">
|
|
|
|
|
<el-table-column label="属性组合" align="center">
|
|
|
|
|
<el-table-column align="center"
|
|
|
|
|
:label="item.attrName"
|
|
|
|
|
v-for="(item,index) in dataResp.tableAttrColumn"
|
|
|
|
|
:key="item.attrId"
|
|
|
|
|
>
|
|
|
|
|
<template slot-scope="scope">
|
|
|
|
|
<span style="margin-left: 10px">{{ scope.row.attr[index].attrValue }}</span>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="商品名称" prop="skuName" align="center">
|
|
|
|
|
<template slot-scope="scope">
|
|
|
|
|
<el-input v-model="scope.row.skuName"></el-input>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="标题" prop="skuTitle" align="center">
|
|
|
|
|
<template slot-scope="scope">
|
|
|
|
|
<el-input v-model="scope.row.skuTitle"></el-input>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="副标题" prop="skuSubtitle" align="center">
|
|
|
|
|
<template slot-scope="scope">
|
|
|
|
|
<el-input v-model="scope.row.skuSubtitle"></el-input>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="价格" prop="price" align="center">
|
|
|
|
|
<template slot-scope="scope">
|
|
|
|
|
<el-input v-model="scope.row.price"></el-input>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column type="expand">
|
|
|
|
|
<template slot-scope="scope">
|
|
|
|
|
<el-row style="margin-top:15px;margin-left: 20px">
|
|
|
|
|
<el-col :span="24">
|
|
|
|
|
<label style="display:block;float:left">选择图集</label>
|
|
|
|
|
<multi-upload
|
|
|
|
|
style="float:left;margin-left:10px;"
|
|
|
|
|
:showFile="false"
|
|
|
|
|
:listType="'text'"
|
|
|
|
|
v-model="uploadImages"
|
|
|
|
|
></multi-upload>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :span="24">
|
|
|
|
|
<el-divider></el-divider>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :span="24">
|
|
|
|
|
<el-card
|
|
|
|
|
style="width:170px;float:left;margin-left:15px;margin-top:15px;"
|
|
|
|
|
:body-style="{ padding: '0px' }"
|
|
|
|
|
v-for="(img,index) in spu.images"
|
|
|
|
|
:key="index"
|
|
|
|
|
>
|
|
|
|
|
<img :src="img" style="width:160px;height:120px" alt=""/>
|
|
|
|
|
<div style="padding: 14px;">
|
|
|
|
|
<el-row>
|
|
|
|
|
<el-col :span="8">
|
|
|
|
|
<el-checkbox
|
|
|
|
|
v-model="scope.row.images[index].imgUrl"
|
|
|
|
|
:true-label="img"
|
|
|
|
|
false-label
|
|
|
|
|
></el-checkbox>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :span="8">
|
|
|
|
|
<el-tag v-if="scope.row.images[index].defaultImg === 1">
|
|
|
|
|
<input
|
|
|
|
|
type="radio"
|
|
|
|
|
checked
|
|
|
|
|
:name="scope.row.skuName"
|
|
|
|
|
@change="checkDefaultImg(scope.row,index,img)"
|
|
|
|
|
/>设为默认
|
|
|
|
|
</el-tag>
|
|
|
|
|
<el-tag v-else>
|
|
|
|
|
<input
|
|
|
|
|
type="radio"
|
|
|
|
|
:name="scope.row.skuName"
|
|
|
|
|
@change="checkDefaultImg(scope.row,index,img)"
|
|
|
|
|
/>设为默认
|
|
|
|
|
</el-tag>
|
|
|
|
|
</el-col>
|
|
|
|
|
</el-row>
|
|
|
|
|
</div>
|
|
|
|
|
</el-card>
|
|
|
|
|
</el-col>
|
|
|
|
|
</el-row>
|
|
|
|
|
<!-- 折扣,满减,会员价 -->
|
|
|
|
|
<el-form :model="scope.row" style="margin-top:35px;margin-left: 20px">
|
|
|
|
|
<el-row>
|
|
|
|
|
<el-col :span="24">
|
|
|
|
|
<el-form-item label="设置折扣">
|
|
|
|
|
<label>满</label>
|
|
|
|
|
<el-input-number
|
|
|
|
|
style="width:120px"
|
|
|
|
|
:min="0"
|
|
|
|
|
controls-position="right"
|
|
|
|
|
v-model="scope.row.fullCount"
|
|
|
|
|
></el-input-number>
|
|
|
|
|
<label>件</label>
|
|
|
|
|
|
|
|
|
|
<label style="margin-left:15px;">打</label>
|
|
|
|
|
<el-input-number
|
|
|
|
|
style="width:120px"
|
|
|
|
|
v-model="scope.row.discount"
|
|
|
|
|
:precision="2"
|
|
|
|
|
:max="1"
|
|
|
|
|
:min="0"
|
|
|
|
|
:step="0.01"
|
|
|
|
|
controls-position="right"
|
|
|
|
|
></el-input-number>
|
|
|
|
|
<label>折</label>
|
|
|
|
|
<el-checkbox
|
|
|
|
|
style="margin-left: 15px"
|
|
|
|
|
v-model="scope.row.countStatus"
|
|
|
|
|
:true-label="1"
|
|
|
|
|
:false-label="0"
|
|
|
|
|
>可叠加优惠
|
|
|
|
|
</el-checkbox>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :span="24">
|
|
|
|
|
<el-form-item label="设置满减">
|
|
|
|
|
<label>满</label>
|
|
|
|
|
<el-input-number
|
|
|
|
|
style="width:120px"
|
|
|
|
|
v-model="scope.row.fullPrice"
|
|
|
|
|
:step="100"
|
|
|
|
|
:min="0"
|
|
|
|
|
controls-position="right"
|
|
|
|
|
></el-input-number>
|
|
|
|
|
<label>元</label>
|
|
|
|
|
<label style="margin-left:15px;">减</label>
|
|
|
|
|
<el-input-number
|
|
|
|
|
style="width:120px"
|
|
|
|
|
v-model="scope.row.reducePrice"
|
|
|
|
|
:step="10"
|
|
|
|
|
:min="0"
|
|
|
|
|
controls-position="right"
|
|
|
|
|
></el-input-number>
|
|
|
|
|
<label>元</label>
|
|
|
|
|
<el-checkbox
|
|
|
|
|
style="margin-left: 15px"
|
|
|
|
|
v-model="scope.row.priceStatus"
|
|
|
|
|
:true-label="1"
|
|
|
|
|
:false-label="0"
|
|
|
|
|
>可叠加优惠
|
|
|
|
|
</el-checkbox>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
|
|
|
|
|
<el-col :span="24">
|
|
|
|
|
<el-form-item label="设置会员价" v-if="scope.row.memberPrice.length>0">
|
|
|
|
|
<br/>
|
|
|
|
|
<!-- @change="handlePriceChange(scope,mpidx,$event)" -->
|
|
|
|
|
<el-form-item v-for="(mp,mpidx) in scope.row.memberPrice" :key="mp.id">
|
|
|
|
|
{{ mp.name }}
|
|
|
|
|
<el-input-number
|
|
|
|
|
style="width:120px"
|
|
|
|
|
v-model="scope.row.memberPrice[mpidx].price"
|
|
|
|
|
:precision="2"
|
|
|
|
|
:min="0"
|
|
|
|
|
controls-position="right"
|
|
|
|
|
></el-input-number>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
</el-row>
|
|
|
|
|
</el-form>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
</el-table>
|
|
|
|
|
<el-button type="primary" @click="step = 2">上一步</el-button>
|
|
|
|
|
<el-button type="success" @click="submitSkus" :loading="loadingButton">下一步:保存商品信息</el-button>
|
|
|
|
|
</el-card>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :span="24" v-show="step===4">
|
|
|
|
|
<el-card class="box-card" style="width:80%;margin:20px auto">
|
|
|
|
|
<el-result icon="success" title="保存成功" subTitle="">
|
|
|
|
|
<template slot="extra">
|
|
|
|
|
</template>
|
|
|
|
|
</el-result>
|
|
|
|
|
<el-button type="primary" @click="addAgian">继续添加</el-button>
|
|
|
|
|
</el-card>
|
|
|
|
|
</el-col>
|
|
|
|
|
</el-row>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
import CategoryCascader from '../../../components/mall/category-cascader'
|
|
|
|
|
import BrandSelect from "../../../components/mall/brand-select";
|
|
|
|
|
import MultiUpload from "@/components/OssUpload/multiUpload";
|
|
|
|
|
import {getMemberLevelList} from "@/api/mall/member/level";
|
|
|
|
|
import {getAttrGroupWithAttrs} from "@/api/mall/product/attr-group";
|
|
|
|
|
import {getBaseAttrList} from "@/api/mall/product/attr";
|
|
|
|
|
import {saveSpuInfo} from "@/api/mall/product/spu-info";
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
name:"SpuAdd",
|
|
|
|
|
components: {CategoryCascader, BrandSelect, MultiUpload},
|
|
|
|
|
props: {},
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
catPathSub: null,
|
|
|
|
|
brandIdSub: null,
|
|
|
|
|
uploadDialogVisible: false,
|
|
|
|
|
uploadImages: [],
|
|
|
|
|
step: 0,
|
|
|
|
|
|
|
|
|
|
loadingButton:false,
|
|
|
|
|
|
|
|
|
|
spu: {
|
|
|
|
|
//要提交的数据
|
|
|
|
|
spuName: "",
|
|
|
|
|
spuDescription: "",
|
|
|
|
|
catalogId: 0,
|
|
|
|
|
brandId: "",
|
|
|
|
|
weight: "",
|
|
|
|
|
publishStatus: 0,
|
|
|
|
|
decript: [], //商品详情
|
|
|
|
|
images: [], //商品图集,最后sku也可以新增
|
|
|
|
|
bounds: {
|
|
|
|
|
//积分
|
|
|
|
|
buyBounds: 0,
|
|
|
|
|
growBounds: 0
|
|
|
|
|
},
|
|
|
|
|
baseAttrs: [], //基本属性
|
|
|
|
|
skus: [] //所有sku信息
|
|
|
|
|
},
|
|
|
|
|
spuBaseInfoRules: {
|
|
|
|
|
spuName: [
|
|
|
|
|
{required: true, message: "请输入商品名字", trigger: "blur"}
|
|
|
|
|
],
|
|
|
|
|
spuDescription: [
|
|
|
|
|
{required: true, message: "请编写一个简单描述", trigger: "blur"}
|
|
|
|
|
],
|
|
|
|
|
catalogId: [
|
|
|
|
|
{required: true, message: "请选择一个分类", trigger: "blur"}
|
|
|
|
|
],
|
|
|
|
|
brandId: [
|
|
|
|
|
{required: true, message: "请选择一个品牌", trigger: "blur"}
|
|
|
|
|
],
|
|
|
|
|
decript: [
|
|
|
|
|
{required: true, message: "请上传商品详情图集", trigger: "blur"}
|
|
|
|
|
],
|
|
|
|
|
images: [
|
|
|
|
|
{required: true, message: "请上传商品图片集", trigger: "blur"}
|
|
|
|
|
],
|
|
|
|
|
weight: [
|
|
|
|
|
{
|
|
|
|
|
type: "number",
|
|
|
|
|
required: true,
|
|
|
|
|
message: "请填写正确的重量值",
|
|
|
|
|
trigger: "blur"
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
dataResp: {
|
|
|
|
|
//后台返回的所有数据
|
|
|
|
|
attrGroups: [],
|
|
|
|
|
baseAttrs: [],
|
|
|
|
|
saleAttrs: [],
|
|
|
|
|
tempSaleAttrs: [],
|
|
|
|
|
tableAttrColumn: [],
|
|
|
|
|
memberLevels: [],
|
|
|
|
|
steped: [false, false, false, false, false]
|
|
|
|
|
},
|
|
|
|
|
inputVisible: [],
|
|
|
|
|
inputValue: []
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
computed: {},
|
|
|
|
|
//监控data中的数据变化
|
|
|
|
|
watch: {
|
|
|
|
|
uploadImages(val) {
|
|
|
|
|
//扩展每个skus里面的imgs选项
|
|
|
|
|
let imgArr = Array.from(new Set(this.spu.images.concat(val)));
|
|
|
|
|
|
|
|
|
|
//{imgUrl:"",defaultImg:0} 由于concat每次迭代上次,有很多重复。所以我们必须得到上次+这次的总长
|
|
|
|
|
|
|
|
|
|
this.spu.skus.forEach((item, index) => {
|
|
|
|
|
let len = imgArr.length - this.spu.skus[index].images.length; //还差这么多
|
|
|
|
|
if (len > 0) {
|
|
|
|
|
let imgs = new Array(len);
|
|
|
|
|
imgs = imgs.fill({imgUrl: "", defaultImg: 0});
|
|
|
|
|
this.spu.skus[index].images = item.images.concat(imgs);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
this.spu.images = imgArr; //去重
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
//方法集合
|
|
|
|
|
methods: {
|
|
|
|
|
addAgian() {
|
|
|
|
|
this.step = 0;
|
|
|
|
|
this.resetSpuData();
|
|
|
|
|
},
|
|
|
|
|
resetSpuData() {
|
|
|
|
|
this.spu = {
|
|
|
|
|
spuName: "",
|
|
|
|
|
spuDescription: "",
|
|
|
|
|
catalogId: 0,
|
|
|
|
|
brandId: "",
|
|
|
|
|
weight: "",
|
|
|
|
|
publishStatus: 0,
|
|
|
|
|
decript: [],
|
|
|
|
|
images: [],
|
|
|
|
|
bounds: {
|
|
|
|
|
buyBounds: 0,
|
|
|
|
|
growBounds: 0
|
|
|
|
|
},
|
|
|
|
|
baseAttrs: [],
|
|
|
|
|
skus: []
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//清空子组件的值
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
handlePriceChange(scope, mpidx, e) {
|
|
|
|
|
this.spu.skus[scope.$index].memberPrice[mpidx].price = e;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
//获取会员等级
|
|
|
|
|
getMemberLevels() {
|
|
|
|
|
let params = {
|
|
|
|
|
page: 1,
|
|
|
|
|
limit: 500
|
|
|
|
|
}
|
|
|
|
|
getMemberLevelList(params).then(res => {
|
|
|
|
|
this.dataResp.memberLevels = res.page.list;
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
showInput(idx) {
|
|
|
|
|
console.log("``````", this.view);
|
|
|
|
|
this.inputVisible[idx].view = true;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
checkDefaultImg(row, index, img) {
|
|
|
|
|
console.log("默认图片", row, index);
|
|
|
|
|
//这个图片被选中了,
|
|
|
|
|
row.images[index].imgUrl = img; //默认选中
|
|
|
|
|
row.images[index].defaultImg = 1; //修改标志位;
|
|
|
|
|
//修改其他人的标志位
|
|
|
|
|
row.images.forEach((item, idx) => {
|
|
|
|
|
if (idx !== index) {
|
|
|
|
|
row.images[idx].defaultImg = 0;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
handleInputConfirm(idx) {
|
|
|
|
|
let inputValue = this.inputValue[idx].val;
|
|
|
|
|
if (inputValue) {
|
|
|
|
|
// this.dynamicTags.push(inputValue);
|
|
|
|
|
if (this.dataResp.saleAttrs[idx].valueSelect === "") {
|
|
|
|
|
this.dataResp.saleAttrs[idx].valueSelect = inputValue;
|
|
|
|
|
} else {
|
|
|
|
|
this.dataResp.saleAttrs[idx].valueSelect += ";" + inputValue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
this.inputVisible[idx].view = false;
|
|
|
|
|
this.inputValue[idx].val = "";
|
|
|
|
|
},
|
|
|
|
|
collectSpuBaseInfo() {
|
|
|
|
|
//spuBaseForm
|
|
|
|
|
this.$refs.spuBaseForm.validate(valid => {
|
|
|
|
|
if (valid) {
|
|
|
|
|
this.step = 1;
|
|
|
|
|
this.showBaseAttrs();
|
|
|
|
|
} else {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
generateSaleAttrs() {
|
|
|
|
|
//把页面绑定的所有attr处理到spu里面,这一步都要做
|
|
|
|
|
this.spu.baseAttrs = [];
|
|
|
|
|
this.dataResp.baseAttrs.forEach(item => {
|
|
|
|
|
item.forEach(attr => {
|
|
|
|
|
let {attrId, attrValues, showDesc} = attr;
|
|
|
|
|
//跳过没有录入值的属性
|
|
|
|
|
if (attrValues !== "") {
|
|
|
|
|
if (attrValues instanceof Array) {
|
|
|
|
|
//多个值用;隔开
|
|
|
|
|
attrValues = attrValues.join(";");
|
|
|
|
|
}
|
|
|
|
|
this.spu.baseAttrs.push({attrId, attrValues, showDesc});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
console.log("baseAttrs", this.spu.baseAttrs);
|
|
|
|
|
this.step = 2;
|
|
|
|
|
this.getShowSaleAttr();
|
|
|
|
|
},
|
|
|
|
|
generateSkus: function () {
|
|
|
|
|
this.step = 3;
|
|
|
|
|
|
|
|
|
|
//根据笛卡尔积运算进行生成sku
|
|
|
|
|
let selectValues = [];
|
|
|
|
|
this.dataResp.tableAttrColumn = [];
|
|
|
|
|
this.dataResp.tempSaleAttrs.forEach(item => {
|
|
|
|
|
if (item.attrValues.length > 0) {
|
|
|
|
|
selectValues.push(item.attrValues);
|
|
|
|
|
this.dataResp.tableAttrColumn.push(item);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
let descartes = this.descartes(selectValues);
|
|
|
|
|
//[["黑色","6GB","移动"],["黑色","6GB","联通"],["黑色","8GB","移动"],["黑色","8GB","联通"],
|
|
|
|
|
//["白色","6GB","移动"],["白色","6GB","联通"],["白色","8GB","移动"],["白色","8GB","联通"],
|
|
|
|
|
//["蓝色","6GB","移动"],["蓝色","6GB","联通"],["蓝色","8GB","移动"],["蓝色","8GB","联通"]]
|
|
|
|
|
console.log("生成的组合", JSON.stringify(descartes));
|
|
|
|
|
//有多少descartes就有多少sku
|
|
|
|
|
let skus = [];
|
|
|
|
|
|
|
|
|
|
descartes.forEach((descar, descaridx) => {
|
|
|
|
|
let attrArray = []; //sku属性组
|
|
|
|
|
descar.forEach((de, index) => {
|
|
|
|
|
//构造saleAttr信息
|
|
|
|
|
let saleAttrItem = {
|
|
|
|
|
attrId: this.dataResp.tableAttrColumn[index].attrId,
|
|
|
|
|
attrName: this.dataResp.tableAttrColumn[index].attrName,
|
|
|
|
|
attrValue: de
|
|
|
|
|
};
|
|
|
|
|
attrArray.push(saleAttrItem);
|
|
|
|
|
});
|
|
|
|
|
//先初始化几个images,后面的上传还要加
|
|
|
|
|
let imgs = [];
|
|
|
|
|
this.spu.images.forEach((img, idx) => {
|
|
|
|
|
imgs.push({imgUrl: "", defaultImg: 0});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
//会员价,也必须在循环里面生成,否则会导致数据绑定问题
|
|
|
|
|
let memberPrices = [];
|
|
|
|
|
if (this.dataResp.memberLevels.length > 0) {
|
|
|
|
|
for (let i = 0; i < this.dataResp.memberLevels.length; i++) {
|
|
|
|
|
if (this.dataResp.memberLevels[i].priviledgeMemberPrice === 1) {
|
|
|
|
|
memberPrices.push({
|
|
|
|
|
id: this.dataResp.memberLevels[i].id,
|
|
|
|
|
name: this.dataResp.memberLevels[i].name,
|
|
|
|
|
price: 0
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//;descaridx,判断如果之前有就用之前的值;
|
|
|
|
|
let res = this.hasAndReturnSku(this.spu.skus, descar);
|
|
|
|
|
if (res === null) {
|
|
|
|
|
skus.push({
|
|
|
|
|
attr: attrArray,
|
|
|
|
|
skuName: this.spu.spuName + " " + descar.join(" "),
|
|
|
|
|
price: 0,
|
|
|
|
|
skuTitle: this.spu.spuName + " " + descar.join(" "),
|
|
|
|
|
skuSubtitle: "",
|
|
|
|
|
images: imgs,
|
|
|
|
|
descar: descar,
|
|
|
|
|
fullCount: 0,
|
|
|
|
|
discount: 0,
|
|
|
|
|
countStatus: 0,
|
|
|
|
|
fullPrice: 0.0,
|
|
|
|
|
reducePrice: 0.0,
|
|
|
|
|
priceStatus: 0,
|
|
|
|
|
memberPrice: new Array().concat(memberPrices)
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
skus.push(res);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
this.spu.skus = skus;
|
|
|
|
|
console.log("结果!!!", this.spu.skus, this.dataResp.tableAttrColumn);
|
|
|
|
|
},
|
|
|
|
|
//判断如果包含之前的sku的descar组合,就返回这个sku的详细信息;
|
|
|
|
|
hasAndReturnSku(skus, descar) {
|
|
|
|
|
let res = null;
|
|
|
|
|
if (skus.length > 0) {
|
|
|
|
|
for (let i = 0; i < skus.length; i++) {
|
|
|
|
|
if (skus[i].descar.join(" ") === descar.join(" ")) {
|
|
|
|
|
res = skus[i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return res;
|
|
|
|
|
},
|
|
|
|
|
getShowSaleAttr() {
|
|
|
|
|
//获取当前分类可以使用的销售属性
|
|
|
|
|
if (!this.dataResp.steped[1] && this.spu.catalogId !== 0) {
|
|
|
|
|
let params = {
|
|
|
|
|
page: 1,
|
|
|
|
|
limit: 500
|
|
|
|
|
}
|
|
|
|
|
this.$modal.loading("请稍后...")
|
|
|
|
|
getBaseAttrList(params, this.spu.catalogId, "sale").then(res => {
|
|
|
|
|
this.dataResp.saleAttrs = res.page.list;
|
|
|
|
|
res.page.list.forEach(item => {
|
|
|
|
|
this.dataResp.tempSaleAttrs.push({
|
|
|
|
|
attrId: item.attrId,
|
|
|
|
|
attrValues: [],
|
|
|
|
|
attrName: item.attrName
|
|
|
|
|
});
|
|
|
|
|
this.inputVisible.push({view: false});
|
|
|
|
|
this.inputValue.push({val: ""});
|
|
|
|
|
});
|
|
|
|
|
this.dataResp.steped[1] = true;
|
|
|
|
|
this.$modal.closeLoading()
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
showBaseAttrs() {
|
|
|
|
|
if (!this.dataResp.steped[0]) {
|
|
|
|
|
this.$modal.loading("请稍后...")
|
|
|
|
|
getAttrGroupWithAttrs(this.spu.catalogId).then(res => {
|
|
|
|
|
//先对表单的baseAttrs进行初始化
|
|
|
|
|
res.data.forEach(item => {
|
|
|
|
|
let attrArray = [];
|
|
|
|
|
item.attrs.forEach(attr => {
|
|
|
|
|
attrArray.push({
|
|
|
|
|
attrId: attr.attrId,
|
|
|
|
|
attrValues: "",
|
|
|
|
|
showDesc: attr.showDesc
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
this.dataResp.baseAttrs.push(attrArray);
|
|
|
|
|
});
|
|
|
|
|
this.dataResp.steped[0] = 0;
|
|
|
|
|
this.dataResp.attrGroups = res.data;
|
|
|
|
|
this.$modal.closeLoading()
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
submitSkus() {
|
|
|
|
|
console.log("~~~~~", JSON.stringify(this.spu));
|
|
|
|
|
this.$confirm("将要提交商品数据,需要一小段时间,是否继续?", "提示", {
|
|
|
|
|
confirmButtonText: "确定",
|
|
|
|
|
cancelButtonText: "取消",
|
|
|
|
|
type: "warning"
|
|
|
|
|
})
|
|
|
|
|
.then(() => {
|
|
|
|
|
this.loadingButton=true
|
|
|
|
|
saveSpuInfo(this.spu).then(res =>{
|
|
|
|
|
this.step = 4;
|
|
|
|
|
this.$modal.notifySuccess("保存成功")
|
|
|
|
|
this.loadingButton=false
|
|
|
|
|
}).catch(err =>{
|
|
|
|
|
this.loadingButton=false
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//笛卡尔积运算
|
|
|
|
|
descartes(list) {
|
|
|
|
|
//parent上一级索引;count指针计数
|
|
|
|
|
var point = {};
|
|
|
|
|
var result = [];
|
|
|
|
|
var pIndex = null;
|
|
|
|
|
var tempCount = 0;
|
|
|
|
|
var temp = [];
|
|
|
|
|
|
|
|
|
|
//根据参数列生成指针对象
|
|
|
|
|
for (var index in list) {
|
|
|
|
|
if (typeof list[index] == "object") {
|
|
|
|
|
point[index] = {parent: pIndex, count: 0};
|
|
|
|
|
pIndex = index;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//单维度数据结构直接返回
|
|
|
|
|
if (pIndex == null) {
|
|
|
|
|
return list;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//动态生成笛卡尔积
|
|
|
|
|
while (true) {
|
|
|
|
|
for (var index in list) {
|
|
|
|
|
tempCount = point[index]["count"];
|
|
|
|
|
temp.push(list[index][tempCount]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//压入结果数组
|
|
|
|
|
result.push(temp);
|
|
|
|
|
temp = [];
|
|
|
|
|
|
|
|
|
|
//检查指针最大值问题
|
|
|
|
|
while (true) {
|
|
|
|
|
if (point[index]["count"] + 1 >= list[index].length) {
|
|
|
|
|
point[index]["count"] = 0;
|
|
|
|
|
pIndex = point[index]["parent"];
|
|
|
|
|
if (pIndex == null) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//赋值parent进行再次检查
|
|
|
|
|
index = pIndex;
|
|
|
|
|
} else {
|
|
|
|
|
point[index]["count"]++;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
created() {
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mounted() {
|
|
|
|
|
this.catPathSub = PubSub.subscribe("catPath", (msg, val) => {
|
|
|
|
|
this.spu.catalogId = val[val.length - 1];
|
|
|
|
|
});
|
|
|
|
|
this.brandIdSub = PubSub.subscribe("brandId", (msg, val) => {
|
|
|
|
|
this.spu.brandId = val;
|
|
|
|
|
});
|
|
|
|
|
this.getMemberLevels();
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
beforeDestroy() {
|
|
|
|
|
PubSub.unsubscribe(this.catPathSub);
|
|
|
|
|
PubSub.unsubscribe(this.brandIdSub);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
</script>
|
|
|
|
|
<style scoped>
|
|
|
|
|
</style>
|