pms-front/src/components/SelectUser.vue

208 lines
5.3 KiB
Vue
Raw Normal View History

<template>
<el-dialog title="选择人员" :visible="dialogVisible" width="50%" @close="handleClose">
<div class="select-user-container">
<div class="org-tree">
<el-tree :data="treeData" :props="defaultProps" @node-click="handleNodeClick" default-expand-all />
</div>
<div class="user-list">
<CustomTable
ref="customTableRef"
:columns="columns"
:tableData="userData"
:total="total"
:show-selection="true"
:show-index="true"
:table-height="tableHeight"
:multiSelect="multiSelect"
@selection-change="handleSelectionChange"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
maxHeight="380"
>
<template slot="operation" slot-scope="{ row }">
<div class="operation-buttons">
<el-button text type="primary" @click="handleEdit(row)"></el-button>
<el-button text type="primary" @click="showTimesheet(row)"></el-button>
<el-button text type="danger" @click="handleDelete(row)"></el-button>
</div>
</template>
</CustomTable>
</div>
</div>
<template slot="footer">
<span class="dialog-footer">
<el-button @click="handleClose"></el-button>
<el-button type="primary" @click="handleConfirm"></el-button>
</span>
</template>
</el-dialog>
</template>
<script>
import CustomTable from '@/components/CustomTable.vue'
import { systemApi } from '@/utils/api'
export default {
components: {
CustomTable,
},
props: {
multiSelect: {
type: Boolean,
default: true,
},
dialogVisible: {
type: Boolean,
required: true,
},
currentSelectedUser: {
type: Array,
default: () => [],
},
},
data() {
return {
currentPage: 1,
pageSize: 10,
total: 0,
selectedUsers: [],
currentDepartment: '',
tableHeight: 350, // 设置一个合适的高度
treeData: [],
defaultProps: {
children: 'children',
label: 'label',
},
columns: [
{ prop: 'nickName', label: '姓名' },
{ prop: 'dept', label: '部门', type: 'status', callback: (data) => data?.deptName },
{ prop: 'roles', label: '角色', type: 'status', callback: (data) => data.map(ele => ele.roleName).join(',') },
],
userData: [],
customTableRef: null,
isInternalChange: false,
}
},
emits: [ 'close', 'confirm'],
methods: {
handleNodeClick(data) {
this.currentDepartment = data.id
this.currentPage = 1
this.fetchUserList()
},
handleCurrentChange(val) {
this.currentPage = val
this.fetchUserList()
},
handleSizeChange(val) {
this.pageSize = val
this.fetchUserList()
},
handleClose() {
this.$emit('close')
},
handleConfirm() {
this.$emit('confirm', this.selectedUsers)
this.handleClose()
},
handleSelectionChange(val) {
if (this.isInternalChange) return
if (!this.multiSelect) {
this.isInternalChange = true
this.$nextTick(() => {
if (val.length > 0) {
const lastSelected = val[val.length - 1]
this.selectedUsers = [lastSelected]
this.$refs.customTableRef.clearSelection()
this.$refs.customTableRef.toggleRowSelection(lastSelected, true)
} else {
this.selectedUsers = []
}
this.isInternalChange = false
})
} else {
this.selectedUsers = val
}
},
fetchUserList: async function () {
const response = await systemApi.getUserList({
pageNum: this.currentPage,
pageSize: this.pageSize,
deptId: this.currentDepartment,
})
this.userData = response.rows
this.total = response.total
},
fetchTreeData: async function () {
const response = await systemApi.getDeptTree()
this.treeData = response.data
},
},
watch: {
currentSelectedUser: {
handler(newVal) {
this.isInternalChange = true
this.$nextTick(() => {
this.selectedUsers = newVal
if (this.$refs.customTableRef) {
this.$refs.customTableRef.clearSelection()
newVal.forEach(user => {
const row = this.userData.find(item => item.userId === user.userId)
if (row) {
this.$refs.customTableRef.toggleRowSelection(row, true)
}
})
}
this.isInternalChange = false
})
},
immediate: true,
deep: true,
},
},
mounted() {
this.fetchTreeData()
this.fetchUserList()
},
}
</script>
<style lang="scss" scoped>
.select-user-container {
display: flex;
height: 400px;
}
.org-tree {
width: 200px;
border-right: 1px solid #dcdfe6;
padding-right: 20px;
overflow-y: auto;
}
.user-list {
flex: 1;
padding-left: 20px;
display: flex;
flex-direction: column;
}
::v-deep .el-dialog__footer {
padding: 20px 20px 20px 0;
}
.dialog-footer {
display: flex;
justify-content: center;
width: 100%;
}
.dialog-footer .el-button {
margin-left: 10px;
}
.dialog-footer .el-button:first-child {
margin-left: 0;
}
</style>