| | |
| | | <script lang="ts" setup> |
| | | import type { TmsRecordDetail } from './types'; |
| | | |
| | | import { onMounted, reactive, ref } from 'vue'; |
| | | import { onMounted, ref } from 'vue'; |
| | | import { useRoute, useRouter } from 'vue-router'; |
| | | |
| | | import { useMessage } from '@jnpf/hooks'; |
| | | import { Table as ATable } from 'ant-design-vue'; |
| | | import dayjs from 'dayjs'; |
| | | |
| | | import { getTmsRecordDetail } from '#/api/x/tms/record'; |
| | | import { TMS_BTN } from '#/views/x/tms/shared/ui'; |
| | | |
| | | import '#/views/x/tms/shared/page.css'; |
| | | |
| | | defineOptions({ name: 'TmsRecordSign' }); |
| | | |
| | |
| | | const { createMessage } = useMessage(); |
| | | |
| | | const loading = ref(false); |
| | | const submitting = ref(false); |
| | | const detail = ref<TmsRecordDetail | null>(null); |
| | | |
| | | const form = reactive({ |
| | | userName: '', |
| | | deptName: '', |
| | | signMode: '在线签到', |
| | | }); |
| | | |
| | | const signColumns = [ |
| | | { title: '序号', key: 'index', width: 70, align: 'center', customRender: ({ index }: any) => index + 1 }, |
| | |
| | | } |
| | | } |
| | | |
| | | function handleSubmit() { |
| | | if (!form.userName.trim()) { |
| | | createMessage.warning('请输入签到人姓名'); |
| | | return; |
| | | } |
| | | if (!detail.value) return; |
| | | submitting.value = true; |
| | | try { |
| | | detail.value.signList = [ |
| | | { |
| | | id: `s-${Date.now()}`, |
| | | userName: form.userName.trim(), |
| | | deptName: form.deptName.trim() || undefined, |
| | | signTime: dayjs().format('YYYY-MM-DD HH:mm:ss'), |
| | | signMode: form.signMode, |
| | | }, |
| | | ...(detail.value.signList || []), |
| | | ]; |
| | | form.userName = ''; |
| | | form.deptName = ''; |
| | | createMessage.success('签到成功(本地 mock,联调后写入服务端)'); |
| | | } finally { |
| | | submitting.value = false; |
| | | } |
| | | } |
| | | |
| | | function goBack() { |
| | | router.push('/tms/record'); |
| | | } |
| | |
| | | <div class="jnpf-content-wrapper-content tms-record-wrap"> |
| | | <a-spin :spinning="loading" class="record-spin"> |
| | | <div v-if="detail" class="record-inner"> |
| | | <div class="record-header"> |
| | | <div class="tms-page-header"> |
| | | <div> |
| | | <div class="text-base font-medium">培训签到</div> |
| | | <div class="mt-1 text-gray-400 text-sm"> |
| | | {{ detail.recordNo }} · {{ detail.subject }} |
| | | <div class="tms-page-header__title">培训签到</div> |
| | | <div class="tms-page-header__sub">{{ detail.recordNo }} · {{ detail.subject }}</div> |
| | | </div> |
| | | <div class="tms-page-header__actions"> |
| | | <a-button @click="goBack">{{ TMS_BTN.back }}</a-button> |
| | | </div> |
| | | <a-button @click="goBack">返回</a-button> |
| | | </div> |
| | | |
| | | <a-form layout="inline" class="sign-form mb-4"> |
| | | <a-form-item label="姓名"> |
| | | <a-input v-model:value="form.userName" placeholder="签到人姓名" class="!w-[140px]" allow-clear /> |
| | | </a-form-item> |
| | | <a-form-item label="部门"> |
| | | <a-input v-model:value="form.deptName" placeholder="部门(可选)" class="!w-[160px]" allow-clear /> |
| | | </a-form-item> |
| | | <a-form-item label="方式"> |
| | | <a-select |
| | | v-model:value="form.signMode" |
| | | class="!w-[130px]" |
| | | :options="[ |
| | | { label: '在线签到', value: '在线签到' }, |
| | | { label: 'APP扫码', value: 'APP扫码' }, |
| | | { label: '微信扫码', value: '微信扫码' }, |
| | | ]" |
| | | <a-alert |
| | | class="tms-page-tip" |
| | | type="info" |
| | | show-icon |
| | | message="管理端补签/扫码签到即将接入" |
| | | description="当前请学员在「个人培训任务」中完成签到。下方为已同步的签到名单(只读)。" |
| | | /> |
| | | </a-form-item> |
| | | <a-form-item> |
| | | <a-button type="primary" :loading="submitting" @click="handleSubmit">确认签到</a-button> |
| | | </a-form-item> |
| | | </a-form> |
| | | |
| | | <div class="section-title">已签到人员</div> |
| | | <ATable |
| | |
| | | padding: 16px 20px 24px; |
| | | } |
| | | |
| | | .record-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-bottom: 16px; |
| | | } |
| | | |
| | | .section-title { |
| | | font-size: 15px; |
| | | font-weight: 600; |
| | | margin: 8px 0 12px; |
| | | padding-left: 10px; |
| | | border-left: 3px solid #1677ff; |
| | | } |
| | | |
| | | .sign-form { |
| | | padding: 12px; |
| | | background: #fafafa; |
| | | border-radius: 6px; |
| | | } |
| | | </style> |