style(webui): 在 Oxfmt 中配置导入排序功能,并对全 webui 目录进行格式化

This commit is contained in:
2026-05-28 21:03:11 +08:00
parent d62a9d9304
commit 1f1ac5f87a
37 changed files with 427 additions and 185 deletions
+2 -1
View File
@@ -2,5 +2,6 @@
"$schema": "./node_modules/oxfmt/configuration_schema.json", "$schema": "./node_modules/oxfmt/configuration_schema.json",
"semi": false, "semi": false,
"singleQuote": true, "singleQuote": true,
"bracketSpacing": true "bracketSpacing": true,
"sortImports": true
} }
+10
View File
@@ -21,11 +21,13 @@ declare module 'vue' {
ChatPromptQuicker: typeof import('./src/components/chatroom/ChatPromptQuicker.vue')['default'] ChatPromptQuicker: typeof import('./src/components/chatroom/ChatPromptQuicker.vue')['default']
ChatroomCard: typeof import('./src/components/chatroom/ChatroomCard.vue')['default'] ChatroomCard: typeof import('./src/components/chatroom/ChatroomCard.vue')['default']
ChatroomCreatorModal: typeof import('./src/components/chatroom/ChatroomCreatorModal.vue')['default'] ChatroomCreatorModal: typeof import('./src/components/chatroom/ChatroomCreatorModal.vue')['default']
ChatroomEditorModal: typeof import('./src/components/chatroom/ChatroomEditorModal.vue')['default']
ChatTable: typeof import('./src/components/chatroom/ChatTable.vue')['default'] ChatTable: typeof import('./src/components/chatroom/ChatTable.vue')['default']
ConfigCard: typeof import('./src/components/admin/ConfigCard.vue')['default'] ConfigCard: typeof import('./src/components/admin/ConfigCard.vue')['default']
FileModal: typeof import('./src/components/file/FileModal.vue')['default'] FileModal: typeof import('./src/components/file/FileModal.vue')['default']
FileThumbnail: typeof import('./src/components/file/FileThumbnail.vue')['default'] FileThumbnail: typeof import('./src/components/file/FileThumbnail.vue')['default']
InDev: typeof import('./src/components/InDev.vue')['default'] InDev: typeof import('./src/components/InDev.vue')['default']
InputFile: typeof import('./src/components/file/InputFile.vue')['default']
NAlert: typeof import('naive-ui')['NAlert'] NAlert: typeof import('naive-ui')['NAlert']
NAvatar: typeof import('naive-ui')['NAvatar'] NAvatar: typeof import('naive-ui')['NAvatar']
NButton: typeof import('naive-ui')['NButton'] NButton: typeof import('naive-ui')['NButton']
@@ -47,6 +49,7 @@ declare module 'vue' {
NGridItem: typeof import('naive-ui')['NGridItem'] NGridItem: typeof import('naive-ui')['NGridItem']
NH2: typeof import('naive-ui')['NH2'] NH2: typeof import('naive-ui')['NH2']
NH3: typeof import('naive-ui')['NH3'] NH3: typeof import('naive-ui')['NH3']
NH4: typeof import('naive-ui')['NH4']
NImage: typeof import('naive-ui')['NImage'] NImage: typeof import('naive-ui')['NImage']
NInput: typeof import('naive-ui')['NInput'] NInput: typeof import('naive-ui')['NInput']
NInputNumber: typeof import('naive-ui')['NInputNumber'] NInputNumber: typeof import('naive-ui')['NInputNumber']
@@ -56,6 +59,7 @@ declare module 'vue' {
NModal: typeof import('naive-ui')['NModal'] NModal: typeof import('naive-ui')['NModal']
NModalProvider: typeof import('naive-ui')['NModalProvider'] NModalProvider: typeof import('naive-ui')['NModalProvider']
NP: typeof import('naive-ui')['NP'] NP: typeof import('naive-ui')['NP']
NPopover: typeof import('naive-ui')['NPopover']
NRadio: typeof import('naive-ui')['NRadio'] NRadio: typeof import('naive-ui')['NRadio']
NRadioButton: typeof import('naive-ui')['NRadioButton'] NRadioButton: typeof import('naive-ui')['NRadioButton']
NRadioGroup: typeof import('naive-ui')['NRadioGroup'] NRadioGroup: typeof import('naive-ui')['NRadioGroup']
@@ -65,6 +69,7 @@ declare module 'vue' {
NTabs: typeof import('naive-ui')['NTabs'] NTabs: typeof import('naive-ui')['NTabs']
NTag: typeof import('naive-ui')['NTag'] NTag: typeof import('naive-ui')['NTag']
NText: typeof import('naive-ui')['NText'] NText: typeof import('naive-ui')['NText']
NTooltip: typeof import('naive-ui')['NTooltip']
NUpload: typeof import('naive-ui')['NUpload'] NUpload: typeof import('naive-ui')['NUpload']
NUploadDragger: typeof import('naive-ui')['NUploadDragger'] NUploadDragger: typeof import('naive-ui')['NUploadDragger']
PageHeader: typeof import('./src/components/PageHeader.vue')['default'] PageHeader: typeof import('./src/components/PageHeader.vue')['default']
@@ -92,11 +97,13 @@ declare global {
const ChatPromptQuicker: typeof import('./src/components/chatroom/ChatPromptQuicker.vue')['default'] const ChatPromptQuicker: typeof import('./src/components/chatroom/ChatPromptQuicker.vue')['default']
const ChatroomCard: typeof import('./src/components/chatroom/ChatroomCard.vue')['default'] const ChatroomCard: typeof import('./src/components/chatroom/ChatroomCard.vue')['default']
const ChatroomCreatorModal: typeof import('./src/components/chatroom/ChatroomCreatorModal.vue')['default'] const ChatroomCreatorModal: typeof import('./src/components/chatroom/ChatroomCreatorModal.vue')['default']
const ChatroomEditorModal: typeof import('./src/components/chatroom/ChatroomEditorModal.vue')['default']
const ChatTable: typeof import('./src/components/chatroom/ChatTable.vue')['default'] const ChatTable: typeof import('./src/components/chatroom/ChatTable.vue')['default']
const ConfigCard: typeof import('./src/components/admin/ConfigCard.vue')['default'] const ConfigCard: typeof import('./src/components/admin/ConfigCard.vue')['default']
const FileModal: typeof import('./src/components/file/FileModal.vue')['default'] const FileModal: typeof import('./src/components/file/FileModal.vue')['default']
const FileThumbnail: typeof import('./src/components/file/FileThumbnail.vue')['default'] const FileThumbnail: typeof import('./src/components/file/FileThumbnail.vue')['default']
const InDev: typeof import('./src/components/InDev.vue')['default'] const InDev: typeof import('./src/components/InDev.vue')['default']
const InputFile: typeof import('./src/components/file/InputFile.vue')['default']
const NAlert: typeof import('naive-ui')['NAlert'] const NAlert: typeof import('naive-ui')['NAlert']
const NAvatar: typeof import('naive-ui')['NAvatar'] const NAvatar: typeof import('naive-ui')['NAvatar']
const NButton: typeof import('naive-ui')['NButton'] const NButton: typeof import('naive-ui')['NButton']
@@ -118,6 +125,7 @@ declare global {
const NGridItem: typeof import('naive-ui')['NGridItem'] const NGridItem: typeof import('naive-ui')['NGridItem']
const NH2: typeof import('naive-ui')['NH2'] const NH2: typeof import('naive-ui')['NH2']
const NH3: typeof import('naive-ui')['NH3'] const NH3: typeof import('naive-ui')['NH3']
const NH4: typeof import('naive-ui')['NH4']
const NImage: typeof import('naive-ui')['NImage'] const NImage: typeof import('naive-ui')['NImage']
const NInput: typeof import('naive-ui')['NInput'] const NInput: typeof import('naive-ui')['NInput']
const NInputNumber: typeof import('naive-ui')['NInputNumber'] const NInputNumber: typeof import('naive-ui')['NInputNumber']
@@ -127,6 +135,7 @@ declare global {
const NModal: typeof import('naive-ui')['NModal'] const NModal: typeof import('naive-ui')['NModal']
const NModalProvider: typeof import('naive-ui')['NModalProvider'] const NModalProvider: typeof import('naive-ui')['NModalProvider']
const NP: typeof import('naive-ui')['NP'] const NP: typeof import('naive-ui')['NP']
const NPopover: typeof import('naive-ui')['NPopover']
const NRadio: typeof import('naive-ui')['NRadio'] const NRadio: typeof import('naive-ui')['NRadio']
const NRadioButton: typeof import('naive-ui')['NRadioButton'] const NRadioButton: typeof import('naive-ui')['NRadioButton']
const NRadioGroup: typeof import('naive-ui')['NRadioGroup'] const NRadioGroup: typeof import('naive-ui')['NRadioGroup']
@@ -136,6 +145,7 @@ declare global {
const NTabs: typeof import('naive-ui')['NTabs'] const NTabs: typeof import('naive-ui')['NTabs']
const NTag: typeof import('naive-ui')['NTag'] const NTag: typeof import('naive-ui')['NTag']
const NText: typeof import('naive-ui')['NText'] const NText: typeof import('naive-ui')['NText']
const NTooltip: typeof import('naive-ui')['NTooltip']
const NUpload: typeof import('naive-ui')['NUpload'] const NUpload: typeof import('naive-ui')['NUpload']
const NUploadDragger: typeof import('naive-ui')['NUploadDragger'] const NUploadDragger: typeof import('naive-ui')['NUploadDragger']
const PageHeader: typeof import('./src/components/PageHeader.vue')['default'] const PageHeader: typeof import('./src/components/PageHeader.vue')['default']
+5 -4
View File
@@ -1,9 +1,10 @@
<script setup lang="ts"> <script setup lang="ts">
import PageHeader from '@/components/PageHeader.vue'
import { dateZhCN, zhCN } from 'naive-ui'
import { useNowUser } from '@/stores/now-user.ts'
import { onMounted } from 'vue'
import { useHead } from '@unhead/vue' import { useHead } from '@unhead/vue'
import { dateZhCN, zhCN } from 'naive-ui'
import { onMounted } from 'vue'
import PageHeader from '@/components/PageHeader.vue'
import { useNowUser } from '@/stores/now-user.ts'
const NOWUSER = useNowUser() const NOWUSER = useNowUser()
+34 -14
View File
@@ -1,6 +1,9 @@
div.message { div.message {
position: relative; position: relative;
padding: 4px 12px; padding: 0 12px;
border-width: 0 0 0 4px;
border-style: solid;
border-radius: 4px;
font-size: 1rem; font-size: 1rem;
height: max-content; height: max-content;
@@ -18,35 +21,52 @@ div.message {
} }
div.user-message { div.user-message {
border: 2px solid #e1ff20; border-color: #e1ff20;
border-radius: 4px; background: #fffbdb;
background: #fffbb1;
} }
div.aii-message { div.aii-message {
border: 2px solid #20ff54; border-color: #20ff54;
border-radius: 4px; background: #e6fff1;
background: #b1ffd0;
} }
div.aii-message-streaming { div.aii-message-streaming {
border: 2px solid #20d2ff; border-color: #20d2ff;
border-radius: 4px; background: #dbfaff;
background: #b1f8ff;
div.thinking { div.thinking {
border: 1px solid #e9ff20; border: solid #5f20ff;
border-width: 0 0 0 2px;
border-radius: 4px; border-radius: 4px;
padding: 4px 8px; padding: 8px 12px;
margin: 6px 3px; margin: 6px 3px;
background: rgb(34 197 94 / 0.2); background: rgb(205 127 255 / 0.2);
min-height: 60px;
} }
} }
// 折叠消息 // 折叠消息
div.collapse { div.collapse {
overflow: hidden; overflow: hidden;
min-height: 80px; min-height: 160px;
&::after {
content: '● ● ●';
text-align: center;
display: block;
position: absolute;
font-size: 18px;
width: 80px;
height: 32px;
bottom: 10px;
left: 50%;
transform: translateX(-50%);
background: rgb(255 255 255 / 0.6);
border: 1px solid rgb(255 255 255);
border-radius: 4px;
}
} }
div.xaml-block { div.xaml-block {
+1
View File
@@ -1,5 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue' import { ref } from 'vue'
import { createErrorBlock, createXamlBlock, type Xaml } from '@/components/xaml-block.tsx' import { createErrorBlock, createXamlBlock, type Xaml } from '@/components/xaml-block.tsx'
const showModal = defineModel('showModal', { required: true }) const showModal = defineModel('showModal', { required: true })
@@ -1,10 +1,11 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue'
import { api } from '@/tools/web.ts'
import type { ReturnDto } from '@/types/response.ts'
import { useMessage } from 'naive-ui' import { useMessage } from 'naive-ui'
import { ref } from 'vue'
import VerifyCodeModal from '@/components/admin/VerifyCodeModal.vue' import VerifyCodeModal from '@/components/admin/VerifyCodeModal.vue'
import { useNowUser } from '@/stores/now-user.ts' import { useNowUser } from '@/stores/now-user.ts'
import { api } from '@/tools/web.ts'
import type { ReturnDto } from '@/types/response.ts'
const MESSAGE = useMessage() const MESSAGE = useMessage()
const NOWUSER = useNowUser() const NOWUSER = useNowUser()
+26 -8
View File
@@ -1,10 +1,11 @@
<script setup lang="ts"> <script setup lang="ts">
import { AxiosError } from 'axios'
import { useMessage } from 'naive-ui'
import { ref } from 'vue' import { ref } from 'vue'
import { useNowUser } from '@/stores/now-user.js'
import { api } from '@/tools/web.js' import { api } from '@/tools/web.js'
import type { ReturnDto } from '@/types/response.js' import type { ReturnDto } from '@/types/response.js'
import { useMessage } from 'naive-ui'
import { AxiosError } from 'axios'
import { useNowUser } from '@/stores/now-user.js'
const MESSAGE = useMessage() const MESSAGE = useMessage()
const NOWUSER = useNowUser() const NOWUSER = useNowUser()
@@ -20,7 +21,7 @@ const loginForm = ref({
function login() { function login() {
api api
.post(`/admin/login/${loginMethod.value}`, { .post(`/admin/login/${loginMethod.value}/`, {
username: loginForm.value.username, username: loginForm.value.username,
password: loginForm.value.password, password: loginForm.value.password,
}) })
@@ -50,11 +51,18 @@ function login() {
MESSAGE.error(`登录失败:${err_msg}`) MESSAGE.error(`登录失败:${err_msg}`)
}) })
} }
function logout() {
NOWUSER.is_login = false
localStorage.removeItem('user-id')
localStorage.removeItem('access-token')
MESSAGE.success('已注销登录状态……')
}
</script> </script>
<template> <template>
<div> <div>
<div class="user-action nyahome-card" v-if="NOWUSER.isLogin" style="position: relative"> <div class="user-action nyahome-card" v-if="NOWUSER.is_login" style="position: relative">
<img :src="NOWUSER.background_url" alt="User Background" class="user-action-background" /> <img :src="NOWUSER.background_url" alt="User Background" class="user-action-background" />
<div class="card-content" style="margin-top: auto; margin-bottom: 20px"> <div class="card-content" style="margin-top: auto; margin-bottom: 20px">
<n-avatar :size="96" circle :src="NOWUSER.avatar_url" /> <n-avatar :size="96" circle :src="NOWUSER.avatar_url" />
@@ -69,9 +77,19 @@ function login() {
<router-link class="card-button" :to="`/user/${NOWUSER.id}`"> <router-link class="card-button" :to="`/user/${NOWUSER.id}`">
<n-button type="info" style="width: 100%" secondary>主页</n-button> <n-button type="info" style="width: 100%" secondary>主页</n-button>
</router-link> </router-link>
<router-link class="card-button" to="#"> <n-popover trigger="click">
<n-button type="error" style="width: 100%" secondary>注销</n-button> <template #trigger>
</router-link> <n-button class="card-button" type="error" style="width: 100%; padding: 0" secondary>
注销
</n-button>
</template>
<n-flex vertical>
<n-alert type="info">
确认注销登录吗注销后你可以重新登录或者切换至其他账号
</n-alert>
<n-button type="warning" secondary @click="logout()">确认注销</n-button>
</n-flex>
</n-popover>
</n-flex> </n-flex>
</div> </div>
</div> </div>
@@ -1,10 +1,11 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue'
import { api } from '@/tools/web.ts'
import { useNowUser } from '@/stores/now-user.ts'
import { useMessage } from 'naive-ui' import { useMessage } from 'naive-ui'
import { ref } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { useNowUser } from '@/stores/now-user.ts'
import { api } from '@/tools/web.ts'
const ROUTER = useRouter() const ROUTER = useRouter()
const MESSAGE = useMessage() const MESSAGE = useMessage()
const NOWUSER = useNowUser() const NOWUSER = useNowUser()
@@ -21,7 +22,7 @@ function change() {
.post('/admin/me/password/', JSON.stringify(changeForm.value)) .post('/admin/me/password/', JSON.stringify(changeForm.value))
.then(() => { .then(() => {
MESSAGE.success('密码修改成功,请重新登录。') MESSAGE.success('密码修改成功,请重新登录。')
NOWUSER.isLogin = false NOWUSER.is_login = false
localStorage.removeItem('user-id') localStorage.removeItem('user-id')
localStorage.removeItem('access-token') localStorage.removeItem('access-token')
ROUTER.push('/') ROUTER.push('/')
@@ -46,8 +47,8 @@ function change() {
<n-flex> <n-flex>
<n-button type="error" @click="change()">确认修改</n-button> <n-button type="error" @click="change()">确认修改</n-button>
<n-tag type="warning" size="large" <n-tag type="warning" size="large"
>修改密码会注销所有已登录状态您将需要重新登录</n-tag >修改密码会注销所有已登录状态您将需要重新登录
> </n-tag>
</n-flex> </n-flex>
</n-form-item> </n-form-item>
</n-form> </n-form>
@@ -1,10 +1,11 @@
<script setup lang="ts"> <script setup lang="ts">
import { type SelectOption, useMessage } from 'naive-ui'
import { computed, onMounted, ref, watch } from 'vue' import { computed, onMounted, ref, watch } from 'vue'
import AiiProviderAddModal from '@/components/chatroom/AiiProviderAddModal.vue' import AiiProviderAddModal from '@/components/chatroom/AiiProviderAddModal.vue'
import { api } from '@/tools/web.js' import { api } from '@/tools/web.js'
import type { ReturnDto } from '@/types/response.js'
import { type SelectOption, useMessage } from 'naive-ui'
import type { AiiProviderPublicWithoutKey } from '@/types/aii.js' import type { AiiProviderPublicWithoutKey } from '@/types/aii.js'
import type { ReturnDto } from '@/types/response.js'
const MESSAGE = useMessage() const MESSAGE = useMessage()
@@ -1,8 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import { useMessage } from 'naive-ui'
import { ref } from 'vue' import { ref } from 'vue'
import { api } from '@/tools/web.js' import { api } from '@/tools/web.js'
import type { ReturnDto } from '@/types/response.js' import type { ReturnDto } from '@/types/response.js'
import { useMessage } from 'naive-ui'
const MESSAGE = useMessage() const MESSAGE = useMessage()
@@ -1,23 +1,29 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import { api } from '@/tools/web.js'
import type { ReturnDto } from '@/types/response.js'
import { type SelectOption, useMessage } from 'naive-ui' import { type SelectOption, useMessage } from 'naive-ui'
import AiiModelAddModal from '@/components/chatroom/AiiModelAddModal.vue' import { computed, onMounted, ref } from 'vue'
import type { AiiModelPublic } from '@/types/aii.js'
import ChatPromptQuicker from '@/components/chatroom/ChatPromptQuicker.vue'
import ScriptDrawer from '@/components/chatroom/ScriptDrawer.vue'
import AiiModelAddModal from '@/components/chatroom/AiiModelAddModal.vue'
import ChatPromptQuicker from '@/components/chatroom/ChatPromptQuicker.vue'
import ChatroomEditorModal from '@/components/chatroom/ChatroomEditorModal.vue'
import ScriptDrawer from '@/components/chatroom/ScriptDrawer.vue'
import { useNowUser } from '@/stores/now-user.ts'
import { api } from '@/tools/web.js'
import type { AiiModelPublic } from '@/types/aii.js'
import type { Chatroom, ChatroomPublic } from '@/types/chatroom.ts'
import type { ReturnDto } from '@/types/response.js'
const NOWUSER = useNowUser()
const MESSAGE = useMessage() const MESSAGE = useMessage()
const selectedModel = defineModel<number | null>('selectModel', { required: true }) const selectedModel = defineModel<number | null>('selectModel', { required: true })
const quickerPrompt = defineModel<string>('quickerPrompt', { required: true }) const quickerPrompt = defineModel<string>('quickerPrompt', { required: true })
const { script } = defineProps<{ const { chatroom, loadPage } = defineProps<{
script: string chatroom: Chatroom
loadPage: () => void
}>() }>()
const showModal = ref(false) const showAddModelModal = ref(false)
const models = ref<AiiModelPublic[]>([]) const models = ref<AiiModelPublic[]>([])
const showScriptDrawer = ref(false) const showScriptDrawer = ref(false)
@@ -32,7 +38,7 @@ const modelOptions = computed(() => {
return options return options
}) })
function load() { function loadModels() {
api api
.get('/aii/model') .get('/aii/model')
.then((res) => res.data as ReturnDto) .then((res) => res.data as ReturnDto)
@@ -49,8 +55,42 @@ function load() {
} }
onMounted(() => { onMounted(() => {
load() loadModels()
if (chatroom.default_model_id) {
selectedModel.value = chatroom.default_model_id
} else {
MESSAGE.info(
'此聊天室还未设置默认模型。你需要选择一个模型然后开始聊天,或者现在就保存一个默认模型嘛?',
)
}
}) })
const showChatroomInfoModal = ref(false)
const chatroomInfo = ref<ChatroomPublic>({
id: chatroom.id,
name: chatroom.name,
description: chatroom.description,
feature_image: chatroom.feature_image,
default_model_id: chatroom.default_model_id,
script_template_id: chatroom.script_template_id,
script_template_version: chatroom.script_template_version,
})
function saveDefaultModel() {
if (selectedModel.value) {
chatroomInfo.value.default_model_id = selectedModel.value
api
.post(`/chatroom/${chatroom.id}/`, JSON.stringify(chatroomInfo.value))
.then(() => {
MESSAGE.success('默认模型设置成功~')
})
.catch((err) => {
MESSAGE.error(`设置默认模型失败:${err}`)
})
} else {
MESSAGE.warning('请先选择一个模型哦~')
}
}
</script> </script>
<template> <template>
@@ -58,18 +98,37 @@ onMounted(() => {
<n-card title="模型"> <n-card title="模型">
<template #header-extra> <template #header-extra>
<n-flex> <n-flex>
<n-button secondary type="info" size="small" round @click="load()">刷新</n-button> <n-button secondary type="info" size="small" round @click="loadModels()">刷新</n-button>
<n-button secondary type="warning" size="small" round @click="showModal = true"> <n-button
v-if="NOWUSER.is_admin"
secondary
type="warning"
size="small"
round
@click="showAddModelModal = true"
>
添加 添加
</n-button> </n-button>
<n-button-group> <n-button-group>
<n-button secondary type="primary" size="small" round>保存</n-button> <n-button secondary type="primary" size="small" round @click="saveDefaultModel()">
保存
</n-button>
<n-popover>
<template #trigger>
<n-button secondary type="tertiary" size="small" round>?</n-button> <n-button secondary type="tertiary" size="small" round>?</n-button>
</template>
<n-h4>有哪些模型</n-h4>
<n-p>NyaHome 管理员可以添加模型然后所有用户都可以使用这些模型</n-p>
<n-p>NyaHome 不提供模型调用</n-p>
<n-h4>默认模型切换模型</n-h4>
<n-p>可以针对聊天室保存一个默认模型</n-p>
<n-p>你也可以在这里切换其他的模型但在保存之前默认模型不会修改</n-p>
</n-popover>
</n-button-group> </n-button-group>
</n-flex> </n-flex>
</template> </template>
<n-select v-model:value="selectedModel" :options="modelOptions" /> <n-select v-model:value="selectedModel" :options="modelOptions" />
<aii-model-add-modal v-model:show-modal="showModal" /> <aii-model-add-modal v-model:show-modal="showAddModelModal" />
</n-card> </n-card>
<chat-prompt-quicker v-model:prompt-prefix="quickerPrompt" /> <chat-prompt-quicker v-model:prompt-prefix="quickerPrompt" />
@@ -82,15 +141,22 @@ onMounted(() => {
故事设定 · 世界书 故事设定 · 世界书
</n-button> </n-button>
</n-flex> </n-flex>
<script-drawer :script v-model:show-drawer="showScriptDrawer" /> <script-drawer :script="chatroom.script" v-model:show-drawer="showScriptDrawer" />
</n-card> </n-card>
<n-card title="设置"> <n-card title="设置">
<template #header-extra>也许你不需要修改这里</template> <template #header-extra>也许你不需要修改这里</template>
<n-flex vertical> <n-flex vertical>
<n-button secondary type="primary">聊天室信息</n-button> <n-button secondary type="primary" @click="showChatroomInfoModal = true">
聊天室信息
</n-button>
<n-button secondary type="info">系统设置</n-button> <n-button secondary type="info">系统设置</n-button>
</n-flex> </n-flex>
<chatroom-editor-modal
:chatroom="chatroomInfo"
v-model:show-modal="showChatroomInfoModal"
:reload="loadPage"
/>
</n-card> </n-card>
</n-flex> </n-flex>
</template> </template>
@@ -1,7 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
import { md } from '@/tools/md.js'
import { onMounted, ref, useTemplateRef } from 'vue' import { onMounted, ref, useTemplateRef } from 'vue'
import { md } from '@/tools/md.js'
const { role, msg } = defineProps<{ const { role, msg } = defineProps<{
role: 'aii' | 'user' role: 'aii' | 'user'
msg: string msg: string
@@ -1,5 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
import { onMounted, ref } from 'vue' import { useMessage } from 'naive-ui'
import { onMounted, ref, watch } from 'vue'
const MESSAGE = useMessage()
const promptPrefix = defineModel<string>('promptPrefix', { required: true }) const promptPrefix = defineModel<string>('promptPrefix', { required: true })
@@ -8,12 +11,31 @@ const quickerForm = ref({
style: '第三人称全知视角,禁止打破第四面墙。', style: '第三人称全知视角,禁止打破第四面墙。',
}) })
function save() { function saveToBrowser() {
promptPrefix.value = `<要求><输出字数>${quickerForm.value.length}</输出字数><风格约束>${quickerForm.value.style}</风格约束></要求>` localStorage.setItem('prompt-quicker', JSON.stringify(quickerForm.value))
MESSAGE.success('已保存快速提示词至浏览器。')
} }
function loadFromBrowser() {
const temp = localStorage.getItem('prompt-quicker')
if (temp) {
quickerForm.value = JSON.parse(temp)
MESSAGE.success('从浏览器中读取到保存的快速提示词。')
} else {
MESSAGE.info('未找到保存的快速提示词。')
}
}
// 将本组件中进行的对快速提示词的修改自动同步到父级
watch(
() => quickerForm.value,
(newValue) => {
promptPrefix.value = `<要求><输出字数>${newValue.length}</输出字数><风格约束>${newValue.style}</风格约束></要求>`
},
)
onMounted(() => { onMounted(() => {
save() loadFromBrowser()
}) })
</script> </script>
@@ -21,8 +43,17 @@ onMounted(() => {
<n-card title="快速调整"> <n-card title="快速调整">
<template #header-extra> <template #header-extra>
<n-button-group> <n-button-group>
<n-button secondary type="primary" size="small" round @click="save()">保存</n-button> <n-button secondary type="primary" size="small" round @click="saveToBrowser()">
保存
</n-button>
<n-popover>
<template #trigger>
<n-button secondary type="tertiary" size="small" round>?</n-button> <n-button secondary type="tertiary" size="small" round>?</n-button>
</template>
<n-h4>这是什么</n-h4>
<n-p>快速预设一些可能需要随时修改的提示词它们会被结构化地拼接在用户消息中</n-p>
<n-p>您的修改无需保存即可随请求发送保存可以将提示词存储在浏览器中</n-p>
</n-popover>
</n-button-group> </n-button-group>
</template> </template>
<n-form :model="quickerForm"> <n-form :model="quickerForm">
@@ -1,42 +1,25 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref, watch } from 'vue'
import type { ChatroomPublic } from '@/types/chatroom.js'
import { api } from '@/tools/web.js'
import type { ReturnDto } from '@/types/response.js'
import { useMessage } from 'naive-ui' import { useMessage } from 'naive-ui'
import UploadFileModal from '@/components/file/UploadFileModal.vue' import { ref } from 'vue'
import InputFile from '@/components/file/InputFile.vue'
import SelectFileModal from '@/components/file/SelectFileModal.vue' import SelectFileModal from '@/components/file/SelectFileModal.vue'
import type { UploadFileDto } from '@/types/user.js' import UploadFileModal from '@/components/file/UploadFileModal.vue'
import { api } from '@/tools/web.js'
import type { ChatroomPublic } from '@/types/chatroom.js'
import type { ReturnDto } from '@/types/response.js'
const MESSAGE = useMessage() const MESSAGE = useMessage()
const showModal = defineModel<boolean>('showModal', { required: true }) const showModal = defineModel<boolean>('showModal', { required: true })
const showSelectModal = ref(false)
const showUploadModal = ref(false)
const files = ref<UploadFileDto[]>([])
const selectFiles = ref<UploadFileDto[]>([])
const image_url = computed(() => selectFiles.value.at(0)?.download_url)
const createChatroomForm = ref<ChatroomPublic>({ const createChatroomForm = ref<ChatroomPublic>({
id: 0, id: 0,
name: '', name: '',
description: '', description: '',
feature_image: '', feature_image: '',
script_template_id: 0,
script_template_version: '',
}) })
watch(image_url, () => {
if (image_url.value) {
createChatroomForm.value.feature_image = image_url.value
}
})
async function loadFiles() {
return await api.get('/file/').then((res) => (files.value = res.data as UploadFileDto[]))
}
function onSubmit() { function onSubmit() {
api api
.post('/chatroom/', JSON.stringify(createChatroomForm.value)) .post('/chatroom/', JSON.stringify(createChatroomForm.value))
@@ -76,14 +59,7 @@ function onSubmit() {
<n-input type="textarea" v-model:value="createChatroomForm.description" /> <n-input type="textarea" v-model:value="createChatroomForm.description" />
</n-form-item> </n-form-item>
<n-form-item path="feature_image" label="特色图像"> <n-form-item path="feature_image" label="特色图像">
<n-flex style="width: 100%" :wrap="false"> <input-file v-model:value="createChatroomForm.feature_image" />
<n-input
v-model:value="createChatroomForm.feature_image"
placeholder="留空以使用默认图像"
/>
<n-button secondary type="info" @click="showSelectModal = true">选择</n-button>
<n-button secondary type="warning" @click="showUploadModal = true">上传</n-button>
</n-flex>
</n-form-item> </n-form-item>
<n-form-item label="确认?"> <n-form-item label="确认?">
<n-button secondary type="primary" @click="onSubmit()">确认</n-button> <n-button secondary type="primary" @click="onSubmit()">确认</n-button>
@@ -0,0 +1,56 @@
<script setup lang="ts">
import { useMessage } from 'naive-ui'
import InputFile from '@/components/file/InputFile.vue'
import { api } from '@/tools/web.ts'
import type { ChatroomPublic } from '@/types/chatroom.ts'
const MESSAGE = useMessage()
const showModal = defineModel('showModal', { required: true })
const { chatroom, reload } = defineProps<{
chatroom: ChatroomPublic
reload: () => void
}>()
function submit() {
api
.post(`/chatroom/${chatroom.id}/`, JSON.stringify(chatroom))
.then(() => {
MESSAGE.success('成功修改聊天室基本信息~')
showModal.value = false
reload() // 由调用方重新获取聊天室数据
})
.catch((err) => {
MESSAGE.error(`修改聊天室基本信息失败:${err}`)
})
}
</script>
<template>
<n-modal
v-model:show="showModal"
title="修改聊天室信息"
style="width: 800px; max-height: 600px"
content-scrollable
preset="card"
>
<n-form label-placement="left" label-align="right" label-width="auto" :model="chatroom">
<n-form-item label="聊天室名称" path="name">
<n-input v-model:value="chatroom.name" />
</n-form-item>
<n-form-item label="聊天室描述" path="description">
<n-input v-model:value="chatroom.description" type="textarea" :rows="3" />
</n-form-item>
<n-form-item label="特色图片" path="feature_image">
<input-file v-model:value="chatroom.feature_image" />
</n-form-item>
<n-form-item label="保存">
<n-button secondary type="primary" @click="submit()">保存</n-button>
</n-form-item>
</n-form>
</n-modal>
</template>
<style scoped></style>
@@ -1,11 +1,12 @@
<script setup lang="ts"> <script setup lang="ts">
import { api } from '@/tools/web.js' import { useMessage } from 'naive-ui'
import { ref, watch } from 'vue' import { ref, watch } from 'vue'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import XamlModal from '@/components/XamlModal.vue'
import { api } from '@/tools/web.js'
import type { ChatScript } from '@/types/chatroom.js' import type { ChatScript } from '@/types/chatroom.js'
import type { ReturnDto } from '@/types/response.js' import type { ReturnDto } from '@/types/response.js'
import { useMessage } from 'naive-ui'
import XamlModal from '@/components/XamlModal.vue'
const ROUTE = useRoute() const ROUTE = useRoute()
const MESSAGE = useMessage() const MESSAGE = useMessage()
+3 -2
View File
@@ -1,8 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import type { UploadFileDto } from '@/types/user.js'
import { useNowUser } from '@/stores/now-user.js'
import { computed } from 'vue' import { computed } from 'vue'
import { useNowUser } from '@/stores/now-user.js'
import type { UploadFileDto } from '@/types/user.js'
const NOWUSER = useNowUser() const NOWUSER = useNowUser()
const { file } = defineProps<{ const { file } = defineProps<{
+2 -1
View File
@@ -1,7 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
import type { UploadFileDto } from '@/types/user.js'
import { computed, onMounted, ref, useTemplateRef } from 'vue' import { computed, onMounted, ref, useTemplateRef } from 'vue'
import FileModal from '@/components/file/FileModal.vue' import FileModal from '@/components/file/FileModal.vue'
import type { UploadFileDto } from '@/types/user.js'
const { file, size, enableSelect, onSelect, onRemove } = defineProps<{ const { file, size, enableSelect, onSelect, onRemove } = defineProps<{
file: UploadFileDto file: UploadFileDto
+44
View File
@@ -0,0 +1,44 @@
<script setup lang="ts">
import { ref, watch } from 'vue'
import SelectFileModal from '@/components/file/SelectFileModal.vue'
import UploadFileModal from '@/components/file/UploadFileModal.vue'
import { api } from '@/tools/web.ts'
import type { UploadFileDto } from '@/types/user.ts'
const value = defineModel('value', { required: true })
const showSelectModal = ref(false)
const showUploadModal = ref(false)
const selectFiles = ref<UploadFileDto[]>([])
async function loadFiles() {
return await api.get('/file/').then((res) => res.data as UploadFileDto[])
}
watch(
() => selectFiles.value,
() => {
value.value = selectFiles.value[0]?.download_url
},
)
</script>
<template>
<n-flex style="width: 100%" :wrap="false">
<n-input v-model:value="value" placeholder="留空以使用默认图像" />
<n-button secondary type="info" @click="showSelectModal = true">选择</n-button>
<n-button secondary type="warning" @click="showUploadModal = true">上传</n-button>
</n-flex>
<select-file-modal
:max="1"
:extensions="['png', 'jpeg', 'jpg']"
:load-files="loadFiles"
v-model:show-modal="showSelectModal"
v-model:select-files="selectFiles"
/>
<upload-file-modal v-model:show-modal="showUploadModal" />
</template>
<style scoped></style>
@@ -1,8 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import { selectFilesCom } from '@/components/file/upload-files.js'
import { computed, ref, watch } from 'vue'
import type { UploadFileDto } from '@/types/user.js'
import { useMessage } from 'naive-ui' import { useMessage } from 'naive-ui'
import { computed, ref, watch } from 'vue'
import { selectFilesCom } from '@/components/file/upload-files.js'
import type { UploadFileDto } from '@/types/user.js'
const MESSAGE = useMessage() const MESSAGE = useMessage()
@@ -1,8 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import { type UploadCustomRequestOptions, type UploadFileInfo } from 'naive-ui' import { type UploadCustomRequestOptions, type UploadFileInfo } from 'naive-ui'
import { shallowRef, useTemplateRef } from 'vue'
import { api } from '@/tools/web.js' import { api } from '@/tools/web.js'
import type { UploadFileDto } from '@/types/user.js' import type { UploadFileDto } from '@/types/user.js'
import { shallowRef, useTemplateRef } from 'vue'
defineProps<{ defineProps<{
afterLeave?: () => void afterLeave?: () => void
+3 -2
View File
@@ -1,7 +1,8 @@
import type { UploadFileDto } from '@/types/user.ts'
import FileThumbnail from '@/components/file/FileThumbnail.vue'
import { NEmpty, NFlex } from 'naive-ui' import { NEmpty, NFlex } from 'naive-ui'
import FileThumbnail from '@/components/file/FileThumbnail.vue'
import type { UploadFileDto } from '@/types/user.ts'
export function uploadFilesCom(files: UploadFileDto[]) { export function uploadFilesCom(files: UploadFileDto[]) {
if (files.length === 0) { if (files.length === 0) {
return <NEmpty description="你还没有上传任何文件。" size="large" /> return <NEmpty description="你还没有上传任何文件。" size="large" />
+2 -3
View File
@@ -1,11 +1,10 @@
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import { createHead } from '@unhead/vue/client' import { createHead } from '@unhead/vue/client'
import { createPinia } from 'pinia'
import { createApp } from 'vue'
import '@/assets/main.scss' import '@/assets/main.scss'
import '@/assets/beautiful.scss' import '@/assets/beautiful.scss'
import '@/assets/chat.scss' import '@/assets/chat.scss'
import App from './App.vue' import App from './App.vue'
import router from './router' import router from './router'
+3 -2
View File
@@ -1,10 +1,11 @@
<script setup lang="ts"> <script setup lang="ts">
import UserAction from '@/components/admin/UserAction.vue' import { useHead } from '@unhead/vue'
import type { MenuOption } from 'naive-ui' import type { MenuOption } from 'naive-ui'
import { computed, onMounted, ref, useTemplateRef } from 'vue' import { computed, onMounted, ref, useTemplateRef } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import UserAction from '@/components/admin/UserAction.vue'
import { useNowUser } from '@/stores/now-user.js' import { useNowUser } from '@/stores/now-user.js'
import { useHead } from '@unhead/vue'
useHead({ useHead({
titleTemplate: '%s | 管理面板 | NayHome', titleTemplate: '%s | 管理面板 | NayHome',
+22 -28
View File
@@ -1,17 +1,18 @@
<script setup lang="ts"> <script setup lang="ts">
import { useRoute } from 'vue-router' import { fetchEventSource } from '@microsoft/fetch-event-source'
import { onMounted, reactive, ref, useTemplateRef, watch } from 'vue' import { useHead } from '@unhead/vue'
import { api } from '@/tools/web.ts'
import type { ReturnDto } from '@/types/response.ts'
import type { Chatroom } from '@/types/chatroom.ts'
import { useMessage } from 'naive-ui' import { useMessage } from 'naive-ui'
import { onMounted, reactive, ref, useTemplateRef, watch } from 'vue'
import { useRoute } from 'vue-router'
import ChatControlPanel from '@/components/chatroom/ChatControlPanel.vue'
import ChatroomCard from '@/components/chatroom/ChatroomCard.vue' import ChatroomCard from '@/components/chatroom/ChatroomCard.vue'
import ChatTable from '@/components/chatroom/ChatTable.vue' import ChatTable from '@/components/chatroom/ChatTable.vue'
import ChatControlPanel from '@/components/chatroom/ChatControlPanel.vue' import { api } from '@/tools/web.ts'
import { fetchEventSource } from '@microsoft/fetch-event-source'
import type { AiiTokenInfo } from '@/types/aii.ts' import type { AiiTokenInfo } from '@/types/aii.ts'
import type { Chatroom } from '@/types/chatroom.ts'
import type { ReturnDto } from '@/types/response.ts'
import { SEE_YOU_TOMORROW } from '@/types/syt.ts' import { SEE_YOU_TOMORROW } from '@/types/syt.ts'
import { useHead } from '@unhead/vue'
const pageHead = reactive({ const pageHead = reactive({
title: '正在加载聊天室...', title: '正在加载聊天室...',
@@ -23,11 +24,7 @@ useHead(pageHead)
const ROUTE = useRoute() const ROUTE = useRoute()
const MESSAGE = useMessage() const MESSAGE = useMessage()
const crName = ref('') const chatroom = ref<Chatroom | null>(null)
const crDescription = ref('')
const crFeatureImage = ref('')
const crContent = ref('')
const crScript = ref('')
const selectedModel = ref<number | null>(null) const selectedModel = ref<number | null>(null)
const quickerPrompt = ref('') const quickerPrompt = ref('')
@@ -54,11 +51,7 @@ function load() {
}) })
.then((cr) => { .then((cr) => {
pageHead.title = cr.name pageHead.title = cr.name
crName.value = cr.name chatroom.value = cr
crDescription.value = cr.description
crFeatureImage.value = cr.feature_image
crContent.value = cr.content
crScript.value = cr.script
}) })
.catch((e) => { .catch((e) => {
MESSAGE.error(`访问聊天室失败:${e}`) MESSAGE.error(`访问聊天室失败:${e}`)
@@ -155,7 +148,7 @@ function accept() {
} }
}) })
.then((result) => { .then((result) => {
crContent.value = result.content chatroom.value!.content = result.content
}) })
.catch((err) => { .catch((err) => {
MESSAGE.error(`保存失败:${err}`) MESSAGE.error(`保存失败:${err}`)
@@ -190,8 +183,8 @@ function messageEdit(oldMessage: string, newMessage: string, change: 'aii' | 'us
} }
}) })
.then((result) => { .then((result) => {
crContent.value = result.content chatroom.value!.content = result.content
MESSAGE.success('聊天记录已删除,页面已更新~') MESSAGE.success('聊天记录已更新,页面已更新~')
}) })
.catch((err) => { .catch((err) => {
MESSAGE.error(`修改聊天消息失败:${err}`) MESSAGE.error(`修改聊天消息失败:${err}`)
@@ -211,7 +204,7 @@ function messageDelete(message: string, change: 'aii' | 'user') {
} }
}) })
.then((result) => { .then((result) => {
crContent.value = result.content chatroom.value!.content = result.content
MESSAGE.success('聊天记录已删除,页面已更新~') MESSAGE.success('聊天记录已删除,页面已更新~')
}) })
.catch((err) => { .catch((err) => {
@@ -243,16 +236,16 @@ function enableSidebar() {
</script> </script>
<template> <template>
<div class="page-container"> <div class="page-container" v-if="chatroom !== null">
<div class="main-column"> <div class="main-column">
<chatroom-card <chatroom-card
:id="Number(ROUTE.params.id)" :id="Number(ROUTE.params.id)"
:name="crName" :name="chatroom.name"
:description="crDescription" :description="chatroom.description"
:feature_image="crFeatureImage" :feature_image="chatroom.feature_image"
/> />
<chat-table <chat-table
:content="crContent" :content="chatroom.content"
:aii-thinking :aii-thinking
:aii-message :aii-message
:aii-token-info :aii-token-info
@@ -269,7 +262,8 @@ function enableSidebar() {
</div> </div>
<div class="sidebar-column" ref="sidebar"> <div class="sidebar-column" ref="sidebar">
<chat-control-panel <chat-control-panel
:script="crScript" :chatroom="chatroom"
:load-page="load"
v-model:quicker-prompt="quickerPrompt" v-model:quicker-prompt="quickerPrompt"
v-model:select-model="selectedModel" v-model:select-model="selectedModel"
/> />
+6 -5
View File
@@ -1,12 +1,13 @@
<script setup lang="ts"> <script setup lang="ts">
import ChatroomCard from '@/components/chatroom/ChatroomCard.vue' import { useHead } from '@unhead/vue'
import { ref, watch } from 'vue' import { ref, watch } from 'vue'
import ChatroomCard from '@/components/chatroom/ChatroomCard.vue'
import ChatroomCreatorModal from '@/components/chatroom/ChatroomCreatorModal.vue'
import { useNowUser } from '@/stores/now-user.ts'
import { api } from '@/tools/web.ts' import { api } from '@/tools/web.ts'
import type { ChatroomPublic } from '@/types/chatroom.ts' import type { ChatroomPublic } from '@/types/chatroom.ts'
import type { ReturnDto } from '@/types/response.ts' import type { ReturnDto } from '@/types/response.ts'
import ChatroomCreatorModal from '@/components/chatroom/ChatroomCreatorModal.vue'
import { useNowUser } from '@/stores/now-user.ts'
import { useHead } from '@unhead/vue'
useHead({ useHead({
title: '聊天室列表', title: '聊天室列表',
@@ -29,7 +30,7 @@ function load() {
} }
watch( watch(
() => NOWUSER.isLogin, () => NOWUSER.is_login,
() => { () => {
load() load()
}, },
+2 -1
View File
@@ -1,7 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
import InDev from '@/components/InDev.vue'
import { useHead } from '@unhead/vue' import { useHead } from '@unhead/vue'
import InDev from '@/components/InDev.vue'
useHead({ useHead({
title: '剧本市场', title: '剧本市场',
}) })
+2 -1
View File
@@ -1,7 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
import UserAction from '@/components/admin/UserAction.vue'
import { useHead } from '@unhead/vue' import { useHead } from '@unhead/vue'
import UserAction from '@/components/admin/UserAction.vue'
useHead({ useHead({
title: '首页', title: '首页',
}) })
+5 -4
View File
@@ -1,10 +1,11 @@
<script setup lang="ts"> <script setup lang="ts">
import ConfigCard from '@/components/admin/ConfigCard.vue'
import { useHead } from '@unhead/vue' import { useHead } from '@unhead/vue'
import { ref } from 'vue'
import { api } from '@/tools/web.ts'
import InDev from '@/components/InDev.vue'
import { useMessage } from 'naive-ui' import { useMessage } from 'naive-ui'
import { ref } from 'vue'
import ConfigCard from '@/components/admin/ConfigCard.vue'
import InDev from '@/components/InDev.vue'
import { api } from '@/tools/web.ts'
import type { ReturnDto } from '@/types/response.ts' import type { ReturnDto } from '@/types/response.ts'
interface SiteConfig { interface SiteConfig {
+3 -2
View File
@@ -1,7 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
import { useNowUser } from '@/stores/now-user.js'
import { computed } from 'vue'
import { useHead } from '@unhead/vue' import { useHead } from '@unhead/vue'
import { computed } from 'vue'
import { useNowUser } from '@/stores/now-user.js'
useHead({ useHead({
title: '总览', title: '总览',
+7 -6
View File
@@ -1,12 +1,13 @@
<script setup lang="ts"> <script setup lang="ts">
import { useNowUser } from '@/stores/now-user.js'
import { ref, watch } from 'vue'
import SelectFileModal from '@/components/file/SelectFileModal.vue'
import { api } from '@/tools/web.js'
import type { UploadFileDto, UserDto } from '@/types/user.js'
import { useHead } from '@unhead/vue' import { useHead } from '@unhead/vue'
import { ref, watch } from 'vue'
import ChangeEmailModal from '@/components/admin/ChangeEmailModal.vue' import ChangeEmailModal from '@/components/admin/ChangeEmailModal.vue'
import ChangePhoneModal from '@/components/admin/ChangePhoneModal.vue' import ChangePhoneModal from '@/components/admin/ChangePhoneModal.vue'
import SelectFileModal from '@/components/file/SelectFileModal.vue'
import { useNowUser } from '@/stores/now-user.js'
import { api } from '@/tools/web.js'
import type { UploadFileDto, UserDto } from '@/types/user.js'
useHead({ useHead({
title: '用户资料', title: '用户资料',
@@ -65,7 +66,7 @@ watch(
) )
watch( watch(
() => NOWUSER.isLogin, () => NOWUSER.is_login,
() => { () => {
reInitForm() reInitForm()
}, },
+2 -1
View File
@@ -1,7 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
import InDev from '@/components/InDev.vue'
import { useHead } from '@unhead/vue' import { useHead } from '@unhead/vue'
import InDev from '@/components/InDev.vue'
useHead({ useHead({
title: '剧本', title: '剧本',
}) })
+7 -6
View File
@@ -1,11 +1,12 @@
<script setup lang="ts"> <script setup lang="ts">
import { useNowUser } from '@/stores/now-user.js'
import UserPasswordModal from '@/components/admin/UserPasswordModal.vue'
import { h, ref } from 'vue'
import { api } from '@/tools/web.ts'
import { type DataTableColumn, NTag, NText } from 'naive-ui'
import InDev from '@/components/InDev.vue'
import { useHead } from '@unhead/vue' import { useHead } from '@unhead/vue'
import { type DataTableColumn, NTag, NText } from 'naive-ui'
import { h, ref } from 'vue'
import UserPasswordModal from '@/components/admin/UserPasswordModal.vue'
import InDev from '@/components/InDev.vue'
import { useNowUser } from '@/stores/now-user.js'
import { api } from '@/tools/web.ts'
useHead({ useHead({
title: '用户安全', title: '用户安全',
+5 -4
View File
@@ -1,11 +1,12 @@
<script setup lang="ts"> <script setup lang="ts">
import { useHead } from '@unhead/vue'
import { ref, watch } from 'vue' import { ref, watch } from 'vue'
import { uploadFilesCom } from '@/components/file/upload-files.js'
import UploadFileModal from '@/components/file/UploadFileModal.vue' import UploadFileModal from '@/components/file/UploadFileModal.vue'
import { useNowUser } from '@/stores/now-user.js'
import { api } from '@/tools/web.js' import { api } from '@/tools/web.js'
import type { UploadFileDto } from '@/types/user.js' import type { UploadFileDto } from '@/types/user.js'
import { useNowUser } from '@/stores/now-user.js'
import { uploadFilesCom } from '@/components/file/upload-files.js'
import { useHead } from '@unhead/vue'
useHead({ useHead({
title: '上传', title: '上传',
@@ -24,7 +25,7 @@ function load() {
} }
watch( watch(
() => NOWUSER.isLogin, () => NOWUSER.is_login,
() => { () => {
load() load()
}, },
+7 -6
View File
@@ -1,15 +1,16 @@
import { createRouter, createWebHashHistory } from 'vue-router' import { createRouter, createWebHashHistory } from 'vue-router'
import ChatroomPage from '@/pages/ChatroomPage.vue'
import WelcomePage from '@/pages/WelcomePage.vue' import AdminNyahome from '@/pages/admin/AdminNyahome.vue'
import Chatroom1Page from '@/pages/Chatroom1Page.vue'
import AdminPage from '@/pages/AdminPage.vue'
import AdminOverview from '@/pages/admin/AdminOverview.vue' import AdminOverview from '@/pages/admin/AdminOverview.vue'
import AdminUserInfo from '@/pages/admin/AdminUserInfo.vue' import AdminUserInfo from '@/pages/admin/AdminUserInfo.vue'
import AdminUserScript from '@/pages/admin/AdminUserScript.vue'
import AdminUserSecurity from '@/pages/admin/AdminUserSecurity.vue' import AdminUserSecurity from '@/pages/admin/AdminUserSecurity.vue'
import AdminUserUpload from '@/pages/admin/AdminUserUpload.vue' import AdminUserUpload from '@/pages/admin/AdminUserUpload.vue'
import AdminNyahome from '@/pages/admin/AdminNyahome.vue' import AdminPage from '@/pages/AdminPage.vue'
import AdminUserScript from '@/pages/admin/AdminUserScript.vue' import Chatroom1Page from '@/pages/Chatroom1Page.vue'
import ChatroomPage from '@/pages/ChatroomPage.vue'
import Marketplace from '@/pages/Marketplace.vue' import Marketplace from '@/pages/Marketplace.vue'
import WelcomePage from '@/pages/WelcomePage.vue'
const router = createRouter({ const router = createRouter({
history: createWebHashHistory(import.meta.env.BASE_URL), history: createWebHashHistory(import.meta.env.BASE_URL),
+4 -3
View File
@@ -1,10 +1,11 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { ref } from 'vue' import { ref } from 'vue'
import { api, setApiToken } from '@/tools/web.ts' import { api, setApiToken } from '@/tools/web.ts'
import type { UserDto } from '@/types/user.ts' import type { UserDto } from '@/types/user.ts'
export const useNowUser = defineStore('now-user', () => { export const useNowUser = defineStore('now-user', () => {
const isLogin = ref(false) const is_login = ref(false)
const id = ref(0) const id = ref(0)
const name = ref('') const name = ref('')
@@ -41,11 +42,11 @@ export const useNowUser = defineStore('now-user', () => {
description.value = user.description description.value = user.description
is_admin.value = user.is_admin is_admin.value = user.is_admin
isLogin.value = true is_login.value = true
} }
return { return {
isLogin, is_login,
id, id,
name, name,
display_name, display_name,
+4 -2
View File
@@ -4,8 +4,10 @@ export interface ChatroomPublic {
description: string description: string
feature_image: string feature_image: string
script_template_id: number script_template_id?: number
script_template_version: string script_template_version?: string
default_model_id?: number
} }
export interface Chatroom extends ChatroomPublic { export interface Chatroom extends ChatroomPublic {