积分商城后台管理
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

1632 lines
55 KiB

<template>
<div class="divBox">
<el-card class="box-card">
<div slot="header" class="clearfix">
<el-steps :active="currentTab" align-center finish-status="success">
<el-step title="商品信息" />
<el-step title="商品详情" />
<!-- <el-step title="其他设置" /> -->
<!--<el-step title="规格设置" />-->
</el-steps>
</div>
<el-form
ref="formValidate"
v-loading="loading"
class="formValidate mt20"
:rules="ruleValidate"
:model="formValidate"
label-width="120px"
@submit.native.prevent
>
<el-row v-show="currentTab === 0" :gutter="24">
<!-- 商品信息-->
<el-col v-bind="grid2">
<el-form-item label="商品分类:" prop="categorys" :rules="[{ required: true, message: '请选择商品分类', trigger: ['change'] }]">
<el-cascader
@change="cascaderChange"
v-model="formValidate.categorys"
:options="merCateList"
:props="props2"
clearable
class="selWidth"
:show-all-levels="false"
:disabled="isDisabled"
/>
</el-form-item>
</el-col>
<el-col v-bind="grid2">
<el-form-item label="商品名称:" prop="productName" :rules="[{ required: true, message: '请输入商品名称', trigger: ['change'] }]">
<el-input v-model="formValidate.productName" maxlength="249" placeholder="请输入商品名称" :disabled="isDisabled" />
</el-form-item>
</el-col>
<el-col v-bind="grid2">
<el-form-item label="商品关键字:" prop="keyword">
<el-input v-model="formValidate.keyword" placeholder="请输入商品关键字" :disabled="isDisabled" />
</el-form-item>
</el-col>
<el-col v-bind="grid2">
<el-form-item label="商品品牌:" prop="brandId" :rules="[{ required: true, message: '请选择商品品牌', trigger: ['change'] }]">
<el-select style="width: 100%;" v-model="formValidate.brandId" placeholder="请选择">
<el-option v-for="item in brandOptions" :key="item.id" :label="item.brandName" :value="item.id"> </el-option>
</el-select>
</el-form-item>
</el-col>
<el-col v-bind="grid2">
<el-form-item label="商品货号" prop="productNum">
<el-input v-model="formValidate.productNum" maxlength="249" placeholder="请输入商品货号" :disabled="isDisabled" />
</el-form-item>
</el-col>
<el-col v-bind="grid2">
<el-form-item label="商品售价" prop="price" :rules="[{ required: true, message: '请输入商品售价', trigger: ['change'] }]">
<el-input v-model="formValidate.price" maxlength="249" type="number" placeholder="请输入商品售价" :disabled="isDisabled" />
</el-form-item>
</el-col>
<el-col v-bind="grid2">
<el-form-item label="商品类型:" prop="productType" :rules="[{ required: true, message: '请选择商品类型', trigger: ['change'] }]">
<el-select style="width: 100%;" v-model="formValidate.productType" placeholder="请选择商品类型">
<el-option label="店铺商品" value="2"> </el-option>
<el-option label="平台商品" value="1"> </el-option>
</el-select>
</el-form-item>
</el-col>
<!-- <el-col v-bind="grid2">
<el-form-item label="商品简介:" prop="storeInfo">
<el-input v-model="formValidate.storeInfo" type="textarea" maxlength="250" :rows="3" placeholder="请输入商品简介"
:disabled="isDisabled" />
</el-form-item>
</el-col> -->
<el-col v-bind="grid2">
<el-form-item label="自提油站" prop="siteIds" :rules="[{ validator: validateSiteIds, trigger: ['change'] }]">
<el-tag
style="margin-left: 10px;"
:key="tagIndex"
v-for="(tag, tagIndex) in OilStationSelectionList"
closable
:disable-transitions="false"
@close="delectOilStationSelectionList(tag, tagIndex)"
>
{{ tag.siteName }}
</el-tag>
<el-button class="button-new-tag" size="small" @click="isOilStationSelection = true">+ 添加油站</el-button>
</el-form-item>
</el-col>
<el-col v-bind="grid2">
<el-form-item label="商品推荐:">
<el-select style="width: 100%;" v-model="formValidate.recommendOrNewMark" placeholder="请选择商品类型">
<el-option label="新品" value="1"> </el-option>
<el-option label="推荐" value="2"> </el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="商品上架" prop="productStatus">
<el-switch active-value="1" inactive-value="2" v-model="formValidate.productStatus" active-color="#13ce66" inactive-color="#ff4949">
</el-switch>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="商品封面图:" prop="image">
<CustomUpload ref="CustomUpload"></CustomUpload>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="商品相册:" prop="sliderImages">
<CustomUpload :limit="5" ref="CustomLBUpload"> </CustomUpload>
</el-form-item>
</el-col>
<!-- <el-col :span="24">
<el-form-item label="商品规格:" props="specType">
<el-radio-group v-model="formValidate.specType" @change="onChangeSpec(formValidate.specType)"
:disabled="isDisabled">
<el-radio :label="false" class="radio">单规格</el-radio>
<el-radio :label="true">多规格</el-radio>
</el-radio-group>
</el-form-item>
</el-col> -->
<!-- 多规格添加-->
<el-col v-if="!isDisabled" :span="24" class="noForm">
<el-form-item label="选择规格:" prop="attributesTypeId" :rules="[{ required: true, message: '请选择规格', trigger: ['blur'] }]">
<div class="acea-row">
<el-select v-model="formValidate.attributesTypeId">
<el-option v-for="item in ruleList" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
<el-button type="primary" class="mr20" @click="confirm">确认</el-button>
<!-- <el-button class="mr15" @click="addRule">添加规格</el-button> -->
</div>
</el-form-item>
<el-form-item>
<div v-for="(item, index) in formValidate.attr" :key="index">
<div class="acea-row row-middle">
<span class="mr5">{{ item.attributeName }}</span
><i class="el-icon-circle-close" @click="handleRemoveAttr(index)" />
</div>
<div class="rulesBox">
<el-tag
v-for="(j, indexn) in item.sku.value"
:key="indexn"
closable
size="medium"
:disable-transitions="false"
class="mb5 mr10"
@close="handleClose(item.sku.value, indexn, index)"
>
{{ j }}
</el-tag>
</div>
</div>
</el-form-item>
</el-col>
<!-- 批量设置-->
<el-col v-if="formValidate.attr.length > 0 && !isDisabled" :span="24" class="noForm">
<el-form-item label="批量设置:">
<el-table :data="oneFormBatch" border class="tabNumWidth" size="mini">
<el-table-column v-for="(item, iii) in attrValue" :key="iii" :label="item.label" align="center" min-width="120">
<template slot-scope="scope">
<el-input
:disabled="isDisabled"
maxlength="9"
min="0.01"
v-model="scope.row[item.value]"
class="priceBox"
@blur="keyupEvent(iii, scope.row[item.value], scope.$index, 3)"
/>
</template>
</el-table-column>
<el-table-column align="center" label="操作" min-width="80">
<template>
<el-button type="text" class="submission" @click="batchAdd">批量添加</el-button>
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-col>
<el-col :xl="24" :lg="24" :md="24" :sm="24" :xs="24">
<!-- 单规格表格-->
<!-- <el-form-item v-if="formValidate.specType === false">
<el-table :data="OneattrValue" border class="tabNumWidth" size="mini">
<el-table-column v-for="(item, iii) in attrValue" :key="iii" :label="item.label" align="center"
min-width="120">
<template slot-scope="scope">
<el-input :disabled="isDisabled" maxlength="9" min="0.01" v-model="scope.row[item.value]"
class="priceBox" @blur="keyupEvent(iii, scope.row[item.value], scope.$index, 3)" />
</template>
</el-table-column>
</el-table>
</el-form-item> -->
<!-- <el-form-item label="全部sku:" v-if="$route.params.id && showAll">
<el-button type="default" @click="showAllSku()" :disabled="isDisabled">展示</el-button>
</el-form-item> -->
<!-- 多规格表格-->
<el-form-item
v-if="formValidate.attr.length > 0"
label="商品属性:"
class="labeltop"
:class="isDisabled ? 'disLabel' : 'disLabelmoren'"
prop="attr"
:rules="[{ validator: validateAttr, trigger: ['change'] }]"
>
<!-- :rules="[{ validator: validateAttr, trigger: ['blur'] }]" -->
<el-table :data="ManyAttrValue" border class="tabNumWidth" size="mini">
<template v-if="manyTabDate">
<el-table-column v-for="item in manyTabDate" :key="item" align="center" :label="item" min-width="80">
<template slot-scope="scope">
<span class="priceBox" v-text="scope.row[item]" />
</template>
</el-table-column>
</template>
<el-table-column v-for="(item, iii) in attrValue" :key="iii" :label="item.label" align="center" min-width="120">
<template slot-scope="scope">
<el-input
:disabled="isDisabled"
maxlength="9"
min="0.01"
required
v-model="scope.row[item.value]"
class="priceBox"
@blur="keyupEvent(iii, scope.row[item.value], scope.$index, 3)"
/>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right">
<template slot-scope="scope">
<el-button type="text" @click="delAttrTable(scope.$index)">删除</el-button>
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-col>
</el-row>
<!-- 商品详情-->
<el-row v-show="currentTab === 1 && !isDisabled">
<el-col :span="24">
<el-form-item label="商品详情:">
<Tinymce v-model="formValidate.productDetail"></Tinymce>
</el-form-item>
</el-col>
</el-row>
<el-row v-show="currentTab === 1 && isDisabled">
<el-col :span="24">
<el-form-item label="商品详情:">
<span v-html="formValidate.productDetail || '无'"></span>
</el-form-item>
</el-col>
</el-row>
<!-- 其他设置-->
<el-row v-show="currentTab === 2">
<el-col :span="24">
<el-col v-bind="grid">
<el-form-item label="排序:">
<el-input-number v-model="formValidate.sort" :min="0" placeholder="请输入排序" :disabled="isDisabled" />
</el-form-item>
</el-col>
<el-col v-bind="grid">
<el-form-item label="积分:">
<el-input-number v-model="formValidate.giveIntegral" :min="0" placeholder="请输入排序" :disabled="isDisabled" />
</el-form-item>
</el-col>
<el-col v-bind="grid">
<el-form-item label="虚拟销量:">
<el-input-number v-model="formValidate.ficti" :min="0" placeholder="请输入排序" :disabled="isDisabled" />
</el-form-item>
</el-col>
</el-col>
<el-col :span="24">
<el-form-item label="商品推荐:">
<el-checkbox-group v-model="checkboxGroup" size="small" @change="onChangeGroup" :disabled="isDisabled">
<el-checkbox v-for="(item, index) in recommend" :key="index" :label="item.value">{{ item.name }}</el-checkbox>
</el-checkbox-group>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="活动优先级:">
<div class="color-list acea-row row-middle">
<div
:disabled="isDisabled"
class="color-item"
:class="activity[item]"
v-for="item in formValidate.activity"
:key="item"
draggable="true"
@dragstart="handleDragStart($event, item)"
@dragover.prevent="handleDragOver($event, item)"
@dragenter="handleDragEnterFont($event, item)"
@dragend="handleDragEnd($event, item)"
>
{{ item }}
</div>
<div class="tip">可拖动按钮调整活动的优先展示顺序</div>
</div>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="优惠券:" class="proCoupon">
<div class="acea-row">
<el-tag
v-for="(tag, index) in formValidate.coupons"
:key="index"
class="mr10 mb10"
:closable="!isDisabled"
:disable-transitions="false"
@close="handleCloseCoupon(tag)"
>
{{ tag.name }}
</el-tag>
<!-- <span v-if="formValidate.couponIds == null">无</span> -->
<el-button v-if="!isDisabled" class="mr15" @click="addCoupon">选择优惠券</el-button>
</div>
</el-form-item>
</el-col>
</el-row>
<el-form-item>
<el-button v-show="currentTab > 0" class="submission priamry_border" @click="handleSubmitUp">上一步</el-button>
<el-button v-show="currentTab < 1" type="primary" class="submission" @click="handleSubmitNest('formValidate')">下一步</el-button>
<el-button
v-show="(currentTab === 1 || $route.params.id) && !isDisabled"
type="primary"
class="submission"
@click="handleSubmit('formValidate')"
>提交</el-button
>
</el-form-item>
</el-form>
</el-card>
<CreatTemplates ref="addTemplates" @getList="getShippingList" />
<el-dialog width="80%" title="选择油站" :visible.sync="isOilStationSelection">
<OilStationSelection
:product-id="this.$route.query.id"
ref="selectSites"
:OilStationSelectionList="OilStationSelectionList"
@submit="oilStationSelectionSubmit"
>
</OilStationSelection>
</el-dialog>
</div>
</template>
<script>
import productApi from '@/api/product/productAttr.js'
import Tinymce from '@/components/Tinymce/index'
import CreatTemplates from '@/views/systemSetting/logistics/shippingTemplates/creatTemplates'
import Templates from '../../appSetting/wxAccount/wxTemplate/index'
import { Debounce } from '@/utils/validate'
import CustomUpload from './components/CustomUpload.vue'
import OilStationSelection from './components/OilStationSelection.vue'
import { loadingFn } from '@/utils/validate'
const defaultObj = {
image: '',
sliderImages: [],
videoLink: '',
sliderImage: '',
storeName: '',
storeInfo: '',
keyword: '',
cateIds: [], // 商品分类id
cateId: null, // 商品分类id传值
unitName: '',
sort: 0,
giveIntegral: 0,
ficti: 0,
isShow: false,
isBenefit: false,
isNew: false,
isGood: false,
isHot: false,
isBest: false,
tempId: '',
attrValue: [
{
image: '',
price: 0,
cost: 0,
otPrice: 0,
stock: 0,
barCode: '',
weight: 0,
volume: 0
}
],
attr: [],
selectRule: '',
isSub: false,
content: '',
specType: false,
id: 0,
couponIds: [],
coupons: [],
activity: ['默认', '秒杀', '砍价', '拼团']
}
const objTitle = {
price: {
title: '市场价格'
},
cost: {
title: '销售价格'
},
otPrice: {
title: '商品库存'
},
stock: {
title: 'SKU编号'
},
barCode: {
title: '兑换积分'
}
}
export default {
name: 'ProductProductAdd',
components: { Templates, CreatTemplates, Tinymce, CustomUpload, OilStationSelection },
data() {
const validateSiteIds = (rule, value, callback) => {
let siteIds = this.OilStationSelectionList.map(item => item.siteId)
if (siteIds.length == 0) {
callback('请选择油站')
}
callback()
}
const validateAttr = (rule, value, callback) => {
// SKU编号,即"skuNum",不需要手填,提交后会自动生成,因此此处略过校验
let length = this.attrValue.length - 1
let isCan = this.ManyAttrValue.every(item => {
// 此处返回已填的值 通过长度来判断是否都填了
let _length = this.attrValue.filter(_item => {
let key = _item.value
if (key != 'skuNum' && item[key]) return _item
}).length
return length != _length
})
if (isCan) callback('商品属性不可存在空')
callback()
}
return {
validateSiteIds,
validateAttr,
loading: false,
OilStationSelectionList: [],
isOilStationSelection: false,
brandOptions: [],
isDisabled: this.$route.params.isDisabled === '1' ? true : false,
activity: { 默认: 'red', 秒杀: 'blue', 砍价: 'green', 拼团: 'yellow' },
props2: {
children: 'children',
label: 'categoryName',
value: 'id'
},
checkboxGroup: [],
recommend: [],
tabs: [],
fullscreenLoading: false,
props: { multiple: true },
active: 0,
OneattrValue: [Object.assign({}, defaultObj.attrValue[0])], // 单规格
ManyAttrValue: [Object.assign({}, defaultObj.attrValue[0])], // 多规格
ruleList: [],
merCateList: [], // 商户分类筛选
shippingList: [], // 运费模板
formThead: Object.assign({}, objTitle),
formValidate: {
recommendOrNewMark: '',
productStatus: '1',
attr: [],
productDetail: ''
},
formDynamics: {
ruleName: '',
ruleValue: []
},
tempData: {
page: 1,
limit: 9999
},
manyTabTit: {},
manyTabDate: {},
grid2: {
xl: 12,
lg: 12,
md: 12,
sm: 24,
xs: 24
},
// 规格数据
formDynamic: {
attrsName: '',
attrsVal: ''
},
isBtn: false,
manyFormValidate: [],
currentTab: 0,
isChoice: '',
grid: {
xl: 8,
lg: 8,
md: 12,
sm: 24,
xs: 24
},
ruleValidate: {
// storeName: [
// { required: true, message: '请输入商品名称', trigger: 'blur' }
// ],
// cateIds: [
// { required: true, message: '请选择商品分类', trigger: 'change', type: 'array', min: '1' }
// ],
// keyword: [
// { required: true, message: '请输入商品关键字', trigger: 'blur' }
// ],
// unitName: [
// { required: true, message: '请输入单位', trigger: 'blur' }
// ],
// storeInfo: [
// { required: true, message: '请输入商品简介', trigger: 'blur' }
// ],
// tempId: [
// { required: true, message: '请选择运费模板', trigger: 'change' }
// ],
// image: [
// { required: true, message: '请上传商品图', trigger: 'change' }
// ],
// sliderImages: [
// { required: true, message: '请上传商品轮播图', type: 'array', trigger: 'change' }
// ],
// specType: [
// { required: true, message: '请选择商品规格', trigger: 'change' }
// ]
},
attrInfo: {},
tableFrom: {
page: 1,
limit: 9999,
keywords: ''
},
tempRoute: {},
keyNum: 0,
isAttr: false,
showAll: false,
videoLink: '',
attrValue: [
{
label: '市场价格',
name: '市场价格',
value: 'marketPrice'
},
{
label: '销售价格',
name: '销售价格',
value: 'sellPrice'
},
{
label: '商品库存',
name: '商品库存',
value: 'stock'
},
{
label: 'SKU编号',
name: 'SKU编号',
value: 'skuNum'
},
{
label: '兑换积分',
name: '兑换积分',
value: 'integral'
}
]
}
},
computed: {
oneFormBatch() {
const obj = [Object.assign({}, defaultObj.attrValue[0])]
delete obj[0].barCode
return obj
}
},
watch: {
$route(to, from) {
if (from.path == '/productList' && to.params.id) {
this.chenkId()
}
// console.log(from.path) //从哪来
// console.log(to.path, to.params) //到哪去
},
// 'formValidate.content': function(n) {},
// ManyAttrValue(n) {},
'formValidate.attr': {
handler: function(val, o) {
if (this.isAttr) this.watCh(val, o) //重要!!!
},
immediate: false,
deep: true
}
},
async created() {
await this.chenkId()
await this.getCategorySelect()
await this.productGetRule()
await this.brandGetAll()
},
mounted() {},
deactivated() {
this.$destroy()
},
methods: {
async chenkId() {
if (this.$route.query && this.$route.query.id) {
await this.getproductInfo(this.$route.query.id)
}
},
productAddGetSites(ids) {
Promise.all(
ids.map(id => {
return productApi.productAddGetSites(id)
})
).then(res => {
// console.log(res, 'productAddGetSites')
})
},
async inverseAnalysis(data) {
let { categoryOneId, categoryTwoId } = data
let categorys = [categoryOneId, categoryTwoId]
this.OilStationSelectionList = data.siteInfos
this.formValidate = {
...this.formValidate,
categorys,
...data
}
// Object.assign(this.formValidate, {
// categorys,
// ...data
// })
this.$refs.CustomUpload.fileList = [...this.formValidate.images.filter(item => item.mainMark == '1')]
this.$refs.CustomLBUpload.fileList = [...this.formValidate.images.filter(item => item.mainMark != '1')]
this.formValidate.recommendOrNewMark = data.newMark == '1' ? '1' : '2'
await this.confirm()
this.$nextTick(() => {
this.formValidate.attr = this.formValidate.attr
.map(item => {
let align = this.formValidate.checkedList.find(i => item.id == i.attributeId)
if (align) {
return {
...item,
sku: {
...item.sku,
value: align.checked.split(',')
}
}
} else {
return null
}
})
.filter(item => item)
setTimeout(() => {
this.ManyAttrValue.forEach((item, index) => {
let data = this.formValidate.stockList.find(i => i.attributeJson == JSON.stringify(item.data))
if (data) {
Object.assign(item, data, { delect: false })
} else {
Object.assign(item, data, { delect: true })
}
})
this.ManyAttrValue = this.ManyAttrValue.filter(item => !item.delect)
}, 1000)
})
},
async getproductInfo(id) {
await productApi.productAddGetEdit(id).then(async res => {
if (res.code == 20000) {
await this.inverseAnalysis(res.data)
}
})
},
setPreferred(setPreferred) {
// console.log(setPreferred, 'setPreferred')
},
delectOilStationSelectionList(e, index) {
this.OilStationSelectionList.splice(index, 1)
if (this.$refs.selectSites && this.$refs.selectSites.checkedSites) {
this.$refs.selectSites.checkedSites = this.$refs.selectSites.checkedSites.filter(site => e.siteId !== site.siteId)
}
},
oilStationSelectionSubmit(e) {
this.OilStationSelectionList = e
this.isOilStationSelection = false
this.formValidate.siteIds = e.map(item => item.siteId)
},
async brandGetAll() {
await productApi.brandGetAll().then(res => {
if (res.code == 20000) {
this.brandOptions = res.data
}
})
},
cascaderChange(e) {
// console.log(e, 'cascaderChange')
},
// 校验输入框不能输入0,保留2位小数,库存为正整数
keyupEvent(key, val, index, num) {
if (key === 'barCode') return
var re = /^\D*([0-9]\d*\.?\d{0,2})?.*$/
switch (num) {
case 1:
if (val == 0) {
this.oneFormBatch[index][key] = key === 'stock' ? 0 : 0.01
} else {
this.oneFormBatch[index][key] =
key === 'stock' ? parseInt(val) : this.$set(this.oneFormBatch[index], key, val.toString().replace(re, '$1'))
}
break
case 2:
if (val == 0) {
this.OneattrValue[index][key] = key === 'stock' ? 0 : 0.01
} else {
this.OneattrValue[index][key] =
key === 'stock' ? parseInt(val) : this.$set(this.OneattrValue[index], key, val.toString().replace(re, '$1'))
}
break
default:
if (val == 0) {
this.ManyAttrValue[index][key] = key === 'stock' ? 0 : 0.01
} else {
this.ManyAttrValue[index][key] =
key === 'stock' ? parseInt(val) : this.$set(this.ManyAttrValue[index], key, val.toString().replace(re, '$1'))
}
break
}
},
handleCloseCoupon(tag) {
this.isAttr = true
this.formValidate.coupons.splice(this.formValidate.coupons.indexOf(tag), 1)
this.formValidate.couponIds.splice(this.formValidate.couponIds.indexOf(tag.id), 1)
},
addCoupon() {
const _this = this
this.$modalCoupon(
'wu',
(this.keyNum += 1),
this.formValidate.coupons,
function(row) {
_this.formValidate.couponIds = []
_this.formValidate.coupons = row
row.map(item => {
_this.formValidate.couponIds.push(item.id)
})
},
''
)
},
setTagsViewTitle() {
const title = this.isDisabled ? '商品详情' : '编辑商品'
const route = Object.assign({}, this.tempRoute, { title: `${title}-${this.$route.query.id}` })
this.$store.dispatch('tagsView/updateVisitedView', route)
},
onChangeGroup() {
this.checkboxGroup.includes('isGood') ? (this.formValidate.isGood = true) : (this.formValidate.isGood = false)
this.checkboxGroup.includes('isBenefit') ? (this.formValidate.isBenefit = true) : (this.formValidate.isBenefit = false)
this.checkboxGroup.includes('isBest') ? (this.formValidate.isBest = true) : (this.formValidate.isBest = false)
this.checkboxGroup.includes('isNew') ? (this.formValidate.isNew = true) : (this.formValidate.isNew = false)
this.checkboxGroup.includes('isHot') ? (this.formValidate.isHot = true) : (this.formValidate.isHot = false)
},
// sku算法
watCh(val, o) {
let arr = []
this.manyTabDate = []
for (let i = 0; i < val.length; i++) {
arr.push(val[i].sku)
this.manyTabDate.push(val[i].sku.name)
}
console.log('this.manyTabDate', this.manyTabDate)
// console.log('arr', arr)
this.ManyAttrValue = arr.reduce(
(prev, cur) => {
let res = []
prev.map(item => {
cur.value.map(_item => {
res.push({
...item,
[cur.name]: _item,
data: Object.assign({}, item.data || {}, { [cur.name]: _item }),
...Object.fromEntries(
this.attrValue.map(item => {
return [item.value, '']
})
)
})
})
})
return res
},
[{}]
)
console.log(this.ManyAttrValue, 'this.ManyAttrValue ')
},
attrFormat(arr) {
let data = []
const res = []
return format(arr)
function format(arr) {
if (arr.length > 1) {
arr.forEach((v, i) => {
if (i === 0) data = arr[i]['attrValue']
const tmp = []
if (!data) return
data.forEach(function(vv) {
arr[i + 1] &&
arr[i + 1]['attrValue'] &&
arr[i + 1]['attrValue'].forEach(g => {
const rep2 = (i !== 0 ? '' : arr[i]['attrName'] + '_') + vv + '$&' + arr[i + 1]['attrName'] + '_' + g
tmp.push(rep2)
if (i === arr.length - 2) {
const rep4 = {
image: '',
price: 0,
cost: 0,
otPrice: 0,
stock: 0,
barCode: '',
weight: 0,
volume: 0,
brokerage: 0,
brokerage_two: 0
}
rep2.split('$&').forEach((h, k) => {
const rep3 = h.split('_')
if (!rep4['attrValue']) rep4['attrValue'] = {}
rep4['attrValue'][rep3[0]] = rep3.length > 1 ? rep3[1] : ''
})
for (let attrValueKey in rep4.attrValue) {
rep4[attrValueKey] = rep4.attrValue[attrValueKey]
}
res.push(rep4)
}
})
})
data = tmp.length ? tmp : []
})
} else {
const dataArr = []
arr.forEach((v, k) => {
v['attrValue'].forEach((vv, kk) => {
dataArr[kk] = v['attrName'] + '_' + vv
res[kk] = {
image: '',
price: 0,
cost: 0,
otPrice: 0,
stock: 0,
barCode: '',
weight: 0,
volume: 0,
brokerage: 0,
brokerage_two: 0,
attrValue: { [v['attrName']]: vv }
}
// Object.values(res[kk].attrValue).forEach((v, i) => {
// res[kk]['value' + i] = v
// })
for (let attrValueKey in res[kk].attrValue) {
res[kk][attrValueKey] = res[kk].attrValue[attrValueKey]
}
})
})
data.push(dataArr.join('$&'))
}
return res
}
},
// 运费模板
addTem() {
this.$refs.addTemplates.dialogVisible = true
this.$refs.addTemplates.getCityList()
},
// 添加规则;
addRule() {
const _this = this
this.$modalAttr(this.formDynamics, function() {
_this.productGetRule()
})
},
// 选择规格
onChangeSpec(num) {
this.isAttr = true
if (num) this.productGetRule()
},
// 选择属性确认
async confirm(is = true) {
this.isAttr = true
if (is) {
if (!this.formValidate.attributesTypeId) {
return this.$message.warning('请选择属性')
}
await this.productGetRule()
this.formValidate.attr = JSON.parse(JSON.stringify(this.ruleList.find(item => item.id == this.formValidate.attributesTypeId).attributesList))
// console.log('this.formValidate.attr ', this.formValidate.attr)
}
// console.log('this.attrValue', this.attrValue)
},
// 商品分类;
async getCategorySelect() {
await productApi.getClassificationTree().then(res => {
if (res.code == 20000) {
this.merCateList = res.data
}
})
},
filerMerCateList(treeData) {
return treeData.map(item => {
if (!item.child) {
item.disabled = true
}
item.label = item.name
return item
})
},
// 获取商品属性模板;
productGetRule() {
return new Promise((re, rj) => {
productApi.getAllAttributesType().then(res => {
if (res.code == 20000) {
this.ruleList = res.data.map(item => {
return {
...item,
attributesList: item.attributesList.map(citem => {
return {
...citem,
sku: { name: citem.attributeName, value: citem.attributeContent.split(',') }
}
})
}
})
re(this.ruleList)
}
})
})
},
// 运费模板;
getShippingList() {
shippingTemplatesList(this.tempData).then(res => {
this.shippingList = res.list
})
},
showInput(item) {
this.$set(item, 'inputVisible', true)
},
onChangetype(item) {
if (item === 1) {
this.OneattrValue.map(item => {
this.$set(item, 'brokerage', null)
this.$set(item, 'brokerageTwo', null)
})
this.ManyAttrValue.map(item => {
this.$set(item, 'brokerage', null)
this.$set(item, 'brokerageTwo', null)
})
} else {
this.OneattrValue.map(item => {
delete item.brokerage
delete item.brokerageTwo
this.$set(item, 'brokerage', null)
this.$set(item, 'brokerageTwo', null)
})
this.ManyAttrValue.map(item => {
delete item.brokerage
delete item.brokerageTwo
})
}
},
// 删除表格中的属性
delAttrTable(index) {
this.ManyAttrValue.splice(index, 1)
},
// 批量添加
batchAdd() {
// if (!this.oneFormBatch[0].pic || !this.oneFormBatch[0].price || !this.oneFormBatch[0].cost || !this.oneFormBatch[0].ot_price ||
// !this.oneFormBatch[0].stock || !this.oneFormBatch[0].bar_code) return this.$Message.warning('请填写完整的批量设置内容!');
// console.log(this.ManyAttrValue, this.oneFormBatch, ' this.ManyAttrValue')
this.ManyAttrValue.forEach(item => {
Object.assign(item, this.oneFormBatch[0])
})
},
// 添加按钮
addBtn() {
this.clearAttr()
this.isBtn = true
},
// 取消
offAttrName() {
this.isBtn = false
},
clearAttr() {
this.isAttr = true
this.formDynamic.attrsName = ''
this.formDynamic.attrsVal = ''
},
// 删除规格
handleRemoveAttr(index) {
this.isAttr = true
this.formValidate.attr.splice(index, 1)
this.manyFormValidate.splice(index, 1)
},
// 删除属性
handleClose(item, index, parentIndex) {
if (item.length == 1) {
this.handleRemoveAttr(parentIndex)
} else {
item.splice(index, 1)
}
},
// 添加规则名称
createAttrName() {
this.isAttr = true
if (this.formDynamic.attrsName && this.formDynamic.attrsVal) {
const data = {
attrName: this.formDynamic.attrsName,
attrValue: [this.formDynamic.attrsVal]
}
this.formValidate.attr.push(data)
var hash = {}
this.formValidate.attr = this.formValidate.attr.reduce(function(item, next) {
/* eslint-disable */
hash[next.attrName] ? '' : (hash[next.attrName] = true && item.push(next))
return item
}, [])
this.clearAttr()
this.isBtn = false
} else {
this.$Message.warning('请添加完整的规格!')
}
},
// 添加属性
createAttr(num, idx) {
this.isAttr = true
if (num) {
this.formValidate.attr[idx].attrValue.push(num)
var hash = {}
this.formValidate.attr[idx].attrValue = this.formValidate.attr[idx].attrValue.reduce(function(item, next) {
/* eslint-disable */
hash[next] ? '' : (hash[next] = true && item.push(next))
return item
}, [])
this.formValidate.attr[idx].inputVisible = false
} else {
this.$message.warning('请添加属性')
}
},
//点击展示所有多规格属性
showAllSku() {
if (this.isAttr == false) {
this.isAttr = true
if (this.formValidate.specType && this.isAttr) this.watCh(this.formValidate.attr) //重要!!!
} else if (this.isAttr == true) {
this.isAttr = false
this.getInfo()
}
},
// 详情
getInfo() {
this.fullscreenLoading = true
productDetailApi(this.$route.query.id)
.then(async res => {
// this.isAttr = true;
let info = res
this.formValidate = {
image: this.$selfUtil.setDomain(info.image),
sliderImage: info.sliderImage,
sliderImages: JSON.parse(info.sliderImage),
storeName: info.storeName,
storeInfo: info.storeInfo,
keyword: info.keyword,
cateIds: info.cateId.split(','), // 商品分类id
cateId: info.cateId, // 商品分类id传值
unitName: info.unitName,
sort: info.sort,
isShow: info.isShow,
isBenefit: info.isBenefit,
isNew: info.isNew,
isGood: info.isGood,
isHot: info.isHot,
isBest: info.isBest,
tempId: info.tempId,
attr: info.attr,
attrValue: info.attrValue,
selectRule: info.selectRule,
isSub: info.isSub,
content: this.$selfUtil.replaceImgSrcHttps(info.content),
specType: info.specType,
id: info.id,
giveIntegral: info.giveIntegral,
ficti: info.ficti,
coupons: info.coupons,
couponIds: info.couponIds,
activity: info.activityStr ? info.activityStr.split(',') : ['默认', '秒杀', '砍价', '拼团']
}
marketingSendApi({ type: 3 }).then(res => {
if (this.formValidate.couponIds !== null) {
let ids = this.formValidate.couponIds.toString()
let arr = res.list
let obj = {}
for (let i in arr) {
obj[arr[i].id] = arr[i]
}
let strArr = ids.split(',')
let newArr = []
for (let item of strArr) {
if (obj[item]) {
newArr.push(obj[item])
}
}
this.$set(this.formValidate, 'coupons', newArr) //在编辑回显时,让返回数据中的优惠券id,通过接口匹配显示,
}
})
let imgs = JSON.parse(info.sliderImage)
let imgss = []
Object.keys(imgs).map(i => {
imgss.push(this.$selfUtil.setDomain(imgs[i]))
})
this.formValidate.sliderImages = [...imgss]
if (info.isHot) this.checkboxGroup.push('isHot')
if (info.isGood) this.checkboxGroup.push('isGood')
if (info.isBenefit) this.checkboxGroup.push('isBenefit')
if (info.isBest) this.checkboxGroup.push('isBest')
if (info.isNew) this.checkboxGroup.push('isNew')
this.productGetRule()
if (info.specType) {
this.formValidate.attr = info.attr.map(item => {
return {
attrName: item.attrName,
attrValue: item.attrValues.split(',')
}
})
this.ManyAttrValue = info.attrValue
this.ManyAttrValue.forEach(val => {
val.image = this.$selfUtil.setDomain(val.image)
val.attrValue = JSON.parse(val.attrValue)
this.attrInfo[
Object.values(val.attrValue)
.sort()
.join('/')
] = val
})
/***多规格商品如果被删除过sku,优先展示api返回的数据,否则会有没有删除的错觉***/
let manyAttr = this.attrFormat(this.formValidate.attr)
if (manyAttr.length !== this.ManyAttrValue.length) {
this.$set(this, 'showAll', true)
this.isAttr = false
} else {
this.isAttr = true
}
/*******/
const tmp = {}
const tmpTab = {}
this.formValidate.attr.forEach((o, i) => {
// tmp['value' + i] = { title: o.attrName }
// tmpTab['value' + i] = ''
tmp[o.attrName] = { title: o.attrName }
tmpTab[o.attrName] = ''
})
// 此处手动实现后台原本value0 value1的逻辑
this.formValidate.attrValue.forEach(item => {
for (let attrValueKey in item.attrValue) {
item[attrValueKey] = item.attrValue[attrValueKey]
}
})
this.manyTabTit = tmp
this.manyTabDate = tmpTab
this.formThead = Object.assign({}, this.formThead, tmp)
} else {
this.OneattrValue = info.attrValue
// this.formValidate.attr = [] //单规格商品规格设置为空
}
this.fullscreenLoading = false
})
.catch(res => {
this.fullscreenLoading = false
this.$message.error(res.message)
})
},
handleRemove(i) {
this.formValidate.sliderImages.splice(i, 1)
},
// 点击商品图
modalPicTap(tit, num, i, status) {
const _this = this
if (_this.isDisabled) return
this.$modalUpload(
function(img) {
if (tit === '1' && !num) {
_this.formValidate.image = img[0].sattDir
_this.OneattrValue[0].image = img[0].sattDir
}
if (tit === '2' && !num) {
if (img.length > 10) return this.$message.warning('最多选择10张图片!')
if (img.length + _this.formValidate.sliderImages.length > 10) return this.$message.warning('最多选择10张图片!')
img.map(item => {
_this.formValidate.sliderImages.push(item.sattDir)
})
}
if (tit === '1' && num === 'dan') {
_this.OneattrValue[0].image = img[0].sattDir
}
if (tit === '1' && num === 'duo') {
_this.ManyAttrValue[i].image = img[0].sattDir
}
if (tit === '1' && num === 'pi') {
_this.oneFormBatch[0].image = img[0].sattDir
}
},
tit,
'content'
)
},
handleSubmitUp() {
// this.currentTab --
if (this.currentTab-- < 0) this.currentTab = 0
},
handleSubmitNest(name) {
// console.log(this.formValidate, 'handleSubmitNest')
if (this.formValidate.attr < 1) {
this.$message.error('规格属性不能为空')
return
}
this.$refs[name].validate(valid => {
if (valid) {
if (this.currentTab++ > 2) this.currentTab = 0
} else {
// if (
// !this.formValidate.store_name ||
// !this.formValidate.cate_id ||
// !this.formValidate.keyword ||
// !this.formValidate.unit_name ||
// !this.formValidate.store_info ||
// !this.formValidate.image ||
// !this.formValidate.slider_image
// ) {
// this.$message.warning('请填写完整商品信息!')
// }
}
})
},
// 提交
handleSubmit: Debounce(function(name) {
let cover = this.$refs.CustomUpload.getFileList()
let Carousel = this.$refs.CustomLBUpload.getFileList()
cover.length && (cover[0]['mainMark'] = 1)
let [categoryOneId, categoryTwoId] = this.formValidate.categorys
let isRecommendOrNewMark = this.formValidate.recommendOrNewMark == '1' ? 'newMark' : 'recommend'
let siteIds = this.OilStationSelectionList.map(item => item.siteId)
// if (siteIds.length == 0) {
// this.$message.error('请选择油站')
// return
// }
let checkedList = this.formValidate.attr.map(item => {
let attributeId = item.id
let checked = item.sku.value.join(',')
return { attributeId, checked }
})
let images = cover.concat(Carousel).map((item, index) => {
let { name, url, mainMark = '' } = item
return {
name,
url,
mainMark
}
})
let stockList = this.ManyAttrValue.map(item => {
let { marketPrice = '', sellPrice = '', stock = '', integral = '', skuNum = '', id = '' } = item
return {
attributeJson: JSON.stringify(item.data),
marketPrice,
sellPrice,
stock,
integral,
skuNum,
id
}
})
this.formValidate[isRecommendOrNewMark] = '1'
loadingFn.call(
this,
'loading',
productApi[this.$route.query.id ? 'addUpdate' : 'addSave'](
Object.assign(this.formValidate, {
categoryOneId,
categoryTwoId,
siteIds,
checkedList,
images,
stockList
})
).then(res => {
if (res.code == 20000) {
this.$message.success('操作成功')
setTimeout(() => {
this.$bus.$emit('productRefresh')
this.$router.push({ path: 'productList', query: { refresh: true } })
// this.$destroy()
}, 1000)
}
})
)
// this.onChangeGroup()
// if (this.formValidate.specType && this.formValidate.attr.length < 1) return this.$message.warning("请填写多规格属性!");
// this.formValidate.cateId = this.formValidate.cateIds.join(',')
// this.formValidate.sliderImage = JSON.stringify(this.formValidate.sliderImages)
// if (this.formValidate.specType) {
// this.formValidate.attrValue = this.ManyAttrValue;
// this.formValidate.attr = this.formValidate.attr.map((item) => {
// return {
// attrName: item.attrName,
// id: item.id,
// attrValues: item.attrValue.join(','),
// }
// })
// for (var i = 0; i < this.formValidate.attrValue.length; i++) {
// this.$set(this.formValidate.attrValue[i], 'id', 0);
// this.$set(this.formValidate.attrValue[i], 'productId', 0);
// this.$set(this.formValidate.attrValue[i], 'attrValue', JSON.stringify(this.formValidate.attrValue[i].attrValue)); //
// delete this.formValidate.attrValue[i].value0
// }
// } else {
// this.formValidate.attr = [{ attrName: '规格', attrValues: '默认', id: this.$route.params.id ? this.formValidate.attr[0].id : 0 }]
// this.OneattrValue.map(item => {
// this.$set(item, 'attrValue', JSON.stringify({ '规格': '默认' }))
// })
// this.formValidate.attrValue = this.OneattrValue
// }
// this.$refs[name].validate((valid) => {
// if (valid) {
// this.fullscreenLoading = true
// this.$route.params.id ? productUpdateApi(this.formValidate).then(async res => {
// this.$message.success('编辑成功');
// setTimeout(() => {
// this.$router.push({ path: '/store/index' });
// }, 500);
// this.fullscreenLoading = false
// }).catch(res => {
// this.fullscreenLoading = false
// }) : productCreateApi(this.formValidate).then(async res => {
// this.$message.success('新增成功');
// setTimeout(() => {
// this.$router.push({ path: '/store/index' });
// }, 500);
// this.fullscreenLoading = false
// }).catch(res => {
// this.fullscreenLoading = false
// })
// } else {
// if (!this.formValidate.storeName || !this.formValidate.cateId || !this.formValidate.keyword
// || !this.formValidate.unitName || !this.formValidate.storeInfo || !this.formValidate.image || !this.formValidate.sliderImages) {
// this.$message.warning("请填写完整商品信息!");
// }
// }
// });
}),
// 表单验证
validate(prop, status, error) {
if (status === false) {
this.$message.warning(error)
}
},
// 移动
handleDragStart(e, item) {
if (!this.isDisabled) this.dragging = item
},
handleDragEnd(e, item) {
if (!this.isDisabled) this.dragging = null
},
handleDragOver(e) {
if (!this.isDisabled) e.dataTransfer.dropEffect = 'move'
},
handleDragEnter(e, item) {
if (!this.isDisabled) {
e.dataTransfer.effectAllowed = 'move'
if (item === this.dragging) {
return
}
const newItems = [...this.formValidate.sliderImages]
const src = newItems.indexOf(this.dragging)
const dst = newItems.indexOf(item)
newItems.splice(dst, 0, ...newItems.splice(src, 1))
this.formValidate.sliderImages = newItems
}
},
handleDragEnterFont(e, item) {
if (!this.isDisabled) {
e.dataTransfer.effectAllowed = 'move'
if (item === this.dragging) {
return
}
const newItems = [...this.formValidate.activity]
const src = newItems.indexOf(this.dragging)
const dst = newItems.indexOf(item)
newItems.splice(dst, 0, ...newItems.splice(src, 1))
this.formValidate.activity = newItems
}
},
getGoodsType() {
/** 让商品推荐列表的name属性与页面设置tab的name匹配**/
goodDesignList({ gid: 70 }).then(response => {
let list = response.list
let arr = [],
arr1 = []
const listArr = [{ name: '是否热卖', value: 'isGood' }]
let typeLists = [
{ name: '', value: 'isHot', type: '2' }, //热门榜单
{ name: '', value: 'isBenefit', type: '4' }, //促销单品
{ name: '', value: 'isBest', type: '1' }, //精品推荐
{ name: '', value: 'isNew', type: '3' }
] //首发新品
list.forEach(item => {
let obj = {}
obj.value = JSON.parse(item.value)
obj.id = item.id
obj.gid = item.gid
obj.status = item.status
arr.push(obj)
})
arr.forEach(item1 => {
let obj1 = {}
obj1.name = item1.value.fields[1].value
obj1.status = item1.status
obj1.type = item1.value.fields[3].value
arr1.push(obj1)
})
typeLists.forEach(item => {
arr1.forEach(item1 => {
if (item.type == item1.type) {
listArr.push({
name: item1.name,
value: item.value,
type: item.type
})
}
})
})
this.recommend = listArr
})
}
}
}
</script>
<style scoped lang="scss">
.disLabel {
::v-deep.el-form-item__label {
margin-left: 36px !important;
}
}
.disLabelmoren {
::v-deep.el-form-item__label {
margin-left: 120px !important;
}
}
.priamry_border {
border: 1px solid #1890ff;
color: #1890ff;
}
.color-item {
height: 30px;
line-height: 30px;
padding: 0 10px;
color: #fff;
margin-right: 10px;
}
.color-list .color-item.blue {
background-color: #1e9fff;
}
.color-list .color-item.yellow {
background-color: rgb(254, 185, 0);
}
.color-list .color-item.green {
background-color: #009688;
}
.color-list .color-item.red {
background-color: #ed4014;
}
.proCoupon {
::v-deep.el-form-item__content {
margin-top: 5px;
}
}
.tabPic {
width: 40px !important;
height: 40px !important;
img {
width: 100%;
height: 100%;
}
}
.noLeft {
::v-deep.el-form-item__content {
margin-left: 0 !important;
}
}
.tabNumWidth {
::v-deep.el-input-number--medium {
width: 121px !important;
}
::v-deep.el-input-number__increase {
width: 20px !important;
font-size: 12px !important;
}
::v-deep.el-input-number__decrease {
width: 20px !important;
font-size: 12px !important;
}
::v-deep.el-input-number--medium .el-input__inner {
padding-left: 25px !important;
padding-right: 25px !important;
}
::v-deep thead {
line-height: normal !important;
}
::v-deep .el-table .cell {
line-height: normal !important;
}
}
.selWidth {
width: 100%;
}
.selWidthd {
width: 300px;
}
.button-new-tag {
height: 28px;
line-height: 26px;
padding-top: 0;
padding-bottom: 0;
}
.input-new-tag {
width: 90px;
margin-left: 10px;
vertical-align: bottom;
}
.pictrue {
width: 60px;
height: 60px;
border: 1px dotted rgba(0, 0, 0, 0.1);
margin-right: 10px;
position: relative;
cursor: pointer;
img {
width: 100%;
height: 100%;
}
video {
width: 100%;
height: 100%;
}
}
.btndel {
position: absolute;
z-index: 1;
width: 20px !important;
height: 20px !important;
left: 46px;
top: -4px;
}
.labeltop {
::v-deep.el-form-item__label {
float: none !important;
display: inline-block !important;
width: auto !important;
}
}
.iview-video-style {
width: 300px;
height: 180px;
border-radius: 10px;
background-color: #707070;
margin: 0 120px 20px;
position: relative;
overflow: hidden;
}
.iview-video-style .iconv {
color: #fff;
line-height: 180px;
width: 50px;
height: 50px;
display: inherit;
font-size: 26px;
position: absolute;
top: -74px;
left: 50%;
margin-left: -25px;
}
.iview-video-style .mark {
position: absolute;
width: 100%;
height: 30px;
top: 0;
background-color: rgba(0, 0, 0, 0.5);
text-align: center;
}
</style>