financial_system/README.md
2026-06-29 14:49:32 +08:00

13 KiB
Raw Permalink Blame History

薪酬考勤管理系统

本项目是一套前后端分离的薪酬考勤管理系统,用于处理钉钉月度汇总 Excel、后续钉钉实时接口、员工档案、薪资档案、提成、考勤扣款、加班费、工资汇总和统计报表。

核心目标是把人工工资核算链路拆成可维护的数据流:

钉钉考勤接口 / Excel导入
  -> 数据标准化
  -> 考勤 / 请假 / 加班引擎
  -> 工时统计
  -> 薪资 / 提成 / 奖惩计算
  -> 工资汇总
  -> 工资条 / 月报表 / 财务报表

当前能力

  • 支持导入钉钉月度汇总 Excel 计算工资。
  • 支持实时考勤看板:按员工档案中的钉钉 userId 自动同步本月至今打卡,不需要人工输入 userId。
  • 支持月度核算中心:按月份导入 Excel 或同步钉钉计算,生成异常清单、核算批次、锁定状态和导出入口。
  • 自动统计出勤天数、缺勤天数、请假工时、缺卡、迟到扣款。
  • 按下班打卡时间自动计算加班17:00 下班18:00 计 1 小时20:30 计 3 小时。
  • 自动计算:剩余加班工时 = 打卡推算加班工时 - 请假工时
  • 迟到规则5 分钟内 3 次合格,超过后每次扣 30 元;超过 5 分钟每次扣 30 元。
  • 缺卡规则:每次扣 20 元。
  • 支持组织架构、员工维护、薪资维护、提成管理、规则配置、操作日志、统计报表。
  • 薪资模式支持:包月、计时、计件、试用期。
  • 加班费支持:工作日、周末、法定节假日独立单价。
  • 提成支持手工维护和 Excel 导入,并按工资月份自动汇总进工资计算。
  • 工资计算结果会落库为工资汇总、工资明细、考勤记录、请假记录和加班记录。
  • 实时薪资预估只用于过程查看,最终工资以月度核算锁定结果为准。

项目结构

main.py                         后端启动入口
config/                         后端配置文件
financial_system/
  api/                           FastAPI app、路由、schema、依赖注入
  core/                          配置、权限、安全、日志
  database/                      ORM、数据库会话、SQL脚本
  domain/                        领域模型、工资计算器
  integrations/                  钉钉等外部系统适配
  io/                            Excel解析、导出、文件存储
  repositories/                  数据库读写层
  services/                      业务服务层
frontend/                        Vue3 前端项目

分层约定:

  • routers 只处理 HTTP、权限、参数和操作日志。
  • schemas 只定义请求响应结构。
  • services 只做业务编排和校验。
  • repositories 只负责 ORM 读写。
  • domain 只负责纯计算规则,不依赖数据库和 HTTP。

运行环境

后端使用 Conda 环境:

/Users/jiaolongyan/miniconda3/envs/Financial_System/bin/python main.py

默认访问:

前端启动:

cd frontend
npm install
npm run dev

前端构建:

cd frontend
npm run build

