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 {
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -136,3 +136,7 @@ export interface CreateSessionDTO {
|
|||||||
*/
|
*/
|
||||||
userId: number;
|
userId: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface CreateSessionVO {
|
||||||
|
id: number;
|
||||||
|
}
|
||||||
|
|||||||
@ -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
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 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();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
},
|
},
|
||||||
|
|||||||
@ -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: [
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user