generated from VLADIMIR/template_frontend
up
This commit is contained in:
@@ -15,6 +15,8 @@ import {
|
||||
NTabPane,
|
||||
NTabs,
|
||||
NText,
|
||||
NUpload,
|
||||
type UploadFileInfo,
|
||||
} from 'naive-ui'
|
||||
import { useMessage } from 'naive-ui'
|
||||
import { computed, ref } from 'vue'
|
||||
@@ -54,6 +56,8 @@ import { useUIStore } from '@/stores/ui'
|
||||
import { applicationFileType, applicationFileURL } from '@/utils/application'
|
||||
import { formatGameDateTime, parseDateWithoutTimezone } from '@/utils/datetime'
|
||||
|
||||
const emit = defineEmits<{ resultsApplied: [] }>()
|
||||
|
||||
const client = getAuthClient()
|
||||
const binaryClient = getBinaryClient()
|
||||
const isDownloadingQR = ref(false)
|
||||
@@ -118,6 +122,16 @@ const canExport = computed(
|
||||
)
|
||||
const isStartingExport = ref(false)
|
||||
const isDownloadingPackage = ref(false)
|
||||
const canDownloadResults = computed(
|
||||
() =>
|
||||
uiStore.environment === 'venue' &&
|
||||
game.value.status === 'finish' &&
|
||||
authStore.hasAnyRole(['admin', 'organizer', 'developer']),
|
||||
)
|
||||
const isDownloadingResults = ref(false)
|
||||
const isApplyingResults = ref(false)
|
||||
const resultsFiles = ref<UploadFileInfo[]>([])
|
||||
const resultsError = ref('')
|
||||
|
||||
const participationOptions = [
|
||||
{ label: 'Ожидает ответа', value: 'pending' },
|
||||
@@ -516,6 +530,60 @@ async function downloadPackage() {
|
||||
}
|
||||
}
|
||||
|
||||
function changeResultsFile({ fileList }: { fileList: UploadFileInfo[] }) {
|
||||
if (isApplyingResults.value) return
|
||||
resultsFiles.value = fileList.slice(-1)
|
||||
resultsError.value = ''
|
||||
}
|
||||
|
||||
async function downloadResults() {
|
||||
if (!canDownloadResults.value || isDownloadingResults.value) return
|
||||
isDownloadingResults.value = true
|
||||
try {
|
||||
const { blob, filename } = await binaryClient.downloadGameResultsPackage(game.value.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 {
|
||||
isDownloadingResults.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function applyResults() {
|
||||
if (!canExport.value || isApplyingResults.value) return
|
||||
const file = resultsFiles.value[0]?.file
|
||||
if (!file || file.size === 0) {
|
||||
resultsError.value = 'Выберите непустой ZIP-файл'
|
||||
return
|
||||
}
|
||||
if (!file.name.toLowerCase().endsWith('.zip')) {
|
||||
resultsError.value = 'Выберите файл с расширением .zip'
|
||||
return
|
||||
}
|
||||
if (file.size > 1024 ** 3) {
|
||||
resultsError.value = 'Размер пакета не должен превышать 1 ГиБ'
|
||||
return
|
||||
}
|
||||
isApplyingResults.value = true
|
||||
resultsError.value = ''
|
||||
try {
|
||||
await binaryClient.applyGameResultsPackage(game.value.ID!, file)
|
||||
message.success('Результаты приняты')
|
||||
emit('resultsApplied')
|
||||
} catch (err) {
|
||||
resultsError.value = err instanceof Error ? err.message : 'Не удалось применить результаты'
|
||||
} finally {
|
||||
isApplyingResults.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function downloadTeamQR() {
|
||||
if (isDownloadingQR.value || !game.value.teams?.length) return
|
||||
isDownloadingQR.value = true
|
||||
@@ -679,6 +747,7 @@ async function issueTickets() {
|
||||
}
|
||||
|
||||
useSimplePolling(() => {
|
||||
if (isApplyingResults.value) return
|
||||
getGame(Number(gameId))
|
||||
getGameScreens()
|
||||
getGameMusic()
|
||||
@@ -905,6 +974,42 @@ useSimplePolling(() => {
|
||||
<n-button @click="updateGame()">Сохранить изменения</n-button>
|
||||
</n-flex>
|
||||
</UiBlock>
|
||||
<UiBlock v-if="canDownloadResults">
|
||||
<n-button
|
||||
:loading="isDownloadingResults"
|
||||
:disabled="isDownloadingResults"
|
||||
@click="downloadResults"
|
||||
>
|
||||
Скачать результаты
|
||||
</n-button>
|
||||
</UiBlock>
|
||||
<UiBlock v-if="canExport">
|
||||
<p class="screens-title">Возврат результатов с площадки</p>
|
||||
<n-space vertical>
|
||||
<n-alert type="warning">
|
||||
Команды, билеты, результаты и игровой сценарий будут заменены данными пакета.
|
||||
Онлайн-правки этих данных потеряются. Оформление и музыка сохраняются.
|
||||
</n-alert>
|
||||
<n-upload
|
||||
:file-list="resultsFiles"
|
||||
:default-upload="false"
|
||||
:max="1"
|
||||
accept=".zip"
|
||||
:disabled="isApplyingResults"
|
||||
@change="changeResultsFile"
|
||||
>
|
||||
<n-button :disabled="isApplyingResults">Выбрать ZIP результатов</n-button>
|
||||
</n-upload>
|
||||
<n-alert v-if="resultsError" type="error" role="alert">{{ resultsError }}</n-alert>
|
||||
<n-button
|
||||
:loading="isApplyingResults"
|
||||
:disabled="isApplyingResults || !resultsFiles.length"
|
||||
@click="applyResults"
|
||||
>
|
||||
Применить ZIP и перезаписать результаты
|
||||
</n-button>
|
||||
</n-space>
|
||||
</UiBlock>
|
||||
<UiBlock v-if="canExport">
|
||||
<p class="screens-title">Передача игры на площадку</p>
|
||||
<n-space vertical>
|
||||
|
||||
Reference in New Issue
Block a user