from docx import Document
from docx.enum.section import WD_ORIENT
from docx.enum.table import WD_TABLE_ALIGNMENT, WD_CELL_VERTICAL_ALIGNMENT
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.oxml import OxmlElement
from docx.oxml.ns import qn
from docx.shared import Cm, Pt, RGBColor


OUT = "/Users/hedy/Desktop/zhct/outputs/guoxin_requirement_assessment/江苏国信智慧食堂需求分析与工期评估_客户版.docx"


def set_run(run, size=10.5, bold=False, color="000000", font="Microsoft YaHei"):
    run.font.name = font
    run._element.rPr.rFonts.set(qn("w:eastAsia"), font)
    run._element.rPr.rFonts.set(qn("w:ascii"), font)
    run._element.rPr.rFonts.set(qn("w:hAnsi"), font)
    run.font.size = Pt(size)
    run.bold = bold
    run.font.color.rgb = RGBColor.from_string(color)


def set_cell_shading(cell, fill):
    tc_pr = cell._tc.get_or_add_tcPr()
    shd = OxmlElement("w:shd")
    shd.set(qn("w:fill"), fill)
    tc_pr.append(shd)


def set_cell_text(cell, text, bold=False, fill=None, color="000000"):
    cell.text = ""
    p = cell.paragraphs[0]
    p.paragraph_format.space_after = Pt(0)
    p.paragraph_format.line_spacing = 1.1
    run = p.add_run(str(text))
    set_run(run, size=9, bold=bold, color=color)
    cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
    if fill:
        set_cell_shading(cell, fill)


def add_para(doc, text, style=None, bold=False, color="000000", size=10.5, after=6):
    p = doc.add_paragraph(style=style)
    p.paragraph_format.space_after = Pt(after)
    p.paragraph_format.line_spacing = 1.15
    run = p.add_run(text)
    set_run(run, size=size, bold=bold, color=color)
    return p


def add_bullets(doc, items):
    for item in items:
        p = doc.add_paragraph(style="List Bullet")
        p.paragraph_format.space_after = Pt(3)
        p.paragraph_format.line_spacing = 1.15
        run = p.add_run(item)
        set_run(run, size=10.5)


def add_table(doc, headers, rows, widths=None):
    table = doc.add_table(rows=1, cols=len(headers))
    table.alignment = WD_TABLE_ALIGNMENT.CENTER
    table.style = "Table Grid"
    for i, h in enumerate(headers):
        set_cell_text(table.rows[0].cells[i], h, bold=True, fill="E8EEF5", color="0B2545")
    for row in rows:
        cells = table.add_row().cells
        for i, value in enumerate(row):
            set_cell_text(cells[i], value)
    if widths:
        for row in table.rows:
            for idx, width in enumerate(widths):
                row.cells[idx].width = Cm(width)
    doc.add_paragraph().paragraph_format.space_after = Pt(2)
    return table


def heading(doc, text, level=1):
    p = doc.add_paragraph(style=f"Heading {level}")
    p.paragraph_format.space_before = Pt(8 if level == 1 else 5)
    p.paragraph_format.space_after = Pt(5)
    run = p.add_run(text)
    set_run(run, size=15 if level == 1 else 12, bold=True, color="2E74B5" if level == 1 else "1F4D78")
    return p


doc = Document()
sec = doc.sections[0]
sec.orientation = WD_ORIENT.LANDSCAPE
sec.page_width = Cm(29.7)
sec.page_height = Cm(21.0)
sec.top_margin = Cm(1.6)
sec.bottom_margin = Cm(1.4)
sec.left_margin = Cm(1.5)
sec.right_margin = Cm(1.5)

styles = doc.styles
styles["Normal"].font.name = "Microsoft YaHei"
styles["Normal"]._element.rPr.rFonts.set(qn("w:eastAsia"), "Microsoft YaHei")
styles["Normal"].font.size = Pt(10.5)
for s in ["List Bullet", "List Number"]:
    styles[s].font.name = "Microsoft YaHei"
    styles[s]._element.rPr.rFonts.set(qn("w:eastAsia"), "Microsoft YaHei")
    styles[s].font.size = Pt(10.5)

