<script lang="ts" setup>
|
import type { TrainArchiveDetail } from './types';
|
|
import { computed, onMounted, ref } from 'vue';
|
|
import { useMessage } from '@jnpf/hooks';
|
import { useUserStore } from '@vben/stores';
|
import {
|
Descriptions as ADescriptions,
|
DescriptionsItem as ADescriptionsItem,
|
Table as ATable,
|
} from 'ant-design-vue';
|
|
import { getMyTrainArchive } from '#/api/x/tms/trainArchive';
|
|
defineOptions({ name: 'TmsTrainArchive' });
|
|
const { createMessage } = useMessage();
|
const userStore = useUserStore();
|
|
const loading = ref(false);
|
const detail = ref<TrainArchiveDetail | null>(null);
|
|
const userInfo = computed(() => (userStore.getUserInfo || {}) as Record<string, any>);
|
|
const workColumns = [
|
{ title: '序号', key: 'index', width: 70, align: 'center', customRender: ({ index }: any) => index + 1 },
|
{ title: '入职时间', dataIndex: 'hireDate', key: 'hireDate', width: 140 },
|
{ title: '离职时间', dataIndex: 'leaveDate', key: 'leaveDate', width: 140 },
|
{ title: '公司名称', dataIndex: 'companyName', key: 'companyName' },
|
{ title: '任职岗位', dataIndex: 'postName', key: 'postName', width: 180 },
|
];
|
|
const catalogColumns = [
|
{ title: '序号', key: 'index', width: 70, align: 'center', customRender: ({ index }: any) => index + 1 },
|
{ title: '培训记录编号', dataIndex: 'recordNo', key: 'recordNo', width: 150 },
|
{ title: '培训类型', dataIndex: 'trainType', key: 'trainType', width: 110 },
|
{ title: '培训内容', dataIndex: 'trainContent', key: 'trainContent', ellipsis: true },
|
{ title: '培训方式', dataIndex: 'trainMode', key: 'trainMode', width: 110 },
|
{ title: '培训师', dataIndex: 'trainerName', key: 'trainerName', width: 100 },
|
{ title: '考核方式', dataIndex: 'evalMode', key: 'evalMode', width: 110 },
|
{ title: '是否合格', dataIndex: 'passFlag', key: 'passFlag', width: 100, align: 'center' },
|
{ title: '培训开始时间', dataIndex: 'trainStart', key: 'trainStart', width: 160 },
|
{ title: '培训结束时间', dataIndex: 'trainEnd', key: 'trainEnd', width: 160 },
|
];
|
|
onMounted(() => {
|
loadArchive();
|
});
|
|
function resolvePositionName() {
|
const list = userInfo.value.positionList;
|
if (Array.isArray(list) && list.length) {
|
return list.map((o: any) => o.treeName || o.fullName || o.name).filter(Boolean).join('、') || '无';
|
}
|
return userInfo.value.positionName || '无';
|
}
|
|
async function loadArchive() {
|
loading.value = true;
|
try {
|
const u = userInfo.value;
|
detail.value = await getMyTrainArchive({
|
userId: u.userId || u.id,
|
userName: u.userName,
|
userAccount: u.userAccount,
|
organizeName: u.organizeName || u.departmentName,
|
positionName: resolvePositionName(),
|
});
|
} catch (e: any) {
|
createMessage.error(e?.message || '加载培训档案失败');
|
} finally {
|
loading.value = false;
|
}
|
}
|
</script>
|
|
<template>
|
<div class="jnpf-content-wrapper tms-archive-page">
|
<div class="jnpf-content-wrapper-center tms-archive-center">
|
<div class="jnpf-content-wrapper-content tms-archive-wrap">
|
<a-spin :spinning="loading" class="archive-spin">
|
<div v-if="detail" class="archive-inner">
|
<section class="archive-block">
|
<div class="section-title">个人培训档案</div>
|
<ADescriptions
|
bordered
|
:column="{ xs: 1, sm: 2, md: 3 }"
|
size="middle"
|
class="archive-desc"
|
>
|
<ADescriptionsItem label="档案编号">{{ detail.profile.archiveNo }}</ADescriptionsItem>
|
<ADescriptionsItem label="建档时间">{{ detail.profile.archiveDate }}</ADescriptionsItem>
|
<ADescriptionsItem label="员工姓名">{{ detail.profile.userName }}</ADescriptionsItem>
|
<ADescriptionsItem label="所属部门">{{ detail.profile.deptName || '无' }}</ADescriptionsItem>
|
<ADescriptionsItem label="主要岗位">{{ detail.profile.mainPostName || '无' }}</ADescriptionsItem>
|
<ADescriptionsItem label="兼职岗位">{{ detail.profile.partPostName || '无' }}</ADescriptionsItem>
|
</ADescriptions>
|
</section>
|
|
<section class="archive-block">
|
<div class="section-title">工作履历</div>
|
<ATable
|
size="middle"
|
bordered
|
row-key="id"
|
:columns="workColumns"
|
:data-source="detail.workList"
|
:pagination="false"
|
:locale="{ emptyText: '暂无工作履历' }"
|
/>
|
</section>
|
|
<section class="archive-block archive-block-grow">
|
<div class="section-title">
|
培训目录
|
<span class="section-extra">共 {{ detail.catalogList.length }} 条</span>
|
</div>
|
<div class="catalog-table-wrap">
|
<ATable
|
size="middle"
|
bordered
|
row-key="id"
|
:columns="catalogColumns"
|
:data-source="detail.catalogList"
|
:pagination="false"
|
:scroll="{ x: 1280 }"
|
:locale="{ emptyText: '暂无培训记录' }"
|
>
|
<template #bodyCell="{ column, record }">
|
<template v-if="column.key === 'passFlag'">
|
<span v-if="record.passFlag === '1'" class="pass-yes">合格</span>
|
<span v-else-if="record.passFlag === '0'" class="pass-no">不合格</span>
|
<span v-else>-</span>
|
</template>
|
</template>
|
</ATable>
|
</div>
|
</section>
|
</div>
|
</a-spin>
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<style scoped>
|
.tms-archive-page {
|
height: 100%;
|
min-height: 0;
|
}
|
|
.tms-archive-center {
|
height: 100% !important;
|
min-height: 0 !important;
|
display: flex;
|
flex-direction: column;
|
}
|
|
.tms-archive-wrap {
|
display: flex !important;
|
flex-direction: column;
|
flex: 1 1 0 !important;
|
min-height: 0 !important;
|
height: 100%;
|
overflow: auto !important;
|
background: #fff;
|
padding: 0;
|
}
|
|
.archive-spin {
|
display: block;
|
flex: 1;
|
min-height: 100%;
|
width: 100%;
|
}
|
|
.archive-spin :deep(.ant-spin-container) {
|
min-height: 100%;
|
width: 100%;
|
}
|
|
.archive-inner {
|
display: flex;
|
flex-direction: column;
|
min-height: 100%;
|
width: 100%;
|
box-sizing: border-box;
|
padding: 16px 20px 20px;
|
gap: 16px;
|
}
|
|
.archive-block {
|
flex-shrink: 0;
|
width: 100%;
|
}
|
|
.archive-block-grow {
|
flex: 1 1 auto;
|
width: 100%;
|
display: flex;
|
flex-direction: column;
|
}
|
|
.section-title {
|
display: flex;
|
align-items: center;
|
gap: 10px;
|
font-size: 15px;
|
font-weight: 600;
|
margin-bottom: 10px;
|
padding-left: 10px;
|
border-left: 3px solid var(--primary-color, #1890ff);
|
line-height: 1.2;
|
}
|
|
.section-extra {
|
font-size: 12px;
|
font-weight: 400;
|
color: rgba(0, 0, 0, 0.45);
|
}
|
|
.archive-desc {
|
width: 100%;
|
}
|
|
.archive-desc :deep(.ant-descriptions-view) {
|
width: 100%;
|
table-layout: fixed;
|
}
|
|
.archive-desc :deep(.ant-descriptions-item-label) {
|
width: 110px;
|
background: #fafafa;
|
color: rgba(0, 0, 0, 0.65);
|
}
|
|
.archive-desc :deep(.ant-descriptions-item-content) {
|
word-break: break-all;
|
}
|
|
.catalog-table-wrap {
|
width: 100%;
|
flex: 1;
|
}
|
|
.catalog-table-wrap :deep(.ant-table) {
|
width: 100%;
|
}
|
|
.pass-yes {
|
color: #52c41a;
|
font-weight: 500;
|
}
|
|
.pass-no {
|
color: #ff4d4f;
|
font-weight: 500;
|
}
|
|
:deep(.ant-table-thead > tr > th) {
|
background: #fafafa !important;
|
font-weight: 600;
|
}
|
|
:deep(.ant-table-wrapper) {
|
width: 100%;
|
}
|
</style>
|