157 lines
4.5 KiB
TypeScript
157 lines
4.5 KiB
TypeScript
import { apiRequest, apiUrl, authHeaders, readTextPayload } from './api';
|
|
|
|
export type WorkReportType = 'CASE' | 'VIDEO' | 'SOP' | 'KNOWLEDGE';
|
|
|
|
export interface WorkReportRecord {
|
|
id: number;
|
|
type: WorkReportType;
|
|
typeLabel: string;
|
|
title: string;
|
|
content: string;
|
|
attachmentName?: string;
|
|
attachmentOssId?: number | string;
|
|
status: 'PENDING' | 'APPROVED' | 'REJECTED';
|
|
statusLabel: string;
|
|
submitterName: string;
|
|
reviewNote?: string;
|
|
createdAt: string;
|
|
reviewedAt?: string;
|
|
}
|
|
|
|
export interface WorkReportAttachment {
|
|
ossId: number | string;
|
|
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 prepareWorkReportOrganizeInput = (
|
|
transcript: string,
|
|
currentDraft?: WorkReportDraft
|
|
): { transcript: string; currentDraft?: WorkReportDraft } => {
|
|
const addition = transcript.trim();
|
|
if (!currentDraft) return { transcript: addition };
|
|
|
|
const currentContent = currentDraft.content.trim();
|
|
const content = !currentContent
|
|
? addition
|
|
: !addition || currentContent === addition
|
|
? currentContent
|
|
: `${currentContent}\n${addition}`;
|
|
|
|
return {
|
|
transcript: '',
|
|
currentDraft: {
|
|
...currentDraft,
|
|
content
|
|
}
|
|
};
|
|
};
|
|
|
|
export const workReportTypes: Array<{ value: WorkReportType; label: string; desc: string; icon: string }> = [
|
|
{ value: 'CASE', label: '优秀案例', desc: '现场处理得好的真实案例', icon: '⭐' },
|
|
{ value: 'VIDEO', label: '操作视频', desc: '值得推广的操作演示视频', icon: '🎬' },
|
|
{ value: 'SOP', label: '完整SOP', desc: '整理好的完整工作流程', icon: '📋' },
|
|
{ value: 'KNOWLEDGE', label: '有用知识', desc: '对工作有帮助的经验知识', icon: '💡' }
|
|
];
|
|
|
|
export const submitWorkReport = (params: {
|
|
requestId: string;
|
|
type: WorkReportType;
|
|
title: string;
|
|
content: string;
|
|
attachmentOssId?: number | string;
|
|
attachmentName?: string;
|
|
}) =>
|
|
apiRequest<WorkReportRecord>({
|
|
url: '/api/aihr/work-report/reports',
|
|
method: 'POST',
|
|
data: 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',
|
|
method: 'GET',
|
|
timeout: 15000
|
|
});
|
|
|
|
export const listReviewWorkReports = (status = '') =>
|
|
apiRequest<WorkReportRecord[]>({
|
|
url: `/api/aihr/work-report/reports${status ? `?status=${encodeURIComponent(status)}` : ''}`,
|
|
method: 'GET',
|
|
timeout: 15000
|
|
});
|
|
|
|
export const reviewWorkReport = (id: number, decision: 'APPROVE' | 'REJECT', note = '') =>
|
|
apiRequest<WorkReportRecord>({
|
|
url: `/api/aihr/work-report/reports/${id}/review`,
|
|
method: 'POST',
|
|
data: { decision, note },
|
|
timeout: 20000
|
|
});
|
|
|
|
export const uploadWorkReportAttachment = (
|
|
filePath: string,
|
|
onUploadTask?: (task: ReturnType<typeof uni.uploadFile> | null) => void
|
|
) =>
|
|
new Promise<WorkReportAttachment>((resolve, reject) => {
|
|
const task = uni.uploadFile({
|
|
url: apiUrl('/api/aihr/work-report/attachment'),
|
|
filePath,
|
|
name: 'file',
|
|
header: authHeaders(false),
|
|
success: (response) => {
|
|
try {
|
|
resolve(readTextPayload<WorkReportAttachment>(response.statusCode, response.data));
|
|
} catch (error) {
|
|
reject(error);
|
|
}
|
|
},
|
|
fail: () => reject(new Error('附件上传失败')),
|
|
complete: () => onUploadTask?.(null)
|
|
});
|
|
onUploadTask?.(task);
|
|
});
|