refactor: 主要功能实现

目前的工作已经实现的功能:
- 基本 FastAPI 路由;
- 基本 AI 聊天和创作功能;
- 用户信息管理、权限验证、JWT 令牌签发和验证、端点保护;
- HTML 验证码邮件发送和验证码验证。
This commit is contained in:
2026-05-24 13:58:51 +08:00
parent f06de85257
commit 21f0d7725e
98 changed files with 6483 additions and 116 deletions
@@ -0,0 +1,134 @@
<script setup lang="ts">
import {api} from '@/tools/web.js'
import {ref, watch} from 'vue'
import {useRoute} from 'vue-router'
import type {ChatScript} from '@/types/chatroom.js'
import type {ReturnDto} from '@/types/response.js'
import {useMessage} from 'naive-ui'
import XamlModal from '@/components/XamlModal.vue'
const ROUTE = useRoute()
const MESSAGE = useMessage()
const showDrawer = defineModel('showDrawer', {required: true})
const showXamlModal = ref(false)
const {script} = defineProps<{
script: string
}>()
const scriptForm = ref<ChatScript>({
main_prompt: '',
user_prefix: '',
user_suffix: '',
world_books: [],
})
function save() {
const id = Number(ROUTE.params.id)
api
.post(`/chatroom/${id}/script/`, JSON.stringify(scriptForm.value))
.then((res) => res.data as ReturnDto)
.then((data) => {
if (data.success) {
scriptForm.value = data.result as ChatScript
MESSAGE.success('保存剧本成功~')
} else {
throw TypeError('未知原因后端保存剧本失败。')
}
})
.catch((err) => {
MESSAGE.error(`保存剧本失败:${err}`)
})
}
watch(
() => script,
() => {
try {
scriptForm.value = JSON.parse(script) as ChatScript
} catch {
}
},
{immediate: true},
)
</script>
<template>
<n-drawer
v-model:show="showDrawer"
placement="left"
default-width="50vw"
resizable
native-scrollbar
@after-leave="showDrawer = false"
:z-index="20"
:on-after-leave="
() => {
if (showXamlModal) {
showXamlModal = false
MESSAGE.info('已关闭 Xaml 可视化工具。')
}
}
"
>
<n-drawer-content>
<template #header>
<n-h2 prefix="bar" style="margin-bottom: 0">剧本编辑器</n-h2>
</template>
<n-flex vertical>
<n-alert type="info" title="故事设定 · 世界书">
以下内容会被拼接在提示词以及用户输入中,在向 LLM 发送请求时携带。
</n-alert>
<n-button secondary type="warning" @click="showXamlModal = true">Xaml 可视化</n-button>
<n-card title="全局设定">
<template #header-extra>
<n-tag round type="info">这些内容每一轮请求都会被携带</n-tag>
</template>
<n-form :model="scriptForm">
<n-form-item label="提示词拼接于 Nya 主提示词后" path="main_prompt">
<n-input
type="textarea"
:rows="8"
v-model:value="scriptForm.main_prompt"
show-count
/>
</n-form-item>
<n-form-item label="用户输入前置词拼接于最新一条用户输入前" path="user_prefix">
<n-input
type="textarea"
:rows="8"
v-model:value="scriptForm.user_prefix"
show-count
/>
</n-form-item>
<n-form-item label="用户输入后置词拼接于最新一条用户输入后" path="user_suffix">
<n-input
type="textarea"
:rows="8"
v-model:value="scriptForm.user_suffix"
show-count
/>
</n-form-item>
</n-form>
</n-card>
<n-card title="世界书">
<template #header-extra>
<n-tag round type="info">仅在被提及时才会被动态拼接并携带的细分设定</n-tag>
</template>
</n-card>
</n-flex>
<template #footer>
<n-button type="primary" @click="save()">保存</n-button>
</template>
</n-drawer-content>
<xaml-modal v-model:show-modal="showXamlModal"/>
</n-drawer>
</template>
<style scoped></style>