add background

This commit is contained in:
2026-09-06 01:03:55 +07:00
parent 56ab0c2c15
commit 13aad8ff4c
46 changed files with 192 additions and 46 deletions
+75
View File
@@ -59,6 +59,9 @@ const scenario = ref<Scenario>({
publishedAt: undefined,
})
const backgroundFiles = ref<UploadFileInfo[]>([])
const savingBackground = ref(false)
const intro = ref<EditableIntroduction>({ text: '', audio: '' })
const introMode = ref('show-editor')
@@ -489,6 +492,38 @@ async function updateIntro() {
await getScenario(Number(scenarioId))
}
async function updateBackground(remove = false) {
savingBackground.value = true
try {
let background = ''
if (!remove) {
const file = backgroundFiles.value[0]?.file
if (!file) return
const uploaded = await uploadFile(
file,
'scenarios_' + scenario.value.id + '_background_' + file.name,
)
if (!uploaded.filename) return
if (uploaded.fileType !== 'image') {
message.error('Фон дела должен быть изображением')
return
}
background = uploaded.filename
}
const res = await client.UpdateScenarioBackground({ id: scenario.value.id, background })
if (res.error) {
message.error(res.error)
return
}
await getScenario(Number(scenarioId))
backgroundFiles.value = []
} catch {
message.error('Не удалось сохранить фон дела')
} finally {
savingBackground.value = false
}
}
async function cancelUpdateIntro() {
await getScenario(Number(scenarioId))
}
@@ -545,6 +580,40 @@ function getRandomComplimentForNastya() {
</n-button>
</div>
<n-card title="Фон дела">
<n-space vertical>
<img
v-if="scenario.story?.background"
:src="scenario.story.background"
alt="Фон дела"
class="background-preview"
/>
<n-upload
v-model:file-list="backgroundFiles"
accept=".jpg,.jpeg,.png,.gif,.webp"
:max="1"
:default-upload="false"
:disabled="savingBackground"
>
<n-button :disabled="savingBackground">Выбрать фон</n-button>
</n-upload>
<n-flex>
<n-button
:loading="savingBackground"
:disabled="!backgroundFiles.length || savingBackground"
@click="updateBackground()"
>Сохранить фон</n-button
>
<n-button
v-if="scenario.story?.background"
:disabled="savingBackground"
@click="updateBackground(true)"
>Удалить фон</n-button
>
</n-flex>
</n-space>
</n-card>
<IntroBlock :introduction="intro" v-model:mode="introMode">
<n-flex justify="end">
<n-button @click="cancelUpdateIntro()">Отмена</n-button>
@@ -748,6 +817,12 @@ function getRandomComplimentForNastya() {
</template>
<style scoped>
.background-preview {
max-height: 200px;
max-width: 100%;
object-fit: contain;
}
.settings-block {
height: 40px;
+17
View File
@@ -81,6 +81,7 @@ async function getStory() {
const oldCount = story.value.places.length
story.value = {
background: res.story!.background,
introduction: res.story!.introduction,
places:
res.story!.places?.map((item, i) => {
@@ -127,6 +128,7 @@ async function addAction(newCode: string) {
}
type AdvancedStory = {
background?: string
introduction?: Introduction
places: AdvancedPlace[]
questions: Question[]
@@ -225,6 +227,12 @@ useSimplePolling(() => {
</script>
<template>
<div
v-if="story.background"
class="case-background"
:style="{ backgroundImage: `url(${JSON.stringify(story.background)})` }"
aria-hidden="true"
/>
<div class="center-block-custom bottom-margin smooth-scroll" ref="scrollContainer">
<div class="width700">
<GameInputForm
@@ -309,6 +317,15 @@ useSimplePolling(() => {
</template>
<style scoped>
.case-background {
background-position: center;
background-size: cover;
inset: 70px 0 0;
pointer-events: none;
position: fixed;
z-index: -1;
}
.bottom-margin {
height: calc(100dvh - 70px - 76px);
}