R18-4/R21-2: 收口企微脱敏通知与 Portal 搜索摘要
这个提交包含在:
+104
-6
@@ -13,12 +13,15 @@ const ENTITY_PRIORITY = {
|
||||
employee: 0,
|
||||
announcement: 1,
|
||||
asset: 2,
|
||||
leave: 3,
|
||||
reimbursement: 4,
|
||||
weekly_report: 5,
|
||||
todo: 6,
|
||||
purchase_request: 7,
|
||||
travel_request: 8,
|
||||
project: 3,
|
||||
contract_registry: 4,
|
||||
confidential_doc_ref: 5,
|
||||
leave: 6,
|
||||
reimbursement: 7,
|
||||
weekly_report: 8,
|
||||
todo: 9,
|
||||
purchase_request: 10,
|
||||
travel_request: 11,
|
||||
};
|
||||
|
||||
function buildValidationError(details, statusCode = 400) {
|
||||
@@ -75,6 +78,9 @@ async function searchRoutes(fastify) {
|
||||
announcements: await isFlagEnabled(fastify, request, FEATURE_FLAG_KEYS.announcements),
|
||||
weeklyReport: await isFlagEnabled(fastify, request, FEATURE_FLAG_KEYS.weeklyReport),
|
||||
todoBoard: await isFlagEnabled(fastify, request, FEATURE_FLAG_KEYS.todoBoard),
|
||||
projectDomain: await isFlagEnabled(fastify, request, FEATURE_FLAG_KEYS.projectDomain),
|
||||
projectLinking: await isFlagEnabled(fastify, request, FEATURE_FLAG_KEYS.projectLinking),
|
||||
confidentialDocRefs: await isFlagEnabled(fastify, request, FEATURE_FLAG_KEYS.confidentialDocRefs),
|
||||
};
|
||||
|
||||
const tasks = [];
|
||||
@@ -261,6 +267,98 @@ async function searchRoutes(fastify) {
|
||||
);
|
||||
}
|
||||
|
||||
if (featureEnabled.projectDomain && (fastify.hasPermission(request.employee, "project.view_own") || fastify.hasPermission(request.employee, "project.view_all") || fastify.hasPermission(request.employee, "project.manage"))) {
|
||||
tasks.push(
|
||||
fastify.prisma.project.findMany({
|
||||
where: {
|
||||
AND: [
|
||||
fastify.hasPermission(request.employee, "project.view_all") || fastify.hasPermission(request.employee, "project.manage") || isAdmin
|
||||
? {}
|
||||
: {
|
||||
OR: [
|
||||
{ owner_employee_id: request.employee.id },
|
||||
{ manager_employee_id: request.employee.id },
|
||||
{ members: { some: { employee_id: request.employee.id, left_at: null } } },
|
||||
],
|
||||
},
|
||||
{
|
||||
OR: [
|
||||
{ project_no: { contains: q, mode: "insensitive" } },
|
||||
{ name: { contains: q, mode: "insensitive" } },
|
||||
{ client_name: { contains: q, mode: "insensitive" } },
|
||||
{ client_alias: { contains: q, mode: "insensitive" } },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
take: limit,
|
||||
orderBy: { updated_at: "desc" },
|
||||
select: { id: true, project_no: true, name: true, client_name: true, client_alias: true, is_confidential: true, updated_at: true },
|
||||
}).then((rows) => rows.map((item) => ({
|
||||
entityType: "project",
|
||||
entityId: item.id,
|
||||
title: `${item.project_no} · ${item.name}`,
|
||||
subtitle: item.is_confidential ? "涉密项目" : item.client_alias || item.client_name || null,
|
||||
status: null,
|
||||
href: `/projects/${item.id}`,
|
||||
matchedBy: matchByValue(q, item.project_no, item.name, item.client_name, item.client_alias),
|
||||
updatedAt: item.updated_at?.toISOString?.() ?? null,
|
||||
}))),
|
||||
);
|
||||
}
|
||||
|
||||
if (featureEnabled.projectLinking && (fastify.hasPermission(request.employee, "project.view_all") || fastify.hasPermission(request.employee, "project.manage") || fastify.hasPermission(request.employee, "system.settings") || isAdmin)) {
|
||||
tasks.push(
|
||||
fastify.prisma.contractRegistry.findMany({
|
||||
where: {
|
||||
OR: [
|
||||
{ contract_no: { contains: q, mode: "insensitive" } },
|
||||
{ counterparty_name: { contains: q, mode: "insensitive" } },
|
||||
{ summary: { contains: q, mode: "insensitive" } },
|
||||
],
|
||||
},
|
||||
take: limit,
|
||||
orderBy: { updated_at: "desc" },
|
||||
select: { id: true, contract_no: true, counterparty_name: true, confidentiality_level: true, summary: true, updated_at: true },
|
||||
}).then((rows) => rows.map((item) => ({
|
||||
entityType: "contract_registry",
|
||||
entityId: item.id,
|
||||
title: item.contract_no,
|
||||
subtitle: ["confidential", "restricted"].includes(item.confidentiality_level) ? "涉密合同台账" : item.counterparty_name,
|
||||
status: item.confidentiality_level,
|
||||
href: "/contracts-registry",
|
||||
matchedBy: matchByValue(q, item.contract_no, item.counterparty_name, item.summary),
|
||||
updatedAt: item.updated_at?.toISOString?.() ?? null,
|
||||
}))),
|
||||
);
|
||||
}
|
||||
|
||||
if (featureEnabled.confidentialDocRefs && (fastify.hasPermission(request.employee, "project.view_all") || fastify.hasPermission(request.employee, "project.manage") || fastify.hasPermission(request.employee, "system.settings") || isAdmin)) {
|
||||
tasks.push(
|
||||
fastify.prisma.confidentialDocumentRef.findMany({
|
||||
where: {
|
||||
OR: [
|
||||
{ title: { contains: q, mode: "insensitive" } },
|
||||
{ document_no: { contains: q, mode: "insensitive" } },
|
||||
{ offline_archive_no: { contains: q, mode: "insensitive" } },
|
||||
],
|
||||
},
|
||||
take: limit,
|
||||
orderBy: { updated_at: "desc" },
|
||||
select: { id: true, title: true, document_no: true, confidentiality_level: true, updated_at: true },
|
||||
}).then((rows) => rows.map((item) => ({
|
||||
entityType: "confidential_doc_ref",
|
||||
entityId: item.id,
|
||||
title: item.document_no || item.title,
|
||||
subtitle: ["confidential", "restricted"].includes(item.confidentiality_level) ? "涉密资料引用" : item.title,
|
||||
status: item.confidentiality_level,
|
||||
href: "/contracts-registry",
|
||||
matchedBy: matchByValue(q, item.title, item.document_no),
|
||||
updatedAt: item.updated_at?.toISOString?.() ?? null,
|
||||
}))),
|
||||
);
|
||||
}
|
||||
|
||||
if (featureEnabled.todoBoard) {
|
||||
tasks.push(
|
||||
fastify.prisma.todoItem.findMany({
|
||||
|
||||
在新工单中引用
屏蔽一个用户