This commit is contained in:
BBIT-Kai
2026-07-16 09:28:57 +08:00
parent cb9a411c55
commit 7be72a50ad
13 changed files with 3383 additions and 0 deletions
+1
View File
@@ -1,6 +1,7 @@
export * from './bot';
export * from './report';
export * from './report-bot';
export * from './report-cube';
export * from './report-data';
export * from './service';
export * from './service-knowledge';
@@ -0,0 +1,249 @@
import { useAppConfig } from '@vben/hooks';
import { useAccessStore } from '@vben/stores';
import { pyRequestClient } from '#/api/request';
export interface CubeReportScope {
canGlobal: boolean;
companies: Array<{ id: string; name: string }>;
}
export interface CubeReportAppParameters {
fileUpload: Record<string, unknown>;
openingStatement: string;
suggestedQuestions: string[];
suggestedQuestionsAfterAnswer: { enabled: boolean };
systemParameters: Record<string, unknown>;
userInputForm: Array<Record<string, unknown>>;
}
export interface CubeReportSession {
allowGlobal: boolean;
createdAt: null | string;
hasData?: boolean;
id: string;
tenantId: null | string;
tenantName: string;
title: string;
updatedAt: null | string;
}
export interface CubeReportFile {
belongsTo?: 'assistant' | 'user';
id: string;
name: string;
type: string;
}
export interface CubeReportMessage {
content: string;
createdAt: null | string;
difyMessageId: null | string;
files: CubeReportFile[];
id: string;
role: 'assistant' | 'user';
status: 'completed' | 'failed' | 'streaming';
}
export interface CubeReportColumn {
key: string;
title: string;
type: string;
}
export interface CubeReportPage {
columns: CubeReportColumn[];
limitSource?: 'system' | 'user';
page: number;
pageSize: number;
rows: Array<Record<string, unknown>>;
sql?: string;
title?: string;
total: number;
}
export interface CubeReportExportResult {
bucketName: string;
filename: string;
objectName: string;
rowCount: number;
sheetCount: number;
url: string;
}
export type CubeReportStreamEvent =
| { content: string; type: 'message_delta' | 'message_replace' }
| {
conversationId?: string;
hasData: boolean;
type: 'complete';
}
| { message: string; type: 'error' }
| { taskId: string; type: 'task' }
| { text: string; type: 'status' };
export interface SendCubeReportMessage {
allowGlobal: boolean;
content: string;
conversationId?: null | string;
files: CubeReportFile[];
tenantId?: string;
tenantName?: string;
}
function getFetchConfig() {
const { pyApiURL } = useAppConfig(import.meta.env, import.meta.env.PROD);
const accessStore = useAccessStore();
return {
baseURL: pyApiURL.replace(/\/$/, ''),
authorization: accessStore.accessToken
? `Bearer ${accessStore.accessToken}`
: '',
};
}
async function responseError(response: Response) {
const text = await response.text();
try {
const payload = JSON.parse(text) as { detail?: string; message?: string };
return payload.detail || payload.message || text;
} catch {
return text || `请求失败(${response.status}`;
}
}
export async function getCubeReportScope() {
return pyRequestClient.get<CubeReportScope>('/llm/cube-report/scope');
}
export async function getCubeReportAppParameters() {
return pyRequestClient.get<CubeReportAppParameters>(
'/llm/cube-report/app-parameters',
);
}
export async function getCubeReportSessions() {
return pyRequestClient.get<CubeReportSession[]>('/llm/cube-report/sessions');
}
export async function getCubeReportSession(id: string) {
return pyRequestClient.get<{
messages: CubeReportMessage[];
session: CubeReportSession;
}>(`/llm/cube-report/sessions/${id}`);
}
export async function getCubeReportData(
id: string,
params: { page: number; pageSize: number },
) {
return pyRequestClient.get<CubeReportPage>(
`/llm/cube-report/sessions/${id}/data`,
{ params },
);
}
export async function exportCubeReportSession(id: string) {
return pyRequestClient.post<CubeReportExportResult>(
`/llm/cube-report/sessions/${id}/export`,
);
}
export async function renameCubeReportSession(id: string, name: string) {
return pyRequestClient.post<CubeReportSession>(
`/llm/cube-report/sessions/${id}/name`,
{ name },
);
}
export async function deleteCubeReportSession(id: string) {
return pyRequestClient.delete<{ result: string }>(
`/llm/cube-report/sessions/${id}`,
);
}
export async function stopCubeReportTask(taskId: string) {
return pyRequestClient.post<{ result: string }>(
`/llm/cube-report/tasks/${taskId}/stop`,
);
}
export async function uploadCubeReportFile(file: File) {
const { authorization, baseURL } = getFetchConfig();
const form = new FormData();
form.append('file', file);
const response = await fetch(`${baseURL}/llm/cube-report/files/upload`, {
method: 'POST',
headers: { Authorization: authorization },
body: form,
});
if (!response.ok) throw new Error(await responseError(response));
const payload = (await response.json()) as {
data: CubeReportFile;
};
return payload.data;
}
export async function downloadCubeReportFile(
conversationId: string,
file: CubeReportFile,
) {
const { authorization, baseURL } = getFetchConfig();
const params = new URLSearchParams({
conversationId,
asAttachment: 'true',
});
const response = await fetch(
`${baseURL}/llm/cube-report/files/${file.id}/preview?${params}`,
{ headers: { Authorization: authorization } },
);
if (!response.ok) throw new Error(await responseError(response));
const blob = await response.blob();
const url = URL.createObjectURL(blob);
const anchor = document.createElement('a');
anchor.href = url;
anchor.download = file.name;
anchor.click();
URL.revokeObjectURL(url);
}
export async function streamCubeReportMessage(
payload: SendCubeReportMessage,
onEvent: (event: CubeReportStreamEvent) => void,
) {
const { authorization, baseURL } = getFetchConfig();
const response = await fetch(`${baseURL}/llm/cube-report/messages/stream`, {
method: 'POST',
headers: {
Accept: 'text/event-stream',
Authorization: authorization,
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
});
if (!response.ok) throw new Error(await responseError(response));
if (!response.body) throw new Error('当前浏览器不支持流式响应');
const reader = response.body.getReader();
const decoder = new TextDecoder('utf-8');
let buffer = '';
const consumePacket = (packet: string) => {
const data = packet
.split(/\r?\n/)
.filter((line) => line.startsWith('data: '))
.map((line) => line.slice(6))
.join('\n');
if (data) onEvent(JSON.parse(data) as CubeReportStreamEvent);
};
while (true) {
const { done, value } = await reader.read();
buffer += decoder.decode(value, { stream: !done });
const packets = buffer.split(/\r?\n\r?\n/);
buffer = packets.pop() ?? '';
packets.forEach((packet) => consumePacket(packet));
if (done) break;
}
if (buffer.trim()) consumePacket(buffer);
}