title = doc.add_paragraph()
title.alignment = WD_ALIGN_PARAGRAPH.LEFT
run = title.add_run("江苏国信智慧食堂项目")
set_run(run, size=22, bold=True, color="0B2545")
subtitle = doc.add_paragraph()
run = subtitle.add_run("客户需求分析与工期评估（客户沟通版）")
set_run(run, size=14, bold=True, color="555555")
meta = doc.add_paragraph()
run = meta.add_run("整理日期：2026-05-21    目标节点：2026-06-15 完成部署，2026-07-01 正式运行")
set_run(run, size=10, color="555555")

heading(doc, "一、结论摘要", 1)
add_bullets(doc, [
    "本项目可按“本地服务器 + 固定公网 IP/专线 + 客户二级域名 + H5 嵌入国信优享小程序”的方案推进；核心风险不在基础系统能力，而在客户侧域名、网络、安全、账号体系和历史数据确认速度。",
    "系统已有能力覆盖人员、部门、账户、补贴、订单、消费报表、消费策略、消费限制、菜谱菜品、人脸、设备、手机端余额/订单/菜谱/人脸等基础功能，可作为首批上线底座。",
    "需新增或定制的重点为：H5 免登录接入、token/加密鉴权、人员与余额数据同步、历史数据迁移、预约/代预约/外部人员预约、错峰就餐、非预约差异扣费、生日提醒、明厨亮灶预警接入等。",
    "建议首批上线以“刷脸消费、余额/订单查询、菜谱展示、基础线上订餐、财务充值、报表对账、人员/人脸管理”为目标；外部人员预约、复杂奖惩、视频预警和多消费场景可分阶段上线。",
    "若客户在 2026-05-23 前确认接口、网络、域名、历史数据和业务规则，按并行开发与实施推进，2026-06-15 完成部署具备可行性；若确认延后或安全测评范围扩大，需要顺延联调和试运行周期。",
])

heading(doc, "二、需求分类与系统匹配", 1)
rows = [
    ["人员、部门、人脸、账户、现金/补贴、订单查询、菜谱、食堂切换", "系统已有", "按现有 PC/手机端能力配置与部署", "低", "首批上线"],
    ["财务充值权限、补贴发放审核、消费订单/充值/退款/补贴统计", "系统已有/需配置", "配置角色、权限、账户规则和报表口径", "低", "首批上线"],
    ["按餐次、身份、部门、档口设置消费策略和消费限制", "系统已有/局部扩展", "现有消费策略可承载基础定价；非预约奖惩需与预约状态联动", "中", "首批或第二批"],
    ["H5 嵌入国信优享小程序、免登录、token 鉴权、手机号映射", "需开发/联调", "需我方 H5 改造、接口文档、客户小程序白名单和曹工团队联调", "高", "首批必须"],
    ["人员、余额、消费记录、订单数据与客户侧同步", "需开发/联调", "需明确数据流向、字段、频率、加密方式和失败重试机制", "高", "首批必须"],
    ["历史余额和人员数据迁移", "需实施/数据治理", "需客户提供原系统唯一标识及余额明细，建议以手机号为统一标识", "高", "首批必须"],
    ["本人预约、内部代预约、外部人员预约、取消时间、月度上限", "需开发", "当前标准能力不足以完整覆盖外部人员和代预约规则", "高", "建议首批基础版，二批增强"],
    ["错峰就餐：按单位/部门设置就餐时段并动态调整", "需开发/配置", "需与消费校验、提示和后台排班维护联动", "中", "首批基础版"],
    ["线上订餐自提、菜品分类筛选", "已有基础/需 H5 化", "已有订餐链路和菜品分类基础，需适配客户 H5 入口与规则", "中", "首批或第二批"],
    ["生日祝福推送、后台提前查看生日名单", "需开发", "需补充生日字段维护、定时任务、消息渠道和后台列表", "中", "第二批"],
    ["明厨亮灶：口罩/帽子识别和后台预警", "需集成/视现场设备", "算法能力可支持口罩帽子，需摄像头/视频流/预警通道接入；动火离人不在现有能力", "高", "第二批或专项"],
    ["咖啡、理发、泳池前台等多消费场景", "部分可配置/局部开发", "可按餐厅/档口/零售商品建模；若需独立结算报表需扩展", "中", "分阶段"],
    ["广告机、消费机、服务器、专线、布线、无线 AP", "硬件/网络", "需客户、施工和设备方配合，不属于纯软件开发", "高", "与软件并行"],
]
add_table(doc, ["客户需求", "匹配结论", "说明", "风险", "建议批次"], rows, [6.0, 2.5, 8.0, 1.6, 2.6])

