forked from Leaf/amber-ui
改进 logo 增加 chat 定义
This commit is contained in:
parent
92b30a6059
commit
55631c2cd6
Binary file not shown.
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 199 KiB |
1
src/components.d.ts
vendored
1
src/components.d.ts
vendored
@ -9,6 +9,7 @@ declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
AssistantMenu: typeof import('./components/AssistantMenu.vue')['default']
|
||||
Assistants: typeof import('./components/assistants/index.vue')['default']
|
||||
AssistantSettings: typeof import('./components/AssistantSettings.vue')['default']
|
||||
Chat: typeof import('./components/chat/Chat.vue')['default']
|
||||
ChatMenu: typeof import('./components/ChatMenu.vue')['default']
|
||||
ChatSettings: typeof import('./components/ChatSettings.vue')['default']
|
||||
|
144
src/components/AssistantSettings.vue
Normal file
144
src/components/AssistantSettings.vue
Normal file
@ -0,0 +1,144 @@
|
||||
<template>
|
||||
<n-list hoverable clickable v-if="assistants.length">
|
||||
<n-list-item v-for="c in assistants" :key="c.id" @click="currentAssistantId = c.id">
|
||||
<n-thing>
|
||||
<div class="flex justify-between items-center">
|
||||
<div>
|
||||
{{ c.name }}
|
||||
</div>
|
||||
<div>
|
||||
<n-button quaternary circle type="info" @click.stop="showEditAssistant(c.id ?? 0)">
|
||||
<template #icon>
|
||||
<n-icon size="16" class="cursor-pointer">
|
||||
<SettingsOutline />
|
||||
</n-icon>
|
||||
</template>
|
||||
</n-button>
|
||||
<n-button
|
||||
quaternary
|
||||
circle
|
||||
type="warning"
|
||||
@click.stop="deleteAssistant(c.id ?? 0)"
|
||||
>
|
||||
<template #icon>
|
||||
<n-icon size="16" class="cursor-pointer">
|
||||
<TrashBinOutline />
|
||||
</n-icon>
|
||||
</template>
|
||||
</n-button>
|
||||
</div>
|
||||
</div>
|
||||
</n-thing>
|
||||
</n-list-item>
|
||||
</n-list>
|
||||
<div v-else>
|
||||
<n-result status="404" title="还没有助理" description="助理可以整合一系列工具,也可以指定人设和自定义提示词">
|
||||
</n-result>
|
||||
</div>
|
||||
<div>
|
||||
<n-drawer placement="left" v-model:show="showSettingsDialog" :width="600">
|
||||
<n-drawer-content closable title="编辑助理">
|
||||
<div v-if="currentAssistant">
|
||||
<n-form>
|
||||
<n-form-item label="助理名称">
|
||||
<n-input
|
||||
v-model:value="currentAssistant.name"
|
||||
@keydown.enter.prevent
|
||||
/>
|
||||
</n-form-item>
|
||||
|
||||
<n-form-item label="资料库选择">
|
||||
<n-select
|
||||
:style="{ width: '33%' }"
|
||||
v-model:value="currentAssistant.library_id"
|
||||
:options="librarySelects"
|
||||
/>
|
||||
</n-form-item>
|
||||
|
||||
<n-button type="primary" @click="editAssistant"> 更新 </n-button>
|
||||
</n-form>
|
||||
</div>
|
||||
</n-drawer-content>
|
||||
</n-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { useDialog } from "naive-ui";
|
||||
import { TrashBinOutline, SettingsOutline } from "@vicons/ionicons5";
|
||||
import getApi from "../plugins/api";
|
||||
import { useChatStore } from "../stores/chat";
|
||||
import router from "@/router";
|
||||
import { ref } from "vue";
|
||||
import { EntityAssistant, EntityLibrary } from "@/api";
|
||||
|
||||
const dialog = useDialog();
|
||||
const chatStore = useChatStore();
|
||||
const showSettingsDialog = ref(false);
|
||||
const currentAssistantId = ref();
|
||||
const currentAssistant: Ref<EntityAssistant> = ref({});
|
||||
const assistants: Ref<EntityAssistant[]> = ref([]);
|
||||
const librarySelects: any = ref([]);
|
||||
const libraries: Ref<EntityLibrary[]> = ref([]);
|
||||
async function getChats() {
|
||||
chatStore.chats = (await getApi().Chat.apiV1ChatsGet()).data.data;
|
||||
}
|
||||
|
||||
const deleteAssistant = async (id: number) => {
|
||||
dialog.warning({
|
||||
title: "删除助理",
|
||||
content: "删除后,将不能恢复",
|
||||
positiveText: "确定",
|
||||
negativeText: "取消",
|
||||
onPositiveClick: async () => {
|
||||
await getApi().Assistant.apiV1AssistantsIdDelete(id);
|
||||
await getAssistants();
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const showEditAssistant = async (id: number) => {
|
||||
showSettingsDialog.value = true;
|
||||
currentAssistantId.value = id;
|
||||
currentAssistant.value =
|
||||
(await getApi().Assistant.apiV1AssistantsIdGet(id)).data.data ?? {};
|
||||
};
|
||||
|
||||
const editAssistant = async () => {
|
||||
await getApi().Assistant.apiV1AssistantsIdPatch(
|
||||
currentAssistantId.value,
|
||||
currentAssistant.value
|
||||
);
|
||||
await getAssistants();
|
||||
};
|
||||
|
||||
const getLibraries = async () => {
|
||||
libraries.value =
|
||||
(await getApi().Library.apiV1LibrariesGet()).data.data ?? [];
|
||||
|
||||
librarySelects.value = [];
|
||||
|
||||
librarySelects.value.push({
|
||||
label: "不使用",
|
||||
value: null,
|
||||
});
|
||||
libraries.value.forEach((a) => {
|
||||
if (a.name !== undefined && a.id !== undefined) {
|
||||
return librarySelects.value.push({
|
||||
label: a.name,
|
||||
// @ts-ignore
|
||||
value: a.id,
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const getAssistants = async () => {
|
||||
assistants.value =
|
||||
(await getApi().Assistant.apiV1AssistantsGet()).data.data ?? [];
|
||||
};
|
||||
|
||||
getChats();
|
||||
getLibraries();
|
||||
getAssistants();
|
||||
</script>
|
@ -4,7 +4,7 @@
|
||||
<ChatSettings />
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="chap2" tab="助理">
|
||||
<Assistants />
|
||||
<AssistantSettings />
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="chap3" tab="工具">
|
||||
“威尔!着火了!快来帮忙!”我听到女朋友大喊。现在一个难题在我面前——是恢复一个重要的
|
||||
|
@ -1,6 +0,0 @@
|
||||
<template>
|
||||
助理
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
</script>
|
@ -56,7 +56,10 @@
|
||||
ref="actionContainer"
|
||||
class="flex [&>button]:ml-2 pr-4 justify-end"
|
||||
>
|
||||
<n-tooltip trigger="hover">
|
||||
<n-tooltip
|
||||
trigger="hover"
|
||||
v-if="chatId !== null && chatData.assistant_id !== null"
|
||||
>
|
||||
<template #trigger>
|
||||
<n-button tertiary circle size="large">
|
||||
<template #icon>
|
||||
@ -134,7 +137,11 @@ import {
|
||||
DocumentAttachOutline,
|
||||
TrashBinOutline,
|
||||
} from "@vicons/ionicons5";
|
||||
import { EntityChatMessage, SchemaChatMessageAddRequestRoleEnum } from "@/api";
|
||||
import {
|
||||
EntityChatMessage,
|
||||
SchemaChatMessageAddRequestRoleEnum,
|
||||
EntityChat,
|
||||
} from "@/api";
|
||||
import getApi from "@/plugins/api";
|
||||
import MessageList from "./MessageList.vue";
|
||||
import { useChatStore } from "@/stores/chat";
|
||||
@ -179,7 +186,6 @@ const uploading = ref(false);
|
||||
const autoScroll = ref(true);
|
||||
const onBottom = ref(false);
|
||||
|
||||
|
||||
function onKeydown(e: KeyboardEvent) {
|
||||
// 带 shift 不触发
|
||||
if (e.shiftKey || inputExpanded.value) {
|
||||
@ -519,11 +525,22 @@ const clearChatHistory = async () => {
|
||||
processing.value = false;
|
||||
};
|
||||
|
||||
const chatData: Ref<EntityChat> = ref({});
|
||||
const getChat = async () => {
|
||||
chatData.value = (
|
||||
await getApi().Chat.apiV1ChatsIdGet(chatStore.currentChatId)
|
||||
).data.data;
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
chatId.value = props.chatId;
|
||||
chatStore.currentChatId = Number(chatId.value);
|
||||
updateInputHeight();
|
||||
getChatMessages();
|
||||
|
||||
if (chatId.value) {
|
||||
getChat();
|
||||
}
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
|
@ -4,6 +4,7 @@ import {
|
||||
ChatMessageApi,
|
||||
ChatPublicApi,
|
||||
Configuration,
|
||||
LibrariesApi,
|
||||
PingApi,
|
||||
ToolApi,
|
||||
} from "../api";
|
||||
@ -20,6 +21,7 @@ interface Api {
|
||||
Tool: ToolApi;
|
||||
ChatMessage: ChatMessageApi;
|
||||
ChatPublic: ChatPublicApi;
|
||||
Library: LibrariesApi;
|
||||
conf: Configuration
|
||||
}
|
||||
|
||||
@ -50,6 +52,7 @@ const getApi = () => {
|
||||
Tool: new ToolApi(conf, undefined, axios),
|
||||
ChatMessage: new ChatMessageApi(conf, undefined, axios),
|
||||
ChatPublic: new ChatPublicApi(conf, undefined, axios),
|
||||
Library: new LibrariesApi(conf, undefined, axios),
|
||||
conf: conf
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user