「权限 × 状态 × 审计」联合约束机制
This commit is contained in:
@@ -65,6 +65,8 @@ import { usePermission } from "../utils/permission";
|
||||
import { aeMachine, getAvailableActions } from "../state-machine";
|
||||
import type { ActionConfig } from "../state-machine";
|
||||
import { statusDict, getDictColor, getDictLabel } from "../dictionaries";
|
||||
import { evaluateAction } from "../guards/actionGuard";
|
||||
import { logAudit } from "../audit";
|
||||
|
||||
const route = useRoute();
|
||||
const study = useStudyStore();
|
||||
@@ -102,6 +104,36 @@ const load = async () => {
|
||||
|
||||
const onAction = async (action: ActionConfig) => {
|
||||
if (!study.currentStudy || !ae.value) return;
|
||||
const prevStatus = ae.value.status;
|
||||
if (prevStatus === action.to) {
|
||||
ElMessage.warning("当前状态不允许该操作");
|
||||
logAudit("INVALID_STATE_TRANSITION_ATTEMPT", {
|
||||
targetId: ae.value.id,
|
||||
targetName: ae.value.term,
|
||||
before: { status: prevStatus },
|
||||
after: { status: action.to },
|
||||
severity: "warning",
|
||||
});
|
||||
return;
|
||||
}
|
||||
const decision = evaluateAction({
|
||||
actorRole: auth.user?.role || null,
|
||||
requiredPermission: "ae.close",
|
||||
stateMachine: aeMachine,
|
||||
currentState: ae.value.status,
|
||||
actionKey: action.key,
|
||||
target: { id: ae.value.id },
|
||||
});
|
||||
if (!decision.allowed) {
|
||||
ElMessage.warning(decision.reason || "当前不可执行该操作");
|
||||
logAudit(decision.auditType, {
|
||||
targetId: ae.value.id,
|
||||
targetName: ae.value.term,
|
||||
reason: decision.reason,
|
||||
severity: decision.severity,
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (action.confirm) {
|
||||
const ok = await ElMessageBox.confirm(action.confirmText || "确认执行该操作?", "提示").catch(() => null);
|
||||
if (!ok) return;
|
||||
@@ -110,9 +142,24 @@ const onAction = async (action: ActionConfig) => {
|
||||
const resp = await updateAe(study.currentStudy.id, ae.value.id, { status: action.to });
|
||||
ElMessage.success("状态已更新");
|
||||
ae.value = enrichOverdue(resp.data);
|
||||
logAudit("AE_CLOSED", {
|
||||
targetId: ae.value.id,
|
||||
targetName: ae.value.term,
|
||||
before: { status: prevStatus },
|
||||
after: { status: action.to },
|
||||
severity: "normal",
|
||||
});
|
||||
await load();
|
||||
} catch (e: any) {
|
||||
ElMessage.error(e?.response?.data?.message || "更新失败");
|
||||
logAudit("AE_CLOSED", {
|
||||
targetId: ae.value.id,
|
||||
targetName: ae.value.term,
|
||||
before: { status: prevStatus },
|
||||
after: { status: action.to },
|
||||
severity: "warning",
|
||||
reason: e?.response?.data?.message,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user