heading(doc, "三、系统功能外/需定制事项工期评估", 1)
rows = [
    ["H5 嵌入与免登录接入", "H5 入口、token 获取/校验、手机号/openId 映射、登录态保持、接口文档", "4-6 个工作日", "客户提供域名、白名单、小程序跳转方式、对接人"],
    ["接口加密与数据同步", "人员、余额、订单/消费记录接口；HTTPS；必要的应用层加密；重试和日志", "5-8 个工作日", "客户确认字段、方向、频率、密钥管理和错误处理口径"],
    ["历史数据迁移", "人员、部门、人脸、余额、卡号/工号等历史数据清洗、导入、核对", "3-5 个工作日", "客户提供可匹配唯一标识，推荐手机号；需至少一次迁移演练"],
    ["预约/报餐规则", "本人预约、取消截止、未预约差异扣费、月度次数统计、后台配置、订单状态", "6-10 个工作日", "需客户书面确认奖惩规则、餐次、价格、取消时间"],
    ["代预约/外部人员预约", "内部代预约、外部人员登记、每月 10 次限制、扣预约人账户、现场核验提示", "5-8 个工作日", "需明确按预约人还是被预约人统计、外部人员身份核验方式"],
    ["错峰就餐管控", "按部门/单位配置用餐时段、消费校验、后台维护、终端提示", "3-5 个工作日", "客户提供单位排班表及例外规则"],
    ["线上订餐 H5 化", "自提订餐入口、分类筛选、下单/取消/支付、订单查询与取餐状态", "4-7 个工作日", "需明确是否只自提、下单截止、取消、库存/限量规则"],
    ["生日提醒", "生日字段维护、前一天后台名单、当天祝福推送或站内消息", "2-4 个工作日", "推送渠道需确认；若走小程序模板消息需客户侧配合"],
    ["明厨亮灶预警", "视频流接入、口罩/帽子识别、后台预警、短信/消息通知", "5-8 个工作日起", "依赖摄像头协议、视频流质量、短信通道；动火离人需另立专项"],
    ["多消费场景扩展", "咖啡、理发等零售商品/服务消费、设备点位、报表分类", "3-6 个工作日", "基础消费可配置；若需独立账期/挂账/报表则扩展"],
    ["跨单位挂账与月度对账", "子公司人员身份、挂账消费、月度对账汇总导出", "4-7 个工作日", "需客户提供单位编码、结算主体、账单格式"],
    ["安全合规资料与验收配合", "部署拓扑、端口、日志、账号权限、加密说明、漏洞扫描整改配合", "3-5 个工作日", "正式等保或第三方测评周期不计入软件开发工期"],
]
add_table(doc, ["定制/扩展事项", "工作内容", "预计工期", "前置条件"], rows, [4.8, 7.2, 2.5, 9.0])

heading(doc, "四、建议上线批次", 1)
rows = [
    ["一期必上线", "2026-06-15 前部署，2026-07-01 正式运行", "人员/部门导入、人脸录入、账户/补贴、刷脸消费、订单/余额/菜谱查询、财务充值、基础报表、H5 嵌入与免登录、基础数据同步、消费终端点位接入", "保障餐厅正式运行和基础对账"],
    ["一期增强", "2026-06-16 至 2026-06-30 试运行中完成", "基础预约/报餐、非预约差异扣费、错峰就餐、线上订餐自提、历史余额核对修正、操作培训", "根据试运行反馈调优规则"],
    ["二期优化", "2026-07-01 后 2-4 周", "代预约、外部人员预约月度限制、跨单位挂账、生日提醒、多消费场景报表、复杂奖惩", "运营规则稳定后再固化"],
    ["专项能力", "另行确认周期", "明厨亮灶视频预警、短信通知、等保/第三方安全测评、动火离人等 AI 模型能力", "依赖第三方设备、安全测评和算法训练"],
]
add_table(doc, ["批次", "时间", "范围", "目标"], rows, [3.0, 4.2, 12.0, 5.0])