Docker 运行(外部 MySQL

项目已提供后端镜像、前端 Nginx 镜像和 docker-compose.yml。数据库使用外部 MySQL不会在 compose 里启动 MySQL 容器。

  1. 准备环境变量:
cp .env.docker.example .env
  1. 修改 .env 里的 DATABASE_URL
DATABASE_URL=mysql+pymysql://用户名:密码@MySQL地址:3306/financial_system?charset=utf8mb4

如果 MySQL 就运行在当前电脑,并且你使用 Docker DesktopMySQL 地址通常写:

DATABASE_URL=mysql+pymysql://root:12345678@host.docker.internal:3306/financial_system?charset=utf8mb4

如果 MySQL 在另一台服务器,写那台服务器的内网 IP、外网 IP 或域名。不要在容器里使用 localhost 连接外部 MySQL因为 localhost 指向的是后端容器本身。

  1. 启动:
docker compose up --build

默认访问:

后端容器启动时会按外部 MySQL 自动建库、建表并初始化默认超级管理员。请确认外部 MySQL 已允许该账号远程连接,并且账号有创建数据库和建表权限。

统一配置

后端配置统一放在:

config/app_settings.json

常用配置:

配置 说明
server.host / server.port 后端监听地址和端口
database.url 数据库连接
系统时区 后端统一使用 Asia/ShanghaiMySQL 会话启动时自动设置为 +08:00
dingtalk.app_key / dingtalk.app_secret 钉钉开放平台凭证
storage.upload_dir 上传文件目录
storage.output_dir 导出工资文件目录
storage.avatar_dir 头像上传目录
logging.* info/error 日志文件和滚动策略
auth.secret_key Token 签名密钥
bootstrap_superuser.* 首次启动超级管理员
cors.allowed_origins 前端跨域来源

默认 MySQL

{
  "database": {
    "url": "mysql+pymysql://root:12345678@localhost:3306/financial_system?charset=utf8mb4"
  }
}

如需使用其他配置文件:

APP_CONFIG_FILE=/path/to/app_settings.json /Users/jiaolongyan/miniconda3/envs/Financial_System/bin/python main.py

数据库

本地 MySQL

host: localhost
port: 3306
user: root
password: 12345678
database: financial_system

完整初始化:

mysql -h localhost -P 3306 -u root -p12345678 < financial_system/database/sql/init_mysql.sql

已有旧库升级到当前版本:

mysql -h localhost -P 3306 -u root -p12345678 financial_system < financial_system/database/sql/upgrade_20260617_payroll_modules.sql
mysql -h localhost -P 3306 -u root -p12345678 financial_system < financial_system/database/sql/upgrade_20260618_monthly_payroll_center.sql

如果历史页面时间整体少 8 小时,说明旧数据曾按 UTC 写入,可确认后执行一次修正脚本:

mysql -h localhost -P 3306 -u root -p12345678 financial_system < financial_system/database/sql/upgrade_20260623_timezone_shanghai.sql

SQL 文件说明:

文件 说明
schema.sql 建库建表脚本,包含所有表和字段注释
seed.sql 初始化默认超级管理员
init_mysql.sql 一键初始化脚本,包含建库、建表、默认配置、默认管理员
upgrade_20260617_payroll_modules.sql 当前薪酬考勤完整模块升级脚本
upgrade_20260618_monthly_payroll_center.sql 实时考勤同步、薪资预估、月度核算批次和异常清单升级脚本
upgrade_20260623_timezone_shanghai.sql 一次性修正历史 UTC 时间为北京时间,确认整体少 8 小时后再执行

主要业务表:

说明
users 系统用户
departments 部门及上下级关系
positions 部门下的岗位
employees 员工档案
salary_profiles 员工薪资档案
attendance_record 标准化考勤记录
leave_record 请假/调休记录
overtime_record 加班记录
commission_record 提成/奖金记录
payroll_jobs 工资计算任务
payroll_results 员工工资计算结果
attendance_sync_jobs 钉钉/Excel 考勤同步批次
salary_preview 本月进行中的薪资预估
monthly_payroll_runs 月度正式核算批次
payroll_exceptions 月度核算异常清单
salary_record 月度工资汇总
salary_detail 工资明细项
salary_config 规则配置中心
operation_logs 操作日志

服务启动时会执行 ORM 建表检查,并补齐默认超级管理员和规则配置。

组织架构启动时会按内置层级补齐部门和岗位:

  • 部门顺序按总经办、行政人事部、财务部、订单部、工程部、杭州运营中心、华南/华中/西南运营中心、生产中心等层级维护。
  • 工程部-安装队工程部-项目预算 会挂到自动补齐的 工程部 父级下。
  • 杭州运营中心-销售部 会挂到自动补齐的 杭州运营中心 父级下。
  • 生产中心-采购部/仓库/品管部/生产部 会挂到 生产中心 下。
  • 西南运营中心-办事处/销售部 会挂到 西南运营中心 下。
  • 岗位编码由系统自动生成,页面只展示编码,不需要人工维护。

员工维护中,员工编号同样由系统自动生成,默认格式为 ZA0001ZA0002 递增,前端只展示不手工维护。

规则配置

规则配置既可以通过前端“规则配置”页面维护,也可以参考:

config/salary_rules.example.json

默认关键规则:

  • 上班时间08:30
  • 下班时间17:00
  • 加班取整60 分钟向下取整
  • 标准日工时8 小时
  • 5 分钟内迟到免扣次数3 次
  • 迟到扣款30 元/次
  • 缺卡扣款20 元/次
  • 周末定义:周六、周日
  • 法定节假日:可在规则配置中维护日期数组

工资公式:

应发工资 = 基础工资 + 提成 + 加班费 - 迟到扣款 - 缺卡扣款 - 其他扣款

基础工资按薪资模式计算:

  • 包月:固定底薪
  • 计时:实际工作工时 × 小时单价
  • 计件:计件数量 × 计件单价
  • 试用期:底薪 × 固定比例,或固定金额

前端页面

页面 路由 说明
登录 /login 用户登录
工作台 /dashboard 系统概览
实时考勤 /attendance/realtime 查看今日打卡、迟到、缺卡、请假、加班和本月薪资预估
月度核算 /payroll/monthly 按月导入/同步、计算、异常处理、锁定和导出
工资计算 /payroll Excel 导入和钉钉实时计算
计算记录 /payroll/jobs 查看历史计算任务
提成管理 /payroll/commissions 手工维护和 Excel 导入提成
统计报表 /reports 工资汇总、部门汇总、考勤工时
组织架构 /system/organization 维护部门上下级和部门岗位
员工维护 /system/employees 员工分页维护
薪资维护 /system/salary-profiles 员工薪资模式和加班单价
规则配置 /system/configs 考勤和薪资规则
用户管理 /system/users 超级用户创建账号
操作日志 /system/operation-logs 查看系统操作审计

前端支持主题色切换、侧边栏收起、个人资料修改、头像上传、修改密码。

登录与权限

首次启动默认超级管理员:

用户名admin
密码Admin@123456
角色superuser

角色:

角色 说明
superuser 超级用户,拥有全部菜单和操作权限
manager 管理者,可维护组织架构、员工、薪资、提成、规则、报表和工资计算
viewer 查看用户,可查看计算记录、下载结果和统计报表

登录示例:

curl -X POST "http://127.0.0.1:8000/api/auth/login" \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"Admin@123456"}'

