add change status buttons

This commit is contained in:
2026-07-26 00:22:30 +07:00
parent e7b7c1180b
commit 93b131dbca
11 changed files with 790 additions and 656 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+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-CGIEdu3F.js"></script> <script type="module" crossorigin src="/assets/index-Cse9kYPG.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-RcOLieKE.css"> <link rel="stylesheet" crossorigin href="/assets/index-DwS7oaRt.css">
</head> </head>
<body> <body>
<div id="app"></div> <div id="app"></div>
+43 -4
View File
@@ -240,6 +240,28 @@ service EveningDetectiveServer {
}; };
} }
rpc PublicScenario(PublicScenarioReq) returns (PublicScenarioRsp) {
option (google.api.http) = {
put : "/api/scenarios/{id}/public"
body: "*"
};
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
tags : "Сценарии";
summary: "Опубликовать сценарий";
};
}
rpc DraftScenario(DraftScenarioReq) returns (DraftScenarioRsp) {
option (google.api.http) = {
put : "/api/scenarios/{id}/draft"
body: "*"
};
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
tags : "Сценарии";
summary: "Снять с публикации сценарий";
};
}
rpc DeleteScenario(DeleteScenarioReq) returns (DeleteScenarioRsp) { rpc DeleteScenario(DeleteScenarioReq) returns (DeleteScenarioRsp) {
option (google.api.http) = { option (google.api.http) = {
delete: "/api/scenarios/{id}" delete: "/api/scenarios/{id}"
@@ -435,10 +457,11 @@ message Scenario {
optional string description = 3; optional string description = 3;
optional string image = 4; optional string image = 4;
Story story = 5; Story story = 5;
User author = 6; string status = 6;
google.protobuf.Timestamp updated_at = 7; User author = 7;
google.protobuf.Timestamp created_at = 8; google.protobuf.Timestamp updated_at = 8;
google.protobuf.Timestamp published_at = 9; google.protobuf.Timestamp created_at = 9;
google.protobuf.Timestamp published_at = 10;
} }
message Story { message Story {
@@ -482,6 +505,22 @@ message UpdateScenarioRsp {
string error = 1; string error = 1;
} }
message PublicScenarioReq {
int32 id = 1;
}
message PublicScenarioRsp {
string error = 1;
}
message DraftScenarioReq {
int32 id = 1;
}
message DraftScenarioRsp {
string error = 1;
}
message DeleteScenarioReq { message DeleteScenarioReq {
int32 id = 1; int32 id = 1;
} }
File diff suppressed because it is too large Load Diff
+4 -3
View File
@@ -17,11 +17,12 @@
--vt-c-text-dark-2: rgb(235 235 235 / 64%); --vt-c-text-dark-2: rgb(235 235 235 / 64%);
/* Главный цвет */ /* Главный цвет */
--main-color: rgba(34, 50, 60, 1); --main-color: rgb(34 50 60 / 100%);
/* --second-color: rgb(97, 74, 22); */ /* --second-color: rgb(97, 74, 22); */
--second-color: burlywood; --second-color: burlywood;
--main-back-color: rgba(240, 240, 240, 1); --main-back-color: rgb(240 240 240 / 100%);
--main-back-item-color: rgba(254, 254, 254, 1); --main-back-item-color: rgb(254 254 254 / 100%);
} }
/* semantic color variables for this project */ /* semantic color variables for this project */
-2
View File
@@ -96,9 +96,7 @@ const openMenu = ref(false)
left: 0; left: 0;
width: 100%; width: 100%;
height: 70px; height: 70px;
background-color: #222; background-color: #222;
padding: 20px; padding: 20px;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
+1 -1
View File
@@ -39,7 +39,7 @@
background-image: url("@/assets/images/paper.jpg"); background-image: url("@/assets/images/paper.jpg");
background-size: cover; background-size: cover;
display: flow-root; display: flow-root;
box-shadow: 0px 0 5px black; box-shadow: 0 0 5px black;
} }
.message-cloud-2, .message-cloud-2,
+7 -5
View File
@@ -1,9 +1,10 @@
<script setup lang="ts"> <script setup lang="ts">
import { NDynamicInput, NInput, NInputGroup, NSpace, NSwitch, NText, NUpload, NUploadDragger, NButton } from 'naive-ui' import { Key24Regular } from '@vicons/fluent'
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'
import { Key24Regular } from '@vicons/fluent' import { NButton,NDynamicInput, NInput, NInputGroup, NSpace, NSwitch, NText, NUpload, NUploadDragger } from 'naive-ui'
import type { PropType } from 'vue'
import type { Application, Door, Key, Place } from '@/api/generated/crabs/evening_detective_server' import type { Application, Door, Key, Place } from '@/api/generated/crabs/evening_detective_server'
const props = defineProps({ const props = defineProps({
@@ -230,6 +231,7 @@ function onCreateKey(): Key {
.hr { .hr {
margin: 10px 0; margin: 10px 0;
border: dashed 1px; border: dashed 1px;
/* border-color: black; */ /* border-color: black; */
border-color: #eee; border-color: #eee;
} }
@@ -304,7 +306,7 @@ function onCreateKey(): Key {
.need-keys-text { .need-keys-text {
color: gold; color: gold;
margin: 15px 0 0 0; margin: 15px 0 0;
padding: 0; padding: 0;
} }
@@ -335,7 +337,7 @@ function onCreateKey(): Key {
margin-right: 15px; margin-right: 15px;
background-image: url("@/assets/images/paper_white.jpg"); background-image: url("@/assets/images/paper_white.jpg");
background-size: cover; background-size: cover;
box-shadow: 0px 3px 15px rgb(98, 98, 98); box-shadow: 0 3px 15px rgb(98 98 98);
transform: rotate(-3deg); transform: rotate(-3deg);
} }
+51 -2
View File
@@ -2,7 +2,7 @@
import { Settings } from '@vicons/carbon' import { Settings } from '@vicons/carbon'
import { Icon } from '@vicons/utils' import { Icon } from '@vicons/utils'
import { NButton, type UploadFileInfo, useMessage } from 'naive-ui' import { NButton, type UploadFileInfo, useMessage } from 'naive-ui'
import { NCard, NFlex, NInput, NModal, NSpace, NText, NUpload, NUploadDragger } from 'naive-ui' import { NCard, NFlex, NInput, NModal, NSpace, NText, NUpload, NUploadDragger, NAlert } from 'naive-ui'
import { ref } from 'vue' import { ref } from 'vue'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
@@ -17,6 +17,7 @@ const route = useRoute()
const scenarioId = route.params.id const scenarioId = route.params.id
const showSettingsScenarioModal = ref(false) const showSettingsScenarioModal = ref(false)
const statusScenarioName = ref('')
const deletedScenarioName = ref('') const deletedScenarioName = ref('')
const message = useMessage() const message = useMessage()
@@ -56,6 +57,30 @@ async function deleteScenario(id: number) {
router.push('/scenarios') router.push('/scenarios')
} }
async function publicScenario(id: number) {
const res = await client.PublicScenario({ id: id })
if (res.error != '') {
message.error(res.error!)
return
}
await getScenario(Number(scenarioId))
statusScenarioName.value = ''
showSettingsScenarioModal.value = false
}
async function draftScenario(id: number) {
const res = await client.DraftScenario({ id: id })
if (res.error != '') {
message.error(res.error!)
return
}
await getScenario(Number(scenarioId))
statusScenarioName.value = ''
showSettingsScenarioModal.value = false
}
async function uploadFile(file: File | null, filename: string): Promise<string> { async function uploadFile(file: File | null, filename: string): Promise<string> {
if (!file) { if (!file) {
return '' return ''
@@ -152,7 +177,7 @@ async function cancelAddPlace() {
async function addNotFoundDoors(scenario: Scenario, place: Place) { async function addNotFoundDoors(scenario: Scenario, place: Place) {
for (const door of place.doors || []) { for (const door of place.doors || []) {
let place = scenario.story?.places?.find((place) => { const place = scenario.story?.places?.find((place) => {
return place.code == door.code return place.code == door.code
}) })
if (place == undefined) { if (place == undefined) {
@@ -227,6 +252,11 @@ async function deletePlace(place: Place) {
<template> <template>
<div class="center-block-custom-big"> <div class="center-block-custom-big">
<div class="places-container"> <div class="places-container">
<n-alert v-if="scenario.status == 'public'" title="Сценарий опубликован" type="warning"
style="margin-bottom: 20px;">
Не рекомендуется редактировать сценарий когда он опубликован.
</n-alert>
<div class="settings-block"> <div class="settings-block">
Точек: {{ scenario.story?.places?.length }} Точек: {{ scenario.story?.places?.length }}
<n-button quaternary @click="showSettingsScenarioModal = true" class="settings-button"> <n-button quaternary @click="showSettingsScenarioModal = true" class="settings-button">
@@ -282,6 +312,25 @@ async function deletePlace(place: Place) {
<n-button @click="updateScenario()" ghost> Сохранить изменения </n-button> <n-button @click="updateScenario()" ghost> Сохранить изменения </n-button>
<hr class="settings-hr" />
<p>Публикация</p>
<p>Статус:
<span v-if="scenario.status == 'public'">опубликовано</span>
<span v-if="scenario.status == 'draft'">в разработке</span>
</p>
<p>
Введите название сценария <n-text class="name-text" strong>{{ scenario.name }}</n-text>
</p>
<n-input v-model:value="statusScenarioName" type="text" placeholder='Дело №0 "Следствие ведут овечки"' />
<n-button v-if="scenario.status != 'public'" @click="publicScenario(scenario.id!)" ghost
:disabled="statusScenarioName != scenario.name">
Опубликовать сценарий
</n-button>
<n-button v-if="scenario.status != 'draft'" @click="draftScenario(scenario.id!)" ghost
:disabled="statusScenarioName != scenario.name">
Снять сценарий с публикации
</n-button>
<hr class="settings-hr" /> <hr class="settings-hr" />
<p> <p>
+4 -3
View File
@@ -1,9 +1,10 @@
<script setup lang="ts"> <script setup lang="ts">
import { NButton, NFlex,NSpace, NTag, useMessage } from 'naive-ui'
import { ref } from 'vue'
import { getAuthClient } from '@/api/auth_client' import { getAuthClient } from '@/api/auth_client'
import type { User } from '@/api/generated/crabs/evening_detective_server' import type { User } from '@/api/generated/crabs/evening_detective_server'
import HeaderMenu from '@/components/HeaderMenu.vue' import HeaderMenu from '@/components/HeaderMenu.vue'
import { useMessage, NTable, NButton, NTag, NSpace, NFlex } from 'naive-ui'
import { ref } from 'vue'
const client = getAuthClient() const client = getAuthClient()
const message = useMessage() const message = useMessage()
@@ -86,7 +87,7 @@ async function deleteRole(userId: number, role: string) {
.user-block { .user-block {
border: 1px solid #444; border: 1px solid #444;
border-radius: 10px; border-radius: 10px;
margin: 0 0 20px 0; margin: 0 0 20px;
padding: 20px; padding: 20px;
} }