import type { PersonalAskResponse, PersonalItem, PersonalItemCreated, PersonalItemSourceType, PersonalExportOutline, PersonalExportOutlineSection, PersonalKnowledgeScope, PersonalPage, PersonalPublishRequest, PersonalSession, PersonalSessionDetail, PersonalSpace } from '@/types/api'; import { apiRequest, apiUrl, authHeaders, readTextPayload } from './api'; import { personalItemApiPath, personalSessionApiPath } from './personal-assistant-id'; 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?: string; queryText: string; scope: KnowledgeScope[]; dateFrom?: string; dateTo?: string; itemIds?: string[]; outputFormat?: 'ANSWER' | 'ACTION_PLAN' | 'OUTLINE'; }) => apiRequest({ url: '/api/aihr/personal-assistant/ask', method: 'POST', data: payload, timeout: 45000 }); export const mergePersonalRows = (current: PersonalItem[], incoming: PersonalItem[]) => { const rows = new Map(); [...current, ...incoming].forEach((item) => rows.set(item.id, item)); return Array.from(rows.values()); }; export const loadPersonalSpace = () => apiRequest({ url: '/api/aihr/personal-assistant/space', method: 'GET' }); export const loadPersonalItems = (query: PersonalItemQuery = {}) => apiRequest>({ url: `/api/aihr/personal-assistant/items${queryString(query)}`, method: 'GET' }); export const loadPersonalItem = (id: string) => apiRequest({ url: personalItemApiPath(id), method: 'GET' }); export const createTextItem = (payload: { title?: string; content: string; capturedAt?: string; tags?: string[] }) => apiRequest({ url: '/api/aihr/personal-assistant/items/text', method: 'POST', data: payload }); export const createUrlItem = (payload: { url: string; title?: string; capturedAt?: string }) => apiRequest({ 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((resolve, reject) => { uni.chooseFile({ count: 1, type: 'all', success: (result) => { const files = Array.isArray(result.tempFiles) ? result.tempFiles : []; const file = (files[0] || {}) as Partial; 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((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(response.statusCode, response.data)); } catch (error) { reject(error); } }, fail: () => reject(new Error('文件收藏失败')) }); }); export const retryPersonalItem = (id: string) => apiRequest({ url: personalItemApiPath(id, '/retry'), method: 'POST' }); export const retryPersonalOcrPages = (id: string) => apiRequest({ url: personalItemApiPath(id, '/ocr/retry-failed'), method: 'POST' }); export const deletePersonalItem = (id: string) => apiRequest<{ cleanupJobId: string }>({ url: personalItemApiPath(id), method: 'DELETE', timeout: 15000 }); export const downloadPersonalItem = (id: string) => apiRequest<{ url: string; expiresAt?: string }>({ url: personalItemApiPath(id, '/download-url'), method: 'GET' }); export const loadPersonalSessions = () => apiRequest({ url: '/api/aihr/personal-assistant/sessions', method: 'GET' }); export const loadPersonalSession = (id: string) => apiRequest({ url: personalSessionApiPath(id), method: 'GET' }); export const deletePersonalSession = (id: string) => apiRequest({ url: personalSessionApiPath(id), method: 'DELETE' }); export const createPersonalOutline = (payload: { sessionId: string; title?: string }) => apiRequest({ url: '/api/aihr/personal-assistant/exports/outline', method: 'POST', data: payload }); export const updatePersonalOutline = (id: string, payload: { title: string; sections: PersonalExportOutlineSection[]; }) => apiRequest({ url: `/api/aihr/personal-assistant/exports/${encodeURIComponent(id)}/outline`, method: 'PUT', data: payload }); export const confirmPersonalOutline = (id: string) => apiRequest({ url: `/api/aihr/personal-assistant/exports/${encodeURIComponent(id)}/confirm`, method: 'POST' }); export const loadPersonalExport = (id: string) => apiRequest({ url: `/api/aihr/personal-assistant/exports/${encodeURIComponent(id)}`, method: 'GET' }); export const enqueuePersonalPpt = (id: string) => apiRequest({ url: `/api/aihr/personal-assistant/exports/${encodeURIComponent(id)}/pptx`, method: 'POST', data: { templateCode: 'standard' } }); export const downloadPersonalExport = (id: string) => apiRequest<{ url: string; expiresAt?: string }>({ url: `/api/aihr/personal-assistant/exports/${encodeURIComponent(id)}/download-url`, method: 'GET' }); export const requestPersonalPublish = (itemId: string, reason: string) => apiRequest({ url: `/api/aihr/personal-assistant/items/${encodeURIComponent(itemId)}/publish-requests`, method: 'POST', data: { targetScope: 'POSITION:生活顾问', reason } }); export const loadPersonalPublishRequests = () => apiRequest({ url: '/api/aihr/personal-assistant/publish-requests', method: 'GET' });