Files
prop-ai-hr/mobile-uni/src/services/practice.ts
T

311 lines
8.5 KiB
TypeScript

import type {
PracticeFinishResponse,
PracticeHelpEvent,
PracticePrepCard,
PracticeRecord,
PracticeMistake,
PracticeTeamSnapshot,
PracticeStartResponse,
PracticeTurnResponse,
CompetencyProfile,
ReviewAdviceRequest,
ReviewDetail,
PracticeAssignment,
OnboardTask,
QualificationSummary,
PracticeAssignmentRequest,
PracticeAssignmentBatchRequest,
PracticeAssignmentBatchResponse,
DailyDrillAnswerResponse,
PracticeAlert,
PromotionEvidence,
PracticeScenarioOption,
PracticeDifficulty,
PracticeQuestionFeedback
} from '@/types/api';
import { apiRequest } from './api';
import { getAuth, getSelectedPosition } from './auth';
const defaultScenarioId = 'complaint-water';
const currentExtPartyId = () => {
const phone = getAuth().phone.trim();
if (!phone) {
throw new Error('请先登录后再查看训练数据');
}
return phone;
};
export const getPracticePrepCard = (scenarioId = defaultScenarioId) =>
apiRequest<PracticePrepCard>({
url: `/api/train/practice/scenarios/${encodeURIComponent(scenarioId)}/prep-card`,
method: 'GET',
timeout: 15000
});
export const recordPracticeHelp = (sessionId: string, roundIndex: number) =>
apiRequest<PracticeHelpEvent>({
url: `/api/train/practice/sessions/${encodeURIComponent(sessionId)}/help`,
method: 'POST',
data: { roundIndex },
timeout: 15000
});
export const getPracticeScenarios = (position = getSelectedPosition()) =>
apiRequest<PracticeScenarioOption[]>({
url: `/api/train/practice/scenarios?position=${encodeURIComponent(position || '生活顾问')}`,
method: 'GET',
timeout: 15000
});
export const startPractice = (scenarioId = defaultScenarioId, assignmentId?: number) =>
apiRequest<PracticeStartResponse>({
url: '/api/train/practice/start',
method: 'POST',
data: {
extPartyId: currentExtPartyId(),
scenarioId,
position: getSelectedPosition(),
mode: 'mobile',
assignmentId
},
timeout: 30000
});
export const submitPracticeTurn = (params: {
sessionId: string;
roundIndex: number;
traineeText: string;
traineeAudioUrl?: string;
traineeAudioOssId?: number | string;
regenerate?: boolean;
style?: string;
suggestReply?: boolean;
}) =>
apiRequest<PracticeTurnResponse>({
url: '/api/train/practice/turn',
method: 'POST',
data: params,
timeout: 45000
});
export const finishPractice = (sessionId: string, assignmentId?: number) =>
apiRequest<PracticeFinishResponse>({
url: '/api/train/practice/finish',
method: 'POST',
data: { sessionId, assignmentId },
timeout: 45000
});
export const submitPracticeSatisfaction = (sessionId: string, score: number, comment = '') =>
apiRequest<{ sessionId: string; score: number; comment: string; submittedAt: string }>({
url: '/api/aihr/mobile/practice/satisfaction',
method: 'POST',
data: { sessionId, score, comment },
timeout: 15000
});
export const getPracticeHistory = () => {
const extPartyId = encodeURIComponent(currentExtPartyId());
return apiRequest<PracticeRecord[]>({
url: `/api/aihr/mobile/practice/history?extPartyId=${extPartyId}`,
method: 'GET',
timeout: 15000
});
};
export const getPracticeHistoryDetail = (id: number) =>
apiRequest<ReviewDetail>({
url: `/api/aihr/mobile/practice/history/${id}`,
method: 'GET',
timeout: 15000
});
export const getPracticeMistakes = () => {
const extPartyId = encodeURIComponent(currentExtPartyId());
return apiRequest<PracticeMistake[]>({
url: `/api/aihr/mobile/practice/mistakes?extPartyId=${extPartyId}`,
method: 'GET',
timeout: 15000
});
};
export const getCompetencyProfile = () => {
const extPartyId = encodeURIComponent(currentExtPartyId());
return apiRequest<CompetencyProfile>({
url: `/api/aihr/mobile/profile?extPartyId=${extPartyId}`,
method: 'GET',
timeout: 15000
});
};
export const getPromotionEvidence = () => {
const extPartyId = encodeURIComponent(currentExtPartyId());
return apiRequest<PromotionEvidence>({
url: `/api/aihr/mobile/profile/promotion-evidence?extPartyId=${extPartyId}`,
method: 'GET',
timeout: 15000
});
};
export const getPracticeReviews = () =>
apiRequest<PracticeRecord[]>({
url: '/api/aihr/mobile/practice/reviews',
method: 'GET',
timeout: 15000
});
export const getPracticeTeamSnapshot = (includeProfiles = false) =>
apiRequest<PracticeTeamSnapshot>({
url: includeProfiles
? '/api/aihr/mobile/practice/team?includeProfiles=true'
: '/api/aihr/mobile/practice/team',
method: 'GET',
timeout: 15000
});
export const getPracticeReviewDetail = (id: number) =>
apiRequest<ReviewDetail>({
url: `/api/aihr/mobile/practice/reviews/${id}`,
method: 'GET',
timeout: 15000
});
export const markPracticeReviewed = (id: number, data: ReviewAdviceRequest) =>
apiRequest<void>({
url: `/api/aihr/mobile/practice/reviews/${id}/reviewed`,
method: 'POST',
data,
timeout: 15000
});
export const getPracticeAssignments = (ownOnly = false) => {
const extPartyId = ownOnly ? encodeURIComponent(currentExtPartyId()) : '';
return apiRequest<PracticeAssignment[]>({
url: `/api/aihr/mobile/practice/assignments${ownOnly ? `?extPartyId=${extPartyId}` : ''}`,
method: 'GET',
timeout: 15000
});
};
export const getOnboardTasks = () =>
apiRequest<OnboardTask[]>({
url: '/api/aihr/mobile/onboard/tasks',
method: 'GET',
timeout: 15000
});
export const completeOnboardTask = (id: number, evidenceRef?: string) =>
apiRequest<void>({
url: `/api/aihr/mobile/onboard/tasks/${id}/complete`,
method: 'POST',
data: evidenceRef ? { evidenceRef } : {},
timeout: 15000
});
export const reportOnboardProgress = (id: number, data: {
progressPercent?: number;
positionSeconds?: number;
durationSeconds?: number;
materialVersion?: string | null;
completed?: boolean;
}) =>
apiRequest<void>({
url: `/api/aihr/mobile/onboard/tasks/${id}/progress`,
method: 'POST',
data,
timeout: 15000
});
export const getQualification = () =>
apiRequest<QualificationSummary>({
url: '/api/aihr/mobile/qualification',
method: 'GET',
timeout: 15000
});
export const createPracticeAssignment = (data: PracticeAssignmentRequest) =>
apiRequest<PracticeAssignment>({
url: '/api/aihr/mobile/practice/assignments',
method: 'POST',
data: {
source: 'manual',
scenarioId: 'fee-parking',
...data
},
timeout: 15000
});
export const createPracticeAssignmentsBatch = (data: PracticeAssignmentBatchRequest) =>
apiRequest<PracticeAssignmentBatchResponse>({
url: '/api/aihr/mobile/practice/assignments/batch',
method: 'POST',
data,
timeout: 30000
});
export const answerDailyDrill = (id: number, answer: string, audioUrl?: string, audioOssId?: number | string) =>
apiRequest<DailyDrillAnswerResponse>({
url: `/api/aihr/mobile/practice/assignments/${id}/answer`,
method: 'POST',
data: { answer, audioUrl, audioOssId },
timeout: 15000
});
export const getPracticeAlerts = () =>
apiRequest<PracticeAlert[]>({
url: '/api/aihr/mobile/practice/alerts',
method: 'GET',
timeout: 15000
});
export const submitPracticeQuestionFeedback = (
assignmentId: number,
verdict: PracticeQuestionFeedback['verdict'],
comment = ''
) =>
apiRequest<PracticeQuestionFeedback>({
url: `/api/aihr/mobile/practice/assignments/${assignmentId}/feedback`,
method: 'POST',
data: { verdict, comment },
timeout: 15000
});
export const getPracticeDifficulties = async (windowDays = 30, position = ''): Promise<PracticeDifficulty[]> => {
const rows = await apiRequest<Array<{
scenarioId: string;
scenarioName: string;
position?: string;
attempts: number;
mistakeCount: number;
affectedPeople: number;
averageScore: number;
difficultyScore: number;
latestTime: string;
}>>({
url: `/api/aihr/mobile/practice/difficulties?windowDays=${windowDays}${position ? `&position=${encodeURIComponent(position)}` : ''}`,
method: 'GET',
timeout: 15000
});
return rows.map((item) => ({
...item,
cause: item.mistakeCount >= Math.max(2, Math.ceil(item.attempts / 2)) ? '高频错题或低分' : '近期低分记录',
count: item.mistakeCount
}));
};
export const assignPracticeDifficulty = (data: {
scenarioId: string;
cause: string;
dueDate: string;
requestId: string;
windowDays: number;
position?: string;
}) =>
apiRequest<PracticeAssignmentBatchResponse>({
url: '/api/aihr/mobile/practice/difficulties/assign',
method: 'POST',
data,
timeout: 30000
});