generate_requirement_breakdown_excel.py 4.32 KB
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
生成「美业系统升级项目需求拆分表」Excel 文档
- 从 docs/美业系统升级项目需求拆分表_data.py 读取数据
- 输出 docs/美业系统升级项目需求拆分表.xlsx
- 含「需求拆分表」与「完整性核对说明」两个工作表
"""
import os
import sys

# 项目根目录
ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))
sys.path.insert(0, ROOT)
os.chdir(ROOT)

# 数据从同目录上一级的 docs 下读取(按项目结构)
DATA_MODULE_PATH = os.path.join(ROOT, "docs", "美业系统升级项目需求拆分表_data.py")

def load_data():
    import importlib.util
    spec = importlib.util.spec_from_file_location("req_data", DATA_MODULE_PATH)
    mod = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(mod)
    return mod.ROWS

def main():
    try:
        import openpyxl
        from openpyxl.styles import Font, Alignment, Border, Side
        from openpyxl.utils import get_column_letter
    except ImportError:
        print("请先安装 openpyxl: pip install openpyxl")
        sys.exit(1)

    rows = load_data()
    out_path = os.path.join(ROOT, "docs", "美业系统升级项目需求拆分表.xlsx")

    wb = openpyxl.Workbook()
    thin = Side(style="thin")
    border = Border(left=thin, right=thin, top=thin, bottom=thin)

    # ========== Sheet1: 需求拆分表 ==========
    ws = wb.active
    ws.title = "需求拆分表"
    headers = ["期数", "板块", "功能模块", "具体功能", "详细说明", "预估人天"]
    for col, h in enumerate(headers, 1):
        c = ws.cell(row=1, column=col, value=h)
        c.font = Font(bold=True)
        c.alignment = Alignment(horizontal="center", vertical="center", wrap_text=True)
        c.border = border
    ws.row_dimensions[1].height = 24

    for row_idx, row_data in enumerate(rows, 2):
        for col_idx, val in enumerate(row_data, 1):
            c = ws.cell(row=row_idx, column=col_idx, value=val)
            c.border = border
            if col_idx == 6:  # 预估人天
                c.alignment = Alignment(horizontal="right")
    # 列宽
    ws.column_dimensions["A"].width = 10
    ws.column_dimensions["B"].width = 18
    ws.column_dimensions["C"].width = 22
    ws.column_dimensions["D"].width = 24
    ws.column_dimensions["E"].width = 52
    ws.column_dimensions["F"].width = 10

    # 合计行
    total_row = len(rows) + 2
    ws.cell(row=total_row, column=5, value="合计(人天)").font = Font(bold=True)
    ws.cell(row=total_row, column=5).border = border
    total_days = sum(r[5] for r in rows)
    ws.cell(row=total_row, column=6, value=round(total_days, 1)).font = Font(bold=True)
    ws.cell(row=total_row, column=6).border = border

    # ========== Sheet2: 完整性核对说明 ==========
    ws2 = wb.create_sheet("完整性核对说明", 1)
    intro = [
        "一、核对结论",
        "与《客户需求梳理-一期收尾与二期规划》逐项对照,本需求拆分表已覆盖:",
        "• 一期收尾:BUG 修复 2 项、功能小优化 9 项、文案注释规范 1 项;",
        "• 二期规划:看板与统计(医美/科技部/教育部/事业部)、会员与客户、金三角与店长、品项与开单、大客与风控、人员与数据准确性、生日与短信、PC 工作台、其他补充、人事管理、预约管理、支付管理、萤石云监控对接。",
        "",
        "二、范围说明(与规划一致)",
        "• 考勤打卡:不含人脸识别、二维码打卡;",
        "• 人事:不含出差管理;薪资仅为人事侧结构与档案,不替代现有工资核算;",
        "• 预约:不做客户在线预约,以线下预约表线上化、健康师维度为主;",
        "• 支付:对接统一收款渠道(聚合支付),非分别对接微信/支付宝。",
        "",
        "三、人天说明",
        "预估人天已按「开发+联调+自测」重新评估:一期收尾合计约 9.5 人天,二期规划合计见下表。",
    ]
    for i, line in enumerate(intro, 1):
        ws2.cell(row=i, column=1, value=line)
    ws2.column_dimensions["A"].width = 90

    wb.save(out_path)
    print(f"已生成: {out_path}")
    print(f"需求条目: {len(rows)} 条,预估总人天: {round(total_days, 1)}")

if __name__ == "__main__":
    main()