511 lines
14 KiB
Vue
511 lines
14 KiB
Vue
<template>
|
|
<section class="AiPeople">
|
|
<a v-if="customCliker" class="custom-clicker" @click="dialog.visible=true">
|
|
<slot></slot>
|
|
</a>
|
|
<el-button v-else size="small" @click="dialog.visible=true">{{btnText}}</el-button>
|
|
<el-dialog
|
|
width="912px"
|
|
:title="dialogTitle"
|
|
top="5vh"
|
|
custom-class="ai-people"
|
|
:visible.sync="dialog.visible"
|
|
:close-on-click-modal="false"
|
|
:modal="true"
|
|
destroy-on-close
|
|
:append-to-body="true"
|
|
:show-close="false"
|
|
@close="selectPeople=[],$refs.peopleTable.clearSelection()"
|
|
>
|
|
<div style="transform: translateY(-30px)">
|
|
<p style="margin-bottom: 16px">
|
|
<ai-area-select
|
|
v-if="!hasMeta&&showAiArea"
|
|
:instance="instance"
|
|
v-model="aid"
|
|
@areaObj="v=>selectArea=v"
|
|
@change="peopleList=[],getUnits()"
|
|
clearable
|
|
:disabled="isShowUnit"
|
|
/>
|
|
</p>
|
|
<el-row type="flex" justify="space-between">
|
|
<el-row class="search-panel" type="flex" justify="space-between">
|
|
<div class="add-item" style="width: 320px">
|
|
<p class="add_top">
|
|
<span>单位列表</span>
|
|
<el-input
|
|
placeholder="单位名称"
|
|
size="small"
|
|
style="width:166px;"
|
|
v-model="filterText"
|
|
prefix-icon="el-icon-search"
|
|
clearable
|
|
></el-input>
|
|
</p>
|
|
<div class="tree_list">
|
|
<el-tree
|
|
:data="unitsData"
|
|
class="dialog-tree"
|
|
:props="unitTreeProp"
|
|
ref="unitTree"
|
|
node-key="id"
|
|
:current-node-key="unitId"
|
|
:highlight-current="true"
|
|
@node-click="treeNodeClick"
|
|
:filter-node-method="filterNode"
|
|
></el-tree>
|
|
</div>
|
|
</div>
|
|
<div class="add-item" style="padding-bottom:3px;border-left:none;overflow-x: hidden">
|
|
<p class="add_top">
|
|
<span>单位人员</span>
|
|
<el-input
|
|
placeholder="姓名/手机号"
|
|
size="small"
|
|
style="width:166px;"
|
|
clearable
|
|
prefix-icon="el-icon-search"
|
|
v-model="searchObj.condition"
|
|
@change="getPeopleByUnit"
|
|
></el-input>
|
|
</p>
|
|
<el-table
|
|
ref="peopleTable"
|
|
:data="peopleList"
|
|
size="mini"
|
|
height="355"
|
|
header-cell-class-name="table-header"
|
|
:header-cell-style="{lineHeight:'26px'}"
|
|
:cell-style="{padding:0,lineHeight:'26px'}"
|
|
tooltip-effect="light"
|
|
cell-class-name="table-cell-add"
|
|
@select="onSelect"
|
|
@select-all="onSelectAll"
|
|
@selection-change="onChooseChange"
|
|
>
|
|
<el-table-column type="selection" />
|
|
<el-table-column prop="userName" align="center" label="姓名" show-overflow-tooltip>
|
|
<template slot-scope="scope">
|
|
<span class="el-icon-user-solid"></span>
|
|
{{scope.row.userName || scope.row.name}}
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="phone" label="手机号码" show-overflow-tooltip />
|
|
<div
|
|
slot="empty"
|
|
style="font-size: 14px;margin-top: -20px;height: 20px;line-height: 20px"
|
|
>当前部门暂无人员</div>
|
|
</el-table>
|
|
</div>
|
|
</el-row>
|
|
<div class="selected-people add-item">
|
|
<p class="add_top">
|
|
<span>已选择</span>
|
|
<el-button
|
|
icon="iconfont iconDelete"
|
|
size="mini"
|
|
@click="selectPeople=[],$refs.peopleTable.clearSelection()"
|
|
>清空</el-button>
|
|
</p>
|
|
<div class="add_tag" v-if="selectPeople.length" style="width:100%;">
|
|
<el-tag
|
|
v-for="(item,i) in selectPeople"
|
|
:disable-transitions="true"
|
|
:key="i"
|
|
closable
|
|
@close="cancelSelect(item,i)"
|
|
>{{item.userName || item.name}}</el-tag>
|
|
</div>
|
|
<div
|
|
class="add_tag"
|
|
v-else
|
|
style="display:flex;align-items:center;justify-content:center;width:100%;"
|
|
>
|
|
<span>暂无数据</span>
|
|
</div>
|
|
</div>
|
|
</el-row>
|
|
</div>
|
|
<div slot="footer" style="text-align: center;">
|
|
<el-button
|
|
style="width:92px"
|
|
size="small"
|
|
class="delete-btn"
|
|
@click="dialog.visible=false"
|
|
>取消</el-button>
|
|
<el-button
|
|
style="width:92px"
|
|
size="small"
|
|
type="primary"
|
|
@click="$emit('change', selectPeople),dialog.visible=false"
|
|
>确认</el-button>
|
|
</div>
|
|
</el-dialog>
|
|
</section>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
name: "AiPeople",
|
|
model: {
|
|
prop: "value",
|
|
event: "change"
|
|
},
|
|
props: {
|
|
value: Array,
|
|
instance: Function,
|
|
btnText: { type: String, default: "选择人员" },
|
|
dialogTitle: { type: String, default: "选择人员" },
|
|
meta: { type: Array, default: () => [] },
|
|
action: String,
|
|
customCliker: { type: Boolean, default: false },
|
|
areaId: String,
|
|
disable: {
|
|
type: Array,
|
|
default: () => []
|
|
},
|
|
unitUrl: {
|
|
type: String
|
|
},
|
|
showAiArea: { type: Boolean, default: true },
|
|
isSingle: { type: Boolean, default: false },
|
|
isShowUnit: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
unitId: {
|
|
type: String,
|
|
default: ''
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
aid: "",
|
|
dialog: {
|
|
visible: false
|
|
},
|
|
filterText: "",
|
|
searchObj: {
|
|
unitId: "",
|
|
condition: ""
|
|
},
|
|
unitTreeProp: {
|
|
children: "children",
|
|
label: "name",
|
|
disabled: 'disabled'
|
|
},
|
|
unitsData: [],
|
|
peopleList: [],
|
|
selecteds: [],
|
|
selectPeople: [],
|
|
selectArea: {}
|
|
};
|
|
},
|
|
computed: {
|
|
hasMeta() {
|
|
return Boolean(this.meta.length);
|
|
}
|
|
},
|
|
watch: {
|
|
selecteds(v, old) {
|
|
var list = []
|
|
this.selectPeople.map(o => {
|
|
let index = this.peopleList.findIndex(d => d.userId == o.userId);
|
|
if (index === -1) {
|
|
list.push(o)
|
|
}
|
|
});
|
|
old.map(o => {
|
|
let index = this.selectPeople.findIndex(d => d.userId == o.userId);
|
|
if (index > -1) {
|
|
this.selectPeople.splice(index, 1);
|
|
}
|
|
});
|
|
if (this.isSingle) {
|
|
this.selectPeople = v;
|
|
} else {
|
|
this.selectPeople = [...v, ...list];
|
|
}
|
|
},
|
|
"dialog.visible"() {
|
|
if (this.value) {
|
|
this.selectPeople = JSON.parse(JSON.stringify(this.value));
|
|
}
|
|
},
|
|
filterText(val) {
|
|
if (this.$refs.unitTree) {
|
|
this.$refs.unitTree.filter(val);
|
|
}
|
|
}
|
|
},
|
|
methods: {
|
|
onChooseChange(v) {
|
|
if (!this.isSingle) {
|
|
this.selecteds = v;
|
|
} else {
|
|
|
|
}
|
|
},
|
|
|
|
onSelectAll() {
|
|
if (this.isSingle) {
|
|
if (this.peopleList.length) {
|
|
this.peopleList.forEach(item => {
|
|
this.$refs.peopleTable.toggleRowSelection(item, false);
|
|
});
|
|
|
|
this.selecteds = [];
|
|
}
|
|
}
|
|
},
|
|
|
|
onSelect(v, row) {
|
|
const isSame = v.length ? (v[0].id === row.id ? true : false) : false;
|
|
if (this.isSingle) {
|
|
this.peopleList.forEach(item => {
|
|
this.$refs.peopleTable.toggleRowSelection(item, false);
|
|
|
|
if (item.id === row.id) {
|
|
this.$refs.peopleTable.toggleRowSelection(
|
|
row,
|
|
isSame ? true : false
|
|
);
|
|
}
|
|
});
|
|
|
|
this.selecteds = isSame ? [row] : [];
|
|
}
|
|
},
|
|
|
|
getUnits() {
|
|
if (this.hasMeta) {
|
|
this.getPeopleByUnit();
|
|
let units = this.meta.map(e => {
|
|
return { id: e.unitId, name: e.unitName, parentId: e.unitParentId };
|
|
});
|
|
if (units.length) {
|
|
let pending = [],
|
|
unitsData = [];
|
|
//生成指定范围人员单位树
|
|
units.map(u => {
|
|
if (units.some(e => e.id == u.parentId)) {
|
|
pending.push(u);
|
|
} else {
|
|
unitsData.push(u);
|
|
}
|
|
});
|
|
unitsData.map(t => this.addChild(t, pending));
|
|
this.unitsData = [
|
|
{
|
|
name: "全部",
|
|
children: unitsData
|
|
}
|
|
];
|
|
}
|
|
} else if (this.aid) {
|
|
this.instance.post(`${this.unitUrl ? this.unitUrl : '/admin/sysunit/getAll'}`, null, { params: { areaId: this.aid } })
|
|
.then(res => {
|
|
res.data = res.data.map(a => {
|
|
return { ...a, label: a.name };
|
|
});
|
|
|
|
this.unitsData = res.data.filter(e => {
|
|
if (this.isShowUnit) {
|
|
return e.id === this.unitId
|
|
}
|
|
return !e.parentId
|
|
});
|
|
this.unitsData.map(t => this.addChild(t, res.data));
|
|
});
|
|
}
|
|
},
|
|
addChild(parent, pending) {
|
|
let doBeforeCount = pending.length;
|
|
parent["children"] = parent["children"] || [];
|
|
pending.map((e, index, arr) => {
|
|
if (e.parentId == parent.id) {
|
|
parent.children.push(e);
|
|
arr.splice(index, 1);
|
|
this.addChild(parent, arr);
|
|
}
|
|
});
|
|
if (pending.length > 0 && doBeforeCount > pending.length) {
|
|
parent.children.map(c => this.addChild(c, pending));
|
|
}
|
|
},
|
|
getPeopleByUnit(unit) {
|
|
if (unit) this.searchObj.unitId = unit.id;
|
|
if (this.hasMeta) {
|
|
return new Promise(resolve => {
|
|
this.peopleList = this.meta.filter(f => {
|
|
if (this.searchObj.unitId) {
|
|
return f.unitId == this.searchObj.unitId;
|
|
} else if (this.searchObj.condition) {
|
|
return (
|
|
[f.userName, f.phone]
|
|
.join("|")
|
|
.indexOf(this.searchObj.condition) > -1
|
|
);
|
|
} else return true;
|
|
});
|
|
this.peopleList = this.peopleList.map(p => {
|
|
return { ...p, area: this.selectArea };
|
|
});
|
|
|
|
this.$nextTick(() => {
|
|
this.filter();
|
|
});
|
|
resolve();
|
|
});
|
|
} else {
|
|
return this.instance
|
|
.post(this.action || "/admin/user/choicePerson", null, {
|
|
params: { ...this.searchObj }
|
|
})
|
|
.then(res => {
|
|
this.peopleList = res.data.map(p => {
|
|
return { ...p, area: this.selectArea };
|
|
});
|
|
|
|
this.$nextTick(() => {
|
|
this.filter();
|
|
});
|
|
});
|
|
}
|
|
},
|
|
|
|
filter() {
|
|
if (this.disable.length) {
|
|
this.peopleList = this.peopleList.filter(item => {
|
|
let index = this.disable.findIndex(d => d.userId == item.userId);
|
|
|
|
return index === -1;
|
|
});
|
|
}
|
|
},
|
|
|
|
treeNodeClick(unit) {
|
|
let temp = JSON.parse(JSON.stringify(this.selectPeople));
|
|
this.getPeopleByUnit(unit).then(() => {
|
|
if (temp) {
|
|
this.selectPeople = JSON.parse(JSON.stringify(temp));
|
|
this.relatedTableAndTags();
|
|
}
|
|
});
|
|
},
|
|
filterNode(value, data) {
|
|
if (!value) return true;
|
|
return data.label.indexOf(value) !== -1;
|
|
},
|
|
cancelSelect(row, index) {
|
|
let tableItem = this.peopleList.find(s => s.userId == row.userId);
|
|
if (tableItem) {
|
|
this.$refs.peopleTable.toggleRowSelection(tableItem);
|
|
}
|
|
this.selectPeople.splice(index, 1);
|
|
},
|
|
relatedTableAndTags() {
|
|
this.peopleList.map(p => {
|
|
let index = this.selectPeople.findIndex(s => s.userId == p.userId);
|
|
if (index > -1) {
|
|
if (!this.isSingle) {
|
|
// this.selectPeople.splice(index, 1);
|
|
}
|
|
this.$refs.peopleTable.toggleRowSelection(p, true);
|
|
}
|
|
});
|
|
}
|
|
},
|
|
mounted() {
|
|
this.aid = this.areaId;
|
|
this.getUnits();
|
|
if (this.isShowUnit) {
|
|
this.treeNodeClick({
|
|
id: this.unitId
|
|
})
|
|
}
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
.ai-people {
|
|
.search-panel {
|
|
width: auto;
|
|
padding-right: 10px;
|
|
}
|
|
|
|
.add-item {
|
|
width: 280px;
|
|
height: 400px;
|
|
background: rgba(252, 252, 252, 1);
|
|
border-radius: 2px;
|
|
border: 1px solid rgba(208, 212, 220, 1);
|
|
position: relative;
|
|
overflow: auto;
|
|
box-sizing: border-box;
|
|
|
|
.add_top {
|
|
width: 100%;
|
|
height: 40px;
|
|
background: rgba(245, 245, 245, 1);
|
|
border-bottom: 1px solid rgba(208, 212, 220, 1);
|
|
padding: 0 8px;
|
|
box-sizing: border-box;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
|
|
.tree_list {
|
|
width: 100%;
|
|
overflow: auto;
|
|
height: calc(100% - 40px);
|
|
|
|
.el-tree {
|
|
height: 100%;
|
|
}
|
|
}
|
|
|
|
.add_buttom {
|
|
position: absolute;
|
|
left: 0;
|
|
bottom: 0;
|
|
font-size: 12px;
|
|
width: 310px;
|
|
height: 32px;
|
|
line-height: 32px;
|
|
z-index: 10000;
|
|
background: rgba(245, 246, 247, 1);
|
|
color: rgba(51, 51, 51, 1);
|
|
box-shadow: 0 1px 0 0 rgba(216, 220, 227, 1);
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.add_tag {
|
|
width: 310px;
|
|
height: calc(100% - 40px);
|
|
overflow-y: auto;
|
|
|
|
.el-tag {
|
|
margin: 8px;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.el-input--mini {
|
|
height: 22px;
|
|
line-height: 22px;
|
|
}
|
|
|
|
.table-cell-add {
|
|
padding: 0 !important;
|
|
}
|
|
</style>
|