裁判报名二维码
This commit is contained in:
parent
1c50b88052
commit
7d258fd3ca
@ -4,4 +4,4 @@ export const judgeAssignmentBoardGet = (eventId) => http.get(`/judgeassignment/b
|
||||
export const judgeCandidatesGet = (eventId, sessionId) => http.get(`/judgeassignment/candidates/${eventId}/${sessionId}`);
|
||||
export const judgeAssignmentSavePost = (data) => http.post('/judgeassignment/save', data);
|
||||
export const judgeAssignmentSubmitPost = (data) => http.post('/judgeassignment/submit', data);
|
||||
export const judgeRegistrationCodePost = (eventId) => http.post(`/judgeassignment/registration-code/${eventId}`);
|
||||
export const judgeRegistrationCodePost = (eventId) => http.post(`/judgeassignment/registration-qrcode/${eventId}`);
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
|
||||
<div v-if="mode === 'eventReferees'" class="panel-body">
|
||||
<ProTable :data="eventReferees" :columns="eventRefereeColumns" :pagination="false" :tool-button="false" :loading="loading" row-key="eventRefereeId">
|
||||
<template #tools><el-button type="success" icon="ele-Postcard" :loading="codeLoading" @click="generateCode">生成裁判报名码</el-button></template>
|
||||
<template #tools><el-button type="success" icon="ele-Postcard" :loading="codeLoading" @click="generateCode">生成裁判报名二维码</el-button></template>
|
||||
<template #certificateUrl="scope"><el-image v-if="scope.row.certificateUrl" :src="scope.row.certificateUrl" :preview-src-list="[scope.row.certificateUrl]" preview-teleported fit="cover" class="certificate" /><span v-else>-</span></template>
|
||||
<template #roles="scope">{{ scope.row.roleNames?.join(' / ') || '-' }}</template>
|
||||
</ProTable>
|
||||
@ -50,15 +50,14 @@
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="codeVisible" title="裁判报名二维码" width="min(420px, 92vw)" align-center destroy-on-close>
|
||||
<div class="code-dialog"><div ref="qrcodeRef" class="qrcode" aria-label="裁判报名二维码"></div><div class="registration-code">报名码:{{ registrationCode }}</div><el-button type="primary" @click="downloadCode">下载二维码</el-button></div>
|
||||
<div class="code-dialog"><div class="qrcode"><img v-if="registrationCodeImage" :src="registrationCodeImage" alt="裁判报名小程序码" /></div><div class="scan-tip">微信扫码后将直接打开小程序赛事详情,并进入裁判报名流程</div><div class="registration-code">报名码:{{ registrationCode }}</div><el-button type="primary" @click="downloadCode">下载二维码</el-button></div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, nextTick, reactive, ref, watch } from 'vue';
|
||||
import { computed, reactive, ref, watch } from 'vue';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import QRCode from 'qrcodejs2-fixes';
|
||||
import ProTable from '/@/components/ProTable/index.vue';
|
||||
import { judgeAssignmentBoardGet, judgeAssignmentSavePost, judgeAssignmentSubmitPost, judgeCandidatesGet, judgeEventRefereesGet, judgeRegistrationCodePost } from '/@/api/match/judgeassignment';
|
||||
|
||||
@ -77,7 +76,7 @@ const assignmentMap = reactive({});
|
||||
const codeVisible = ref(false);
|
||||
const codeLoading = ref(false);
|
||||
const registrationCode = ref('');
|
||||
const qrcodeRef = ref();
|
||||
const registrationCodeImage = ref('');
|
||||
|
||||
const eventRefereeColumns = [
|
||||
{ prop: 'index', label: '序号', type: 'index', width: 80 },
|
||||
@ -143,9 +142,18 @@ async function saveAssignments() {
|
||||
async function submitAll() { await ElMessageBox.confirm('提交后分配任务即可同步到裁判端,是否继续?', '提交确认', { type: 'warning' }); const result = await judgeAssignmentSubmitPost({ eventId: Number(props.eventId) }); if (!result?.succeeded) return; ElMessage.success('提交成功'); load(); }
|
||||
async function generateCode() {
|
||||
codeLoading.value = true;
|
||||
try { const result = await judgeRegistrationCodePost(props.eventId); if (!result?.succeeded || !result.data) return ElMessage.error('报名码生成失败,请稍后重试'); registrationCode.value = result.data; codeVisible.value = true; await nextTick(); qrcodeRef.value.innerHTML = ''; new QRCode(qrcodeRef.value, { text: registrationCode.value, width: 240, height: 240, colorDark: '#1d2129', colorLight: '#ffffff', correctLevel: QRCode.CorrectLevel.H }); } finally { codeLoading.value = false; }
|
||||
try {
|
||||
const result = await judgeRegistrationCodePost(props.eventId);
|
||||
const data = result?.data;
|
||||
if (!result?.succeeded || !data?.registrationCode || !data?.qrCodeDataUrl) return ElMessage.error('裁判报名二维码生成失败,请稍后重试');
|
||||
registrationCode.value = data.registrationCode;
|
||||
registrationCodeImage.value = data.qrCodeDataUrl;
|
||||
codeVisible.value = true;
|
||||
} catch {
|
||||
// 请求层已统一提示错误,此处仅收口事件 Promise,避免产生未处理异常。
|
||||
} finally { codeLoading.value = false; }
|
||||
}
|
||||
function downloadCode() { const canvas = qrcodeRef.value?.querySelector('canvas'); const image = qrcodeRef.value?.querySelector('img'); const url = canvas?.toDataURL('image/png') || image?.src; if (!url) return ElMessage.error('二维码尚未生成,请稍后重试'); const link = document.createElement('a'); link.href = url; link.download = `裁判报名二维码-${registrationCode.value}.png`; document.body.appendChild(link); link.click(); document.body.removeChild(link); }
|
||||
function downloadCode() { if (!registrationCodeImage.value) return ElMessage.error('二维码尚未生成,请稍后重试'); const link = document.createElement('a'); link.href = registrationCodeImage.value; link.download = `裁判报名二维码-${registrationCode.value}.jpg`; document.body.appendChild(link); link.click(); document.body.removeChild(link); }
|
||||
watch(() => props.active, value => value && load(), { immediate: true });
|
||||
</script>
|
||||
|
||||
@ -175,7 +183,8 @@ watch(() => props.active, value => value && load(), { immediate: true });
|
||||
.candidate { width: calc(100% - 16px); margin: 8px 8px 0; }
|
||||
.code-dialog { display: flex; flex-direction: column; align-items: center; gap: 16px; }
|
||||
.qrcode { width: 264px; height: 264px; padding: 12px; background: #fff; border: 1px solid var(--el-border-color-lighter); border-radius: 8px; box-shadow: var(--el-box-shadow-light); }
|
||||
.qrcode :deep(img), .qrcode :deep(canvas) { display: block; width: 240px !important; height: 240px !important; }
|
||||
.qrcode img { display: block; width: 240px; height: 240px; }
|
||||
.scan-tip { max-width: 300px; font-size: 13px; line-height: 1.6; color: var(--el-text-color-secondary); text-align: center; }
|
||||
.registration-code { font-size: 14px; color: var(--el-text-color-secondary); word-break: break-all; }
|
||||
@media (max-width: 768px) { .judge-panel { padding: 0; } .project-heading { flex-direction: column; align-items: flex-start; gap: 6px; } .assign-layout { grid-template-columns: 1fr; } .role-slots { grid-template-columns: 1fr; } .submit-bar { position: sticky; bottom: 0; z-index: 2; padding: 12px; background: var(--el-bg-color); } }
|
||||
</style>
|
||||
|
||||
@ -36,6 +36,9 @@ const viteConfig = defineConfig((mode: ConfigEnv) => {
|
||||
port: env.VITE_PORT as unknown as number,
|
||||
open: JSON.parse(env.VITE_OPEN),
|
||||
hmr: true,
|
||||
watch: {
|
||||
ignored: ['**/[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/**', '**/dist/**'],
|
||||
},
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: env.VITE_API_TARGET || 'https://event.yuedongsports.com',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user