Commit e8c821cd by member

Merge branch 'dev' into dev-dingdang

parents 555d18e8 90747d51
<!DOCTYPE html><html><head><meta charset=utf-8><link rel="shortcut icon" href=./favicon.ico><title>GIC-会员标签</title><link href=./static/css/app.7aa769483667fb36ae04b02ae601b62c.css rel=stylesheet></head><body style="background-color: #f0f2f5;min-width: 1400px;"><div id=app></div><script src=//web-1251519181.file.myqcloud.com/lib/vue/2.6.6/vue.min.js></script><script src=//web-1251519181.file.myqcloud.com/lib/vue-router/3.0.2/vue-router.min.js></script><script src=//web-1251519181.file.myqcloud.com/lib/vuex/3.1.0/vuex.min.js></script><script src=//web-1251519181.file.myqcloud.com/lib/elementUI/index.2.5.4.js></script><script src=//web-1251519181.file.myqcloud.com/components/header.2.0.20.js></script><script src=//web-1251519181.file.myqcloud.com/components/footer.2.0.02.js></script><script src=//web-1251519181.file.myqcloud.com/components/store-new.2.0.12.js></script><script src=//web-1251519181.file.myqcloud.com/components/aside-menu.2.0.02.js></script><script src=//web-1251519181.file.myqcloud.com/components/area-ab.2.0.00.js></script><script src=//web-1251519181.file.myqcloud.com/components/card.2.0.02.js></script><script src=//web-1251519181.cos.ap-shanghai.myqcloud.com/components/selector.1.1.24.js></script><script type=text/javascript src=./static/js/manifest.9d7bc62cfbb175ca5194.js></script><script type=text/javascript src=./static/js/vendor.83081d6a93a866b5b8f1.js></script><script type=text/javascript src=./static/js/app.74abcb1641987b233d64.js></script></body></html>
\ No newline at end of file
<!DOCTYPE html><html><head><meta charset=utf-8><link rel="shortcut icon" href=./favicon.ico><title>GIC-会员标签</title><link href=./static/css/app.3c85591c85402a7e3ed164eaa15c77e3.css rel=stylesheet></head><body style="background-color: #f0f2f5;min-width: 1400px;"><div id=app></div><script src=//web-1251519181.file.myqcloud.com/lib/vue/2.6.6/vue.min.js></script><script src=//web-1251519181.file.myqcloud.com/lib/vue-router/3.0.2/vue-router.min.js></script><script src=//web-1251519181.file.myqcloud.com/lib/vuex/3.1.0/vuex.min.js></script><script src=//web-1251519181.file.myqcloud.com/lib/elementUI/index.2.5.4.js></script><script src=//web-1251519181.file.myqcloud.com/components/header.2.0.20.js></script><script src=//web-1251519181.file.myqcloud.com/components/footer.2.0.02.js></script><script src=//web-1251519181.file.myqcloud.com/components/store-new.2.0.12.js></script><script src=//web-1251519181.file.myqcloud.com/components/aside-menu.2.0.02.js></script><script src=//web-1251519181.file.myqcloud.com/components/area-ab.2.0.00.js></script><script src=//web-1251519181.file.myqcloud.com/components/card.2.0.02.js></script><script src=//web-1251519181.cos.ap-shanghai.myqcloud.com/components/selector.1.1.47.js></script><script type=text/javascript src=./static/js/manifest.61d10ac452b6fb7d21b5.js></script><script type=text/javascript src=./static/js/vendor.83081d6a93a866b5b8f1.js></script><script type=text/javascript src=./static/js/app.74abcb1641987b233d64.js></script></body></html>
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
!function(e){var c=window.webpackJsonp;window.webpackJsonp=function(n,a,o){for(var f,b,d,i=0,u=[];i<n.length;i++)b=n[i],r[b]&&u.push(r[b][0]),r[b]=0;for(f in a)Object.prototype.hasOwnProperty.call(a,f)&&(e[f]=a[f]);for(c&&c(n,a,o);u.length;)u.shift()();if(o)for(i=0;i<o.length;i++)d=t(t.s=o[i]);return d};var n={},r={33:0};function t(c){if(n[c])return n[c].exports;var r=n[c]={i:c,l:!1,exports:{}};return e[c].call(r.exports,r,r.exports,t),r.l=!0,r.exports}t.e=function(e){var c=r[e];if(0===c)return new Promise(function(e){e()});if(c)return c[2];var n=new Promise(function(n,t){c=r[e]=[n,t]});c[2]=n;var a=document.getElementsByTagName("head")[0],o=document.createElement("script");o.type="text/javascript",o.charset="utf-8",o.async=!0,o.timeout=12e4,t.nc&&o.setAttribute("nonce",t.nc),o.src=t.p+"static/js/"+e+"."+{0:"591c1b7953520b7d007d",1:"1a66f3452cb905b67755",2:"3f2364554aa552a47411",3:"fe684d5b3be8d6a06050",4:"5b0346475b0b9639d969",5:"8756e3a39cb4cea7cbab",6:"31eb51419dea97959645",7:"f169140cbd6ad9f5611c",8:"fe61efcd1ccfc3412252",9:"ea583eedf0e8e01807bd",10:"49dc4ce10dca172e66e9",11:"ccd88f29f9f216d131be",12:"543f6c991cec8c913a41",13:"4cbb12cbf7a9b8c30ba8",14:"012b850d5f8cb0572383",15:"c0b9b2e643a3d7f2e4a1",16:"07a972b413b1bb61c0ea",17:"874e4520e26cc90eb0a8",18:"643011894ba40b8da49b",19:"308e228686726571bdcf",20:"0fef167461d750bfe493",21:"9552d108595ed6cf8df5",22:"61bb63c1296b6c9972a5",23:"c24a9f56d0040598512c",24:"590887b93345814f00ef",25:"fbc9d87dd52c837c39be",26:"c5f9e5a4bc2c63938b70",27:"2c48b10d124016d57c0b",28:"f5fc73b651e29d17f74d",29:"ed4b43f3d8456f7bd36e",30:"5d1cb1b10c82fdeede4d"}[e]+".js";var f=setTimeout(b,12e4);function b(){o.onerror=o.onload=null,clearTimeout(f);var c=r[e];0!==c&&(c&&c[1](new Error("Loading chunk "+e+" failed.")),r[e]=void 0)}return o.onerror=o.onload=b,a.appendChild(o),n},t.m=e,t.c=n,t.d=function(e,c,n){t.o(e,c)||Object.defineProperty(e,c,{configurable:!1,enumerable:!0,get:n})},t.n=function(e){var c=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(c,"a",c),c},t.o=function(e,c){return Object.prototype.hasOwnProperty.call(e,c)},t.p="./",t.oe=function(e){throw console.error(e),e}}([]);
\ No newline at end of file
!function(e){var c=window.webpackJsonp;window.webpackJsonp=function(n,a,o){for(var f,b,d,i=0,u=[];i<n.length;i++)b=n[i],r[b]&&u.push(r[b][0]),r[b]=0;for(f in a)Object.prototype.hasOwnProperty.call(a,f)&&(e[f]=a[f]);for(c&&c(n,a,o);u.length;)u.shift()();if(o)for(i=0;i<o.length;i++)d=t(t.s=o[i]);return d};var n={},r={33:0};function t(c){if(n[c])return n[c].exports;var r=n[c]={i:c,l:!1,exports:{}};return e[c].call(r.exports,r,r.exports,t),r.l=!0,r.exports}t.e=function(e){var c=r[e];if(0===c)return new Promise(function(e){e()});if(c)return c[2];var n=new Promise(function(n,t){c=r[e]=[n,t]});c[2]=n;var a=document.getElementsByTagName("head")[0],o=document.createElement("script");o.type="text/javascript",o.charset="utf-8",o.async=!0,o.timeout=12e4,t.nc&&o.setAttribute("nonce",t.nc),o.src=t.p+"static/js/"+e+"."+{0:"41db9431e767747369bc",1:"1a66f3452cb905b67755",2:"3f2364554aa552a47411",3:"fe684d5b3be8d6a06050",4:"5b0346475b0b9639d969",5:"8756e3a39cb4cea7cbab",6:"31eb51419dea97959645",7:"f169140cbd6ad9f5611c",8:"fe61efcd1ccfc3412252",9:"ea583eedf0e8e01807bd",10:"49dc4ce10dca172e66e9",11:"ccd88f29f9f216d131be",12:"543f6c991cec8c913a41",13:"4cbb12cbf7a9b8c30ba8",14:"012b850d5f8cb0572383",15:"c0b9b2e643a3d7f2e4a1",16:"07a972b413b1bb61c0ea",17:"874e4520e26cc90eb0a8",18:"643011894ba40b8da49b",19:"308e228686726571bdcf",20:"0fef167461d750bfe493",21:"9552d108595ed6cf8df5",22:"61bb63c1296b6c9972a5",23:"c24a9f56d0040598512c",24:"590887b93345814f00ef",25:"fbc9d87dd52c837c39be",26:"c5f9e5a4bc2c63938b70",27:"2c48b10d124016d57c0b",28:"f5fc73b651e29d17f74d",29:"ed4b43f3d8456f7bd36e",30:"5d1cb1b10c82fdeede4d"}[e]+".js";var f=setTimeout(b,12e4);function b(){o.onerror=o.onload=null,clearTimeout(f);var c=r[e];0!==c&&(c&&c[1](new Error("Loading chunk "+e+" failed.")),r[e]=void 0)}return o.onerror=o.onload=b,a.appendChild(o),n},t.m=e,t.c=n,t.d=function(e,c,n){t.o(e,c)||Object.defineProperty(e,c,{configurable:!1,enumerable:!0,get:n})},t.n=function(e){var c=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(c,"a",c),c},t.o=function(e,c){return Object.prototype.hasOwnProperty.call(e,c)},t.p="./",t.oe=function(e){throw console.error(e),e}}([]);
\ No newline at end of file
......@@ -21,6 +21,6 @@
<script src="//web-1251519181.file.myqcloud.com/components/aside-menu.2.0.02.js"></script>
<script src="//web-1251519181.file.myqcloud.com/components/area-ab.2.0.00.js"></script>
<script src="//web-1251519181.file.myqcloud.com/components/card.2.0.02.js"></script>
<script src="//web-1251519181.cos.ap-shanghai.myqcloud.com/components/selector.1.1.24.js"></script>
<script src="//web-1251519181.cos.ap-shanghai.myqcloud.com/components/selector.1.1.47.js"></script>
</body>
</html>
const host = window.location.origin;
// eslint-disable-next-line
export const baseUrl = host.indexOf('localhost') != '-1' ? 'http://gicdev.demogic.com' : host;
export const baseUrl = host.indexOf('localhost') > '-1' ? 'http://gicdev.demogic.com' : host;
export function hasClass(el, cls) {
if (!el || !cls) return false;
if (cls.indexOf(' ') !== -1) throw new Error('className should not contain space.');
if (el.classList) {
return el.classList.contains(cls);
} else {
return (' ' + el.className + ' ').indexOf(' ' + cls + ' ') > -1;
}
}
/* istanbul ignore next */
export function addClass(el, cls) {
if (!el) return;
let curClass = el.className;
let classes = (cls || '').split(' ');
for (let i = 0, j = classes.length; i < j; i++) {
let clsName = classes[i];
if (!clsName) continue;
if (el.classList) {
el.classList.add(clsName);
} else if (!hasClass(el, clsName)) {
curClass += ' ' + clsName;
}
}
if (!el.classList) {
el.className = curClass;
}
}
/* istanbul ignore next */
export function removeClass(el, cls) {
let i = 0;
let j;
let clsName;
if (!el || !cls) return;
let classes = cls.split(' ');
let curClass = ' ' + el.className + ' ';
for (i, j = classes.length; i < j; i++) {
clsName = classes[i];
if (!clsName) continue;
if (el.classList) {
el.classList.remove(clsName);
} else if (hasClass(el, clsName)) {
curClass = curClass.replace(' ' + clsName + ' ', ' ');
}
}
if (!el.classList) {
el.className = curClass;
}
}
// 向下查找
function broadcast(componentName, eventName, params) {
this.$children.forEach(child => {
const name = child.$options.name;
if (name === componentName) {
child.$emit.apply(child, [eventName].concat([params]));
} else {
broadcast.apply(child, [componentName, eventName].concat([params]));
}
});
}
// 向上查找组件
export default {
methods: {
dispatch(componentName, eventName, params) {
let parent = this.$parent || this.$root;
let name = parent.$options.name;
while (parent && (!name || name !== componentName)) {
parent = parent.$parent;
if (parent) {
name = parent.$options.name;
}
}
if (parent) {
parent.$emit.apply(parent, [eventName, params]);
}
},
broadcast(componentName, eventName, params) {
broadcast.call(this, componentName, eventName, params);
},
findComponentUpward(context, componentName) {
let parent = context.$parent;
let name = parent.$options.name;
while (parent && (!name || name !== componentName)) {
parent = parent.$parent;
if (parent) {
name = parent.$options.name;
}
}
return parent;
}
// findAnyComponent(componentName, root = null) {
// if (!root) {
// root = this.$root;
// }
// const childrens = root.$children;
// let children = null;
// if (childrens.length) {
// for (const child of childrens) {
// const name = child.$options.name;
// if (name === componentName) {
// children = child;
// break;
// } else {
// children = findAnyComponent.call(this, componentName, child);
// if (children) break;
// }
// }
// }
// return children;
// }
}
};
export function debounce(func, wait) {
let timeout;
return function(...args) {
let that = this;
clearTimeout(timeout);
timeout = setTimeout(_ => {
func.apply(that, args);
}, wait);
};
}
export function throttle(func, wait) {
let timeout;
// let previous = 0; // 时间戳
return function(...args) {
let that = this;
if (!timeout) {
timeout = setTimeout(_ => {
timeout = null;
func.apply(that, args);
}, wait);
}
};
}
<template>
<li :class="classes">
<span> {{ data.categoryName }} </span>
<i v-if="showArrow" class="el-icon-arrow-right fr"></i>
</li>
</template>
<script>
export default {
name: 'Casitem',
props: {
data: Object,
tmpItem: Object
},
computed: {
classes() {
return [
`cascader-menu__item`,
{
[`cascader-menu__item--extensible`]: this.data && this.data.isChildren,
[`is-active`]: this.tmpItem.categoryName === this.data.categoryName
}
];
},
showArrow() {
return this.data.isChildren;
}
}
};
</script>
<style lang="less" scoped>
.cascader-menu__item {
font-size: 14px;
padding: 8px 20px;
width: 152px;
position: relative;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: #606266;
height: 34px;
line-height: 1.5;
box-sizing: border-box;
cursor: pointer;
outline: none;
&:hover {
color: #409eff;
}
.fr {
position: absolute;
font-size: 12px;
right: 15px;
top: 50%;
margin-top: -6px;
}
}
.is-active {
color: #409eff;
}
</style>
<template>
<div class="caspanel-box">
<span class="ate-keys-box">
<el-input placeholder="搜索关键字" prefix-icon="el-icon-search" v-model="keys" @keyup.native.enter="handleEnter($event)"> </el-input>
</span>
<div class="casitem-box">
<ul v-if="data && data.length" class="casitem-ul">
<Casitem v-for="(item, i) in data" :key="i" :data="item" :tmp-item="tmpItem" @click.native.stop="handleClickItem(item)" @dblclick.native.stop="handleDbClickItem(item)"> </Casitem>
</ul>
</div>
<Caspanel v-if="sublist && sublist.length" :data="sublist" :middle="sublist" :change-on-select="changeOnSelect"></Caspanel>
</div>
</template>
<script>
import Casitem from './casitem';
import Emitter from '../assist/emitter';
import { baseUrl } from '@/config/index.js';
let key = 1;
export default {
name: 'Caspanel',
components: {
Casitem
},
mixins: [Emitter],
props: {
data: {
type: Array,
default() {
return [];
}
},
middle: {
type: Array,
default() {
return [];
}
},
changeOnSelect: Boolean
},
data() {
return {
tmpItem: {},
result: [],
sublist: [],
keys: ''
};
},
methods: {
//
handleEnter(eve) {
let value = eve.target.value;
console.log(this.middle);
this.data = this.middle.filter(el => el.categoryName.indexOf(value) > -1);
},
handleClickItem(item) {
this.tmpItem = Object.assign({}, item);
this.getNextData(item.categoryId);
},
// 双击
handleDbClickItem(item) {
const goodItem = this.findComponentUpward(this, 'gooditem');
item.index = goodItem.goodsIndex;
const tags = Object.assign({}, item);
// 拿到tags比较是否有重复的id
const ategory = this.findComponentUpward(this, 'goods-ategory');
const Tags = ategory.tags;
let hasTag;
if (Tags && Tags.length) {
hasTag = Tags.findIndex(tag => {
return tag.categoryId === item.categoryId;
});
}
if (hasTag != void 0 && hasTag != -1) {
this.$message({
message: '已存在改品类,不能重复添加',
type: 'warning'
});
} else {
this.dispatch('vue-gic-goods-selector', 'handle-ategory', tags);
}
},
// 查找下级
getNextData(id) {
this.axios
.get(`${baseUrl}/api-mall/list-mall-goods-children-category?requestProject=mall&categoryId=${id}`)
.then(res => {
if (res.data.errorCode === 0) {
const data = res.data.result;
if (data && data.length) {
this.sublist = data;
} else if (data && data.length == 0) {
this.sublist = [];
}
} else {
// 占位
}
})
.catch(err => {
console.log(err);
});
},
getKey() {
return key++;
}
}
};
</script>
<style lang="less" scoped>
.caspanel-box {
position: relative;
display: inline-block;
vertical-align: top;
height: 240px;
.ate-keys-box {
display: inline-block;
height: 32px;
width: 138px;
padding: 8px 10px;
border: 1px solid #e8eaec;
border-bottom: none;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
background-color: #f5f7fa;
box-sizing: content-box;
}
.casitem-box {
position: absolute;
border: 1px solid #e8eaec;
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
border-top: none;
background-color: #fff;
.casitem-ul {
display: inline-block;
vertical-align: top;
width: 158px;
height: 190px;
list-style: none;
margin: 0;
overflow: auto;
}
}
.caspanel-box {
position: absolute;
margin-left: 12px;
}
}
</style>
<template>
<transition name="transition-drop">
<div class="gic-caspanel">
<Caspanel :data="data" ref="caspanel" :middle="middle" :change-on-select="changeOnSelect"> </Caspanel>
</div>
</transition>
</template>
<script>
import Caspanel from './caspanel';
export default {
name: 'cascader',
components: {
Caspanel
},
props: {
data: {
type: Array,
default() {
return [];
}
},
middle: {
type: Array,
default() {
return [];
}
},
changeOnSelect: {
type: Boolean,
default: false
}
},
data() {
return {
// 占位
};
}
};
</script>
<style lang="less" scoped>
.gic-caspanel {
height: 240px;
padding-bottom: 12px;
overflow-x: auto;
overflow-y: hidden;
font-size: 0px;
}
</style>
import { addClass, removeClass } from './assist/dom';
const Transition = {
beforeEnter(el) {
addClass(el, 'collapse-transition');
if (!el.dataset) el.dataset = {};
el.dataset.oldPaddingTop = el.style.paddingTop;
el.dataset.oldPaddingBottom = el.style.paddingBottom;
el.style.height = '0';
el.style.paddingTop = 0;
el.style.paddingBottom = 0;
},
enter(el) {
el.dataset.oldOverflow = el.style.overflow;
if (el.scrollHeight !== 0) {
el.style.height = el.scrollHeight + 'px';
el.style.paddingTop = el.dataset.oldPaddingTop;
el.style.paddingBottom = el.dataset.oldPaddingBottom;
} else {
el.style.height = '';
el.style.paddingTop = el.dataset.oldPaddingTop;
el.style.paddingBottom = el.dataset.oldPaddingBottom;
}
el.style.overflow = 'hidden';
},
afterEnter(el) {
// for safari: remove class then reset height is necessary
removeClass(el, 'collapse-transition');
el.style.height = '';
el.style.overflow = el.dataset.oldOverflow;
},
beforeLeave(el) {
if (!el.dataset) el.dataset = {};
el.dataset.oldPaddingTop = el.style.paddingTop;
el.dataset.oldPaddingBottom = el.style.paddingBottom;
el.dataset.oldOverflow = el.style.overflow;
el.style.height = el.scrollHeight + 'px';
el.style.overflow = 'hidden';
},
leave(el) {
if (el.scrollHeight !== 0) {
// for safari: add class after set height, or it will jump to zero height suddenly, weired
addClass(el, 'collapse-transition');
el.style.height = 0;
el.style.paddingTop = 0;
el.style.paddingBottom = 0;
}
},
afterLeave(el) {
removeClass(el, 'collapse-transition');
el.style.height = '';
el.style.overflow = el.dataset.oldOverflow;
el.style.paddingTop = el.dataset.oldPaddingTop;
el.style.paddingBottom = el.dataset.oldPaddingBottom;
}
};
export default {
name: 'ElCollapseTransition',
functional: true,
render(h, { children }) {
const data = {
on: Transition
};
return h('transition', data, children);
}
};
<template>
<div class="complex-info">
<div class="complex-items" v-for="(item, i) in abbrInfos" :key="i">
<complex-item :data="item"></complex-item>
<strong class="complex-and" v-if="abbrInfos[i + 1] && abbrInfos[i + 1].length">并且</strong>
</div>
</div>
</template>
<script>
/* eslint-disable */
import ComplexItem from './complex-item';
export default {
name: 'complex-info',
props: {
complexData: Array
},
components: {
ComplexItem
},
watch: {
complexData: {
immediate: true,
handler(newval) {
this.abbrInfos = newval;
}
}
},
data() {
return {
abbrInfos: []
};
}
};
</script>
<style lang="less" scoped>
.complex-items {
.complex-and {
display: inline-block;
margin: 10px 0;
padding: 10px 20px;
color: #64666a;
border-radius: 20px;
background-color: #e2e2e2;
}
}
.complex-info {
display: inline-block;
vertical-align: middle;
}
</style>
<template>
<!-- 缩略信息递归组件的一部分 -->
<div class="complex-item">
<div class="selector-item-txt" v-for="(item, i) in items" :key="i">
<span class="condition" v-if="item.optName"> {{ item.optName }}</span>
<div class="txt">
{{ item.typeName }}{{ item.belong }}
<div class="child-name" v-if="item.childNames && item.childNames.length">
<span v-for="(child, index) in item.childNames" :key="index">{{ child || '' }}</span>
</div>
<!-- <div class="child-name" v-else>
暂无
</div> -->
</div>
</div>
</div>
</template>
<script>
export default {
name: 'complex-item',
props: {
data: Array
},
watch: {
data: {
immediate: true,
handler(newval) {
this.items = newval;
}
}
},
data() {
return {
items: []
};
}
};
</script>
<style lang="less" scoped>
.complex-item {
.selector-item-txt {
display: inline-block;
vertical-align: middle;
.txt {
display: inline-block;
padding: 5px 10px;
font-size: 12px;
color: #8d8d8d;
background-color: #f5f7fa;
border-radius: 5px;
.child-name {
display: inline-block;
}
}
.condition {
display: inline-block;
vertical-align: middle;
margin: 0 5px;
font-size: 12px;
}
}
}
</style>
const host = window.location.origin;
export const baseUrl = host.('localhost') ? 'http://gicdev.demogic.com' : host;
<template>
<li class="good-item">
<el-checkbox v-model="item.check"></el-checkbox>
<div class="good-info">
<img :src="item.img" />
<p>{{ item.name }}</p>
<p>{{ item.code }}</p>
</div>
<span class="price"> {{ item.price }} </span>
<span class="store"> {{ item.store }} </span>
</li>
</template>
<script>
export default {
name: 'GoodFilterItem',
props: {
goods: Object
},
data() {
return {
item: {}
};
},
watch: {
goods: {
immediate: true,
handler(newval) {
this.item = newval;
}
}
}
};
</script>
<template>
<div class="goods-ategory">
<div class="check-title">
<div class="ategory-lists">
<span class="ate-txt" v-if="!tags.length">下方选择品类</span>
<el-tag v-for="tag in tags" size="small" :key="tag.categoryId" closable @close="handleClose(tag)"> {{ tag.categoryName }} </el-tag>
<el-popover placement="top" width="320" trigger="hover" popper-class="selector-popper">
<el-tag class="dm-pop-tag" v-for="tag in tags" size="small" :key="tag.categoryId" closable @close="handleClose(tag)"> {{ tag.categoryName }} </el-tag>
<span class="pop-tips" slot="reference">{{ tags.length }}</span>
</el-popover>
</div>
</div>
<div class="ate-group">
<Cascader :data="ateData" :middle="middle"></Cascader>
</div>
<slot></slot>
</div>
</template>
<script>
import Cascader from './cascader';
import { baseUrl } from '@/config/index.js';
export default {
name: 'goods-ategory',
components: {
Cascader
},
props: {
tags: {
type: Array,
default() {
return [];
}
}
},
data() {
return {
ateData: [{}],
middle: [{}]
};
},
methods: {
getData() {
this.axios
.get(`${baseUrl}/api-mall/list-mall-goods-all-category?requestProject=mall`)
.then(res => {
if (res.data.errorCode == 0) {
const data = res.data.result;
if (data && data.length) {
this.ateData = data;
this.middle = data;
console.log(this.middle);
}
} else {
// 占位
}
})
.catch(err => {
console.log(err);
});
},
handleClose(tag) {
let index = this.tags.findIndex(t => {
return t.categoryId === tag.categoryId;
});
if (index != -1) {
this.tags.splice(index, 1);
}
}
},
created() {
this.getData();
}
};
</script>
<style lang="less" scoped>
.goods-ategory {
.check-title {
height: 48px;
line-height: 48px;
background-color: #ebeef5;
border-top-right-radius: 5px;
border-top-left-radius: 5px;
overflow: hidden;
}
.ategory-lists {
position: relative;
overflow: hidden;
white-space: nowrap;
margin: 7px 20px;
padding: 2px 10px;
height: 32px;
line-height: 24px;
font-size: 0px;
border: 1px solid #dcdfe6;
border-radius: 5px;
box-sizing: border-box;
background-color: #fff;
.ate-txt {
font-size: 14px;
color: #c0c4cc;
}
.pop-tips {
position: absolute;
top: 0;
right: 0;
height: 32px;
line-height: 32px;
width: 70px;
text-align: center;
font-size: 14px;
color: #606266;
background-color: rgba(255, 255, 255, 1);
}
}
.ate-group {
padding: 10px 12px;
overflow-x: scroll;
}
}
.el-tag + .el-tag {
margin-left: 10px;
}
.dm-pop-tag {
margin-right: 10px;
margin-bottom: 5px;
}
.dm-pop-tag + .dm-pop-tag {
margin-left: 0px;
}
</style>
<template>
<div class="goods-brand">
<div class="check-title">
<el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange">全部选择</el-checkbox>
</div>
<el-checkbox-group v-model="checkedBrandes" @change="handleCheckedBrandChange" class="brand-group">
<el-checkbox v-for="brand in brandes" :key="brand.brandId" :label="brand" class="brand-list">{{ brand.brandName }}</el-checkbox>
</el-checkbox-group>
<slot></slot>
</div>
</template>
<script>
import Emitter from './assist/emitter';
import { baseUrl } from '@/config/index.js';
// 品牌
export default {
name: 'goods-brand',
mixins: [Emitter],
props: {
goodsBrands: Array,
goodsIndex: Array
},
data() {
return {
isIndeterminate: false,
checkAll: false,
checkedBrandes: [],
brandes: [],
middleBrands: []
};
},
methods: {
// 全选
handleCheckAllChange(val) {
this.checkedBrandes = val ? this.brandes : [];
this.isIndeterminate = false;
},
// 复选框多选
handleCheckedBrandChange(val) {
let checkCount = val.length;
this.checkAll = checkCount === this.brandes.length;
this.isIndeterminate = checkCount > 0 && checkCount < this.brandes.length;
this.dispatch('vue-gic-goods-selector', 'pass-checkbox', {
index: this.goodsIndex,
items: val
});
},
getBrandList() {
const param = {
currentPage: 1,
pageSize: 20
};
this.axios
.get(`${baseUrl}/api-goods/brandlist?requestProject=goods`, {
params: param
})
.then(res => {
let data;
if (res.data.errorCode === 0) {
data = res.data.result;
this.brandes = data.result;
// 如果超过了20条 totalCount 是总数 根据总数来判断是否还要继续展示第二页的 并不适合全选
} else {
this.$message.error(res.data.message);
}
})
.catch(err => {
this.$message.error(err);
});
}
},
beforeMount() {
// 获取品牌列表
this.getBrandList();
setTimeout(() => {
let checkCount = this.middleBrands.length;
this.checkAll = checkCount === this.brandes.length;
this.isIndeterminate = checkCount > 0 && checkCount < this.brandes.length;
this.middleBrands.forEach(el => {
let index = this.brandes.findIndex(item => item.brandId === el.brandId);
if (index> -1) {
this.checkedBrandes.push(this.brandes[index]);
}
})
}, 100);
},
watch: {
goodsBrands: {
immediate: true,
handler(newval) {
this.middleBrands = newval;
}
}
}
};
</script>
<style lang="scss" scoped>
.goods-box {
.check-title {
height: 48px;
line-height: 48px;
padding-left: 20px;
background-color: #ebeef5;
border-top-right-radius: 5px;
border-top-left-radius: 5px;
}
.brand-group {
padding: 10px 20px;
}
.brand-list {
line-height: 30px;
margin-left: 0;
margin-right: 10px;
}
}
.bounce-enter-active {
animation: bounce-in 0.5s;
}
.bounce-leave-active {
animation: bounce-in 0.5s reverse;
}
@keyframes bounce-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1.5);
}
100% {
transform: scale(1);
}
}
</style>
<template>
<div class="collection">
<div class="coll-options" v-if="goodIndex[1] <= 3">
<el-radio-group v-model="bindCondition" @change="handleChange">
<el-radio :disabled="disabled" :label="1">并且</el-radio>
<el-radio :disabled="disabled" :label="0">或者</el-radio>
<el-radio :disabled="disabled" :label="2">剔除</el-radio>
</el-radio-group>
</div>
<div class="coll-options" v-else></div>
<div class="oper-btn">
<el-popover placement="top" width="150" trigger="click" v-model="visiable">
<el-radio-group v-model="goodOption" class="pop-options">
<el-radio :label="1" class="pop-goodlist">商品品牌</el-radio>
<el-radio :label="2" class="pop-goodlist">商品品类</el-radio>
<el-radio :label="3" class="pop-goodlist">商品规格</el-radio>
<el-radio :label="4" class="pop-goodlist">商品属性</el-radio>
<el-radio :label="5" class="pop-goodlist">部分商品</el-radio>
</el-radio-group>
<div class="insert-dir">
<el-button type="text" class="btn-selector" @click="insertUpward">上方插入</el-button>
<el-button type="text" class="btn-selector" @click="insertUpdown">下方插入</el-button>
</div>
<el-button type="text" class="button-txt" slot="reference" :disabled="length == 5">插入条件</el-button>
</el-popover>
<span class="cut-line">|</span>
<el-button type="text" class="button-txt" @click="deleteCondition">删除</el-button>
</div>
</div>
</template>
<script>
import Emitter from './assist/emitter';
// 集合条件 并且 或者 剔除
export default {
name: 'goods-collection',
props: {
disabled: Boolean,
goodIndex: Array,
length: Number,
condition: Number
},
mixins: [Emitter],
data() {
return {
bindCondition: '',
goodOption: 1, // 插入的商品
visiable: false
};
},
methods: {
deleteCondition() {
// 触发selector 组件去删除
this.dispatch('vue-gic-goods-selector', 'delete-gooditem', this.goodIndex);
},
handleChange(val) {
this.dispatch('vue-gic-goods-selector', 'pass-radioGroup', { index: this.goodIndex, val: this.bindCondition });
},
insertUpward() {
this.dispatch('vue-gic-goods-selector', 'insert-uselector', { index: this.goodIndex, type: parseInt(this.goodOption, 10) });
this.visiable = false;
},
insertUpdown() {
this.dispatch('vue-gic-goods-selector', 'insert-dselector', { index: this.goodIndex, type: parseInt(this.goodOption, 10) });
this.visiable = false;
}
},
watch: {
condition: {
immediate: true,
handler(val) {
this.bindCondition = val;
}
}
}
};
</script>
<style lang="less" scoped>
.collection {
margin-left: 20px;
margin-right: 20px;
padding-top: 10px;
display: flex;
justify-content: space-between;
.coll-options {
display: inline-block;
}
.oper-btn {
display: inline-block;
text-align: right;
.cut-line {
color: #dcdfe6;
}
}
}
.pop-options {
text-align: center;
.pop-goodlist {
margin-left: 0;
line-height: 26px;
}
}
.insert-dir {
border-top: 1px solid #dcdfe6;
padding-top: 10px;
text-align: center;
}
.button-txt {
color: #a4a7aa;
&:hover {
color: #1890ff;
}
}
.btn-selector {
display: inline-block;
vertical-align: middle;
margin: 0;
}
</style>
import GoodsBrand from './goods-brand'; // 商品品牌
import GoodsAtegory from './goods-ategory'; // 商品品类
import GoodsSpecifications from './goods-specifications'; // 规格
import GoodsSome from './goods-some'; // 部分商品
import GoodsProperties from './goods-properties'; // 商品属性
import ElCollapseTransition from './collapse-transition';
export default {
name: 'gooditem',
components: {
GoodsBrand,
GoodsAtegory,
GoodsSpecifications,
GoodsSome,
GoodsProperties,
ElCollapseTransition
},
props: {
type: {
type: String,
validator: val => ['brand', 'ategory', 'specifications', 'properties', 'some'].indexOf(val) > -1
},
goodsIndex: Array,
tags: Array,
goodsBrands: Array,
listReback: Array
},
data() {
return {};
},
render(h) {
// 定义五种类型
const slotVal = this.$slots.default;
const type = this.type;
let FinalComponent;
// 扩展的属性
const goodsData = {
props: {
tags: this.tags,
'goods-brands': this.goodsBrands,
'goods-index': this.goodsIndex,
'list-reback': this.listReback
}
};
if (type == 'brand') {
// 品牌
FinalComponent = <goods-brand {...goodsData}>{slotVal}</goods-brand>;
} else if (type == 'ategory') {
// 品类
FinalComponent = <goods-ategory {...goodsData}>{slotVal}</goods-ategory>;
} else if (type == 'specifications') {
// 规格
FinalComponent = <goods-specifications {...goodsData}>{slotVal}</goods-specifications>;
} else if (type == 'properties') {
// 属性
FinalComponent = <goods-properties {...goodsData}>{slotVal}</goods-properties>;
} else if (type == 'some') {
// 部分商品
FinalComponent = <goods-some {...goodsData}>{slotVal}</goods-some>;
}
return <el-collapse-transition>{FinalComponent}</el-collapse-transition>;
}
};
<template>
<div class="goods-properties">
<div class="check-title">
选择属性
<load-select v-model="propVal" @scrollload="loadMore" :load="load" @change-load="changeLoad">
<gic-load-item v-for="item in propOptions" :key="item.propertyId" :value="item.propertyId" :label="item.propertyName" @pass-item="resiver"> </gic-load-item>
</load-select>
<!-- 多选有 包含其一 和 包含所有-->
<!-- <el-select v-model="exclude" placeholder="请选择" style="width: 120px" v-if="propType === 'TYP_CHECK'">
<el-option
v-for="item in excludeOption"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select> -->
</div>
<div class="prop-content">
<!-- 单选 属性勾选 TYP_SINGLE -->
<!-- v-if="propType === 'TYP_SINGLE' || propType === 'TYP_CHECK'" -->
<div v-if="propType === 'TYP_SINGLE' || propType === 'TYP_CHECK'" class="prop-type">
<el-checkbox :indeterminate="isIndeterminate" v-model="propList.checkAll" @change="handleCheckAllChange">全选</el-checkbox>
<div class="box-group">
<el-checkbox-group v-model="checkedSpes" @change="handleCheckedSpesChange">
<el-checkbox v-for="spe in spes" class="dm-checkbox" :label="spe" :key="spe.valueId">
{{ spe.valueName }}
</el-checkbox>
</el-checkbox-group>
</div>
</div>
<!-- 文本 关键字搜索 -->
<!-- <div v-if="propType === 'TYP_TEXT'" class="prop-type">关键字搜索:<el-input v-model="propList.text" style="width: 200px;" maxlength="8" placeholder="关键字" clearable></el-input></div> -->
<!-- 整数 没有小数-->
<!-- <div v-if="propType === 'TYP_NUM'" class="prop-type">
<el-select v-model="interval" placeholder="请选择" style="width: 100px">
<el-option v-for="item in intervalOption" :key="item.value" :label="item.label" :value="item.value"> </el-option>
</el-select>
<el-input placeholder="请输入" maxlength="8" minlength="1" style="width: 150px" v-model="propList.number"></el-input>
</div> -->
<!-- 实数 有小数-->
<!-- <div v-if="propType === 'TYP_REAL_NUM'" class="prop-type">
<el-select v-model="interval" placeholder="请选择" style="width: 100px;">
<el-option v-for="item in intervalOption" :key="item.value" :label="item.label" :value="item.value"> </el-option>
</el-select>
<el-input placeholder="请输入" maxlength="8" minlength="1" style="width: 150px;" v-model="propList.rel_num"></el-input>
</div> -->
<!-- 时间 TYP_TIME -->
<!-- <div v-if="propType === 'TYP_TIME'" class="prop-type">
<el-date-picker v-model="propList.Time" type="daterange" range-separator="至" start-placeholder="开始时间" end-placeholder="结束时间"> </el-date-picker>
</div> -->
</div>
<slot></slot>
</div>
</template>
<script>
import LoadSelect from './load-select';
import GicLoadItem from './load-item';
import Emitter from './assist/emitter';
import { baseUrl } from '@/config/index.js';
// 文本 单选 多选 勾选 整数 实数 货币 时间 百分比
const PROP_TYPE = [
'TYP_TEXT', // 文本
'TYP_SINGLE', // 单选
'TYP_CHECK', // 多选
'TYP_MULTI', // 勾选
'TYP_NUM', // 整数
'TYP_REAL_NUM', // 实数
'TYP_CURRENCY', // 货币
'TYP_TIME', // 时间
'TYP_PERCENT' // 百分比
];
export default {
name: 'goods-properties',
mixins: [Emitter],
props: {
goodsIndex: Array,
listReback: Array
},
components: {
GicLoadItem,
LoadSelect
},
data() {
return {
propOptions: [],
propVal: [],
checkedSpes: [],
load: false,
currentPage: 1,
spes: [],
interval: null,
isIndeterminate: false,
propType: '',
propList: {
Time: '',
checkAll: false,
number: null,
rel_num: null
}
// intervalOption: [{ label: '>=', value: 0 }, { label: '<=', value: 1 }, { label: '=', value: 2 }]
};
},
watch: {
checkedSpes(newval) {
this.dispatch('vue-gic-goods-selector', 'pass-property', {
index: this.goodsIndex,
items: {
propId: newval,
parentId: this.propertyId,
condition: this.exclude
}
});
}
},
methods: {
loadMore() {
if (this.propOptions.length == (this.currentPage - 1) * 20) {
this.getPropData('success');
} else {
this.load = true;
}
},
changeLoad() {
this.load = false;
},
handleCheckAllChange(val) {
this.checkedSpes = val ? this.spes : [];
this.isIndeterminate = false;
},
handleCheckedSpesChange(value) {
let checkedCount = value.length;
this.propList.checkAll = checkedCount === this.spes.length;
this.isIndeterminate = checkedCount > 0 && checkedCount < this.spes.length;
},
// 商品属性列表下拉数据
getPropData(suc) {
const param = {
currentPage: this.currentPage,
pageSize: 20
};
this.axios
.get(`${baseUrl}/api-goods/page-property?requestProject=goods`, {
params: param
})
.then(res => {
if (res.data.errorCode === 0) {
let data = res.data.result;
this.propOptions = this.propOptions.concat(data.result);
this.currentPage++;
if (suc == 'success') {
this.load = true;
}
// 回显
if (this.listReback.ids.parentId) {
let index = this.propOptions.findIndex(el => el.propertyId == this.listReback.ids.parentId);
if (index > -1) {
this.resiver(this.propOptions[index].propertyName);
}
}
} else {
// this.$message.error(res.data.message);
}
})
.catch(err => {
console.log(err);
// this.$message.error(error);
});
},
resiver(val) {
this.propVal = val;
const item = this.propOptions.find(el => el.propertyName === val);
this.propertyId = item.propertyId;
// propertyType 字段属性类型
const type = PROP_TYPE.find(type => type === item.propertyType);
// 属性类型
if (type) {
this.propType = type;
if (this.propType == 'TYP_SINGLE' || this.propType == 'TYP_CHECK') {
const param = {
currentPage: 1,
pageSize: 20,
propertyId: item.propertyId
};
this.axios
.get(`${baseUrl}/api-goods/page-property-value?requestProject=goods`, {
params: param
})
.then(res => {
if (res.data.errorCode == 0) {
const data = res.data.result;
if (data.result && data.result.length) {
this.spes = data.result;
} else {
this.spes = [];
}
// 回显内部属性
const List = this.listReback.ids.propId;
if (List && List.length) {
List.forEach(el => {
let i = this.spes.findIndex(item => item.valueId == el.valueId);
if (i > -1) {
this.checkedSpes.push(this.spes[i]);
}
});
let checkedCount = this.checkedSpes.length;
this.propList.checkAll = checkedCount === this.spes.length;
this.isIndeterminate = checkedCount > 0 && checkedCount < this.spes.length;
}
}
})
.catch(err => {
console.log(err);
});
}
// 多选
}
}
},
beforeMount() {
this.getPropData();
},
mounted() {
this.$on('pass-item', this.resiver);
}
};
</script>
<style lang="less" scoped>
.goods-properties {
.check-title {
height: 48px;
line-height: 48px;
padding-left: 20px;
background-color: #ebeef5;
font-size: 14px;
color: #606266;
border-top-right-radius: 5px;
border-top-left-radius: 5px;
}
.prop-content {
padding: 10px 20px;
.box-group {
margin-top: 10px;
padding-top: 10px;
border-top: 1px dashed #dcdfe6;
}
.prop-type {
color: #606266;
font-size: 14px;
}
}
}
</style>
<template>
<div class="goods-specifications">
<div class="check-title">
选择规格 &nbsp;
<load-select v-model="specvalue" @scrollload="loadMore" :load="load" @change-load="changeLoad">
<gic-load-item v-for="item in speOptions" :key="item.standardId" :value="item.standardId" :label="item.standardName" @pass-item="resiver"> </gic-load-item>
</load-select>
<!-- 规格类型筛选 -->
<div class="spe-type">
<el-radio v-model="speRadio" label="2">通过规格值筛选</el-radio>
<el-radio v-model="speRadio" label="1">通过规格值组筛选</el-radio>
</div>
</div>
<div class="spe-con">
<!-- <spes v-if="spesGroup" :list-spes="spesList" :goods-index="goodsIndex"></spes>
<spe-group v-if="spesVal" :list-group="groupList" :goods-index="goodsIndex" @spe-list="speList"></spe-group> -->
<spes v-if="spesGroup && speRadio == '1'" :list-spes="spesList" :return-list="returnList" :goods-index="goodsIndex"></spes>
<spe-group v-if="spesVal && speRadio == '2'" :list-group="groupList" :return-list="returnList" :goods-index="goodsIndex" @spe-list="speList"></spe-group>
</div>
<slot></slot>
</div>
</template>
<script>
import Emitter from './assist/emitter';
import Spes from './spes';
import SpeGroup from './spe-group';
import LoadSelect from './load-select';
import GicLoadItem from './load-item';
import { baseUrl } from '@/config/index.js';
export default {
name: 'goods-specifications',
mixins: [Emitter],
components: {
Spes,
SpeGroup,
LoadSelect,
GicLoadItem
},
props: {
goodsIndex: Array,
listReback: Array
},
data() {
return {
spesGroup: false,
spesVal: false,
speOptions: [], // 规格
speRadio: '2',
currentPage: 1,
load: false,
specvalue: '',
spesList: [],
returnList: [],
groupList: [] // 规格值 在规格值组里面
};
},
watch: {
listReback: {
immediate: true,
handler(newval) {
console.log(newval);
// 根据parentId
}
}
},
methods: {
speList(list) {
this.dispatch('vue-gic-goods-selector', 'pass-spe-group-list', {
index: this.goodsIndex,
item: list
});
},
loadMore() {
if (this.speOptions.length == (this.currentPage - 1) * 20) {
this.getOptionsData('success');
} else {
this.load = true;
}
},
// 规格查找
getOptionsData(suc) {
const param = {
type: 'TYP_NORMAL',
currentPage: this.currentPage,
pageSize: 20
};
this.axios
.get(`${baseUrl}/api-goods/page-standard?requestProject=goods`, {
params: param
})
.then(res => {
let data;
if (res.data.errorCode === 0) {
data = res.data.result;
this.speOptions = this.speOptions.concat(data.result);
this.currentPage++;
if (suc == 'success') {
this.load = true;
}
} else {
this.$message.error(res.data.message);
}
})
.catch(err => {
this.$message.error(err);
});
},
changeLoad() {
this.load = false;
},
resiver(val) {
// 选中的值
this.specvalue = val;
this.specList = this.speOptions.find(val => val.standardName == this.specvalue);
this.standardId = this.specList.standardId;
if (this.specList && this.specList.standardId) {
this.validateGoods(this.specList.standardId);
}
this.dispatch('vue-gic-goods-selector', 'pass-standardId', {
index: this.goodsIndex,
items: {
parentId: this.standardId
}
});
},
// 查询是规格值还是规格值组
validateGoods(id) {
this.axios.get(`${baseUrl}/api-goods/validate-standard-pull-data?requestProject=goods&standardId=${id}`).then(res => {
const data = res.data;
// false是规格值组 true 是规格值
if (data.errorCode === 0) {
if (data.result) {
this.spesGroup = false;
this.spesVal = true;
this.speRadio = '2';
this.getSpeData();
} else {
this.spesVal = false;
this.spesGroup = true;
this.speRadio = '1';
this.getSpeGroupData();
}
}
});
},
// 规格值分组数据
getSpeGroupData() {
const param = {
currentPage: 1,
pageSize: 20,
parentId: this.specList.standardId,
type: 'TYP_GROUP',
categoryId: this.specList.gicStandardId
};
this.axios
.get(`${baseUrl}/api-goods/page-standard?requestProject=goods`, {
params: param
})
.then(res => {
if (res.data.errorCode === 0) {
const data = res.data.result;
if (data.result && data.result.length) {
this.spesList = data.result;
} else {
this.spesList = [];
}
}
})
.catch(err => {
console.log(err);
});
},
// 规格值数据
getSpeData() {
const param = {
currentPage: 1,
pageSize: 20,
standardId: this.specList.standardId
};
this.axios
.get(`${baseUrl}/api-goods/page-standard-values?requestProject=goods`, {
params: param
})
.then(res => {
if (res.data.errorCode === 0) {
const data = res.data.result;
if (data.result && data.result.length) {
const middleData = data.result;
this.groupList = middleData;
} else {
this.groupList = [];
}
}
})
.catch(err => {
console.log(err);
});
}
},
mounted() {
// this.$on('pass-item', this.resiver);
// 用来回显规格
setTimeout(() => {
let index = this.speOptions.findIndex(el => el.standardId == this.listReback.parentId);
if (index > -1) {
this.specvalue = this.speOptions[index].standardName;
this.specList = this.speOptions.find(val => val.standardName == this.specvalue);
this.returnList = this.listReback.ids;
this.validateGoods(this.listReback.parentId);
}
}, 100);
},
beforeMount() {
this.getOptionsData();
}
};
</script>
<style lang="less" scoped>
.goods-box {
.check-title {
height: 48px;
line-height: 48px;
padding-left: 20px;
font-size: 14px;
background-color: #ebeef5;
border-top-right-radius: 5px;
border-top-left-radius: 5px;
}
.spe-con {
max-height: 295px;
padding: 10px 20px;
overflow: hidden;
}
.spe-type {
float: right;
margin-right: 20px;
}
}
</style>
import vueGicSelector from './index.vue';
const gicSelector = {
install(Vue, options) {
Vue.component(vueGicSelector.name, vueGicSelector);
}
};
if (typeof window !== 'undefined' && window.Vue) {
window.Vue.use(gicSelector);
}
export default gicSelector;
<template>
<li class="load-item" @click="handleClick">
<slot>
<span>{{ currentLabel }}</span>
</slot>
</li>
</template>
<script>
import Emitter from './assist/emitter';
export default {
name: 'gic-load-item',
mixins: [Emitter],
props: {
value: {
required: true
},
label: [String, Number]
},
computed: {
currentLabel() {
return this.label || this.value;
}
},
methods: {
handleClick() {
this.$emit('pass-item', this.currentLabel);
}
}
};
</script>
<style lang="less" scoped>
.load-item {
height: 24px;
line-height: 24px;
padding: 4px 10px;
cursor: pointer;
color: #606266;
&:hover {
background-color: #f5f7fa;
}
}
</style>
<template>
<el-popover placement="bottom" width="195" trigger="click" v-model="loadShow" popper-class="select-popper">
<ul class="load-ul" @scroll="handleScroll" ref="loadbox">
<slot></slot>
<p class="el-select-dropdown__empty no-data" v-if="isEmpty">
<i class="el-icon-loading"></i>
{{ emptyTxt }}
</p>
</ul>
<div class="load-select" slot="reference">
<el-input placeholder="请选择" v-model="selectLabel" readonly="readonly" :class="{ 'is-focus': visible }" ref="select">
<i slot="suffix" :class="['el-select__caret', 'el-input__icon', 'el-icon-arrow-up' + iconClass]" @click="handleIconClick"> </i>
</el-input>
</div>
</el-popover>
</template>
<script>
// import LoadItem from './load-item'; // 加载的item选项
export default {
name: 'load-select',
// components: {
// LoadItem
// },
props: {
value: {
required: true
},
load: {
type: Boolean,
default: false
},
loadover: {
type: Boolean,
default: false
}
},
computed: {
iconClass() {
if (this.visible) {
return ' is-reverse';
} else {
return '';
}
}
},
data() {
return {
readonly: false,
visible: false,
selectLabel: '',
isEmpty: false,
emptyTxt: '',
loadShow: false
};
},
watch: {
load: {
immediate: true,
handler(newval) {
if (newval) {
this.isEmpty = false;
this.$emit('change-load');
// 方案一 加载时候移动一下
// 方案二 价格loadover 标识
this.$refs.loadbox.scrollTop = this.$refs.loadbox.scrollHeight - 250;
}
}
},
value(newval) {
this.selectLabel = newval;
this.loadShow = false;
this.visible = false;
},
loadShow(newval) {
if (newval) {
this.visible = true;
} else {
this.visible = false;
}
}
},
methods: {
handleIconClick() {
this.visible = !this.visible;
},
// 滚动监听
handleScroll(e) {
const ele = e.target;
// scrollHeight 获取元素内容高度
// scrollTop 可以获取或者设置元素的偏移值
// 满足滚到底部和上次加载结束两个条件
if (ele.scrollHeight - ele.scrollTop == 220 && !this.isEmpty) {
// 滚到底部 先加载
this.emptyTxt = '加载中';
this.isEmpty = true;
setTimeout(_ => {
this.$emit('scrollload');
}, 500);
}
}
}
};
</script>
<style lang="less" scoped>
.load-select {
display: inline-block;
width: 200px;
cursor: pointer;
}
.load-ul {
position: relative;
max-height: 200px;
padding-bottom: 20px;
overflow: auto;
.no-data {
padding: 0;
text-align: center;
color: #ccc;
}
}
.el-select__caret {
color: #c0c4cc;
font-size: 14px;
transition: transform 0.3s;
transform: rotateZ(180deg);
cursor: pointer;
}
.el-select__caret.is-reverse {
transform: rotateZ(0deg);
}
</style>
<template>
<div class="sku-filter">
<div class="title">
<el-checkbox v-model="checkAll" :indeterminate="isIndeterminate" @change="handleCheckAllChange" v-if="!skuFlt"></el-checkbox>
<span class="arrow-bottom" v-if="skuFlt"></span>
<span class="good-info">
商品信息
</span>
<el-popover placement="bottom" width="300" trigger="hover" v-model="showPopPrice">
<el-input placeholder="最低单价" :minlength="1" :maxlength="6" style="width: 90px;" v-model="lowPrice"></el-input>
<el-input placeholder="最高单价" :minlength="1" :maxlength="6" style="width: 90px;" v-model="mostPrice"></el-input>
&nbsp;
<el-button type="primary" @click="searchGoods">搜索</el-button>
<span class="price" :class="{ 'showpop-price': showPopPrice }" slot="reference" @click="showPopPrice = !showPopPrice">
单价
<i class="icon iconfont icon-shaixuan-shi icon-filter"></i>
</span>
</el-popover>
<el-popover placement="bottom" width="300" trigger="hover" v-model="showPopNum">
<el-input placeholder="最低数量" :minlength="1" :maxlength="6" style="width: 90px;" v-model="lowStore"></el-input>
<el-input placeholder="最高数量" :minlength="1" :maxlength="6" style="width: 90px;" v-model="mostStore"></el-input>
&nbsp;
<el-button type="primary" @click="storeSearch">搜索</el-button>
<span class="price store" :class="{ 'showpop-num': showPopNum }" slot="reference" @click="showPopNum = !showPopNum">
库存
<i class="icon iconfont icon-shaixuan-shi icon-filter"></i>
</span>
</el-popover>
</div>
<ul class="goods-sku-lists" @scroll="scrollEvent($event)">
<sku-left-item v-for="(item, i) in items" :key="i" :goods="item" :inx="i" :check="skuFlt" :checkbox.sync="item.check" @changeIndeterminate="handleIndeter"></sku-left-item>
<span class="el-table__empty-text no-data" v-if="!items || !items.length">暂无数据</span>
</ul>
</div>
</template>
<script>
import SkuLeftItem from './sku-left-item';
import { throttle } from './assist/util';
// 正则
const INTEGER_REG = /^[1-9]{1}[0-9]{0,5}$/; // 最小1 最大999999 的整数
export default {
name: 'SkuFilterTable',
components: {
SkuLeftItem
},
props: {
data: Array,
skufilter: Boolean // sku筛选
},
data() {
return {
skuFlt: null,
checkAll: false,
visiable: false,
items: [],
mostPrice: null,
lowPrice: null,
lowStore: null,
mostStore: null,
showPopPrice: false,
showPopNum: false,
isIndeterminate: false,
loadDone: false,
checkedGoods: [] // 选中的商品
};
},
methods: {
scrollEvent(event) {
const ele = event.target;
// scrollHeight 获取元素内容高度
// scrollTop 可以获取或者设置元素的偏移值
// 满足滚到底部和上次加载结束两个条件
if (ele.scrollHeight - ele.scrollTop == 303 && !this.loadDone) {
// 滚到底部 先加载
this.loadDone = true;
setTimeout(_ => {
this.$emit('scrollload');
this.loadDone = false;
}, 50);
}
},
// 处理最低的库存
handleLowStore() {
// 占位
},
// 处理最高的库存
handleMostStore() {
// 占位
},
// item 是勾选的sku信息
resiverSku(val) {
// val里面有个check
if (val.checkAll === true) {
this.$emit('resiverAllSku', {
skus: val.skus,
inx: val.inx
});
} else {
this.$emit('resiverSku');
}
},
// 单价搜索
searchGoods() {
// 占位
this.$emit('search-store', {
regionName: 'PRICE',
lowerLimit: this.lowPrice,
upperLimit: this.mostPrice
});
},
// 库存搜索
storeSearch() {
// 占位
this.$emit('search-store', {
regionName: 'STOCK',
lowerLimit: this.lowStore,
upperLimit: this.mostStore
});
},
handleCheckAllChange(val) {
this.items = this.items.map(el => ({
...el,
check: val
}));
this.isIndeterminate = false;
this.$emit('resiverSku', this.items);
},
// 修改checkbox的状态
handleIndeter() {
this.checkedGoods = this.items.filter(el => el.check);
this.checkAll = this.checkedGoods.length === this.items.length;
this.isIndeterminate = this.checkedGoods.length > 0 && this.checkedGoods.length < this.items.length;
},
// 正则限制输入价格和库存
regInput(val) {
if (!INTEGER_REG.test(val)) {
this.$message.warning('单价必须大于0!');
}
}
},
mounted() {
this.$on('passku', this.resiverSku);
// 低价
this.$watch(
'lowPrice',
throttle(newval => {
this.regInput(newval);
}, 500)
);
// 高级
this.$watch(
'mostPrice',
throttle(newval => {
this.regInput(newval);
}, 500)
);
},
watch: {
skufilter: {
immediate: true,
handler(newval) {
this.skuFlt = newval;
}
},
data: {
immediate: true,
handler(newval) {
this.items = newval;
}
},
checkedGoods: {
immediate: true,
handler(newval) {
this.$emit('resiverSku');
}
}
}
};
</script>
<style lang="less" scoped>
.sku-filter {
height: 350px;
padding-bottom: 20px;
.title {
height: 44px;
line-height: 44px;
padding: 0 10px;
font-size: 14px;
background-color: #f5f7fa;
border-top-right-radius: 5px;
border-top-left-radius: 5px;
color: #909399;
.arrow-bottom {
display: inline-block;
vertical-align: middle;
width: 14px;
}
span {
display: inline-block;
text-align: center;
height: 44px;
}
.good-info {
width: 160px;
text-align: left;
padding-left: 10px;
}
.price {
position: relative;
width: 60px;
outline: none;
border: none;
.icon-filter::before {
top: 10px;
}
}
.store {
position: relative;
width: 60px;
}
.showpop-price,
.showpop-num {
background-color: #e3e5eb;
}
}
.goods-sku-lists {
height: 303px;
overflow: auto;
list-style: none;
.no-data {
display: inline-block;
width: 100%;
text-align: center;
font-size: 14px;
}
}
}
</style>
<template>
<li class="sku-item" v-if="popShow">
<el-popover placement="bottom" :width="320" trigger="hover">
<div slot="reference">
<el-checkbox v-model="skuItem.check" @change="handleChange"></el-checkbox>
<div class="good-img">
<img :src="skuItem.img" />
</div>
<div class="good-info">
<p class="name" :title="skuItem.goodsName">{{ skuItem.goodsName }}</p>
<p class="code" :title="skuItem.goodsCode">{{ skuItem.goodsCode }}</p>
</div>
</div>
<table-checkbox :data="skuItem.skus" b-color="white"></table-checkbox>
</el-popover>
</li>
<li class="sku-item" v-else>
<el-checkbox v-model="skuItem.check" @change="handleChange"></el-checkbox>
<div class="good-img">
<img :src="skuItem.img" />
</div>
<div class="good-info">
<p class="name">{{ skuItem.goodsName }}</p>
<p class="code">{{ skuItem.goodsCode }}</p>
</div>
</li>
</template>
<script>
import TableCheckbox from './table-checkbox';
export default {
name: 'sku-item',
components: {
TableCheckbox
},
props: {
skuList: Object,
popShow: Boolean
},
data() {
return {
skuItem: {},
visiable: false
};
},
methods: {
handleChange(val) {
this.$emit('update:check', val);
this.$emit('pass-check');
}
},
watch: {
skuList: {
immediate: true,
handler(newval) {
this.skuItem = newval;
}
}
}
};
</script>
<style lang="less" scoped>
.sku-item {
height: 56px;
line-height: 56px;
padding: 0 10px;
box-sizing: border-box;
border-bottom: 1px solid #dcdfe6;
.good-img {
margin: 0 10px;
display: inline-block;
vertical-align: middle;
height: 35px;
width: 35px;
img {
height: 100%;
width: 100%;
}
}
.good-info {
display: inline-block;
vertical-align: middle;
p {
margin: 0;
font-size: 12px;
width: 73px;
height: 20px;
line-height: 20px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
&:last-child {
border-bottom: none;
}
}
</style>
<template>
<li class="sku-left-item">
<!-- 这里是商品的结构 如果有sku的筛选 就会展示箭头 默认不展示sku的选择 -->
<div class="goods-box" :class="{ expands: expands }">
<div class="gic-icon">
<el-checkbox v-model="skuItem.check" @change="handleChange" v-if="!checked"></el-checkbox>
<i class="icon-trans el-icon-arrow-right" @click="expands = !expands" v-if="checked"></i>
</div>
<div class="good-img">
<img class="img" :src="skuItem.mainImageUrl" />
<div class="info">
<p class="name" :title="skuItem.goodsName">{{ skuItem.goodsName }}</p>
<p class="code" :titile="skuItem.goodsCode">{{ skuItem.goodsCode }}</p>
</div>
</div>
<div class="good-item good-price">
{{ skuItem.salePrice }}
</div>
<div class="good-item good-store">
{{ skuItem.spuStock }}
</div>
</div>
<!-- 如果勾选sku 展示sku show-checkbox 决定是左边的勾选 还是右边的pop显示 一个是展示 一个是待操作 -->
<el-collapse-transition>
<table-checkbox :data="skuItem.skus" show-checkbox v-if="expands" :inx="inx" @passku="resiverSku"></table-checkbox>
</el-collapse-transition>
</li>
</template>
<script>
import ElCollapseTransition from './collapse-transition';
import TableCheckbox from './table-checkbox';
import Emitter from './assist/emitter';
import { baseUrl } from '@/config/index.js';
export default {
name: 'sku-left-item',
mixins: [Emitter],
components: {
ElCollapseTransition,
TableCheckbox
},
props: {
check: Boolean,
goods: Object,
inx: Number
},
data() {
return {
checked: null, // 是显示el-box 还是显示 > ( 也就是sku的筛选 )
skuItem: null,
expands: false
};
},
methods: {
handleChange(val) {
this.$emit('update:checkbox', val);
this.$emit('changeIndeterminate');
},
// 接收 sku筛选的时候传过来的值
resiverSku(item) {
this.dispatch('');
},
getSkuList() {
this.axios
.get(`${baseUrl}/api-goods/list-store-goods-select-sku?goodsId=${this.skuItem.goodsId}`)
.then(res => {
if (res.data.errorCode === 0) {
const data = res.data.result;
if (data && data.length) {
this.skuItem.skus = data.map(el => ({
...el,
color: this.parseAttr(el.skuAttributes).color,
size: this.parseAttr(el.skuAttributes).size
}));
// 当前商品id 跟左边的数据对比
const component = this.findComponentUpward(this, 'goods-some');
if (component.filterData.length) {
const data = component.filterData;
// 当前商品左边的商品
if (data.length) {
const currentGoods = data.find(ele => this.skuItem.goodsId === ele.goodsId);
// 找到存在的sku 然后切换状态
currentGoods.skus.forEach(sku => {
for (let i = 0; i < this.skuItem.skus.length; i++) {
if (this.skuItem.skus[i].skuId === sku.skuId) {
this.skuItem.skus[i].check = true;
break;
}
}
});
// 主动切换sku的状态
this.broadcast('table-checkbox', 'changeSkuStatus');
}
}
} else {
this.skuItem.skus = [];
}
}
})
.catch(err => {
console.log(err);
});
},
parseAttr(attr = '') {
if (!attr) return { color: '--', size: '--' };
let attrs = JSON.parse(attr);
return {
color: attrs[0].valueName,
size: attrs[1].valueName
};
}
},
watch: {
check: {
immediate: true,
handler(newval) {
this.checked = newval;
if (!newval) {
this.expands = false;
}
}
},
goods: {
immediate: true,
handler(newval) {
console.log(newval);
this.skuItem = newval;
}
},
expands(newval) {
// 请求商品的sku
if (newval) {
this.getSkuList();
}
}
}
};
</script>
<style lang="less" scoped>
.sku-left-item {
font-size: 12px;
color: #606266;
border-bottom: 1px solid #dcdfe6;
.expands {
border-bottom: 1px solid #dcdfe6;
}
.gic-icon {
display: inline-block;
vertical-align: middle;
width: 16px;
height: 56px;
line-height: 56px;
padding: 0 10px;
box-sizing: content-box;
}
.good-img {
display: inline-block;
vertical-align: middle;
height: 56px;
width: 160px;
.img {
display: inline-block;
vertical-align: middle;
height: 40px;
width: 40px;
border-radius: 2px;
}
.info {
display: inline-block;
vertical-align: middle;
padding: 6px 0;
p {
width: 110px;
height: 16px;
line-height: 16px;
margin: 4px 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
.good-info {
display: inline-block;
vertical-align: middle;
}
.good-item {
display: inline-block;
vertical-align: middle;
text-align: center;
width: 60px;
}
.goods-box {
.icon-trans {
padding: 4px;
transition: all 0.3s;
}
}
.expands .icon-trans {
transform: rotate(90deg);
}
&:last-child {
margin-bottom: -1px;
padding-bottom: 20px;
}
}
</style>
<template>
<div class="spe-group">
<div class="spe-transfer-left spe-transfer">
<div class="check-all check-all-left">
<el-checkbox v-model="checkLeft" :indeterminate="isIndeterminate" @change="handleChange">全选</el-checkbox>
<span></span>
</div>
<div class="transfer-tree">
<el-input prefix-icon="el-icon-search" style="width: 200px; margin: 10px 0px;" v-model="treeLeftval" placeholder="请输入规格值名称筛选" @keyup.native.enter="leftSearch($event)"></el-input>
<div class="tree-content">
<el-tree ref="leftTree" :data="rightData" show-checkbox node-key="valueId" :default-expand-all="true" :default-checked-keys="defaultLeftKeys" :props="defaultProps" @check="handleLeftCheck"> </el-tree>
</div>
</div>
</div>
<div class="spe-transfer-button">
<!-- 把左边选择的数据移到右边 -->
<el-button type="primary" @click.native="addToLeft" :disabled="!leftChecked.length" class="el-transfer__button">
<i class="el-icon-arrow-right"></i>
</el-button>
<el-button type="primary" @click.native="addToRight" :disabled="!rightChecked.length" class="el-transfer__button ">
<i class="el-icon-arrow-left"></i>
</el-button>
</div>
<div class="spe-transfer-right spe-transfer">
<div class="check-all check-all-right">
<el-checkbox :indeterminate="isRightIndeterminate" v-model="checkRight" @change="handleRightChangeAll">全选</el-checkbox>
<span></span>
</div>
<div class="transfer-tree">
<el-input prefix-icon="el-icon-search" style="width: 200px; margin: 10px 0px;" v-model="treeRightval" placeholder="请输入规格值名称筛选" @keyup.native.enter="rightSearch($event)"> </el-input>
<div class="tree-content">
<el-tree ref="rightTree" :data="leftData" show-checkbox node-key="valueId" :default-expand-all="true" :default-checked-keys="defaultRightKeys" :props="defaultProps" @check="handleRightCheck"> </el-tree>
</div>
</div>
</div>
</div>
</template>
<script>
/* eslint-disable */
export default {
name: 'spe-group',
props: {
listGroup: {
type: Array,
default() {
return [];
}
},
returnList: Array
},
data() {
return {
isIndeterminate: false,
isRightIndeterminate: false,
leftData: [],
rightData: [],
leftChecked: [],
rightChecked: [],
defaultProps: {
children: 'standardGroup',
label: 'valueName'
},
treeRightval: '',
treeLeftval: '',
checkLeft: false,
checkRight: false,
defaultLeftKeys: [], // 左边默认选中
defaultRightKeys: [], //
leftMiddleData: [],
rightMiddleData: []
};
},
watch: {
listGroup: {
immediate: true,
handler(val) {
this.rightData = val;
this.leftMiddleData = val;
this.leftData = [];
}
},
leftData(newval) {
if (newval.length > 0) {
this.$emit('spe-list', newval);
}
},
rightData(newval) {
console.log(newval);
},
},
methods: {
// 左边过滤
leftSearch(eve) {
let val = eve.target.value;
this.rightData = this.leftMiddleData.filter(el => el.valueName.indexOf(val) > -1);
this.$refs.leftTree.setCheckedKeys([]);
this.checkLeft = false;
this.isIndeterminate = false;
},
rightSearch(eve) {
let val = eve.target.value;
this.leftData = this.rightMiddleData.filter(el => el.valueName.indexOf(val) > -1);
this.$refs.rightTree.setCheckedKeys([]);
this.checkRight = false;
this.isRightIndeterminate = false;
},
addToRight() {
// const checkNodes = this.$refs.rightTree.getCheckedNodes();
const checkIds = this.$refs.rightTree.getCheckedKeys();
for (let i = 0; i < checkIds.length; i++) {
let index = this.leftData.findIndex(el => el.valueId === checkIds[i]);
if (index > -1) {
checkIds.splice(i, 1);
i--;
this.leftData.splice(index, 1);
this.rightMiddleData.splice(index, 1);
}
}
if (!this.leftData.length) {
this.checkRight = false;
}
},
/** 处理树形选中的树形数据然后把选中的数据筛出来
* @param { list } 传进来的树形结构
*
* */
handleTreeData(list) {
const checkIds = this.$refs.leftTree.getCheckedKeys();
const middleData = JSON.parse(JSON.stringify(list));
checkIds.forEach((id, i) => {
let inx = middleData.findIndex(el => el.valueId == id);
if (inx > -1) {
this.leftData.push(middleData[inx]);
}
});
this.$refs.rightTree.setCheckedKeys([]);
this.checkRight = false;
this.rightMiddleData = JSON.parse(JSON.stringify(this.leftData));
},
addToLeft() {
/**
* 左侧是目前最多两层的树形(暂时两层的但是还是得当成很多层处理 一劳永逸)
* 首先获取左边选中的id集合 然后把左边的数据深度拷贝一份
* 先对比第一层的id 如果不相等就比较第二层的id 过滤
*/
this.leftData = [];
this.handleTreeData(this.rightData);
},
handleLeftCheck(data, current) {
// 左边选择的节点
this.leftChecked = current.checkedKeys;
if (this.leftChecked.length > 0 && this.leftChecked.length < this.rightData.length) {
this.isIndeterminate = true;
} else if (this.leftChecked.length == this.rightData.length) {
this.isIndeterminate = false;
this.checkLeft = true;
} else {
this.isIndeterminate = false;
this.checkLeft = false;
}
},
handleRightCheck(data, current) {
// 右边选择的节点
this.rightChecked = current.checkedKeys;
if (this.rightChecked.length > 0 && this.rightChecked.length < this.leftData.length) {
this.isRightIndeterminate = true;
} else if (this.rightChecked.length == this.leftData.length) {
this.isRightIndeterminate = false;
this.checkRight = true;
} else {
this.isRightIndeterminate = false;
this.checkRight = false;
}
},
handleChange(val) {
if (this.rightData && this.rightData.length) {
if (val) {
this.defaultLeftKeys = this.rightData.map(el => el.valueId);
this.leftChecked = this.rightData;
this.isIndeterminate = false;
} else {
this.$refs.leftTree.setCheckedKeys([]);
this.leftChecked = [];
this.isIndeterminate = false;
}
}
},
handleRightChangeAll(val) {
if (this.leftData && this.leftData.length) {
if (val) {
this.defaultRightKeys = this.leftData.map(el => el.valueId);
this.rightChecked = this.leftData;
this.isRightIndeterminate = false;
} else {
this.$refs.rightTree.setCheckedKeys([]);
this.rightChecked = [];
this.isRightIndeterminate = false;
}
}
},
handleRightChange(val) {
if (this.leftData && this.leftData.length) {
if (val) {
this.defaultRightKeys = this.leftData.map(el => el.valueId);
this.rightChecked = this.leftData;
} else {
this.$refs.leftTree.setCheckedKeys([]);
this.rightChecked = [];
}
}
}
},
mounted() {
setTimeout(() => {
const list = JSON.parse(JSON.stringify(this.rightData));
this.returnList.forEach(el => {
let i = list.findIndex(item => el.valueId == item.valueId);
if (i > -1) {
this.leftData.push(list[i]);
}
});
}, 100);
}
};
</script>
<style lang="less" scoped>
.spe-group {
position: relative;
height: 285px;
box-sizing: border-box;
border-radius: 5px;
border: 1px solid #dcdfe6;
font-size: 0px;
.spe-transfer {
display: inline-block;
vertical-align: middle;
width: 258px;
height: 285px;
box-sizing: border-box;
.check-all {
height: 20px;
line-height: 20px;
padding: 10px;
background-color: #f5f7fa;
box-sizing: content-box;
}
.check-all-left {
border-top-left-radius: 5px;
}
.check-all-right {
border-top-right-radius: 5px;
}
.transfer-tree {
text-align: center;
border-radius: 50%;
}
.tree-content {
height: 190px;
overflow: auto;
}
}
.spe-transfer-left {
border-right: 1px solid #dcdfe6;
}
.spe-transfer-right {
border-left: 1px solid #dcdfe6;
}
.spe-transfer-button {
display: inline-block;
vertical-align: middle;
width: 50px;
padding: 0 20px;
box-sizing: content-box;
}
.el-transfer__button {
margin: 0 auto;
margin-bottom: 10px;
}
}
</style>
<template>
<!-- 商品规格 规格值筛选 -->
<div class="good-spes">
<el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange">全选</el-checkbox>
<div class="box-group">
<el-checkbox-group v-model="checkedSpes" @change="handleCheckedSpesChange">
<el-checkbox v-for="spe in spes" :label="spe" :key="spe.standardId">
{{ spe.standardName }}
</el-checkbox>
</el-checkbox-group>
</div>
</div>
</template>
<script>
import Emitter from './assist/emitter';
// 商品规格
export default {
name: 'good-spes',
mixins: [Emitter],
props: {
listSpes: {
type: Array,
default() {
return [];
}
},
goodsIndex: Array,
returnList: Array
},
data() {
return {
checkAll: false,
checkedSpes: [],
spes: [],
isIndeterminate: false
};
},
watch: {
listSpes: {
immediate: true,
handler(val) {
this.spes = val;
}
},
checkedSpes(newval) {
this.dispatch('vue-gic-goods-selector', 'pass-spes', {
index: this.goodsIndex,
items: newval
});
}
},
methods: {
handleCheckAllChange(val) {
this.checkedSpes = val ? this.spes : [];
this.isIndeterminate = false;
},
handleCheckedSpesChange(value) {
let checkedCount = value.length;
this.checkAll = checkedCount === this.spes.length;
this.isIndeterminate = checkedCount > 0 && checkedCount < this.spes.length;
}
},
mounted() {
setTimeout(() => {
this.returnList.forEach(el => {
let i = this.spes.findIndex(item => el.standardId == item.standardId);
if (i > -1) {
this.checkedSpes.push(this.spes[i]);
}
});
let checkedCount = this.checkedSpes.length;
this.checkAll = checkedCount === this.spes.length;
this.isIndeterminate = checkedCount > 0 && checkedCount < this.spes.length;
}, 100);
},
};
</script>
<style lang="less" scoped>
.good-spes .box-group {
margin-top: 10px;
}
</style>
.goods-box {
.check-title {
height: 48px;
line-height: 48px;
padding-left: 20px;
border: 1px solid #dcdfe6;
border-bottom: none;
background-color: #f5f7fa;
}
.brand-group {
padding: 10px 20px;
border: 1px solid #dcdfe6;
border-top: none;
}
.brand-list {
min-width: 175px;
line-height: 30px;
margin-left: 0;
margin-right: 10px;
}
}
\ No newline at end of file
<template>
<!-- 表格内部sku筛选的组件 -->
<div class="sku-checkbox" :class="{ 'sku-white': bgColor }" v-if="skus.length">
<div class="sku-table">
<el-checkbox v-model="allSku" v-if="showCurrentCheckBox" :indeterminate="isIndeterminate" @change="handleCheckAllChange"></el-checkbox>
<span class="sku-attr sku-code">SKU码</span>
<span class="sku-attr sku-color">颜色</span>
<span class="sku-attr sku-size">大小</span>
</div>
<ul class="sku-lists">
<li v-for="(sku, i) in skus" :key="i" class="list">
<el-checkbox v-if="showCurrentCheckBox" v-model="sku.check" @change="handleCheckedSku"></el-checkbox>
<span class="sku-attr sku-code" :title="sku.skuCode">{{ sku.skuCode }}</span>
<span class="sku-color sku-attr">
{{ sku.color }}
</span>
<span class="sku-size sku-attr">
{{ sku.size }}
</span>
</li>
</ul>
</div>
<div class="no-sku-data" v-else>
<i class="icon iconfont icon-jibenxinxi"></i>
暂无数据
</div>
</template>
<script>
import Emitter from './assist/emitter';
export default {
name: 'table-checkbox',
mixins: [Emitter],
props: {
data: {
type: Array,
default() {
return [];
}
},
showCheckbox: Boolean,
bColor: String,
inx: Number
},
data() {
return {
skus: [],
allSku: false,
showCurrentCheckBox: false,
isIndeterminate: false,
checkedSku: []
};
},
methods: {
handleSkuStatus() {
this.checkedSku = this.skus.filter(el => el.check);
this.allSku = this.checkedSku.length === this.skus.length;
this.isIndeterminate = this.checkedSku.length > 0 && this.checkedSku.length < this.skus.length;
},
handleCheckAllChange(val) {
this.skus = this.skus.map(el => ({
...el,
check: val
}));
this.isIndeterminate = false;
this.dispatch('SkuFilterTable', 'passku', {
skus: this.skus,
inx: this.inx,
checkAll: val
});
},
handleCheckedSku() {
console.log('商品');
this.handleSkuStatus();
// 每次勾选sku的时候传到最外层的商品层
this.dispatch('SkuFilterTable', 'passku', {
skus: this.skus,
inx: this.inx
});
}
},
created() {
this.showCurrentCheckBox = this.showCheckbox;
this.bgColor = this.bColor ? this.bColor : '';
},
mounted() {
// 切换sku的状态 跟左边对应
this.$on('changeSkuStatus', this.handleSkuStatus);
},
watch: {
data: {
immediate: true,
handler(newval) {
console.log(newval, 's');
this.skus = newval;
}
}
}
};
</script>
<style lang="less" scoped>
.sku-checkbox {
padding: 10px;
.sku-attr {
display: inline-block;
vertical-align: middle;
margin: 0 5px;
line-height: 30px;
color: #909399;
}
.sku-code {
width: 130px;
}
.sku-color {
width: 50px;
text-align: center;
}
.sku-size {
width: 50px;
text-align: center;
}
.sku-lists {
.list {
height: 35px;
line-height: 35px;
}
}
}
.sku-white {
background-color: #fff;
.sku-table {
border-bottom: 1px solid #dcdfe6;
}
}
.no-sku-data {
margin: 15px 0;
text-align: center;
color: #8ab3d9;
.icon-jibenxinxi {
display: block;
margin-bottom: 10px;
color: #8ab3d9;
font-size: 18px;
}
}
</style>
<template> </template>
<script>
export default {
name: 'tree-node'
};
</script>
......@@ -653,19 +653,20 @@
<!-- 嵌入商品选择器 -->
<div v-if="parent.templateCode == 'com022'">
<vue-gic-goods-selector ref="selector"></vue-gic-goods-selector>
<div class="gic-button">
<el-button type="primary" @click="confirmSelector" v-if="select.expends">确认</el-button>
<el-button @click="goback" v-else>返回</el-button>
<vue-gic-goods-selector ref="selector" @changelist="changelist"></vue-gic-goods-selector>
<!-- <vue-gic-selector ref="selector" @changelist="changelist"></vue-gic-selector> -->
<div class="gic-button" v-show="select.expends">
<el-button type="primary" @click="confirmSelector">确认</el-button>
</div>
</div>
</div>
</div>
</template>
<script>
import qs from 'qs';
// import vueGicSelector from '@/components/selector/index.vue';
import tagDetails from '@/components/tagDetail/mixin/index';
import VueGicCard from '@/components/card/card';
import { getTagType, findWidget, findOndJson } from '@/request/tagConfig';
......@@ -692,6 +693,7 @@ export default {
components: {
VueGicCard
// vueGicSelector
},
data() {
......@@ -896,7 +898,10 @@ export default {
},
// 商品选择器
com022: {
selectList: []
selectList: [],
conditionsList: [],
abbrInfo: '',
finalId: null
},
// 卡券选择器
com023: {
......@@ -911,29 +916,27 @@ export default {
handler(newval) {
this.id = newval;
}
},
templateDataList: {
immediate: true,
handler(newval) {
//
}
}
},
methods: {
goback() {
this.select.expends = !this.select.expends;
this.$refs.selector[0].removeConditions();
changelist() {
this.select.expends = true;
},
// 获取商品选择器的缩略信息
confirmSelector() {
this.$refs.selector[0].collectConditions().then(res => {
this.select.expends = !res.filterAbbrInfo.length;
this.com022.selectList = res.conditions;
this.com022.abbrInfo = res.filterAbbrInfo;
this.com022.conditionsList = res.conditionList;
this.com022.finalId = res.id;
});
async confirmSelector() {
let flag = this.$refs.selector[0].collectConditions();
if (flag == false) {
this.$message.warning('商品选择器条件不能为空!');
} else {
flag.then(res => {
this.select.expends = !res.filterAbbrInfo.length;
this.com022.selectList = res.conditions;
this.com022.abbrInfo = res.filterAbbrInfo;
this.com022.conditionsList = res.conditionList;
this.com022.finalId = res.id;
});
}
},
// 格式化输入的字符
handleNumRangeStart(eve) {
......@@ -1612,9 +1615,9 @@ export default {
break;
case 'com022':
this.$refs.selector[0].conditions = tagParams.conditionList;
this.confirmSelector();
this.select.expends = false;
this.$refs.selector[0].conditions = JSON.parse(JSON.stringify(tagParams.template[0].conditionsList));
// this.confirmSelector();
// this.select.expends = false;
break;
// 卡券
......
......@@ -430,6 +430,7 @@ export default {
for (let i = 0; i < this.templateData.length; i++) {
// 商品选择器
if (this.templateData[i].templateCode == 'com022') {
await this.confirmSelector();
if (!this.com022.selectList || !this.com022.selectList.length) {
this.$message.warning('商品选择器未选择条件!')
return false;
......@@ -440,7 +441,7 @@ export default {
tagValue.val[0].data.value = this.com022.finalId;
let abbr = this.translateAbbrinfo(this.com022.abbrInfo);
this.postTemplateData.selectedVal.push(abbr.join(' '));
that.postTemplateData.conditionList = this.com022.conditionsList;
this.postTemplateData.conditionList = this.com022.conditionsList;
}
}
......@@ -961,8 +962,6 @@ export default {
}
// 门店参数修改
that.templateData.forEach(function(ele, index) {
if (ele.templateCode == 'tag011') {
......@@ -981,10 +980,11 @@ export default {
}
}
}
that.postTemplateData.template = that.templateData;
tagParams = that.postTemplateData;
tagParams.selectedVal = tagParams.selectedVal.map(el => el.replace(/(null|undefined)/g, ''));
// console.log(this.postTemplateData.conditionList);
await this.addToTemp(tagValue, tagParams);
return true;
},
......
const host = window.location.origin;
// eslint-disable-next-line
export const baseUrl = host.indexOf('localhost') > '-1' ? 'http://gicdev.demogic.com' : host;
export const ERR_OK = 0;
<template>
<div>
<!-- 添加标签、编辑标签 -->
<el-dialog :title="title" :visible.sync="showEditTagPop" width="1000px" top="10vh" :before-close="handleClose" custom-class="edit-tag" :close-on-click-modal="false" append-to-body>
<el-dialog :title="title" :visible.sync="showEditTagPop" top="10vh" width="900px" :before-close="handleClose" custom-class="edit-tag" :close-on-click-modal="false" append-to-body>
<div class="dialog-box">
<div class="tag-info">
<p class="tag-name">
......@@ -78,7 +78,6 @@ export default {
handleSave() {
const ret = this.$refs.tagConfig.getTemplateData();
this.templateData = JSON.parse(JSON.stringify(ret));
this.tagId = this.tagDataAssgin.tagId;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment