fetch: 页面移植

AI聊天移植
This commit is contained in:
杨谢雨 2025-03-04 16:52:20 +08:00
parent 46d23bd6b6
commit cf1c7210f7
23 changed files with 359 additions and 584 deletions

View File

@ -37,7 +37,7 @@ export function clean(conversationId: string | null) {
})
}
export function getMessages(conversationId?: string) {
export function getMessages(conversationId?: string | number) {
return request.get({
url: `/aigc/chat/messages/${conversationId}`
})

View File

@ -1,9 +1,7 @@
import { defineStore } from 'pinia';
import projectSetting from '@/settings/projectSetting.ts';
// import {ICrumbsSetting, IHeaderSetting, IMenuSetting, IMultiTabsSetting} from "../../../types/config";
import projectSetting from '@/settings/projectSetting';
import type { ICrumbsSetting, IHeaderSetting, IMenuSetting, IMultiTabsSetting } from '/#/config';
const {
navMode,
navTheme,

View File

@ -17,12 +17,12 @@
<script lang="ts" setup>
import PromptPage from './prompt/index.vue'
import SettingsPage from './settings/index.vue'
import Chat from '@/views/ai/chat/Chat.vue'
import Chat from '@/views/ai/chat/new-chat/Chat.vue'
import { useRouter, useRoute } from 'vue-router'
import { onMounted, ref } from 'vue'
import { ElMessage } from 'element-plus'
import { useAppStore } from '../store'
import { useChatStore } from '@/views/ai/chat/store/useChatStore'
import { useChatStore } from '@/views/ai/chat/new-chat/store/useChatStore'
import { getAppInfo } from '@/api/new-ai/chat'
import { formatToDateTime } from '@/utils/dateUtil'

View File

@ -1,56 +0,0 @@
<!--
- Copyright (c) 2024 LangChat. TyCoding All Rights Reserved.
-
- Licensed under the GNU Affero General Public License, Version 3 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- https://www.gnu.org/licenses/agpl-3.0.html
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-->
<script lang="ts" setup>
import { onMounted, ref } from 'vue';
import Chat from '@/views/ai/chat/Chat.vue';
import { getMessages } from '@/api/new-ai/chat';
import { useChatStore } from '@/views/ai/chat/store/useChatStore';
import { useUserStore } from '@/store/modules/user';
import Header from './Header.vue';
const loading = ref(true);
const chatStore = useChatStore();
const userStore = useUserStore();
onMounted(async () => {
await fetch();
});
async function fetch() {
loading.value = true;
chatStore.conversationId = userStore.info.id;
chatStore.messages = await getMessages(userStore.info.id);
loading.value = false;
}
</script>
<template>
<n-card class="p-4 pt-1 w-full h-full">
<Header title="AI聊天助手" @reload="fetch" />
<div class="flex flex-col w-full overflow-hidden" style="height: calc(100vh - 180px)">
<main ref="contentRef" class="flex-1 overflow-hidden overflow-y-auto">
<Chat />
</main>
</div>
</n-card>
</template>
<style lang="less" scoped>
::v-deep(.n-tabs.n-tabs--top .n-tab-pane) {
padding: 0 !important;
}
</style>

View File

@ -1,122 +0,0 @@
@import 'highlight.js/styles/github.css';
.message-reply,
.message-request {
position: relative;
margin-bottom: 0;
}
.message-reply {
margin-right: 12px;
}
.message-request {
margin-left: 12px;
}
.text-wrap {
max-width: 80%;
}
.code-block-wrapper {
position: relative;
padding-top: 24px;
border-radius: 8px;
margin: 8px 0;
&:hover {
.code-block-header__copy {
display: block;
}
}
.code-block-header {
position: absolute;
top: 0;
left: 0;
width: 100%;
padding: 4px 0;
background-color: #f6f8fa;
border-radius: 8px 8px 0 0;
&__lang {
position: absolute;
left: 8px;
font-size: 12px;
font-weight: 500;
color: #666;
}
&__copy {
position: absolute;
right: 8px;
font-size: 12px;
font-weight: 500;
color: #666;
cursor: pointer;
display: none;
&:hover {
color: #000;
}
}
}
.code-block-body {
margin: 0;
padding: 12px;
border-radius: 0 0 8px 8px;
overflow-x: auto;
font-family: 'Fira Code', monospace;
}
}
.markdown-body {
background-color: transparent;
margin-bottom: 0;
pre {
background-color: #f6f8fa;
}
code {
background-color: transparent;
padding: 0;
}
table {
width: 100%;
margin-bottom: 16px;
border-collapse: collapse;
th,
td {
padding: 6px 13px;
border: 1px solid #dfe2e5;
}
th {
background-color: #f6f8fa;
}
tr:nth-child(2n) {
background-color: #f6f8fa;
}
}
}
@keyframes blink {
0% {
background: #fff;
}
50% {
background: #000;
}
100% {
background: #fff;
}
}
.animate-blink {
animation: blink 1s infinite;
}

View File

@ -1,222 +0,0 @@
/*
* Copyright (c) 2024 LangChat. TyCoding All Rights Reserved.
*
* Licensed under the GNU Affero General Public License, Version 3 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.gnu.org/licenses/agpl-3.0.html
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
html.dark {
pre code.hljs {
display: block;
overflow-x: auto;
padding: 1em
}
code.hljs {
padding: 3px 5px
}
.hljs {
color: #abb2bf;
background: #282c34
}
.hljs-keyword,
.hljs-operator,
.hljs-pattern-match {
color: #f92672
}
.hljs-function,
.hljs-pattern-match .hljs-constructor {
color: #61aeee
}
.hljs-function .hljs-params {
color: #a6e22e
}
.hljs-function .hljs-params .hljs-typing {
color: #fd971f
}
.hljs-module-access .hljs-module {
color: #7e57c2
}
.hljs-constructor {
color: #e2b93d
}
.hljs-constructor .hljs-string {
color: #9ccc65
}
.hljs-comment,
.hljs-quote {
color: #b18eb1;
font-style: italic
}
.hljs-doctag,
.hljs-formula {
color: #c678dd
}
.hljs-deletion,
.hljs-name,
.hljs-section,
.hljs-selector-tag,
.hljs-subst {
color: #e06c75
}
.hljs-literal {
color: #56b6c2
}
.hljs-addition,
.hljs-attribute,
.hljs-meta .hljs-string,
.hljs-regexp,
.hljs-string {
color: #98c379
}
.hljs-built_in,
.hljs-class .hljs-title,
.hljs-title.class_ {
color: #e6c07b
}
.hljs-attr,
.hljs-number,
.hljs-selector-attr,
.hljs-selector-class,
.hljs-selector-pseudo,
.hljs-template-variable,
.hljs-type,
.hljs-variable {
color: #d19a66
}
.hljs-bullet,
.hljs-link,
.hljs-meta,
.hljs-selector-id,
.hljs-symbol,
.hljs-title {
color: #61aeee
}
.hljs-emphasis {
font-style: italic
}
.hljs-strong {
font-weight: 700
}
.hljs-link {
text-decoration: underline
}
}
html {
pre code.hljs {
display: block;
overflow-x: auto;
padding: 1em
}
code.hljs {
padding: 3px 5px;
&::-webkit-scrollbar {
height: 4px;
}
}
.hljs {
color: #383a42;
background: #fafafa
}
.hljs-comment,
.hljs-quote {
color: #a0a1a7;
font-style: italic
}
.hljs-doctag,
.hljs-formula,
.hljs-keyword {
color: #a626a4
}
.hljs-deletion,
.hljs-name,
.hljs-section,
.hljs-selector-tag,
.hljs-subst {
color: #e45649
}
.hljs-literal {
color: #0184bb
}
.hljs-addition,
.hljs-attribute,
.hljs-meta .hljs-string,
.hljs-regexp,
.hljs-string {
color: #50a14f
}
.hljs-attr,
.hljs-number,
.hljs-selector-attr,
.hljs-selector-class,
.hljs-selector-pseudo,
.hljs-template-variable,
.hljs-type,
.hljs-variable {
color: #986801
}
.hljs-bullet,
.hljs-link,
.hljs-meta,
.hljs-selector-id,
.hljs-symbol,
.hljs-title {
color: #4078f2
}
.hljs-built_in,
.hljs-class .hljs-title,
.hljs-title.class_ {
color: #c18401
}
.hljs-emphasis {
font-style: italic
}
.hljs-strong {
font-weight: 700
}
.hljs-link {
text-decoration: underline
}
}

View File

@ -1,19 +0,0 @@
/*
* Copyright (c) 2024 LangChat. TyCoding All Rights Reserved.
*
* Licensed under the GNU Affero General Public License, Version 3 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.gnu.org/licenses/agpl-3.0.html
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@import "github-markdown.less";
@import "highlight.less";
@import "style.less";

View File

@ -1,105 +0,0 @@
/*
* Copyright (c) 2024 LangChat. TyCoding All Rights Reserved.
*
* Licensed under the GNU Affero General Public License, Version 3 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.gnu.org/licenses/agpl-3.0.html
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.markdown-body {
background-color: transparent;
font-size: 14px;
p {
white-space: pre-wrap;
}
ol {
list-style-type: decimal;
}
ul {
list-style-type: disc;
}
pre code,
pre tt {
line-height: 1.65;
}
.highlight pre,
pre {
background-color: #fff;
}
code.hljs {
padding: 0;
}
.code-block {
&-wrapper {
position: relative;
padding-top: 24px;
margin-top: 10px;
}
&-header {
position: absolute;
top: 5px;
right: 0;
width: 100%;
padding: 0 1rem;
display: flex;
justify-content: flex-end;
align-items: center;
color: #b3b3b3;
&__copy {
cursor: pointer;
margin-left: 0.5rem;
user-select: none;
&:hover {
color: #65a665;
}
}
}
}
}
html.dark {
.message-reply {
.whitespace-pre-wrap {
white-space: pre-wrap;
color: var(--n-text-color);
}
}
.highlight pre,
pre {
background-color: #282c34;
}
}
@keyframes blink {
0%, to {
background-color: currentColor
}
50% {
background-color: transparent
}
}
.animate-blink {
animation: blink 1.2s infinite steps(1, start)
}

View File

@ -15,7 +15,7 @@
-->
<script lang="ts" setup>
import Message from './message/Message.vue'
import Message from '@/views/ai/chat/new-chat/message/Message.vue'
import { useProjectSetting } from '@/hooks/setting/useProjectSetting'
import { computed, ref } from 'vue'
import { v4 as uuidv4 } from 'uuid'

View File

@ -1,18 +1,3 @@
<!--
- Copyright (c) 2024 LangChat. TyCoding All Rights Reserved.
-
- Licensed under the GNU Affero General Public License, Version 3 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- https://www.gnu.org/licenses/agpl-3.0.html
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-->
<script lang="ts" setup>
import { ElMessage, ElMessageBox } from 'element-plus'
@ -32,7 +17,7 @@ function handleClear() {
if (chatStore.conversationId == null) {
return
}
ElMessageBox.confirm('确认清除聊天', '清除聊天', {
confirmButtonText: '是',
cancelButtonText: '否',
@ -50,7 +35,7 @@ function handleClear() {
</script>
<template>
<div class="mb-3 flex flex-wrap justify-between items-center">
<div class="mb-10px flex flex-wrap justify-between items-center">
<div class="font-bold flex justify-center items-center flex-wrap gap-2">
<el-icon class="text-lg"><Star /></el-icon>
<span>{{ title }}</span>

View File

@ -0,0 +1,47 @@
<script lang="ts" setup>
import { onMounted, ref } from 'vue';
import Chat from '@/views/ai/chat/new-chat/Chat.vue';
import { getMessages } from '@/api/new-ai/chat';
import { useChatStore } from '@/views/ai/chat/new-chat/store/useChatStore';
import { useUserStore } from '@/store/modules/user';
import Header from './Header.vue';
const loading = ref(true);
const chatStore = useChatStore();
const userStore = useUserStore();
onMounted(async () => {
await fetch();
});
async function fetch() {
loading.value = true;
chatStore.conversationId = userStore.user.id;
chatStore.messages = await getMessages(userStore.user.id);
loading.value = false;
}
</script>
<template>
<div class="p-4 pt-1 chat-card w-full h-full bg-white rounded-xl shadow-xl pt-20px">
<Header title="AI聊天助手" @reload="fetch" />
<main ref="contentRef" class="flex-1 overflow-hidden overflow-y-auto">
<Chat />
</main>
</div>
</template>
<style lang="scss" scoped>
:v-deep(.n-tabs.n-tabs--top .n-tab-pane) {
padding: 0 !important;
}
.chat-card {
box-sizing: border-box;
height: calc(100vh - var(--top-tool-height) - var(--tags-view-height) - var(--app-footer-height) - (var(--app-content-padding) * 3)) !important;
main {
height: calc(100% - 60px);
}
}
</style>

View File

@ -1,18 +1,3 @@
<!--
- Copyright (c) 2024 LangChat. TyCoding All Rights Reserved.
-
- Licensed under the GNU Affero General Public License, Version 3 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- https://www.gnu.org/licenses/agpl-3.0.html
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-->
<script lang="ts" setup>
import { computed, onMounted, onUnmounted, onUpdated, ref } from 'vue'
@ -134,6 +119,6 @@ onUnmounted(() => {
</div>
</template>
<style lang="scss">
@import './styles.scss';
<style lang="scss" scoped>
@import './styles/index.scss';
</style>

View File

@ -1,19 +1,3 @@
/*
* Copyright (c) 2024 LangChat. TyCoding All Rights Reserved.
*
* Licensed under the GNU Affero General Public License, Version 3 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.gnu.org/licenses/agpl-3.0.html
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
html.dark {
.markdown-body {
color-scheme: dark;

View File

@ -0,0 +1,208 @@
html.dark {
pre code.hljs {
display: block;
overflow-x: auto;
padding: 1em;
}
code.hljs {
padding: 3px 5px;
}
.hljs {
color: #abb2bf;
background: #282c34;
}
.hljs-keyword,
.hljs-operator,
.hljs-pattern-match {
color: #f92672;
}
.hljs-function,
.hljs-pattern-match .hljs-constructor {
color: #61aeee;
}
.hljs-function .hljs-params {
color: #a6e22e;
}
.hljs-function .hljs-params .hljs-typing {
color: #fd971f;
}
.hljs-module-access .hljs-module {
color: #7e57c2;
}
.hljs-constructor {
color: #e2b93d;
}
.hljs-constructor .hljs-string {
color: #9ccc65;
}
.hljs-comment,
.hljs-quote {
color: #b18eb1;
font-style: italic;
}
.hljs-doctag,
.hljs-formula {
color: #c678dd;
}
.hljs-deletion,
.hljs-name,
.hljs-section,
.hljs-selector-tag,
.hljs-subst {
color: #e06c75;
}
.hljs-literal {
color: #56b6c2;
}
.hljs-addition,
.hljs-attribute,
.hljs-meta .hljs-string,
.hljs-regexp,
.hljs-string {
color: #98c379;
}
.hljs-built_in,
.hljs-class .hljs-title,
.hljs-title.class_ {
color: #e6c07b;
}
.hljs-attr,
.hljs-number,
.hljs-selector-attr,
.hljs-selector-class,
.hljs-selector-pseudo,
.hljs-template-variable,
.hljs-type,
.hljs-variable {
color: #d19a66;
}
.hljs-bullet,
.hljs-link,
.hljs-meta,
.hljs-selector-id,
.hljs-symbol,
.hljs-title {
color: #61aeee;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: 700;
}
.hljs-link {
text-decoration: underline;
}
}
html {
pre code.hljs {
display: block;
overflow-x: auto;
padding: 1em;
}
code.hljs {
padding: 3px 5px;
&::-webkit-scrollbar {
height: 4px;
}
}
.hljs {
color: #383a42;
background: #fafafa;
}
.hljs-comment,
.hljs-quote {
color: #a0a1a7;
font-style: italic;
}
.hljs-doctag,
.hljs-formula,
.hljs-keyword {
color: #a626a4;
}
.hljs-deletion,
.hljs-name,
.hljs-section,
.hljs-selector-tag,
.hljs-subst {
color: #e45649;
}
.hljs-literal {
color: #0184bb;
}
.hljs-addition,
.hljs-attribute,
.hljs-meta .hljs-string,
.hljs-regexp,
.hljs-string {
color: #50a14f;
}
.hljs-attr,
.hljs-number,
.hljs-selector-attr,
.hljs-selector-class,
.hljs-selector-pseudo,
.hljs-template-variable,
.hljs-type,
.hljs-variable {
color: #986801;
}
.hljs-bullet,
.hljs-link,
.hljs-meta,
.hljs-selector-id,
.hljs-symbol,
.hljs-title {
color: #4078f2;
}
.hljs-built_in,
.hljs-class .hljs-title,
.hljs-title.class_ {
color: #c18401;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: 700;
}
.hljs-link {
text-decoration: underline;
}
}

View File

@ -0,0 +1,3 @@
@import "github-markdown";
@import "highlight";
@import "style";

View File

@ -0,0 +1,89 @@
.markdown-body {
background-color: transparent;
font-size: 14px;
p {
white-space: pre-wrap;
}
ol {
list-style-type: decimal;
}
ul {
list-style-type: disc;
}
pre code,
pre tt {
line-height: 1.65;
}
.highlight pre,
pre {
background-color: #fff;
}
code.hljs {
padding: 0;
}
.code-block {
&-wrapper {
position: relative;
padding-top: 24px;
margin-top: 10px;
}
&-header {
position: absolute;
top: 5px;
right: 0;
width: 100%;
padding: 0 1rem;
display: flex;
justify-content: flex-end;
align-items: center;
color: #b3b3b3;
&__copy {
cursor: pointer;
margin-left: 0.5rem;
user-select: none;
&:hover {
color: #65a665;
}
}
}
}
}
html.dark {
.message-reply {
.whitespace-pre-wrap {
white-space: pre-wrap;
color: var(--n-text-color);
}
}
.highlight pre,
pre {
background-color: #282c34;
}
}
@keyframes blink {
0%, to {
background-color: currentColor;
}
50% {
background-color: transparent;
}
}
.animate-blink {
animation: blink 1.2s infinite steps(1, start);
}

View File

@ -16,7 +16,7 @@
import { defineStore } from 'pinia';
import { formatToDateTime } from '@/utils/dateUtil';
import type { ChatState } from '@/views/ai/chat/store/chat';
import type { ChatState } from '@/views/ai/chat/new-chat/store/chat';
export const useChatStore = defineStore('chat-store', {
state: (): ChatState =>

View File

@ -19,7 +19,7 @@ import { onMounted, ref, toRaw } from 'vue'
import { ModelApi } from '@/api/new-ai/model'
import { LLMProviders } from '@/views/ai/model/chatModel/composables/consts'
import { ModelTypeEnum } from '@/api/models'
import { useChatStore } from '@/views/ai/chat/store/useChatStore'
import { useChatStore } from '@/views/ai/chat/new-chat/store/useChatStore'
const chatStore = useChatStore()
const props = defineProps<{