from pathlib import Path

from docx import Document
from docx.enum.table import 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 Pt

ROOT = Path(__file__).resolve().parent
doc = Document(ROOT / "working-copy.docx")

for paragraph in list(doc.paragraphs):
    if not paragraph.text.strip():
        doc._element.body.remove(paragraph._element)


def font(run, size=11, bold=False):
    run.font.name = "Noto Sans CJK SC"
    run._element.rPr.rFonts.set(qn("w:eastAsia"), "Noto Sans CJK SC")
    run.font.size = Pt(size)
    run.bold = bold


def paragraph(text, size=11, bold=False, after=6):
    item = doc.add_paragraph()
    item.paragraph_format.line_spacing = 1.35
    item.paragraph_format.space_after = Pt(after)
    font(item.add_run(text), size, bold)
    return item


title = paragraph("食材用量与采购单核对操作说明", 20, True, 14)
title.alignment = WD_ALIGN_PARAGRAPH.CENTER
paragraph("页面已优化数量显示和人工改量反馈，但采购计算、确认接口、数据库精度和 Excel 导出数据保持不变。", 11, False, 12)
paragraph("入口与前提", 15, True)
paragraph("入口：膳食营养 → 食材用量与采购单。食谱审核发布并生成采购需求后，具有学校和档口权限的采购人员可以核对。")
paragraph("数量显示规则", 15, True)

rows = [
    ("9.000000", "9.00", "普通数量保留2位"),
    ("18.600000", "18.60", "删除无意义尾随0"),
    ("2549.900000", "2,549.90", "大数增加千位分隔"),
    ("0.002000", "0.002", "微量非零需求保留有效精度"),
    ("空值或无效值", "—", "不伪造为0"),
]
table = doc.add_table(rows=1, cols=3)
table.autofit = True
borders = OxmlElement("w:tblBorders")
for edge in ("top", "left", "bottom", "right", "insideH", "insideV"):
    node = OxmlElement(f"w:{edge}")
    node.set(qn("w:val"), "single")
    node.set(qn("w:sz"), "4")
    node.set(qn("w:color"), "D9D9D9")
    borders.append(node)
table._tbl.tblPr.append(borders)
for index, value in enumerate(("接口原值", "页面显示", "说明")):
    cell = table.rows[0].cells[index]
    fill = OxmlElement("w:shd")
    fill.set(qn("w:fill"), "D9EAF7")
    cell._tc.get_or_add_tcPr().append(fill)
    cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
    cell.paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.CENTER
    font(cell.paragraphs[0].add_run(value), 10, True)
for values in rows:
    cells = table.add_row().cells
    for index, value in enumerate(values):
        cells[index].vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
        cells[index].paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.CENTER if index < 2 else WD_ALIGN_PARAGRAPH.LEFT
        font(cells[index].paragraphs[0].add_run(value), 10)

paragraph("来源信息", 15, True, 6)
paragraph("采购需求选择项同时显示食谱名称、版本、状态和冻结供餐范围。食谱名称是历史业务文本，采购计算以冻结供餐范围为准。")
paragraph("改量与确认", 15, True, 6)
paragraph("确认采购量偏离建议值时，对应说明框显示红色必填提示，表格上方汇总缺少说明的数量。页面显示“当前修改未保存”时，数据尚未写入系统；点击“保存并确认”后，系统校验全部行，定位第一条缺失说明，并在校验通过后一次性保存并进入已确认状态。")
paragraph("操作边界", 15, True, 6)
paragraph("调整确认量后必须填写说明；交接只保存记录，不向进销存传输；只有已确认或已交接需求可以导出和打印。页面不会自动保存未确认的改量。")
paragraph("验证", 15, True, 6)
paragraph("2026-09-22：前端9项定向单测、采购服务6 tests / 38 assertions、目标 lint 与 PC 生产构建均通过。登录后截图因默认测试账号无效尚未补录。")

doc.save(ROOT / "manual.docx")
