PayrollManagementSystem/scripts/windows/README.md
liuwenxin 1461a8d113 feat(后端): 添加授权体系、系统监控与试用期计提
按 2026-11-02 需求补齐计划交付后端能力:
- 角色授权:权限目录化,接口统一准入校验,未登记默认拒绝;
  管理员判断改为按数据库角色重新判定,防止权限码持有者绕过
- 系统监控:单进程采集资源、请求与异常指标,分钟级聚合,
  阈值配置化;敏感配置增加 repr 保护,Redis 密码 URL 转义
- 试用期计提:按回款日判定并写入快照,年度结清与调整单联动;
  人员模型补试用期、离职日期与工资版本历史字段
- 计提模板:公式骨架受控,页面维护名称与参数绑定
- T+ 采集:自动化配置表与进度查询

内置角色禁停用保护对齐模块注释;核算规则版本提为常量并
补充批量核算失败堆栈日志。

影响范围:后端全部模块、数据库迁移 V22-V28
验证:uv run ruff check 通过;922 个单元测试全部通过;
集成测试因本机 MySQL 数据卷被其他容器锁定暂未运行
2026-11-03 11:20:55 +08:00

80 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Windows 任务计划托管
本包托管后端、T+ worker 和每分钟周期检查。首次安装生成三个禁用任务并保留停止标记;自动周采集另外由应用配置启用。采集不会自动导入正式业务、核算或生成工资。
## 配置及账号准备
使用目标服务器已有受限服务账号,配置“作为批处理作业登录”、MySQL/Redis 连接和项目外的 T+ 只读连接文件。生产不能使用 SYSTEM。管理员须预先准备运行目录及文件权限:
- 部署目录、Python 环境和全部程序文件,只允许管理员及指定服务账号维护,不允许普通 Users、Everyone、Authenticated Users 写入。
- 只读连接文件和 `backend/.env`,仅限管理员、SYSTEM 与服务账号读取;连接文件不放进仓库。
- 运行目录供服务账号写入日志、安装清单和停止标记,拒绝其他普通用户写入。上层目录也不能给普通用户删除/替换这些目录的权限。
- 脚本安装前和 Start 前检查关键入口、文件所有者和上层目录 ACL;不会自动改变 ACL。管理员仍需确保部署树全部内容和 Python 依赖都受相同保护。
- 安装清单保存服务账号 SID 和登录方式,Check/Start/Stop 均核验实际任务账号及 Limited 权限,发现漂移则拒绝操作。
应用需先完成经授权的迁移;当前 head 为 `21f2a3b4c5d6`(V20 调度状态、V21 状态默认值修正)。本次仅在隔离库验证,未迁移客户业务库。
`backend/.env` 中的非敏感开关:
```dotenv
T_PLUS_AUTOMATION_ENABLED=false
T_PLUS_SCHEDULE_WEEKDAY=0
T_PLUS_SCHEDULE_TIME=02:00
```
`T_PLUS_AUTOMATION_ENABLED` 只是未保存页面设置时的初始值。T+ 同步页保存开关后写入 `tplus_automation_configs`,维护程序以该源级设置为准;关闭页面开关会阻止后续自动排队,不影响当前任务和手动同步。
weekday 的 0~6 分别为周一至周日,时间固定按 `Asia/Shanghai` 解释。上线前保持自动化开关为 false。修改后重启托管进程,使后端与检查命令使用同一配置。
## 预检查和安装
在 Windows PowerShell 5 中执行,使用实际部署路径。以下为示例路径,不含真实凭据。
```powershell
$project = 'D:\Payroll App'
$python = 'D:\Payroll App\backend\.venv\Scripts\python.exe'
$runtime = 'D:\Payroll Runtime'
$reader = 'D:\Payroll Secrets\reader.local.json'
# 只读预演:输出路径、动作、触发和恢复策略,不注册任务
& "$project\scripts\windows\Install-PayrollTasks.ps1" `
-ProjectRoot $project -PythonPath $python -RuntimeDirectory $runtime -ConnectionFile $reader
# 检查脚本语法、任务策略、引号、ACL规则及账号核验;不注册任务
& "$project\scripts\windows\Test-PayrollTaskPlan.ps1" `
-ProjectRoot $project -PythonPath $python -RuntimeDirectory $runtime -ConnectionFile $reader
```
客户环境安装需另行确认。确认后管理员才执行 `Install-PayrollTasks.ps1` 的同组参数,并增加 `-ServiceAccount '域或主机\已有服务账号' -Apply`。凭据通过交互框输入,不写入命令行、清单或日志。目录须提前准备且 ACL 合格,否则拒绝注册;已有同名任务/安装清单不会覆盖。安装过程部分失败时,已创建的任务仍保持禁用,按提示核对专用任务目录后处理。
测试模式只允许 `\PayrollManagementSystem-Test-xxxxxxxx\`(8 位十六进制)的独立目录及当前用户 Interactive/Limited 身份,同样要求显式 `-Apply` 和合格 ACL。不要用测试模式替代客户服务账号验收。
## 检查、启动、停用
```powershell
# 检查状态、最近退出码、下次执行及任务身份/动作/恢复策略
& "$project\scripts\windows\Manage-PayrollTasks.ps1" -Action Check -RuntimeDirectory $runtime
# 预演启动或停用;增加 -Apply 才改变任务状态
& "$project\scripts\windows\Manage-PayrollTasks.ps1" -Action Start -RuntimeDirectory $runtime
& "$project\scripts\windows\Manage-PayrollTasks.ps1" -Action Stop -RuntimeDirectory $runtime
```
Start 的 `-Apply` 删除项目停止标记,启用并启动三项任务。Stop 的 `-Apply` 先写停止标记并禁用任务;worker 完成当前工作后退出,不再领取下一项。默认等待 30 秒,长查询未结束则返回 2,稍后 Check。仅在核实中断影响后,才使用 `-Force -Apply` 强制停止明确的项目任务;重启后遗留 RUNNING 批次标记中断,原数据及失败批次保留,由制作人核对后重试。
每项任务使用 IgnoreNew,异常退出间隔 1 分钟重启,最多 3 次;启动器保留子进程退出码。后端及 worker 开机触发,维护命令开机及每分钟触发,长任务无强制执行时限。启动器子进程隐藏运行,后端绑定 `127.0.0.1`,对外访问应沿用现有网关。
## 调度和异常处理
`tplus-maintain --once` 只排队最近已到期的一周,同周期幂等;停机后补一次,不逐周补积压。手动任务/正式导入工作区正在运行时延后排队。人工重试结果接入该周期,不会在人工恢复成功后再次重读原失败批次。
仅定时采集且错误均为明确断连或超时,才在终止后 5 分钟、15 分钟重试,最多两次。中途断连保留已暂存页并标记失败,重新全量读取由哈希去重。行级错误/部分失败、配置错误、字段错误、进程中断和正式导入不自动重试。原批次、重试关系与错误记录一直保留。
T+ 同步页显示自动化开关、心跳、最近成功和下次重试,以及失败/部分失败、排队超过 15 分钟、超过 8 天无成功、心跳中断提示。独立心跳每 30 秒写入,2 分钟无更新提示离线。日志按次写入 `runtime\logs`,不自动删除;不输出驱动连接文本。外部邮件及企业消息未启用。
## 验证范围
已验证 Windows PowerShell 5 的计划参数、单实例/重启设置、含空格路径、隐藏子进程、停止标记和退出码传递;测试未注册计划任务或连接业务数据库。应用侧已完成隔离库周期竞争、人工/自动重试竞争、上限及独立长查询心跳验证。
客户服务器实际注册、服务账号权限、开机触发、每分钟三次恢复和停止后不再启动,仍需在专用目标环境演练并留存 Check 输出。SQL Server 2008 R2 实机、备份全量/增量恢复链及生产启用分别验收,不由本机测试替代。