改进 聊天和左侧菜单
This commit is contained in:
parent
92da9181e1
commit
086dd9979a
@ -1,4 +0,0 @@
|
||||
node_modules
|
||||
dist
|
||||
out
|
||||
.gitignore
|
@ -1,17 +1,16 @@
|
||||
/* eslint-env node */
|
||||
require('@rushstack/eslint-patch/modern-module-resolution')
|
||||
require("@rushstack/eslint-patch/modern-module-resolution");
|
||||
|
||||
module.exports = {
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:vue/vue3-recommended',
|
||||
'@electron-toolkit',
|
||||
'@electron-toolkit/eslint-config-ts/eslint-recommended',
|
||||
'@vue/eslint-config-typescript/recommended',
|
||||
'@vue/eslint-config-prettier'
|
||||
"eslint:recommended",
|
||||
"plugin:vue/vue3-recommended",
|
||||
"@vue/eslint-config-typescript/recommended",
|
||||
"@vue/eslint-config-prettier",
|
||||
],
|
||||
rules: {
|
||||
'vue/require-default-prop': 'off',
|
||||
'vue/multi-word-component-names': 'off'
|
||||
}
|
||||
}
|
||||
"vue/require-default-prop": "off",
|
||||
"vue/multi-word-component-names": "off",
|
||||
},
|
||||
ignores: ["src/typed-router.d.ts", "node_modules", "dist", "out", ".gitignore"],
|
||||
};
|
||||
|
12
package.json
12
package.json
@ -31,11 +31,17 @@
|
||||
"@vue/eslint-config-prettier": "^9.0.0",
|
||||
"@vue/eslint-config-typescript": "^13.0.0",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-plugin-vue": "^9.26.0",
|
||||
"eslint": "^9.10.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-config-standard": "^17.1.0",
|
||||
"eslint-plugin-import": "^2.30.0",
|
||||
"eslint-plugin-n": "^17.10.2",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^7.1.0",
|
||||
"eslint-plugin-vue": "^9.28.0",
|
||||
"naive-ui": "^2.39.0",
|
||||
"postcss": "^8.4.45",
|
||||
"prettier": "^3.3.2",
|
||||
"prettier": "^3.3.3",
|
||||
"tailwindcss": "^3.4.10",
|
||||
"typescript": "^5.5.2",
|
||||
"unplugin-auto-import": "^0.18.2",
|
||||
|
2
src/components.d.ts
vendored
2
src/components.d.ts
vendored
@ -12,6 +12,8 @@ declare module 'vue' {
|
||||
ChatMenu: typeof import('./components/ChatMenu.vue')['default']
|
||||
Container: typeof import('./components/Container.vue')['default']
|
||||
copy: typeof import('./components/AssistantMenu.vue')['default']
|
||||
LeftSetting: typeof import('./components/LeftSetting.vue')['default']
|
||||
LeftSettings: typeof import('./components/LeftSettings.vue')['default']
|
||||
Menu: typeof import('./components/Menu.vue')['default']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
|
@ -1,5 +1,6 @@
|
||||
<template>
|
||||
<n-list hoverable clickable>
|
||||
<div v-show="!loaded">正在载入</div>
|
||||
<n-list hoverable clickable v-show="loaded" class="select-none">
|
||||
<template #header>
|
||||
<div>
|
||||
<span class="text-xl">切换助理</span>
|
||||
@ -14,14 +15,11 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useRoute } from "vue-router";
|
||||
import { useUserStore } from "../stores/user";
|
||||
import { updateAll } from "../plugins/update/update";
|
||||
import { useAssistantStore } from "../stores/assistants";
|
||||
|
||||
const route = useRoute();
|
||||
const currentRoute: any = computed(() => route.name);
|
||||
const collapsed = ref(false);
|
||||
const loaded = ref(false);
|
||||
const userStore = useUserStore();
|
||||
const assistantStore = useAssistantStore();
|
||||
|
||||
@ -35,6 +33,7 @@ watch(
|
||||
);
|
||||
function update() {
|
||||
updateAll();
|
||||
loaded.value = true
|
||||
}
|
||||
|
||||
update();
|
||||
|
@ -2,7 +2,8 @@
|
||||
// import router from '../plugins/router';
|
||||
import Header from "../layouts/Header.vue";
|
||||
import { useUserStore } from "../stores/user";
|
||||
|
||||
import { useRoute } from "vue-router";
|
||||
const route = useRoute();
|
||||
const userStore = useUserStore();
|
||||
// const currentRoute = computed(() => router.currentRoute.value.name)
|
||||
</script>
|
||||
@ -14,7 +15,7 @@ const userStore = useUserStore();
|
||||
></Header>
|
||||
|
||||
<div class="p-4">
|
||||
<router-view v-slot="{ Component }">
|
||||
<router-view v-slot="{ Component }" :key="route.path">
|
||||
<transition mode="out-in" name="fade">
|
||||
<div>
|
||||
<component :is="Component" />
|
||||
|
53
src/components/LeftSettings.vue
Normal file
53
src/components/LeftSettings.vue
Normal file
@ -0,0 +1,53 @@
|
||||
<template>
|
||||
<n-tabs type="segment" animated>
|
||||
<n-tab-pane name="chap1" tab="对话">
|
||||
<n-list hoverable clickable>
|
||||
<n-list-item
|
||||
v-for="c in chatStore.chats"
|
||||
:key="c.id"
|
||||
:class="c.id == chatStore.currentChatId ? 'text-primary' : ''"
|
||||
@click="viewChat(c.id ?? 0)"
|
||||
>
|
||||
<n-thing> {{ c.name }} </n-thing>
|
||||
</n-list-item>
|
||||
</n-list>
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="chap2" tab="助理">
|
||||
“威尔!着火了!快来帮忙!”我听到女朋友大喊。现在一个难题在我面前——是恢复一个重要的
|
||||
Amazon 服务,还是救公寓的火。<br /><br />
|
||||
我的脑海中忽然出现了 Amazon
|
||||
著名的领导力准则”客户至上“,有很多的客户还依赖我们的服务,我不能让他们失望!所以着火也不管了,女朋友喊我也无所谓,我开始
|
||||
debug 这个线上问题。
|
||||
</n-tab-pane>
|
||||
</n-tabs>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { NMenu } from "naive-ui";
|
||||
import { useRoute } from "vue-router";
|
||||
import { leftMenuOptions } from "../plugins/menus/left";
|
||||
import { ChatboxOutline } from "@vicons/ionicons5";
|
||||
import getApi from "../plugins/api";
|
||||
import { useChatStore } from "../stores/chat";
|
||||
import router from "@/router";
|
||||
|
||||
const route = useRoute();
|
||||
// @ts-ignore
|
||||
const chatId = route.params.id as number;
|
||||
|
||||
const currentRoute: any = computed(() => route.name);
|
||||
|
||||
const collapsed = ref(false);
|
||||
|
||||
const chatStore = useChatStore();
|
||||
|
||||
async function getChats() {
|
||||
chatStore.chats = (await getApi().Chat.apiV1ChatsGet()).data.data;
|
||||
}
|
||||
|
||||
const viewChat = (chatId: number) => {
|
||||
router.push("/chat/" + chatId);
|
||||
};
|
||||
|
||||
getChats();
|
||||
</script>
|
@ -13,8 +13,8 @@
|
||||
<span class="font-xl ml-2">对话列表</span>
|
||||
</div>
|
||||
</template>
|
||||
<n-list-item v-for="i in 10" :key="i">
|
||||
<n-thing> 对话 </n-thing>
|
||||
<n-list-item v-for="c in chatStore.chats" :key="c.id">
|
||||
<n-thing> {{ c.name }} </n-thing>
|
||||
</n-list-item>
|
||||
</n-list>
|
||||
</template>
|
||||
@ -24,10 +24,20 @@ import { NMenu } from "naive-ui";
|
||||
import { useRoute } from "vue-router";
|
||||
import { leftMenuOptions } from "../plugins/menus/left";
|
||||
import { ChatboxOutline } from "@vicons/ionicons5";
|
||||
import getApi from "../plugins/api";
|
||||
import { useChatStore } from "../stores/chat";
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
const currentRoute: any = computed(() => route.name);
|
||||
|
||||
const collapsed = ref(false);
|
||||
|
||||
const chatStore = useChatStore();
|
||||
|
||||
async function getChats() {
|
||||
chatStore.chats = (await getApi().Chat.apiV1ChatsGet()).data.data;
|
||||
}
|
||||
|
||||
getChats();
|
||||
</script>
|
||||
|
@ -20,7 +20,7 @@ const menuCollapsed = ref({
|
||||
|
||||
<template>
|
||||
<n-layout position="absolute" :has-sider="true">
|
||||
<n-layout-sider
|
||||
<!-- <n-layout-sider
|
||||
v-if="userStore.logined && !isMobile"
|
||||
:collapsed-width="0"
|
||||
:native-scrollbar="false"
|
||||
@ -34,7 +34,7 @@ const menuCollapsed = ref({
|
||||
@expand="menuCollapsed.left = false"
|
||||
>
|
||||
<Menu v-show="!isMobile"></Menu>
|
||||
</n-layout-sider>
|
||||
</n-layout-sider> -->
|
||||
<n-layout-content>
|
||||
<!-- <Guest v-if="!userStore.logined && currentRoute != '/auth/login'" />
|
||||
<Container v-else /> -->
|
||||
|
@ -4,7 +4,7 @@
|
||||
<n-grid cols="2" class="header-height">
|
||||
<n-grid-item class="flex items-center justify-start mr-1.5">
|
||||
<!-- 左侧 -->
|
||||
<n-popover
|
||||
<!-- <n-popover
|
||||
placement="bottom"
|
||||
trigger="click"
|
||||
style="padding: 0; width: 288px"
|
||||
@ -16,7 +16,25 @@
|
||||
</n-icon>
|
||||
</template>
|
||||
<Menu></Menu>
|
||||
</n-popover>
|
||||
</n-popover> -->
|
||||
|
||||
<n-drawer
|
||||
v-model:show="showDrawer"
|
||||
resizable
|
||||
:default-width="width"
|
||||
placement="left"
|
||||
>
|
||||
<n-drawer-content>
|
||||
<LeftSettings></LeftSettings>
|
||||
</n-drawer-content>
|
||||
</n-drawer>
|
||||
<n-icon
|
||||
size="20"
|
||||
style="margin-left: 12px"
|
||||
@click="showDrawer = true"
|
||||
>
|
||||
<menu-outline />
|
||||
</n-icon>
|
||||
|
||||
<!-- 更新状态 -->
|
||||
<div v-show="appStore.updating">正在更新数据</div>
|
||||
@ -72,6 +90,16 @@ const userStore = useUserStore();
|
||||
const isMobile = useIsMobile();
|
||||
const isTablet = useIsTablet();
|
||||
const appStore = useAppStore();
|
||||
const showDrawer = ref(false);
|
||||
const width = ref(200);
|
||||
|
||||
// 如果是手机,则 width 为全屏
|
||||
if (isMobile.value) {
|
||||
// 获取屏幕宽度
|
||||
width.value = window.innerWidth - 100;
|
||||
} else {
|
||||
width.value = "40%";
|
||||
}
|
||||
|
||||
const userPlacement = ref("bottom");
|
||||
if (isMobile.value) {
|
||||
|
322
src/pages/chat/[id]/index copy.vue
Normal file
322
src/pages/chat/[id]/index copy.vue
Normal file
@ -0,0 +1,322 @@
|
||||
<template>
|
||||
<div>
|
||||
<h3 class="mb-3">聊天记录</h3>
|
||||
|
||||
<v-card
|
||||
v-for="message in messages.data"
|
||||
:key="message.id"
|
||||
class="mx-auto mt-3"
|
||||
width="100%"
|
||||
>
|
||||
<template #title>
|
||||
<div class="font-weight-black">
|
||||
<div v-if="message.role == 'assistant'">AI</div>
|
||||
<div v-else-if="message.role == 'system'">系统</div>
|
||||
|
||||
<div v-else-if="message.role == 'file'" class="text-right">文件</div>
|
||||
<div v-else-if="message.role == 'image'" class="text-right">图片</div>
|
||||
<div v-else-if="message.role == 'user'" class="text-right">用户</div>
|
||||
|
||||
<div v-else>
|
||||
{{ message.role }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<v-card-text class="bg-surface-light pt-4">
|
||||
<div
|
||||
v-if="message.role == 'assistant' || message.role == 'system'"
|
||||
class="text-left"
|
||||
>
|
||||
<vue-markdown :source="message.content" />
|
||||
</div>
|
||||
|
||||
<div v-else-if="message.role == 'user'" class="text-right">
|
||||
<vue-markdown :source="message.content" />
|
||||
</div>
|
||||
<div v-else-if="message.role == 'image'" class="text-right">
|
||||
<img
|
||||
:src="fileBaseUrl + '/' + message.content + '/download'"
|
||||
width="30%"
|
||||
/>
|
||||
</div>
|
||||
<div v-else-if="message.role == 'file'" class="text-right">
|
||||
其他文件:<a :href="fileBaseUrl + '/' + message.content + '/download'"
|
||||
>下载</a
|
||||
>
|
||||
</div>
|
||||
<div v-else>
|
||||
{{ message.content }}
|
||||
</div>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
|
||||
<div class="mt-3">
|
||||
<div v-if="toolError" class="mb-3">
|
||||
<v-alert
|
||||
density="compact"
|
||||
text="这个工具出现了异常,这应该不是我们的问题,如果你是此工具的开发者,请打开开发者控制台查看具体错误。"
|
||||
:title="'工具 ' + toolName + ' 出现异常'"
|
||||
type="warning"
|
||||
></v-alert>
|
||||
</div>
|
||||
|
||||
<div v-show="toolCalling">
|
||||
<v-progress-circular
|
||||
color="primary"
|
||||
indeterminate
|
||||
:size="16"
|
||||
></v-progress-circular>
|
||||
正在执行 {{ toolName }}
|
||||
</div>
|
||||
<v-text-field
|
||||
v-model="input"
|
||||
label="输入消息"
|
||||
@keyup.enter="sendMessage"
|
||||
></v-text-field>
|
||||
<v-file-input v-model="fileUpload" label="选择文件"></v-file-input>
|
||||
|
||||
<v-btn color="primary" @click="sendMessage">发送</v-btn>
|
||||
<v-btn
|
||||
class="ml-2"
|
||||
color="primary"
|
||||
:loading="uploading"
|
||||
@click="uploadFile"
|
||||
>上传文件</v-btn
|
||||
>
|
||||
|
||||
<v-btn class="ml-2" color="primary" @click="clearMessages">清空</v-btn>
|
||||
<v-btn class="ml-2" color="primary" @click="deleteChat">删除</v-btn>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import useApi from "@/plugins/api";
|
||||
import router from "@/router";
|
||||
import { useChatStore } from "@/stores/chat";
|
||||
import config from "@/config/config";
|
||||
|
||||
const chatStore = useChatStore();
|
||||
const api = useApi();
|
||||
|
||||
// @ts-ignore
|
||||
const chatId = useRoute().params.id as number;
|
||||
chatStore.currentChatId = chatId;
|
||||
|
||||
const messages: Ref<any> = ref({
|
||||
data: [],
|
||||
});
|
||||
const input = ref("");
|
||||
const toolName = ref("");
|
||||
const toolError = ref(false);
|
||||
const toolCalling = ref(false);
|
||||
const fileUpload = ref();
|
||||
const uploading = ref(false);
|
||||
const fileBaseUrl = config.backend + "/api/v1/files";
|
||||
|
||||
document.addEventListener("paste", function (event) {
|
||||
const items = event.clipboardData && event.clipboardData.items;
|
||||
if (items && items.length) {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
if (items[i].type.indexOf("image") !== -1) {
|
||||
fileUpload.value = items[i].getAsFile();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function sendMessage() {
|
||||
if (input.value !== "") {
|
||||
toolError.value = false;
|
||||
api.ChatMessage.apiV1ChatsIdMessagesPost(chatId, {
|
||||
message: input.value,
|
||||
role: "user",
|
||||
})
|
||||
.then((res) => {
|
||||
const newMessage = {
|
||||
content: input.value,
|
||||
role: "user",
|
||||
};
|
||||
|
||||
if (messages.value.data == null) {
|
||||
messages.value.data = [newMessage];
|
||||
} else {
|
||||
messages.value.data?.push(newMessage);
|
||||
}
|
||||
|
||||
const streamId = res.data.data?.stream_id;
|
||||
|
||||
if (streamId) {
|
||||
streamChat(streamId);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
// if 409
|
||||
if (err.response.status === 409) {
|
||||
const streamId = err.response.data.data?.stream_id;
|
||||
|
||||
if (streamId) {
|
||||
streamChat(streamId);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function streamChat(streamId: String) {
|
||||
const url = api.conf.basePath + "/api/v1/stream/" + streamId;
|
||||
|
||||
const evtSource = new EventSource(url);
|
||||
|
||||
let messageAdded = false;
|
||||
|
||||
// 滚动页面到最底部
|
||||
window.scrollTo(0, document.body.scrollHeight);
|
||||
|
||||
let i = 0;
|
||||
|
||||
evtSource.addEventListener("data", (e) => {
|
||||
if (e.data === "[DONE]") {
|
||||
evtSource.close();
|
||||
return;
|
||||
}
|
||||
|
||||
const data = JSON.parse(e.data);
|
||||
|
||||
let append = true;
|
||||
|
||||
switch (data.state) {
|
||||
case "tool_calling":
|
||||
toolCalling.value = true;
|
||||
toolName.value =
|
||||
data.tool_call_message.tool_name +
|
||||
" 中的 " +
|
||||
data.tool_call_message.function_name;
|
||||
break;
|
||||
case "tool_response":
|
||||
setTimeout(() => {
|
||||
toolName.value = "";
|
||||
toolCalling.value = false;
|
||||
}, 300);
|
||||
break;
|
||||
case "tool_failed":
|
||||
toolName.value =
|
||||
data.tool_response_message.tool_name +
|
||||
" 中的 " +
|
||||
data.tool_response_message.function_name;
|
||||
toolError.value = true;
|
||||
append = false;
|
||||
setTimeout(() => {
|
||||
toolCalling.value = false;
|
||||
}, 300);
|
||||
break;
|
||||
case "chunk":
|
||||
if (!messageAdded) {
|
||||
const newMessage = {
|
||||
content: "",
|
||||
role: "assistant",
|
||||
};
|
||||
|
||||
if (messages.value.data == null) {
|
||||
messages.value.data = [newMessage];
|
||||
} else {
|
||||
// add to messages
|
||||
messages.value.data?.push(newMessage);
|
||||
}
|
||||
|
||||
messageAdded = true;
|
||||
append = true;
|
||||
// set index
|
||||
i = (messages.value.data?.length ?? 1) - 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (append && messageAdded) {
|
||||
// @ts-ignore
|
||||
messages.value.data[i].content += data.content;
|
||||
}
|
||||
});
|
||||
|
||||
// close
|
||||
evtSource.addEventListener("close", () => {
|
||||
evtSource.close();
|
||||
});
|
||||
}
|
||||
|
||||
const getMessages = () => {
|
||||
api.ChatMessage.apiV1ChatsIdMessagesGet(chatId).then((res) => {
|
||||
messages.value.data = [];
|
||||
res.data.data?.forEach((message: any) => {
|
||||
if (message.role === "file") {
|
||||
// 如果 mime_type 是 image/
|
||||
if (message.user_file) {
|
||||
if (message.user_file.file.mime_type.startsWith("image/")) {
|
||||
message.role = "image";
|
||||
message.content = message.user_file.file.id;
|
||||
}
|
||||
} else if (message.file.mime_type.startsWith("image/")) {
|
||||
message.role = "image";
|
||||
message.content = message.file.id;
|
||||
}
|
||||
|
||||
messages.value.data?.push(message);
|
||||
} else if (message.role === "assistant" || message.role === "user") {
|
||||
messages.value.data?.push(message);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const clearMessages = () => {
|
||||
api.ChatMessage.apiV1ChatsIdClearPost(chatId).then(() => {
|
||||
getMessages();
|
||||
});
|
||||
};
|
||||
|
||||
const deleteChat = () => {
|
||||
api.Chat.apiV1ChatsIdDelete(chatId).then(() => {
|
||||
api.Chat.apiV1ChatsGet().then((r) => {
|
||||
chatStore.chats = r.data.data;
|
||||
});
|
||||
router.push("/assistants");
|
||||
});
|
||||
};
|
||||
|
||||
const uploadFile = () => {
|
||||
if (!fileUpload.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
uploading.value = true;
|
||||
api.ChatMessage.apiV1ChatsIdFilesPost(
|
||||
chatId,
|
||||
{
|
||||
file: fileUpload.value,
|
||||
url: "",
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data",
|
||||
},
|
||||
}
|
||||
)
|
||||
.then((r) => {
|
||||
// 如果成功
|
||||
if (r.status === 200 || r.status === 201) {
|
||||
fileUpload.value = null;
|
||||
getMessages();
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
alert(err.response.data.message);
|
||||
})
|
||||
.finally(() => {
|
||||
uploading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
getMessages();
|
||||
</script>
|
9
src/pages/chat/[id]/index.vue
Normal file
9
src/pages/chat/[id]/index.vue
Normal file
@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<div>聊天记录 {{ chatId }}</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
// @ts-ignore
|
||||
const chatId = useRoute().params.id as number;
|
||||
// chatStore.currentChatId = chatId;
|
||||
</script>
|
@ -20,6 +20,7 @@ interface Api {
|
||||
Tool: ToolApi;
|
||||
ChatMessage: ChatMessageApi;
|
||||
ChatPublic: ChatPublicApi;
|
||||
conf: Configuration
|
||||
}
|
||||
|
||||
let api: Api | null = null; // 使用联合类型来表示初始状态可能是 null
|
||||
@ -49,6 +50,7 @@ const getApi = () => {
|
||||
Tool: new ToolApi(conf, undefined, axios),
|
||||
ChatMessage: new ChatMessageApi(conf, undefined, axios),
|
||||
ChatPublic: new ChatPublicApi(conf, undefined, axios),
|
||||
conf: conf
|
||||
};
|
||||
|
||||
return api;
|
||||
|
@ -4,6 +4,7 @@ import { EntityChat } from "../api";
|
||||
export const useChatStore = defineStore("chats", {
|
||||
persist: false,
|
||||
state: () => ({
|
||||
currentChatId: 0,
|
||||
chats: <EntityChat[] | undefined>[],
|
||||
}),
|
||||
});
|
||||
|
2
src/typed-router.d.ts
vendored
2
src/typed-router.d.ts
vendored
@ -23,6 +23,8 @@ declare module 'vue-router/auto-routes' {
|
||||
'/auth/continue': RouteRecordInfo<'/auth/continue', '/auth/continue', Record<never, never>, Record<never, never>>,
|
||||
'/auth/login': RouteRecordInfo<'/auth/login', '/auth/login', Record<never, never>, Record<never, never>>,
|
||||
'/auth/logout': RouteRecordInfo<'/auth/logout', '/auth/logout', Record<never, never>, Record<never, never>>,
|
||||
'/chat/[id]/': RouteRecordInfo<'/chat/[id]/', '/chat/:id', { id: ParamValue<true> }, { id: ParamValue<false> }>,
|
||||
'/chat/[id]/index copy': RouteRecordInfo<'/chat/[id]/index copy', '/chat/:id/index copy', { id: ParamValue<true> }, { id: ParamValue<false> }>,
|
||||
'/guest/': RouteRecordInfo<'/guest/', '/guest', Record<never, never>, Record<never, never>>,
|
||||
'/test': RouteRecordInfo<'/test', '/test', Record<never, never>, Record<never, never>>,
|
||||
'/test2': RouteRecordInfo<'/test2', '/test2', Record<never, never>, Record<never, never>>,
|
||||
|
@ -17,7 +17,16 @@
|
||||
"skipLibCheck": true,
|
||||
"types": [
|
||||
"unplugin-vue-router/client"
|
||||
]
|
||||
],
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"./src/*"
|
||||
]
|
||||
},
|
||||
"allowJs": true,
|
||||
"strictNullChecks": true,
|
||||
"noUnusedLocals": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
@ -30,4 +39,4 @@
|
||||
"path": "./tsconfig.node.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -1,13 +1,13 @@
|
||||
import { defineConfig } from "vite"
|
||||
import vue from "@vitejs/plugin-vue"
|
||||
import VueRouter from "unplugin-vue-router/vite"
|
||||
import Layouts from "vite-plugin-vue-layouts"
|
||||
import Components from "unplugin-vue-components/vite"
|
||||
import AutoImport from "unplugin-auto-import/vite"
|
||||
import { defineConfig } from "vite";
|
||||
import vue from "@vitejs/plugin-vue";
|
||||
import VueRouter from "unplugin-vue-router/vite";
|
||||
import Layouts from "vite-plugin-vue-layouts";
|
||||
import Components from "unplugin-vue-components/vite";
|
||||
import AutoImport from "unplugin-auto-import/vite";
|
||||
// import { resolve } from "path";
|
||||
// const rootPath = new URL(".", import.meta.url).pathname;
|
||||
|
||||
import { fileURLToPath, URL } from "node:url"
|
||||
import { fileURLToPath, URL } from "node:url";
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
resolve: {
|
||||
@ -54,4 +54,4 @@ export default defineConfig({
|
||||
port: 5173,
|
||||
strictPort: true,
|
||||
},
|
||||
})
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user