203 lines
5.4 KiB
Vue
203 lines
5.4 KiB
Vue
<template>
|
|
<div>
|
|
<a-row v-if="!hideTrigger" class="j-select-row" type="flex" :gutter="8">
|
|
<a-col class="left">
|
|
<a-select
|
|
:value="displayValue"
|
|
:placeholder="'请选择人员'"
|
|
:disabled="disabled"
|
|
:open="false"
|
|
mode="multiple"
|
|
:maxTagCount="3"
|
|
style="width: 100%"
|
|
/>
|
|
</a-col>
|
|
<a-col class="right">
|
|
<a-button type="primary" @click="open()" :disabled="disabled">选择</a-button>
|
|
</a-col>
|
|
</a-row>
|
|
<a-modal
|
|
:width="1200"
|
|
:title="title"
|
|
v-model:open="visible"
|
|
centered
|
|
:confirm-loading="confirmLoading"
|
|
@ok="handleOk"
|
|
@cancel="handleCancel"
|
|
:mask-closable="false"
|
|
>
|
|
<div v-if="dataLoading" style="height: 556px; display: flex; align-items: center; justify-content: center">
|
|
<a-spin tip="加载中..." />
|
|
</div>
|
|
<SzCollabUserSelect
|
|
v-show="!dataLoading"
|
|
ref="selectRef"
|
|
:secLevel="secLevel"
|
|
:departId="innerDepartId"
|
|
:role="role"
|
|
:isSpecial="isSpecial"
|
|
:editableUsers="innerEditable"
|
|
:readonlyUsers="innerReadonly"
|
|
:excludedUserIds="excludedUserIds"
|
|
@update:editableUsers="(v) => (tempEditable = v)"
|
|
@update:readonlyUsers="(v) => (tempReadonly = v)"
|
|
/>
|
|
<template #footer>
|
|
<a-button @click="handleCancel">取消</a-button>
|
|
<a-button type="primary" :loading="confirmLoading" @click="handleOk">确定</a-button>
|
|
</template>
|
|
</a-modal>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import { ref, computed } from 'vue';
|
|
import { defHttp } from '/@/utils/http/axios';
|
|
import { useUserStore } from '/@/store/modules/user';
|
|
import SzCollabUserSelect from './SzCollabUserSelect.vue';
|
|
import type { UserItem, CollabConfirmResult } from './types';
|
|
|
|
const props = withDefaults(
|
|
defineProps<{
|
|
editableUserIds?: string;
|
|
readonlyUserIds?: string;
|
|
departId?: string;
|
|
secLevel?: any;
|
|
role?: string | number;
|
|
isSpecial?: number;
|
|
disabled?: boolean;
|
|
title?: string;
|
|
hideTrigger?: boolean;
|
|
excludedUserIds?: string;
|
|
}>(),
|
|
{
|
|
editableUserIds: '',
|
|
readonlyUserIds: '',
|
|
departId: '',
|
|
secLevel: 0,
|
|
role: 1,
|
|
isSpecial: 0,
|
|
disabled: false,
|
|
title: '选择协作人',
|
|
hideTrigger: false,
|
|
excludedUserIds: '',
|
|
}
|
|
);
|
|
|
|
const emit = defineEmits(['confirm']);
|
|
|
|
const userStore = useUserStore();
|
|
const selectRef = ref<InstanceType<typeof SzCollabUserSelect> | null>(null);
|
|
const visible = ref(false);
|
|
const dataLoading = ref(false);
|
|
const confirmLoading = ref(false);
|
|
let loadSeq = 0;
|
|
const innerEditable = ref<UserItem[]>([]);
|
|
const innerReadonly = ref<UserItem[]>([]);
|
|
const tempEditable = ref<UserItem[]>([]);
|
|
const tempReadonly = ref<UserItem[]>([]);
|
|
|
|
const innerDepartId = computed(() => {
|
|
return props.departId || userStore.getUserInfo?.orgCode || '';
|
|
});
|
|
|
|
const displayValue = computed(() => {
|
|
const names: string[] = [];
|
|
for (const u of innerEditable.value) names.push(`[编]${u.realname}`);
|
|
for (const u of innerReadonly.value) names.push(`[阅]${u.realname}`);
|
|
return names;
|
|
});
|
|
|
|
async function loadUsers(valueStr: string, permission: '2' | '3') {
|
|
if (!valueStr) return [];
|
|
try {
|
|
const res: any = await defHttp.get({
|
|
url: '/sys/user/queryUserComponentData',
|
|
params: { id: valueStr, isMultiTranslate: 'true', pageNo: 1, pageSize: 9999 },
|
|
});
|
|
return (res.records || res) as UserItem[];
|
|
} catch {
|
|
return [];
|
|
}
|
|
}
|
|
|
|
async function loadInitialUsers() {
|
|
const [editUsers, readUsers] = await Promise.all([
|
|
loadUsers(props.editableUserIds, '2'),
|
|
loadUsers(props.readonlyUserIds, '3'),
|
|
]);
|
|
innerEditable.value = editUsers;
|
|
innerReadonly.value = readUsers;
|
|
}
|
|
|
|
async function open(editIds?: string, readIds?: string) {
|
|
if (props.disabled) return;
|
|
visible.value = true;
|
|
confirmLoading.value = false;
|
|
|
|
const hasExplicitData = editIds !== undefined || readIds !== undefined;
|
|
const hasPropsData = props.editableUserIds || props.readonlyUserIds;
|
|
|
|
if (!hasExplicitData && !hasPropsData) {
|
|
dataLoading.value = true;
|
|
return;
|
|
}
|
|
|
|
dataLoading.value = true;
|
|
const seq = ++loadSeq;
|
|
|
|
const loadUsersTask = (async () => {
|
|
let editU: UserItem[] = [];
|
|
let readU: UserItem[] = [];
|
|
if (hasExplicitData) {
|
|
[editU, readU] = await Promise.all([loadUsers(editIds || ''), loadUsers(readIds || '')]);
|
|
} else {
|
|
[editU, readU] = await Promise.all([loadUsers(props.editableUserIds), loadUsers(props.readonlyUserIds)]);
|
|
}
|
|
if (seq !== loadSeq) return;
|
|
innerEditable.value = editU;
|
|
innerReadonly.value = readU;
|
|
tempEditable.value = [...editU];
|
|
tempReadonly.value = [...readU];
|
|
})();
|
|
|
|
const tableTask = selectRef.value?.resetSearch?.();
|
|
|
|
await Promise.all([loadUsersTask, tableTask]);
|
|
if (seq !== loadSeq) return;
|
|
dataLoading.value = false;
|
|
}
|
|
|
|
function handleOk() {
|
|
const result: CollabConfirmResult = selectRef.value?.getResult() || {
|
|
editableIds: '', editableNames: '', readonlyIds: '', readonlyNames: '',
|
|
};
|
|
emit('confirm', result);
|
|
visible.value = false;
|
|
}
|
|
|
|
function handleCancel() {
|
|
visible.value = false;
|
|
}
|
|
|
|
defineExpose({ open, loadInitialUsers });
|
|
</script>
|
|
|
|
<style lang="less" scoped>
|
|
.j-select-row {
|
|
@width: 82px;
|
|
|
|
.left {
|
|
width: calc(100% - @width - 8px);
|
|
}
|
|
|
|
.right {
|
|
width: @width;
|
|
}
|
|
|
|
:deep(.ant-select-search__field) {
|
|
display: none !important;
|
|
}
|
|
}
|
|
</style>
|