R44 A2-A8 完成员工高级筛选批量操作与统计页

这个提交包含在:
2026-03-29 12:27:44 +08:00
父节点 c3873999c2
当前提交 d11f5593d1
共修改 17 个文件,包含 1640 行新增和 337 行删除
+17 -20
查看文件
@@ -3,6 +3,11 @@ const { Readable } = require("node:stream");
const ExcelJS = require("exceljs");
const { z } = require("zod");
const {
EMPLOYMENT_STATUS_VALUES,
buildEmployeeDirectoryWhere,
parseEmployeeDirectoryFilters,
} = require("../services/employeeDirectoryFilters");
const {
HISTORY_STATUS_VALUES,
buildPresenceValidationError,
@@ -61,6 +66,11 @@ const EMPLOYEE_EXPORT_QUERY_SCHEMA = z.object({
status: z.enum(["active", "archived"]).optional(),
departmentId: z.string().uuid().optional(),
q: z.string().max(100).optional(),
title: z.string().max(100).optional(),
managerId: z.string().uuid().optional(),
hireDateFrom: DATE_ONLY_SCHEMA.optional(),
hireDateTo: DATE_ONLY_SCHEMA.optional(),
employmentStatus: z.enum(EMPLOYMENT_STATUS_VALUES).optional(),
limit: z.coerce.number().int().min(1).max(20000).optional(),
});
@@ -193,25 +203,6 @@ function buildDashboardWhere(request, query) {
};
}
function buildEmployeeExportWhere(query) {
const q = query.q?.trim() ?? "";
return {
...(query.status ? { status: query.status } : {}),
...(query.departmentId ? { department_id: query.departmentId } : {}),
...(q
? {
OR: [
{ employee_no: { contains: q, mode: "insensitive" } },
{ name: { contains: q, mode: "insensitive" } },
{ phone: { contains: q, mode: "insensitive" } },
{ email: { contains: q, mode: "insensitive" } },
],
}
: {}),
};
}
async function* streamDashboardReimbursementsCsv(prisma, where, limit) {
yield "\ufeff";
yield csvRow([
@@ -907,7 +898,8 @@ async function exportsRoutes(fastify) {
},
async (request, reply) => {
const query = parseQuery(EMPLOYEE_EXPORT_QUERY_SCHEMA, request.query);
const where = buildEmployeeExportWhere(query);
const filters = parseEmployeeDirectoryFilters(query, { allowDepartmentFilter: true });
const where = buildEmployeeDirectoryWhere(filters);
const format = resolveExportFormat(query);
const limit = query.limit ?? 5000;
const total = await fastify.prisma.employee.count({ where });
@@ -922,6 +914,11 @@ async function exportsRoutes(fastify) {
status: query.status ?? null,
departmentId: query.departmentId ?? null,
q: query.q?.trim() || null,
title: query.title?.trim() || null,
managerId: query.managerId ?? null,
hireDateFrom: query.hireDateFrom ?? null,
hireDateTo: query.hireDateTo ?? null,
employmentStatus: query.employmentStatus ?? null,
limit,
matchedTotal: total,
},