|
|
@@ -155,7 +155,11 @@ const assignment = (id: string, channel: Channel, kind: AssignmentKind, audience |
|
|
executionMode: kind === 'FORMAL_EXAM' ? 'EXAM' : 'PRACTICE', audienceType, collaborationMode, |
|
|
executionMode: kind === 'FORMAL_EXAM' ? 'EXAM' : 'PRACTICE', audienceType, collaborationMode, |
|
|
contentProjectId: 'training-project-1', contentVersionId: 'training-version-1', |
|
|
contentProjectId: 'training-project-1', contentVersionId: 'training-version-1', |
|
|
definitionSnapshot: twoStepDefinition(channel), definitionChecksum: `checksum-${id}`, |
|
|
definitionSnapshot: twoStepDefinition(channel), definitionChecksum: `checksum-${id}`, |
|
|
digitalHumanAllowed: kind !== 'FORMAL_EXAM', ownerUserId: '2', ownerUsername: 'teacher', ownerName: '周教员', |
|
|
|
|
|
|
|
|
digitalHumanAllowed: kind !== 'FORMAL_EXAM', |
|
|
|
|
|
digitalInstructorAgentSlug: channel === 'VIRTUAL' && kind !== 'FORMAL_EXAM' ? 'demo-equipment-instructor' : '', |
|
|
|
|
|
digitalInstructorAgentName: channel === 'VIRTUAL' && kind !== 'FORMAL_EXAM' ? '装备维修虚拟教员' : '', |
|
|
|
|
|
digitalInstructorKnowledgeSource: 'AGENT', |
|
|
|
|
|
ownerUserId: '2', ownerUsername: 'teacher', ownerName: '周教员', |
|
|
departmentId: '110', departmentName: '维修教研室', status: 'PUBLISHED', |
|
|
departmentId: '110', departmentName: '维修教研室', status: 'PUBLISHED', |
|
|
scheduleStartAt: 1786383600, dueAt: 1786473600, publishedAt: 1786380000, |
|
|
scheduleStartAt: 1786383600, dueAt: 1786473600, publishedAt: 1786380000, |
|
|
withdrawnAt: null, archivedAt: null, lifecycleReason: '', version: 3, |
|
|
withdrawnAt: null, archivedAt: null, lifecycleReason: '', version: 3, |
|
|
@@ -171,7 +175,11 @@ const assignment = (id: string, channel: Channel, kind: AssignmentKind, audience |
|
|
const assignmentBrief = (item: JsonRecord) => ({ |
|
|
const assignmentBrief = (item: JsonRecord) => ({ |
|
|
id: item.id, code: item.code, name: item.name, channel: item.channel, assignmentKind: item.assignmentKind, |
|
|
id: item.id, code: item.code, name: item.name, channel: item.channel, assignmentKind: item.assignmentKind, |
|
|
executionMode: item.executionMode, audienceType: item.audienceType, collaborationMode: item.collaborationMode, |
|
|
executionMode: item.executionMode, audienceType: item.audienceType, collaborationMode: item.collaborationMode, |
|
|
digitalHumanAllowed: item.digitalHumanAllowed, status: item.status, |
|
|
|
|
|
|
|
|
digitalHumanAllowed: item.digitalHumanAllowed, |
|
|
|
|
|
digitalInstructorAgentSlug: item.digitalInstructorAgentSlug, |
|
|
|
|
|
digitalInstructorAgentName: item.digitalInstructorAgentName, |
|
|
|
|
|
digitalInstructorKnowledgeSource: item.digitalInstructorKnowledgeSource, |
|
|
|
|
|
status: item.status, |
|
|
scheduleStartAt: item.scheduleStartAt, dueAt: item.dueAt, serverNow: item.serverNow, |
|
|
scheduleStartAt: item.scheduleStartAt, dueAt: item.dueAt, serverNow: item.serverNow, |
|
|
}) |
|
|
}) |
|
|
|
|
|
|
|
|
@@ -232,6 +240,9 @@ export class TeachingContractMock { |
|
|
name: '支腿液压缸中修训练(虚拟仿真)', |
|
|
name: '支腿液压缸中修训练(虚拟仿真)', |
|
|
description: '面向液压密封件检查与更换的八步虚拟训练任务。', |
|
|
description: '面向液压密封件检查与更换的八步虚拟训练任务。', |
|
|
definitionSnapshot: virtualPreviewDefinition(), |
|
|
definitionSnapshot: virtualPreviewDefinition(), |
|
|
|
|
|
digitalInstructorAgentSlug: 'demo-equipment-instructor', |
|
|
|
|
|
digitalInstructorAgentName: '装备维修虚拟教员', |
|
|
|
|
|
digitalInstructorKnowledgeSource: 'WORKSHOP', |
|
|
runCount: 0, |
|
|
runCount: 0, |
|
|
pendingReviewCount: 0, |
|
|
pendingReviewCount: 0, |
|
|
listed: false, |
|
|
listed: false, |
|
|
@@ -454,7 +465,7 @@ export class TeachingContractMock { |
|
|
await page.route('**/api/tran/v1/content/catalog**', (route) => fulfill(route, pageResult([{ |
|
|
await page.route('**/api/tran/v1/content/catalog**', (route) => fulfill(route, pageResult([{ |
|
|
projectId: 'training-project-1', versionId: 'training-version-1', type: 'TRAINING', code: 'TRAIN-001', name: '挖掘机液压系统训练', categoryCode: 'VIRTUAL', coverUri: '', versionNumber: 2, versionStatus: 'PUBLISHED', publishedAt: '2026-08-11T08:00:00+08:00', content: { steps: [] }, |
|
|
projectId: 'training-project-1', versionId: 'training-version-1', type: 'TRAINING', code: 'TRAIN-001', name: '挖掘机液压系统训练', categoryCode: 'VIRTUAL', coverUri: '', versionNumber: 2, versionStatus: 'PUBLISHED', publishedAt: '2026-08-11T08:00:00+08:00', content: { steps: [] }, |
|
|
}]), 'ute2e-teaching-catalog')) |
|
|
}]), 'ute2e-teaching-catalog')) |
|
|
await page.route(/\/embed\/dh-b69424ed0904(?:\?.*)?$/, (route) => { |
|
|
|
|
|
|
|
|
await page.route(/\/embed\/(?:dh-b69424ed0904|demo-equipment-instructor)(?:\?.*)?$/, (route) => { |
|
|
this.digitalInstructorFrameLoads += 1 |
|
|
this.digitalInstructorFrameLoads += 1 |
|
|
return route.fulfill({ |
|
|
return route.fulfill({ |
|
|
status: 200, |
|
|
status: 200, |
|
|
@@ -478,6 +489,20 @@ export class TeachingContractMock { |
|
|
}]), 'ute2e-guides') |
|
|
}]), 'ute2e-guides') |
|
|
if (method === 'GET' && path === '/guides/guide-project-1') return fulfill(route, { |
|
|
if (method === 'GET' && path === '/guides/guide-project-1') return fulfill(route, { |
|
|
projectId: 'guide-project-1', versionId: 'guide-version-1', code: 'GUIDE-001', name: '挖掘机检修作业指导书', description: '标准维修作业流程', categoryCode: '维修作业', coverUri: '', versionNumber: 3, versionCode: 'V3', publishedAt: 1786387200, |
|
|
projectId: 'guide-project-1', versionId: 'guide-version-1', code: 'GUIDE-001', name: '挖掘机检修作业指导书', description: '标准维修作业流程', categoryCode: '维修作业', coverUri: '', versionNumber: 3, versionCode: 'V3', publishedAt: 1786387200, |
|
|
|
|
|
editorDocument: null, |
|
|
|
|
|
resources: {}, |
|
|
|
|
|
assets: [], |
|
|
|
|
|
capabilities: { |
|
|
|
|
|
publishedAssetDownload: false, |
|
|
|
|
|
serverGeneratesOfd: false, |
|
|
|
|
|
serverGeneratesOfflineHtml: false, |
|
|
|
|
|
clientGenerationSupported: false, |
|
|
|
|
|
availableDeliveryFormats: [], |
|
|
|
|
|
}, |
|
|
|
|
|
reading: { |
|
|
|
|
|
projectId: 'guide-project-1', versionId: 'guide-version-1', status: 'NOT_STARTED', |
|
|
|
|
|
startedAt: null, lastReadAt: null, completedAt: null, |
|
|
|
|
|
}, |
|
|
content: { |
|
|
content: { |
|
|
equipment: '履带式挖掘机', specification: '教学训练型', |
|
|
equipment: '履带式挖掘机', specification: '教学训练型', |
|
|
chapters: [ |
|
|
chapters: [ |
|
|
@@ -495,6 +520,12 @@ export class TeachingContractMock { |
|
|
], |
|
|
], |
|
|
}, |
|
|
}, |
|
|
}, 'ute2e-guide-detail') |
|
|
}, 'ute2e-guide-detail') |
|
|
|
|
|
if (method === 'GET' && path === '/guides/guide-project-1/deliveries') return fulfill(route, [], 'ute2e-guide-deliveries') |
|
|
|
|
|
if (method === 'GET' && path === '/guides/guide-project-1/assets') return fulfill(route, [], 'ute2e-guide-assets') |
|
|
|
|
|
if (method === 'GET' && path === '/guides/guide-project-1/statistics') return fulfill(route, { |
|
|
|
|
|
projectId: 'guide-project-1', versionId: 'guide-version-1', readerCount: 6, completedCount: 4, |
|
|
|
|
|
completionRate: 67, feedbackCount: 2, openFeedbackCount: 1, handledFeedbackCount: 1, |
|
|
|
|
|
}, 'ute2e-guide-statistics') |
|
|
|
|
|
|
|
|
if (method === 'GET' && path === '/assignments/summary') { |
|
|
if (method === 'GET' && path === '/assignments/summary') { |
|
|
const channel = url.searchParams.get('channel') |
|
|
const channel = url.searchParams.get('channel') |
|
|
@@ -502,6 +533,17 @@ export class TeachingContractMock { |
|
|
const tasks = [...this.assignments.values()].filter((item) => item.listed !== false && (!channel || item.channel === channel) && item.assignmentKind === kind) |
|
|
const tasks = [...this.assignments.values()].filter((item) => item.listed !== false && (!channel || item.channel === channel) && item.assignmentKind === kind) |
|
|
return fulfill(route, { assignments: tasks.length, draft: 0, published: tasks.length, withdrawn: 0, archived: 0, pendingRuns: 0, activeRuns: this.visibleRuns().filter((item) => item.status === 'IN_PROGRESS').length, submittedRuns: this.visibleRuns().filter((item) => item.status === 'SUBMITTED').length, reviewedRuns: this.visibleRuns().filter((item) => item.status === 'REVIEWED').length, byChannel: Object.fromEntries(tasks.map((item) => [String(item.channel), 1])) }, 'ute2e-summary') |
|
|
return fulfill(route, { assignments: tasks.length, draft: 0, published: tasks.length, withdrawn: 0, archived: 0, pendingRuns: 0, activeRuns: this.visibleRuns().filter((item) => item.status === 'IN_PROGRESS').length, submittedRuns: this.visibleRuns().filter((item) => item.status === 'SUBMITTED').length, reviewedRuns: this.visibleRuns().filter((item) => item.status === 'REVIEWED').length, byChannel: Object.fromEntries(tasks.map((item) => [String(item.channel), 1])) }, 'ute2e-summary') |
|
|
} |
|
|
} |
|
|
|
|
|
if (method === 'GET' && path === '/digital-instructors') return fulfill(route, [{ |
|
|
|
|
|
id: 'agent-equipment-instructor', |
|
|
|
|
|
slug: 'demo-equipment-instructor', |
|
|
|
|
|
name: '装备维修虚拟教员', |
|
|
|
|
|
description: '装备维修训练在线答疑', |
|
|
|
|
|
accessMode: 'internal', |
|
|
|
|
|
interactionModes: ['text', 'voice'], |
|
|
|
|
|
knowledgeSources: ['AGENT', 'WORKSHOP'], |
|
|
|
|
|
agentKnowledgeBaseCount: 1, |
|
|
|
|
|
workshopKnowledgeProviderName: '数字车间维修知识', |
|
|
|
|
|
}], 'ute2e-digital-instructors') |
|
|
if (method === 'GET' && path === '/assignments') { |
|
|
if (method === 'GET' && path === '/assignments') { |
|
|
const channel = url.searchParams.get('channel') |
|
|
const channel = url.searchParams.get('channel') |
|
|
const kind = url.searchParams.get('assignmentKind') ?? 'TRAINING' |
|
|
const kind = url.searchParams.get('assignmentKind') ?? 'TRAINING' |
|
|
@@ -509,7 +551,9 @@ export class TeachingContractMock { |
|
|
return fulfill(route, pageResult(tasks), 'ute2e-assignments') |
|
|
return fulfill(route, pageResult(tasks), 'ute2e-assignments') |
|
|
} |
|
|
} |
|
|
if (method === 'POST' && path === '/assignments') { |
|
|
if (method === 'POST' && path === '/assignments') { |
|
|
if (typeof body.scheduleStartAt !== 'number' || typeof body.dueAt !== 'number' || body.scheduleStartAt >= 1_000_000_000_000 || body.dueAt >= 1_000_000_000_000) return reject(route, 400, '正式考核时间必须是 Unix 秒') |
|
|
|
|
|
|
|
|
if (body.assignmentKind === 'FORMAL_EXAM' |
|
|
|
|
|
&& (typeof body.scheduleStartAt !== 'number' || typeof body.dueAt !== 'number' |
|
|
|
|
|
|| body.scheduleStartAt >= 1_000_000_000_000 || body.dueAt >= 1_000_000_000_000)) return reject(route, 400, '正式考核时间必须是 Unix 秒') |
|
|
if (body.assignmentKind === 'FORMAL_EXAM' && (body.executionMode !== 'EXAM' || body.digitalHumanAllowed !== false)) return reject(route, 400, '正式考核必须使用 EXAM 且禁用数字教员') |
|
|
if (body.assignmentKind === 'FORMAL_EXAM' && (body.executionMode !== 'EXAM' || body.digitalHumanAllowed !== false)) return reject(route, 400, '正式考核必须使用 EXAM 且禁用数字教员') |
|
|
const created = { ...assignment('assignment-created-exam', String(body.channel) as Channel, String(body.assignmentKind) as AssignmentKind, 'ASSIGNED', 'INDIVIDUAL'), ...body, id: 'assignment-created-exam', version: 0, status: 'DRAFT' } |
|
|
const created = { ...assignment('assignment-created-exam', String(body.channel) as Channel, String(body.assignmentKind) as AssignmentKind, 'ASSIGNED', 'INDIVIDUAL'), ...body, id: 'assignment-created-exam', version: 0, status: 'DRAFT' } |
|
|
this.assignments.set(String(created.id), created) |
|
|
this.assignments.set(String(created.id), created) |
|
|
|