R36-4 放开跨域转审并同步回归

这个提交包含在:
2026-03-25 15:33:46 +08:00
父节点 d0b9d9eaca
当前提交 87b52f0509
共修改 6 个文件,包含 327 行新增和 35 行删除
+33 -27
查看文件
@@ -54,7 +54,7 @@ const APPROVER_LIST_QUERY_SCHEMA = z.object({
});
const APPROVER_ROLE_CODES = Object.keys(ROLE_PERMISSIONS).filter((roleCode) =>
hasPermission(ROLE_PERMISSIONS[roleCode], "expense.approve"),
ROLE_PERMISSIONS[roleCode].some((permissionCode) => permissionCode.endsWith(".approve")),
);
function parseRequiredComment(body) {
@@ -303,14 +303,12 @@ function listAllowedActionsForTask(request, task, actionable) {
const actions = [];
const approvePermission = resolveEntityPermission(task.workflow_instance?.entity_type, "approve");
if (approvePermission && hasPermission(request.employee.permissionCodes, approvePermission)) {
const canApprove = approvePermission && hasPermission(request.employee.permissionCodes, approvePermission);
if (canApprove) {
actions.push("approve", "reject", "return");
}
if (
task.workflow_instance?.entity_type === "reimbursement" &&
hasPermission(request.employee.permissionCodes, "expense.transfer")
) {
if (canApprove && hasPermission(request.employee.permissionCodes, "expense.transfer")) {
actions.push("transfer");
}
@@ -734,8 +732,8 @@ async function ensureTransferChainNotExceeded(tx, taskId) {
if (transferCount >= 3) {
throw new AppError({
code: "VALID_001",
message: "参数校验失败",
code: "WORKFLOW_003",
message: "已达转审上限",
statusCode: 409,
details: { transfer: "chain_limit_exceeded" },
});
@@ -744,7 +742,7 @@ async function ensureTransferChainNotExceeded(tx, taskId) {
return transferCount;
}
async function ensureTransferTargetEligible(tx, toApproverId) {
async function ensureTransferTargetEligible(tx, toApproverId, approvePermission) {
const target = await tx.employee.findUnique({
where: { id: toApproverId },
select: {
@@ -769,7 +767,7 @@ async function ensureTransferTargetEligible(tx, toApproverId) {
const roleCodes = target.roles.map((item) => item.role_code);
const permissionCodes = resolvePermissionsForRoles(roleCodes);
if (!hasPermission(permissionCodes, "expense.approve")) {
if (!approvePermission || !hasPermission(permissionCodes, approvePermission)) {
throw new AppError({
code: "VALID_001",
message: "参数校验失败",
@@ -2039,7 +2037,11 @@ async function workflowRoutes(fastify) {
const assignment = await ensureTaskAssignableToCurrentEmployee(tx, task, request);
const workflowInstance = await loadWorkflowInstanceForTask(tx, task.instance_id);
if (workflowInstance.entity_type !== "reimbursement") {
const approvePermission = resolveEntityPermission(
workflowInstance.entity_type,
"approve",
);
if (!approvePermission) {
throw new AppError({
code: "VALID_001",
message: "参数校验失败",
@@ -2048,7 +2050,7 @@ async function workflowRoutes(fastify) {
});
}
const transferCount = await ensureTransferChainNotExceeded(tx, taskId);
await ensureTransferTargetEligible(tx, toApproverId);
await ensureTransferTargetEligible(tx, toApproverId, approvePermission);
if (toApproverId === request.employee.id) {
throw new AppError({
@@ -2067,19 +2069,23 @@ async function workflowRoutes(fastify) {
},
});
const transfer = await tx.approvalTransfer.create({
data: {
reimbursement_id: workflowInstance.entity_id,
from_approver_id: request.employee.id,
to_approver_id: toApproverId,
reason,
status: "active",
created_by: request.employee.id,
},
select: {
id: true,
},
});
let transferId = null;
if (workflowInstance.entity_type === "reimbursement") {
const transfer = await tx.approvalTransfer.create({
data: {
reimbursement_id: workflowInstance.entity_id,
from_approver_id: request.employee.id,
to_approver_id: toApproverId,
reason,
status: "active",
created_by: request.employee.id,
},
select: {
id: true,
},
});
transferId = transfer.id;
}
await tx.workflowHistory.create({
data: {
@@ -2137,8 +2143,8 @@ async function workflowRoutes(fastify) {
taskId,
outcome: "transferred",
workflowInstanceId: workflowInstance.id,
reimbursementStatus: "reviewing",
transferId: transfer.id,
reimbursementStatus: workflowInstance.entity_type === "reimbursement" ? "reviewing" : null,
transferId,
fromApproverId: request.employee.id,
toApproverId,
transferCount: transferCount + 1,