组织管理
parent
daf86f30ee
commit
51a43af100
@ -1,263 +0,0 @@
|
|||||||
<template>
|
|
||||||
<layout-content
|
|
||||||
:header="formType == 'add' ? $t('menu.create') : $t('menu.modify')"
|
|
||||||
back-name="system-menu"
|
|
||||||
>
|
|
||||||
<el-form
|
|
||||||
ref="menuForm"
|
|
||||||
:model="form"
|
|
||||||
:rules="rule"
|
|
||||||
size="small"
|
|
||||||
label-width="auto"
|
|
||||||
label-position="right"
|
|
||||||
>
|
|
||||||
<el-form-item :label="$t('menu.menu_type')" prop="type">
|
|
||||||
<el-radio-group
|
|
||||||
v-model="form.type"
|
|
||||||
size="mini"
|
|
||||||
:disabled="formType !== 'add'"
|
|
||||||
>
|
|
||||||
<el-radio-button label="0">{{
|
|
||||||
$t("commons.catalogue")
|
|
||||||
}}</el-radio-button>
|
|
||||||
<el-radio-button label="1">{{ $t("commons.menu") }}</el-radio-button>
|
|
||||||
<el-radio-button label="2">{{
|
|
||||||
$t("commons.button")
|
|
||||||
}}</el-radio-button>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item
|
|
||||||
v-if="form.type === 1 && form.icon"
|
|
||||||
:label="$t('commons.icon')"
|
|
||||||
prop="icon"
|
|
||||||
>
|
|
||||||
<el-popover
|
|
||||||
placement="bottom-start"
|
|
||||||
width="425"
|
|
||||||
trigger="click"
|
|
||||||
@show="$refs['iconSelect'].reset()"
|
|
||||||
>
|
|
||||||
<IconSelect ref="iconSelect" @selected="selected" />
|
|
||||||
<el-input
|
|
||||||
slot="reference"
|
|
||||||
v-model="form.icon"
|
|
||||||
:placeholder="$t('menu.select_icon')"
|
|
||||||
readonly
|
|
||||||
>
|
|
||||||
<svg-icon
|
|
||||||
v-if="form.icon"
|
|
||||||
slot="prefix"
|
|
||||||
:icon-class="form.icon"
|
|
||||||
class="el-input__icon"
|
|
||||||
style="height: 32px; width: 16px"
|
|
||||||
/>
|
|
||||||
<i v-else slot="prefix" class="el-icon-search el-input__icon" />
|
|
||||||
</el-input>
|
|
||||||
</el-popover>
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-form-item
|
|
||||||
v-if="form.type !== 2"
|
|
||||||
:label="$t('menu.tile')"
|
|
||||||
prop="title"
|
|
||||||
>
|
|
||||||
<el-input v-model="form.title" :placeholder="$t('menu.tile')" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item
|
|
||||||
v-if="form.type === 2"
|
|
||||||
:label="$t('menu.button_name')"
|
|
||||||
prop="title"
|
|
||||||
>
|
|
||||||
<el-input v-model="form.title" :placeholder="$t('menu.button_name')" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item
|
|
||||||
v-if="form.type !== 2"
|
|
||||||
:label="$t('menu.menu_sort')"
|
|
||||||
prop="menuSort"
|
|
||||||
>
|
|
||||||
<el-input-number
|
|
||||||
v-model.number="form.menuSort"
|
|
||||||
:min="0"
|
|
||||||
:max="999"
|
|
||||||
controls-position="right"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item :label="$t('menu.parent_category')" prop="pid">
|
|
||||||
<treeselect
|
|
||||||
v-model="form.pid"
|
|
||||||
:disabled="formType !== 'add'"
|
|
||||||
:options="menus"
|
|
||||||
:load-options="loadMenus"
|
|
||||||
:placeholder="$t('menu.parent_category')"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" @click="save">{{
|
|
||||||
$t("commons.reset")
|
|
||||||
}}</el-button>
|
|
||||||
<el-button @click="reset">{{ $t("commons.confirm") }}</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
</layout-content>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import LayoutContent from "@/components/business/LayoutContent";
|
|
||||||
import Treeselect from "@riophae/vue-treeselect";
|
|
||||||
import IconSelect from "@/components/IconSelect";
|
|
||||||
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
|
|
||||||
import {
|
|
||||||
LOAD_CHILDREN_OPTIONS,
|
|
||||||
LOAD_ROOT_OPTIONS,
|
|
||||||
} from "@riophae/vue-treeselect";
|
|
||||||
import {
|
|
||||||
addMenu,
|
|
||||||
editMenu,
|
|
||||||
getMenusTree,
|
|
||||||
treeByMenuId,
|
|
||||||
} from "@/api/system/dept";
|
|
||||||
export default {
|
|
||||||
components: { LayoutContent, Treeselect, IconSelect },
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
topMunu: { id: 0, label: "顶级目录", children: null },
|
|
||||||
defaultForm: {
|
|
||||||
menuId: null,
|
|
||||||
title: null,
|
|
||||||
menuSort: 999,
|
|
||||||
path: null,
|
|
||||||
component: null,
|
|
||||||
componentName: null,
|
|
||||||
iframe: false,
|
|
||||||
pid: 0,
|
|
||||||
icon: null,
|
|
||||||
cache: false,
|
|
||||||
hidden: false,
|
|
||||||
type: 0,
|
|
||||||
permission: null,
|
|
||||||
},
|
|
||||||
form: {},
|
|
||||||
rule: {
|
|
||||||
name: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: this.$t("organization.input_name"),
|
|
||||||
trigger: "blur",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
min: 2,
|
|
||||||
max: 25,
|
|
||||||
message: this.$t("commons.input_limit", [2, 25]),
|
|
||||||
trigger: "blur",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
description: [
|
|
||||||
{
|
|
||||||
max: 50,
|
|
||||||
message: this.$t("commons.input_limit", [0, 50]),
|
|
||||||
trigger: "blur",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
menus: null,
|
|
||||||
maps: new Map(),
|
|
||||||
formType: "add",
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
created() {
|
|
||||||
if (
|
|
||||||
this.$router.currentRoute.params &&
|
|
||||||
this.$router.currentRoute.params.menuId
|
|
||||||
) {
|
|
||||||
const row = this.$router.currentRoute.params;
|
|
||||||
this.edit(row);
|
|
||||||
} else {
|
|
||||||
this.create();
|
|
||||||
}
|
|
||||||
this.initData();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
create() {
|
|
||||||
this.formType = "add";
|
|
||||||
this.form = Object.assign({}, this.defaultForm);
|
|
||||||
},
|
|
||||||
edit(row) {
|
|
||||||
this.formType = "modify";
|
|
||||||
this.form = Object.assign({}, row);
|
|
||||||
this.initMenuTree();
|
|
||||||
},
|
|
||||||
initMenuTree() {
|
|
||||||
treeByMenuId(this.form.pid || 0).then((res) => {
|
|
||||||
const results = res.data.map((node) => {
|
|
||||||
if (node.hasChildren && !node.children) {
|
|
||||||
node.children = null;
|
|
||||||
}
|
|
||||||
return node;
|
|
||||||
});
|
|
||||||
this.menus = results;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
// 获取弹窗内部门数据
|
|
||||||
loadMenus({ action, parentNode, callback }) {
|
|
||||||
if (action === LOAD_ROOT_OPTIONS) {
|
|
||||||
const _self = this;
|
|
||||||
!this.menus &&
|
|
||||||
getMenusTree("0").then((res) => {
|
|
||||||
_self.menus = res.data.map((node) => _self.normalizer(node));
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (action === LOAD_CHILDREN_OPTIONS) {
|
|
||||||
const _self = this;
|
|
||||||
getMenusTree(parentNode.id).then((res) => {
|
|
||||||
parentNode.children = res.data.map(function (obj) {
|
|
||||||
return _self.normalizer(obj);
|
|
||||||
});
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
initData() {
|
|
||||||
this.menus = [];
|
|
||||||
this.menus.push(this.topMunu);
|
|
||||||
},
|
|
||||||
normalizer(node) {
|
|
||||||
if (node.hasChildren) {
|
|
||||||
node.children = null;
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
id: node.menuId,
|
|
||||||
label: node.title,
|
|
||||||
children: node.children,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
selected(name) {
|
|
||||||
this.form.icon = name;
|
|
||||||
},
|
|
||||||
|
|
||||||
reset() {
|
|
||||||
this.$refs.menuForm.resetFields();
|
|
||||||
},
|
|
||||||
save() {
|
|
||||||
this.$refs.menuForm.validate((valid) => {
|
|
||||||
if (valid) {
|
|
||||||
const method = this.formType === "add" ? addMenu : editMenu;
|
|
||||||
method(this.form).then((res) => {
|
|
||||||
this.$success(this.$t("commons.save_success"));
|
|
||||||
this.backToList();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
backToList() {
|
|
||||||
this.$router.push({ name: "system-menu" });
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
@ -1,26 +1,244 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<layout-content
|
||||||
<async-component
|
:header="formType == 'add' ? $t('organization.create') : $t('organization.modify')"
|
||||||
url="http://localhost:9528/static/SystemDeptForm.js"
|
back-name="system-dept"
|
||||||
></async-component>
|
>
|
||||||
</div>
|
<el-form ref="deptForm" :model="form" :rules="rule" size="small" label-width="auto" label-position="right">
|
||||||
|
<el-form-item :label="$t('organization.name')" prop="name">
|
||||||
|
<el-input v-model="form.name" :placeholder="$t('organization.name')" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="$t('organization.sort')" prop="deptSort">
|
||||||
|
<el-input-number v-model="form.deptSort" :min="0" :max="999" controls-position="right" :placeholder="$t('organization.sort')" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="$t('organization.top_org')" prop="top">
|
||||||
|
<el-radio-group v-model="form.top" @change="topChange">
|
||||||
|
<el-radio-button :label="true">{{ $t('commons.yes') }}</el-radio-button>
|
||||||
|
<el-radio-button :label="false">{{ $t('commons.no') }}</el-radio-button>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-if="form.pid !== 0" :label="$t('organization.parent_org')" prop="pid">
|
||||||
|
<treeselect
|
||||||
|
v-model="form.pid"
|
||||||
|
:auto-load-root-options="false"
|
||||||
|
:options="depts"
|
||||||
|
:load-options="loadDepts"
|
||||||
|
:placeholder="$t('organization.select_parent_org')"
|
||||||
|
@select="nodeChange"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="save">{{ $t('commons.reset') }}</el-button>
|
||||||
|
<el-button @click="reset">{{ $t('commons.confirm') }}</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</layout-content>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import AsyncComponent from "@/components/AsyncComponent";
|
import LayoutContent from '@/components/business/LayoutContent'
|
||||||
|
import Treeselect from '@riophae/vue-treeselect'
|
||||||
|
import IconSelect from '@/components/IconSelect'
|
||||||
|
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
|
||||||
|
import {
|
||||||
|
LOAD_CHILDREN_OPTIONS,
|
||||||
|
LOAD_ROOT_OPTIONS
|
||||||
|
} from '@riophae/vue-treeselect'
|
||||||
|
import {
|
||||||
|
addMenu,
|
||||||
|
editMenu,
|
||||||
|
getMenusTree,
|
||||||
|
treeByMenuId
|
||||||
|
} from '@/api/system/dept'
|
||||||
|
import { execute } from '@/api/system/dynamic'
|
||||||
export default {
|
export default {
|
||||||
name: "SystemDept",
|
name: 'SystemDeptForm',
|
||||||
components: {
|
components: { LayoutContent },
|
||||||
AsyncComponent,
|
|
||||||
},
|
|
||||||
data() {
|
data() {
|
||||||
return {};
|
return {
|
||||||
|
defaultForm: { deptId: null, top: true, pid: null },
|
||||||
|
maps: new Map(),
|
||||||
|
form: {},
|
||||||
|
rule: {
|
||||||
|
name: [{ required: true, message: this.$t('organization.input_name'), trigger: 'blur' }, { min: 2, max: 25, message: this.$t('commons.input_limit', [2, 25]), trigger: 'blur' }],
|
||||||
|
description: [{ max: 50, message: this.$t('commons.input_limit', [0, 50]), trigger: 'blur' }]
|
||||||
|
},
|
||||||
|
depts: null,
|
||||||
|
|
||||||
|
formType: 'add',
|
||||||
|
pLabel: this.$t('dept.root_org')
|
||||||
|
}
|
||||||
},
|
},
|
||||||
mounted() {},
|
|
||||||
methods: {},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
created() {
|
||||||
</style>
|
if (this.$router.currentRoute.params && this.$router.currentRoute.params.deptId) {
|
||||||
|
var row = this.$router.currentRoute.params
|
||||||
|
this.edit(row)
|
||||||
|
} else {
|
||||||
|
this.create()
|
||||||
|
}
|
||||||
|
this.setLoyoutInfo()
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.bindKey()
|
||||||
|
},
|
||||||
|
destroyed() {
|
||||||
|
this.unBindKey()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
entryKey(event) {
|
||||||
|
var keyCode = event.keyCode
|
||||||
|
if (keyCode === 13) {
|
||||||
|
this.save()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
bindKey() {
|
||||||
|
document.addEventListener('keypress', this.entryKey)
|
||||||
|
},
|
||||||
|
unBindKey() {
|
||||||
|
document.removeEventListener('keypress', this.entryKey)
|
||||||
|
},
|
||||||
|
executeAxios(url, type, data, callBack) {
|
||||||
|
var param = {
|
||||||
|
url: url,
|
||||||
|
type: type,
|
||||||
|
data: data,
|
||||||
|
callBack: callBack
|
||||||
|
}
|
||||||
|
execute(param)
|
||||||
|
.then(function(res) {
|
||||||
|
if (param.callBack) {
|
||||||
|
param.callBack(res)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(function(e) {
|
||||||
|
if (param.error) {
|
||||||
|
param.error(e)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
setLoyoutInfo() {
|
||||||
|
this.$emit('on-plugin-layout', {
|
||||||
|
header: this.formType === 'add' ? this.$t('organization.create') : this.$t('organization.modify'),
|
||||||
|
backName: 'system-dept'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
create() {
|
||||||
|
this.formType = 'add'
|
||||||
|
this.form = Object.assign({}, this.defaultForm)
|
||||||
|
},
|
||||||
|
edit(row) {
|
||||||
|
this.formType = 'modify'
|
||||||
|
this.form = Object.assign({}, row)
|
||||||
|
this.initDeptTree()
|
||||||
|
},
|
||||||
|
initDeptTree() {
|
||||||
|
var _this = this
|
||||||
|
this.executeAxios('/plugin/dept/nodesByDeptId/' + (this.form.pid || 0), 'post', {}, function(res) {
|
||||||
|
var results = res.data.map(function(node) {
|
||||||
|
if (node.hasChildren && !node.children) {
|
||||||
|
node.children = null
|
||||||
|
}
|
||||||
|
return node
|
||||||
|
})
|
||||||
|
_this.depts = results
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 获取弹窗内部门数据
|
||||||
|
loadDepts(_ref) {
|
||||||
|
var action = _ref.action
|
||||||
|
var parentNode = _ref.parentNode
|
||||||
|
var callback = _ref.callback
|
||||||
|
|
||||||
|
if (action === 'LOAD_ROOT_OPTIONS' && !this.form.pid) {
|
||||||
|
var _self = this
|
||||||
|
this.executeAxios('/plugin/dept/nodesByDeptId/' + 0, 'post', {}, function(res) {
|
||||||
|
var results = res.data.map(function(node) {
|
||||||
|
if (node.hasChildren && !node.children) {
|
||||||
|
node.children = null
|
||||||
|
}
|
||||||
|
return node
|
||||||
|
})
|
||||||
|
_self.depts = _self.excludeSelf(results)
|
||||||
|
callback()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action === 'LOAD_CHILDREN_OPTIONS') {
|
||||||
|
var _self2 = this
|
||||||
|
this.executeAxios('/plugin/dept/childNodes/' + parentNode.id, 'post', {}, function(res) {
|
||||||
|
var kids = res.data.map(function(obj) {
|
||||||
|
return _self2.normalizer(obj)
|
||||||
|
})
|
||||||
|
|
||||||
|
parentNode.children = _self2.excludeSelf(kids)
|
||||||
|
callback()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
normalizer(node) {
|
||||||
|
if (node.hasChildren) {
|
||||||
|
node.children = null
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
id: node.deptId,
|
||||||
|
label: node.name,
|
||||||
|
children: node.children
|
||||||
|
}
|
||||||
|
},
|
||||||
|
topChange(value) {
|
||||||
|
if (!value) {
|
||||||
|
this.form.pid = null
|
||||||
|
this.depts = null
|
||||||
|
this.pLabel = this.$t('dept.root_org')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
reset() {
|
||||||
|
if (this.formType !== 'add') {
|
||||||
|
var row = this.$router.currentRoute.params
|
||||||
|
this.edit(row)
|
||||||
|
} else {
|
||||||
|
this.$refs.deptForm.resetFields()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
save() {
|
||||||
|
var _this2 = this
|
||||||
|
|
||||||
|
this.$refs.deptForm.validate(function(valid) {
|
||||||
|
if (valid) {
|
||||||
|
var url = _this2.formType === 'add' ? '/plugin/dept/create' : '/plugin/dept/update'
|
||||||
|
_this2.executeAxios(url, 'post', _this2.form, function(res) {
|
||||||
|
if (res.data && res.data === -2) {
|
||||||
|
var msg = _this2.pLabel + _this2.$t('dept.name_exist_pre') + _this2.form.name + _this2.$t('dept.name_exist_suf')
|
||||||
|
_this2.$warning(msg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_this2.$success(_this2.$t('commons.save_success'))
|
||||||
|
_this2.backToList()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
backToList() {
|
||||||
|
this.$router.push({ name: 'system-dept' })
|
||||||
|
},
|
||||||
|
excludeSelf(nodes) {
|
||||||
|
var _this3 = this
|
||||||
|
|
||||||
|
if (this.formType !== 'modify') return nodes
|
||||||
|
nodes.forEach(function(node) {
|
||||||
|
return node.id === _this3.form.deptId && (node.isDisabled = true)
|
||||||
|
})
|
||||||
|
return nodes
|
||||||
|
},
|
||||||
|
nodeChange(node, instanceId) {
|
||||||
|
if (node.label) {
|
||||||
|
this.pLabel = node.label
|
||||||
|
}
|
||||||
|
// console.log(node)
|
||||||
|
console.log(instanceId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|||||||
@ -1,26 +1,443 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<layout-content
|
||||||
<async-component
|
v-loading="$store.getters.loadingMap[$store.getters.currentPath]"
|
||||||
url="http://localhost:9528/static/SystemDept.js"
|
>
|
||||||
></async-component>
|
<tree-table
|
||||||
</div>
|
:columns="columns"
|
||||||
|
:search-config="searchConfig"
|
||||||
|
@search="search"
|
||||||
|
>
|
||||||
|
<template #toolbar>
|
||||||
|
<el-button
|
||||||
|
v-permission="['dept:add']"
|
||||||
|
icon="el-icon-circle-plus-outline"
|
||||||
|
@click="create"
|
||||||
|
>{{ $t("organization.create") }}</el-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<el-table
|
||||||
|
ref="table"
|
||||||
|
:class="'de-dept-table-class'"
|
||||||
|
:style="{'width':'100%'}"
|
||||||
|
:data="tableData"
|
||||||
|
lazy
|
||||||
|
:load="loadExpandDatas"
|
||||||
|
:indent="30"
|
||||||
|
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
||||||
|
row-key="deptId"
|
||||||
|
>
|
||||||
|
<!-- <el-table-column type="selection" fix /> -->
|
||||||
|
<el-table-column
|
||||||
|
:show-overflow-tooltip="true"
|
||||||
|
:label="$t('organization.name')"
|
||||||
|
prop="name"
|
||||||
|
>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span :data-id="scope.row.deptId" class="dept-name" :class="(scope.row.subCount === 0 && scope.row.pid === 0) ? 'indent-no-child': ''" @drop="endDrag" @dragover="allowDrop">
|
||||||
|
<span :id="scope.row.deptId" :draggable="true" @dragstart="startDrag">
|
||||||
|
{{ scope.row.name }}
|
||||||
|
</span>
|
||||||
|
</span></template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="subCount"
|
||||||
|
:label="$t('organization.sub_organizations')"
|
||||||
|
align="center"
|
||||||
|
/>
|
||||||
|
<el-table-column
|
||||||
|
prop="createTime"
|
||||||
|
:label="$t('organization.create_time')"
|
||||||
|
align="center"
|
||||||
|
>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span :data-id="scope.row.deptId" class="dept-name" :class="(scope.row.subCount === 0 && scope.row.pid === 0) ? 'indent-no-child': ''" @drop="endDrag" @dragover="allowDrop">
|
||||||
|
{{ scope.row.createTime | timestampFormatDate }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<fu-table-operations
|
||||||
|
:buttons="buttons"
|
||||||
|
:label="$t('commons.operating')"
|
||||||
|
fix
|
||||||
|
/>
|
||||||
|
</el-table>
|
||||||
|
</tree-table>
|
||||||
|
</layout-content>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import AsyncComponent from "@/components/AsyncComponent";
|
import LayoutContent from '@/components/business/LayoutContent'
|
||||||
|
import TreeTable from '@/components/business/tree-table'
|
||||||
|
// import { checkPermission } from '@/utils/permission'
|
||||||
|
import IconSelect from '@/components/IconSelect'
|
||||||
|
import Treeselect from '@riophae/vue-treeselect'
|
||||||
|
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
|
||||||
|
import {
|
||||||
|
LOAD_CHILDREN_OPTIONS,
|
||||||
|
LOAD_ROOT_OPTIONS
|
||||||
|
} from '@riophae/vue-treeselect'
|
||||||
|
import { checkPermission } from '@/utils/permission'
|
||||||
|
import { getDeptTree, loadTable, treeByDeptId } from '@/api/system/dept'
|
||||||
|
import { formatCondition, formatQuickCondition } from '@/utils/index'
|
||||||
|
import { execute } from '@/api/system/dynamic'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "SystemDept",
|
name: 'SystemDept',
|
||||||
components: {
|
components: {
|
||||||
AsyncComponent,
|
TreeTable,
|
||||||
|
LayoutContent
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {};
|
return {
|
||||||
|
depts: null,
|
||||||
|
tableData: [],
|
||||||
|
maps: new Map(),
|
||||||
|
|
||||||
|
permission: {
|
||||||
|
add: ['dept:add'],
|
||||||
|
edit: ['dept:edit'],
|
||||||
|
del: ['dept:del']
|
||||||
|
},
|
||||||
|
header: '',
|
||||||
|
columns: [],
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
label: this.$t('commons.edit'),
|
||||||
|
icon: 'el-icon-edit',
|
||||||
|
type: 'primary',
|
||||||
|
click: this.edit,
|
||||||
|
show: this.checkPermission(['dept:edit'])
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('commons.delete'),
|
||||||
|
icon: 'el-icon-delete',
|
||||||
|
type: 'danger',
|
||||||
|
click: this._handleDelete,
|
||||||
|
disabled: this.btnDisabled,
|
||||||
|
show: this.checkPermission(['dept:del'])
|
||||||
|
}
|
||||||
|
],
|
||||||
|
searchConfig: {
|
||||||
|
useQuickSearch: true,
|
||||||
|
quickPlaceholder: this.$t('organization.search_by_name'),
|
||||||
|
components: [
|
||||||
|
{
|
||||||
|
field: 'name',
|
||||||
|
label: this.$t('organization.name'),
|
||||||
|
component: 'DeComplexInput'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
defaultCondition: {
|
||||||
|
field: 'pid',
|
||||||
|
operator: 'eq',
|
||||||
|
value: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.form = Object.assign({}, this.defaultForm)
|
||||||
|
this.search()
|
||||||
|
console.log('dept tree has inited')
|
||||||
},
|
},
|
||||||
mounted() {},
|
methods: {
|
||||||
methods: {},
|
executeAxios(url, type, data, callBack) {
|
||||||
};
|
var param = {
|
||||||
|
url: url,
|
||||||
|
type: type,
|
||||||
|
data: data,
|
||||||
|
callBack: callBack
|
||||||
|
}
|
||||||
|
execute(param)
|
||||||
|
.then(function(res) {
|
||||||
|
if (param.callBack) {
|
||||||
|
param.callBack(res)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(function(e) {
|
||||||
|
if (param.error) {
|
||||||
|
param.error(e)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
create() {
|
||||||
|
this.$router.push({ name: 'system-dept-form' })
|
||||||
|
},
|
||||||
|
edit(row) {
|
||||||
|
this.$router.push({ name: 'system-dept-form', params: row })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 加载表格数据
|
||||||
|
search(condition) {
|
||||||
|
const _this = this
|
||||||
|
if (condition) {
|
||||||
|
condition.quick = { value: condition.name }
|
||||||
|
}
|
||||||
|
condition = formatQuickCondition(condition, 'name')
|
||||||
|
if (condition && condition.name && condition.name.field) {
|
||||||
|
condition = { name: condition.name }
|
||||||
|
}
|
||||||
|
let conditionExist = false
|
||||||
|
const temp = formatCondition(condition)
|
||||||
|
this.tableData = []
|
||||||
|
let param = {}
|
||||||
|
if (temp && temp.conditions && temp.conditions.length !== 0) {
|
||||||
|
conditionExist = true
|
||||||
|
param = temp
|
||||||
|
} else {
|
||||||
|
param = { conditions: [this.defaultCondition] }
|
||||||
|
}
|
||||||
|
this.executeAxios('/plugin/dept/search', 'post', param, function(res) {
|
||||||
|
let data = res.data
|
||||||
|
data = data.map(function(obj) {
|
||||||
|
if (obj.subCount > 0) {
|
||||||
|
obj.hasChildren = true
|
||||||
|
}
|
||||||
|
return obj
|
||||||
|
})
|
||||||
|
|
||||||
|
if (conditionExist) {
|
||||||
|
data = data.map(function(node) {
|
||||||
|
delete node.hasChildren
|
||||||
|
return node
|
||||||
|
})
|
||||||
|
_this.tableData = _this.buildTree(data)
|
||||||
|
_this.$nextTick(function() {
|
||||||
|
data.forEach(function(node) {
|
||||||
|
_this.$refs.table.toggleRowExpansion(node, true)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
_this.tableData = data
|
||||||
|
}
|
||||||
|
|
||||||
|
_this.depts = null
|
||||||
|
})
|
||||||
|
},
|
||||||
|
buildTree(arrs) {
|
||||||
|
var idMapping = arrs.reduce(function(acc, el, i) {
|
||||||
|
acc[el.deptId] = i
|
||||||
|
return acc
|
||||||
|
}, {})
|
||||||
|
var roots = []
|
||||||
|
console.log(123123, arrs)
|
||||||
|
arrs.forEach(function(el) {
|
||||||
|
// 判断根节点
|
||||||
|
if (el.pid === null || el.pid === 0) {
|
||||||
|
roots.push(el)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 用映射表找到父元素
|
||||||
|
var parentEl = arrs[idMapping[el.pid]]
|
||||||
|
// 把当前元素添加到父元素的`children`数组中
|
||||||
|
parentEl.children = parentEl.children || []
|
||||||
|
parentEl.children = [...parentEl.children, ...el]
|
||||||
|
})
|
||||||
|
console.log(333, roots)
|
||||||
|
return roots
|
||||||
|
},
|
||||||
|
|
||||||
|
// 加载下一级子节点数据
|
||||||
|
loadExpandDatas(row, treeNode, resolve) {
|
||||||
|
var _this2 = this
|
||||||
|
this.executeAxios(
|
||||||
|
'/plugin/dept/childNodes/' + row.deptId,
|
||||||
|
'post',
|
||||||
|
{},
|
||||||
|
function(res) {
|
||||||
|
var data = res.data
|
||||||
|
data = data.map(function(obj) {
|
||||||
|
if (obj.subCount > 0) {
|
||||||
|
obj.hasChildren = true
|
||||||
|
}
|
||||||
|
return obj
|
||||||
|
})
|
||||||
|
_this2.maps.set(row.deptId, {
|
||||||
|
row: row,
|
||||||
|
treeNode: treeNode,
|
||||||
|
resolve: resolve
|
||||||
|
})
|
||||||
|
resolve && resolve(data)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
},
|
||||||
|
_handleDelete(organization) {
|
||||||
|
var _this3 = this
|
||||||
|
this.$confirm(this.$t('organization.delete_confirm'), '', {
|
||||||
|
confirmButtonText: this.$t('commons.confirm'),
|
||||||
|
cancelButtonText: this.$t('commons.cancel'),
|
||||||
|
type: 'warning'
|
||||||
|
})
|
||||||
|
.then(function() {
|
||||||
|
var requests = [
|
||||||
|
{ deptId: organization.deptId, pid: organization.pid }
|
||||||
|
]
|
||||||
|
_this3.executeAxios(
|
||||||
|
'/plugin/dept/delete',
|
||||||
|
'post',
|
||||||
|
requests,
|
||||||
|
function(res) {
|
||||||
|
_this3.$success(_this3.$t('commons.delete_success'))
|
||||||
|
_this3.search()
|
||||||
|
_this3.reloadByPid(organization.pid)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.catch(function() {
|
||||||
|
_this3.$message({
|
||||||
|
type: 'info',
|
||||||
|
message: _this3.$t('commons.delete_cancelled')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
reloadByPid(pid) {
|
||||||
|
if (pid !== 0 && this.maps.get(pid)) {
|
||||||
|
var _maps$get = this.maps.get(pid)
|
||||||
|
var row = _maps$get.row
|
||||||
|
var treeNode = _maps$get.treeNode
|
||||||
|
var resolve = _maps$get.resolve
|
||||||
|
|
||||||
|
this.$set(this.$refs.table.store.states.lazyTreeNodeMap, pid, [])
|
||||||
|
this.loadExpandDatas(row, treeNode, resolve)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
btnDisabled(row) {
|
||||||
|
return row.deptId === 1 || row.subCount > 0
|
||||||
|
},
|
||||||
|
startDrag(ev) {
|
||||||
|
ev.dataTransfer.setData('sourceId', ev.target.id)
|
||||||
|
},
|
||||||
|
allowDrop(ev) {
|
||||||
|
ev.preventDefault()
|
||||||
|
},
|
||||||
|
endDrag(ev) {
|
||||||
|
ev.preventDefault()
|
||||||
|
var targetId = ev.target.id
|
||||||
|
var sourceId = ev.dataTransfer.getData('sourceId')
|
||||||
|
|
||||||
|
this.nodeMoveHandler(sourceId, targetId)
|
||||||
|
},
|
||||||
|
nodeMoveHandler(resourceId, targetId) {
|
||||||
|
var _this4 = this
|
||||||
|
|
||||||
|
if (!resourceId || !targetId) return
|
||||||
|
resourceId = parseInt(resourceId)
|
||||||
|
targetId = parseInt(targetId)
|
||||||
|
var parent = this.getParent(resourceId)
|
||||||
|
var pid = parent ? parent.id || parent.deptId : null
|
||||||
|
// if (!pid) {
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// console.log('pid = ' + pid + ', targetId = ' + targetId)
|
||||||
|
if (this.isParentNoChange(pid, targetId)) {
|
||||||
|
this.$warning(this.$t('dept.can_not_move_change_sort'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.isParent2Children(resourceId, targetId)) {
|
||||||
|
this.$warning(this.$t('dept.can_not_move_parent_to_children'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var param = {
|
||||||
|
resourceId: resourceId,
|
||||||
|
targetId: targetId
|
||||||
|
}
|
||||||
|
this.executeAxios('/plugin/dept/move', 'post', param, function(res) {
|
||||||
|
_this4.$success(_this4.$t('dept.move_success'))
|
||||||
|
_this4.search()
|
||||||
|
_this4.reloadByPid(targetId)
|
||||||
|
if (pid) {
|
||||||
|
_this4.reloadByPid(pid)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
// 判断是否是父节点移动到子节点
|
||||||
|
isParent2Children(resourceId, targetId) {
|
||||||
|
var currentId = targetId
|
||||||
|
while (currentId) {
|
||||||
|
if (resourceId === currentId) {
|
||||||
|
// 说明 目标节点是 源节点的子集
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
var parent = void 0
|
||||||
|
if ((parent = this.getParent(currentId)) === null) {
|
||||||
|
// 找到顶都没有 说明就不是子集
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
currentId = parent.id || parent.deptId
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 判断是否移动前后父节点没有改变
|
||||||
|
isParentNoChange(pid, targetId) {
|
||||||
|
return pid === targetId
|
||||||
|
},
|
||||||
|
|
||||||
|
// 根据deptId获取parent
|
||||||
|
getParent(id) {
|
||||||
|
var currentNode = this.getNodeWithId(id)
|
||||||
|
if (!currentNode || !currentNode.pid) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return this.getNodeWithId(currentNode.pid)
|
||||||
|
},
|
||||||
|
getNodeWithId(id) {
|
||||||
|
for (var index = 0; index < this.tableData.length; index++) {
|
||||||
|
var element = this.tableData[index]
|
||||||
|
if ((element.id || element.deptId) === id) {
|
||||||
|
return element
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var lazyTreeNodeMap = this.$refs.table.store.states.lazyTreeNodeMap
|
||||||
|
for (var key in lazyTreeNodeMap) {
|
||||||
|
if (Object.hasOwnProperty.call(lazyTreeNodeMap, key)) {
|
||||||
|
var childNodes = lazyTreeNodeMap[key]
|
||||||
|
for (var i = 0; i < childNodes.length; i++) {
|
||||||
|
var node = childNodes[i]
|
||||||
|
if ((node.id || node.deptId) === id) {
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
.member-size {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.org-member-id {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.org-member-email {
|
||||||
|
float: right;
|
||||||
|
color: #8492a6;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-width {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-css >>> .el-dialog__header {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
::v-deep .el-input-number .el-input__inner {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
::v-deep .vue-treeselect__control,
|
||||||
|
::v-deep .vue-treeselect__placeholder,
|
||||||
|
::v-deep .vue-treeselect__single-value {
|
||||||
|
height: 30px;
|
||||||
|
line-height: 30px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,423 +0,0 @@
|
|||||||
<template>
|
|
||||||
<layout-content
|
|
||||||
v-loading="$store.getters.loadingMap[$store.getters.currentPath]"
|
|
||||||
>
|
|
||||||
<tree-table
|
|
||||||
:columns="columns"
|
|
||||||
:search-config="searchConfig"
|
|
||||||
@search="search"
|
|
||||||
>
|
|
||||||
<template #toolbar>
|
|
||||||
<el-button
|
|
||||||
v-permission="['dept:add']"
|
|
||||||
icon="el-icon-circle-plus-outline"
|
|
||||||
@click="create"
|
|
||||||
>{{ $t("organization.create") }}</el-button
|
|
||||||
>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<el-table
|
|
||||||
ref="table"
|
|
||||||
:data="tableData"
|
|
||||||
lazy
|
|
||||||
:load="search"
|
|
||||||
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
|
||||||
row-key="deptId"
|
|
||||||
>
|
|
||||||
<!-- <el-table-column type="selection" fix /> -->
|
|
||||||
<el-table-column
|
|
||||||
:show-overflow-tooltip="true"
|
|
||||||
:label="$t('organization.name')"
|
|
||||||
prop="name"
|
|
||||||
/>
|
|
||||||
<el-table-column
|
|
||||||
prop="sub_count"
|
|
||||||
:label="$t('organization.sub_organizations')"
|
|
||||||
align="center"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<fu-table-operations
|
|
||||||
:buttons="buttons"
|
|
||||||
:label="$t('commons.operating')"
|
|
||||||
fix
|
|
||||||
/>
|
|
||||||
</el-table>
|
|
||||||
</tree-table>
|
|
||||||
</layout-content>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import LayoutContent from "@/components/business/LayoutContent";
|
|
||||||
import TreeTable from "@/components/business/tree-table";
|
|
||||||
// import { checkPermission } from '@/utils/permission'
|
|
||||||
import IconSelect from "@/components/IconSelect";
|
|
||||||
import Treeselect from "@riophae/vue-treeselect";
|
|
||||||
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
|
|
||||||
import {
|
|
||||||
LOAD_CHILDREN_OPTIONS,
|
|
||||||
LOAD_ROOT_OPTIONS,
|
|
||||||
} from "@riophae/vue-treeselect";
|
|
||||||
import { checkPermission } from "@/utils/permission";
|
|
||||||
import { getDeptTree, loadTable, treeByDeptId } from "@/api/system/dept";
|
|
||||||
import { formatCondition, formatQuickCondition } from "@/utils/index";
|
|
||||||
import { execute } from "@/api/system/dynamic";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "SystemDept",
|
|
||||||
components: {
|
|
||||||
TreeTable,
|
|
||||||
LayoutContent,
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
depts: null,
|
|
||||||
tableData: [],
|
|
||||||
maps: new Map(),
|
|
||||||
|
|
||||||
permission: {
|
|
||||||
add: ["dept:add"],
|
|
||||||
edit: ["dept:edit"],
|
|
||||||
del: ["dept:del"],
|
|
||||||
},
|
|
||||||
header: "",
|
|
||||||
columns: [],
|
|
||||||
buttons: [
|
|
||||||
{
|
|
||||||
label: this.$t("commons.edit"),
|
|
||||||
icon: "el-icon-edit",
|
|
||||||
type: "primary",
|
|
||||||
click: this.edit,
|
|
||||||
show: this.checkPermission(["dept:edit"]),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.$t("commons.delete"),
|
|
||||||
icon: "el-icon-delete",
|
|
||||||
type: "danger",
|
|
||||||
click: this._handleDelete,
|
|
||||||
disabled: this.btnDisabled,
|
|
||||||
show: this.checkPermission(["dept:del"]),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
searchConfig: {
|
|
||||||
useQuickSearch: true,
|
|
||||||
quickPlaceholder: this.$t("organization.search_by_name"),
|
|
||||||
components: [
|
|
||||||
{
|
|
||||||
field: "name",
|
|
||||||
label: this.$t("organization.name"),
|
|
||||||
component: "DeComplexInput",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
defaultCondition: {
|
|
||||||
field: "pid",
|
|
||||||
operator: "eq",
|
|
||||||
value: 0,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.form = Object.assign({}, this.defaultForm);
|
|
||||||
this.search();
|
|
||||||
console.log("dept tree has inited");
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
executeAxios(url, type, data, callBack) {
|
|
||||||
var param = {
|
|
||||||
url: url,
|
|
||||||
type: type,
|
|
||||||
data: data,
|
|
||||||
callBack: callBack,
|
|
||||||
};
|
|
||||||
execute(param)
|
|
||||||
.then(function (res) {
|
|
||||||
if (param.callBack) {
|
|
||||||
param.callBack(res);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(function (e) {
|
|
||||||
if (param.error) {
|
|
||||||
param.error(e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
create() {
|
|
||||||
this.$router.push({ name: "system-dept-form" });
|
|
||||||
},
|
|
||||||
edit(row) {
|
|
||||||
this.$router.push({ name: "system-dept-form", params: row });
|
|
||||||
},
|
|
||||||
|
|
||||||
// 加载表格数据
|
|
||||||
search(condition) {
|
|
||||||
const _this = this;
|
|
||||||
if (condition) {
|
|
||||||
condition.quick = { value: condition.name };
|
|
||||||
}
|
|
||||||
condition = formatQuickCondition(condition, "name");
|
|
||||||
if (condition && condition.name && condition.name.field) {
|
|
||||||
condition = { name: condition.name };
|
|
||||||
}
|
|
||||||
let conditionExist = false;
|
|
||||||
const temp = formatCondition(condition);
|
|
||||||
this.tableData = [];
|
|
||||||
let param = {};
|
|
||||||
if (temp && temp.conditions && temp.conditions.length !== 0) {
|
|
||||||
conditionExist = true;
|
|
||||||
param = temp;
|
|
||||||
} else {
|
|
||||||
param = { conditions: [this.defaultCondition] };
|
|
||||||
}
|
|
||||||
this.executeAxios("/plugin/dept/search", "post", param, function (res) {
|
|
||||||
let data = res.data;
|
|
||||||
data = data.map(function (obj) {
|
|
||||||
if (obj.subCount > 0) {
|
|
||||||
obj.hasChildren = true;
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (conditionExist) {
|
|
||||||
data = data.map(function (node) {
|
|
||||||
delete node.hasChildren;
|
|
||||||
return node;
|
|
||||||
});
|
|
||||||
_this.tableData = _this.buildTree(data);
|
|
||||||
_this.$nextTick(function () {
|
|
||||||
data.forEach(function (node) {
|
|
||||||
_this.$refs.table.toggleRowExpansion(node, true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
_this.tableData = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
_this.depts = null;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
buildTree(arrs) {
|
|
||||||
var idMapping = arrs.reduce(function (acc, el, i) {
|
|
||||||
acc[el.deptId] = i;
|
|
||||||
return acc;
|
|
||||||
}, {});
|
|
||||||
var roots = [];
|
|
||||||
console.log(123123, arrs);
|
|
||||||
arrs.forEach(function (el) {
|
|
||||||
// 判断根节点
|
|
||||||
if (el.pid === null || el.pid === 0) {
|
|
||||||
roots.push(el);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 用映射表找到父元素
|
|
||||||
var parentEl = arrs[idMapping[el.pid]];
|
|
||||||
// 把当前元素添加到父元素的`children`数组中
|
|
||||||
parentEl.children = parentEl.children || [];
|
|
||||||
parentEl.children = [...parentEl.children, ...el];
|
|
||||||
});
|
|
||||||
console.log(333, roots);
|
|
||||||
return roots;
|
|
||||||
},
|
|
||||||
|
|
||||||
// 加载下一级子节点数据
|
|
||||||
loadExpandDatas(row, treeNode, resolve) {
|
|
||||||
var _this2 = this;
|
|
||||||
this.executeAxios(
|
|
||||||
"/plugin/dept/childNodes/" + row.deptId,
|
|
||||||
"post",
|
|
||||||
{},
|
|
||||||
function (res) {
|
|
||||||
var data = res.data;
|
|
||||||
data = data.map(function (obj) {
|
|
||||||
if (obj.subCount > 0) {
|
|
||||||
obj.hasChildren = true;
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
});
|
|
||||||
_this2.maps.set(row.deptId, {
|
|
||||||
row: row,
|
|
||||||
treeNode: treeNode,
|
|
||||||
resolve: resolve,
|
|
||||||
});
|
|
||||||
resolve && resolve(data);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
_handleDelete(organization) {
|
|
||||||
var _this3 = this;
|
|
||||||
this.$confirm(this.$t("organization.delete_confirm"), "", {
|
|
||||||
confirmButtonText: this.$t("commons.confirm"),
|
|
||||||
cancelButtonText: this.$t("commons.cancel"),
|
|
||||||
type: "warning",
|
|
||||||
})
|
|
||||||
.then(function () {
|
|
||||||
var requests = [
|
|
||||||
{ deptId: organization.deptId, pid: organization.pid },
|
|
||||||
];
|
|
||||||
_this3.executeAxios(
|
|
||||||
"/plugin/dept/delete",
|
|
||||||
"post",
|
|
||||||
requests,
|
|
||||||
function (res) {
|
|
||||||
_this3.$success(_this3.$t("commons.delete_success"));
|
|
||||||
_this3.search();
|
|
||||||
_this3.reloadByPid(organization.pid);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
})
|
|
||||||
.catch(function () {
|
|
||||||
_this3.$message({
|
|
||||||
type: "info",
|
|
||||||
message: _this3.$t("commons.delete_cancelled"),
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
reloadByPid(pid) {
|
|
||||||
if (pid !== 0 && this.maps.get(pid)) {
|
|
||||||
var _maps$get = this.maps.get(pid);
|
|
||||||
var row = _maps$get.row;
|
|
||||||
var treeNode = _maps$get.treeNode;
|
|
||||||
var resolve = _maps$get.resolve;
|
|
||||||
|
|
||||||
this.$set(this.$refs.table.store.states.lazyTreeNodeMap, pid, []);
|
|
||||||
this.loadExpandDatas(row, treeNode, resolve);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
btnDisabled(row) {
|
|
||||||
return row.deptId === 1 || row.subCount > 0;
|
|
||||||
},
|
|
||||||
startDrag(ev) {
|
|
||||||
ev.dataTransfer.setData("sourceId", ev.target.id);
|
|
||||||
},
|
|
||||||
allowDrop(ev) {
|
|
||||||
ev.preventDefault();
|
|
||||||
},
|
|
||||||
endDrag(ev) {
|
|
||||||
ev.preventDefault();
|
|
||||||
var targetId = ev.target.id;
|
|
||||||
var sourceId = ev.dataTransfer.getData("sourceId");
|
|
||||||
|
|
||||||
this.nodeMoveHandler(sourceId, targetId);
|
|
||||||
},
|
|
||||||
nodeMoveHandler(resourceId, targetId) {
|
|
||||||
var _this4 = this;
|
|
||||||
|
|
||||||
if (!resourceId || !targetId) return;
|
|
||||||
resourceId = parseInt(resourceId);
|
|
||||||
targetId = parseInt(targetId);
|
|
||||||
var parent = this.getParent(resourceId);
|
|
||||||
var pid = parent ? parent.id || parent.deptId : null;
|
|
||||||
// if (!pid) {
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// console.log('pid = ' + pid + ', targetId = ' + targetId)
|
|
||||||
if (this.isParentNoChange(pid, targetId)) {
|
|
||||||
this.$warning(this.$t("dept.can_not_move_change_sort"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.isParent2Children(resourceId, targetId)) {
|
|
||||||
this.$warning(this.$t("dept.can_not_move_parent_to_children"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var param = {
|
|
||||||
resourceId: resourceId,
|
|
||||||
targetId: targetId,
|
|
||||||
};
|
|
||||||
this.executeAxios("/plugin/dept/move", "post", param, function (res) {
|
|
||||||
_this4.$success(_this4.$t("dept.move_success"));
|
|
||||||
_this4.search();
|
|
||||||
_this4.reloadByPid(targetId);
|
|
||||||
if (pid) {
|
|
||||||
_this4.reloadByPid(pid);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
// 判断是否是父节点移动到子节点
|
|
||||||
isParent2Children(resourceId, targetId) {
|
|
||||||
var currentId = targetId;
|
|
||||||
while (currentId) {
|
|
||||||
if (resourceId === currentId) {
|
|
||||||
// 说明 目标节点是 源节点的子集
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
var parent = void 0;
|
|
||||||
if ((parent = this.getParent(currentId)) === null) {
|
|
||||||
// 找到顶都没有 说明就不是子集
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
currentId = parent.id || parent.deptId;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// 判断是否移动前后父节点没有改变
|
|
||||||
isParentNoChange(pid, targetId) {
|
|
||||||
return pid === targetId;
|
|
||||||
},
|
|
||||||
|
|
||||||
// 根据deptId获取parent
|
|
||||||
getParent(id) {
|
|
||||||
var currentNode = this.getNodeWithId(id);
|
|
||||||
if (!currentNode || !currentNode.pid) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return this.getNodeWithId(currentNode.pid);
|
|
||||||
},
|
|
||||||
getNodeWithId(id) {
|
|
||||||
for (var index = 0; index < this.tableData.length; index++) {
|
|
||||||
var element = this.tableData[index];
|
|
||||||
if ((element.id || element.deptId) === id) {
|
|
||||||
return element;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var lazyTreeNodeMap = this.$refs.table.store.states.lazyTreeNodeMap;
|
|
||||||
for (var key in lazyTreeNodeMap) {
|
|
||||||
if (Object.hasOwnProperty.call(lazyTreeNodeMap, key)) {
|
|
||||||
var childNodes = lazyTreeNodeMap[key];
|
|
||||||
for (var i = 0; i < childNodes.length; i++) {
|
|
||||||
var node = childNodes[i];
|
|
||||||
if ((node.id || node.deptId) === id) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.member-size {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.org-member-id {
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.org-member-email {
|
|
||||||
float: right;
|
|
||||||
color: #8492a6;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.select-width {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dialog-css >>> .el-dialog__header {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
::v-deep .el-input-number .el-input__inner {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
::v-deep .vue-treeselect__control,
|
|
||||||
::v-deep .vue-treeselect__placeholder,
|
|
||||||
::v-deep .vue-treeselect__single-value {
|
|
||||||
height: 30px;
|
|
||||||
line-height: 30px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
Loading…
Reference in New Issue