常用接口

上传 Excel 计算工资:

curl -X POST "http://127.0.0.1:8000/api/payroll/excel" \
  -H "Authorization: Bearer <access_token>" \
  -F "file=@/path/to/月度汇总.xlsx" \
  -F "export_excel=true"

实时考勤看板同步钉钉:

curl -X POST "http://127.0.0.1:8000/api/attendance/realtime/sync" \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{"attendance_date":"2026-06-22","include_salary_preview":true}'

查看实时考勤看板:

curl "http://127.0.0.1:8000/api/attendance/realtime/today?date=2026-06-22" \
  -H "Authorization: Bearer <access_token>"

月度核算同步钉钉并计算:

curl -X POST "http://127.0.0.1:8000/api/payroll/monthly/dingtalk" \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{"salary_month":"2026-06","source_type":"dingtalk","export_excel":true}'

旧版钉钉实时计算接口仍可使用,但需要手动传 user_ids

curl -X POST "http://127.0.0.1:8000/api/payroll/dingtalk/realtime" \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{"user_ids":["001","002"],"start_date":"2026-05-01","end_date":"2026-05-31","export_excel":true}'

新增提成:

curl -X POST "http://127.0.0.1:8000/api/commissions" \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{"employee_id":1,"commission_month":"2026-06","commission_type":"销售提成","amount":1000,"source_type":"manual","business_ref":"","remark":""}'

查询统计报表:

curl "http://127.0.0.1:8000/api/reports/payroll-summary?salary_month=2026-06" \
  -H "Authorization: Bearer <access_token>"

日志

日志统一由 financial_system/core/logger.py 封装。

默认文件:

文件 说明
logs/info.log 正常流程日志
logs/error.log 错误和异常日志

修改 config/app_settings.jsonlogging.* 后重启服务即可生效。