feat(mobile): add personal assistant knowledge flow

This commit is contained in:
2026-07-12 11:57:02 +08:00
parent e66db3e432
commit c8ef15ee9e
10 changed files with 825 additions and 0 deletions
@@ -0,0 +1,155 @@
import type {
PersonalAskResponse,
PersonalItem,
PersonalItemCreated,
PersonalItemSourceType,
PersonalKnowledgeScope,
PersonalPage,
PersonalSession,
PersonalSessionDetail,
PersonalSpace
} from '@/types/api';
import { apiRequest, apiUrl, authHeaders, readTextPayload } from './api';
export type KnowledgeScope = PersonalKnowledgeScope;
export interface PersonalItemQuery {
pageNum?: number;
pageSize?: number;
status?: string;
sourceType?: PersonalItemSourceType | '';
dateFrom?: string;
dateTo?: string;
keyword?: string;
}
const queryString = (query: PersonalItemQuery) => {
const params = Object.entries(query)
.filter(([, value]) => value !== undefined && value !== '')
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);
return params.length ? `?${params.join('&')}` : '';
};
export const askPersonalAssistant = (payload: {
sessionId?: number;
queryText: string;
scope: KnowledgeScope[];
dateFrom?: string;
dateTo?: string;
itemIds?: number[];
outputFormat?: 'ANSWER' | 'ACTION_PLAN' | 'OUTLINE';
}) => apiRequest<PersonalAskResponse>({
url: '/api/aihr/personal-assistant/ask',
method: 'POST',
data: payload,
timeout: 45000,
clearAuthOnUnauthorized: false
});
export const loadPersonalSpace = () => apiRequest<PersonalSpace>({
url: '/api/aihr/personal-assistant/space',
method: 'GET'
});
export const loadPersonalItems = (query: PersonalItemQuery = {}) => apiRequest<PersonalPage<PersonalItem>>({
url: `/api/aihr/personal-assistant/items${queryString(query)}`,
method: 'GET'
});
export const loadPersonalItem = (id: number) => apiRequest<PersonalItem>({
url: `/api/aihr/personal-assistant/items/${id}`,
method: 'GET'
});
export const createTextItem = (payload: { title?: string; content: string; capturedAt?: string; tags?: string[] }) =>
apiRequest<PersonalItemCreated>({
url: '/api/aihr/personal-assistant/items/text',
method: 'POST',
data: payload
});
export const createUrlItem = (payload: { url: string; title?: string; capturedAt?: string }) =>
apiRequest<PersonalItemCreated>({
url: '/api/aihr/personal-assistant/items/url',
method: 'POST',
data: payload,
timeout: 45000
});
export interface PersonalSelectedFile {
path: string;
name: string;
size: number;
}
export const choosePersonalFile = () => new Promise<PersonalSelectedFile>((resolve, reject) => {
uni.chooseFile({
count: 1,
type: 'all',
success: (result) => {
const files = Array.isArray(result.tempFiles) ? result.tempFiles : [];
const file = (files[0] || {}) as Partial<PersonalSelectedFile>;
const path = file.path || result.tempFilePaths?.[0] || '';
if (!path) {
reject(new Error('未获取到文件路径'));
return;
}
resolve({ path, name: file.name || path.split('/').pop() || 'personal-file', size: Number(file.size || 0) });
},
fail: () => reject(new Error('未选择文件'))
});
});
export const uploadPersonalFile = (file: PersonalSelectedFile, title?: string, capturedAt?: string) =>
new Promise<PersonalItemCreated>((resolve, reject) => {
uni.uploadFile({
url: apiUrl('/api/aihr/personal-assistant/items/file'),
filePath: file.path,
name: 'file',
header: authHeaders(false),
formData: {
...(title?.trim() ? { title: title.trim() } : {}),
...(capturedAt ? { capturedAt } : {})
},
timeout: 45000,
success: (response) => {
try {
resolve(readTextPayload<PersonalItemCreated>(response.statusCode, response.data));
} catch (error) {
reject(error);
}
},
fail: () => reject(new Error('文件收藏失败'))
});
});
export const retryPersonalItem = (id: number) => apiRequest<PersonalItem>({
url: `/api/aihr/personal-assistant/items/${id}/retry`,
method: 'POST'
});
export const deletePersonalItem = (id: number) => apiRequest<{ cleanupJobId: number }>({
url: `/api/aihr/personal-assistant/items/${id}`,
method: 'DELETE',
timeout: 15000
});
export const downloadPersonalItem = (id: number) => apiRequest<{ url: string; expiresAt?: string }>({
url: `/api/aihr/personal-assistant/items/${id}/download-url`,
method: 'GET'
});
export const loadPersonalSessions = () => apiRequest<PersonalSession[]>({
url: '/api/aihr/personal-assistant/sessions',
method: 'GET'
});
export const loadPersonalSession = (id: number) => apiRequest<PersonalSessionDetail>({
url: `/api/aihr/personal-assistant/sessions/${id}`,
method: 'GET'
});
export const deletePersonalSession = (id: number) => apiRequest<void>({
url: `/api/aihr/personal-assistant/sessions/${id}`,
method: 'DELETE'
});