30 KiB
月度核算中心与实时考勤看板 Implementation Plan
For Claude: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
Goal: 将当前薪酬考勤系统从“多个功能页分散操作”升级为“实时考勤看板 + 月度核算中心”的主流程系统,支持钉钉实时同步、Excel 导入、考勤标准化、薪资预估、月度工资复核、锁定和导出。
Architecture: 后端继续沿用 FastAPI 分层架构:router 只处理 HTTP 和权限,schema 只定义请求响应,service 负责编排,repository 负责 ORM 读写,domain 负责纯计算。新增实时考勤和月度核算模块时,复用现有 PayrollCalculator、MonthlySummaryParser、DingTalkAttendanceAdapter、attendance_record、payroll_results 等能力,只补齐同步批次、实时预估、月度核算状态和异常记录。
Tech Stack: Python 3 / FastAPI / SQLAlchemy / MySQL / openpyxl / Vue 3 / Pinia / Vue Router / TypeScript / Vite / lucide-vue。
目标业务流
实时考勤看板
-> 读取在职员工和钉钉 userId
-> 同步今天或本月至今的钉钉打卡
-> 标准化为每日考勤
-> 展示今日打卡、迟到、缺卡、请假、加班和本月薪资预估
月度核算中心
-> 选择工资月份
-> 同步钉钉或导入 Excel
-> 标准化考勤
-> 生成异常清单
-> 计算工资
-> 复核员工明细
-> 锁定本月工资
-> 导出工资表和报表
阶段 0:开发前保护
Task 0.1: 建立当前基线
Files:
- Read:
README.md - Read:
financial_system/database/orm.py - Read:
financial_system/services/payroll_service.py - Read:
financial_system/api/routers/payroll.py - Read:
frontend/src/router/index.ts - Read:
frontend/src/components/SidebarNav.vue - Read:
frontend/src/views/PayrollView.vue
Step 1: 查看工作区状态
Run:
git status --short
Expected: 确认哪些文件已有用户改动。不要回滚任何非本任务改动。
Step 2: 编译当前后端
Run:
/Users/jiaolongyan/miniconda3/envs/Financial_System/bin/python -m compileall financial_system
Expected: financial_system 编译成功。
Step 3: 构建当前前端
Run:
cd frontend
npm run build
Expected: Vite build 通过。
Step 4: Commit
本任务只做基线验证,不需要 commit。
阶段 1:数据库模型与 SQL
Task 1.1: 增加实时同步和月度核算 ORM
Files:
- Modify:
financial_system/database/orm.py - Modify:
financial_system/database/sql/schema.sql - Modify:
financial_system/database/sql/init_mysql.sql - Create:
financial_system/database/sql/upgrade_20260618_monthly_payroll_center.sql
Step 1: 设计新增表
新增 4 张表,所有表和字段都必须有 MySQL 注释:
attendance_sync_jobs
id
source_type
sync_mode
attendance_date
salary_month
start_date
end_date
status
employee_count
record_count
error_message
created_by
created_at
updated_at
salary_preview
id
sync_job_id
employee_id
employee_no
employee_name
department
position
salary_month
attendance_days
actual_work_hours
punch_overtime_hours
leave_hours
remaining_overtime_hours
late_deduction
missing_card_deduction
commission_amount
overtime_pay
estimated_gross_salary
estimated_net_salary
status
note
created_at
updated_at
monthly_payroll_runs
id
salary_month
source_type
source_job_id
status
employee_count
gross_total
net_total
deduction_total
overtime_total
locked_by
locked_at
created_by
created_at
updated_at
payroll_exceptions
id
run_id
sync_job_id
employee_id
employee_no
employee_name
salary_month
exception_type
severity
message
status
created_at
resolved_at
Step 2: 修改 ORM
在 financial_system/database/orm.py 中新增:
class AttendanceSyncJobORM(Base):
"""钉钉或 Excel 考勤同步批次,用于实时看板和月度核算追踪。"""
__tablename__ = "attendance_sync_jobs"
...
class SalaryPreviewORM(Base):
"""本月进行中的薪资预估结果,不作为最终工资发放依据。"""
__tablename__ = "salary_preview"
...
class MonthlyPayrollRunORM(Base):
"""月度正式核算批次,支持复核、锁定和导出。"""
__tablename__ = "monthly_payroll_runs"
...
class PayrollExceptionORM(Base):
"""核算异常记录,例如缺员工、缺薪资档案、缺卡、请假无法识别。"""
__tablename__ = "payroll_exceptions"
...
字段类型沿用现有风格:金额用 Float,月份用 String(7),状态用 String(32),时间用 DateTime。
Step 3: 更新 SQL
在 schema.sql 和 init_mysql.sql 中增加建表语句。新增 upgrade_20260618_monthly_payroll_center.sql,包含 CREATE TABLE IF NOT EXISTS,可对已有库安全执行。
Step 4: 编译验证
Run:
/Users/jiaolongyan/miniconda3/envs/Financial_System/bin/python -m compileall financial_system
Expected: PASS。
Step 5: Commit
git add financial_system/database/orm.py financial_system/database/sql/schema.sql financial_system/database/sql/init_mysql.sql financial_system/database/sql/upgrade_20260618_monthly_payroll_center.sql
git commit -m "feat: add monthly payroll center tables"
Task 1.2: 增加权限和菜单
Files:
- Modify:
financial_system/core/permissions.py - Modify:
frontend/src/router/index.ts - Modify:
frontend/src/components/SidebarNav.vue
Step 1: 增加权限码
在 financial_system/core/permissions.py 增加:
PERMISSION_ATTENDANCE_REALTIME_VIEW = "attendance:realtime:view"
PERMISSION_ATTENDANCE_REALTIME_SYNC = "attendance:realtime:sync"
PERMISSION_MONTHLY_PAYROLL_VIEW = "monthly_payroll:view"
PERMISSION_MONTHLY_PAYROLL_CALCULATE = "monthly_payroll:calculate"
PERMISSION_MONTHLY_PAYROLL_LOCK = "monthly_payroll:lock"
PERMISSION_MONTHLY_PAYROLL_EXPORT = "monthly_payroll:export"
Step 2: 增加菜单
新增菜单:
"attendance_realtime": MenuPermission(
code="attendance_realtime",
name="实时考勤",
path="/attendance/realtime",
),
"monthly_payroll": MenuPermission(
code="monthly_payroll",
name="月度核算",
path="/payroll/monthly",
),
超级用户和管理者可见两个菜单;查看权限至少可见 实时考勤 和报表,是否能看月度工资按业务需要决定,默认仅查看 实时考勤。
Step 3: 前端路由占位
在 frontend/src/router/index.ts 先注册页面:
{
path: "attendance/realtime",
name: "attendance-realtime",
component: RealtimeAttendanceView,
meta: { permission: "attendance:realtime:view" },
},
{
path: "payroll/monthly",
name: "monthly-payroll",
component: MonthlyPayrollView,
meta: { permission: "monthly_payroll:view" },
},
Step 4: 侧边栏图标
在 frontend/src/components/SidebarNav.vue 中增加图标映射:
attendance_realtime: CalendarClock,
monthly_payroll: Calculator,
Step 5: 验证
Run:
cd frontend
npm run build
Expected: PASS。
Step 6: Commit
git add financial_system/core/permissions.py frontend/src/router/index.ts frontend/src/components/SidebarNav.vue
git commit -m "feat: add realtime attendance and monthly payroll menus"
阶段 2:后端实时考勤看板
Task 2.1: 增加实时考勤 schema
Files:
- Create:
financial_system/api/schemas/realtime_attendance.py - Modify:
financial_system/api/schemas/__init__.py
Step 1: 编写 schema
Create financial_system/api/schemas/realtime_attendance.py:
from __future__ import annotations
from datetime import date, datetime
from pydantic import BaseModel
class RealtimeAttendanceSyncRequest(BaseModel):
attendance_date: date
include_salary_preview: bool = True
class TodayAttendanceItem(BaseModel):
employee_id: int | None
employee_no: str
employee_name: str
department: str
position: str
first_punch: str
last_punch: str
attendance_status: str
late_minutes: int
missing_card_count: int
leave_hours: float
today_overtime_hours: float
month_remaining_overtime_hours: float
estimated_net_salary: float | None
note: str
class RealtimeAttendanceSummary(BaseModel):
attendance_date: date
employee_total: int
checked_in_count: int
unchecked_count: int
late_count: int
leave_count: int
missing_card_count: int
estimated_overtime_count: int
estimated_net_total: float
class RealtimeAttendanceResponse(BaseModel):
sync_job_id: str | None
synced_at: datetime | None
summary: RealtimeAttendanceSummary
items: list[TodayAttendanceItem]
Step 2: 编译验证
Run:
/Users/jiaolongyan/miniconda3/envs/Financial_System/bin/python -m compileall financial_system
Expected: PASS。
Step 3: Commit
git add financial_system/api/schemas/realtime_attendance.py financial_system/api/schemas/__init__.py
git commit -m "feat: add realtime attendance schemas"
Task 2.2: 增加实时考勤 Repository
Files:
- Create:
financial_system/repositories/realtime_attendance_repository.py - Modify:
financial_system/repositories/__init__.py
Step 1: 实现 repository
Repository 负责:
- 查询在职员工和钉钉 userId。
- 创建
attendance_sync_jobs。 - 保存
attendance_record。 - 保存
salary_preview。 - 查询某日考勤记录。
- 查询某月薪资预估。
核心方法:
class RealtimeAttendanceRepository:
def list_active_employees_with_dingtalk(self) -> list[EmployeeORM]: ...
def create_sync_job(...) -> AttendanceSyncJobORM: ...
def mark_sync_completed(...) -> None: ...
def mark_sync_failed(...) -> None: ...
def replace_attendance_records(...) -> None: ...
def replace_salary_previews(...) -> None: ...
def list_today_records(...) -> list[AttendanceRecordORM]: ...
def list_salary_previews(...) -> list[SalaryPreviewORM]: ...
Step 2: 注意幂等
同一天多次同步时,应按 source_type=dingtalk + work_date + employee_id 替换当天记录,避免列表越来越多。
Step 3: 编译验证
Run:
/Users/jiaolongyan/miniconda3/envs/Financial_System/bin/python -m compileall financial_system
Expected: PASS。
Step 4: Commit
git add financial_system/repositories/realtime_attendance_repository.py financial_system/repositories/__init__.py
git commit -m "feat: add realtime attendance repository"
Task 2.3: 增加实时薪资预估服务
Files:
- Create:
financial_system/services/realtime_attendance_service.py - Modify:
financial_system/services/__init__.py - Modify:
financial_system/api/dependencies.py
Step 1: 实现服务职责
RealtimeAttendanceService 负责:
- 从数据库拿在职员工。
- 自动收集员工
dingtalk_user_id,不再让用户手填。 - 调用
DingTalkClient.list_attendance_records。 - 使用
DingTalkAttendanceAdapter转成EmployeeAttendance。 - 使用
PayrollCalculator计算本月薪资预估。 - 写入
attendance_record和salary_preview。 - 输出今日考勤列表和汇总。
Step 2: 保持预估语义
返回字段命名使用 estimated_*,页面文案必须展示“预估金额,最终以月度核算锁定结果为准”。
Step 3: 缺少钉钉配置
复用 PayrollApplicationService._dingtalk_settings() 的逻辑,或者抽出公共 helper。缺少 app_key/app_secret 时返回 400,提示用户修改 config/app_settings.json。
Step 4: 编译验证
Run:
/Users/jiaolongyan/miniconda3/envs/Financial_System/bin/python -m compileall financial_system
Expected: PASS。
Step 5: Commit
git add financial_system/services/realtime_attendance_service.py financial_system/services/__init__.py financial_system/api/dependencies.py
git commit -m "feat: add realtime attendance service"
Task 2.4: 增加实时考勤 API
Files:
- Create:
financial_system/api/routers/realtime_attendance.py - Modify:
financial_system/api/app.py
Step 1: 新增路由
Create router prefix:
router = APIRouter(prefix="/api/attendance/realtime", tags=["realtime-attendance"])
Endpoints:
GET /api/attendance/realtime/today?date=YYYY-MM-DD
POST /api/attendance/realtime/sync
Step 2: 权限
GET today使用PERMISSION_ATTENDANCE_REALTIME_VIEWPOST sync使用PERMISSION_ATTENDANCE_REALTIME_SYNC
Step 3: 操作日志
同步成功记录:
module=attendance
action=attendance.realtime.sync
target_type=attendance_sync_job
查看成功记录:
module=attendance
action=attendance.realtime.view
Step 4: 注册路由
在 financial_system/api/app.py 导入并 include_router(realtime_attendance.router)。
Step 5: 编译验证
Run:
/Users/jiaolongyan/miniconda3/envs/Financial_System/bin/python -m compileall financial_system
Expected: PASS。
Step 6: Commit
git add financial_system/api/routers/realtime_attendance.py financial_system/api/app.py
git commit -m "feat: add realtime attendance api"
阶段 3:后端月度核算中心
Task 3.1: 增加月度核算 schema
Files:
- Create:
financial_system/api/schemas/monthly_payroll.py - Modify:
financial_system/api/schemas/__init__.py
Step 1: 定义请求响应
Create:
class MonthlyPayrollCreateRequest(BaseModel):
salary_month: str
source_type: str
export_excel: bool = True
class MonthlyPayrollImportExcelResponse(BaseModel):
run_id: int
status: str
employee_count: int
exception_count: int
class MonthlyPayrollRunResponse(BaseModel):
id: int
salary_month: str
source_type: str
status: str
employee_count: int
gross_total: float
net_total: float
deduction_total: float
overtime_total: float
locked_by: str
locked_at: datetime | None
created_at: datetime
updated_at: datetime
class MonthlyPayrollDetailResponse(BaseModel):
run: MonthlyPayrollRunResponse
results: list[PayrollResultItem]
exceptions: list[PayrollExceptionItem]
PayrollResultItem 可复用现有 financial_system/api/schemas/payroll.py 中的结果 schema,避免重复字段。
Step 2: 编译验证
Run:
/Users/jiaolongyan/miniconda3/envs/Financial_System/bin/python -m compileall financial_system
Expected: PASS。
Step 3: Commit
git add financial_system/api/schemas/monthly_payroll.py financial_system/api/schemas/__init__.py
git commit -m "feat: add monthly payroll schemas"
Task 3.2: 增加月度核算 Repository
Files:
- Create:
financial_system/repositories/monthly_payroll_repository.py - Modify:
financial_system/repositories/__init__.py
Step 1: 实现方法
Repository 负责:
class MonthlyPayrollRepository:
def create_run(...) -> MonthlyPayrollRunORM: ...
def get_run(run_id: int) -> MonthlyPayrollRunORM | None: ...
def get_run_by_month(salary_month: str) -> MonthlyPayrollRunORM | None: ...
def update_run_totals(...) -> None: ...
def lock_run(...) -> None: ...
def replace_exceptions(...) -> None: ...
def list_exceptions(...) -> list[PayrollExceptionORM]: ...
Step 2: 锁定保护
如果 monthly_payroll_runs.status == "locked",任何重新计算或覆盖结果都必须拒绝。
Step 3: 编译验证
Run:
/Users/jiaolongyan/miniconda3/envs/Financial_System/bin/python -m compileall financial_system
Expected: PASS。
Step 4: Commit
git add financial_system/repositories/monthly_payroll_repository.py financial_system/repositories/__init__.py
git commit -m "feat: add monthly payroll repository"
Task 3.3: 增加异常识别规则
Files:
- Create:
financial_system/domain/payroll_exceptions.py
Step 1: 实现纯函数
Create:
def detect_payroll_exceptions(results: list[PayrollResult]) -> list[PayrollException]:
...
异常类型:
missing_salary_profile
missing_employee_match
missing_dingtalk_user_id
missing_card
late_penalty
negative_remaining_overtime
empty_attendance
Step 2: 规则建议
base_pay is None->missing_salary_profilemissing_card_count > 0->missing_cardpenalized_late_count > 0->late_penaltyremaining_overtime_hours < 0->negative_remaining_overtimeattendance_days == 0->empty_attendance
Step 3: 编译验证
Run:
/Users/jiaolongyan/miniconda3/envs/Financial_System/bin/python -m compileall financial_system
Expected: PASS。
Step 4: Commit
git add financial_system/domain/payroll_exceptions.py
git commit -m "feat: add payroll exception detection"
Task 3.4: 增加月度核算服务
Files:
- Create:
financial_system/services/monthly_payroll_service.py - Modify:
financial_system/services/__init__.py - Modify:
financial_system/api/dependencies.py
Step 1: 服务职责
MonthlyPayrollService 负责:
- Excel 导入并创建月度 run。
- 钉钉全量同步并创建月度 run。
- 复用
PayrollApplicationService或直接复用 parser/calculator。 - 生成工资结果。
- 生成异常记录。
- 更新 run 汇总金额。
- 锁定工资。
- 导出工资文件。
Step 2: 状态机
状态只保留必要值:
draft 草稿/已导入
calculated 已计算
reviewed 已复核
locked 已锁定
failed 失败
Step 3: 锁定规则
锁定后:
- 不允许重新计算。
- 不允许覆盖结果。
- 允许导出。
- 操作日志必须记录锁定人。
Step 4: 编译验证
Run:
/Users/jiaolongyan/miniconda3/envs/Financial_System/bin/python -m compileall financial_system
Expected: PASS。
Step 5: Commit
git add financial_system/services/monthly_payroll_service.py financial_system/services/__init__.py financial_system/api/dependencies.py
git commit -m "feat: add monthly payroll service"
Task 3.5: 增加月度核算 API
Files:
- Create:
financial_system/api/routers/monthly_payroll.py - Modify:
financial_system/api/app.py
Step 1: 新增路由
Create router prefix:
router = APIRouter(prefix="/api/payroll/monthly", tags=["monthly-payroll"])
Endpoints:
GET /api/payroll/monthly/runs?month=YYYY-MM
GET /api/payroll/monthly/runs/{run_id}
POST /api/payroll/monthly/excel
POST /api/payroll/monthly/dingtalk
POST /api/payroll/monthly/runs/{run_id}/recalculate
POST /api/payroll/monthly/runs/{run_id}/lock
GET /api/payroll/monthly/runs/{run_id}/export
Step 2: 权限
- 查看:
PERMISSION_MONTHLY_PAYROLL_VIEW - 计算:
PERMISSION_MONTHLY_PAYROLL_CALCULATE - 锁定:
PERMISSION_MONTHLY_PAYROLL_LOCK - 导出:
PERMISSION_MONTHLY_PAYROLL_EXPORT
Step 3: 操作日志
记录以下动作:
monthly_payroll.view
monthly_payroll.excel.import
monthly_payroll.dingtalk.calculate
monthly_payroll.recalculate
monthly_payroll.lock
monthly_payroll.export
Step 4: 注册路由
在 financial_system/api/app.py 导入并 include。
Step 5: 编译验证
Run:
/Users/jiaolongyan/miniconda3/envs/Financial_System/bin/python -m compileall financial_system
Expected: PASS。
Step 6: Commit
git add financial_system/api/routers/monthly_payroll.py financial_system/api/app.py
git commit -m "feat: add monthly payroll api"
阶段 4:前端信息架构和 API
Task 4.1: 重组菜单展示
Files:
- Modify:
frontend/src/components/SidebarNav.vue - Modify:
frontend/src/assets/styles.css
Step 1: 分组菜单
将菜单视觉分组为:
工作台
实时考勤
月度核算
工资核算
计算记录
提成录入
员工薪资
员工维护
薪资档案
组织架构
报表分析
工资报表
系统管理
规则配置
用户管理
操作日志
Step 2: 收起侧栏体验
收起时隐藏分组文字,只保留图标;悬停显示 title。保持现在的平滑过渡变量:
--motion-duration: 280ms;
--motion-easing: cubic-bezier(0.22, 1, 0.36, 1);
Step 3: 构建验证
Run:
cd frontend
npm run build
Expected: PASS。
Step 4: Commit
git add frontend/src/components/SidebarNav.vue frontend/src/assets/styles.css
git commit -m "feat: group sidebar navigation"
Task 4.2: 增加前端 API 类型
Files:
- Modify:
frontend/src/api/types.ts - Create:
frontend/src/api/realtimeAttendance.ts - Create:
frontend/src/api/monthlyPayroll.ts
Step 1: 增加类型
在 types.ts 增加:
export interface RealtimeAttendanceSummary { ... }
export interface TodayAttendanceItem { ... }
export interface RealtimeAttendanceResponse { ... }
export interface MonthlyPayrollRun { ... }
export interface PayrollException { ... }
export interface MonthlyPayrollDetailResponse { ... }
Step 2: 增加 API 方法
Create realtimeAttendance.ts:
export function getTodayAttendance(date: string): Promise<RealtimeAttendanceResponse> { ... }
export function syncRealtimeAttendance(date: string): Promise<RealtimeAttendanceResponse> { ... }
Create monthlyPayroll.ts:
export function listMonthlyRuns(month?: string): Promise<MonthlyPayrollRun[]> { ... }
export function getMonthlyRun(runId: number): Promise<MonthlyPayrollDetailResponse> { ... }
export function calculateMonthlyFromExcel(...): Promise<MonthlyPayrollDetailResponse> { ... }
export function calculateMonthlyFromDingTalk(month: string): Promise<MonthlyPayrollDetailResponse> { ... }
export function lockMonthlyRun(runId: number): Promise<MonthlyPayrollRun> { ... }
export function exportMonthlyRun(runId: number): Promise<void> { ... }
Step 3: 构建验证
Run:
cd frontend
npm run build
Expected: PASS。
Step 4: Commit
git add frontend/src/api/types.ts frontend/src/api/realtimeAttendance.ts frontend/src/api/monthlyPayroll.ts
git commit -m "feat: add realtime and monthly payroll api clients"
阶段 5:实时考勤页面
Task 5.1: 创建实时考勤页面
Files:
- Create:
frontend/src/views/RealtimeAttendanceView.vue - Modify:
frontend/src/router/index.ts
Step 1: 页面布局
页面结构:
顶部:今日考勤与薪资预估 / 日期选择 / 同步钉钉 / 自动刷新开关
摘要:应到人数、已打卡、未打卡、迟到、请假、预估加班
主表:员工今日考勤
右侧抽屉:员工本月明细
Step 2: 主表字段
员工
部门/岗位
上班打卡
下班打卡
今日状态
迟到分钟
缺卡
请假工时
今日加班
本月剩余加班
本月预估实发
Step 3: 文案
页面必须展示:
预估金额,最终以月度核算锁定结果为准
Step 4: 视觉要求
- 不使用大面积营销式卡片。
- 摘要卡片压扁,适合后台扫描。
- 表格上方保留紧凑筛选栏。
- 员工明细使用右侧抽屉,不跳页面。
Step 5: 构建验证
Run:
cd frontend
npm run build
Expected: PASS。
Step 6: Commit
git add frontend/src/views/RealtimeAttendanceView.vue frontend/src/router/index.ts
git commit -m "feat: add realtime attendance view"
Task 5.2: 接入实时考勤页面数据
Files:
- Modify:
frontend/src/views/RealtimeAttendanceView.vue
Step 1: 加载数据
页面 mounted 后默认请求今天:
const today = new Date().toISOString().slice(0, 10);
await getTodayAttendance(today);
Step 2: 同步钉钉
点击 同步钉钉 调用:
await syncRealtimeAttendance(selectedDate.value);
同步时按钮显示 loading,成功后刷新摘要和表格。
Step 3: 错误处理
钉钉未配置时显示:
钉钉配置缺失,请先在 config/app_settings.json 中配置 app_key 和 app_secret
Step 4: 构建验证
Run:
cd frontend
npm run build
Expected: PASS。
Step 5: Commit
git add frontend/src/views/RealtimeAttendanceView.vue
git commit -m "feat: connect realtime attendance data"
阶段 6:月度核算中心页面
Task 6.1: 创建月度核算中心页面
Files:
- Create:
frontend/src/views/MonthlyPayrollView.vue - Modify:
frontend/src/router/index.ts
Step 1: 页面结构
顶部:月份选择 / 当前状态 / 同步钉钉 / 导入 Excel / 导出 / 锁定
步骤条:数据导入 -> 考勤转换 -> 异常处理 -> 工资计算 -> 复核锁定
摘要条:员工数、应发、实发、扣款、剩余加班
主表:员工工资核算结果
右侧抽屉:员工每日考勤和工资拆分
异常面板:缺薪资档案、缺卡、迟到扣款、未匹配员工
Step 2: 状态文案
draft: 草稿
calculated: 已计算
reviewed: 已复核
locked: 已锁定
failed: 失败
Step 3: 锁定按钮
locked 状态下禁用重新计算和导入,只保留导出。
Step 4: 构建验证
Run:
cd frontend
npm run build
Expected: PASS。
Step 5: Commit
git add frontend/src/views/MonthlyPayrollView.vue frontend/src/router/index.ts
git commit -m "feat: add monthly payroll center view"
Task 6.2: 接入月度核算 API
Files:
- Modify:
frontend/src/views/MonthlyPayrollView.vue
Step 1: 默认月份
默认当前月份:
const selectedMonth = ref(new Date().toISOString().slice(0, 7));
Step 2: 加载 run
进入页面或月份变化时加载:
await listMonthlyRuns(selectedMonth.value);
如果已有 run,自动打开最新 run;否则显示空状态和操作按钮。
Step 3: Excel 导入
导入按钮使用隐藏 file input,不让用户填配置路径。
Step 4: 钉钉计算
点击 同步钉钉并计算,后端自动读取在职员工 dingtalk_user_id。
Step 5: 锁定确认
锁定前弹窗确认:
锁定后本月工资不能重新计算,只能导出。确认锁定?
Step 6: 构建验证
Run:
cd frontend
npm run build
Expected: PASS。
Step 7: Commit
git add frontend/src/views/MonthlyPayrollView.vue
git commit -m "feat: connect monthly payroll center api"
阶段 7:工作台改造
Task 7.1: 工作台改为流程总览
Files:
- Modify:
frontend/src/views/DashboardView.vue - Modify:
frontend/src/assets/styles.css
Step 1: 改成经营总览
工作台展示:
今日考勤状态
本月工资预估
本月核算状态
待处理异常
最近同步任务
Step 2: 快捷入口
保留按钮:
进入实时考勤
进入月度核算
提成录入
员工维护
Step 3: 移除假图表
现在 chartBars 是静态假数据。要么接后端报表,要么先移除,避免误导。
Step 4: 构建验证
Run:
cd frontend
npm run build
Expected: PASS。
Step 5: Commit
git add frontend/src/views/DashboardView.vue frontend/src/assets/styles.css
git commit -m "feat: redesign dashboard around payroll workflow"
阶段 8:文档与验证
Task 8.1: 更新 README
Files:
- Modify:
README.md - Modify:
frontend/README.md
Step 1: README 增加模块说明
补充:
实时考勤看板
月度核算中心
薪资预估和正式工资的区别
锁定规则
新增 SQL 升级脚本
Step 2: 更新运行说明
说明后端仍然使用:
/Users/jiaolongyan/miniconda3/envs/Financial_System/bin/python main.py
前端仍然使用:
cd frontend
npm run dev
Step 3: Commit
git add README.md frontend/README.md
git commit -m "docs: update payroll center documentation"
Task 8.2: 全量验证
Files:
- No source edits unless verification fails.
Step 1: 后端编译
Run:
/Users/jiaolongyan/miniconda3/envs/Financial_System/bin/python -m compileall financial_system
Expected: PASS。
Step 2: 前端构建
Run:
cd frontend
npm run build
Expected: PASS。
Step 3: 启动后端
Run:
/Users/jiaolongyan/miniconda3/envs/Financial_System/bin/python main.py
Expected: 后端启动成功,/health 返回正常。
Step 4: 启动前端
Run:
cd frontend
npm run dev
Expected: 前端启动成功。
Step 5: 浏览器验收
检查:
/attendance/realtime
/payroll/monthly
/dashboard
/system/employees
/system/salary-profiles
/payroll/commissions
验收点:
- 菜单显示分组合理。
- 实时考勤能进入,未配置钉钉时提示明确。
- 月度核算能进入,Excel 导入入口存在。
- 锁定状态不会允许重新计算。
- 侧栏收起/展开仍然平滑。
- 控制台无 error/warn。
Step 6: Commit
若修复了验证问题,按实际文件提交:
git add <changed-files>
git commit -m "fix: stabilize payroll center flow"
实施顺序建议
优先级从高到低:
- 阶段 1:数据库和菜单权限。
- 阶段 2:实时考勤后端。
- 阶段 5:实时考勤前端。
- 阶段 3:月度核算后端。
- 阶段 6:月度核算前端。
- 阶段 7:工作台改造。
- 阶段 8:文档和全量验证。
这样可以先让你看到“今天打卡和实时薪资预估”的效果,再继续完善月底正式核算。
风险点
- 钉钉接口真实字段可能和当前
DingTalkAttendanceAdapter的假设不完全一致,需要用真实返回样例校准。 - 实时薪资只能作为预估,不能覆盖正式工资结果。
- 包月员工的“本月预估工资”要确认是否按自然日、工作日进度、还是直接展示已产生工资。
- 计件员工如果没有每日计件数据,只能显示已录入计件金额,不能凭考勤自动估算。
- 锁定工资后是否允许管理员解锁,需要单独确认。当前计划默认不提供解锁。
后续可选增强
- 自动同步定时任务:每天 09:30、12:00、18:30 同步钉钉。
- 异常提醒:缺卡、迟到、未绑定钉钉 userId 自动出现在工作台。
- 工资条:锁定后生成员工工资条。
- 审批流:人事核算、财务复核、老板确认。
- 导入计件数据:为计件员工增加单独的产量录入或 Excel 导入。