|
|
@@ -213,20 +213,44 @@
|
|
|
@row-dblclick="handleViewRecord"
|
|
|
>
|
|
|
<el-table-column type="selection" width="55" align="center" />
|
|
|
- <el-table-column label="课程名称" align="center" prop="courseName" min-width="150" :show-overflow-tooltip="true" />
|
|
|
- <el-table-column label="培训地点" align="center" prop="location" min-width="110" :show-overflow-tooltip="true" />
|
|
|
- <el-table-column label="部门" align="center" prop="department" min-width="110" :show-overflow-tooltip="true" />
|
|
|
- <el-table-column label="完成状态" align="center" prop="completionStatus" width="100">
|
|
|
+ <!-- 主办单位:从申请表course_name字段关联获取 -->
|
|
|
+ <el-table-column label="主办单位" align="center" prop="organizerUnit" min-width="150" :show-overflow-tooltip="true">
|
|
|
<template #default="scope">
|
|
|
- <el-tag :type="scope.row.completionStatus === '0' ? 'warning' : scope.row.completionStatus === '1' ? 'success' : 'info'">
|
|
|
- {{ scope.row.completionStatus === '0' ? '未完成' : scope.row.completionStatus === '1' ? '已完成' : '未知' }}
|
|
|
- </el-tag>
|
|
|
+ <span>{{ scope.row.organizerUnit || '暂无' }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <!-- 培训类型:从申请表training_type字段关联获取 -->
|
|
|
+ <el-table-column label="培训类型" align="center" prop="trainingType" min-width="110" :show-overflow-tooltip="true">
|
|
|
+ <template #default="scope">
|
|
|
+ <span>{{ scope.row.trainingType || '暂无' }}</span>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column label="学时" align="center" prop="duration" width="80" />
|
|
|
- <el-table-column label="完成时间" align="center" prop="completionTime" width="160">
|
|
|
+ <!-- 开始时间:从记录表start_time字段获取 -->
|
|
|
+ <el-table-column label="开始时间" align="center" prop="startTime" width="160">
|
|
|
<template #default="scope">
|
|
|
- <span>{{ parseTime(scope.row.completionTime) || '未完成' }}</span>
|
|
|
+ <span>{{ parseTime(scope.row.startTime) || '暂无' }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <!-- 结束时间:从记录表end_time字段获取 -->
|
|
|
+ <el-table-column label="结束时间" align="center" prop="endTime" width="160">
|
|
|
+ <template #default="scope">
|
|
|
+ <span>{{ parseTime(scope.row.endTime) || '暂无' }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <!-- 同行人员:从申请表companions字段关联获取,格式化为教师姓名 -->
|
|
|
+ <el-table-column label="同行人员" align="center" prop="companions" min-width="120" :show-overflow-tooltip="true">
|
|
|
+ <template #default="scope">
|
|
|
+ <span v-if="scope.row.companions && scope.row.companions !== '[]'">
|
|
|
+ {{ formatCompanions(scope.row.companions) }}
|
|
|
+ </span>
|
|
|
+ <span v-else>无</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="完成状态" align="center" prop="completionStatus" width="100">
|
|
|
+ <template #default="scope">
|
|
|
+ <el-tag :type="getCompletionStatusType(scope.row.completionStatus)">
|
|
|
+ {{ getCompletionStatusLabel(scope.row.completionStatus) }}
|
|
|
+ </el-tag>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
|
|
|
@@ -742,7 +766,6 @@
|
|
|
</el-form-item>
|
|
|
<el-form-item label="完成状态" prop="completionStatus">
|
|
|
<el-radio-group v-model="recordForm.completionStatus">
|
|
|
- <el-radio label="0">进行中</el-radio>
|
|
|
<el-radio label="1">已完成</el-radio>
|
|
|
<el-radio label="2">未完成</el-radio>
|
|
|
</el-radio-group>
|
|
|
@@ -860,79 +883,58 @@
|
|
|
</el-dialog>
|
|
|
|
|
|
<!-- 培训记录详情对话框 -->
|
|
|
- <el-dialog title="培训记录详情" v-model="recordDetailDialogVisible" width="700px" append-to-body>
|
|
|
+ <el-dialog title="培训记录详情" v-model="recordDetailDialogVisible" width="800px" append-to-body>
|
|
|
<el-descriptions :column="2" border>
|
|
|
- <el-descriptions-item label="课程名称">{{ recordDetail.courseName }}</el-descriptions-item>
|
|
|
+ <!-- 学员基本信息 -->
|
|
|
<el-descriptions-item label="学员姓名">{{ recordDetail.userName }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="所在部门(系部)">{{ recordDetail.department || '暂无' }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="现职称">{{ recordDetail.currentTitle || '暂无' }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="现岗位">{{ recordDetail.currentPosition || '暂无' }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="参加工作时间">{{ parseTime(recordDetail.workStartTime) || '暂无' }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="联系电话">{{ recordDetail.phone || '暂无' }}</el-descriptions-item>
|
|
|
+
|
|
|
+ <!-- 培训情况信息 -->
|
|
|
+ <el-descriptions-item label="主办单位">{{ recordDetail.organizerUnit || recordDetail.courseName || '暂无' }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="培训地点">{{ recordDetail.location || '暂无' }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="开始时间">{{ parseTime(recordDetail.startTime) || '暂无' }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="结束时间">{{ parseTime(recordDetail.endTime) || '暂无' }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="培训类型">{{ recordDetail.trainingType || '暂无' }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="培训费用">{{ recordDetail.trainingFee ? `${recordDetail.trainingFee}元` : '暂无' }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="申请时间">{{ parseTime(recordDetail.applyTime) || '暂无' }}</el-descriptions-item>
|
|
|
<el-descriptions-item label="完成状态">
|
|
|
- <el-tag :type="recordDetail.completionStatus === '0' ? 'warning' : recordDetail.completionStatus === '1' ? 'success' : 'info'">
|
|
|
- {{ recordDetail.completionStatus === '0' ? '进行中' : recordDetail.completionStatus === '1' ? '已完成' : '未完成' }}
|
|
|
+ <el-tag :type="getCompletionStatusType(recordDetail.completionStatus)">
|
|
|
+ {{ getCompletionStatusLabel(recordDetail.completionStatus) }}
|
|
|
</el-tag>
|
|
|
</el-descriptions-item>
|
|
|
- <el-descriptions-item label="学时">{{ recordDetail.duration || '暂无' }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="完成时间">{{ parseTime(recordDetail.completionTime) || '未完成' }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="证书" :span="2">
|
|
|
- <div v-if="getCertificatePath(recordDetail)" class="certificate-preview">
|
|
|
- <!-- 证书预览区域 -->
|
|
|
- <div class="certificate-container">
|
|
|
- <!-- 统一显示为图片预览,支持OSS ID和传统路径 -->
|
|
|
- <div class="image-preview">
|
|
|
- <el-image
|
|
|
- v-if="certificatePreviewUrl"
|
|
|
- :src="certificatePreviewUrl"
|
|
|
- :preview-src-list="[certificatePreviewUrl]"
|
|
|
- fit="contain"
|
|
|
- style="width: 300px; height: 200px; border: 1px solid #dcdfe6; border-radius: 4px"
|
|
|
- preview-teleported
|
|
|
- >
|
|
|
- <template #error>
|
|
|
- <div class="image-slot">
|
|
|
- <el-icon><Picture /></el-icon>
|
|
|
- <div>加载失败</div>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- </el-image>
|
|
|
- <div
|
|
|
- v-else
|
|
|
- class="loading-preview"
|
|
|
- style="
|
|
|
- width: 300px;
|
|
|
- height: 200px;
|
|
|
- border: 1px solid #dcdfe6;
|
|
|
- border-radius: 4px;
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- "
|
|
|
- >
|
|
|
- <el-icon class="is-loading"><Loading /></el-icon>
|
|
|
- <span style="margin-left: 8px">加载中...</span>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <!-- 操作按钮 -->
|
|
|
- <div class="certificate-actions" style="margin-top: 10px">
|
|
|
- <el-button type="primary" size="small" @click="viewCertificateDetail(recordDetail)">
|
|
|
- <el-icon><View /></el-icon>
|
|
|
- 查看原图
|
|
|
- </el-button>
|
|
|
- <el-button type="success" size="small" @click="downloadCertificateFile(recordDetail)">
|
|
|
- <el-icon><Download /></el-icon>
|
|
|
- 下载证书
|
|
|
- </el-button>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div v-else class="no-certificate">
|
|
|
- <el-empty description="暂无证书" :image-size="60" />
|
|
|
- </div>
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item label="证书编号">{{ recordDetail.certificateNumber || '无' }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="创建时间">{{ parseTime(recordDetail.createTime) }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="培训反馈" :span="2">
|
|
|
- <div class="detail-text">{{ recordDetail.feedback || '暂无反馈' }}</div>
|
|
|
- </el-descriptions-item>
|
|
|
+ <el-descriptions-item label="同行人" :span="2">{{ getCompanionNames(recordDetail.companions) || '无' }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="培训目的" :span="2">{{ recordDetail.trainingPurpose || recordDetail.reason || '暂无' }}</el-descriptions-item>
|
|
|
<el-descriptions-item label="备注" :span="2">{{ recordDetail.remark || '暂无备注' }}</el-descriptions-item>
|
|
|
</el-descriptions>
|
|
|
+
|
|
|
+ <!-- 申请附件显示区域 -->
|
|
|
+ <div v-if="recordDetailAttachmentList.length > 0" class="attachment-section" style="margin-top: 20px;">
|
|
|
+ <div class="section-title" style="margin-bottom: 15px; padding: 10px; border-left: 4px solid #409eff; background-color: #f5f7fa;">
|
|
|
+ <el-icon style="margin-right: 8px;"><Paperclip /></el-icon>
|
|
|
+ <strong>申请附件</strong>
|
|
|
+ </div>
|
|
|
+ <el-table :data="recordDetailAttachmentList" border size="small">
|
|
|
+ <el-table-column label="序号" type="index" width="60" align="center" />
|
|
|
+ <el-table-column label="文件名称" prop="name" align="left" show-overflow-tooltip />
|
|
|
+ <el-table-column label="上传时间" prop="uploadTime" width="180" align="center">
|
|
|
+ <template #default="scope">
|
|
|
+ {{ parseTime(scope.row.uploadTime) }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="操作" width="100" align="center">
|
|
|
+ <template #default="scope">
|
|
|
+ <el-button type="primary" link icon="Download" @click="handleDownloadApplicationAttachment(scope.row)" size="small">
|
|
|
+ 下载
|
|
|
+ </el-button>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+
|
|
|
<template #footer>
|
|
|
<div class="dialog-footer">
|
|
|
<el-button @click="recordDetailDialogVisible = false">关 闭</el-button>
|
|
|
@@ -1270,8 +1272,7 @@ const recordRules = reactive({
|
|
|
|
|
|
// 培训记录详情
|
|
|
const recordDetailDialogVisible = ref(false);
|
|
|
-const certificatePreviewUrl = ref('');
|
|
|
-const recordDetail = reactive<RecordVO>({
|
|
|
+const recordDetail = reactive<any>({
|
|
|
recordId: undefined,
|
|
|
courseId: undefined,
|
|
|
courseName: '',
|
|
|
@@ -1285,7 +1286,22 @@ const recordDetail = reactive<RecordVO>({
|
|
|
updateTime: '',
|
|
|
createBy: '',
|
|
|
updateBy: '',
|
|
|
- remark: ''
|
|
|
+ remark: '',
|
|
|
+ // 从培训申请获取的详细信息
|
|
|
+ department: '',
|
|
|
+ currentTitle: '',
|
|
|
+ currentPosition: '',
|
|
|
+ workStartTime: '',
|
|
|
+ phone: '',
|
|
|
+ organizerUnit: '',
|
|
|
+ trainingType: '',
|
|
|
+ trainingFee: '',
|
|
|
+ companions: '',
|
|
|
+ trainingPurpose: '',
|
|
|
+ location: '',
|
|
|
+ startTime: '',
|
|
|
+ endTime: '',
|
|
|
+ applyTime: ''
|
|
|
});
|
|
|
|
|
|
// 培训记录多选框选中数据
|
|
|
@@ -1323,6 +1339,7 @@ const applicationDialogLoading = ref(false);
|
|
|
const applicationFormRef = ref<any>(null);
|
|
|
const applicationAttachmentFileList = ref<any[]>([]); // 申请培训附件文件列表
|
|
|
const applicationDetailAttachmentList = ref<any[]>([]); // 申请详情附件文件列表
|
|
|
+const recordDetailAttachmentList = ref<any[]>([]); // 培训记录详情附件文件列表
|
|
|
const applicationForm = reactive<{
|
|
|
applicationId?: number | string;
|
|
|
// 情况基本信息
|
|
|
@@ -1620,6 +1637,24 @@ function getApplicationList() {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
+/** 获取完成状态的标签类型 */
|
|
|
+const getCompletionStatusType = (status: string) => {
|
|
|
+ // 培训记录的完成状态逻辑
|
|
|
+ if (status === '1') return 'success'; // 已完成 - 绿色
|
|
|
+ if (status === '2') return 'danger'; // 未完成 - 红色
|
|
|
+ // 对于空状态或其他状态,由于培训记录都是基于已通过审批的申请生成的,默认显示为已通过
|
|
|
+ return 'success'; // 已通过 - 绿色
|
|
|
+};
|
|
|
+
|
|
|
+/** 获取完成状态的标签文本 */
|
|
|
+const getCompletionStatusLabel = (status: string) => {
|
|
|
+ // 培训记录的完成状态逻辑
|
|
|
+ if (status === '1') return '已完成';
|
|
|
+ if (status === '2') return '未完成';
|
|
|
+ // 对于空状态或其他状态,由于培训记录都是基于已通过审批的申请生成的,默认显示为已通过
|
|
|
+ return '已通过';
|
|
|
+};
|
|
|
+
|
|
|
/** 获取教师列表 */
|
|
|
function getTeacherList() {
|
|
|
listClassTeacherCounselorRel({})
|
|
|
@@ -1712,6 +1747,8 @@ async function handleApplicationDetailAttachmentData(attachmentIds: string | nul
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
/** 新增培训申请 */
|
|
|
async function handleAddApplication() {
|
|
|
resetApplicationForm();
|
|
|
@@ -2029,6 +2066,11 @@ function getCompanionNames(companions: (string | number)[] | string | null | und
|
|
|
}).join('、');
|
|
|
}
|
|
|
|
|
|
+/** 格式化同行人员显示(表格列使用) */
|
|
|
+function formatCompanions(companions: string | undefined): string {
|
|
|
+ return getCompanionNames(companions);
|
|
|
+}
|
|
|
+
|
|
|
/** 查看申请详情 */
|
|
|
async function handleViewApplicant(row: any) {
|
|
|
// 如果行数据中没有完整的课程名称,尝试从课程列表获取
|
|
|
@@ -2372,8 +2414,16 @@ function handleRecordSelectionChange(selection: RecordVO[]) {
|
|
|
function handleTrainingSubTabClick() {
|
|
|
if (trainingSubTab.value === 'application') {
|
|
|
getApplicationList();
|
|
|
+ // 确保教师列表已加载(用于同行人显示)
|
|
|
+ if (teacherList.value.length === 0) {
|
|
|
+ loadTeacherListForDisplay();
|
|
|
+ }
|
|
|
} else if (trainingSubTab.value === 'record') {
|
|
|
getRecordList();
|
|
|
+ // 确保教师列表已加载(用于同行人显示)
|
|
|
+ if (teacherList.value.length === 0) {
|
|
|
+ loadTeacherListForDisplay();
|
|
|
+ }
|
|
|
} else {
|
|
|
getTrainingList();
|
|
|
}
|
|
|
@@ -2430,6 +2480,11 @@ function getRecordList() {
|
|
|
recordList.value = response.rows;
|
|
|
recordTotal.value = response.total;
|
|
|
recordLoading.value = false;
|
|
|
+
|
|
|
+ // 确保教师列表已加载(用于同行人显示)
|
|
|
+ if (teacherList.value.length === 0) {
|
|
|
+ loadTeacherListForDisplay();
|
|
|
+ }
|
|
|
})
|
|
|
.catch(() => {
|
|
|
recordLoading.value = false;
|
|
|
@@ -2453,7 +2508,7 @@ function resetRecordForm() {
|
|
|
recordForm.recordId = undefined;
|
|
|
recordForm.courseId = '';
|
|
|
recordForm.userId = '';
|
|
|
- recordForm.completionStatus = '0';
|
|
|
+ recordForm.completionStatus = '1';
|
|
|
recordForm.score = '';
|
|
|
recordForm.completionTime = '';
|
|
|
recordForm.certificatePath = '';
|
|
|
@@ -2670,31 +2725,78 @@ async function handleUpdateRecord(row: RecordVO) {
|
|
|
|
|
|
/** 查看培训记录详情 */
|
|
|
async function handleViewRecord(row: RecordVO) {
|
|
|
- // 如果行数据中没有完整的课程名称,尝试从课程选项获取
|
|
|
- if (!row.courseName && row.courseId) {
|
|
|
- const course = courseOptions.value.find((c) => c.courseId === row.courseId);
|
|
|
- if (course) {
|
|
|
- row.courseName = course.title;
|
|
|
+ try {
|
|
|
+ // 确保教师列表已加载(用于显示同行人姓名)
|
|
|
+ if (teacherList.value.length === 0) {
|
|
|
+ await loadTeacherListForDisplay();
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- // 复制记录详情
|
|
|
- Object.assign(recordDetail, row);
|
|
|
+ // 首先复制记录的基本信息
|
|
|
+ Object.assign(recordDetail, row);
|
|
|
|
|
|
- // 异步获取证书预览URL
|
|
|
- const certificatePath = getCertificatePath(row);
|
|
|
- if (certificatePath) {
|
|
|
- try {
|
|
|
- certificatePreviewUrl.value = await getSecureCertificatePreviewUrl(certificatePath);
|
|
|
- } catch (error) {
|
|
|
- console.error('获取证书预览URL失败:', error);
|
|
|
- certificatePreviewUrl.value = '';
|
|
|
+ // 如果行数据中没有完整的课程名称,尝试从课程选项获取
|
|
|
+ if (!row.courseName && row.courseId) {
|
|
|
+ const course = courseOptions.value.find((c) => c.courseId === row.courseId);
|
|
|
+ if (course) {
|
|
|
+ recordDetail.courseName = course.title;
|
|
|
+ }
|
|
|
}
|
|
|
- } else {
|
|
|
- certificatePreviewUrl.value = '';
|
|
|
- }
|
|
|
|
|
|
- recordDetailDialogVisible.value = true;
|
|
|
+ // 如果有申请ID,获取完整的申请详情来补充缺失的字段
|
|
|
+ if (row.applicationId) {
|
|
|
+ try {
|
|
|
+ const applicationResponse = await getTrainingApplication(row.applicationId);
|
|
|
+ const applicationData = applicationResponse.data;
|
|
|
+
|
|
|
+ // 合并申请数据中的详细信息到记录详情
|
|
|
+ Object.assign(recordDetail, {
|
|
|
+ // 保留记录的核心信息
|
|
|
+ recordId: row.recordId,
|
|
|
+ completionStatus: row.completionStatus,
|
|
|
+ completionTime: row.completionTime,
|
|
|
+ certificatePath: row.certificatePath,
|
|
|
+ certificateNumber: row.certificateNumber,
|
|
|
+ feedback: row.feedback,
|
|
|
+
|
|
|
+ // 从申请数据中获取详细信息
|
|
|
+ department: applicationData.department || row.department,
|
|
|
+ currentTitle: applicationData.currentTitle,
|
|
|
+ currentPosition: applicationData.currentPosition,
|
|
|
+ workStartTime: applicationData.workStartTime,
|
|
|
+ phone: applicationData.phone,
|
|
|
+ organizerUnit: applicationData.organizerUnit,
|
|
|
+ trainingType: applicationData.trainingType,
|
|
|
+ trainingFee: applicationData.trainingFee,
|
|
|
+ companions: applicationData.companions,
|
|
|
+ trainingPurpose: applicationData.trainingPurpose || applicationData.reason,
|
|
|
+ location: applicationData.location || row.location,
|
|
|
+ startTime: applicationData.startTime,
|
|
|
+ endTime: applicationData.endTime,
|
|
|
+ applyTime: applicationData.applyTime,
|
|
|
+
|
|
|
+ // 其他基本信息
|
|
|
+ courseName: applicationData.courseName || recordDetail.courseName,
|
|
|
+ userName: applicationData.userName || row.userName,
|
|
|
+ duration: applicationData.duration || row.duration,
|
|
|
+ remark: row.remark
|
|
|
+ });
|
|
|
+
|
|
|
+ // 加载申请附件数据
|
|
|
+ if (applicationData.attachmentIds) {
|
|
|
+ await handleApplicationDetailAttachmentData(applicationData.attachmentIds);
|
|
|
+ recordDetailAttachmentList.value = [...applicationDetailAttachmentList.value];
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.warn('获取申请详情失败,使用记录基本信息:', error);
|
|
|
+ // 如果获取申请详情失败,继续使用记录的基本信息
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ recordDetailDialogVisible.value = true;
|
|
|
+ } catch (error) {
|
|
|
+ console.error('查看培训记录详情失败:', error);
|
|
|
+ proxy?.$modal.msgError('获取培训记录详情失败,请重试');
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/** 删除培训记录 */
|
|
|
@@ -3234,82 +3336,6 @@ function getCertificateFileName(filePath: string): string {
|
|
|
return fileName;
|
|
|
}
|
|
|
|
|
|
-/** 查看证书详情 */
|
|
|
-async function viewCertificateDetail(row: any) {
|
|
|
- const certificatePath = getCertificatePath(row);
|
|
|
- if (!certificatePath) {
|
|
|
- proxy?.$modal.msgWarning('该培训记录暂无证书');
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- try {
|
|
|
- const previewUrl = await getSecureCertificatePreviewUrl(certificatePath);
|
|
|
- if (previewUrl) {
|
|
|
- window.open(previewUrl, '_blank');
|
|
|
- } else {
|
|
|
- proxy?.$modal.msgError('无法获取证书预览链接');
|
|
|
- }
|
|
|
- } catch (error) {
|
|
|
- console.error('获取证书预览链接失败:', error);
|
|
|
- proxy?.$modal.msgError('获取证书预览链接失败');
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-/** 下载证书文件 */
|
|
|
-async function downloadCertificateFile(row: any) {
|
|
|
- const certificatePath = getCertificatePath(row);
|
|
|
- if (!certificatePath) {
|
|
|
- proxy?.$modal.msgWarning('该培训记录暂无证书');
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- try {
|
|
|
- // 如果是OSS ID,使用专门的下载方法
|
|
|
- if (/^\d+$/.test(certificatePath.trim())) {
|
|
|
- // 使用request下载,带认证信息
|
|
|
- const loading = ElLoading.service({
|
|
|
- text: '正在下载证书...',
|
|
|
- background: 'rgba(0, 0, 0, 0.7)'
|
|
|
- });
|
|
|
-
|
|
|
- try {
|
|
|
- const response = await request({
|
|
|
- url: `/resource/oss/download/${certificatePath.trim()}`,
|
|
|
- method: 'get',
|
|
|
- responseType: 'blob',
|
|
|
- timeout: 300000
|
|
|
- });
|
|
|
-
|
|
|
- if (response) {
|
|
|
- const blob = response instanceof Blob ? response : response.data;
|
|
|
- const url = window.URL.createObjectURL(blob);
|
|
|
- const link = document.createElement('a');
|
|
|
- link.href = url;
|
|
|
- link.download = getCertificateFileName(certificatePath) || `certificate_${certificatePath}.pdf`;
|
|
|
- document.body.appendChild(link);
|
|
|
- link.click();
|
|
|
- document.body.removeChild(link);
|
|
|
- window.URL.revokeObjectURL(url);
|
|
|
- }
|
|
|
- } finally {
|
|
|
- loading?.close();
|
|
|
- }
|
|
|
- } else {
|
|
|
- // 普通文件路径的处理
|
|
|
- const downloadUrl = getCertificatePreviewUrl(certificatePath);
|
|
|
- const link = document.createElement('a');
|
|
|
- link.href = downloadUrl;
|
|
|
- link.download = getCertificateFileName(certificatePath);
|
|
|
- document.body.appendChild(link);
|
|
|
- link.click();
|
|
|
- document.body.removeChild(link);
|
|
|
- }
|
|
|
- } catch (error) {
|
|
|
- console.error('下载证书失败:', error);
|
|
|
- proxy?.$modal.msgError('下载证书失败');
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
/** 下载证书 */
|
|
|
function downloadCertificate(row: RecordVO) {
|
|
|
if (!row.certificatePath) {
|
|
|
@@ -3635,6 +3661,10 @@ onActivated(() => {
|
|
|
|
|
|
// 同时加载课程选项,确保下拉选项可用
|
|
|
loadCourseOptions();
|
|
|
+ // 确保教师列表已加载(用于同行人显示)
|
|
|
+ if (teacherList.value.length === 0) {
|
|
|
+ loadTeacherListForDisplay();
|
|
|
+ }
|
|
|
});
|
|
|
|
|
|
onMounted(() => {
|
|
|
@@ -3646,6 +3676,8 @@ onMounted(() => {
|
|
|
getRecordList();
|
|
|
loadCourseOptions();
|
|
|
getDepartmentList();
|
|
|
+ // 加载教师列表(用于同行人显示)
|
|
|
+ loadTeacherListForDisplay();
|
|
|
});
|
|
|
|
|
|
// ===== 申请培训附件上传相关方法 =====
|