# 衍水集团营销人员工资管理系统 营销人员绩效工资核算系统。后端 Python/FastAPI,前端 Vue 3,数据存 MySQL,会话与缓存在 Redis。 > 当前进度:正式工资闭环及同步运维自动化已完成本地开发验证,支持每周原始采集、有限重试、独立心跳和站内提示,并提供 Windows 托管脚本。生产自动化默认关闭,尚未安装启用;真实金额与整月工资尚未验收,首组样本缺人工指导成本。审核能力保留但默认关闭,多原单更正仍单独跟踪。最新交付见 [开发记录](docs/同步运维自动化与样本核对开发记录_2026-10-30.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 ``` 打开 即可登录。接口文档在 。 > **务必加 `--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` 消费验证码,任何一次提交后它都已失效——前端已自动处理,改动登录页时注意保留。 ## 相关文档 | 文档 | 内容 | | --- | --- | | `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`。测试运行器保留隔离库供复查,不删除原开发数据。 审核默认关闭:`PAYROLL_APPROVAL_ENABLED=false`,工资生成直接完成且不产生审批痕迹;如确需系统内复核,显式开启后沿用财务/领导审核和各类审批参数。此配置与旧核算引擎兼容开关独立。 ## 权限管理 - “用户管理 → 分配角色”:选择角色并预览继承权限,支持多个角色叠加。 - “角色管理 → 配置权限”:按模块配置模板;停用角色即时撤销其授权。 - 管理员拥有全部功能权限;月份锁定、审核节点及源读取开关继续独立检查。 - 授权变更无需重新登录,后端逐请求校验;详情、只读提示、菜单与按钮使用统一规则。操作与接口说明见 [权限管理使用与开发记录](docs/权限管理使用与开发记录_2026-11-02.md)。