From c153ee817af3699307dda9feab98cfa46269fd0e Mon Sep 17 00:00:00 2001 From: Fedorov Vladimir Date: Mon, 12 Oct 2026 15:58:46 +0700 Subject: [PATCH] up --- proto/main.proto | 8 +++++ src/api/binary_client.ts | 5 ++++ .../crabs/evening_detective_server/index.ts | 21 ++++++++++++++ src/components/GamePage.vue | 29 +++++++++++++++++++ 4 files changed, 63 insertions(+) diff --git a/proto/main.proto b/proto/main.proto index e2d0e3e..5008508 100644 --- a/proto/main.proto +++ b/proto/main.proto @@ -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" diff --git a/src/api/binary_client.ts b/src/api/binary_client.ts index a3a4f4d..36089b5 100644 --- a/src/api/binary_client.ts +++ b/src/api/binary_client.ts @@ -61,6 +61,10 @@ function buildBinaryClient( return download(`api/games/${id}/teams/qr.pdf`, `game-${id}.pdf`) } + function downloadGamePrintMaterials(id: number): Promise { + return download(`api/games/${id}/print-materials`, `game-${id}-print-materials.zip`) + } + function downloadGamePackage(id: number): Promise { return download(`api/games/${id}/export/download`, `game-${id}.zip`) } @@ -132,6 +136,7 @@ function buildBinaryClient( return { downloadScenarioArchive, downloadTeamQR, + downloadGamePrintMaterials, uploadScenarioArchive, downloadGamePackage, uploadGamePackage, diff --git a/src/api/generated/crabs/evening_detective_server/index.ts b/src/api/generated/crabs/evening_detective_server/index.ts index 3b66127..803004a 100644 --- a/src/api/generated/crabs/evening_detective_server/index.ts +++ b/src/api/generated/crabs/evening_detective_server/index.ts @@ -1440,6 +1440,7 @@ export interface EveningDetectiveServer { SaveScreenPlan(request: SaveScreenPlanReq): Promise; SetScreenPlanStep(request: SetScreenPlanStepReq): Promise; GetScreenResults(request: GetScreenResultsReq): Promise; + DownloadGamePrintMaterials(request: GetGameReq): Promise; DownloadTeamQR(request: GetGameReq): Promise; GetGameAnswers(request: GetGameAnswersReq): Promise; GetGameResults(request: GetGameResultsReq): Promise; @@ -3105,6 +3106,26 @@ export function createEveningDetectiveServerClient( method: "GetScreenResults", }) as Promise; }, + 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; + }, DownloadTeamQR(request) { // eslint-disable-line @typescript-eslint/no-unused-vars if (!request.ID) { throw new Error("missing required field request.ID"); diff --git a/src/components/GamePage.vue b/src/components/GamePage.vue index 53a2bfa..8d89b36 100644 --- a/src/components/GamePage.vue +++ b/src/components/GamePage.vue @@ -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(() => {
+ + Скачать материалы для печати + QR