PayrollManagementSystem/README.md
liuwenxin 35fea3802f fix(备份): 防止恢复脚本覆盖数据库并返回失败码
修复根目录 README 的失效文档链接,改为现有 T+ 本地恢复手册。\n恢复脚本移除 RESTORE WITH REPLACE,默认不覆盖已有数据库;成功和失败均写入结果文件,失败显式返回非零退出码,并统一释放数据库连接。\n\n影响范围:项目导航文档与两个本地 SQL Server 恢复辅助脚本。\n\nCo-Authored-By: Claude Code <noreply@anthropic.com>
2026-11-06 15:36:39 +08:00

156 lines
7.9 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.

# 衍水集团营销人员工资管理系统
营销人员绩效工资核算系统。后端 Python/FastAPI,前端 Vue 3,数据存 MySQL,会话与缓存在 Redis。
> 当前进度:正式工资闭环及同步运维自动化已完成本地开发验证,支持每周原始采集、有限重试、独立心跳和站内提示,并提供 Windows 托管脚本。辽宁兴晟达真实样本已在隔离库完成正式导入、核算、月结、报表与导出验收,整月实际工资仍须另行核定,见[真实样本业务闭环验收](docs/真实样本业务闭环验收_2026-11-03.md)。生产自动化默认关闭,尚未安装启用。审核能力保留但默认关闭,多原单更正仍单独跟踪。相关说明见 [T+ 本地恢复与同步开发手册](docs/T+本地恢复与同步开发手册.md) 和 [Windows 操作说明](scripts/windows/README.md)。
## 快速开始
### 0. 前置条件
| 工具 | 版本 | 说明 |
| --- | --- | --- |
| Docker Desktop | — | 提供 MySQL 8.0 与 Redis 7,**必须先启动** |
| Python | 3.12 | 由 uv 自动获取,无需手动安装 |
| uv | ≥ 0.12 | Python 依赖与虚拟环境管理 |
| Node.js / pnpm | 22 / 12 | 前端 |
> **国内网络建议先配镜像。** 直连 pypi.org 实测约 4 KB/s,一次 `uv sync` 要几分钟。
> 配在 **uv 的用户级配置**(`%APPDATA%\uv\uv.toml`,Linux/macOS 为 `~/.config/uv/uv.toml`),
> **不要写进 `pyproject.toml`** —— 那会被 `uv.lock` 记录为包来源,仓库就此绑死在该镜像上。
>
> ```toml
> [[index]]
> url = "https://pypi.tuna.tsinghua.edu.cn/simple"
> default = true
> ```
>
> 前端已默认走 npmmirror,无需额外配置。
### 1. 首次准备
```bash
# 从模板创建配置文件,填入真实值(.env 不入库)
cp docker/.env.example docker/.env
cp backend/.env.example backend/.env
# 生成后端密钥并填入 backend/.env 的 APP_SECRET_KEY
python -c "import secrets; print(secrets.token_urlsafe(48))"
# 两处 MYSQL_PASSWORD / REDIS_PASSWORD 需保持一致
```
### 2. 启动(三步)
```bash
# ① 数据库与缓存(首次会自动执行 db/init/init-dev.sql 建表)
docker compose -f docker/docker-compose.dev.yml up -d
# ② 后端:装依赖 → 应用迁移 → 建管理员 → 起服务
cd backend
uv sync
uv run alembic upgrade head
uv run python -m app.cli create-admin --username admin # 密码交互输入
uv run uvicorn app.main:app --reload --port 8000
# ③ 前端(另开终端)
cd frontend
pnpm install
pnpm dev
```
打开 <http://localhost:5173> 即可登录。接口文档在 <http://localhost:8000/api/docs>。
> **务必加 `--reload`**:不加的话改了后端代码进程不会重载,而前端仍能正常访问,
> 会出现「改了没生效但看不出哪里错」的困惑。
## 日常开发
```bash
# 后端测试与代码检查
cd backend
uv run pytest tests/unit -q # 纯单元,无需容器,秒级
python ../scripts/run_isolated_tests.py # 创建独立测试库运行集成,禁止指向业务库
uv run ruff check . # 代码检查
uv run ruff format . # 代码格式化
# 前端
cd frontend
pnpm dev # 开发服务
pnpm type-check # 类型检查
pnpm build # 类型检查 + 生产构建
# 浏览器端到端(需容器、后端、前端都在运行)
python e2e/login_flow.py # 登录链路 8 项
python e2e/system_management.py # 系统管理 13 项
```
## 目录结构
```text
.
├── backend/ 后端 FastAPI(六层:api/core/models/repositories/schemas/services)
│ ├── app/ 应用代码
│ ├── alembic/ 数据库迁移
│ ├── tests/ unit(无需容器)/ integration(需容器)
│ └── README.md 模块说明
├── frontend/ 前端 Vue 3 + TS
│ ├── src/ 应用代码
│ ├── e2e/ Playwright 端到端脚本
│ └── README.md 模块说明(含视觉设计约定)
├── db/
│ ├── init/ 开发环境初始化(仅供参考,见下方说明)
│ ├── migration/ 生产迁移脚本,按序编号
│ └── queries/ 业务 SQL 留存
├── docker/ 容器编排
├── docs/ 需求文档
└── ai-aux/ AI 辅助上下文(不纳入版本管理)
```
## 几个容易踩的点
**`db/init/init-dev.sql` 改了不生效**
它只在 MySQL **数据卷为空时的首次启动**执行。数据卷已存在时改动它没有任何提示。
需要重置时:`docker compose -f docker/docker-compose.dev.yml down -v` 再 `up -d`(会清空数据)。
**生产路径是 `db/migration/`,那个才必须保证正确。**
**环境变量分两处,重复项要同步改**
`docker/.env` 管编排凭据(数据库 root 密码、业务账号密码、Redis 密码);
`backend/.env` 管应用配置(连接串、密钥、JWT、验证码、T+ 凭据)。
`MYSQL_PASSWORD` / `REDIS_PASSWORD` 两处都有,改一处要改两处。
**后端 401 与登录失败是两回事**
`401` 只表示「登录态失效」;登录接口自身失败返回 `400`/`403`。
前端拦截器把 401 一律当作「清 token + 跳登录页」,两者混用会导致「输错密码就被弹回登录页」。
**登录失败后必须刷新验证码**
后端用 Redis `GETDEL` 消费验证码,任何一次提交后它都已失效——前端已自动处理,改动登录页时注意保留。
## 相关文档
客户现场部署见 [客户现场部署与 T+ 连接说明](docs/客户现场部署与T+连接说明.md):按 Linux 容器、Windows Server 或 Linux 原生选择托管方式,连接客户既有 T+ SQL Server。生产 Compose 为 `docker/docker-compose.prod.yml`,T+ 恢复库编排仅用于本地开发。
| 文档 | 内容 |
| --- | --- |
| `backend/README.md` | 后端启动、分层约定、接口清单 |
| `backend/tests/README.md` | 测试约定、用例清单、运行记录、已修复缺陷 |
| `frontend/README.md` | 前端版本约束、视觉设计约定、端到端测试 |
| `docs/` | 需求文档与工资算法方案 |
## 正式工资闭环
- 在“角色管理”配置工资操作权限,在“用户管理”分配角色;账号自动继承权限,无需单独绑定工资制作人。每次实际经办人继续留痕。
- 应用新增迁移后,T+ 页面提供正式业务导入预览/执行;业务列表“正式核算”准备人工业务资料或核算已导入资料,台账可查看逐段依据。
- “生成月结快照”首次成功即锁定该月分配;审批退回、重新生成不解锁。历史已生成工资保留,差额计调整单生成当月。
- 后端接口说明、验证状态和已知边界见 `docs/正式工资闭环开发记录_2026-10-30.md`。旧引擎仅通过 `PAYROLL_ALLOW_LEGACY_CALCULATION` 显式启用作历史兼容,默认关闭,不用于最新规则验收。
- 集成回归使用 `scripts/run_isolated_tests.py`;原 `.venv` 不可用时,本机使用 `backend/.venv-workbench/Scripts/python.exe`。运行器默认清理本次新建的隔离库和账号,绝不删除原开发数据;需复查失败现场时加 `--keep`。
审核默认关闭:`PAYROLL_APPROVAL_ENABLED=false`,工资生成直接完成且不产生审批痕迹;如确需系统内复核,显式开启后沿用财务/领导审核和各类审批参数。此配置与旧核算引擎兼容开关独立。
## 权限管理
- “用户管理 → 分配角色”:选择角色并预览继承权限,支持多个角色叠加。
- “角色管理 → 配置权限”:按模块配置模板;停用角色即时撤销其授权。
- 管理员拥有全部功能权限;月份锁定、审核节点及源读取开关继续独立检查。
- 授权变更无需重新登录,后端逐请求校验;详情、只读提示、菜单与按钮使用统一规则。操作与接口说明见 [权限管理使用与开发记录](docs/权限管理使用与开发记录_2026-11-02.md)。