fix: 接口对接

This commit is contained in:
Json_Lee 2025-05-12 20:13:09 +08:00
parent 11ce542b5d
commit 7ccfc4a10c
10 changed files with 355 additions and 20 deletions

1
.env Normal file
View File

@ -0,0 +1 @@
VITE_API_URL = https://web.pandarobot.chat/api

8
src/api/chat/index.ts Normal file
View File

@ -0,0 +1,8 @@
import type { ChatMessageVo, GetChatListParams, SendDTO } from './types';
import { get, post } from '@/utils/request';
export const send = (data: SendDTO) => post<null>('/chat/send', data).stream();
export function getChatList(params: GetChatListParams) {
return get<ChatMessageVo[]>('/system/message/list', params);
}

221
src/api/chat/types.ts Normal file
View File

@ -0,0 +1,221 @@
/**
* ChatRequest
*/
export interface SendDTO {
/**
* ID
*/
appId?: string;
/**
*
*/
contentNumber?: number;
/**
* mcp
*/
isMcp?: boolean;
/**
* id
*/
kid?: string;
messages: Message[];
model: string;
/**
*
*/
prompt?: string;
/**
* (0 1)
*/
search?: boolean;
/**
* id
*/
sessionId?: number;
/**
*
*/
stream?: boolean;
/**
*
*/
sysPrompt?: string;
/**
* id
*/
userId?: number;
/**
*
*/
usingContext?: boolean;
}
/**
* Message
*/
export interface Message {
content?: string;
name?: string;
reasoning_content?: string;
/**
*
* https://platform.openai.com/docs/guides/chat/introduction
*/
role?: 'system' | 'user' | 'assistant' | 'function' | 'tool';
tool_call_id?: string;
/**
* The tool calls generated by the model, such as function calls.
*/
tool_calls?: ToolCalls[];
}
/**
* ToolCallsThe tool calls generated by the model, such as function calls.
*/
export interface ToolCalls {
function?: ToolCallFunction;
/**
* The ID of the tool call.
*/
id?: string;
/**
* The type of the tool. Currently, only function is supported.
*/
type?: string;
}
/**
* ToolCallFunctionToolCall Function参数
* The function that the model called.
*/
export interface ToolCallFunction {
/**
*
*/
arguments?: string;
/**
*
*/
name?: string;
}
export interface GetChatListParams {
/**
*
*/
content?: string;
/**
*
*/
createBy?: number;
/**
*
*/
createDept?: number;
/**
*
*/
createTime?: Date;
/**
*
*/
deductCost?: number;
/**
*
*/
id?: number;
/**
* desc或者asc
*/
isAsc?: string;
/**
*
*/
modelName?: string;
/**
*
*/
orderByColumn?: string;
/**
*
*/
pageNum?: number;
/**
*
*/
pageSize?: number;
/**
*
*/
params?: { [key: string]: { [key: string]: any } };
/**
*
*/
remark?: string;
/**
*
*/
role?: string;
/**
* id
*/
sessionId?: number;
/**
* Tokens
*/
totalTokens?: number;
/**
*
*/
updateBy?: number;
/**
*
*/
updateTime?: Date;
/**
* id
*/
userId?: number;
}
/**
* ChatMessageVo chat_message
*/
export interface ChatMessageVo {
/**
*
*/
content?: string;
/**
*
*/
deductCost?: number;
/**
*
*/
id?: number;
/**
*
*/
modelName?: string;
/**
*
*/
remark?: string;
/**
*
*/
role?: string;
/**
* id
*/
sessionId?: number;
/**
* Tokens
*/
totalTokens?: number;
/**
* id
*/
userId?: number;
}

View File

@ -1,6 +1,7 @@
import type { import type {
ChatSessionVo, ChatSessionVo,
CreateSessionDTO, CreateSessionDTO,
CreateSessionVO,
GetSessionListParams, GetSessionListParams,
} from './types'; } from './types';
import { get, post } from '@/utils/request'; import { get, post } from '@/utils/request';
@ -10,5 +11,5 @@ export function getSessionList(params: GetSessionListParams) {
} }
export function createSession(data: CreateSessionDTO) { export function createSession(data: CreateSessionDTO) {
return post<null>('/system/session', data); return post<CreateSessionVO>('/system/session', data);
} }

View File

@ -136,3 +136,7 @@ export interface CreateSessionDTO {
*/ */
userId: number; userId: number;
} }
export interface CreateSessionVO {
id: number;
}

View File

