UNPKG

element-ui-for-gov

Version:

element-ui for gov

331 lines (319 loc) 10.9 kB
import ElRow from 'element-ui-for-gov/packages/row'; import ElCol from 'element-ui-for-gov/packages/col'; import ElButton from 'element-ui-for-gov/packages/button'; import ElTree from 'element-ui-for-gov/packages/tree'; import Store from 'element-ui-for-gov/src/utils/tree-store'; import SectionHeader from './section-header'; import SelectedList from './selected-list'; const prefix = 'el-user-picker'; export default { name: 'Transfer', inject: ['handleChangeUser', 'clearChecked', 'nodeKey', 'setTreeInstance'], props: { treeProps: Object, fieldNames: Object, grid: Object, checkedUsers: Array, filterNodeMethod: Function, defaultChecked: Array, renderChecked: Function, renderCheckedItem: Function, selectPanelButton: Function, radio: Boolean, isSearchCheckAll: Boolean, height: Number, checkOnClickNode: Boolean }, components: {ElRow, ElCol, ElButton, ElTree, SectionHeader, SelectedList}, data() { return { treeData: [], store: null, totalData: [], searchData: [], prevChecked: [], searchWrapHeight: 0 }; }, created() { const {lazy, loadData, children, disabled} = this.treeProps; const {fieldNames} = this; this.store = new Store({ key: this.nodeKey, label: data => data[fieldNames.parent] || data[fieldNames.userName], isLeaf: (data) => !!data[fieldNames.userName], hideCheckbox: 'hideCheckbox', children: children || 'children', disabled: disabled || 'disabled', data: [] }); !lazy ? loadData().then((data) => { this.store.initData(data); this.treeData = this.store.data; this.totalData = this.treeData; this.searchData = this.treeData; this.setDefaultChecked(this.defaultChecked); }) : this.setDefaultChecked(this.defaultChecked); }, mounted() { this.setTreeInstance(this.treeProps.key, this); this.initFilterResize(); }, watch: { defaultChecked(users) { this.$nextTick(() => { this.setDefaultChecked(users); }); }, checkedUsers(arr) { let nodes = []; arr.forEach(item => { const cache = this.store.getNodes(item); nodes = nodes.concat(cache); }); this.prevChecked = [].concat(nodes); // console.log('selected nodes: ', nodes); this.$nextTick(() => { this.setCheckedNodes(nodes); }); } }, methods: { initFilterResize() { const filterWrapper = this.$el.querySelector('.custom-filter-wrapper'); if (filterWrapper) { try { const resizeObserver = new ResizeObserver(entries => { for (let entry of entries) { if (entry.contentRect.height > 0) { this.searchWrapHeight = filterWrapper.offsetHeight; } } }); resizeObserver.observe(filterWrapper); } catch (e) { this.$nextTick(() => { this.searchWrapHeight = filterWrapper.offsetHeight; }); } } }, setDefaultChecked(keys) { // console.log(ids); let users = []; keys.forEach(user => { // console.log(user); let nodes = typeof user === 'object' ? [{data: user}] : this.store.getNodesByKey(user); if (nodes.length) { users.push(nodes[0].data); } }); this.handleChangeUser(users); }, handleCheck(node, {checkedNodes}) { if (this.radio) { let users = []; if (checkedNodes.includes(node)) { users = [node.data]; } this.handleChangeUser(users); } else { const deleteArr = this.store.difference(this.prevChecked, checkedNodes.filter(node => node.isLeaf)); // console.log(deleteArr); const users = checkedNodes.filter(node => node.isLeaf).map(item => item.data); const deleteUsers = deleteArr.filter(node => node.isLeaf).map(item => item.data); this.handleChangeUser(users, deleteUsers); } }, getCheckedNodes() { const nodes = this.$refs['tree'].getCheckedNodes(); const users = nodes.filter(node => node.isLeaf).map(item => item.data); if (this.radio) { if (users && users.length) { this.handleChangeUser(users, []); } } else { this.handleChangeUser(users, []); } }, checkAll() { console.log('checkAll'); const {checkAllMethod} = this.treeProps; if (checkAllMethod) { checkAllMethod(this, (users) => { this.handleChangeUser(users); }); } else { const users = []; const traverse = (arr) => { arr.forEach(item => { if (item.isLeaf && !item.disabled) { users.push(item.data); } else if (item.children) { traverse(item.children); } }); }; if (this.isSearchCheckAll) { traverse(this.searchData); } else { traverse(this.totalData); } this.handleChangeUser(users); } }, setCheckedNodes(nodes) { this.$refs['tree'].setCheckedNodes(nodes); }, filter(value) { const filteredData = []; const traverse = (arr) => { arr.forEach(item => { if (this.filterNodeMethod(value, item, item)) { filteredData.push(item); } else if (item.children) { traverse(item.children); } }); }; traverse(this.totalData); this.searchData = filteredData; this.$refs['tree'].filter(value); }, setTreeData(data) { this.store.initData(data, this.treeProps.lazy); this.treeData = this.store.data; this.searchData = this.store.data; this.setDefaultChecked(this.defaultChecked); }, bfsRegisterNode(data, current) { const getChildren = (node) => { const children = this.treeProps.children || 'children'; return typeof children === 'function' ? children(node) : node[children]; }; const queue = [{root: true, children: data}]; const queueNode = [current]; while (queue.length) { const head = queue.shift(); const parent = queueNode.shift(); if (Array.isArray(head.children)) { for (let i = 0, len = head.children.length; i < len; i++) { const node = this.store.registerNode(head.children[i]); node.parent = parent; parent.children.push(node); queue.push({ ...head.children[i], children: getChildren(head.children[i]) }); queueNode.push(node); } } } }, bfsTravel(node, cb) { const queue = [node]; while (queue.length) { const head = queue.shift(); cb && cb(head); if (Array.isArray(head.children)) { for (let i = 0; i < head.children.length ; i++) { queue.push(head.children[i]); } } } }, loadDataAsync(node, resolve, isCheck) { const {loadDataAsync} = this.treeProps; // console.log('load', node); loadDataAsync(node.data ? node.data : node, data => { // console.log(data); if (data && data.length > 0) { const current = !node.parent ? {children: []} : node.data; this.bfsRegisterNode(data, current); if (!node.parent) { this.store.data = current.children; this.totalData = this.store.data; this.searchData = this.store.data; } if (!isCheck) { if (this.radio) { if (this.checkedUsers && this.checkedUsers.length && this.defaultChecked.length) { if (this.checkedUsers[0].id && this.checkedUsers[0].id === this.defaultChecked[0].id) { this.setDefaultChecked([this.defaultChecked[0]]); } } } else { const sList = []; this.checkedUsers.forEach((node) => { this.defaultChecked.forEach((nodeD) => { if (nodeD.key && nodeD.key === node.key) { sList.push(node); } }); }); this.setDefaultChecked(sList); } } else { const selectList = []; this.bfsTravel(current, (node) => { if (!node.disabled && node.isLeaf) { selectList.push(node.key); } }); this.defaultChecked.forEach((item) => { if (!selectList.includes(item)) { selectList.push(item); } }); this.setDefaultChecked(selectList); } return resolve(current.children); } else { return resolve([]); } }, isCheck); } }, render() { const {treeData, fieldNames, treeProps, checkedUsers, $slots, renderChecked, renderCheckedItem, selectPanelButton, height, checkOnClickNode} = this; return (<ElRow> <ElCol span={10}> <div class={`${prefix}__section-wrapper`}> <SectionHeader title="待选列表" /> {$slots.filter && <div class="custom-filter-wrapper">{$slots.filter}</div> } <div class={`${prefix}__section-content`} style={{height: `${height ? height - this.searchWrapHeight - 1 : 464 - this.searchWrapHeight}px`}}> <ElTree ref="tree" lazy={treeProps.lazy} data={treeData} nodeKey="id" load={this.loadDataAsync} props={{ hideCheckbox: 'hideCheckbox', isLeaf: item => item.isLeaf }} show-checkbox checkOnClickNode={checkOnClickNode} expand-on-check={treeProps.lazy} filterNodeMethod={this.filterNodeMethod} {...{ on: { // 'check-change': treeProps.lazy ? this.handleCheckChange : this.getCheckedNodes, 'node-expand': treeProps.lazy ? this.getCheckedNodes : () => {}, 'check': this.handleCheck } }} /> </div> </div> </ElCol> <ElCol span={4} class={`${prefix}__section-btns`}> {!this.radio && <ElButton {...{on: {click: this.checkAll}}}>全选<i class="el-icon-arrow-right"/></ElButton>} <br /> <ElButton {...{on: {click: this.clearChecked}}}>清空已选</ElButton> </ElCol> <ElCol span={10}> <SelectedList height={this.height} checkedUsers={checkedUsers} label={fieldNames.userName} renderChecked={renderChecked} renderCheckedItem={renderCheckedItem} selectPanelButton={selectPanelButton} /> </ElCol> </ElRow>); } };