fixed 优化商品sku(未完成,计划端午完成)
This commit is contained in:
parent
3170e8b9dd
commit
515b6afe62
@ -156,69 +156,7 @@
|
|||||||
<el-row v-if="formData.goodsSpecType == 2">
|
<el-row v-if="formData.goodsSpecType == 2">
|
||||||
<el-col :lg="24">
|
<el-col :lg="24">
|
||||||
|
|
||||||
<el-form-item :label-width="labelWidth" label="商品规格">
|
<MultiSpec></MultiSpec>
|
||||||
<div style="display: block;width: 100%;">
|
|
||||||
<!-- <el-input-number v-model.number="formData.goodsSpec" controls-position="right" :min="0.01"
|
|
||||||
:precision="2" /> -->
|
|
||||||
<div class="input-intro">最多添加3个商品规格组,生成的SKU数量不能超出50个</div>
|
|
||||||
|
|
||||||
<!-- 规格样式 -->
|
|
||||||
<div class="sepc-big-box" v-for="(item, index) in goodsSpecList">
|
|
||||||
<div class="sepc-title-box">
|
|
||||||
<el-input v-model="item.specName" @change="handleChangeSepc(item, index)" class="spec-input"
|
|
||||||
placeholder="规格组名称" clearable />
|
|
||||||
<el-link type="primary" @click="handleDelSpec(item)">删除规格组</el-link>
|
|
||||||
</div>
|
|
||||||
<div class="spec-value-box">
|
|
||||||
<div class="spec-value-input-big-box">
|
|
||||||
<div class="spec-value-input-box" v-for="specValue in item.props">
|
|
||||||
<div class="spec-value-input-del" @click="handleDelSpecValue(item,specValue)"><el-icon>
|
|
||||||
<Close />
|
|
||||||
</el-icon></div>
|
|
||||||
<el-input v-model="specValue.specValueName" @change="handleChangeSepcValue(item,specValue)"
|
|
||||||
class="spec-value-input" placeholder="规格值名称" clearable />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<el-link type="primary" v-if="isAddSpecValueMax" @click="handleAddSpecValue(item)">添加规格值</el-link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-button v-if="isAddSpecMax" class="mt-5" @click="handleAddSpec">
|
|
||||||
<el-icon class="avatar-uploader-icon">
|
|
||||||
<plus />
|
|
||||||
</el-icon>
|
|
||||||
添加规格组
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Sku列表 -->
|
|
||||||
<el-form-item :label-width="labelWidth" label="Sku列表">
|
|
||||||
|
|
||||||
<!-- sku列表 -->
|
|
||||||
<el-table :data="skuList" border style="width: 100%" :span-method="objectSpanMethod">
|
|
||||||
<!-- 动态列 -->
|
|
||||||
<el-table-column v-for="column in skuColumns" :prop="column.prop" :label="column.label"
|
|
||||||
:key="column.key" :width="column.width">
|
|
||||||
</el-table-column>
|
|
||||||
|
|
||||||
<!-- <el-table-column prop="goodsSkuPrice" label="预览图">
|
|
||||||
<template #default="scope">
|
|
||||||
<UploadImage ref="uploadRef" v-model="scope.row.goodsSkuImg" :data=imgData :limit="1"
|
|
||||||
:fileSize="5" :drag="true" :isShowTip="false" />
|
|
||||||
</template>
|
|
||||||
</el-table-column> -->
|
|
||||||
|
|
||||||
<el-table-column prop="goodsSkuPrice" label="商品价格">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-input-number v-model.number="scope.row.goodsSkuPrice" controls-position="right" :min="0"
|
|
||||||
:precision="2" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
|
|
||||||
</el-table>
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
@ -388,6 +326,7 @@ import { shopGoodsCategoryTreeList } from '@/api/business/GoodsManager/ShopGoods
|
|||||||
import { deliveryList } from '@/api/business/LogisticsManage/Deliverys/delivery.js'
|
import { deliveryList } from '@/api/business/LogisticsManage/Deliverys/delivery.js'
|
||||||
import useUserStore from '@/store/modules/user'
|
import useUserStore from '@/store/modules/user'
|
||||||
import ChooseShopDialog from './ChooseShopDialog.vue';
|
import ChooseShopDialog from './ChooseShopDialog.vue';
|
||||||
|
import MultiSpec from './MultiSpec/MultiSpec.vue';
|
||||||
|
|
||||||
|
|
||||||
// 打开弹窗时回调
|
// 打开弹窗时回调
|
||||||
|
@ -1,286 +0,0 @@
|
|||||||
<template>
|
|
||||||
<el-form-item :label-width="labelWidth" label="商品规格">
|
|
||||||
<div style="display: block;width: 100%;">
|
|
||||||
<div class="input-intro">最多添加3个商品规格组,生成的SKU数量不能超出50个</div>
|
|
||||||
|
|
||||||
<!-- 规格样式 -->
|
|
||||||
<div class="sepc-big-box" v-for="(item, index) in multiSpecData.specList">
|
|
||||||
<div class="sepc-title-box">
|
|
||||||
<el-input v-model="item.spec_name" @change="onChangeSpecGroupIpt" class="spec-input" placeholder="规格组名称"
|
|
||||||
clearable />
|
|
||||||
<el-link type="primary" @click="handleDeleteSpecGroup(index)">删除规格组</el-link>
|
|
||||||
</div>
|
|
||||||
<div class="spec-value-box">
|
|
||||||
<div class="spec-value-input-big-box">
|
|
||||||
<div class="spec-value-input-box" v-for="(itm, idx) in item.valueList" :key="idx">
|
|
||||||
<div class="spec-value-input-del" @click="handleDeleteSpecValue(index, idx)"><el-icon>
|
|
||||||
<Close />
|
|
||||||
</el-icon></div>
|
|
||||||
<el-input v-model="specValue.specValueName" @change="onChangeSpecValueIpt"
|
|
||||||
class="spec-value-input" placeholder="规格值名称" clearable />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<el-link type="primary" v-if="!isSpecLocked" @click="handleAddSpecValue(index)">添加规格值</el-link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-button v-if="!isSpecLocked && multiSpecData.specList.length < 3" class="mt-5" @click="handleAddSpecGroup">
|
|
||||||
<el-icon class="avatar-uploader-icon">
|
|
||||||
<plus />
|
|
||||||
</el-icon>
|
|
||||||
添加规格组
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Sku列表 -->
|
|
||||||
<el-form-item :label-width="labelWidth" label="Sku列表">
|
|
||||||
|
|
||||||
<!-- sku列表 -->
|
|
||||||
<el-table :data="skuList" border style="width: 100%" :span-method="objectSpanMethod">
|
|
||||||
<!-- 动态列 -->
|
|
||||||
<el-table-column v-for="column in skuColumns" :prop="column.prop" :label="column.label" :key="column.key"
|
|
||||||
:width="column.width">
|
|
||||||
</el-table-column>
|
|
||||||
|
|
||||||
<!-- <el-table-column prop="goodsSkuPrice" label="预览图">
|
|
||||||
<template #default="scope">
|
|
||||||
<UploadImage ref="uploadRef" v-model="scope.row.goodsSkuImg" :data=imgData :limit="1"
|
|
||||||
:fileSize="5" :drag="true" :isShowTip="false" />
|
|
||||||
</template>
|
|
||||||
</el-table-column> -->
|
|
||||||
|
|
||||||
<el-table-column prop="goodsSkuPrice" label="商品价格">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-input-number v-model.number="scope.row.goodsSkuPrice" controls-position="right" :min="0" :precision="2" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
|
|
||||||
</el-table>
|
|
||||||
</el-form-item>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import PropTypes from 'ant-design-vue/es/_util/vue-types'
|
|
||||||
import MultiSpecModel from '@/common/model/goods/MultiSpec'
|
|
||||||
import { SelectImage } from '@/components'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
SelectImage
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
// 默认的规格列表
|
|
||||||
defaultSpecList: PropTypes.array.def([]),
|
|
||||||
// 默认的SKU列表
|
|
||||||
defaultSkuList: PropTypes.array.def([]),
|
|
||||||
// 商品规格是否锁定(锁定状态下不允许编辑规格)
|
|
||||||
isSpecLocked: PropTypes.bool.def(false)
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
// 标签布局属性
|
|
||||||
labelCol: { span: 3 },
|
|
||||||
// 输入框布局属性
|
|
||||||
wrapperCol: { span: 21 },
|
|
||||||
// 商品多规格模型
|
|
||||||
MultiSpecModel: new MultiSpecModel(),
|
|
||||||
// MultiSpecModel: Object,
|
|
||||||
multiSpecData: {
|
|
||||||
// 规格列表
|
|
||||||
specList: [],
|
|
||||||
// SKU列表
|
|
||||||
skuList: []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
defaultSpecList(val) {
|
|
||||||
if (val.length && this.MultiSpecModel.isEmpty()) {
|
|
||||||
this.getData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 初始化数据
|
|
||||||
created() {
|
|
||||||
// 获取规格及SKU信息
|
|
||||||
this.getData()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
|
|
||||||
// 获取规格及SKU信息(展示)
|
|
||||||
getData() {
|
|
||||||
const { defaultSpecList, defaultSkuList } = this
|
|
||||||
this.multiSpecData = this.MultiSpecModel.getData(defaultSpecList, defaultSkuList)
|
|
||||||
},
|
|
||||||
|
|
||||||
// 获取规格及SKU信息(表单提交)
|
|
||||||
getFromSpecData() {
|
|
||||||
return this.MultiSpecModel.getFromSpecData()
|
|
||||||
},
|
|
||||||
|
|
||||||
// 添加规格组
|
|
||||||
handleAddSpecGroup() {
|
|
||||||
if (this.checkSkuMaxNum()) {
|
|
||||||
this.MultiSpecModel.handleAddSpecGroup()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// 删除规格组
|
|
||||||
handleDeleteSpecGroup(groupIndex) {
|
|
||||||
const app = this
|
|
||||||
const modal = this.$confirm({
|
|
||||||
title: '您确定要删除该规格组吗?',
|
|
||||||
content: '删除后不可恢复',
|
|
||||||
onOk() {
|
|
||||||
// 删除元素
|
|
||||||
app.MultiSpecModel.handleDeleteSpecGroup(groupIndex)
|
|
||||||
// 关闭对话框
|
|
||||||
modal.destroy()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
// 新增规格值
|
|
||||||
handleAddSpecValue(groupIndex) {
|
|
||||||
if (this.checkSkuMaxNum()) {
|
|
||||||
this.MultiSpecModel.handleAddSpecValue(groupIndex)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// 删除规格值
|
|
||||||
handleDeleteSpecValue(groupIndex, valueIndex) {
|
|
||||||
const app = this
|
|
||||||
const modal = this.$confirm({
|
|
||||||
title: '您确定要删除该规格值吗?',
|
|
||||||
content: '删除后不可恢复',
|
|
||||||
onOk() {
|
|
||||||
// 删除元素
|
|
||||||
app.MultiSpecModel.handleDeleteSpecValue(groupIndex, valueIndex)
|
|
||||||
// 关闭对话框
|
|
||||||
modal.destroy()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
// 规格组输入框change事件
|
|
||||||
onChangeSpecGroupIpt() {
|
|
||||||
// 更新skuList
|
|
||||||
this.MultiSpecModel.onUpdate(true)
|
|
||||||
},
|
|
||||||
|
|
||||||
// 规格值输入框change事件
|
|
||||||
onChangeSpecValueIpt(event, itm) {
|
|
||||||
// 更新skuList
|
|
||||||
this.MultiSpecModel.onUpdate(true)
|
|
||||||
},
|
|
||||||
|
|
||||||
// 验证最大sku数量
|
|
||||||
checkSkuMaxNum() {
|
|
||||||
const skuList = this.multiSpecData.skuList
|
|
||||||
if (skuList.length >= 50) {
|
|
||||||
this.$message.error(`生成的sku列表数量不能大于50个,当前数量:${skuList.length}个`, 2.5)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
|
|
||||||
// 批量设置sku事件
|
|
||||||
handleSkuBatch() {
|
|
||||||
this.MultiSpecModel.handleSkuBatch()
|
|
||||||
},
|
|
||||||
|
|
||||||
// 验证多规格表单
|
|
||||||
verifyForm() {
|
|
||||||
if (!this.MultiSpecModel.verifyForm()) {
|
|
||||||
this.$message.error(this.MultiSpecModel.getError(), 2)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
|
|
||||||
<style lang="less" scoped>
|
|
||||||
.divider-title {
|
|
||||||
font-size: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-intro {
|
|
||||||
color: #8c8c8c;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-divider {
|
|
||||||
margin: 50px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sepc-big-box {
|
|
||||||
width: 100%;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sepc-title-box {
|
|
||||||
width: 100%;
|
|
||||||
padding: 10px;
|
|
||||||
background-color: #f4f4f5;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
.spec-value-box {
|
|
||||||
width: 100%;
|
|
||||||
padding: 20px 20px 20px 40px;
|
|
||||||
background-color: #fbfbfb;
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.spec-value-input-big-box {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.spec-value-input-box {
|
|
||||||
width: 250px;
|
|
||||||
position: relative;
|
|
||||||
margin-right: 30px;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.spec-value-input-del {
|
|
||||||
position: absolute;
|
|
||||||
top: -5px;
|
|
||||||
right: -5px;
|
|
||||||
z-index: 99;
|
|
||||||
width: 18px;
|
|
||||||
height: 18px;
|
|
||||||
background-color: grey;
|
|
||||||
color: white;
|
|
||||||
border-radius: 50%;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
font-size: 10px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.spec-input {
|
|
||||||
width: 250px;
|
|
||||||
margin-right: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.mt-5 {
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-input-number {
|
|
||||||
width: 140px;
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,446 +0,0 @@
|
|||||||
|
|
||||||
import _ from 'lodash'
|
|
||||||
import { debounce, isEmpty } from '@/utils/util'
|
|
||||||
|
|
||||||
// 默认的sku字段属性
|
|
||||||
const defaultColumns = [
|
|
||||||
{
|
|
||||||
title: '预览图',
|
|
||||||
dataIndex: 'image',
|
|
||||||
width: 90,
|
|
||||||
scopedSlots: { customRender: 'image' }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '商品价格',
|
|
||||||
dataIndex: 'goods_price',
|
|
||||||
width: 120,
|
|
||||||
scopedSlots: { customRender: 'goods_price' }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '划线价格',
|
|
||||||
dataIndex: 'line_price',
|
|
||||||
width: 120,
|
|
||||||
scopedSlots: { customRender: 'line_price' }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '库存数量',
|
|
||||||
dataIndex: 'stock_num',
|
|
||||||
width: 120,
|
|
||||||
scopedSlots: { customRender: 'stock_num' }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '商品重量 (KG)',
|
|
||||||
dataIndex: 'goods_weight',
|
|
||||||
width: 120,
|
|
||||||
scopedSlots: { customRender: 'goods_weight' }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'SKU编码',
|
|
||||||
dataIndex: 'goods_sku_no',
|
|
||||||
width: 140,
|
|
||||||
scopedSlots: { customRender: 'goods_sku_no' }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
// 默认的sku记录值
|
|
||||||
const defaultSkuItemData = {
|
|
||||||
image_id: 0,
|
|
||||||
image: {},
|
|
||||||
// imageList: [],
|
|
||||||
goods_price: '',
|
|
||||||
line_price: '',
|
|
||||||
stock_num: '',
|
|
||||||
goods_weight: '',
|
|
||||||
goods_sku_no: ''
|
|
||||||
}
|
|
||||||
|
|
||||||
// const demoSpecList = [
|
|
||||||
// {
|
|
||||||
// key: 0,
|
|
||||||
// spec_name: '颜色',
|
|
||||||
// valueList: [
|
|
||||||
// { key: 0, groupKey: 0, /* spec_value_id: 10001, */ spec_value: '红色' },
|
|
||||||
// { key: 1, groupKey: 0, spec_value: '白色' },
|
|
||||||
// { key: 2, groupKey: 0, spec_value: '蓝色' }
|
|
||||||
// ]
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// key: 1,
|
|
||||||
// spec_name: '尺码',
|
|
||||||
// valueList: [
|
|
||||||
// { key: 0, groupKey: 1, spec_value: 'XXL' },
|
|
||||||
// { key: 1, groupKey: 1, spec_value: 'XL' }
|
|
||||||
// ]
|
|
||||||
// }
|
|
||||||
// ]
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 商品 model类
|
|
||||||
* GoodsModel
|
|
||||||
*/
|
|
||||||
export default class MultiSpec {
|
|
||||||
// 商品多规格数据
|
|
||||||
multiSpecData = {}
|
|
||||||
|
|
||||||
// 错误信息
|
|
||||||
error = '';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构造方法
|
|
||||||
* @param {array} specList 规格列表
|
|
||||||
* @param {array} skuList SKU列表
|
|
||||||
*/
|
|
||||||
constructor () {
|
|
||||||
this.multiSpecData = {
|
|
||||||
// 规格列表
|
|
||||||
specList: [],
|
|
||||||
// SKU列表
|
|
||||||
skuList: [],
|
|
||||||
// SKU字段
|
|
||||||
skuColumns: _.cloneDeep(defaultColumns),
|
|
||||||
// 批量设置sku
|
|
||||||
skuBatchForm: _.cloneDeep(defaultSkuItemData)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 生成并获取多规格数据
|
|
||||||
getData (specList = [], skuList = []) {
|
|
||||||
if (specList.length) {
|
|
||||||
this.multiSpecData.specList = _.cloneDeep(specList)
|
|
||||||
this.multiSpecData.skuList = _.cloneDeep(skuList)
|
|
||||||
}
|
|
||||||
// 整理所有的规格组
|
|
||||||
const specGroupArr = this.specGroupArr()
|
|
||||||
// sku记录的规格属性集(生成笛卡尔积)
|
|
||||||
const cartesianList = cartesianProductOf(specGroupArr)
|
|
||||||
// 合并单元格
|
|
||||||
const rowSpanArr = this.rowSpanArr(specGroupArr, cartesianList)
|
|
||||||
// 生成sku字段名
|
|
||||||
this.buildSkuColumns(rowSpanArr)
|
|
||||||
// 生成sku列表数据
|
|
||||||
this.buildSkuList(cartesianList)
|
|
||||||
// 返回多规格数据
|
|
||||||
return this.multiSpecData
|
|
||||||
}
|
|
||||||
|
|
||||||
// 数据是否为空
|
|
||||||
isEmpty () {
|
|
||||||
return this.multiSpecData.specList.length === 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// 返回错误信息
|
|
||||||
getError () {
|
|
||||||
return this.error
|
|
||||||
}
|
|
||||||
|
|
||||||
// 整理所有的规格
|
|
||||||
specGroupArr () {
|
|
||||||
const specGroupArr = []
|
|
||||||
this.multiSpecData.specList.forEach(specGroup => {
|
|
||||||
const itemArr = []
|
|
||||||
specGroup.valueList.forEach(value => {
|
|
||||||
itemArr.push(value)
|
|
||||||
})
|
|
||||||
specGroupArr.push(itemArr)
|
|
||||||
})
|
|
||||||
return specGroupArr
|
|
||||||
}
|
|
||||||
|
|
||||||
// 合并单元格
|
|
||||||
rowSpanArr (specGroupArr, cartesianList) {
|
|
||||||
const rowSpanArr = []
|
|
||||||
var rowSpan = cartesianList.length
|
|
||||||
for (let i = 0; i < specGroupArr.length; i++) {
|
|
||||||
rowSpanArr[i] = parseInt(rowSpan / specGroupArr[i].length)
|
|
||||||
rowSpan = rowSpanArr[i]
|
|
||||||
}
|
|
||||||
return rowSpanArr
|
|
||||||
}
|
|
||||||
|
|
||||||
// 生成skuList
|
|
||||||
buildSkuList (cartesianList) {
|
|
||||||
// 生成新的skuList
|
|
||||||
const newSkuList = []
|
|
||||||
for (let i = 0; i < cartesianList.length; i++) {
|
|
||||||
const newSkuItem = {
|
|
||||||
...defaultSkuItemData,
|
|
||||||
key: i,
|
|
||||||
// skuKey用于合并旧记录
|
|
||||||
skuKey: cartesianList[i].map(item => item.key).join('_'),
|
|
||||||
// skuKeys用于传参给后端
|
|
||||||
skuKeys: cartesianList[i].map(item => {
|
|
||||||
return {
|
|
||||||
groupKey: item.groupKey,
|
|
||||||
valueKey: item.key
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
cartesianList[i].forEach((val, idx) => {
|
|
||||||
newSkuItem[`spec_value_${idx}`] = val.spec_value
|
|
||||||
})
|
|
||||||
newSkuList.push(newSkuItem)
|
|
||||||
}
|
|
||||||
// 兼容旧的sku数据
|
|
||||||
this.multiSpecData.skuList = this.oldSkuList(newSkuList)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 合并已存在的sku数据
|
|
||||||
oldSkuList (newSkuList) {
|
|
||||||
// const oldSkuList = _.cloneDeep(this.multiSpecData.skuList)
|
|
||||||
const oldSkuList = this.multiSpecData.skuList.concat()
|
|
||||||
if (!oldSkuList.length || !newSkuList.length) {
|
|
||||||
return newSkuList
|
|
||||||
}
|
|
||||||
for (const index in newSkuList) {
|
|
||||||
// 查找符合的旧记录
|
|
||||||
let oldSkuItem = {}
|
|
||||||
if (oldSkuList.length === newSkuList.length) {
|
|
||||||
oldSkuItem = _.cloneDeep(oldSkuList[index])
|
|
||||||
} else {
|
|
||||||
oldSkuItem = oldSkuList.find(item => {
|
|
||||||
return item.skuKey === newSkuList[index].skuKey
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 写入新纪录
|
|
||||||
if (oldSkuItem) {
|
|
||||||
newSkuList[index] = {
|
|
||||||
...newSkuList[index],
|
|
||||||
..._.pick(oldSkuItem, Object.keys(defaultSkuItemData))
|
|
||||||
}
|
|
||||||
// console.log(newSkuList[index].image)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return newSkuList
|
|
||||||
}
|
|
||||||
|
|
||||||
// 生成sku表格字段名
|
|
||||||
buildSkuColumns (rowSpanArr) {
|
|
||||||
const specList = this.multiSpecData.specList
|
|
||||||
const newColumns = defaultColumns.concat()
|
|
||||||
// 渲染字段的rowSpan
|
|
||||||
const customRender = (specIndex, value, row, index) => {
|
|
||||||
const obj = {
|
|
||||||
children: value,
|
|
||||||
attrs: {}
|
|
||||||
}
|
|
||||||
const rowSpan = rowSpanArr[specIndex - 1]
|
|
||||||
if ((index % rowSpan) === 0) {
|
|
||||||
obj.attrs.rowSpan = rowSpan
|
|
||||||
} else {
|
|
||||||
obj.attrs.rowSpan = 0
|
|
||||||
}
|
|
||||||
return obj
|
|
||||||
}
|
|
||||||
// 遍历规格组整理字段
|
|
||||||
for (let specIndex = specList.length; specIndex > 0; specIndex--) {
|
|
||||||
const specGroupItem = specList[specIndex - 1]
|
|
||||||
newColumns.unshift({
|
|
||||||
title: specGroupItem.spec_name,
|
|
||||||
dataIndex: `spec_value_${specIndex - 1}`,
|
|
||||||
customRender: (value, row, index) => customRender(specIndex, value, row, index)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
this.multiSpecData.skuColumns = newColumns
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加规格组
|
|
||||||
handleAddSpecGroup () {
|
|
||||||
const specList = this.multiSpecData.specList
|
|
||||||
specList.push({
|
|
||||||
key: specList.length || 0,
|
|
||||||
spec_name: '',
|
|
||||||
valueList: []
|
|
||||||
})
|
|
||||||
// 默认规格值
|
|
||||||
const groupIndex = specList.length - 1
|
|
||||||
this.handleAddSpecValue(groupIndex)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加规格值
|
|
||||||
handleAddSpecValue (groupIndex) {
|
|
||||||
const specGroupItem = this.multiSpecData.specList[groupIndex]
|
|
||||||
const specValueList = specGroupItem.valueList
|
|
||||||
specValueList.push({
|
|
||||||
key: specValueList.length || 0,
|
|
||||||
groupKey: specGroupItem.key,
|
|
||||||
spec_value: ''
|
|
||||||
})
|
|
||||||
// 刷新规格值的key
|
|
||||||
this.onRefreshSpecValueKey(groupIndex)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除规格组
|
|
||||||
handleDeleteSpecGroup (groupIndex) {
|
|
||||||
this.multiSpecData.specList.splice(groupIndex, 1)
|
|
||||||
this.onUpdate(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除规格值
|
|
||||||
handleDeleteSpecValue (groupIndex, valueIndex) {
|
|
||||||
// 将规格值移出
|
|
||||||
this.multiSpecData.specList[groupIndex].valueList.splice(valueIndex, 1)
|
|
||||||
// 刷新规格值的key
|
|
||||||
this.onRefreshSpecValueKey(groupIndex)
|
|
||||||
this.onUpdate(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 刷新规格值的key
|
|
||||||
onRefreshSpecValueKey (groupIndex) {
|
|
||||||
const specGroupItem = this.multiSpecData.specList[groupIndex]
|
|
||||||
const specValueList = specGroupItem.valueList
|
|
||||||
specValueList.forEach((item, index) => {
|
|
||||||
specValueList[index].key = index
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 批量设置sku事件
|
|
||||||
handleSkuBatch () {
|
|
||||||
const skuBatchForm = this.getFilterObject(this.multiSpecData.skuBatchForm)
|
|
||||||
const skuList = this.multiSpecData.skuList
|
|
||||||
// if (!skuBatchForm.image_id) {
|
|
||||||
// delete skuBatchForm.image
|
|
||||||
// }
|
|
||||||
console.log('skuBatchForm', skuBatchForm)
|
|
||||||
for (const index in skuList) {
|
|
||||||
skuList[index] = { ...skuList[index], ...skuBatchForm }
|
|
||||||
}
|
|
||||||
this.onUpdate(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 过滤对象的空元素
|
|
||||||
* (仅支持一维对象)
|
|
||||||
* @param {object} object 源对象
|
|
||||||
* @returns {object}
|
|
||||||
*/
|
|
||||||
getFilterObject (object) {
|
|
||||||
const newObj = {}
|
|
||||||
for (const key in object) {
|
|
||||||
const value = object[key]
|
|
||||||
// value === 0 可以不过滤image_id为0的情况
|
|
||||||
// if (!isEmpty(value) || value === 0) {
|
|
||||||
// newObj[key] = value
|
|
||||||
// }
|
|
||||||
if (!isEmpty(value)) {
|
|
||||||
newObj[key] = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return newObj
|
|
||||||
}
|
|
||||||
|
|
||||||
// 表单验证
|
|
||||||
verifyForm () {
|
|
||||||
// 验证规格
|
|
||||||
if (!this.verifySpec()) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
// 验证sku
|
|
||||||
if (!this.verifySkuList()) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// 验证sku
|
|
||||||
verifySkuList () {
|
|
||||||
const columns = [
|
|
||||||
{ field: 'goods_price', name: '商品价格' },
|
|
||||||
{ field: 'stock_num', name: '库存数量' },
|
|
||||||
{ field: 'goods_weight', name: '商品重量' }
|
|
||||||
]
|
|
||||||
const skuList = this.multiSpecData.skuList
|
|
||||||
for (const skuIndex in skuList) {
|
|
||||||
const skuItem = skuList[skuIndex]
|
|
||||||
for (const colIndex in columns) {
|
|
||||||
const value = skuItem[columns[colIndex].field]
|
|
||||||
if (value === '' || value === null) {
|
|
||||||
this.error = `${columns[colIndex].name}不能为空`
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// 验证规格
|
|
||||||
verifySpec () {
|
|
||||||
const specList = this.multiSpecData.specList
|
|
||||||
if (!specList.length) {
|
|
||||||
this.error = '亲,还没有添加规格组~'
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for (const index in specList) {
|
|
||||||
// 验证规格组
|
|
||||||
const specGroup = specList[index]
|
|
||||||
if (isEmpty(specGroup.spec_name)) {
|
|
||||||
this.error = '规格组名称不能为空~'
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
// 验证规格值
|
|
||||||
const valueList = specGroup.valueList
|
|
||||||
if (!valueList.length) {
|
|
||||||
this.error = '还没有添加规格值~'
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for (const i in valueList) {
|
|
||||||
if (isEmpty(valueList[i].spec_value)) {
|
|
||||||
this.error = '规格值不能为空~'
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取规格及SKU信息(表单提交)
|
|
||||||
getFromSpecData () {
|
|
||||||
const { multiSpecData: { specList, skuList } } = this
|
|
||||||
const specData = {
|
|
||||||
specList: _.cloneDeep(specList),
|
|
||||||
skuList: _.cloneDeep(skuList)
|
|
||||||
}
|
|
||||||
for (const skuIndex in specData.skuList) {
|
|
||||||
const skuItem = specData.skuList[skuIndex]
|
|
||||||
delete skuItem.image
|
|
||||||
// delete skuItem.imageList
|
|
||||||
delete skuItem.key
|
|
||||||
}
|
|
||||||
return specData
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 使用防抖节流方式刷新sku列表
|
|
||||||
* @param {boolean} isDebounce 如果true则使用防抖函数
|
|
||||||
*/
|
|
||||||
onUpdate (isDebounce = true) {
|
|
||||||
if (isDebounce) {
|
|
||||||
debounce(getDataForDebounce, 200)(this)
|
|
||||||
} else {
|
|
||||||
getDataForDebounce(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// onUpdate调用的逻辑方法
|
|
||||||
const getDataForDebounce = MultiSpecModel => {
|
|
||||||
return MultiSpecModel.getData()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 生成笛卡尔积数据
|
|
||||||
* cartesianProductOf([arr1, arr2, arr3 ...])
|
|
||||||
*/
|
|
||||||
const cartesianProductOf = arrays => {
|
|
||||||
if (!arrays.length) {
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
return Array.prototype.reduce.call(arrays, (arr1, arr2) => {
|
|
||||||
var ret = []
|
|
||||||
arr1.forEach(v1 => {
|
|
||||||
arr2.forEach(v2 => {
|
|
||||||
ret.push(v1.concat([v2]))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
return ret
|
|
||||||
}, [[]])
|
|
||||||
}
|
|
@ -1,407 +1,518 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<el-form-item :label-width="labelWidth" label="商品规格">
|
||||||
<a-form-item label="商品规格" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
<div style="display: block;width: 100%;">
|
||||||
<div v-if="true" class="form-item-help" style="line-height: 36px">
|
<!-- <el-input-number v-model.number="formData.goodsSpec" controls-position="right" :min="0.01"
|
||||||
<small>最多添加3个商品规格组,生成的SKU数量不能超出50个</small>
|
:precision="2" /> -->
|
||||||
</div>
|
<div class="input-intro">最多添加3个商品规格组,生成的SKU数量不能超出50个</div>
|
||||||
<!-- 规格组 -->
|
|
||||||
<div class="spec-group" v-for="(item, index) in multiSpecData.specList" :key="index">
|
<!-- 规格样式 -->
|
||||||
<div class="spec-group-item clearfix">
|
<div class="sepc-big-box" v-for="(item, index) in goodsSpecList">
|
||||||
<a-input
|
<div class="sepc-title-box">
|
||||||
class="group-item-input"
|
<el-input v-model="item.specName" @change="handleChangeSepc(item, index)" class="spec-input" placeholder="规格组名称"
|
||||||
v-model="item.spec_name"
|
clearable />
|
||||||
:readOnly="isSpecLocked"
|
<el-link type="primary" @click="handleDelSpec(item)">删除规格组</el-link>
|
||||||
placeholder="请输入规格名称"
|
|
||||||
@change="onChangeSpecGroupIpt"
|
|
||||||
/>
|
|
||||||
<a
|
|
||||||
v-if="!isSpecLocked"
|
|
||||||
class="group-item-delete"
|
|
||||||
href="javascript:;"
|
|
||||||
@click="handleDeleteSpecGroup(index)"
|
|
||||||
>删除规格组</a>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="spec-value clearfix">
|
<div class="spec-value-box">
|
||||||
<div class="spec-value-item" v-for="(itm, idx) in item.valueList" :key="idx">
|
<div class="spec-value-input-big-box">
|
||||||
<a-input
|
<div class="spec-value-input-box" v-for="specValue in item.props">
|
||||||
class="value-item-input"
|
<div class="spec-value-input-del" @click="handleDelSpecValue(item, specValue)"><el-icon>
|
||||||
v-model="itm.spec_value"
|
<Close />
|
||||||
:readOnly="isSpecLocked"
|
</el-icon></div>
|
||||||
placeholder="请输入规格值"
|
<el-input v-model="specValue.specValueName" @change="handleChangeSepcValue(item, specValue)"
|
||||||
@change="onChangeSpecValueIpt"
|
class="spec-value-input" placeholder="规格值名称" clearable />
|
||||||
/>
|
</div>
|
||||||
<a-icon
|
|
||||||
v-if="!isSpecLocked"
|
|
||||||
class="icon-close"
|
|
||||||
theme="filled"
|
|
||||||
type="close-circle"
|
|
||||||
@click="handleDeleteSpecValue(index, idx)"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div v-if="!isSpecLocked" class="spec-value-add">
|
|
||||||
<a
|
|
||||||
class="group-item-delete"
|
|
||||||
href="javascript:;"
|
|
||||||
@click="handleAddSpecValue(index)"
|
|
||||||
>新增规格值</a>
|
|
||||||
</div>
|
</div>
|
||||||
|
<el-link type="primary" v-if="isAddSpecValueMax" @click="handleAddSpecValue(item)">添加规格值</el-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 添加规格按钮 -->
|
|
||||||
<a-button
|
<el-button v-if="isAddSpecMax" class="mt-5" @click="handleAddSpec">
|
||||||
v-if="!isSpecLocked && multiSpecData.specList.length < 3"
|
<el-icon class="avatar-uploader-icon">
|
||||||
class="spec-group-add-btn"
|
<plus />
|
||||||
icon="plus"
|
</el-icon>
|
||||||
@click="handleAddSpecGroup"
|
添加规格组
|
||||||
>添加规格组</a-button>
|
</el-button>
|
||||||
</a-form-item>
|
</div>
|
||||||
<a-form-item
|
</el-form-item>
|
||||||
v-show="multiSpecData.skuList.length"
|
|
||||||
label="SKU列表"
|
|
||||||
:labelCol="labelCol"
|
<!-- Sku列表 -->
|
||||||
:wrapperCol="wrapperCol"
|
<el-form-item :label-width="labelWidth" label="Sku列表">
|
||||||
>
|
|
||||||
<!-- 批量设置 -->
|
<!-- sku列表 -->
|
||||||
<div v-if="multiSpecData.skuList.length > 1" class="sku-batch">
|
<el-table :data="skuList" border style="width: 100%" :span-method="objectSpanMethod">
|
||||||
<span class="title">批量设置:</span>
|
<!-- 动态列 -->
|
||||||
<a-input-number
|
<el-table-column v-for="column in skuColumns" :prop="column.prop" :label="column.label" :key="column.key"
|
||||||
v-model="multiSpecData.skuBatchForm.goods_price"
|
:width="column.width">
|
||||||
placeholder="商品价格"
|
</el-table-column>
|
||||||
:min="0.01"
|
|
||||||
:precision="2"
|
<!-- <el-table-column prop="goodsSkuPrice" label="预览图">
|
||||||
/>
|
<template #default="scope">
|
||||||
<a-input-number
|
<UploadImage ref="uploadRef" v-model="scope.row.goodsSkuImg" :data=imgData :limit="1"
|
||||||
v-model="multiSpecData.skuBatchForm.line_price"
|
:fileSize="5" :drag="true" :isShowTip="false" />
|
||||||
placeholder="划线价格"
|
</template>
|
||||||
:min="0"
|
</el-table-column> -->
|
||||||
:precision="2"
|
|
||||||
/>
|
<el-table-column prop="goodsSkuPrice" label="商品价格">
|
||||||
<a-input-number
|
<template #default="scope">
|
||||||
v-model="multiSpecData.skuBatchForm.stock_num"
|
<el-input-number v-model.number="scope.row.goodsSkuPrice" controls-position="right" :min="0" :precision="2" />
|
||||||
placeholder="库存数量"
|
|
||||||
:min="0"
|
|
||||||
:precision="0"
|
|
||||||
/>
|
|
||||||
<a-input-number
|
|
||||||
v-model="multiSpecData.skuBatchForm.goods_weight"
|
|
||||||
placeholder="商品重量"
|
|
||||||
:min="0"
|
|
||||||
:precision="2"
|
|
||||||
/>
|
|
||||||
<a-input v-model="multiSpecData.skuBatchForm.goods_sku_no" placeholder="sku编码" />
|
|
||||||
<a-button @click="handleSkuBatch">立即设置</a-button>
|
|
||||||
</div>
|
|
||||||
<!-- sku列表table -->
|
|
||||||
<a-table
|
|
||||||
class="sku-list"
|
|
||||||
:columns="multiSpecData.skuColumns"
|
|
||||||
:dataSource="multiSpecData.skuList"
|
|
||||||
:scroll="{ x: true }"
|
|
||||||
:pagination="false"
|
|
||||||
bordered
|
|
||||||
>
|
|
||||||
<!-- 预览图 -->
|
|
||||||
<template slot="image" slot-scope="text, item">
|
|
||||||
<SelectImage
|
|
||||||
v-model="item.image_id"
|
|
||||||
:defaultList="(item.image_id > 0 && item.image) ? [item.image] : []"
|
|
||||||
:width="50"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
<!-- 商品价格 -->
|
</el-table-column>
|
||||||
<template slot="goods_price" slot-scope="text, item">
|
|
||||||
<a-input-number v-model="item.goods_price" size="small" :min="0.01" :precision="2" />
|
</el-table>
|
||||||
</template>
|
</el-form-item>
|
||||||
<!-- 划线价格 -->
|
|
||||||
<template slot="line_price" slot-scope="text, item">
|
|
||||||
<a-input-number v-model="item.line_price" size="small" :min="0" :precision="2" />
|
|
||||||
</template>
|
|
||||||
<!-- 库存数量 -->
|
|
||||||
<template slot="stock_num" slot-scope="text, item">
|
|
||||||
<a-input-number v-model="item.stock_num" size="small" :min="0" :precision="0" />
|
|
||||||
</template>
|
|
||||||
<!-- 商品重量 -->
|
|
||||||
<template slot="goods_weight" slot-scope="text, item">
|
|
||||||
<a-input-number v-model="item.goods_weight" size="small" :min="0" :precision="2" />
|
|
||||||
</template>
|
|
||||||
<!-- sku编码 -->
|
|
||||||
<template slot="goods_sku_no" slot-scope="text, item">
|
|
||||||
<a-input v-model="item.goods_sku_no" size="small" />
|
|
||||||
</template>
|
|
||||||
</a-table>
|
|
||||||
</a-form-item>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
import PropTypes from 'ant-design-vue/es/_util/vue-types'
|
import descartes from "./dikaerji";
|
||||||
import MultiSpecModel from '@/common/model/goods/MultiSpec'
|
|
||||||
import { SelectImage } from '@/components'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
SelectImage
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
// 默认的规格列表
|
|
||||||
defaultSpecList: PropTypes.array.def([]),
|
|
||||||
// 默认的SKU列表
|
|
||||||
defaultSkuList: PropTypes.array.def([]),
|
|
||||||
// 商品规格是否锁定(锁定状态下不允许编辑规格)
|
|
||||||
isSpecLocked: PropTypes.bool.def(false)
|
|
||||||
},
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
// 标签布局属性
|
|
||||||
labelCol: { span: 3 },
|
|
||||||
// 输入框布局属性
|
|
||||||
wrapperCol: { span: 21 },
|
|
||||||
// 商品多规格模型
|
|
||||||
MultiSpecModel: new MultiSpecModel(),
|
|
||||||
// MultiSpecModel: Object,
|
|
||||||
multiSpecData: {
|
|
||||||
// 规格列表
|
|
||||||
specList: [],
|
|
||||||
// SKU列表
|
|
||||||
skuList: []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
defaultSpecList (val) {
|
|
||||||
if (val.length && this.MultiSpecModel.isEmpty()) {
|
|
||||||
this.getData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 初始化数据
|
|
||||||
created () {
|
|
||||||
// 获取规格及SKU信息
|
|
||||||
this.getData()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
|
|
||||||
// 获取规格及SKU信息(展示)
|
/** 商品规格 业务参数 */
|
||||||
getData () {
|
|
||||||
const { defaultSpecList, defaultSkuList } = this
|
|
||||||
this.multiSpecData = this.MultiSpecModel.getData(defaultSpecList, defaultSkuList)
|
|
||||||
},
|
|
||||||
|
|
||||||
// 获取规格及SKU信息(表单提交)
|
// 添加商品规格按钮状态
|
||||||
getFromSpecData () {
|
const isAddSpecMax = ref(true)
|
||||||
return this.MultiSpecModel.getFromSpecData()
|
const isAddSpecValueMax = ref(true)
|
||||||
},
|
|
||||||
|
|
||||||
// 添加规格组
|
// 动态表头
|
||||||
handleAddSpecGroup () {
|
const skuColumns = ref([
|
||||||
if (this.checkSkuMaxNum()) {
|
// {
|
||||||
this.MultiSpecModel.handleAddSpecGroup()
|
// prop: 'specValue',
|
||||||
}
|
// label: '颜色',
|
||||||
},
|
// width: '100'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// prop: 'specSecondValue',
|
||||||
|
// label: '内存',
|
||||||
|
// width: '100'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// prop: 'specThirdValue',
|
||||||
|
// label: '版本',
|
||||||
|
// width: '100'
|
||||||
|
// },
|
||||||
|
])
|
||||||
|
|
||||||
// 删除规格组
|
// 规格组
|
||||||
handleDeleteSpecGroup (groupIndex) {
|
const goodsSpecList = ref([
|
||||||
const app = this
|
// 规格值Json属性
|
||||||
const modal = this.$confirm({
|
// {
|
||||||
title: '您确定要删除该规格组吗?',
|
// specId: 0,
|
||||||
content: '删除后不可恢复',
|
// specName: "",
|
||||||
onOk () {
|
// props: [
|
||||||
// 删除元素
|
// {
|
||||||
app.MultiSpecModel.handleDeleteSpecGroup(groupIndex)
|
// specValueId: 0,
|
||||||
// 关闭对话框
|
// specValueName: "",
|
||||||
modal.destroy()
|
// specValue: "",
|
||||||
}
|
// },
|
||||||
})
|
// ],
|
||||||
},
|
// }
|
||||||
|
])
|
||||||
// 新增规格值
|
|
||||||
handleAddSpecValue (groupIndex) {
|
|
||||||
if (this.checkSkuMaxNum()) {
|
|
||||||
this.MultiSpecModel.handleAddSpecValue(groupIndex)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// 删除规格值
|
|
||||||
handleDeleteSpecValue (groupIndex, valueIndex) {
|
|
||||||
const app = this
|
|
||||||
const modal = this.$confirm({
|
|
||||||
title: '您确定要删除该规格值吗?',
|
|
||||||
content: '删除后不可恢复',
|
|
||||||
onOk () {
|
|
||||||
// 删除元素
|
|
||||||
app.MultiSpecModel.handleDeleteSpecValue(groupIndex, valueIndex)
|
|
||||||
// 关闭对话框
|
|
||||||
modal.destroy()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
// 规格组输入框change事件
|
|
||||||
onChangeSpecGroupIpt () {
|
|
||||||
// 更新skuList
|
|
||||||
this.MultiSpecModel.onUpdate(true)
|
|
||||||
},
|
|
||||||
|
|
||||||
// 规格值输入框change事件
|
|
||||||
onChangeSpecValueIpt (event, itm) {
|
|
||||||
// 更新skuList
|
|
||||||
this.MultiSpecModel.onUpdate(true)
|
|
||||||
},
|
|
||||||
|
|
||||||
// 验证最大sku数量
|
|
||||||
checkSkuMaxNum () {
|
|
||||||
const skuList = this.multiSpecData.skuList
|
|
||||||
if (skuList.length >= 50) {
|
|
||||||
this.$message.error(`生成的sku列表数量不能大于50个,当前数量:${skuList.length}个`, 2.5)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
|
|
||||||
// 批量设置sku事件
|
|
||||||
handleSkuBatch () {
|
|
||||||
this.MultiSpecModel.handleSkuBatch()
|
|
||||||
},
|
|
||||||
|
|
||||||
// 验证多规格表单
|
|
||||||
verifyForm () {
|
|
||||||
if (!this.MultiSpecModel.verifyForm()) {
|
|
||||||
this.$message.error(this.MultiSpecModel.getError(), 2)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
<style lang="less" scoped>
|
|
||||||
// 商品多规格
|
|
||||||
.spec-group {
|
|
||||||
width: 895px;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
line-height: normal;
|
|
||||||
|
|
||||||
.ant-input {
|
|
||||||
height: 28px;
|
|
||||||
padding: 4px 11px;
|
|
||||||
font-size: @font-size-base;
|
|
||||||
line-height: 1.5;
|
|
||||||
|
|
||||||
&::placeholder {
|
|
||||||
font-size: @font-size-base;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-item-help {
|
|
||||||
line-height: 36px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.spec-group-item {
|
|
||||||
background: #f4f5f9;
|
|
||||||
padding: 7px 12px;
|
|
||||||
line-height: 28px;
|
|
||||||
|
|
||||||
.group-item-input {
|
|
||||||
float: left;
|
|
||||||
width: 180px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.group-item-delete {
|
|
||||||
font-size: 12px;
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.spec-value {
|
|
||||||
background: #fbfbfb;
|
|
||||||
padding: 8px 35px;
|
|
||||||
|
|
||||||
.spec-value-add,
|
|
||||||
.spec-value-item {
|
|
||||||
float: left;
|
|
||||||
margin-bottom: 6px;
|
|
||||||
margin-top: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.spec-value-add {
|
|
||||||
height: 28px;
|
|
||||||
line-height: 28px;
|
|
||||||
|
|
||||||
a {
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.spec-value-item {
|
|
||||||
position: relative;
|
|
||||||
margin-right: 20px;
|
|
||||||
|
|
||||||
.value-item-input {
|
|
||||||
width: 186px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
.icon-close {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon-close {
|
|
||||||
display: none;
|
|
||||||
position: absolute;
|
|
||||||
top: -8px;
|
|
||||||
right: -8px;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 16px;
|
|
||||||
color: #7d7d7d;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加规格按钮
|
|
||||||
.spec-group-add-btn {
|
|
||||||
font-size: @font-size-base;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 批量设置sku
|
|
||||||
.sku-batch {
|
|
||||||
line-height: 40px;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
.title {
|
|
||||||
line-height: 28px;
|
|
||||||
margin-right: 15px;
|
|
||||||
font-size: @font-size-base;
|
|
||||||
}
|
|
||||||
/deep/.ant-input,
|
|
||||||
/deep/.ant-input-number {
|
|
||||||
width: 120px;
|
|
||||||
margin-right: 15px;
|
|
||||||
}
|
|
||||||
/deep/.ant-input {
|
|
||||||
width: 140px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// sku列表
|
// sku列表
|
||||||
.sku-list {
|
const skuList = ref([
|
||||||
width: 895px;
|
])
|
||||||
/deep/.ant-table-thead > tr > th,
|
|
||||||
/deep/.ant-table-tbody > tr > td {
|
|
||||||
white-space: nowrap;
|
/** sku列表参数 */
|
||||||
|
const newList = ref([])
|
||||||
|
const newData = ref([])
|
||||||
|
const tableData7 = ref([])
|
||||||
|
const spanArr = ref([])
|
||||||
|
const spanArr1 = ref([])
|
||||||
|
const pos = ref("")
|
||||||
|
const pos1 = ref("")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** sku列表方法 */
|
||||||
|
|
||||||
|
|
||||||
|
//处理数据(拆分规格组里的规格值为数组)
|
||||||
|
const processing = () => {
|
||||||
|
newData.value = [];
|
||||||
|
for (let i = 0; i < goodsSpecList.value.length; i++) {
|
||||||
|
var newlist = [];
|
||||||
|
for (
|
||||||
|
let index = 0;
|
||||||
|
index < goodsSpecList.value[i].props.length;
|
||||||
|
index++
|
||||||
|
) {
|
||||||
|
newlist.push(goodsSpecList.value[i].props[index].specValueName);
|
||||||
|
}
|
||||||
|
this.newData.push(newlist);
|
||||||
}
|
}
|
||||||
/deep/.ant-table-tbody > tr > td {
|
console.log(this.newData, '各规格组中的规格值');
|
||||||
padding: 12px 18px;
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//转换数据
|
||||||
|
const getList = () => {
|
||||||
|
tableData7.value = [];
|
||||||
|
newList.value = this.descartes(newData.value);
|
||||||
|
console.log(newList.value, '笛卡尔积处理过后的数据');
|
||||||
|
for (let index = 0; index < newList.value.length; index++) {
|
||||||
|
this.tableData7.push({
|
||||||
|
specValue: newList.value[index][0],
|
||||||
|
specSecondValue: newList.value[index][1],
|
||||||
|
specThirdValue: newList.value[index][2],
|
||||||
|
goodsGuid: 0,
|
||||||
|
specValueName: "",
|
||||||
|
goodsSkuImg: "",
|
||||||
|
goodsSkuSkuCode: 0,
|
||||||
|
goodsSkuPrice: 0,
|
||||||
|
goodsSkuLinePrice: 0,
|
||||||
|
goodsSkuStockNum: 0,
|
||||||
|
goodsSkuWeight: 0,
|
||||||
|
goodsSkuProps: ""
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/.ant-input-sm,
|
getSpanArr(this.tableData7);
|
||||||
/deep/.ant-input-number-sm {
|
console.log(this.tableData7, '表格中的数据');
|
||||||
height: 28px;
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//计算位置的方法
|
||||||
|
const getSpanArr = (data) => {
|
||||||
|
spanArr.value = [];
|
||||||
|
pos.value = "";
|
||||||
|
spanArr1.value = [];
|
||||||
|
pos1.value = "";
|
||||||
|
for (var i = 0; i < data.length; i++) {
|
||||||
|
if (i === 0) {
|
||||||
|
spanArr.value.push(1);
|
||||||
|
pos.value = 0;
|
||||||
|
} else {
|
||||||
|
// 判断当前元素与上一个元素是否相同
|
||||||
|
if (data[i].specValue === data[i - 1].specValue) {
|
||||||
|
spanArr.value[pos.value] += 1;
|
||||||
|
spanArr.value.push(0);
|
||||||
|
} else {
|
||||||
|
spanArr.value.push(1);
|
||||||
|
pos.value = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/deep/.ant-input-number-sm input {
|
|
||||||
height: 26px;
|
for (var i = 0; i < data.length; i++) {
|
||||||
|
if (i === 0) {
|
||||||
|
spanArr1.value.push(1);
|
||||||
|
pos1.value = 0;
|
||||||
|
} else {
|
||||||
|
//如果笛卡尔积一直递增下去的话 这是一个很蠢的方法 由于我的要求层数是已知的 这里偷懒了 不然应该用for循环
|
||||||
|
if (data[i].specSecondValue === data[i - 1].specSecondValue) {
|
||||||
|
spanArr1.value[pos1.value] += 1;
|
||||||
|
spanArr1.value.push(0);
|
||||||
|
} else {
|
||||||
|
spanArr1.value.push(1);
|
||||||
|
pos1.value = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(this.spanArr, '排序Arr');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 合并行数
|
||||||
|
const objectSpanMethod = ({ row, column, rowIndex, columnIndex }) => {
|
||||||
|
// columnIndex === 0 找到第一列,实现合并随机出现的行数
|
||||||
|
if (columnIndex === 0) {
|
||||||
|
const _row = spanArr.value[rowIndex];
|
||||||
|
const _col = _row > 0 ? 1 : 0;
|
||||||
|
return {
|
||||||
|
rowspan: _row,
|
||||||
|
colspan: _col
|
||||||
|
};
|
||||||
|
// columnIndex === 1 找到第二列,合并他的列数
|
||||||
|
} else if (columnIndex === 1) {
|
||||||
|
const _row = spanArr1.value[rowIndex];
|
||||||
|
const _col = _row > 0 ? 1 : 0;
|
||||||
|
return {
|
||||||
|
rowspan: _row,
|
||||||
|
colspan: _col
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 合并列表
|
||||||
|
// const objectSpanMethod = ({
|
||||||
|
// row,
|
||||||
|
// column,
|
||||||
|
// rowIndex,
|
||||||
|
// columnIndex,
|
||||||
|
// }) => {
|
||||||
|
// // if (columnIndex === 0) {
|
||||||
|
// // if (rowIndex % firstLen === 0) {
|
||||||
|
// // return {
|
||||||
|
// // rowspan: firstLen,
|
||||||
|
// // colspan: 1,
|
||||||
|
// // }
|
||||||
|
// // } else {
|
||||||
|
// // return {
|
||||||
|
// // rowspan: 0,
|
||||||
|
// // colspan: 0,
|
||||||
|
// // }
|
||||||
|
// // }
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // if (columnIndex === 1) {
|
||||||
|
// // if (rowIndex % secondLen === 0) {
|
||||||
|
// // return {
|
||||||
|
// // rowspan: secondLen,
|
||||||
|
// // colspan: 1,
|
||||||
|
// // }
|
||||||
|
// // } else {
|
||||||
|
// // return {
|
||||||
|
// // rowspan: 0,
|
||||||
|
// // colspan: 0,
|
||||||
|
// // }
|
||||||
|
// // }
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// let firstLen = 0
|
||||||
|
// let secondLen = 0
|
||||||
|
// skuList.value.map((item, idx) => {
|
||||||
|
// let firstVal = skuList?.value[0].specValue
|
||||||
|
// if (item.specValue === firstVal) {
|
||||||
|
// firstLen += 1
|
||||||
|
// firstVal = item.specValue
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // let secondVal = skuList?.value[0].specSecondValue
|
||||||
|
// // if (item.specSecondValue === secondVal) {
|
||||||
|
// // secondLen += 1
|
||||||
|
// // secondVal = item.specSecondValue
|
||||||
|
// // }
|
||||||
|
// })
|
||||||
|
// console.log(secondLen, '第二列');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** 商品规格 业务方法 */
|
||||||
|
|
||||||
|
// 添加规格组
|
||||||
|
function handleAddSpec() {
|
||||||
|
let data = {
|
||||||
|
specId: 0,
|
||||||
|
specName: "",
|
||||||
|
key: 0,
|
||||||
|
props: [
|
||||||
|
|
||||||
|
]
|
||||||
|
}
|
||||||
|
goodsSpecList.value.push(data)
|
||||||
|
|
||||||
|
if (goodsSpecList.value.length == 3) {
|
||||||
|
isAddSpecMax.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改规格组
|
||||||
|
function handleChangeSepc(item, idx) {
|
||||||
|
|
||||||
|
item.key = idx
|
||||||
|
let foundMatch = false;
|
||||||
|
skuColumns.value.map((i, index) => {
|
||||||
|
if (i.key == idx) {
|
||||||
|
i.label = item.specName
|
||||||
|
foundMatch = true
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (foundMatch) {
|
||||||
|
return; // 停止执行后续代码
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加动态表头
|
||||||
|
let column = {
|
||||||
|
prop: 'specValue',
|
||||||
|
label: item.specName,
|
||||||
|
width: '100',
|
||||||
|
key: idx
|
||||||
|
}
|
||||||
|
skuColumns.value.push(column)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除规格组
|
||||||
|
function handleDelSpec(item) {
|
||||||
|
const index = goodsSpecList.value.indexOf(item);
|
||||||
|
if (index > -1) {
|
||||||
|
goodsSpecList.value.splice(index, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (goodsSpecList.value.length < 3) {
|
||||||
|
isAddSpecMax.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 输出对应的表头
|
||||||
|
skuColumns.value = skuColumns.value.filter(column => column.label !== item.specName);
|
||||||
|
|
||||||
|
// 删除对应的sku
|
||||||
|
// skuColumns.value = skuColumns.value.filter(column => column.specName !== item.specName);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 添加规格值
|
||||||
|
function handleAddSpecValue(item) {
|
||||||
|
let data = {
|
||||||
|
specId: 0,
|
||||||
|
specValueId: 0,
|
||||||
|
specValueName: "",
|
||||||
|
}
|
||||||
|
item.props.push(data)
|
||||||
|
|
||||||
|
if (item.props.length == 50) {
|
||||||
|
isAddSpecValueMax.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 修改规格值
|
||||||
|
function handleChangeSepcValue(item, specValue) {
|
||||||
|
|
||||||
|
let firstSpecValue = ""
|
||||||
|
let secondSpecValue = ""
|
||||||
|
let thirdSpecValue = ""
|
||||||
|
|
||||||
|
console.log(item, 'item喵喵喵喵喵喵');
|
||||||
|
// goodsSpecList.value.map((item,index) => {
|
||||||
|
// if(item.key === 0){
|
||||||
|
// firstSpecValue = specValue.specValueName
|
||||||
|
// }
|
||||||
|
// if(item.key === 1){
|
||||||
|
// secondSpecValue = specValue.specValueName
|
||||||
|
// }
|
||||||
|
// if(item.key === 2){
|
||||||
|
// thirdSpecValue = specValue.specValueName
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
|
||||||
|
// 添加sku
|
||||||
|
let sku = {
|
||||||
|
specValue: firstSpecValue,
|
||||||
|
specSecondValue: secondSpecValue,
|
||||||
|
specThirdValue: thirdSpecValue,
|
||||||
|
goodsGuid: 0,
|
||||||
|
specValueName: "",
|
||||||
|
goodsSkuImg: "",
|
||||||
|
goodsSkuSkuCode: 0,
|
||||||
|
goodsSkuPrice: 0,
|
||||||
|
goodsSkuLinePrice: 0,
|
||||||
|
goodsSkuStockNum: 0,
|
||||||
|
goodsSkuWeight: 0,
|
||||||
|
goodsSkuProps: ""
|
||||||
|
}
|
||||||
|
skuList.value.push(sku)
|
||||||
|
|
||||||
|
console.log(skuList.value, 'asdasd-------------');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 删除规格值
|
||||||
|
function handleDelSpecValue(item, specValue) {
|
||||||
|
const index = item.props.indexOf(specValue);
|
||||||
|
if (index > -1) {
|
||||||
|
item.props.splice(index, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.props.length < 50) {
|
||||||
|
isAddSpecValueMax.value = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.divider-title {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-intro {
|
||||||
|
color: #8c8c8c;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-divider {
|
||||||
|
margin: 50px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sepc-big-box {
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sepc-title-box {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
background-color: #f4f4f5;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spec-value-box {
|
||||||
|
width: 100%;
|
||||||
|
padding: 20px 20px 20px 40px;
|
||||||
|
background-color: #fbfbfb;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spec-value-input-big-box {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spec-value-input-box {
|
||||||
|
width: 250px;
|
||||||
|
position: relative;
|
||||||
|
margin-right: 30px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spec-value-input-del {
|
||||||
|
position: absolute;
|
||||||
|
top: -5px;
|
||||||
|
right: -5px;
|
||||||
|
z-index: 99;
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
background-color: grey;
|
||||||
|
color: white;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spec-input {
|
||||||
|
width: 250px;
|
||||||
|
margin-right: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.mt-5 {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-input-number {
|
||||||
|
width: 140px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -0,0 +1,226 @@
|
|||||||
|
// const skuList = ref([
|
||||||
|
// {
|
||||||
|
// specValue: "蓝色",
|
||||||
|
// specSecondValue: "4+128G",
|
||||||
|
// specThirdValue: "5G",
|
||||||
|
// goodsGuid: 0,
|
||||||
|
// specValueName: "",
|
||||||
|
// goodsSkuImg: "",
|
||||||
|
// goodsSkuSkuCode: 0,
|
||||||
|
// goodsSkuPrice: 10,
|
||||||
|
// goodsSkuLinePrice: 0,
|
||||||
|
// goodsSkuStockNum: 0,
|
||||||
|
// goodsSkuWeight: 0,
|
||||||
|
// goodsSkuProps: ""
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// specValue: "蓝色",
|
||||||
|
// specSecondValue: "4+128G",
|
||||||
|
// specThirdValue: "4G",
|
||||||
|
// goodsGuid: 0,
|
||||||
|
// specValueName: "",
|
||||||
|
// goodsSkuImg: "",
|
||||||
|
// goodsSkuSkuCode: 0,
|
||||||
|
// goodsSkuPrice: 10,
|
||||||
|
// goodsSkuLinePrice: 0,
|
||||||
|
// goodsSkuStockNum: 0,
|
||||||
|
// goodsSkuWeight: 0,
|
||||||
|
// goodsSkuProps: ""
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// specValue: "蓝色",
|
||||||
|
// specSecondValue: "8+256G",
|
||||||
|
// specThirdValue: "5G",
|
||||||
|
// goodsGuid: 0,
|
||||||
|
// specValueName: "",
|
||||||
|
// goodsSkuImg: "",
|
||||||
|
// goodsSkuSkuCode: 0,
|
||||||
|
// goodsSkuPrice: 10,
|
||||||
|
// goodsSkuLinePrice: 0,
|
||||||
|
// goodsSkuStockNum: 0,
|
||||||
|
// goodsSkuWeight: 0,
|
||||||
|
// goodsSkuProps: ""
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// specValue: "蓝色",
|
||||||
|
// specSecondValue: "8+256G",
|
||||||
|
// specThirdValue: "4G",
|
||||||
|
// goodsGuid: 0,
|
||||||
|
// specValueName: "",
|
||||||
|
// goodsSkuImg: "",
|
||||||
|
// goodsSkuSkuCode: 0,
|
||||||
|
// goodsSkuPrice: 10,
|
||||||
|
// goodsSkuLinePrice: 0,
|
||||||
|
// goodsSkuStockNum: 0,
|
||||||
|
// goodsSkuWeight: 0,
|
||||||
|
// goodsSkuProps: ""
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// specValue: "蓝色",
|
||||||
|
// specSecondValue: "12+1T",
|
||||||
|
// specThirdValue: "5G",
|
||||||
|
// goodsGuid: 0,
|
||||||
|
// specValueName: "",
|
||||||
|
// goodsSkuImg: "",
|
||||||
|
// goodsSkuSkuCode: 0,
|
||||||
|
// goodsSkuPrice: 10,
|
||||||
|
// goodsSkuLinePrice: 0,
|
||||||
|
// goodsSkuStockNum: 0,
|
||||||
|
// goodsSkuWeight: 0,
|
||||||
|
// goodsSkuProps: ""
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// specValue: "蓝色",
|
||||||
|
// specSecondValue: "12+1T",
|
||||||
|
// specThirdValue: "4G",
|
||||||
|
// goodsGuid: 0,
|
||||||
|
// specValueName: "",
|
||||||
|
// goodsSkuImg: "",
|
||||||
|
// goodsSkuSkuCode: 0,
|
||||||
|
// goodsSkuPrice: 10,
|
||||||
|
// goodsSkuLinePrice: 0,
|
||||||
|
// goodsSkuStockNum: 0,
|
||||||
|
// goodsSkuWeight: 0,
|
||||||
|
// goodsSkuProps: ""
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// specValue: "蓝色",
|
||||||
|
// specSecondValue: "1000G",
|
||||||
|
// specThirdValue: "5G",
|
||||||
|
// goodsGuid: 0,
|
||||||
|
// specValueName: "",
|
||||||
|
// goodsSkuImg: "",
|
||||||
|
// goodsSkuSkuCode: 0,
|
||||||
|
// goodsSkuPrice: 10,
|
||||||
|
// goodsSkuLinePrice: 0,
|
||||||
|
// goodsSkuStockNum: 0,
|
||||||
|
// goodsSkuWeight: 0,
|
||||||
|
// goodsSkuProps: ""
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// specValue: "蓝色",
|
||||||
|
// specSecondValue: "1000G",
|
||||||
|
// specThirdValue: "4G",
|
||||||
|
// goodsGuid: 0,
|
||||||
|
// specValueName: "",
|
||||||
|
// goodsSkuImg: "",
|
||||||
|
// goodsSkuSkuCode: 0,
|
||||||
|
// goodsSkuPrice: 10,
|
||||||
|
// goodsSkuLinePrice: 0,
|
||||||
|
// goodsSkuStockNum: 0,
|
||||||
|
// goodsSkuWeight: 0,
|
||||||
|
// goodsSkuProps: ""
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// specValue: "黑色",
|
||||||
|
// specSecondValue: "4+128G",
|
||||||
|
// specThirdValue: "5G",
|
||||||
|
// goodsGuid: 0,
|
||||||
|
// specValueName: "",
|
||||||
|
// goodsSkuImg: "",
|
||||||
|
// goodsSkuSkuCode: 0,
|
||||||
|
// goodsSkuPrice: 10,
|
||||||
|
// goodsSkuLinePrice: 0,
|
||||||
|
// goodsSkuStockNum: 0,
|
||||||
|
// goodsSkuWeight: 0,
|
||||||
|
// goodsSkuProps: ""
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// specValue: "黑色",
|
||||||
|
// specSecondValue: "4+128G",
|
||||||
|
// specThirdValue: "4G",
|
||||||
|
// goodsGuid: 0,
|
||||||
|
// specValueName: "",
|
||||||
|
// goodsSkuImg: "",
|
||||||
|
// goodsSkuSkuCode: 0,
|
||||||
|
// goodsSkuPrice: 10,
|
||||||
|
// goodsSkuLinePrice: 0,
|
||||||
|
// goodsSkuStockNum: 0,
|
||||||
|
// goodsSkuWeight: 0,
|
||||||
|
// goodsSkuProps: ""
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// specValue: "黑色",
|
||||||
|
// specSecondValue: "8+256G",
|
||||||
|
// specThirdValue: "5G",
|
||||||
|
// goodsGuid: 0,
|
||||||
|
// specValueName: "",
|
||||||
|
// goodsSkuImg: "",
|
||||||
|
// goodsSkuSkuCode: 0,
|
||||||
|
// goodsSkuPrice: 10,
|
||||||
|
// goodsSkuLinePrice: 0,
|
||||||
|
// goodsSkuStockNum: 0,
|
||||||
|
// goodsSkuWeight: 0,
|
||||||
|
// goodsSkuProps: ""
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// specValue: "黑色",
|
||||||
|
// specSecondValue: "8+256G",
|
||||||
|
// specThirdValue: "4G",
|
||||||
|
// goodsGuid: 0,
|
||||||
|
// specValueName: "",
|
||||||
|
// goodsSkuImg: "",
|
||||||
|
// goodsSkuSkuCode: 0,
|
||||||
|
// goodsSkuPrice: 10,
|
||||||
|
// goodsSkuLinePrice: 0,
|
||||||
|
// goodsSkuStockNum: 0,
|
||||||
|
// goodsSkuWeight: 0,
|
||||||
|
// goodsSkuProps: ""
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// specValue: "黑色",
|
||||||
|
// specSecondValue: "12+1T",
|
||||||
|
// specThirdValue: "5G",
|
||||||
|
// goodsGuid: 0,
|
||||||
|
// specValueName: "",
|
||||||
|
// goodsSkuImg: "",
|
||||||
|
// goodsSkuSkuCode: 0,
|
||||||
|
// goodsSkuPrice: 10,
|
||||||
|
// goodsSkuLinePrice: 0,
|
||||||
|
// goodsSkuStockNum: 0,
|
||||||
|
// goodsSkuWeight: 0,
|
||||||
|
// goodsSkuProps: ""
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// specValue: "黑色",
|
||||||
|
// specSecondValue: "12+1T",
|
||||||
|
// specThirdValue: "4G",
|
||||||
|
// goodsGuid: 0,
|
||||||
|
// specValueName: "",
|
||||||
|
// goodsSkuImg: "",
|
||||||
|
// goodsSkuSkuCode: 0,
|
||||||
|
// goodsSkuPrice: 10,
|
||||||
|
// goodsSkuLinePrice: 0,
|
||||||
|
// goodsSkuStockNum: 0,
|
||||||
|
// goodsSkuWeight: 0,
|
||||||
|
// goodsSkuProps: ""
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// specValue: "黑色",
|
||||||
|
// specSecondValue: "1000G",
|
||||||
|
// specThirdValue: "5G",
|
||||||
|
// goodsGuid: 0,
|
||||||
|
// specValueName: "",
|
||||||
|
// goodsSkuImg: "",
|
||||||
|
// goodsSkuSkuCode: 0,
|
||||||
|
// goodsSkuPrice: 10,
|
||||||
|
// goodsSkuLinePrice: 0,
|
||||||
|
// goodsSkuStockNum: 0,
|
||||||
|
// goodsSkuWeight: 0,
|
||||||
|
// goodsSkuProps: ""
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// specValue: "黑色",
|
||||||
|
// specSecondValue: "1000G",
|
||||||
|
// specThirdValue: "4G",
|
||||||
|
// goodsGuid: 0,
|
||||||
|
// specValueName: "",
|
||||||
|
// goodsSkuImg: "",
|
||||||
|
// goodsSkuSkuCode: 0,
|
||||||
|
// goodsSkuPrice: 10,
|
||||||
|
// goodsSkuLinePrice: 0,
|
||||||
|
// goodsSkuStockNum: 0,
|
||||||
|
// goodsSkuWeight: 0,
|
||||||
|
// goodsSkuProps: ""
|
||||||
|
// },
|
||||||
|
// ])
|
@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
|
||||||
|
//笛卡尔积算法
|
||||||
|
function descartes(array){
|
||||||
|
|
||||||
|
if( array.length < 2 ) return array[0] || [];
|
||||||
|
return [].reduce.call(array, function(col, set) {
|
||||||
|
var res = [];
|
||||||
|
col.forEach(function(c) {
|
||||||
|
set.forEach(function(s) {
|
||||||
|
var t = [].concat( Array.isArray(c) ? c : [c] );
|
||||||
|
t.push(s);
|
||||||
|
res.push(t);
|
||||||
|
})});
|
||||||
|
return res;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export default descartes
|
Loading…
Reference in New Issue
Block a user