1、先上效果图
2、选人组件代码
前端代码:
<template>
<div>
<el-input v-model="userInfo.names" @click.native="dataInitialization()" placeholder="点击选择人员" />
<el-input v-model="userInfo.ids" placeholder="请输入id" v-show="false" />
<el-dialog title="人员选择" :visible.sync="visible" width="500px" v-if="visible" append-to-body>
<el-tree
ref="userTree"
:data="data"
show-checkbox
default-expand-all
node-key="id"
:default-checked-keys="checkedData"
highlight-current
:props="defaultProps"
@check-change="handleClick"
>
<span class="custom-tree-node" slot-scope="{ node, data }">
<span :class="data.icon"></span>
<span>{{ node.label }}</span>
</span>
</el-tree>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="getCheckedNodes">确 定</el-button>
<el-button @click="resetChecked">重置</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { getDeptAndUserTreeData } from '@/api/base/deptAndUser'
import { getUserNamesByIds } from '../../api/system/user'
export default {
name: 'SelectUser',
props: {
sType: 0,
id: [String,Number],
},
data() {
return {
checkedData: [],
currentNodeData: {},
// 是否显示弹出层
visible: false,
//是否单选
isSingle: false,
userInfo:{
ids: '',
names: ''
},
selectedData: {
ids:'',
names: '',
userList: []
},
data: [{
id: 1,
label: '一级 1',
children: [{
id: 4,
label: '二级 1-1',
children: [{
id: 9,
label: '三级 1-1-1'
}, {
id: 10,
label: '三级 1-1-2'
}]
}]
}],
defaultProps: {
children: 'children',
label: 'label'
}
}
},
watch: {
// 监听id变化,重新渲染后面功能
id(newValue,oldValue){
this.$nextTick(()=> {
this.getUserNames();
}
)
},
immediate: true,
deep: true,
},
mounted() {
this.getUserNames();
},
methods: {
getUserNames(){
this.userInfo.ids='';
this.userInfo.names='';
if(this.id!=="" && this.id!==undefined){
this.userInfo.ids=this.id;
getUserNamesByIds(this.id).then(res=>{
console.log(res);
this.userInfo.names=res.data;
})
}else {
}
},
dataInitialization() {
// 获取部门和人员的数据
getDeptAndUserTreeData().then(res => {
this.data = res.data;
// 1代表单选,0代表选
if (this.sType === 1) {
this.isSingle = true
}
let ids=this.userInfo.ids;
console.log(ids)
// 根据主页面传来的id值,进行默认选中设置
if (ids !== '') {
var dataIntArr = [];
if(ids.indexOf(",")>0){
const dataStrArr = ids.split(',');
dataStrArr.forEach(function (data, index, arr) {
dataIntArr.push(+data);
})
} else {
dataIntArr.push(ids);
}
this.checkedData = dataIntArr;
}
this.visible = true;
})
},
getCheckedNodes() {
this.checkChange(this.$refs.userTree.getCheckedNodes());
},
checkChange(List) {
let ids = '';
let names = '';
const that_user=this;
List.forEach(function (item) {
//对选中的数据进行过滤,部门的数据过滤掉,isDept=0(员工)的数据进行id和name的json重构,传给主页面
if (item.isDept === 0) {
ids += item.id + ',';
names += item.label + ',';
that_user.selectedData.userList.push(item);
}
})
if (ids.length > 0) {
ids = ids.slice(0, ids.length - 1);
names = names.slice(0, names.length - 1);
}
this.userInfo.ids = ids;
this.userInfo.names = names;
this.visible = false;
// 返回值给调用页面的@backEventListen绑定的函数
this.$emit('callBackEvent', this.selectedData);
// 直接返回给v-model绑定的值
this.$emit('input', ids);
},
resetChecked() {
this.$refs.userTree.setCheckedKeys([]);
this.checkedData=[];
},
// 单选判断,执行操作
handleClick(data, checked, node) {
if (this.isSingle) {
if (checked) {
this.$refs.userTree.setCheckedNodes([data]);
}
}
},
}
}
</script>
<style scoped>
</style>
后端重要部分代码,其他代码自行补充:
(1)、dto实体
@Data
public class DeptAndUserListDto {
private static final long serialVersionUID = 1L;
private String id;
private String parentId;
private Long deptId;
private Integer isDept;
private String name;
private String icon;
private Boolean disabled;
private Boolean isLeaf;
private Integer orderNum;
}
(2)、mapper中获取数据的方法
@Mapper
public interface DeptAndUserListMapper extends Mapper {
@Select("SELECT sys_dept.dept_id id,sys_dept.dept_id deptId,sys_dept.parent_id parentId,1 as isDept,sys_dept.dept_name NAME,'el-icon-folder' AS icon,TRUE AS disabled,sys_dept.order_num AS orderNum FROM sys_dept WHERE sys_dept.status=0 "
+ "union ALL "
+ "SELECT sys_user.user_id id,sys_user.dept_id deptId,sys_user.dept_id parentId,0 as isDept,sys_user.nick_name NAME,'el-icon-user-solid' AS icon,FALSE AS disabled,999 AS orderNum FROM sys_user WHERE sys_user.status=0 ORDER BY orderNum ASC")
List<DeptAndUserListDto> getDeptAndUserList();
}
(3)、serviceImpl实例
@Service
@RequiredArgsConstructor
public class DeptAndUserServiceImpl implements IDeptAndUserService {
private final DeptAndUserListMapper deptAndUserListMapper;
@Override
public List<DeptAndUserListDto> getDeptAndUserList() {
return deptAndUserListMapper.getDeptAndUserList();
}
@Override
public List<Tree<String>> getDeptAndUserTreeData() {
List<DeptAndUserListDto> list = deptAndUserListMapper.getDeptAndUserList();
// List<TreeNode<String>> nodeList = CollUtil.newArrayList();
// for(DeptAndUserTreeDto dudto : list){
// nodeList.add(new TreeNode<>(dudto.getId(),dudto.getParentId(),dudto.getName(),dudto.getOrderNum()));
// }
TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
// 自定义属性名 都有默认值的哈
// 默认支持排序
treeNodeConfig.setWeightKey("orderNum");
//treeNodeConfig.setChildrenKey("children");
//可配置树深度
treeNodeConfig.setDeep(8);
treeNodeConfig.setIdKey("id");
List<Tree<String>> build = TreeUtil.build(list, "0", treeNodeConfig,
(treeNode, tree) -> {
tree.setId(treeNode.getId());
tree.setParentId(treeNode.getParentId());
tree.setWeight(treeNode.getOrderNum());
tree.setName(treeNode.getName());
// 扩展属性
tree.putExtra("deptId", treeNode.getDeptId());
tree.putExtra("label", treeNode.getName());
tree.putExtra("isDept", treeNode.getIsDept());
tree.putExtra("icon", treeNode.getIcon());
});
return build;
}
}
3、调用示例–把组件挂到main.js全局中,然后直接调用即可。
<div>
<h2>人员选择示例2</h2>
<h5>v-model="userInfo.ids"是用来接收回传的ids数据,也是页面上需要存储的值</h5>
<h5>:id="userInfo.ids" 是把当前的ids值传给选人组件,也就是已选人员的id串</h5>
<h5>:sType=0 标识单选1,多选0</h5>
<h5>@callBackEvent="doSomeThing" 回调函数,接收选人组件回传的其他完整值</h5>
<h5></h5>
<select-user ref="selectUser" :sType=0 @callBackEvent="doSomeThing" v-model="userInfo.ids" :id="userInfo.ids" />
</div>