add images

This commit is contained in:
2026-07-24 00:50:46 +07:00
parent 9bcfe42683
commit 7d04e5a1cd
7 changed files with 80 additions and 23 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

+2 -2
View File
@@ -5,8 +5,8 @@
<link rel="icon" href="/favicon.ico"> <link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Вечерний детектив</title> <title>Вечерний детектив</title>
<script type="module" crossorigin src="/assets/index-BWJYHkKx.js"></script> <script type="module" crossorigin src="/assets/index-DWsDSIY1.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-DEZbkC4o.css"> <link rel="stylesheet" crossorigin href="/assets/index-DEorfnlJ.css">
</head> </head>
<body> <body>
<div id="app"></div> <div id="app"></div>
Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

+34 -2
View File
@@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { NDynamicInput, NInput, NInputGroup, NSpace, NSwitch } from 'naive-ui' import { NDynamicInput, NInput, NInputGroup, NSpace, NSwitch, NText, NUpload, NUploadDragger } from 'naive-ui'
import type { PropType } from 'vue' import type { PropType } from 'vue'
import { LockOutlined } from '@vicons/material' import { LockOutlined } from '@vicons/material'
import { Icon } from '@vicons/utils' import { Icon } from '@vicons/utils'
@@ -87,7 +87,14 @@ function onCreateKey(): Key {
<div v-if="mode == 'show-editor'" class="place-block-hover show-editor-block" @click="updateMode('edit')"> <div v-if="mode == 'show-editor'" class="place-block-hover show-editor-block" @click="updateMode('edit')">
<p>[{{ props.place.code }}] - {{ props.place.name }}</p> <p>[{{ props.place.code }}] - {{ props.place.name }}</p>
<div class="message-content">{{ props.place.text }}</div> <div class="message-content">
<div v-if="props.place.image">
<div class="message-image-border">
<img :src="props.place.image" class="message-image">
</div>
</div>
{{ props.place.text }}
</div>
<div v-for="door in props.place.doors" v-bind:key="door.code" class="door-block"> <div v-for="door in props.place.doors" v-bind:key="door.code" class="door-block">
{{ door.name }} <span v-for="key in door.keys" class="key-block"> {{ door.name }} <span v-for="key in door.keys" class="key-block">
@@ -121,6 +128,16 @@ function onCreateKey(): Key {
</n-input-group> </n-input-group>
<n-input v-model:value="props.place.text" type="textarea" :autosize="{ minRows: 3 }" <n-input v-model:value="props.place.text" type="textarea" :autosize="{ minRows: 3 }"
placeholder="В начале было слово..." /> placeholder="В начале было слово..." />
<p class="settings-header">Картинка</p>
<n-input v-model:value="props.place.image" type="text" placeholder="Не задано" disabled />
<n-upload directory-dnd :max="1" v-model:file-list="props.place.fileList">
<n-upload-dragger>
<n-text style="font-size: 16px">
Щелкните или перетащите файл в эту область для загрузки
</n-text>
</n-upload-dragger>
</n-upload>
<n-switch v-model:value="props.place.hidden"> <n-switch v-model:value="props.place.hidden">
<template #checked> <template #checked>
Скрытая точка Скрытая точка
@@ -284,4 +301,19 @@ function onCreateKey(): Key {
cursor: pointer; cursor: pointer;
color: #63e2b7; color: #63e2b7;
} }
.message-image-border {
width: 40%;
float: left;
padding: 7px;
margin-right: 15px;
background-image: url("@/assets/images/paper_white.jpg");
background-size: cover;
box-shadow: 0px 3px 15px rgb(98, 98, 98);
transform: rotate(-3deg);
}
.message-image {
width: 100%;
}
</style> </style>
+35 -10
View File
@@ -56,28 +56,45 @@ async function deleteScenario(id: number) {
router.push('/scenarios') router.push('/scenarios')
} }
async function updateScenario() { async function uploadFile(file: File | null, filename: string): Promise<string> {
const file = fileList.value[0].file if (!file) {
if (!file) return return ''
}
// Читаем как ArrayBuffer // Читаем как ArrayBuffer
const arrayBuffer = await file.arrayBuffer() const arrayBuffer = await file.arrayBuffer()
const bytes = new Uint8Array(arrayBuffer) const bytes = new Uint8Array(arrayBuffer)
const resUploadFile = await client.UploadFile({ const resUploadFile = await client.UploadFile({
filename: 'scenarios_' + scenario.value.id + '_' + file.name, filename: filename,
data: uint8ToBase64(bytes), data: uint8ToBase64(bytes),
}) })
if (resUploadFile.error != '') { if (resUploadFile.error != '') {
message.error(resUploadFile.error!) message.error(resUploadFile.error!)
return ''
}
return resUploadFile.filename || ''
}
async function updateScenario() {
let resUploadFilename = ''
if (fileList.value.length > 0) {
const file = fileList.value[0].file || null
if (file == null) {
return return
} }
resUploadFilename = await uploadFile(file, 'scenarios_' + scenario.value.id + '_' + file.name)
if (resUploadFilename === '') {
return
}
}
const res = await client.UpdateScenario({ const res = await client.UpdateScenario({
id: scenario.value.id, id: scenario.value.id,
name: scenario.value.name, name: scenario.value.name,
description: scenario.value.description, description: scenario.value.description,
image: resUploadFile.filename, image: resUploadFilename,
}) })
if (res.error != '') { if (res.error != '') {
message.error(res.error!) message.error(res.error!)
@@ -160,10 +177,6 @@ async function addNotFoundDoors(scenario: Scenario, place: Place) {
} }
} }
async function collapseAddPlace(place: Place) {
place.mode = 'mini-add'
}
async function cancelUpdatePlace(place: Place) { async function cancelUpdatePlace(place: Place) {
await getScenario(Number(scenarioId)) await getScenario(Number(scenarioId))
@@ -171,6 +184,18 @@ async function cancelUpdatePlace(place: Place) {
} }
async function updatePlace(place: Place) { async function updatePlace(place: Place) {
if (place.fileList.length > 0) {
const file = place.fileList[0].file || null
if (file == null) {
return
}
const resUploadFilename = await uploadFile(file, 'scenarios_' + scenario.value.id + '_place_' + place.code + '_' + file.name)
if (resUploadFilename === '') {
return
}
place.image = resUploadFilename
}
await addNotFoundDoors(scenario.value, place) await addNotFoundDoors(scenario.value, place)
const res = await client.UpdateScenarioPlace({ const res = await client.UpdateScenarioPlace({
id: scenario.value.id, id: scenario.value.id,
@@ -247,7 +272,7 @@ async function deletePlace(place: Place) {
<p class="settings-header">Картинка</p> <p class="settings-header">Картинка</p>
<n-input v-model:value="scenario.image" type="text" placeholder="default_scenario.png" disabled /> <n-input v-model:value="scenario.image" type="text" placeholder="default_scenario.png" disabled />
<n-upload multiple directory-dnd :max="1" v-model:file-list="fileList"> <n-upload directory-dnd :max="1" v-model:file-list="fileList">
<n-upload-dragger> <n-upload-dragger>
<n-text style="font-size: 16px"> <n-text style="font-size: 16px">
Щелкните или перетащите файл в эту область для загрузки Щелкните или перетащите файл в эту область для загрузки