This commit is contained in:
2026-10-12 15:58:46 +07:00
parent 4a89dd1d74
commit c153ee817a
4 changed files with 63 additions and 0 deletions
+8
View File
@@ -912,6 +912,14 @@ service EveningDetectiveServer {
};
}
rpc DownloadGamePrintMaterials(GetGameReq) returns (google.api.HttpBody) {
option (google.api.http) = {get: "/api/games/{ID}/print-materials"};
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
tags: "Игры";
summary: "Скачать материалы игры для печати ZIP-архивом";
};
}
rpc DownloadTeamQR(GetGameReq) returns (google.api.HttpBody) {
option (google.api.http) = {
get: "/api/games/{ID}/teams/qr.pdf"
+5
View File
@@ -61,6 +61,10 @@ function buildBinaryClient(
return download(`api/games/${id}/teams/qr.pdf`, `game-${id}.pdf`)
}
function downloadGamePrintMaterials(id: number): Promise<DownloadFileResult> {
return download(`api/games/${id}/print-materials`, `game-${id}-print-materials.zip`)
}
function downloadGamePackage(id: number): Promise<DownloadFileResult> {
return download(`api/games/${id}/export/download`, `game-${id}.zip`)
}
@@ -132,6 +136,7 @@ function buildBinaryClient(
return {
downloadScenarioArchive,
downloadTeamQR,
downloadGamePrintMaterials,
uploadScenarioArchive,
downloadGamePackage,
uploadGamePackage,
@@ -1440,6 +1440,7 @@ export interface EveningDetectiveServer {
SaveScreenPlan(request: SaveScreenPlanReq): Promise<SaveScreenPlanRsp>;
SetScreenPlanStep(request: SetScreenPlanStepReq): Promise<SetScreenPlanStepRsp>;
GetScreenResults(request: GetScreenResultsReq): Promise<GetScreenResultsRsp>;
DownloadGamePrintMaterials(request: GetGameReq): Promise<googleapi_HttpBody>;
DownloadTeamQR(request: GetGameReq): Promise<googleapi_HttpBody>;
GetGameAnswers(request: GetGameAnswersReq): Promise<GetGameAnswersRsp>;
GetGameResults(request: GetGameResultsReq): Promise<GetGameResultsRsp>;
@@ -3105,6 +3106,26 @@ export function createEveningDetectiveServerClient(
method: "GetScreenResults",
}) as Promise<GetScreenResultsRsp>;
},
DownloadGamePrintMaterials(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
if (!request.ID) {
throw new Error("missing required field request.ID");
}
const path = `api/games/${request.ID}/print-materials`; // eslint-disable-line quotes
const body = null;
const queryParams: string[] = [];
let uri = path;
if (queryParams.length > 0) {
uri += `?${queryParams.join("&")}`
}
return handler({
path: uri,
method: "GET",
body,
}, {
service: "EveningDetectiveServer",
method: "DownloadGamePrintMaterials",
}) as Promise<googleapi_HttpBody>;
},
DownloadTeamQR(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
if (!request.ID) {
throw new Error("missing required field request.ID");
+29
View File
@@ -66,6 +66,7 @@ const emit = defineEmits<{ resultsApplied: [] }>()
const client = getAuthClient()
const binaryClient = getBinaryClient()
const isDownloadingQR = ref(false)
const isDownloadingPrintMaterials = ref(false)
const router = useRouter()
const route = useRoute()
const gameId = route.params.id
@@ -731,6 +732,27 @@ async function applyResults() {
}
}
async function downloadPrintMaterials() {
const id = game.value.ID
if (!canManageGame.value || !id || isDownloadingPrintMaterials.value) return
isDownloadingPrintMaterials.value = true
try {
const { blob, filename } = await binaryClient.downloadGamePrintMaterials(id)
const url = URL.createObjectURL(blob)
const link = document.createElement('a')
link.href = url
link.download = filename
document.body.appendChild(link)
link.click()
link.remove()
setTimeout(() => URL.revokeObjectURL(url), 1000)
} catch (err) {
message.error(err instanceof Error ? err.message : 'Не удалось скачать материалы для печати')
} finally {
isDownloadingPrintMaterials.value = false
}
}
async function downloadTeamQR() {
if (isDownloadingQR.value || !game.value.teams?.length) return
isDownloadingQR.value = true
@@ -1073,6 +1095,13 @@ useSimplePolling(() => {
<div class="game-tab-content">
<UiBlock>
<n-flex justify="end">
<n-button
:loading="isDownloadingPrintMaterials"
:disabled="!game.ID || isDownloadingPrintMaterials"
@click="downloadPrintMaterials"
>
Скачать материалы для печати
</n-button>
<n-button quaternary @click="openQR(url, 'Админка')">QR</n-button>
<n-button v-if="game.status == 'finish'" quaternary @click="toResults()">
<Icon class="settings-icon">