流程设计

This commit is contained in:
2026-07-20 12:29:07 +08:00 Unverified
parent c5446d5241
commit 4c7fafc03d
13 changed files with 240 additions and 54 deletions
+31 -2
View File
@@ -72,10 +72,33 @@ function adminsForStep(db, adminLevel, profile) {
if (item.role !== 'admin' || !item.active || item.adminLevel !== adminLevel) return false;
if (adminLevel === 'super') return true;
if (adminLevel === 'school') return Boolean(profile?.schoolId && item.schoolId === profile.schoolId);
return Boolean(profile?.classId && item.classId === profile.classId);
if (adminLevel === 'class') return Boolean(
profile?.schoolId && profile?.classId
&& item.schoolId === profile.schoolId && item.classId === profile.classId
);
return false;
});
}
function selectAdminForStep(db, adminLevel, profile) {
const pendingByAdmin = new Map();
for (const instance of db.workflowInstances) {
if (instance.status !== 'pending' || !instance.assigneeId) continue;
pendingByAdmin.set(instance.assigneeId, (pendingByAdmin.get(instance.assigneeId) || 0) + 1);
}
const assignedByAdmin = new Map();
for (const action of db.workflowActions) {
if (!action.toAssigneeId) continue;
assignedByAdmin.set(action.toAssigneeId, (assignedByAdmin.get(action.toAssigneeId) || 0) + 1);
}
return adminsForStep(db, adminLevel, profile).sort((left, right) =>
(pendingByAdmin.get(left.id) || 0) - (pendingByAdmin.get(right.id) || 0)
|| (assignedByAdmin.get(left.id) || 0) - (assignedByAdmin.get(right.id) || 0)
|| String(left.createdAt || '').localeCompare(String(right.createdAt || ''))
|| left.id.localeCompare(right.id)
)[0] || null;
}
function activeWorkflow(db, businessType) {
return db.workflows.find(item => item.businessType === businessType && item.active);
}
@@ -84,7 +107,7 @@ function createWorkflowSubmission(db, businessType, businessId, profile, actorId
const workflow = activeWorkflow(db, businessType);
if (!workflow?.steps.length) throw Object.assign(new Error('该业务尚未配置审批流程'), { status: 409 });
const firstStep = workflow.steps[0];
const assignee = adminsForStep(db, firstStep.adminLevel, profile)[0];
const assignee = selectAdminForStep(db, firstStep.adminLevel, profile);
if (!assignee) throw Object.assign(new Error(`没有可承接“${firstStep.name}”的${adminLevelNames[firstStep.adminLevel]}`), { status: 409 });
const instance = {
id: uid('flow'), workflowId: workflow.id, businessType, businessId, status: 'pending', currentStep: 1,
@@ -165,6 +188,11 @@ function workflowScopeProfile(db, instance) {
const batch = db.candidateAccountBatches.find(item => item.id === instance.businessId);
return batch ? centerScopeProfile(db, batch.schoolId) : null;
}
if (instance.businessType === 'score_appeal') {
const result = db.results.find(item => item.id === instance.businessId);
const registration = db.registrations.find(item => item.id === result?.registrationId);
return db.candidateProfiles.find(item => item.userId === registration?.userId) || null;
}
return null;
}
@@ -536,6 +564,7 @@ const routeContext = {
registrationInScope,
adminScopeLabel,
adminsForStep,
selectAdminForStep,
activeWorkflow,
createWorkflowSubmission,
workflowView,