fix: 接口对接
This commit is contained in:
parent
11ce542b5d
commit
7ccfc4a10c
8
src/api/chat/index.ts
Normal file
8
src/api/chat/index.ts
Normal 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
221
src/api/chat/types.ts
Normal 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[];
|
||||
}
|
||||
|
||||
/**
|
||||
* ToolCalls,The 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* ToolCallFunction,ToolCall 的 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;
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
import type {
|
||||
ChatSessionVo,
|
||||
CreateSessionDTO,
|
||||
CreateSessionVO,
|
||||
GetSessionListParams,
|
||||
} from './types';
|
||||
import { get, post } from '@/utils/request';
|
||||
@ -10,5 +11,5 @@ export function getSessionList(params: GetSessionListParams) {
|
||||
}
|
||||
|
||||
export function createSession(data: CreateSessionDTO) {
|
||||
return post<null>('/system/session', data);
|
||||
return post<CreateSessionVO>('/system/session', data);
|
||||
}
|
||||
|
||||
@ -136,3 +136,7 @@ export interface CreateSessionDTO {
|
||||
*/
|
||||
userId: number;
|
||||
}
|
||||
|
||||
export interface CreateSessionVO {
|
||||
id: number;
|
||||
}
|
||||
|
||||
@ -1,33 +1,93 @@
|
||||
<script setup lang="ts">
|
||||
import { createSession } from '@/api';
|
||||
import { send } from '@/api/chat';
|
||||
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';
|
||||
|
||||
const route = useRoute();
|
||||
const _router = useRouter();
|
||||
console.log(route.params, '>>>>>>', route.query);
|
||||
const chatId = computed(() => route.params?.id);
|
||||
const router = useRouter();
|
||||
const chatId = computed(() => Number(route.params?.id));
|
||||
const senderValue = ref('');
|
||||
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() {
|
||||
console.log('chatId', chatId.value);
|
||||
console.log('value', senderValue.value);
|
||||
if (!chatId.value) {
|
||||
await createSession({
|
||||
try {
|
||||
const res = await createSession({
|
||||
userId: userStore.userInfo?.userId as number,
|
||||
sessionContent: senderValue.value,
|
||||
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>
|
||||
|
||||
<template>
|
||||
<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>
|
||||
</template>
|
||||
|
||||
33
src/store/modules/chat.ts
Normal file
33
src/store/modules/chat.ts
Normal 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,
|
||||
};
|
||||
});
|
||||
@ -1,10 +1,12 @@
|
||||
import type { LoginUser } from '@/api/auth/types';
|
||||
import { defineStore } from 'pinia';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
export const useUserStore = defineStore(
|
||||
'user',
|
||||
() => {
|
||||
const token = ref<string>();
|
||||
const router = useRouter();
|
||||
const setToken = (value: string) => {
|
||||
token.value = value;
|
||||
};
|
||||
@ -20,9 +22,10 @@ export const useUserStore = defineStore(
|
||||
userInfo.value = void 0;
|
||||
};
|
||||
|
||||
const logout = () => {
|
||||
const logout = async () => {
|
||||
// 如果需要调用接口,可以在这里调用
|
||||
clearToken();
|
||||
router.replace({ name: 'login' });
|
||||
clearUserInfo();
|
||||
};
|
||||
|
||||
|
||||
@ -12,11 +12,11 @@ interface BaseResponse {
|
||||
}
|
||||
|
||||
export const request = hookFetch.create<BaseResponse, 'data' | 'rows'>({
|
||||
baseURL: 'https://web.pandarobot.chat/api',
|
||||
baseURL: import.meta.env.VITE_API_URL,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
plugins: [sseTextDecoderPlugin()],
|
||||
plugins: [sseTextDecoderPlugin({ json: true, prefix: 'data:' })],
|
||||
});
|
||||
|
||||
function jwtPlugin(): HookFetchPlugin<BaseResponse> {
|
||||
@ -29,10 +29,13 @@ function jwtPlugin(): HookFetchPlugin<BaseResponse> {
|
||||
return config;
|
||||
},
|
||||
afterResponse: async (response) => {
|
||||
console.log(response);
|
||||
// console.log(response);
|
||||
if (response.result?.code === 200) {
|
||||
return response;
|
||||
}
|
||||
if (response.result?.code === 401) {
|
||||
userStore.logout();
|
||||
}
|
||||
ElMessage.error(response.result?.msg);
|
||||
return Promise.reject(response);
|
||||
},
|
||||
|
||||
@ -6,6 +6,7 @@ import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
|
||||
import UnoCSS from "unocss/vite";
|
||||
import path from "path";
|
||||
|
||||
// TODO: 开发一个环境变量ts类型处理的插件
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user