from pathlib import Path

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


BASE = Path(__file__).resolve().parent
MEDIA = BASE / "docx-extract" / "media"
OUT = BASE / "智慧食堂产品标准化周会材料-20260530.docx"


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, color=None):
    cell.text = ""
    p = cell.paragraphs[0]
    p.alignment = WD_ALIGN_PARAGRAPH.LEFT
    run = p.add_run(str(text))
    run.bold = bold
    run.font.name = "Microsoft YaHei"
    run._element.rPr.rFonts.set(qn("w:eastAsia"), "Microsoft YaHei")
    run.font.size = Pt(9.5)
    if color:
        run.font.color.rgb = RGBColor.from_string(color)


def set_repeat_table_header(row):
    tr_pr = row._tr.get_or_add_trPr()
    tbl_header = OxmlElement("w:tblHeader")
    tbl_header.set(qn("w:val"), "true")
    tr_pr.append(tbl_header)


def style_table(table):
    table.alignment = WD_TABLE_ALIGNMENT.CENTER
    table.style = "Table Grid"
    for row in table.rows:
        for cell in row.cells:
            cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
            for p in cell.paragraphs:
                for run in p.runs:
                    run.font.name = "Microsoft YaHei"
                    run._element.rPr.rFonts.set(qn("w:eastAsia"), "Microsoft YaHei")
                    run.font.size = Pt(9.5)


def add_heading(doc, text, level=1):
    p = doc.add_heading(level=level)
    run = p.add_run(text)
    run.font.name = "Microsoft YaHei"
    run._element.rPr.rFonts.set(qn("w:eastAsia"), "Microsoft YaHei")
    run.font.color.rgb = RGBColor(31, 78, 121)
    return p


def add_para(doc, text, bold_prefix=None):
    p = doc.add_paragraph()
    p.paragraph_format.space_after = Pt(6)
    p.paragraph_format.line_spacing = 1.15
    if bold_prefix and text.startswith(bold_prefix):
        r1 = p.add_run(bold_prefix)
        r1.bold = True
        r1.font.name = "Microsoft YaHei"
        r1._element.rPr.rFonts.set(qn("w:eastAsia"), "Microsoft YaHei")
        r2 = p.add_run(text[len(bold_prefix):])
        r2.font.name = "Microsoft YaHei"
        r2._element.rPr.rFonts.set(qn("w:eastAsia"), "Microsoft YaHei")
    else:
        run = p.add_run(text)
        run.font.name = "Microsoft YaHei"
        run._element.rPr.rFonts.set(qn("w:eastAsia"), "Microsoft YaHei")
    return p


def add_bullet(doc, text):
    p = doc.add_paragraph(style="List Bullet")
    p.paragraph_format.space_after = Pt(3)
    run = p.add_run(text)
    run.font.name = "Microsoft YaHei"
    run._element.rPr.rFonts.set(qn("w:eastAsia"), "Microsoft YaHei")
    run.font.size = Pt(10.5)
    return p


def add_caption(doc, text):
    p = doc.add_paragraph()
    p.alignment = WD_ALIGN_PARAGRAPH.CENTER
    run = p.add_run(text)
    run.italic = True
    run.font.name = "Microsoft YaHei"
    run._element.rPr.rFonts.set(qn("w:eastAsia"), "Microsoft YaHei")
    run.font.size = Pt(9)
    run.font.color.rgb = RGBColor(89, 89, 89)


def add_image(doc, image_name, caption):
    image = MEDIA / image_name
    if image.exists():
        p = doc.add_paragraph()
        p.alignment = WD_ALIGN_PARAGRAPH.CENTER
        p.add_run().add_picture(str(image), width=Cm(15.2))
        add_caption(doc, caption)


def add_table(doc, headers, rows, widths=None):
    table = doc.add_table(rows=1, cols=len(headers))
    style_table(table)
    hdr = table.rows[0]
    set_repeat_table_header(hdr)
    for i, h in enumerate(headers):
        set_cell_text(hdr.cells[i], h, bold=True, color="FFFFFF")
        set_cell_shading(hdr.cells[i], "1F4E79")
        if widths:
            hdr.cells[i].width = Cm(widths[i])
    for row in rows:
        cells = table.add_row().cells
        for i, value in enumerate(row):
            set_cell_text(cells[i], value)
            if widths:
                cells[i].width = Cm(widths[i])
    doc.add_paragraph()
    return table


doc = Document()

