This commit is contained in:
Владимир Фёдоров 2025-06-30 23:25:12 +07:00
parent 417284c7f0
commit 805f5a6d4f
3 changed files with 78 additions and 70 deletions

View File

@ -1,10 +1,10 @@
<script setup lang="ts"> <script setup lang="ts">
import { onMounted, ref } from 'vue'; import { onMounted, ref } from 'vue';
import { getApiUrl } from './net';
import router from '@/router'; import router from '@/router';
import VueQrcode from '@chenfengyuan/vue-qrcode'; import VueQrcode from '@chenfengyuan/vue-qrcode';
import type { Game, Teams } from './models'; import type { Game, Teams } from './models';
import { apiGetTeams, apiAddTeam, apiGetGame, apiStartGame, apiStopGame } from './client'; import { qrOptions } from './qr';
import { apiGetTeams, apiAddTeam, apiGetGame, apiStartGame, apiStopGame, apiGaveApplication, apiDownloadQrCodesFile } from './client';
const qrurl = ref("-") const qrurl = ref("-")
const qrteam = ref("-") const qrteam = ref("-")
@ -14,44 +14,11 @@ const game = ref<Game | undefined>()
const teams = ref<Teams>({ teams: [] }) const teams = ref<Teams>({ teams: [] })
function gaveApplication(teamId: number, id: number) {
fetch(
getApiUrl("/teams/" + teamId + "/applications"),
{
method: "POST",
body: JSON.stringify({
"applications": [{ "id": id }]
})
}
)
.then(() => { })
.catch(error => {
console.error('Ошибка:', error)
});
}
const teamName = ref("") const teamName = ref("")
function addTeam() { function addTeam() {
apiAddTeam(teamName) apiAddTeam(teamName)
} }
interface QROptions {
width?: number;
margin?: number;
color?: {
dark: string;
light: string;
};
}
const qrOptions = ref<QROptions>({
width: 100,
margin: 1,
color: {
dark: '#000000',
light: 'f0f0f0'
}
});
function getGame() { function getGame() {
apiGetGame(game, gameState) apiGetGame(game, gameState)
} }
@ -64,39 +31,6 @@ function stopGame() {
apiStopGame(gameState) apiStopGame(gameState)
} }
function base64ToBytes(base64: string): Uint8Array {
const binaryString = atob(base64);
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
return bytes;
}
function downloadQrCodesFile() {
fetch(
getApiUrl("/teams/pdf")
)
.then(response => response.json())
.then(data => {
const b = base64ToBytes(data.result)
downloadFile(b, 'teams_qr_code.pdf', 'application/pdf;teams_qr_code.pdf')
})
.catch(error => {
console.error('Ошибка:', error)
});
}
function downloadFile(bytes: Uint8Array, fileName: string, mimeType: string) {
const blob = new Blob([bytes], { type: mimeType });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = fileName;
link.click();
URL.revokeObjectURL(url);
};
let intervalId = 0 let intervalId = 0
onMounted(() => { onMounted(() => {
apiGetTeams(teams) apiGetTeams(teams)
@ -137,7 +71,7 @@ onMounted(() => {
<th>Название команды</th> <th>Название команды</th>
<th>Поездки</th> <th>Поездки</th>
<th>Приложения</th> <th>Приложения</th>
<th><button v-on:click="downloadQrCodesFile" class="button-custom-inline">Скачать qr-ы</button></th> <th><button v-on:click="apiDownloadQrCodesFile" class="button-custom-inline">Скачать qr-ы</button></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -152,7 +86,7 @@ onMounted(() => {
<td> <td>
<div v-for="application in team.applications" :key="application.id"> <div v-for="application in team.applications" :key="application.id">
{{ application.name }} <button class="link-button" {{ application.name }} <button class="link-button"
@click="gaveApplication(team.id, application.id)">Выдано</button> @click="apiGaveApplication(team.id, application.id)">Выдано</button>
</div> </div>
</td> </td>
<td class="cell-center"> <td class="cell-center">

View File

@ -1,6 +1,7 @@
import type { Ref } from 'vue'; import type { Ref } from 'vue';
import { getApiUrl } from './net'; import { getApiUrl } from './net';
import type { Game, Teams } from './models'; import type { Game, Teams } from './models';
import { downloadData } from './qr';
export const apiGetTeams = (teams: Ref<Teams>) => { export const apiGetTeams = (teams: Ref<Teams>) => {
fetch( fetch(
@ -74,3 +75,33 @@ export const apiStopGame = (gameState: Ref<string>) => {
console.error('Ошибка:', error) console.error('Ошибка:', error)
}); });
} }
export const apiGaveApplication = (teamId: number, id: number) => {
fetch(
getApiUrl("/teams/" + teamId + "/applications"),
{
method: "POST",
body: JSON.stringify({
"applications": [{ "id": id }]
})
}
)
.then(() => { })
.catch(error => {
console.error('Ошибка:', error)
});
}
export const apiDownloadQrCodesFile = () => {
fetch(
getApiUrl("/teams/pdf")
)
.then(response => response.json())
.then(data => {
downloadData(data.result)
})
.catch(error => {
console.error('Ошибка:', error)
});
}

43
src/components/qr.ts Normal file
View File

@ -0,0 +1,43 @@
import { ref } from 'vue';
interface QROptions {
width?: number;
margin?: number;
color?: {
dark: string;
light: string;
};
}
export const qrOptions = ref<QROptions>({
width: 100,
margin: 1,
color: {
dark: '#000000',
light: 'f0f0f0'
}
});
export const downloadData = (data: string) => {
const b = base64ToBytes(data)
downloadFile(b, 'teams_qr_code.pdf', 'application/pdf;teams_qr_code.pdf')
}
export const base64ToBytes = (base64: string): Uint8Array => {
const binaryString = atob(base64);
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
return bytes;
}
export const downloadFile = (bytes: Uint8Array, fileName: string, mimeType: string) => {
const blob = new Blob([bytes], { type: mimeType });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = fileName;
link.click();
URL.revokeObjectURL(url);
};