declare const process: { cwd(): string }; declare function require(name: string): { existsSync?: (path: string) => boolean; readFileSync?: (path: string, encoding: string) => string; join?: (...parts: string[]) => string; }; const { existsSync, readFileSync } = require("node:fs"); const { join } = require("node:path"); if (!existsSync || !readFileSync || !join) { throw new Error("测试运行环境缺少文件读取能力"); } const root = process.cwd(); const realtimeApiPath = join(root, "src/api/realtimeAttendance.ts"); const monthlyApiPath = join(root, "src/api/monthlyPayroll.ts"); const realtimeViewPath = join(root, "src/views/RealtimeAttendanceView.vue"); const monthlyViewPath = join(root, "src/views/MonthlyPayrollView.vue"); assertTruthy(existsSync(realtimeApiPath), "缺少实时考勤 API 客户端"); assertTruthy(existsSync(monthlyApiPath), "缺少月度核算 API 客户端"); const realtimeApi = readFileSync(realtimeApiPath, "utf-8"); assertIncludes(realtimeApi, "/api/attendance/realtime/today"); assertIncludes(realtimeApi, "/api/attendance/realtime/sync"); const monthlyApi = readFileSync(monthlyApiPath, "utf-8"); assertIncludes(monthlyApi, "/api/payroll/monthly/runs"); const realtimeView = readFileSync(realtimeViewPath, "utf-8"); assertNotIncludes(realtimeView, "待接入菜单"); assertNotIncludes(realtimeView, "待接入钉钉同步"); assertIncludes(realtimeView, "预估金额,最终以月度核算锁定结果为准"); const monthlyView = readFileSync(monthlyViewPath, "utf-8"); assertNotIncludes(monthlyView, "下一阶段接入"); assertIncludes(monthlyView, "锁定后本月工资不能重新计算"); function assertIncludes(content: string, expected: string): void { if (!content.includes(expected)) { throw new Error(`期望包含 ${expected}`); } } function assertNotIncludes(content: string, unexpected: string): void { if (content.includes(unexpected)) { throw new Error(`不应包含 ${unexpected}`); } } function assertTruthy(value: boolean, message: string): void { if (!value) { throw new Error(message); } }