@ -1,33 +1,93 @@
<script setup lang="ts"> <script setup lang="ts">
import { createSession } from '@/api'; import { createSession } from '@/api';
import { send } from '@/api/chat';
import { useUserStore } from '@/store'; import { useUserStore } from '@/store';
import { Sender } from 'vue-element-plus-x'; import { useChatStore } from '@/store/modules/chat';
import { BubbleList, Sender } from 'vue-element-plus-x';
import { useRoute, useRouter } from 'vue-router'; import { useRoute, useRouter } from 'vue-router';
const route = useRoute(); const route = useRoute();
const _router = useRouter(); const router = useRouter();
console.log(route.params, '>>>>>>', route.query); const chatId = computed(() => Number(route.params?.id));
const chatId = computed(() => route.params?.id);
const senderValue = ref(''); const senderValue = ref('');
const userStore = useUserStore(); const userStore = useUserStore();
const chatStore = useChatStore();
const chatList = computed(() => chatStore.chatMap[chatId.value] ?? []);
if (chatId.value) {
chatStore.requestChatList(chatId.value);
}
watch(
() => route.params?.id,
(_id_) => {
if (_id_) {
chatStore.requestChatList(Number(_id_));
const v = localStorage.getItem('chatContent');
if (v) {
senderValue.value = v;
localStorage.removeItem('chatContent');
//
console.log(v);
}
}
},
);
// const a = JSON.parse(`{"id":"chatcmpl-BVD1f4snw4KHOCKIgu4JOMoZbOwRh","object":"chat.completion.chunk","created":1746777939,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_ded0d14823","choices":[{"delta":{"content":"","role":"assistant"},"logprobs":null,"finish_reason":null,"index":0}],"usage":null}`)
// console.log(a);
const loading = ref(false);
async function handleSend() { async function handleSend() {
console.log('chatId', chatId.value);
console.log('value', senderValue.value);
if (!chatId.value) { if (!chatId.value) {
await createSession({ try {
userId: userStore.userInfo?.userId as number, const res = await createSession({
sessionContent: senderValue.value, userId: userStore.userInfo?.userId as number,
sessionTitle: senderValue.value.slice(0, 10), sessionContent: senderValue.value,
remark: senderValue.value.slice(0, 10), sessionTitle: senderValue.value.slice(0, 10),
}); remark: senderValue.value.slice(0, 10),
// (query-sendValue) });
// router.replace(`${}`) localStorage.setItem('chatContent', senderValue.value);
router.replace({
name: 'chat',
params: {
id: res.data.id,
},
});
}
catch (error) {
console.error('createSessionError', error);
}
return;
} }
//
loading.value = true;
const req = send({
sessionId: chatId.value,
model: 'gpt-4o-mini',
messages: [
{
role: 'user',
content: senderValue.value,
},
],
});
for await (const chunk of req) {
if (chunk.result && typeof chunk.result === 'string') {
console.log('string:', chunk.result);
// const a = JSON.parse(chunk.result);
// console.log(a,'>>>');
}
console.log(chunk.result);
}
loading.value = false;
} }
</script> </script>
<template> <template>
<div> <div>
<Sender v-model="senderValue" @submit="handleSend" /> <BubbleList :list="chatList">
<template #content="{ item }">
{{ item.content }}
</template>
</BubbleList>
<Sender v-model="senderValue" :loading="loading" @submit="handleSend" />
</div> </div>
</template> </template>

33
src/store/modules/chat.ts Normal file
View File

@ -0,0 +1,33 @@
import type { ChatMessageVo } from '@/api/chat/types';
import { getChatList } from '@/api/chat';
import { defineStore } from 'pinia';
import { useUserStore } from './user';
export const useChatStore = defineStore('chat', () => {
const userStore = useUserStore();
const chatMap = ref<Record<number, ChatMessageVo[]>>({});
const setChatMap = (id: number, data: ChatMessageVo[]) => {
chatMap.value[id] = data;
};
const requestChatList = async (sessionId: number) => {
try {
const res = await getChatList({
sessionId,
userId: userStore.userInfo?.userId as number,
});
if (res.rows) {
setChatMap(sessionId, res.rows);
}
}
catch (error) {
console.error('getChatList:', error);
}
};
return {
chatMap,
requestChatList,
};
});

View File

@ -1,10 +1,12 @@
import type { LoginUser } from '@/api/auth/types'; import type { LoginUser } from '@/api/auth/types';
import { defineStore } from 'pinia'; import { defineStore } from 'pinia';
import { useRouter } from 'vue-router';
export const useUserStore = defineStore( export const useUserStore = defineStore(
'user', 'user',
() => { () => {
const token = ref<string>(); const token = ref<string>();
const router = useRouter();
const setToken = (value: string) => { const setToken = (value: string) => {
token.value = value; token.value = value;
}; };
@ -20,9 +22,10 @@ export const useUserStore = defineStore(
userInfo.value = void 0; userInfo.value = void 0;
}; };
const logout = () => { const logout = async () => {
// 如果需要调用接口,可以在这里调用 // 如果需要调用接口,可以在这里调用
clearToken(); clearToken();
router.replace({ name: 'login' });
clearUserInfo(); clearUserInfo();
}; };

View File

@ -12,11 +12,11 @@ interface BaseResponse {
} }
export const request = hookFetch.create<BaseResponse, 'data' | 'rows'>({ export const request = hookFetch.create<BaseResponse, 'data' | 'rows'>({
baseURL: 'https://web.pandarobot.chat/api', baseURL: import.meta.env.VITE_API_URL,
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}, },
plugins: [sseTextDecoderPlugin()], plugins: [sseTextDecoderPlugin({ json: true, prefix: 'data:' })],
}); });
function jwtPlugin(): HookFetchPlugin<BaseResponse> { function jwtPlugin(): HookFetchPlugin<BaseResponse> {
@ -29,10 +29,13 @@ function jwtPlugin(): HookFetchPlugin<BaseResponse> {
return config; return config;
}, },
afterResponse: async (response) => { afterResponse: async (response) => {
console.log(response); // console.log(response);
if (response.result?.code === 200) { if (response.result?.code === 200) {
return response; return response;
} }
if (response.result?.code === 401) {
userStore.logout();
}
ElMessage.error(response.result?.msg); ElMessage.error(response.result?.msg);
return Promise.reject(response); return Promise.reject(response);
}, },

View File

@ -6,6 +6,7 @@ import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
import UnoCSS from "unocss/vite"; import UnoCSS from "unocss/vite";
import path from "path"; import path from "path";
// TODO: 开发一个环境变量ts类型处理的插件
// https://vite.dev/config/ // https://vite.dev/config/
export default defineConfig({ export default defineConfig({
plugins: [ plugins: [