for section in doc.sections:
    section.top_margin = Cm(1.8)
    section.bottom_margin = Cm(1.8)
    section.left_margin = Cm(1.9)
    section.right_margin = Cm(1.9)

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)

title = doc.add_paragraph()
title.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = title.add_run("智慧食堂产品标准化周会材料")
run.bold = True
run.font.name = "Microsoft YaHei"
run._element.rPr.rFonts.set(qn("w:eastAsia"), "Microsoft YaHei")
run.font.size = Pt(22)
run.font.color.rgb = RGBColor(31, 78, 121)

subtitle = doc.add_paragraph()
subtitle.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = subtitle.add_run("围绕机场/赛迪、金斯瑞、206 与重庆环卫参数库形成可复制产品模块")
run.font.name = "Microsoft YaHei"
run._element.rPr.rFonts.set(qn("w:eastAsia"), "Microsoft YaHei")
run.font.size = Pt(11)
run.font.color.rgb = RGBColor(89, 89, 89)

add_heading(doc, "一、核心结论", 1)
add_para(doc, "本次材料只保留一个判断：产品标准化不是把所有项目做成一模一样，而是把每个项目拆成“标准产品模块 + 项目定制适配”。项目越多，标准模块越清楚，定制边界越清楚，下一次复制就越快。")
add_para(doc, "周会表达建议：机场/赛迪让营养结算主系统和主流程落地；金斯瑞让前厅、后厨、食安和多设备联调跑通；206 让纯内网、国产化数据库、国产化服务器和复杂网络环境跑通。这三个项目合在一起，正在形成智慧营养健康餐厅的标准产品包。")

add_table(
    doc,
    ["层次", "要讲清楚的内容", "证据支撑"],
    [
        ["标准产品模块", "营养结算、前厅交易结算、后厨食安进销存、餐前餐中餐后营养闭环、国产化/内网部署、设备接入与联调。", "项目清单、Word 方案功能清单、金斯瑞软硬件表、重庆环卫参数库。"],
        ["项目定制适配", "客户现场网络、设备点位、第三方系统、OA/商城/咖啡机/无人售卖柜、国产数据库服务器环境、客户特殊流程。", "机场/赛迪消费策略和商城对接；金斯瑞 OA 与多设备联调；206 服务器/数据库/网络问题。"],
        ["复制方式", "每个项目沉淀为一张产品卡：标准模块、定制边界、报价/实施清单、验收证据、可转招投标参数。", "项目标准化地图、品类汇总、控制参数库。"],
    ],
    widths=[3.0, 8.0, 5.0],
)

add_heading(doc, "二、项目如何沉淀为产品模块", 1)
add_table(
    doc,
    ["项目", "已上线/落地内容", "形成的标准产品模块", "定制化部分", "数据口径与证据"],
    [
        ["机场/赛迪", "营养结算系统主系统已搭建，人员、账户、充值、收银、结算、对账、消费策略等主流程已落地。", "营养结算 1.0 标准场景：平台 + 收银秤/挂式收银机 + IC/发卡 + 结算对账 + 消费策略边界。", "线上商城对接、消费策略定制开发、客户流程适配、现场服务单。", "项目标准化地图金额约 192,900；标准化/定制化约 50%/50%。"],
        ["金斯瑞", "大部分工作集中在设备联调联试，并投入客户真实使用；覆盖南京、镇江两地前厅与后厨/食安设备。", "前厅交易设备包 + 后厨食安设备包 + 多设备联调清单 + 两园区复制模板。", "OA 平台对接、两地设备组合差异、叫号/取餐/食安点位适配、上线数据清理与刷卡测试。", "项目标准化地图金额约 449,400；标准化/定制化约 65%/35%；来源为金斯瑞实施计划与设备清单。"],
        ["206", "重点解决纯内网部署、国产化数据库、国产化服务器运行，以及服务器、数据库、网络三个问题。", "内网国产化部署包：服务器、数据库、网络、设备接入、现场排障、外部设备消费扣款闭环。", "新食堂现场点位、无人售卖机/售卖柜、补打/出货逻辑、客户内网环境适配。", "项目标准化地图金额约 541,385；另一个项目证据库单项采购口径为 399,820，金额口径需后续统一。"],
        ["重庆环卫", "不作为单个上线案例重点讲，而作为参数化模板使用。", "招投标参数库：把餐前、餐中、餐后的能力转成可评分、可验收、可报价的参数。", "需结合不同客户资质、国产化要求、安全测评要求调整。", "控制参数库 v0.2：覆盖资质、商务评分、软件功能、硬件参数、国产化与验收要求。"],
    ],
    widths=[2.2, 4.2, 4.2, 3.8, 3.8],
)

