弹窗截图
弹窗功能代码:
<template>
<el-dialog
:title="title"
:visible.sync="dialogCopyVisible"
:before-close="handelcloseDialog"
:close-on-click-modal="false"
width="60%"
:modal-append-to-body="false"
top="60px"
append-to-body
>
<div class="fx-dialog" :close-on-click-modal="false">
<div class="flex-item">
<div class="box-left column">
<span><i class="one" />组织架构</span>
<el-scrollbar wrap-class="tree-wrapper-scroller orgTree1">
<el-tree
ref="orgTree"
:data="treeData"
default-expand-all
node-key="id"
highlight-current
@node-click="handleNodeClick"
>
<span slot-scope="{ data }" class="custom-tree-node">
<span>
<i v-if="data.id == '0'" class="treeIcon1 treeIcon_father2" />
<i v-else class="treeIcon1 treeIcon_children2" />
{{ data.name }}
</span>
</span>
</el-tree>
</el-scrollbar>
</div>
<span
v-if="params.isMultiple !== undefined"
class="link el-icon-arrow-right"
/>
<!-- 多选 -->
<div v-if="params.isMultiple == true" class="box-right column">
<span><i class="two" />人员</span>
<el-input
v-model="filterText"
placeholder="输入关键字筛选"
class="filter-text"
clearable
style="padding: 10px 10px 0px 10px; margin-bottom: 0"
/>
<el-checkbox-group v-model="copyPeople" @change="handleCheckChange">
<el-checkbox
v-for="item in filterCheckList"
:key="item.id"
:label="item.id"
>
{{ item.name }}
<span v-if="item.personStatus" class="red"
>({{ item.personStatus }})</span
>
</el-checkbox>
</el-checkbox-group>
</div>
<!-- 单选 -->
<div v-if="params.isMultiple == false" class="box-right column">
<span><i class="two" />人员</span>
<el-input
v-model="filterText"
placeholder="输入关键字筛选"
class="filter-text"
clearable
style="padding: 10px 10px 0px 10px; margin-bottom: 0"
/>
<el-radio-group v-model="copyPeople1" @change="handleCheckChange1">
<el-radio
v-for="item in filterCheckList"
:key="item.id"
:label="item.id"
>
{{ item.name }}
<span v-if="item.personStatus" class="red"
>({{ item.personStatus }})</span
>
</el-radio>
</el-radio-group>
</div>
</div>
</div>
<div class="main-container" style="padding-left: 0; padding-right: 0">
<div class="max-height">
<page-table
ref="table"
:hidden-page="true"
:max-height="tableMaxHeight"
:columns="tablePerson"
:enable-external-data="true"
:external-data="tableData"
>
<template v-slot:operate="slotProps">
<div class="data-operate">
<span class="op-red" @click="deleteFn(slotProps.$index)">
删除
</span>
</div>
</template>
</page-table>
</div>
</div>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="sure"> 确 定 </el-button>
<el-button type="danger" plain @click="handelcloseDialog">
取 消
</el-button>
</div>
</el-dialog>
</template>
<script>
/* 组织结构下人员选择的弹框 */
import { getListData } from '@/utils/utils';
import { mapGetters } from 'vuex';
export default {
props: {
dialogCopyVisible: {
type: Boolean,
default: false,
},
/**
* params: {
* title: 弹框标题
* isMultiple: 是否多选
* treeData: 组织结构
* }
*
* */
params: {
type: Object,
default: () => {
return {};
},
},
// 回显人员id,打开弹窗时已勾选人员的回显
uuidList: {
type: String,
},
title: {
type: String,
default: '',
},
},
data() {
return {
tablePerson: [
{
label: '序号',
type: 'index',
width: 60,
align: 'center',
},
{
label: '姓名',
minWidth: 200,
showOverflowTooltip: true,
align: 'center',
prop: 'name',
},
{
label: '组织',
minWidth: 200,
align: 'center',
showOverflowTooltip: true,
prop: 'orgName',
},
{
label: '操作',
minWidth: 150,
prop: 'operate',
show: 'template',
align: 'center',
},
],
tableMaxHeight: 'auto',
tableData: [],
treeData: [],
// 单选人员
copyPeople1: '',
// 多选的人员
copyPeople: [],
// 根据组织获取的人员数组
checkList: [],
// 过滤文字
filterText: '',
perList: [],
};
},
computed: {
...mapGetters(['user']),
// 用户列表副本
filterCheckList: function () {
// 人员列表姓名模糊过滤
if (!this.filterText) return this.checkList;
return this.checkList.filter(
(item) => item.name.indexOf(this.filterText) !== -1
);
},
},
watch: {
dialogCopyVisible(val) {
if (val) {
// 打开时清空相关数据
this.filterText = '';
this.tableData = [];
this.copyPeople1 = '';
this.copyPeople = [];
this.perList = [];
// 获取组织树
this.getData();
// 如果勾选人员后打开弹窗进行修改
if (this.uuidList && this.uuidList != '') {
this.$api.system
.getUserByIds({ userId: this.uuidList })
.then((res) => {
this.tableData = res.data;
this.perList.push(...res.data);
this.params.isMultiple
? (this.copyPeople = res.data.map((item) => item.id))
: (this.copyPeople1 = res.data[0].id);
});
}
}
},
},
methods: {
// 获取左侧组织树结构数据
getData() {
this.$api.system.getAllOrgList().then((res) => {
this.treeData = getListData(res.data, {
id: 'id',
pId: 'parent',
label: 'name',
children: 'children',
});
// 组织树默认选中当前登录人员所在组织
this.$nextTick(() => {
this.$refs.orgTree.setCurrentKey(this.$store.getters.user.orgId);
});
// 根据当前登录人员所在组织去获取右侧人员
this.$api.system
.getXtUserByOrgId(this.$store.getters.user.orgId)
.then((res) => {
this.checkList = res.data;
});
});
},
// 树的节点点击事件
handleNodeClick(data) {
this.$api.system.getXtUserByOrgId(data.id).then((res) => {
this.checkList = res.data;
});
},
// 人员对象数组进行过滤,去重!
personSortFn(arr) {
return arr.filter((item, index, arr) => {
return arr.map((item) => item.id).indexOf(item.id) === index;
});
},
// 多选
handleCheckChange(val) {
// 当前页面勾选人员的数据
let personPage = this.checkList.filter((item) => val.includes(item.id));
// 勾选前表格里当前页面已经勾选的数据
let tPerPage = this.checkList.filter((item) =>
this.tableData.some((it) => it.id === item.id)
);
// 取消勾选
if (personPage.length == 0) {
this.tableData = this.tableData.filter(
(item) => item.id !== tPerPage[0].id
);
this.perList = this.perList.filter(
(item) => item.id !== tPerPage[0].id
);
return;
}
if (personPage.length < tPerPage.length) {
// 取消勾选 筛选出刚刚取消勾选的数据
let consolItem = tPerPage.filter((item) =>
personPage.every((it) => it.id !== item.id)
);
this.tableData = this.tableData.filter(
(item) => item.id !== consolItem[0].id
);
this.perList = this.perList.filter(
(item) => item.id !== consolItem[0].id
);
} else if (personPage.length > tPerPage.length) {
// 勾选人员
this.perList.push(...personPage);
this.tableData = this.personSortFn(this.perList);
}
},
// 单选
handleCheckChange1(val) {
let personPage = this.checkList.filter((item) => val.includes(item.id));
this.tableData = personPage;
},
// 删除表格某个数据
deleteFn(index) {
if (this.params.isMultiple) {
// 多选
this.copyPeople = this.copyPeople.filter(
(item) => item !== this.tableData[index].id
);
this.perList = this.perList.filter(
(item) => item.id !== this.tableData[index].id
);
this.tableData.splice(index, 1);
} else {
// 单选
this.copyPeople1 = '';
this.tableData = [];
}
},
// 确认
sure() {
this.$emit('copyData', this.tableData);
this.$emit('closeDialogCopy');
},
// 取消
handelcloseDialog() {
this.$emit('closeDialogCopy');
},
},
};
</script>
<style lang="scss" scoped>
.dialog-footer {
text-align: center !important;
}
.fx-dialog .flex-item > div.column {
height: 250px !important;
}
.max-height {
max-height: 150px;
overflow-y: scroll;
}
</style>
相关CSS样式代码
.fx-dialog {
.flex-item {
display: flex;
span.link {
width: 40px;
display: inline-block;
text-align: center;
line-height: 40px;
height: 40px;
color: #333333;
font-weight: 600;
}
& > div {
flex: 1;
//padding: 15px 12px;
border: solid 1px #e5e5e5;
/* &:not(:last-child) {
margin-right: 50px;
} */
&.column {
height: 400px;
overflow: auto;
&.moreHeight{
height: 500px;
}
& > div > label {
&.el-checkbox {
padding-left: 20px;
}
}
& > span {
color: #333333;
width: 100%;
display: block;
line-height: 40px;
padding-left: 18px;
//padding-bottom: 10px;
border-bottom: 1px solid #eaeaea;
font-weight: 600;
i {
color: #3e96f0;
display: inline-block;
margin-right: 10px;
height: 15px;
width: 15px;
&.one {
background: url('../assets/next-task.png') center center no-repeat;
background-size: 100% 100%;
}
&.two {
background: url('../assets/next-user.png') center center no-repeat;
background-size: 100% 100%;
}
}
}
.el-checkbox-group,
.el-radio-group {
padding-left: 20px;
display: flex;
}
.el-checkbox-group{
flex-wrap: wrap;
& > label {
width: 40%;
}
}
.el-radio-group {
display: flex;
flex-direction: column;
}
.el-radio .el-radio__input.is-checked + .el-radio__label {
background-color: #e2f0fd;
}
.el-radio .el-radio__label {
padding: 0 8px 0 8px;
margin-left: 10px;
}
.el-tree,
.el-checkbox-group,
.el-radio-group {
margin-top: 5px;
}
}
}
}
.item {
display: flex;
line-height: 45px;
&:not(:last-child),
&.last {
margin-top: 10px;
}
span.tit {
width: 100px;
}
label {
line-height: 45px;
}
.el-date-editor input,
input,
.el-input__inner {
height: 38px !important;
line-height: 38px;
}
}
}
弹窗组件相关的代码已经放在上面了,代码也写了相应的注释。
组件的样式布局都可以优化,例如:可以去除最下面的表格,改为3列,最右侧展示已勾选人员。
但是目前想要的功能已经实现,等我有空再来优化优化弹窗样式吧!