|
|
@@ -999,6 +999,7 @@ import {
|
|
|
deleteTrainingApplication,
|
|
|
getTrainingApprovalHistory,
|
|
|
resubmitTrainingApplication,
|
|
|
+ batchQueryCompanions,
|
|
|
updateRecordAttachments,
|
|
|
listAllApprovalRecords
|
|
|
} from '@/api/rs/training';
|
|
|
@@ -1432,6 +1433,9 @@ const applicationForm = reactive<{
|
|
|
// 同行人选择器相关
|
|
|
const selectedCompanions = ref<TeacherVO[]>([]);
|
|
|
|
|
|
+// 同行人姓名缓存(用于详情展示)
|
|
|
+const companionNamesCache = ref<Record<string, string>>({});
|
|
|
+
|
|
|
// 培训申请表单校验规则
|
|
|
const applicationRules = reactive<any>({
|
|
|
// 情况基本信息验证
|
|
|
@@ -1716,7 +1720,7 @@ function getTeacherList() {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
-/** 异步加载教师列表用于详情显示 */
|
|
|
+/** 异步加载教师列表用于详情显示(容错版,权限不足时不报错)*/
|
|
|
async function loadTeacherListForDisplay() {
|
|
|
try {
|
|
|
console.log('开始加载教师列表...');
|
|
|
@@ -1733,8 +1737,9 @@ async function loadTeacherListForDisplay() {
|
|
|
}));
|
|
|
console.log('教师列表加载完成:', teacherList.value.length, '位教师');
|
|
|
console.log('教师ID列表:', teacherList.value.map(t => t.teacherId));
|
|
|
- } catch (error) {
|
|
|
- console.error('获取教师列表失败:', error);
|
|
|
+ } catch (error: any) {
|
|
|
+ console.warn('获取教师列表失败(可能是权限不足),将使用备用查询方式:', error);
|
|
|
+ // ⚠️ 不再抛出错误,允许使用备用的同行人查询接口
|
|
|
teacherList.value = [];
|
|
|
}
|
|
|
}
|
|
|
@@ -2131,66 +2136,91 @@ function formatFileSize(bytes: number | string | undefined): string {
|
|
|
return parseFloat((size / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
|
}
|
|
|
|
|
|
-/** 获取同行人姓名列表 */
|
|
|
-function getCompanionNames(companions: (string | number)[] | string | null | undefined): string {
|
|
|
+/** 异步加载同行人姓名并缓存(使用新的批量查询接口)*/
|
|
|
+async function loadCompanionNames(companions: (string | number)[] | string | null | undefined): Promise<string> {
|
|
|
if (!companions) {
|
|
|
- console.log('[同行人解析] 同行人数据为空');
|
|
|
return '';
|
|
|
}
|
|
|
|
|
|
- let companionArray: (string | number)[] = [];
|
|
|
+ // 生成缓存key
|
|
|
+ const cacheKey = typeof companions === 'string' ? companions : JSON.stringify(companions);
|
|
|
+
|
|
|
+ // 如果已缓存,直接返回
|
|
|
+ if (companionNamesCache.value[cacheKey]) {
|
|
|
+ return companionNamesCache.value[cacheKey];
|
|
|
+ }
|
|
|
+
|
|
|
+ let companionArray: number[] = [];
|
|
|
|
|
|
- // 如果是字符串,尝试解析JSON
|
|
|
+ // 解析同行人ID列表
|
|
|
if (typeof companions === 'string') {
|
|
|
try {
|
|
|
- companionArray = JSON.parse(companions);
|
|
|
- if (!Array.isArray(companionArray)) {
|
|
|
- console.log('[同行人解析] JSON解析结果不是数组:', companionArray);
|
|
|
- return '';
|
|
|
+ const parsed = JSON.parse(companions);
|
|
|
+ if (Array.isArray(parsed)) {
|
|
|
+ companionArray = parsed.map(id => Number(id));
|
|
|
}
|
|
|
console.log('[同行人解析] JSON解析成功:', companionArray);
|
|
|
} catch (e) {
|
|
|
// 如果JSON解析失败,可能是逗号分隔的字符串
|
|
|
- companionArray = companions.split(',').map(id => id.trim()).filter(id => id);
|
|
|
+ companionArray = companions.split(',')
|
|
|
+ .map(id => Number(id.trim()))
|
|
|
+ .filter(id => !isNaN(id));
|
|
|
console.log('[同行人解析] 使用逗号分隔解析:', companionArray);
|
|
|
}
|
|
|
} else if (Array.isArray(companions)) {
|
|
|
- companionArray = companions;
|
|
|
+ companionArray = companions.map(id => Number(id));
|
|
|
console.log('[同行人解析] 直接使用数组:', companionArray);
|
|
|
}
|
|
|
|
|
|
if (companionArray.length === 0) {
|
|
|
- console.log('[同行人解析] 同行人数组为空');
|
|
|
return '';
|
|
|
}
|
|
|
|
|
|
- // 如果教师列表还未加载,显示"加载中..."
|
|
|
- if (teacherList.value.length === 0) {
|
|
|
- console.log('[同行人解析] 教师列表未加载,返回加载中');
|
|
|
- return '加载中...';
|
|
|
+ try {
|
|
|
+ // 调用新的批量查询接口(不需要system:teacher:list权限)
|
|
|
+ console.log('[同行人查询] 调用批量查询接口:', companionArray);
|
|
|
+ const response: any = await batchQueryCompanions(companionArray);
|
|
|
+ const users = response.data || [];
|
|
|
+
|
|
|
+ console.log('[同行人查询] 查询结果:', users.length, '个用户');
|
|
|
+
|
|
|
+ // 拼接姓名
|
|
|
+ const names = companionArray.map(userId => {
|
|
|
+ const user = users.find((u: any) => u.userId === userId);
|
|
|
+ const name = user ? (user.nickName || user.userName) : `未知用户(ID:${userId})`;
|
|
|
+ console.log(`[同行人查询] ID ${userId} -> ${name}`);
|
|
|
+ return name;
|
|
|
+ }).join('、');
|
|
|
+
|
|
|
+ // 缓存结果
|
|
|
+ companionNamesCache.value[cacheKey] = names;
|
|
|
+ console.log('[同行人查询] 最终结果:', names);
|
|
|
+ return names;
|
|
|
+ } catch (error) {
|
|
|
+ console.error('[同行人查询] 接口调用失败:', error);
|
|
|
+ // 降级方案:显示ID列表
|
|
|
+ const fallback = `同行人ID: ${companionArray.join('、')}`;
|
|
|
+ companionNamesCache.value[cacheKey] = fallback;
|
|
|
+ return fallback;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/** 获取同行人姓名列表(同步版,从缓存读取)*/
|
|
|
+function getCompanionNames(companions: (string | number)[] | string | null | undefined): string {
|
|
|
+ if (!companions) {
|
|
|
+ return '';
|
|
|
}
|
|
|
|
|
|
- console.log('[同行人解析] 教师列表已加载:', teacherList.value.length, '位教师');
|
|
|
- console.log('[同行人解析] 需要查找的ID:', companionArray);
|
|
|
+ const cacheKey = typeof companions === 'string' ? companions : JSON.stringify(companions);
|
|
|
|
|
|
- const names = companionArray.map(teacherId => {
|
|
|
- // 确保teacherId转换为正确的类型进行比较
|
|
|
- const teacher = teacherList.value.find(t =>
|
|
|
- String(t.teacherId) === String(teacherId) ||
|
|
|
- Number(t.teacherId) === Number(teacherId)
|
|
|
- );
|
|
|
- const name = teacher ? teacher.teacherName : `未知教师(ID:${teacherId})`;
|
|
|
- console.log(`[同行人解析] ID ${teacherId} -> ${name}`);
|
|
|
- return name;
|
|
|
- }).join('、');
|
|
|
+ // 从缓存返回
|
|
|
+ if (companionNamesCache.value[cacheKey]) {
|
|
|
+ return companionNamesCache.value[cacheKey];
|
|
|
+ }
|
|
|
|
|
|
- console.log('[同行人解析] 最终结果:', names);
|
|
|
- return names;
|
|
|
-}
|
|
|
-
|
|
|
-/** 格式化同行人员显示(表格列使用) */
|
|
|
-function formatCompanions(companions: string | undefined): string {
|
|
|
- return getCompanionNames(companions);
|
|
|
+ // 如果缓存中没有,返回"加载中..."并异步加载
|
|
|
+ loadCompanionNames(companions);
|
|
|
+ return '加载中...';
|
|
|
}
|
|
|
|
|
|
/** 查看申请详情 */
|
|
|
@@ -2210,20 +2240,22 @@ async function handleViewApplicant(row: any) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // 确保教师列表已加载(用于显示同行人姓名)
|
|
|
- if (teacherList.value.length === 0) {
|
|
|
- await loadTeacherListForDisplay();
|
|
|
- }
|
|
|
-
|
|
|
// 复制申请详情
|
|
|
Object.assign(applicationDetail, row);
|
|
|
|
|
|
console.log('[查看申请详情] 详情数据已设置:', {
|
|
|
userName: applicationDetail.userName,
|
|
|
nickName: applicationDetail.nickName,
|
|
|
- attachmentIds: applicationDetail.attachmentIds // 添加附件ID日志
|
|
|
+ companions: applicationDetail.companions,
|
|
|
+ attachmentIds: applicationDetail.attachmentIds
|
|
|
});
|
|
|
|
|
|
+ // 预加载同行人信息(使用新接口,不需要system:teacher:list权限)
|
|
|
+ if (row.companions) {
|
|
|
+ await loadCompanionNames(row.companions);
|
|
|
+ console.log('[查看申请详情] 同行人信息已预加载');
|
|
|
+ }
|
|
|
+
|
|
|
// 加载申请详情的附件数据
|
|
|
await handleApplicationDetailAttachmentData(row.attachmentIds);
|
|
|
|