add_heading(doc, "三、金斯瑞软硬件证据：前厅与后厨分别沉淀什么", 1)
add_para(doc, "金斯瑞项目的价值，不是只证明某个功能能用，而是证明前厅交易、称重结算、叫号取餐、后厨食安、视频与传感器、服务器和系统对接可以在客户现场组合运行。")

add_table(
    doc,
    ["区域", "南京设备", "镇江设备", "可沉淀的产品模块"],
    [
        ["前厅", "档口人脸消费机 17 台；自选称重结算设备 5 台；叫号信息盒 8 台；小票打印机 8 台；自助交互终端 1 台。", "视觉结算台 2 台；台式收银机 13 台；智能称重收银机 2 台；信息发布盒 2 台；叫号信息盒 7 台。", "前厅交易结算设备包：人脸消费、称重结算、视觉结算、叫号、打印、自助交互。"],
        ["后厨/食安", "智能留样柜 1 台；智能分析盒 1 台；摄像头 4 个；16 路硬盘录像机 1 台。", "食品安全监督管理系统 1 套；服务器 1 台；并配置电子菜谱管理系统。", "后厨食安设备包：留样、视频、AI 分析、晨检、传感器、食安监管。"],
        ["环境与对接", "云服务器环境、支付通道、刷卡测试、数据清理、移动端登录调整。", "OA 平台对接、两地设备组合与现场联调。", "实施联调清单：网络、电源、点位、账号、人员、余额、脸库、IC 卡、支付、报表验证。"],
    ],
    widths=[2.2, 5.2, 5.2, 4.4],
)

add_heading(doc, "四、餐前餐中餐后：从营养能力到产品参数", 1)
add_para(doc, "餐前餐中餐后是本次最需要讲深的产品标准化主线。它把康比特营养健康能力，从专家经验变成系统流程，再变成客户采购和招投标能识别的技术参数。")

add_image(doc, "image1.png", "图 1：餐前注册、健康目标、个性化菜单、到店取餐、营养报告的完整闭环。")
add_image(doc, "image8.png", "图 2：餐中设备端展示菜品、重量、热量、推荐摄入和提醒。")
add_image(doc, "image18.png", "图 3：餐中红绿灯式营养指导，可转化为实时提醒和干预参数。")
add_image(doc, "image19.png", "图 4：餐后形成个人和群体营养资产报告，支持复盘与管理。")

add_table(
    doc,
    ["阶段", "产品能力", "可转成招投标参数的表达", "证据"],
    [
        ["餐前", "小程序注册、上传体检信息、关联运动数据/体重秤、设置健康或体重目标、生成个性化菜单。", "支持接入运动数据、体检数据、体重目标；支持基于 BMI、健康指标和个人目标生成摄入建议。", "Word 方案餐前流程图；方案文字“关联运动数据/体检数据/体重秤”。"],
        ["餐中", "设备端识别人员和菜品，展示推荐克重、剩余推荐摄入量、热量超标提醒、菜品推荐。", "支持餐中实时推荐克重、剩余推荐量、超标提醒；支持不少于 12 类标签，识别准确率可写入参数；支持红绿灯式指导。", "Word 方案设备截图；方案参数中包含标签、识别准确率和实时建议示例。"],
        ["餐后", "个人日/周/月/年报告，群体报告，营养摄入分析，导出、打印、科普宣教。", "支持不少于 30 项摄入分析指标；支持个人与群体营养报告导出打印；支持日/周/月/年统计；内置食材库、菜品库、营养科普。", "方案参数：不少于 2000 个食材、1500 个菜品、60 篇营养文章；报告截图。"],
        ["投标参数化", "把营养闭环拆成软件参数、硬件参数、国产化参数、验收参数。", "按重庆环卫参数库口径组织：资质、商务评分、软件功能、硬件规格、国产化部署、安全测评和验收。", "控制参数库 v0.2。"],
    ],
    widths=[2.2, 5.0, 6.6, 3.4],
)

