|
|
@@ -89,7 +89,7 @@
|
|
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
|
|
<template #default="scope">
|
|
|
<el-tooltip content="手动取票" placement="top">
|
|
|
- <el-button link type="primary" icon="Edit" @click="getNextTournament(scope.row)">手动取票</el-button>
|
|
|
+ <el-button link type="primary" icon="Printer" @click="handlePrintTicket(scope.row)">手动取票</el-button>
|
|
|
</el-tooltip>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
@@ -148,26 +148,70 @@
|
|
|
</div>
|
|
|
</template>
|
|
|
</el-dialog>
|
|
|
+ <!-- 打印票券弹窗 -->
|
|
|
+ <el-dialog v-model="ticketDialog.visible" title="票券信息" width="400px" append-to-body>
|
|
|
+ <div class="ticket-info-list">
|
|
|
+ <div class="info-item" v-if="ticketHeaderTitle">
|
|
|
+ <span class="info-label">编号:</span>
|
|
|
+ <span class="info-value">{{ ticketHeaderTitle }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="info-item" v-if="ticketData.leagueTournamentRegion">
|
|
|
+ <span class="info-label">赛区:</span>
|
|
|
+ <span class="info-value">{{ ticketData.leagueTournamentRegion }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="info-item" v-if="ticketData.startTime">
|
|
|
+ <span class="info-label">时间:</span>
|
|
|
+ <span class="info-value">{{ ticketData.startTime }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="info-item" v-if="ticketData.name">
|
|
|
+ <span class="info-label">赛事:</span>
|
|
|
+ <span class="info-value">{{ ticketData.name }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="info-item" v-if="ticketData.leagueTournamentTitle">
|
|
|
+ <span class="info-label">联赛:</span>
|
|
|
+ <span class="info-value">{{ ticketData.leagueTournamentTitle }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="info-item" v-if="ticketData.idCardNumber">
|
|
|
+ <span class="info-label">身份证:</span>
|
|
|
+ <span class="info-value">{{ ticketData.idCardNumber }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="info-item" v-if="ticketData.realName">
|
|
|
+ <span class="info-label">姓名:</span>
|
|
|
+ <span class="info-value">{{ ticketData.realName }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="info-item" v-if="ticketData.seatNumInfo">
|
|
|
+ <span class="info-label">座位:</span>
|
|
|
+ <span class="info-value">{{ ticketData.seatNumInfo }}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <template #footer>
|
|
|
+ <div class="dialog-footer">
|
|
|
+ <el-button type="primary" @click="doPrint">打 印</el-button>
|
|
|
+ <el-button @click="ticketDialog.visible = false">关 闭</el-button>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script setup name="Participants" lang="ts">
|
|
|
import { ref, reactive, onMounted, toRefs, watch } from 'vue';
|
|
|
-import { useRoute } from 'vue-router'; // 添加这一行
|
|
|
+import { useRoute } from 'vue-router'; // 添加这一行
|
|
|
import { ElFormInstance } from 'element-plus';
|
|
|
import { ComponentInternalInstance, getCurrentInstance } from 'vue';
|
|
|
-const route = useRoute(); // 添加这一行
|
|
|
+const route = useRoute(); // 添加这一行
|
|
|
import {
|
|
|
listParticipants,
|
|
|
getParticipants,
|
|
|
delParticipants,
|
|
|
addParticipants,
|
|
|
updateParticipants,
|
|
|
- promoteTournament
|
|
|
+ promoteTournament,
|
|
|
+ printTicketInfo
|
|
|
} from '@/api/system/physical/participants';
|
|
|
-import { ParticipantsVO, ParticipantsQuery, ParticipantsForm } from '@/api/system/physical/participants/types';
|
|
|
+import { ParticipantsVO, ParticipantsQuery, ParticipantsForm, TicketTournamentsVo } from '@/api/system/physical/participants/types';
|
|
|
import { parseTime } from '@/utils/dateUtils';
|
|
|
-
|
|
|
+import { generateTicketQRCode, executeTicketPrint, type TicketPrintItem } from '@/api/system/physical/participants/printHelper';
|
|
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
|
|
|
|
|
const participantsList = ref<ParticipantsVO[]>([]);
|
|
|
@@ -178,6 +222,8 @@ const ids = ref<Array<string | number>>([]);
|
|
|
const single = ref(true);
|
|
|
const multiple = ref(true);
|
|
|
const total = ref(0);
|
|
|
+const ticketQrCode = ref();
|
|
|
+const ticketHeaderTitle = ref();
|
|
|
|
|
|
const queryFormRef = ref<ElFormInstance>();
|
|
|
const participantsFormRef = ref<ElFormInstance>();
|
|
|
@@ -186,6 +232,12 @@ const dialog = reactive({
|
|
|
visible: false,
|
|
|
title: ''
|
|
|
});
|
|
|
+const ticketDialog = reactive({
|
|
|
+ visible: false
|
|
|
+});
|
|
|
+
|
|
|
+const ticketPrintRef = ref<HTMLElement>();
|
|
|
+const ticketData = ref<TicketTournamentsVo>({});
|
|
|
|
|
|
const initFormData: ParticipantsForm = {
|
|
|
id: undefined,
|
|
|
@@ -417,7 +469,56 @@ const handleExport = () => {
|
|
|
`用户报名记录${parseTime(new Date(), '{y}{m}{d}{h}{i}{s}')}.xlsx`
|
|
|
);
|
|
|
};
|
|
|
+/** 手动取票 - 打印票券 */
|
|
|
+const handlePrintTicket = async (row: ParticipantsVO) => {
|
|
|
+ try {
|
|
|
+ const res = await printTicketInfo({
|
|
|
+ id: row.id,
|
|
|
+ tournamentId: row.tournamentId,
|
|
|
+ playerId: row.playerId
|
|
|
+ } as ParticipantsForm);
|
|
|
+ debugger;
|
|
|
+ if (res.code === 200 && res.data) {
|
|
|
+
|
|
|
+ console.log('res.data:', res.data);
|
|
|
+ console.log('orderNumber:', res.data.orderNumber);
|
|
|
+ console.log('tournamentSerialNumber:', res.data.tournamentSerialNumber);
|
|
|
+ console.log('seatNumInfo:', res.data.seatNumInfo);
|
|
|
|
|
|
+ ticketData.value = res.data;
|
|
|
+ const printItem: TicketPrintItem = {
|
|
|
+ ...res.data,
|
|
|
+ qrCodeContent: res.data.ticketCode
|
|
|
+ };
|
|
|
+ ticketQrCode.value = await generateTicketQRCode(printItem);
|
|
|
+ if (res.data.orderNumber && res.data.tournamentSerialNumber) {
|
|
|
+ ticketHeaderTitle.value = `${res.data.orderNumber}-#${res.data.tournamentSerialNumber}`;
|
|
|
+ }
|
|
|
+ ticketDialog.visible = true;
|
|
|
+ } else {
|
|
|
+ proxy?.$modal.msgError(res.msg || '获取票券信息失败');
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ proxy?.$modal.msgError('获取票券信息失败:' + (error as Error).message);
|
|
|
+ }
|
|
|
+};
|
|
|
+/** 执行打印 */
|
|
|
+const doPrint = () => {
|
|
|
+ const printItem: TicketPrintItem = {
|
|
|
+ ...ticketData.value,
|
|
|
+ qrCodeContent: ticketData.value.ticketCode
|
|
|
+ };
|
|
|
+ executeTicketPrint(
|
|
|
+ printItem,
|
|
|
+ ticketQrCode.value,
|
|
|
+ () => {
|
|
|
+ ticketDialog.visible = false;
|
|
|
+ },
|
|
|
+ (error) => {
|
|
|
+ proxy?.$modal.msgError(error.message || '打印失败');
|
|
|
+ }
|
|
|
+ );
|
|
|
+};
|
|
|
// 监听路由变化
|
|
|
watch(
|
|
|
() => route.query,
|
|
|
@@ -436,7 +537,7 @@ watch(
|
|
|
getList();
|
|
|
}
|
|
|
},
|
|
|
- { immediate: false } // 改为 false,不在组件挂载时立即执行
|
|
|
+ { immediate: false } // 改为 false,不在组件挂载时立即执行
|
|
|
);
|
|
|
|
|
|
// 组件挂载时的处理
|
|
|
@@ -451,3 +552,24 @@ onMounted(() => {
|
|
|
getList();
|
|
|
});
|
|
|
</script>
|
|
|
+<!-- ... existing code ... -->
|
|
|
+<style scoped>
|
|
|
+.ticket-info-list {
|
|
|
+ padding: 10px 0;
|
|
|
+}
|
|
|
+.info-item {
|
|
|
+ display: flex;
|
|
|
+ padding: 8px 0;
|
|
|
+ border-bottom: 1px solid #f0f0f0;
|
|
|
+ font-size: 14px;
|
|
|
+}
|
|
|
+.info-label {
|
|
|
+ width: 70px;
|
|
|
+ color: #909399;
|
|
|
+ flex-shrink: 0;
|
|
|
+}
|
|
|
+.info-value {
|
|
|
+ color: #303133;
|
|
|
+ font-weight: 500;
|
|
|
+}
|
|
|
+</style>
|