| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- <template>
- <div class="inspector-select">
- <div class="left">
- <div class="filter-title">
- <el-input v-model="queryContent" placeholder="请输入搜索的内容" clearable />
- </div>
- <div class="filter-result">
- <el-tree
- ref="treeRef"
- :data="treeData"
- node-key="id"
- show-checkbox
- :props="{
- label: 'label',
- children: 'children',
- disabled: (data) => !data.isUser || disabledIds.includes(data.id),
- }"
- placeholder="请选择任务检查人"
- filterable
- check-strictly
- default-expand-all
- :filter-node-method="filterNode"
- @check-change="handleCheckChange"
- >
- <template #empty>
- <div class="empty">
- <img :src="empty" alt="" />
- <div>暂无数据</div>
- </div>
- </template>
- </el-tree>
- </div>
- </div>
- <div class="right">
- <div class="head">
- <span>已选择:{{ selectedPersonList.length }}人</span>
- </div>
- <div class="selected">
- <el-tag
- v-for="person in selectedPersonList"
- :key="person.id"
- :closable="!person.checked"
- @close="handleTagClose(person.id)"
- >
- {{ person.realname }}({{ person.staffNo }})
- </el-tag>
- </div>
- <div class="footer">
- <el-button @click="emit('cancel')">取消</el-button>
- <el-button
- type="primary"
- @click="
- emit(
- 'submit',
- selectedPersonList.map((item) => item.id),
- )
- "
- >确定
- </el-button>
- </div>
- </div>
- </div>
- </template>
- <script lang="ts" setup>
- import { onMounted, ref, watch, computed, nextTick } from 'vue';
- import empty from 'assets/images/empty@1X.png';
- import type { TreeNode } from '@/views/disaster/types';
- import type { PersonGroupItem } from '@/types/person-group/type';
- import { ElMessage, type ElTree } from 'element-plus';
- import { useUserInfoHook } from '@/views/disaster/hooks/userInfo';
- import { updateTaskInspector } from '@/api/disaster-precaution';
- const { getUserFirstLevelTreeList, treeData, id: userId } = useUserInfoHook();
- const props = defineProps<{
- customUserList: PersonGroupItem[];
- }>();
- interface Tree {
- [key: string]: any;
- }
- const queryContent = ref('');
- const treeRef = ref<InstanceType<typeof ElTree>>();
- const selectedPersonList = ref<PersonGroupItem[]>([]);
- const filterNode = (
- value: string,
- data: Tree,
- node: {
- parent: { label: string; parent: any; level: number };
- label: string;
- level: number;
- },
- ) => {
- if (!value) return true;
- let parentNode = node.parent,
- labels = [node.label],
- level = 1;
- while (level < node.level) {
- labels = [...labels, parentNode.label];
- parentNode = parentNode.parent;
- level++;
- }
- return labels.some((label) => label.indexOf(value) !== -1);
- };
- // 需要禁用的用户ID列表
- const disabledIds = computed(() => {
- const selectedIds = selectedPersonList.value.filter((item) => item.checked).map((item) => item.id);
- const ids = Array.from(new Set([userId, ...selectedIds]));
- return ids;
- });
- const removeSelectedPerson = (id: number) => {
- const index = selectedPersonList.value.findIndex((item) => item.id === id);
- if (index !== -1) {
- selectedPersonList.value.splice(index, 1);
- }
- };
- const handleCheckChange = (node: TreeNode, checked: boolean) => {
- if (checked) {
- const selectedPerson = {
- id: node.id,
- realname: node.label.split('(')[0],
- staffNo: node.staffNo || '',
- checked: false,
- };
- selectedPersonList.value.push(selectedPerson);
- } else {
- removeSelectedPerson(node.id);
- }
- };
- const handleTagClose = (id) => {
- const index = selectedPersonList.value.findIndex((item) => item.id === id);
- if (index !== -1) {
- selectedPersonList.value.splice(index, 1);
- treeRef.value!.setChecked(id, false, true);
- }
- };
- const emit = defineEmits(['cancel', 'submit']);
- onMounted(async () => {
- await getUserFirstLevelTreeList();
- });
- watch(queryContent, (val) => {
- treeRef.value!.filter(val);
- });
- watch(
- () => props.customUserList,
- (newVal) => {
- selectedPersonList.value = newVal;
- const selectedIds = newVal.map((item) => item.id);
- nextTick(() => {
- if (!treeRef.value) return;
- treeRef.value.setCheckedKeys(selectedIds, true);
- });
- },
- {
- immediate: true,
- },
- );
- </script>
- <style lang="scss" scoped>
- .inspector-select {
- display: flex;
- width: 100%;
- height: 600px;
- .left {
- display: flex;
- flex-direction: column;
- gap: 10px;
- width: 50%;
- height: 100%;
- padding: 0 5px;
- border-right: 1px solid rgba($text-color, 0.1);
- }
- .filter-result {
- flex: 1;
- overflow-y: auto;
- .el-tree {
- width: 100%;
- height: 100%;
- }
- .empty,
- img {
- width: 100%;
- }
- .empty {
- @include flex-center;
- flex-direction: column;
- height: 100%;
- gap: 5px;
- }
- }
- .select-type {
- width: 75px;
- }
- .right {
- display: flex;
- flex-direction: column;
- flex: 1;
- height: 100%;
- position: relative;
- margin-left: 16px;
- gap: 20px;
- .head {
- display: flex;
- align-items: center;
- font-weight: 400;
- font-size: 16px;
- color: rgba($text-color, 0.88);
- line-height: 22px;
- margin: 6px 0 6px;
- }
- .selected {
- display: flex;
- flex-wrap: wrap;
- gap: 8px;
- overflow-y: auto;
- max-height: calc(100% - 120px);
- }
- .footer {
- display: flex;
- gap: 6px;
- position: absolute;
- right: 24px;
- bottom: 20px;
- }
- }
- }
- </style>
|