add_heading(doc, "五、已经形成的产品标准模块", 1)
add_table(
    doc,
    ["标准模块", "已覆盖项目/证据", "当前成熟度判断", "下一步标准化动作"],
    [
        ["营养结算主系统", "机场/赛迪主流程落地；Word 方案中形成餐前餐中餐后闭环。", "从方案进入主流程落地阶段。", "固化人员、账户、充值、收银、结算、对账、报告、商城/消费策略边界。"],
        ["前厅交易结算设备包", "金斯瑞、206、机场/赛迪等项目出现收银机、称重结算、视觉结算、绑盘机、消费机等。", "设备类型已较丰富，但需要形成标准报价和联调清单。", "按场景拆为档口收银、称重自助、视觉结算、叫号取餐、打印/交互五类。"],
        ["后厨食安进销存设备包", "金斯瑞留样柜、分析盒、摄像头、NVR、传感器；多个项目包含食安监管和进销存。", "具备产品组合基础。", "形成后厨食安基础包、增强包、国产化政企包。"],
        ["国产化/内网部署包", "206 重点解决服务器、数据库、网络；Word 方案明确支持国产化系统部署，用户数据库为人大金仓。", "是政企复制的关键能力，但证据还需补齐。", "沉淀部署检查清单、数据库适配清单、网络排障清单、验收截图。"],
        ["招投标参数库", "重庆环卫参数库已覆盖资质、商务、软件、硬件、国产化、安全测评。", "已具备方法框架。", "把本次餐前餐中餐后指标补入 v1.0 参数库。"],
    ],
    widths=[3.2, 5.0, 4.0, 5.0],
)

add_heading(doc, "六、下一步规划", 1)
add_table(
    doc,
    ["时间", "目标", "具体动作", "交付物"],
    [
        ["下周", "把本次周会材料落到可复用证据。", "完成机场/赛迪、金斯瑞、206 三张产品标准化样板卡；统一项目金额口径；把原始截图和来源文件路径登记清楚。", "3 张项目标准化卡片；证据目录；金额口径说明。"],
        ["两周内", "形成标准产品包 v1.0。", "整理营养结算、前厅设备、后厨食安、国产化内网部署、第三方设备接入五类模块。", "标准产品模块清单；软硬件配置模板；实施联调检查清单。"],
        ["一个月内", "形成可用于售前和招投标的参数库。", "把重庆环卫参数库与餐前餐中餐后能力合并，补齐软件参数、硬件参数、国产化参数、验收截图。", "智慧营养健康餐厅招投标参数库 v1.0。"],
        ["持续机制", "让每个项目都反哺产品标准化。", "项目复盘时固定记录：标准模块、定制边界、可复用参数、未标准化问题、下一次复制方式。", "产品标准化看板；项目复盘模板；周会跟踪口径。"],
    ],
    widths=[2.4, 4.0, 6.4, 4.2],
)

add_heading(doc, "七、来源与证据路径", 1)
sources = [
    "原始 Word：/Users/jack/Library/Containers/com.tencent.xinWeChat/Data/Documents/xwechat_files/aqua118_1a62/temp/drag/260306智慧食堂方案(3).docx；SHA256：5189706b1b80ebcd0ebfaf47cc44dcebd2f68afae900fbf9abe9ad02c017dcb9。",
    "Word 派生 Markdown：work/2026-05-30-product-standardization-weekly-talking-points/docx-extract/260306-smart-canteen-solution.md。",
    "Word 原始图片：work/2026-05-30-product-standardization-weekly-talking-points/docx-extract/media/。",
    "金斯瑞软硬件表：work/2026-05-23-gpt-monthly-planning-context-pack/04_mac_file_index/raw-small/金斯瑞智慧食堂实施计划20260324.xlsx。",
    "项目标准化地图：work/2026-05-29-product-standardization-ai-native-weekly-material/project-standardization-map.csv。",
    "项目品类汇总：modules/product/products/smart-canteen/review/2026-05-29-smart-canteen-15-project-product-evidence-database/product-category-summary.csv。",
    "项目证据库：modules/product/products/smart-canteen/review/2026-05-29-smart-canteen-15-project-product-evidence-database/project-product-evidence-db.csv。",
    "重庆环卫参数库：standards-stack/product-strategy/smart-canteen/bid-parameter-library/control-parameter-library-v0.2.md。",
]
for source in sources:
    add_bullet(doc, source)

doc.add_section(WD_SECTION.CONTINUOUS)
footer = doc.sections[0].footer.paragraphs[0]
footer.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = footer.add_run("智慧食堂产品标准化周会材料 | 2026-05-30")
run.font.name = "Microsoft YaHei"
run._element.rPr.rFonts.set(qn("w:eastAsia"), "Microsoft YaHei")
run.font.size = Pt(8)
run.font.color.rgb = RGBColor(127, 127, 127)

doc.save(OUT)
print(OUT)
