From 8534025c45b4736975730678b9ccf23570a75f95 Mon Sep 17 00:00:00 2001
From: liuyu <yu.liu@cqgbkj.com>
Date: 星期二, 22 九月 2026 09:25:48 +0800
Subject: [PATCH] feat(tms): 新增试卷、培训任务、个人任务页面
---
apps/jnpf-web-apps-main/src/views/x/tms/onlineExam/index.vue | 109 +++++++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 94 insertions(+), 15 deletions(-)
diff --git a/apps/jnpf-web-apps-main/src/views/x/tms/onlineExam/index.vue b/apps/jnpf-web-apps-main/src/views/x/tms/onlineExam/index.vue
index 8fe379c..df9fb19 100644
--- a/apps/jnpf-web-apps-main/src/views/x/tms/onlineExam/index.vue
+++ b/apps/jnpf-web-apps-main/src/views/x/tms/onlineExam/index.vue
@@ -3,15 +3,26 @@
import type { MyPaperListItem } from './types';
-import { ref } from 'vue';
+import { onMounted, ref } from 'vue';
import { useRouter } from 'vue-router';
import { useMessage } from '@jnpf/hooks';
import { BasicVxeTable, TableAction, useVxeTable } from '@jnpf/ui/vxeTable';
import { getMyPaperList, startOnlineExam } from '#/api/x/tms/onlineExam';
+import { TMS_DIC_FIELD_NAMES } from '#/views/x/tms/shared/dic';
+import { TMS_BTN } from '#/views/x/tms/shared/ui';
-import { MY_PAPER_STATUS_OPTIONS, colorOfMyPaperStatus, labelOfMyPaperStatus } from './constants';
+import {
+ MY_PAPER_STATUS_OPTIONS,
+ colorOfMyPaperStatus,
+ colorOfPassFlag,
+ labelOfMyPaperStatus,
+ labelOfPassFlag,
+ loadOnlineExamDics,
+} from './constants';
+
+import '#/views/x/tms/shared/page.css';
defineOptions({ name: 'TmsOnlineExam' });
@@ -20,7 +31,18 @@
const starting = ref(false);
const columns: BasicColumn[] = [
- { title: '璇曞嵎鍚嶇О', dataIndex: 'paperName', minWidth: 260 },
+ { title: '璇曞嵎鍚嶇О', dataIndex: 'paperName', minWidth: 220 },
+ {
+ title: '鑰冭瘯绫诲瀷',
+ dataIndex: 'attemptLabel',
+ width: 130,
+ align: 'center',
+ customRender: ({ record }) => {
+ const row = record as MyPaperListItem;
+ return row.attemptLabel
+ || (row.attemptNo && row.attemptNo > 1 ? `琛ヨ�冿紙绗�${row.attemptNo - 1}娆★級` : '棣栬��');
+ },
+ },
{
title: '鐘舵��',
dataIndex: 'status',
@@ -31,7 +53,7 @@
{
title: '鑰冭瘯鏃堕棿',
dataIndex: 'examTimeText',
- minWidth: 280,
+ minWidth: 260,
customRender: ({ record }) => (record as MyPaperListItem).examTimeText || '-',
},
{
@@ -40,12 +62,30 @@
width: 100,
align: 'center',
},
+ {
+ title: '鏄惁鍚堟牸',
+ dataIndex: 'passFlag',
+ width: 100,
+ align: 'center',
+ slots: { default: 'passFlag' },
+ },
+ {
+ title: '鍓╀綑琛ヨ��',
+ dataIndex: 'remainingRetakes',
+ width: 100,
+ align: 'center',
+ customRender: ({ record }) => {
+ const row = record as MyPaperListItem;
+ if (row.retakeLimit == null) return '-';
+ return `${row.remainingRetakes ?? 0} / ${row.retakeLimit}`;
+ },
+ },
];
-const [registerTable] = useVxeTable({
+const [registerTable, { reload, getForm }] = useVxeTable({
api: fetchList,
columns,
- immediate: true,
+ immediate: false,
rowKey: 'id',
useSearchForm: true,
formConfig: {
@@ -65,21 +105,42 @@
componentProps: {
allowClear: true,
placeholder: '璇烽�夋嫨鐘舵��',
- options: MY_PAPER_STATUS_OPTIONS,
+ options: MY_PAPER_STATUS_OPTIONS.value,
+ fieldNames: TMS_DIC_FIELD_NAMES,
},
},
],
},
actionColumn: {
- width: 160,
+ width: 200,
title: '鎿嶄綔',
dataIndex: 'action',
fixed: 'right',
},
});
+onMounted(async () => {
+ await loadOnlineExamDics();
+ getForm()?.updateSchema?.({
+ field: 'status',
+ componentProps: {
+ allowClear: true,
+ placeholder: '璇烽�夋嫨鐘舵��',
+ options: MY_PAPER_STATUS_OPTIONS.value,
+ fieldNames: TMS_DIC_FIELD_NAMES,
+ },
+ });
+ reload();
+});
+
async function fetchList(params: Record<string, any>) {
- return { data: await getMyPaperList(params) };
+ const page = await getMyPaperList(params);
+ return {
+ data: {
+ list: Array.isArray(page?.list) ? page.list : [],
+ pagination: page?.pagination || { total: 0 },
+ },
+ };
}
function handleDetail(record: MyPaperListItem) {
@@ -91,11 +152,22 @@
starting.value = true;
try {
const paper = await startOnlineExam(record.id);
+ if (paper?.autoSubmitted) {
+ createMessage.warning('鑰冭瘯鏃堕棿宸插埌锛屽凡鑷姩浜ゅ嵎');
+ reload();
+ return;
+ }
sessionStorage.setItem('tms_online_exam_paper', JSON.stringify(paper));
sessionStorage.setItem('tms_online_exam_myPaperId', record.id);
router.push('/tms/onlineExam/exam');
} catch (e: any) {
- createMessage.error(e?.message || '寮�濮嬭�冭瘯澶辫触');
+ const msg = e?.message || '寮�濮嬭�冭瘯澶辫触';
+ if (String(msg).includes('鑷姩浜ゅ嵎')) {
+ createMessage.warning(msg);
+ reload();
+ } else {
+ createMessage.error(msg);
+ }
} finally {
starting.value = false;
}
@@ -104,11 +176,13 @@
function getTableActions(record: MyPaperListItem): ActionItem[] {
const actions: ActionItem[] = [];
if (record.status === 'notStarted') {
- actions.push({ label: '寮�濮嬭�冭瘯', onClick: handleStart.bind(null, record) });
+ actions.push({ label: TMS_BTN.startExam, onClick: handleStart.bind(null, record) });
} else if (record.status === 'doing') {
- actions.push({ label: '缁х画鑰冭瘯', onClick: handleStart.bind(null, record) });
+ actions.push({ label: TMS_BTN.continueExam, onClick: handleStart.bind(null, record) });
+ } else if (record.status === 'submitted' && record.canRetake) {
+ actions.push({ label: TMS_BTN.retake, onClick: handleStart.bind(null, record) });
}
- actions.push({ label: '鏌ョ湅璇︽儏', onClick: handleDetail.bind(null, record) });
+ actions.push({ label: TMS_BTN.detail, onClick: handleDetail.bind(null, record) });
return actions;
}
</script>
@@ -120,8 +194,8 @@
<BasicVxeTable @register="registerTable">
<template #tableTitle>
<div>
- <div class="text-base font-medium">鎴戠殑璇曞嵎</div>
- <div class="mt-1 text-gray-400 text-sm">鎴戠殑璇曞嵎锛岄�夋嫨璇曞嵎鍙傚姞鑰冭瘯锛屾垨鑰呮煡鐪嬭�冭瘯璇︽儏銆�</div>
+ <div class="tms-page-header__title">鎴戠殑璇曞嵎</div>
+ <div class="tms-page-header__sub">鍙傚姞鑰冭瘯鎴栨煡鐪嬫垚缁╋紱鍙�冩椂鎿嶄綔鍒楃洿鎺ュ紑鑰冦��</div>
</div>
</template>
<template #status="{ record }">
@@ -129,6 +203,11 @@
{{ labelOfMyPaperStatus(record.status) }}
</span>
</template>
+ <template #passFlag="{ record }">
+ <span :style="{ color: colorOfPassFlag(record.passFlag) }">
+ {{ labelOfPassFlag(record.passFlag) }}
+ </span>
+ </template>
<template #action="{ record }">
<TableAction :actions="getTableActions(record)" />
</template>
--
Gitblit v1.8.0