heading(doc, "五、倒排计划建议", 1)
rows = [
    ["2026-05-21 至 2026-05-23", "范围冻结与规则确认", "确认唯一标识、历史数据、域名/IP/专线、防火墙、H5 接入方式、预约/扣费/错峰规则"],
    ["2026-05-24 至 2026-05-27", "方案与接口输出", "输出 H5 功能清单、接口字段、鉴权加密方案、部署拓扑、客户侧配合清单"],
    ["2026-05-28 至 2026-06-05", "开发与内部联调", "完成 H5 接入、数据同步、基础预约/错峰/线上订餐改造、历史数据导入工具与内部测试"],
    ["2026-06-06 至 2026-06-10", "客户联调与现场准备", "客户小程序嵌入联调、域名 HTTPS、专线/防火墙/白名单、服务器和终端准备"],
    ["2026-06-11 至 2026-06-15", "部署与首轮验收", "生产部署、人员/余额导入、人脸采集、终端连通、核心消费链路验收"],
    ["2026-06-16 至 2026-06-24", "试运行与规则调优", "试运行问题修复、报表核对、预约/错峰规则调整、财务对账演练"],
    ["2026-06-25 至 2026-06-30", "上线准备", "培训、操作手册、应急预案、最终数据核对、上线检查"],
    ["2026-07-01", "正式运行", "正式启用刷脸就餐与相关 H5 查询/订餐能力"],
]
add_table(doc, ["时间", "阶段", "主要事项"], rows, [4.2, 4.0, 15.8])

heading(doc, "六、需客户尽快确认事项", 1)
add_bullets(doc, [
    "原消费系统唯一标识：身份证号、手机号、工号、卡号是否完整且可唯一匹配；历史余额、补贴余额和消费流水导出格式。",
    "H5 接入方式：客户二级域名、HTTPS 证书、固定公网 IP、端口开放、小程序业务域名白名单、嵌入方式和跳转限制。",
    "接口鉴权：token 生成方、有效期、手机号/openId 传递规则、是否要求应用层加密、密钥交付和轮换方式。",
    "预约规则：本人预约、内部代预约、外部人员预约、取消截止时间、月度 10 次限制按谁统计、未预约是否上调费用及上调金额。",
    "扣费规则：按次还是按金额、早中晚三餐价格、内部/外部/跨单位/特殊人员价格，1000 元预充值和 200 元补贴/福利的具体口径。",
    "错峰就餐排班：各单位/部门用餐时段、例外人员、迟到/提前是否允许消费、现场提示方式。",
    "线上订餐：是否仅自提、菜单分类、下单截止、取消、库存/限量、取餐号、小票打印和退款规则。",
    "明厨亮灶：摄像头品牌、协议、点位、是否已有视频平台、预警接收人、短信/消息通道；动火离人如需实现需另行评估。",
    "硬件网络：广告机数量、消费机点位、备用服务器、布线、50M 专线、防火墙、无线 AP、服务器到终端白名单。",
])

heading(doc, "七、风险与边界说明", 1)
add_bullets(doc, [
    "进度边界：以上工期按客户资料及时提供、规则及时确认、客户侧小程序对接人可同步联调估算；若客户确认延后，联调和试运行时间将被压缩。",
    "安全边界：本地部署加公网访问仍需客户信息部门确认安全要求；若要求正式等保、第三方测评或集团安全整改，测评周期需另行排期。",
    "能力边界：口罩、帽子识别可按现有视觉能力评估接入；动火离人不属于现有训练模型和本次标准交付范围。",
    "商务边界：硬件、专线、域名、备案/证书、防火墙、安全测评、短信通道、第三方小程序改造等应单独列项，避免混入软件定制开发费用。",
    "上线策略：建议客户先确认一期范围，保证 2026-07-01 可运行；复杂运营规则在试运行中确认后分阶段固化。",
])

heading(doc, "八、建议给客户的确认口径", 1)
add_para(doc, "基于现有沟通材料和系统能力，本项目核心业务可在现有智慧食堂平台基础上完成交付。为保障 2026 年 7 月 1 日正式运行，建议将首批范围锁定为人员与账户初始化、刷脸消费、财务充值、余额/订单/菜谱查询、H5 嵌入、基础数据同步、核心报表和现场终端接入；预约、错峰、线上订餐等可先交付基础规则，再在试运行中根据客户运营口径调优。", after=5)
add_para(doc, "外部人员预约、复杂奖惩、多消费场景、明厨亮灶预警和安全测评属于新增或依赖第三方的事项，需在客户确认规则、接口、网络、安全条件后排期实施。若客户能在 2026 年 5 月 23 日前确认关键前置条件，我方可按 6 月 15 日完成部署、6 月 16 日至 6 月 30 日试运行、7 月 1 日正式运行的节奏推进。", after=5)

doc.save(OUT)
print(OUT)
