TechnicianAssign 技术员分配组件
概述
TechnicianAssign 是一个用于技术员分配的 Vue 3 组件,支持多选技术员,显示技术员名称和编码,并提供工作状态和任务负载信息。
功能特点
- ✅ 技术员多选支持
- ✅ 显示技术员名称和编码格式:
姓名 (编码) - ✅ 显示技术员工作状态(空闲/忙碌/休假/出差)
- ✅ 显示技术员任务负载
- ✅ 按任务负载自动排序(负载低的在前)
- ✅ 过滤和搜索功能
- ✅ 支持排除指定技术员
- ✅ 可选的选中技术员详情卡片
- ✅ 响应式数据绑定
基础用法
<template>
<TechnicianAssign
v-model="selectedTechnicianIds"
label="分配技术员"
placeholder="请选择技术员"
@technician-selected="handleTechnicianSelected"
/>
</template>
<script setup>
import { ref } from 'vue';
import TechnicianAssign from '@/components/TechnicianAssign/index.vue';
const selectedTechnicianIds = ref([]);
function handleTechnicianSelected(technicians) {
console.log('选中的技术员:', technicians);
}
</script>
组件属性 (Props)
| 属性名 | 类型 | 默认值 | 必填 | 说明 |
|---|---|---|---|---|
modelValue |
Array |
[] |
是 | v-model 绑定的技术员ID数组 |
label |
String |
'分配技术员' |
否 | 表单项标签文本 |
prop |
String |
'' |
否 | 表单项 prop 属性 |
rules |
Object/Array |
null |
否 | 表单验证规则 |
placeholder |
String |
'请选择技术员' |
否 | 选择器占位符 |
disabled |
Boolean |
false |
否 | 是否禁用选择器 |
showCard |
Boolean |
false |
否 | 是否显示选中技术员的详情卡片 |
filterParams |
Object |
{} |
否 | 技术员过滤条件 |
excludeTechnicianId |
Number/String |
null |
否 | 要排除的技术员ID |
组件事件 (Events)
| 事件名 | 参数 | 说明 |
|---|---|---|
update:modelValue |
(technicianIds: Array) |
选中的技术员ID数组变化时触发 |
change |
(technicianIds: Array, technicians: Array) |
技术员选择变化时触发 |
technician-selected |
(technicians: Array) |
选择技术员时触发,返回完整的技术员对象数组 |
数据结构
技术员对象结构
interface Technician {
id: number; // 技术员ID
technicianName: string; // 技术员姓名
technicianCode: string; // 技术员编码
workStatus: string; // 工作状态:'idle'空闲, 'busy'忙碌, 'vacation'休假, 'business_trip'出差
currentTasks: number; // 当前任务数
maxTasks: number; // 最大任务数
phone: string; // 联系电话
department: string; // 所属部门
position: string; // 职位
avatar: string; // 头像URL
}
显示格式
- 下拉选项显示:
张三 (T001)+ 工作状态标签 +2/5(任务负载) - 选中标签显示:
张三 (T001),李四 (T002),… - 详情卡片:显示选中的技术员列表,包含详细信息
高级用法
多选与表单验证
<template>
<el-form :model="form" :rules="rules">
<TechnicianAssign
v-model="form.assignedTechnicianIds"
label="分配技术员"
prop="assignedTechnicianIds"
:rules="rules.assignedTechnicianIds"
placeholder="请至少选择一个技术员"
@technician-selected="handleTechnicianSelected"
/>
</el-form>
</template>
<script setup>
import { reactive } from 'vue';
import TechnicianAssign from '@/components/TechnicianAssign/index.vue';
const form = reactive({
assignedTechnicianIds: []
});
const rules = {
assignedTechnicianIds: [
{ required: true, message: '请至少选择一个技术员', trigger: 'change' }
]
};
function handleTechnicianSelected(technicians) {
// technicians 是选中的技术员对象数组
form.assignedTechnicians = technicians;
}
</script>
带过滤条件
<template>
<TechnicianAssign
v-model="selectedIds"
:filterParams="{
status: 'active', // 只显示在职技术员
skillLevel: 'senior' // 只显示高级技术员
}"
:exclude-technician-id="currentUserId" // 排除当前用户
/>
</template>
显示详情卡片
<template>
<TechnicianAssign
v-model="selectedIds"
:show-card="true"
label="选择技术员"
/>
</template>
与其他组件配合使用
<template>
<el-form :model="subtaskForm">
<el-form-item label="子任务标题">
<el-input v-model="subtaskForm.title" />
</el-form-item>
<el-form-item label="分配技术员">
<TechnicianAssign
v-model="subtaskForm.assignedTechnicianIds"
:label="''"
:show-card="false"
placeholder="请选择负责技术员"
@technician-selected="(technicians) => updateTechnicians(technicians)"
/>
</el-form-item>
</el-form>
</template>
<script setup>
import { reactive } from 'vue';
const subtaskForm = reactive({
title: '',
assignedTechnicianIds: [],
assignedTechnicians: []
});
function updateTechnicians(technicians) {
subtaskForm.assignedTechnicians = technicians;
// 更新兼容字段
if (technicians.length > 0) {
subtaskForm.assignedTechnicianNames = technicians.map(t => t.technicianName).join(',');
subtaskForm.assignedTechnicianId = technicians[0].id;
} else {
subtaskForm.assignedTechnicianNames = '';
subtaskForm.assignedTechnicianId = null;
}
}
</script>
样式定制
组件支持通过 CSS 变量进行样式定制:
/* 在父组件中覆盖样式 */
.technician-assign {
/* 修改选项间距 */
--technician-option-gap: 16px;
/* 修改字体大小 */
--tech-name-size: 16px;
--tech-code-size: 13px;
}
/* 自定义详情卡片样式 */
:deep(.selected-technician-card) {
.tech-card-item {
background: #f0f9ff;
border-color: #0ea5e9;
}
}
常见问题
Q: 如何获取选中的技术员详细信息?
A: 使用 @technician-selected 事件,它会返回完整的技术员对象数组:
function handleTechnicianSelected(technicians) {
// technicians 数组包含完整的技师对象
technicians.forEach(tech => {
console.log(tech.technicianName, tech.technicianCode, tech.workStatus);
});
}
Q: 如何限制只能选择一个技术员?
A: 组件默认支持多选,如需单选可通过以下方式:
<template>
<TechnicianAssign
v-model="selectedIds"
@change="handleSingleSelect"
/>
</template>
<script setup>
function handleSingleSelect(ids, technicians) {
if (ids.length > 1) {
// 只保留最后一个选中的
selectedIds.value = [ids[ids.length - 1]];
}
}
</script>
Q: 如何自定义技术员数据源?
A: 组件内部调用 listTechnician API,如需自定义可通过 filterParams 传入过滤条件,或修改组件内部的加载逻辑。
Q: 如何处理技术员加载失败的情况?
A: 组件内部有错误处理,会在控制台输出错误信息并显示空列表。你也可以监听组件的 refresh 方法:
const technicianAssignRef = ref();
// 手动刷新
async function refreshTechnicians() {
try {
await technicianAssignRef.value.refresh();
} catch (error) {
// 处理错误
}
}
API 依赖
组件依赖以下 API:
listTechnician- 获取技术员列表
相关文件
- 组件文件:
@/components/TechnicianAssign/index.vue - API 文件:
@/api/business/technician.js
更新日志
v2.0.0 (2025-01-22)
- 🔄 重写组件:简化界面,专注于显示技术员名称和编码
- ✨ 新功能:支持名称+编码格式显示
- 🗑️ 移除:移除头像、评分、技能等级等复杂信息
- 🎨 优化:改进下拉选项和详情卡片布局
v1.0.0 (2024-XX-XX)
- 🎉 初始版本:基础技术员选择功能
作者: Claude Assistant
维护: Husky Equipment Maintenance Service Team
更新时间: 2025-01-22
作者:聂盼盼 创建时间:2025-10-27 23:08
最后编辑:聂盼盼 更新时间:2025-10-28 19:53
最后编辑:聂盼盼 更新时间:2025-10-28 19:53