Files
klp-oa/klp-ui/src/components/userSelect/single.vue
2025-12-30 13:47:53 +08:00

308 lines
8.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<el-dialog
title="人员选择"
:visible.sync="showFlag"
:modal="false"
width="80%"
center
append-to-body
>
<el-row :gutter="20">
<!-- 部门数据 -->
<el-col :span="4" :xs="24">
<div class="head-container">
<el-input
v-model="deptName"
placeholder="请输入部门名称"
clearable
size="small"
prefix-icon="el-icon-search"
style="margin-bottom: 20px"
/>
</div>
<div class="head-container">
<el-tree
:data="deptOptions"
:props="defaultProps"
:expand-on-click-node="false"
:filter-node-method="filterNode"
ref="tree"
node-key="deptId"
default-expand-all
@node-click="handleNodeClick"
/>
</div>
</el-col>
<!-- 用户数据 -->
<el-col :span="20" :xs="24">
<el-form
:model="queryParams"
ref="queryForm"
size="small"
:inline="true"
v-show="showSearch"
label-width="68px"
>
<el-form-item label="用户名称" prop="userName">
<el-input
v-model="queryParams.userName"
placeholder="请输入用户名称"
clearable
style="width: 240px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="手机号码" prop="phonenumber">
<el-input
v-model="queryParams.phonenumber"
placeholder="请输入手机号码"
clearable
style="width: 240px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<KLPTable v-loading="loading" :data="userList" @current-change="handleCurrent" @row-dblclick="handleRowDbClick">
<el-table-column width="55" align="center">
<template v-slot="scope">
<el-radio v-model="selectedId" :label="scope.row.userId" @change="handleRowChange(scope.row)">{{ '' }}</el-radio>
</template>
</el-table-column>
<el-table-column label="用户名称" align="center" key="userName" prop="userName" v-if="columns[1].visible" :show-overflow-tooltip="true" />
<el-table-column label="用户昵称" align="center" key="nickName" prop="nickName" v-if="columns[2].visible" :show-overflow-tooltip="true" />
<el-table-column label="部门" align="center" key="deptName" prop="dept.deptName" v-if="columns[3].visible" :show-overflow-tooltip="true" />
<el-table-column label="手机号码" align="center" key="phonenumber" prop="phonenumber" v-if="columns[4].visible" width="120" />
<el-table-column label="创建时间" align="center" prop="createTime" v-if="columns[6].visible" width="160">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
</KLPTable>
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</el-col>
</el-row>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="confirmSelect"> </el-button>
<el-button @click="showFlag = false"> </el-button>
</div>
</el-dialog>
</template>
<script>
import { listUser } from '@/api/system/user'
import { listDept } from '@/api/system/dept'
export default {
name: 'UserSingleSelect',
// 让父组件可以通过 v-model 控制弹窗显示
props: {
value: {
type: Boolean,
default: false
}
},
data() {
return {
showFlag: false,
// 遮罩层
loading: true,
// 选中
selectedId: null,
selectedRow: null,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 用户表格数据
userList: [],
// 部门树
deptOptions: [],
// 部门名称
deptName: undefined,
defaultProps: {
children: 'children',
label: 'deptName'
},
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 20,
userName: undefined,
phonenumber: undefined,
status: undefined,
deptId: undefined
},
// 列信息
columns: [
{ key: 0, label: '用户编号', visible: true },
{ key: 1, label: '用户名称', visible: true },
{ key: 2, label: '用户昵称', visible: true },
{ key: 3, label: '部门', visible: true },
{ key: 4, label: '手机号码', visible: true },
{ key: 5, label: '状态', visible: true },
{ key: 6, label: '创建时间', visible: true }
]
}
},
watch: {
// v-model -> showFlag
value: {
immediate: true,
handler(val) {
this.showFlag = !!val
if (val) {
// 打开时再加载,避免页面初始化就请求
this.getDeptTree()
this.getList()
}
}
},
// showFlag -> v-model
showFlag(val) {
this.$emit('input', !!val)
},
// 根据名称筛选部门树
deptName(val) {
if (this.$refs.tree) {
this.$refs.tree.filter(val)
}
}
},
methods: {
// 供父组件 ref 调用this.$refs.xxx.open()
open() {
this.showFlag = true
// watch(value) 不会触发,这里手动加载
this.getDeptTree()
this.getList()
},
// 构建树形
buildTree(list, parentId = 0) {
const tree = []
if (!Array.isArray(list)) return tree
list.forEach(item => {
const pid = item.parentId ?? item.pid ?? 0
if (Number(pid) === Number(parentId)) {
const children = this.buildTree(list, item.deptId)
const node = { ...item }
if (children.length) node.children = children
tree.push(node)
}
})
return tree
},
/** 查询部门树:用 listDept 自己组装,彻底避免 /treeselect 路由冲突 */
async getDeptTree() {
try {
const res = await listDept()
const rows = res.rows || res.data || []
this.deptOptions = this.buildTree(rows, 0)
} catch (e) {
console.error('获取部门列表失败', e)
this.deptOptions = []
}
},
/** 查询用户列表 */
getList() {
this.loading = true
const params = { ...this.queryParams }
// deptId 必须是 Long对非法值直接丢弃
if (params.deptId !== undefined && params.deptId !== null) {
const num = Number(params.deptId)
params.deptId = isNaN(num) ? undefined : num
}
listUser(params)
.then(response => {
this.userList = response.rows || []
this.total = response.total || 0
})
.finally(() => {
this.loading = false
})
},
// 筛选节点
filterNode(value, data) {
if (!value) return true
return (data.deptName || '').indexOf(value) !== -1
},
// 节点单击事件
handleNodeClick(data) {
const id = data && (data.deptId ?? data.id)
const num = Number(id)
this.queryParams.deptId = isNaN(num) ? undefined : num
this.queryParams.pageNum = 1
this.getList()
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.queryParams.pageNum = 1
this.queryParams.userName = undefined
this.queryParams.phonenumber = undefined
this.queryParams.deptId = undefined
this.getList()
},
handleCurrent(row) {
if (row) {
this.selectedRow = row
}
},
// 行双击选中
handleRowDbClick(row) {
if (row) {
this.selectedRow = row
this.confirmSelect()
}
},
// 单选选中数据
handleRowChange(row) {
if (row) {
this.selectedRow = row
}
},
// 确定选中
confirmSelect() {
if (!this.selectedRow) {
this.$notify({
title: '提示',
type: 'warning',
message: '请至少选择一条数据!'
})
return
}
this.$emit('onSelected', this.selectedRow)
this.showFlag = false
}
}
}
</script>