liuyu
21 小时以前 93c133349a5ccd7a328371fa113dce69d5611f21
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>