Files
klp-oa/klp-ui/src/components/EmployeeSelector/index.vue
砂糖 c8f576dea3 refactor(wms): 优化合卷逻辑和员工选择组件
- 移除合卷流程中的箭头图示和最小源卷数量限制
- 修改处理时间显示为完成时间并更新相关字段
- 优化员工选择组件的前端筛选和取消操作处理
2026-03-16 10:41:50 +08:00

350 lines
9.2 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>
<div class="employee-selector">
<!-- 触发器 -->
<div class="trigger" @click="toggleDialog">
<slot name="trigger">
<div class="default-trigger">
{{ displayText }}
</div>
</slot>
</div>
<!-- 选择对话框 -->
<el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
<el-input v-model="searchQuery" placeholder="请输入员工姓名或部门" clearable @keyup.enter.native="handleSearch">
<el-button slot="append" icon="el-icon-search" @click="handleSearch" />
</el-input>
<!-- 已选员工列表多选模式 -->
<div v-if="multiple && selectedEmployees.length > 0" class="selected-list">
<div class="selected-list-title">已选员工 ({{ selectedEmployees.length }})</div>
<el-tag v-for="employee in selectedEmployees" :key="employee[keyField]" closable
@close="removeSelectedEmployee(employee)" class="selected-tag">
{{ employee.name }} ({{ employee.dept }})
</el-tag>
</div>
<el-table v-loading="loading" :data="employeeList" style="width: 100%" height="400px" @row-click="handleRowClick"
:row-class-name="rowClassName">
<el-table-column label="部门" align="center" prop="dept" />
<el-table-column label="姓名" align="center" prop="name" />
<el-table-column label="岗位工种" align="center" prop="jobType" />
<el-table-column label="联系电话" align="center" prop="phone" />
</el-table>
<div slot="footer" class="dialog-footer">
<el-button @click="cancelSelection">取消</el-button>
<el-button v-if="multiple" type="primary" @click="confirmSelection" :disabled="selectedEmployees.length === 0">
确认选择 ({{ selectedEmployees.length }})
</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listEmployeeInfo } from '@/api/wms/employeeInfo'
export default {
name: 'EmployeeSelector',
props: {
value: {
type: [String, Array],
default: ''
},
keyField: {
type: String,
default: 'infoId'
},
placeholder: {
type: String,
default: '请选择员工'
},
title: {
type: String,
default: '选择员工'
},
multiple: {
type: Boolean,
default: false
},
disabledNames: {
type: String,
default: ''
}
},
data() {
return {
selectedEmployee: {},
selectedEmployees: [],
rawEmployeeList: [],
open: false,
loading: false,
searchQuery: ''
}
},
computed: {
// 显示在触发器上的文本
displayText() {
if (this.multiple) {
if (this.selectedEmployees.length > 0) {
return `${this.selectedEmployees.length} 人已选择`
} else {
return this.placeholder
}
} else {
return this.selectedEmployee.name || this.placeholder
}
},
// 禁用的员工ID列表
disabledIdList() {
if (!this.disabledNames) {
return []
}
return this.disabledNames.split(',').map(id => id.trim()).filter(id => id)
},
// 处理后的员工列表,包含禁用状态
employeeList() {
return this.rawEmployeeList.filter(employee => {
return employee.name?.includes(this.searchQuery) || employee.dept?.includes(this.searchQuery)
}).map(employee => ({
...employee,
disabled: this.disabledIdList.includes(employee.infoId.toString())
}))
}
},
watch: {
value: {
handler(newVal) {
if (this.multiple) {
if (newVal) {
// 多选模式:根据逗号分隔的字符串查找已选员工
this.findSelectedEmployees(newVal.split(','))
} else {
this.selectedEmployees = []
}
} else {
if (newVal) {
this.findSelectedEmployee(newVal)
} else {
this.selectedEmployee = {}
}
}
},
immediate: true
}
},
methods: {
// 切换对话框显示
toggleDialog() {
if (!this.open) {
this.getEmployeeList()
}
this.open = !this.open
},
// 获取员工列表
getEmployeeList() {
this.loading = true
const params = {
pageNum: 1,
pageSize: 9999,
// name: this.searchQuery || undefined,
// dept: this.searchQuery || undefined
}
return new Promise((resolve) => {
listEmployeeInfo(params).then(response => {
// 前端筛选员工列表,根据姓名或部门
this.rawEmployeeList = response.rows;
this.loading = false
resolve()
}).catch(() => {
this.loading = false
resolve()
})
})
},
// 搜索员工
handleSearch() {
this.getEmployeeList()
},
// 选择员工
handleRowClick(row) {
// 检查员工是否被禁用
if (this.isDisabled(row)) {
return
}
if (this.multiple) {
// 多选模式:添加或移除员工
const index = this.selectedEmployees.findIndex(item => item[this.keyField] === row[this.keyField])
if (index > -1) {
this.selectedEmployees.splice(index, 1)
} else {
this.selectedEmployees.push(row)
}
} else {
// 单选模式:选择员工并关闭弹窗
this.selectedEmployee = row
this.$emit('input', row[this.keyField])
this.$emit('change', row)
this.open = false
}
},
// 检查员工是否被禁用
isDisabled(row) {
const isDisabled = this.disabledIdList.includes(row[this.keyField].toString())
if (isDisabled) {
this.$message.warning('该员工已禁用,不能选择')
}
return isDisabled
},
// 确认选择(多选模式)
confirmSelection() {
const selectedIds = this.selectedEmployees.map(item => item[this.keyField])
this.$emit('input', selectedIds.join(','))
this.$emit('change', this.selectedEmployees)
this.open = false
},
cancelSelection() {
if (this.multiple) {
if (this.value) {
// 多选模式:根据逗号分隔的字符串查找已选员工
this.findSelectedEmployees(this.value.split(','))
} else {
this.selectedEmployees = []
}
} else {
if (this.value) {
this.findSelectedEmployee(this.value)
} else {
this.selectedEmployee = {}
}
}
this.open = false
},
// 移除已选员工
removeSelectedEmployee(employee) {
const index = this.selectedEmployees.findIndex(item => item[this.keyField] === employee[this.keyField])
if (index > -1) {
this.selectedEmployees.splice(index, 1)
}
},
// 表格行样式
rowClassName({ row }) {
// if (this.isDisabled(row)) {
// return 'disabled-row'
// }
if (this.isSelected(row)) {
return 'selected-row'
}
return ''
},
// 检查员工是否已选
isSelected(row) {
if (this.multiple) {
return this.selectedEmployees.some(item => item[this.keyField] === row[this.keyField])
} else {
return this.selectedEmployee[this.keyField] === row[this.keyField]
}
},
// 根据value查找选中的员工单选
findSelectedEmployee(value) {
if (this.employeeList.length > 0) {
const employee = this.employeeList.find(item => item[this.keyField] === value)
if (employee) {
this.selectedEmployee = employee
}
} else {
// 如果员工列表为空,先获取列表再查找
this.getEmployeeList().then(() => {
const employee = this.employeeList.find(item => item[this.keyField] === value)
if (employee) {
this.selectedEmployee = employee
}
})
}
},
// 根据value查找选中的员工多选
findSelectedEmployees(values) {
if (this.employeeList.length > 0) {
this.selectedEmployees = this.employeeList.filter(item => values.includes(item[this.keyField]))
} else {
// 如果员工列表为空,先获取列表再查找
this.getEmployeeList().then(() => {
this.selectedEmployees = this.employeeList.filter(item => values.includes(item[this.keyField]))
})
}
}
}
}
</script>
<style scoped>
.employee-selector {
position: relative;
}
.trigger {
cursor: pointer;
user-select: none;
}
.default-trigger {
padding: 2px 4px;
border: 1px solid #dcdfe6;
min-width: 120px;
font-size: 13px;
display: inline-block;
}
.default-trigger:hover {
border-color: #409eff;
}
.selected-list {
margin: 10px 0;
padding: 10px;
background-color: #f5f7fa;
border-radius: 4px;
}
.selected-list-title {
font-weight: bold;
margin-bottom: 8px;
color: #606266;
}
.selected-tag {
margin-right: 8px;
margin-bottom: 8px;
}
.el-table .selected-row {
background-color: #ecf5ff !important;
}
.el-table .selected-row:hover {
background-color: #ecf5ff !important;
}
.el-table .disabled-row {
background-color: #f5f7fa !important;
color: #c0c4cc !important;
}
.el-table .disabled-row:hover {
background-color: #f5f7fa !important;
color: #c0c4cc !important;
}
</style>