feat(work-report): add voice-first reporting flow

This commit is contained in:
2026-07-19 12:17:11 +08:00
parent 24da833fa6
commit 925b48e436
15 changed files with 2813 additions and 451 deletions
+51 -3
View File
@@ -23,6 +23,35 @@ export interface WorkReportAttachment {
fileName: string;
}
export interface WorkReportDraft {
suggestedType: WorkReportType;
title: string;
content: string;
}
export interface OrganizeResponse extends WorkReportDraft {
missingQuestions: string[];
privacyWarnings: string[];
confidence: number;
notice?: string;
}
export const stableWorkReportRequestId = (current: string, create: () => string) => current || create();
export const isDefinitiveWorkReportRejection = (error: { statusCode?: number; bizCode?: number }) => {
const status = Number(error.statusCode || 0);
const bizCode = Number(error.bizCode || 0);
const isDefinitive = (code: number) => code >= 400 && code < 500 && ![408, 409, 425, 429].includes(code);
return isDefinitive(status) || isDefinitive(bizCode);
};
export const isCurrentWorkReportRequest = (
generation: number,
currentGeneration: number,
accountKey: string,
currentAccountKey: string
) => generation === currentGeneration && accountKey === currentAccountKey;
export const workReportTypes: Array<{ value: WorkReportType; label: string; desc: string; icon: string }> = [
{ value: 'CASE', label: '优秀案例', desc: '现场处理得好的真实案例', icon: '⭐' },
{ value: 'VIDEO', label: '操作视频', desc: '值得推广的操作演示视频', icon: '🎬' },
@@ -31,6 +60,7 @@ export const workReportTypes: Array<{ value: WorkReportType; label: string; desc
];
export const submitWorkReport = (params: {
requestId: string;
type: WorkReportType;
title: string;
content: string;
@@ -44,6 +74,19 @@ export const submitWorkReport = (params: {
timeout: 20000
});
export const organizeWorkReport = (params: {
transcript: string;
currentDraft?: WorkReportDraft;
attachmentOssId?: number | string;
attachmentName?: string;
}) =>
apiRequest<OrganizeResponse>({
url: '/api/aihr/work-report/organize',
method: 'POST',
data: params,
timeout: 45000
});
export const listMyWorkReports = () =>
apiRequest<WorkReportRecord[]>({
url: '/api/aihr/work-report/reports/mine',
@@ -66,9 +109,12 @@ export const reviewWorkReport = (id: number, decision: 'APPROVE' | 'REJECT', not
timeout: 20000
});
export const uploadWorkReportAttachment = (filePath: string) =>
export const uploadWorkReportAttachment = (
filePath: string,
onUploadTask?: (task: ReturnType<typeof uni.uploadFile> | null) => void
) =>
new Promise<WorkReportAttachment>((resolve, reject) => {
uni.uploadFile({
const task = uni.uploadFile({
url: apiUrl('/api/aihr/work-report/attachment'),
filePath,
name: 'file',
@@ -80,6 +126,8 @@ export const uploadWorkReportAttachment = (filePath: string) =>
reject(error);
}
},
fail: () => reject(new Error('附件上传失败'))
fail: () => reject(new Error('附件上传失败')),
complete: () => onUploadTask?.(null)
});
onUploadTask?.(task);
});