<template> <div class="goods-all"> <!-- 选择商品类目 start --> <el-card class="good-all-type" v-if="!isShowGoodsDetails"> <div slot="header" class="clearfix"> <p class="card-header-title"><span class="blue-block-goods"></span>确认商品所在目录</p> </div> <div> <div> <p class="goods-type-tip">为商品设置正确的类目,能让商品快速的被搜索到</p> </div> <div class="goods-type-options" v-loading="loading"> <el-cascader-panel v-model="SSQList" :props='props' @change="SSQChange" ref="ssqCascader"></el-cascader-panel> </div> <el-button type="primary" class="next-step" :disabled="isNextStep" @click="nextStep">下一步</el-button> </div> </el-card> <!-- 选择商品类目 end --> <!-- 添加商品 start --> <el-card class="box-card good-details-body" v-if="isShowGoodsDetails"> <div class="floor-nav" id="floorNavList"> <ul class="nav-list"> <li class="nav-list-item" :class="{'floor-item-active': isFIActive === index}" v-for="(item, index) in floorNav" :key="item.id" @click="setFloorNavMountClick(index)">{{ item.name }}</li> </ul> </div> <div class="floor-cont" ref="scrollview"> <!-- 商品信息 --> <div class="floor-item"> <div class="floor-item-box"> <p class="card-header-title floor-item-box-title"><span class="blue-block-goods blue-block-goods-title"></span>商品信息</p> <Goodsinfomation ref="goodsInfo" :goodsinfodata='goodsinfodata'/> </div> </div> <!-- 商品规格 --> <div class="floor-item"> <div class="floor-item-box"> <p class="card-header-title floor-item-box-title"><span class="blue-block-goods blue-block-goods-title"></span>商品规格</p> <GoodsSpecifications ref="goodsspecifications" :specificationsdata="specificationsdata" @calcSpeTable="calcSpeTable"/> </div> </div> <!-- 商品售价 --> <div class="floor-item"> <div class="floor-item-box"> <p class="card-header-title floor-item-box-title"><span class="blue-block-goods blue-block-goods-title"></span>商品售价</p> <GoodsParameter ref="goodsparameter" :parameterdata="parameterdata" /> </div> </div> <div class="floor-item"> <div class="floor-item-box"> <p class="card-header-title floor-item-box-title"><span class="blue-block-goods blue-block-goods-title"></span>商品详情</p> <Goodsimg ref="goodsdetailsimg" :imgdata="imgdata"/> </div> </div> <!-- 售后及服务 --> <div class="floor-item"> <div class="floor-item-box"> <p class="card-header-title floor-item-box-title"><span class="blue-block-goods blue-block-goods-title"></span>售后及服务</p> <Goodsaftersale ref="goodsaftersale" :goodsaftersale="goodsaftersale" /> <div class="submit-type-con"> <el-radio-group v-model="goodsAllData.submit" size="small"> <el-radio :label="0" border>放入仓库</el-radio> <el-radio :label="1" border>立即上架</el-radio> </el-radio-group> </div> </div> </div> </div> <div class="submit-cont"> <el-button type="primary" style="padding: 10px 30px;" @click="save">提 交</el-button> </div> </el-card> <!-- 添加商品 end --> </div> </template> <script> import { getAreaList } from '@/api/module/retreat/address'; import { NewGetCategory,addGoods,getGoodsNew,updateGoodsNew } from '@/api/module/goods'; import Goodsinfomation from './components/goodsinfomation'; import GoodsSpecifications from './components/goodsspecifications'; import GoodsParameter from './components/goodsparameter'; import Goodsimg from './components/goodsimg'; import Goodsaftersale from './components/goodsaftersale'; export default { name: 'Index', props: { option: { type: Number, required: true } }, components: { Goodsinfomation, GoodsSpecifications, GoodsParameter, Goodsimg, Goodsaftersale, }, data() { return { loading: false, SSQList: [], // 省市区 SSQStr: '', // 省市区 拼接 props: { expandTrigger: 'click', lazy: true, lazyLoad: this.lazyLoad, value: "id", label: 'label', leaf: 'leaf' }, isNextStep: true, isShowGoodsDetails: false, isFIActive: 0, /**/ floorNav: [ { id: 1, name: '商品信息' }, { id: 2, name: '商品规格' }, { id: 3, name: '商品售价' }, { id: 4, name: '商品详情' }, { id: 5, name: '售后及服务' } ], /* 商品信息 */ goodsinfodata: { // orgGoodsInfoForm: {}, categoryList: [], categoryStr: '' }, /* 商品规格 */ specificationsdata: [], /* 商品售价 */ parameterdata: { }, /* 商品详情 */ imgdata: { description: '' }, /* 售后及服务 */ goodsaftersale: { stags: [], freight_id: 310, delay_compensate: 24, aftersale_time: 7 }, goodsAllData: { submit: 0, }, // 商品所有数据 TIMER: null, } // return end }, created() { // option 商品的id //debugger if( this.option && this.option !== 0 ) { let data = { goodsId: this.option}; getGoodsNew(data).then(res => { console.log("编辑接口返回", res); if(res.data) { this.isShowGoodsDetails = true; // 商品信息 this.goodsinfodata = { goods_id: res.data.goods_id, categoryStr: '', // 商品分类 地址拼接 categoryList: [], // 商品分类 id集合的数组 goods_des: res.data.goods_des, // 关键词 goods_name: res.data.goods_name, // 商品标题 category_id: res.data.category_id, producing_area: res.data.producing_area, // 产地 deliver_area: res.data.deliver_area, // 发货地 unit: res.data.unit, // 单位 goods_brand: res.data.goods_brand, // 品牌 web_url: res.data.web_url, // 外部链接 out_goods_id: res.data.out_goods_id, // 商品编码 imgs: res.data.imgs // 商品图片 } this.goodsinfodata.categoryStr = res.data.category_first_name + '/' + res.data.category_first_name + '/' + res.data.category_three_name; let arr = []; arr[0] = res.data.category_first_id; arr[0] = res.data.category_second_id; arr[0] = res.data.category_three_id; this.goodsinfodata.categoryList = arr; // 商品规格, 售价由规格决定 if(res.data.specs && res.data.specs.length > 0) { this.specificationsdata = res.data.specs; } // 商品详情 this.imgdata.description = res.data.description; //this.goodsinfodata = res.data; //this.imgdata = res.data.description; //this.goodsaftersale = res.data; // 售后服务 // stags: [], // freight_id: 310, // delay_compensate: 24, // aftersale_time: 7 this.goodsaftersale.freight_id = res.data.freight_id; this.goodsaftersale.delay_compensate = res.data.delay_compensate; this.goodsaftersale.aftersale_time = res.data.aftersale_time; let stagArr = []; if( res.data.stags.indexOf(',') > -1 ) { stagArr = res.data.stags.split(','); stagArr.forEach(item => { if (item) { this.goodsaftersale.stags.push(Number(item)); } }) } } }); } }, mounted() { }, methods: { // 规格子组件,传给父组件的数据 calcSpeTable(data) { if(data.pamTableList.length > 0) { // debugger data.pamTableList.forEach((item, index) => { if( Array.isArray(data.pamDataList[index]) ) { item[0].spec_values = data.pamDataList[index]; }else { item[0].spec_values.push(data.pamDataList[index]); } }) } this.parameterdata = data; //console.log(153,this.parameterdata); }, // 只有点击完最后一级,才会有值 SSQChange() { if(this.SSQList && this.SSQList.length > 0) { this.isNextStep = false }else { this.SSQList = [] this.isNextStep = true } }, lazyLoad(node, resolve) { this.SSQList = []; this.SSQStr = ''; //debugger this.getArea(node, resolve); if(this.SSQList && this.SSQList.length > 0) { this.isNextStep = false }else { this.isNextStep = true } }, getArea(node, resolve) { const level = node.level; let limboNode = {}; if(level === 0) { limboNode = {id: 0} } if(level === 1) { limboNode = { id: node.value }; } if(level === 2) { limboNode = { id: node.value }; } this.loading = true; NewGetCategory(limboNode).then(res => { let result = {}; //debugger if (level === 0) { result = res.data result.forEach(item => { item.value = item.id; item.label = item.label; item.children = []; item.leaf = 0; // 可以控制 是否有下级 值为true都不行,必须等于0 }) } if (level === 1) { //result = res.data // res.data.forEach((item,index)=> { // result = (item.id === limboNode.id) ? item.children : []; // }); for(let i = 0; i < res.data.length; i++) { if( limboNode.id === res.data[i].id ) { result = res.data[i].children; break; } } result.forEach(item => { item.value = item.id; item.label = item.label item.children=[]; //这句代码表示当点击最后一级的时候 label后面不会转圈圈 并把相关值赋值到选择器上 item.leaf = 0 }) } if (level === 2) { for(let i = 0; i < res.data.length; i++) { if( res.data[i].children.length > 0) { for(let j = 0; j < res.data[i].children.length; j++) { if( limboNode.id === res.data[i].children[j].id ) { result = res.data[i].children[j].children; break; } } } } result.forEach(item => { item.value = item.id; item.label = item.label item.leaf = 1; }) } // result = [] resolve(result) this.loading = false; }); }, // 添加商品后,下一步 操作 nextStep() { // 注意数据格式 [1,2,3] 数组,且里面是数字类型 let ssqLabelList = this.$refs['ssqCascader'].getCheckedNodes()[0].pathLabels; this.goodsinfodata.categoryList = this.SSQList; this.goodsinfodata.categoryStr = ssqLabelList[0] + '/' + ssqLabelList[1] + '/' + ssqLabelList[2]; this.isShowGoodsDetails = true; // console.log(232,this.goodsinfodata.categoryStr,this.goodsinfodata.categoryList); }, // // getGoodsAfterSaleData(data) { // console.log("售后子组件给的:",data); // }, // save() { // let spxxDataId = this.$refs.goodsInfo.goodsInfoForm.goods_id; // // if(!spxxDataId) { // // } // 此处变量 有顺序 校验时,电梯至某处 // 商品信息 是否填写完整 let isGoodsInfoMsg = this.$refs['goodsInfo'].validateGoodsInfoForm(); // 商品规格 无需校验 // 商品售价,通过获取的数据,分别进行判断 let isGoodsPrice = true; let spsjData1 = this.$refs.goodsparameter.singleSpecTable; let spsjData2 = this.$refs.goodsparameter.orgGoodsPam; //debugger // 如果有,则说明有规格组合数据 if ( spsjData2.pamTableList && spsjData2.pamTableList.length > 0 ) { //console.log(25522,spsjData2); for(let i = 0; i < spsjData2.pamTableList.length; i++) { //console.log("外",spsjData2.pamTableList[i]); let itemObj = spsjData2.pamTableList[i][0]; for (let itemKey in itemObj) { // 长度判断,可以校验规格是否上传了图片 // if ( !itemObj[itemKey] || itemObj[itemKey].length === 0) { if ( !itemObj[itemKey] && itemKey !== 'thumb') { isGoodsPrice = false; break } else { isGoodsPrice = true; } } if (!isGoodsPrice) { break } } }else { // 无规格组合数据 let slingleSpeObj = spsjData1[0]; for (let key in slingleSpeObj) { // 长度判断,可以校验规格是否上传了图片 // if ( !slingleSpeObj[key] || (slingleSpeObj[key].length === 0) ) { if ( !slingleSpeObj[key] && ( key !== 'imgs') ) { isGoodsPrice = false; break } else { isGoodsPrice = true; } } } // 商品详情 是否填写完整 let isGoodsDetailsImgMsg = this.$refs.goodsdetailsimg.goodsDeForm.description ? true : false; // 售后服务 是否填写完整 let isGoodsAfterSaleMsg = this.$refs['goodsaftersale'].validateGoodsAfterSaleForm(); // 商品售价,由商品规格决定, // 如果 没有填写商品规格,那么商品售价应该获取 if(!isGoodsInfoMsg) { this.$message({type:'error',message:'商品信息未填写完整'}); this.setFloorNavMountClick(0); return } if(!isGoodsPrice) { this.$message({type:'error',message:'商品售价未填写完整'}); this.setFloorNavMountClick(2); return } if(!isGoodsDetailsImgMsg) { this.$message({type:'error',message:'请先上传描述商品详情的图片'}); this.setFloorNavMountClick(3); return } if(!isGoodsAfterSaleMsg) { this.$message({type:'error',message:'售后及服务未填写完整'}); this.setFloorNavMountClick(4); return } // 所有校验通过,整理数据 // 获取 商品信息数据 let spxxData = this.$refs.goodsInfo.goodsInfoForm; // 商品规格 let spggData = this.$refs.goodsspecifications.speData; // this.goodsAllData.specs = spggData; // 商品售价,上面已经获取, let spsjData = {}; // specs_group if( spsjData2.pamTableList && spsjData2.pamTableList.length > 0 ) { this.goodsAllData['specs_group'] = []; this.goodsAllData['specs'] = spggData; spsjData2.pamTableList.forEach((item,index)=> { this.goodsAllData['specs_group'].push(item[0]); }); }else { spsjData = spsjData1[0]; } // 商品详情 数据 let spxqData = this.$refs.goodsdetailsimg.goodsDeForm; // 售后服务 数据 let ssffData = this.$refs.goodsaftersale.goodsAfterSaleForm; console.log("商品信息:",spxxData); console.log("商品规格:",spggData); console.log("商品售价:",spsjData); console.log("商品详情:",spxqData); console.log("商品售后:",ssffData); Object.assign( this.goodsAllData, spxxData, spsjData, spxqData, ssffData); // spxxData.categoryList = [] // 经营类目,服务标签,需要单独处理数据格式 this.goodsAllData.category_id = spxxData.categoryList.slice(-1)[0] ? spxxData.categoryList.slice(-1)[0] : ''; if(this.goodsAllData.stags) { this.goodsAllData.stags = this.goodsAllData.stags.toString(); } console.log('最终数据:',this.goodsAllData); if(this.goodsAllData.goods_id) { updateGoodsNew(this.goodsAllData).then(res=> { console.log("修改结果:",res); }); }else { addGoods( this.goodsAllData ).then( res=> { console.log("返回结果",res); }); } }, /*-----------------------*/ /* 添加商品详细 */ /* 设置楼层导航事件驱动方法* @params Number index 楼层下标 */ setFloorNavMountClick(index) { let _this = this _this.isFIActive = index; clearInterval(_this.TIMER); // 可以通过 floor-cont的父元素,高度减去上下两个div的高度,来准确计算出来了,需要wtach监听,暂时用初步高来计算,一般问题不大 let floor_cont = document.getElementsByClassName('floor-cont')[0]; let floor_item = document.getElementsByClassName('floor-item'), // 每次点击,对应dom需要滚动的高度 floor_offsetTop = floor_item[index].offsetTop - floor_item[0].offsetTop, window_scrollTop = _this.$refs.scrollview.scrollTop, // 基本滚动动画配置 timer = { step: 45, times: 20, FLOOR_OFFSETTOP: 0 }; // floor_cont 可是窗口的 高 let hxz = 0; let resList = []; let list = []; for(let i = 0; i < floor_item.length; i++) { list.push(Number(floor_item[i].offsetHeight)); } resList = list.slice(index) for(let j = 0; j < resList.length; j++) { hxz += resList[j] } if( hxz > floor_cont.offsetHeight) { timer.FLOOR_OFFSETTOP = floor_offsetTop; }else { timer.FLOOR_OFFSETTOP = floor_cont.scrollHeight - floor_cont.offsetHeight } if (window_scrollTop > floor_offsetTop) { _this.setFloorScrollArrowUp(timer) } else if (window_scrollTop === floor_offsetTop) { return false } else { _this.setFloorScrollArrowDown(timer) } }, /* 设置楼层向上滚动* @params Object timer 定时器配置 */ setFloorScrollArrowUp(timer) { let _this = this clearInterval(_this.TIMER) _this.TIMER = setInterval(() => { const window_scrollTop = _this.$refs.scrollview.scrollTop if (window_scrollTop <= timer.FLOOR_OFFSETTOP) { _this.$refs.scrollview.scrollTop = timer.FLOOR_OFFSETTOP clearInterval(_this.TIMER) } else { _this.$refs.scrollview.scrollTop = window_scrollTop - timer.step } }, timer.times) }, /* 设置楼层向下滚动@params Object timer 定时器配置 */ setFloorScrollArrowDown(timer) { let _this = this clearInterval(_this.TIMER) _this.TIMER = setInterval(() => { const window_scrollTop = _this.$refs.scrollview.scrollTop if (window_scrollTop >= timer.FLOOR_OFFSETTOP) { _this.$refs.scrollview.scrollTop = timer.FLOOR_OFFSETTOP clearInterval(_this.TIMER) } else { _this.$refs.scrollview.scrollTop = window_scrollTop + timer.step } }, timer.times) }, } // methods end } </script> <style scoped lang="scss" type="text/css"> .goods-all { height: 100%; padding: 20px; } /deep/.goods-all .good-all-type { height: 100%; } /deep/.goods-all .el-card .el-card__body{ height:100%; overflow: auto; } p { margin: 0; padding: 0; } /* el-card title hxz 样式统一 */ .card-header-title { display: flex; flex-direction: row; justify-content: start; align-items: center; font-size: 16px; color: #333; font-weight: 400; height: 24px; } .blue-block-goods { width: 5px; height: 24px; background: #3A84FF; margin: 0 7px 0 0; border-radius: 2px; } /* el-card title hxz 样式统一 end */ .goods-type-tip { width: 100%; background: #F1F7FD; border: 1px solid #3A84FF; font-size: 14px; font-weight: 400; color: #3A84FF; line-height: 1em; padding: 14px 15px; } .goods-type-options { margin: 25px 0; } /*------------ 联级面板样式重置 start ------------*/ /deep/.el-cascader-panel.is-bordered { border: none; } /deep/.el-cascader-menu { min-width: 280px; border: none; box-shadow: 0px 4px 9px 1px rgba(51, 51, 51, 0.09); border-radius: 2px; overflow: hidden; } /deep/.el-cascader-menu__wrap { width: 280px; height: 500px; overflow: auto; margin: 5px 0!important; } /* 很重要,不要问我为什么 */ /deep/.el-scrollbar:hover>.el-scrollbar__bar, /deep/.el-scrollbar:active>.el-scrollbar__bar, /deep/.el-scrollbar:focus>.el-scrollbar__bar { opacity: 0; } /*------------ 联级面板样式重置 end ---------------*/ .next-step { padding: 10px 25px; margin: 0 auto; display: block; } /* 电梯效果 样式 */ .floor-nav { width: 100%; } .floor-nav .nav-list { padding: 0; margin:0; display: flex; justify-content: start; flex-direction: row; border-bottom:1px solid #eee; } .floor-nav .nav-list .nav-list-item { font-size: 16px; font-weight: 400; color: #333333; padding: 0 25px 15px; list-style: none; vertical-align: middle; align-self: center; border-bottom: 2px solid #fff; cursor: pointer; } .floor-nav .nav-list .floor-item-active, .floor-nav .nav-list .nav-list-item:hover { color: #3A84FF; font-weight: bold; border-bottom: 2px solid #3A84FF; } .floor-item-box-title { background: #F1F1F6; height: 45px; } .blue-block-goods-title { margin: 0 20px 0 0; } .good-details-body { height: 100%; } /deep/.good-details-body .el-card__body { height: 100%; padding: 15px 20px 0px 20px; overflow: hidden; } .floor-cont{ height: calc(100% - 98px); overflow: auto; } .floor-item { padding: 0 20px 0 0; margin: 15px auto; color: #333; } .submit-type-con { width: 236px; margin: 0 auto 20px; } .submit-cont { width: calc(100% + 40px); padding: 12px 0 8px; margin-left: -20px; display: flex; flex-direction: row; justify-content: center; align-items: center; /*align-content: center;*/ box-shadow: 0px -8px 9px 1px rgba(51, 51, 51, 0.06); } </style>