项目:值班排班管理系统

举报
哦啦啦啦啦 发表于 2026/08/30 22:41:54 2026/08/30
【摘要】 一、今日工作概述对 scheduling-app 项目进行全量代码审查,完成两项 P0 级修复,通过全部测试后发布至华为云开发者作品展览馆。阶段内容耗时(估)代码审查拉取仓库,逐文件审阅,产出优化建议清单—P0 修复#1 防连续值班 + #4 year 参数校验—测试验证新增 1 个测试用例,9/9 全部通过—作品发布截图 → 封面 → 详情文章 → 发布 → 领积分— 二、代码审查结论对...

一、今日工作概述

scheduling-app 项目进行全量代码审查,完成两项 P0 级修复,通过全部测试后发布至华为云开发者作品展览馆。

阶段 内容 耗时(估)
代码审查 拉取仓库,逐文件审阅,产出优化建议清单
P0 修复 #1 防连续值班 + #4 year 参数校验
测试验证 新增 1 个测试用例,9/9 全部通过
作品发布 截图 → 封面 → 详情文章 → 发布 → 领积分

二、代码审查结论

app.pyscheduler.pytest_scheduler.pyapp.jsindex.htmlstyle.css 逐文件审查后,按影响程度分六层提出 19 项优化建议,摘录如下:

按优先级分布

级别 数量 代表项
🔴 P0(必修) 2 防连续值班、year 参数校验
🟡 P1(应修) 3 多年份测试、导出 CSV、生产部署文档
🟢 P2(建议) 14 死代码清理、类型注解、日志、CI、Dockerfile 等

关键发现

  • 算法层sparse_score(×10)权重远低于 yearly_score(×100),无法有效阻止同一人连续值班;monthly_avg 未扣除轮休天数导致月度均衡评分系统性偏移。
  • 安全面year 参数无边界校验,/api/regeneratedata.get('year') 不做类型转换,非法输入直接 500。
  • 测试层:仅覆盖 2025 年,未验证闰年(2024)等边界条件;无 API 层测试;未测试 seed 可复现性。

三、代码变更明细

3.1 scheduler.py — 防连续值班硬约束

问题:原算法仅靠 sparse_score = days_since_last * 10 作为软偏好,被 yearly_score(×100)轻易压过,同一人可能连续 2-3 天值班。

修复:在 generate_month 的每日循环中,计算完 available(已排除轮休人员)后,加入硬约束排除逻辑:

# 防止同一人连续值班:当可用人员 ≥ 2 时,排除昨天值班的人
if len(available) > 1:
    yesterday = date(self.year, month, day) - timedelta(days=1)
    just_duty = [p for p in available
                 if self.last_duty_date[p] == yesterday]
    if just_duty and len(available) > len(just_duty):
        available = [p for p in available if p not in just_duty]

设计考量

  • 用硬排除而非软扣分——保证无论评分如何,都不会连班。
  • 保留 fallback:排除后无人可用时不排除(总不能空班),实际测试中未触发。
  • 跨月边界自然生效:last_duty_date 在全年生成时跨月持续维护。
  • 新增 from datetime import date, timedelta 导入。

3.2 app.py — year 参数校验

问题year 参数无边界校验,/api/regeneratedata.get('year', 2025) 不做类型转换,传入字符串直接透传给 Scheduler,后续 calendar.monthrange 报 500。

修复:新增 _validate_year() 函数,两个接口都接入:

MIN_YEAR = 2000
MAX_YEAR = 2100

def _validate_year(year):
    try:
        year = int(year)
    except (TypeError, ValueError):
        return None, 'year 必须是整数'
    if year < MIN_YEAR or year > MAX_YEAR:
        return None, f'year 必须在 {MIN_YEAR}-{MAX_YEAR} 之间'
    return year, None

/api/schedule/api/regenerate 均改为先校验再使用,非法返回 400 + 错误信息。

3.3 test_scheduler.py — 新增防连续值班测试

def test_no_consecutive_duty(self):
    """同一人不应连续两天值班(跨月边界也要检查)"""
    prev_person = None
    for month_data in self.result['months']:
        for day_info in month_data['days']:
            duty = day_info['duty_person']
            if duty is not None and prev_person is not None:
                self.assertNotEqual(duty, prev_person, ...)
            prev_person = duty

变更统计

 app.py            | 26 ++++++++++++++++++++++++--
 scheduler.py      | 11 ++++++++++-
 test_scheduler.py | 14 ++++++++++++++
 3 files changed, 48 insertions(+), 3 deletions(-)

四、测试结果

test_balance_gap_within_target      ... ok   固定6人全年均衡差距 ≤ 2
test_fixed_people_have_similar_total_duties ... ok
test_every_day_has_duty_person      ... ok   每天恰好1人值班
test_no_consecutive_duty            ... ok   ★ 新增:无连续值班
test_duty_person_is_valid           ... ok   值班人在当月人员名单中
test_resting_people_not_on_duty     ... ok   轮休人当天不值班
test_extra_people_only_in_sep_to_dec ... ok  额外人员仅9-12月
test_month_days_match_calendar      ... ok   月天数与日历一致
test_year_has_12_months             ... ok   全年12个月

Ran 9 tests in 0.034s — OK

API 层验证(年份校验)

请求 状态码 说明
year=2025 200 正常
year=1999 400 超出下限
year=9999 400 超出上限
year=abc 400 非整数
POST {"year":"not_a_number"} 400 非整数

六、待办事项(P1,计划明日完成)

序号 项目 说明
#8 多年份测试 当前仅测 2025,需覆盖 2024(闰年)、2026、2027 等
#14 导出 CSV 用户最可能立刻需要的功能,加一个"导出本月"按钮

其他 P2 项(不急)

  • #9 API 层测试(Flask test client)
  • #10 seed 可复现性测试
  • #11 清理死代码(FIXED_PEOPLE/EXTRA_PEOPLE/ALL_PEOPLE 兼容别名)
  • #12 添加类型注解
  • #13 引入 logging
  • #15 标记"今天"行高亮
  • #17 CI 配置
  • #18 Dockerfile
  • #19 健康检查端点

七、反思

做得好的

  • 审查时分层归类、按优先级排序,避免一把抓。
  • P0 修复用硬约束而非软评分,从根上解决问题。
  • 每步改完立刻跑测试,没有攒一堆再验。

可改进的

  • 审查时花了不少时间读前端 CSS(400 行),其实 CSS 对排班质量无影响,优先级应该更低。
  • 发布流程中封面设计尝试了一次就过了,如果字形校验没过会卡比较久——下次可以先把字体门禁跑完再写封面 HTML。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。