Industrial-image-management.../src/views/task/task-publish/components/AssigneeSelector.vue

134 lines
2.7 KiB
Vue

<template>
<div class="assignee-selector">
<h3>任务分配</h3>
<p>请选择任务负责人参与人和相关部门</p>
<div class="form-group">
<label for="department">部门 <span class="required">*</span></label>
<select
id="department"
v-model="selectedDepartment"
@change="filterUsersByDepartment"
>
<option value="">请选择部门</option>
<option v-for="dept in departments" :key="dept.id" :value="dept.id">
{{ dept.name }}
</option>
</select>
</div>
<div class="form-group">
<label for="leader">任务负责人 <span class="required">*</span></label>
<select
id="leader"
v-model="assignees.leader"
:disabled="!selectedDepartment"
>
<option value="">请选择负责人</option>
<option
v-for="user in filteredUsers"
:key="user.id"
:value="user.id"
>
{{ user.name }}
</option>
</select>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
// 模拟用户数据
const users = ref([
{ id: 1, name: '张三', departmentId: 1 },
{ id: 2, name: '李四', departmentId: 2 },
{ id: 3, name: '王五', departmentId: 3 },
{ id: 4, name: '赵六', departmentId: 4 }
]);
const selectedDepartment = ref('');
const filteredUsers = ref<typeof users.value>([]);
const filterUsersByDepartment = () => {
if (!selectedDepartment.value) {
filteredUsers.value = [];
assignees.value.leader = -1;
return;
}
filteredUsers.value = users.value.filter(
user => user.departmentId === Number(selectedDepartment.value)
);
// 如果当前选择的负责人不在筛选后的列表中,则清空选择
if (assignees.value.leader && !filteredUsers.value.some(u => u.id === assignees.value.leader)) {
assignees.value.leader = 0;
}
};
// 模拟部门数据
const departments = ref([
{ id: 1, name: '产品部' },
{ id: 2, name: '开发部' },
{ id: 3, name: '测试部' },
{ id: 4, name: '设计部' }
]);
// 分配数据
const assignees = ref({
leader: 0
});
// 暴露分配数据给父组件
defineExpose({
assignees
});
</script>
<style scoped>
.assignee-selector {
padding: 16px;
border: 1px solid #e5e7eb;
border-radius: 4px;
margin-top: 16px;
}
.form-group {
margin-bottom: 16px;
}
label {
display: block;
margin-bottom: 8px;
font-weight: 500;
}
select {
width: 100%;
padding: 8px 12px;
border: 1px solid #d1d5db;
border-radius: 4px;
}
.checkbox-group {
display: flex;
flex-wrap: wrap;
gap: 12px;
margin-top: 8px;
}
.checkbox-item {
display: flex;
align-items: center;
gap: 6px;
cursor: pointer;
}
.required {
color: #ef4444;
}
</style>