Files
JY1.0/scripts/build_production_plan_requirement_docx.py

348 lines
18 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 修改人:Ld 修改时间:2026-08-12 14:53:07; 生成生产计划组件补充需求方案 Word 文档。
from docx import Document
from docx.enum.section import WD_SECTION
from docx.enum.table import WD_CELL_VERTICAL_ALIGNMENT, WD_TABLE_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, Inches, Pt, RGBColor
OUT = r"D:\景耀\JY1.0\docs\生产计划组件补充需求方案.docx"
def set_cell_shading(cell, fill):
tc_pr = cell._tc.get_or_add_tcPr()
shd = tc_pr.find(qn("w:shd"))
if shd is None:
shd = OxmlElement("w:shd")
tc_pr.append(shd)
shd.set(qn("w:fill"), fill)
def set_cell_text(cell, text, bold=False, color=None):
cell.text = ""
p = cell.paragraphs[0]
p.paragraph_format.space_after = Pt(0)
run = p.add_run(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)
cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
def set_table_width(table, widths_cm):
table.autofit = False
table.alignment = WD_TABLE_ALIGNMENT.CENTER
for row in table.rows:
for idx, width in enumerate(widths_cm):
row.cells[idx].width = Cm(width)
def add_table(doc, headers, rows, widths_cm):
table = doc.add_table(rows=1, cols=len(headers))
table.style = "Table Grid"
set_table_width(table, widths_cm)
for idx, header in enumerate(headers):
set_cell_text(table.rows[0].cells[idx], header, bold=True, color="0B2545")
set_cell_shading(table.rows[0].cells[idx], "F2F4F7")
for row in rows:
cells = table.add_row().cells
for idx, value in enumerate(row):
set_cell_text(cells[idx], str(value))
doc.add_paragraph()
return table
def add_flow(doc, title, steps):
doc.add_heading(title, level=3)
table = doc.add_table(rows=1, cols=len(steps))
table.style = "Table Grid"
table.alignment = WD_TABLE_ALIGNMENT.CENTER
width = 16.0 / len(steps)
set_table_width(table, [width] * len(steps))
for idx, step in enumerate(steps):
cell = table.rows[0].cells[idx]
set_cell_text(cell, step, bold=True)
set_cell_shading(cell, "E8EEF5" if idx % 2 == 0 else "F4F6F9")
p = doc.add_paragraph()
p.paragraph_format.space_after = Pt(4)
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)
def add_para(doc, text, bold_prefix=None):
p = doc.add_paragraph()
p.paragraph_format.space_after = Pt(6)
if bold_prefix and text.startswith(bold_prefix):
run = p.add_run(bold_prefix)
run.bold = True
run.font.name = "Microsoft YaHei"
run._element.rPr.rFonts.set(qn("w:eastAsia"), "Microsoft YaHei")
run.font.size = Pt(10.5)
text = text[len(bold_prefix):]
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)
def build():
doc = Document()
section = doc.sections[0]
section.top_margin = Inches(0.85)
section.bottom_margin = Inches(0.85)
section.left_margin = Inches(0.85)
section.right_margin = Inches(0.85)
styles = doc.styles
normal = styles["Normal"]
normal.font.name = "Microsoft YaHei"
normal._element.rPr.rFonts.set(qn("w:eastAsia"), "Microsoft YaHei")
normal.font.size = Pt(10.5)
normal.paragraph_format.line_spacing = 1.1
normal.paragraph_format.space_after = Pt(6)
for style_name, size, color, before, after in [
("Heading 1", 16, "2E74B5", 16, 8),
("Heading 2", 13, "2E74B5", 12, 6),
("Heading 3", 12, "1F4D78", 8, 4),
]:
style = styles[style_name]
style.font.name = "Microsoft YaHei"
style._element.rPr.rFonts.set(qn("w:eastAsia"), "Microsoft YaHei")
style.font.size = Pt(size)
style.font.bold = True
style.font.color.rgb = RGBColor.from_string(color)
style.paragraph_format.space_before = Pt(before)
style.paragraph_format.space_after = Pt(after)
title = doc.add_paragraph()
title.alignment = WD_ALIGN_PARAGRAPH.CENTER
title.paragraph_format.space_after = Pt(8)
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.from_string("0B2545")
subtitle = doc.add_paragraph()
subtitle.alignment = WD_ALIGN_PARAGRAPH.CENTER
subtitle.paragraph_format.space_after = Pt(14)
run = subtitle.add_run("周计划、设备小时级计划、销售合同计划、设备门牌看板")
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.from_string("555555")
add_para(doc, "本次先做方案,不修改业务页面和数据库过程。围绕生产计划组件的四项补充需求,建议拆成三个前端能力和一组后端数据源。")
for item in [
"生产计划支持“周计划”显示。",
"点击设备查看后续工作时,模块时间显示到“小时/分钟”。",
"在生产任务计划之外,增加“销售合同计划”视角。",
"增加类似医院诊室门口屏幕的“设备当前生产/下一项生产”直观展示。",
]:
add_bullet(doc, item)
doc.add_heading("一、总体设计", level=1)
add_para(doc, "建议新增一个“计划看板”入口,保留现有生产计划表格页作为明细查询和导出页面,在其上扩展三种视图。")
add_table(
doc,
["视图", "主要用途", "展示粒度", "用户动作"],
[
["月计划", "复用现有生产计划表格", "月", "查询、导出、打开可视化"],
["周计划", "查看本周投产、派工、交付压力", "周、天", "周次切换、按天筛选、查看明细"],
["设备门牌看板", "现场快速查看每台设备当前和下一项", "设备、当前任务、下一任务", "自动刷新、点击设备查看后续队列"],
["销售合同计划", "从合同交付节点倒推生产风险", "合同、订单、产品、计划节点", "查看合同进度、跳转生产计划/订单进度"],
],
[3.0, 5.0, 3.8, 4.2],
)
doc.add_heading("二、功能方案", level=1)
doc.add_heading("2.1 周计划显示", level=2)
add_para(doc, "现有生产计划页面已经按月份查询,建议周计划不新增单独页面,先在当前生产计划页面增加“视图模式”。")
for item in [
"月计划:保持现有表格。",
"周计划:按选中月份自动生成第 1 周到第 5/6 周。",
"周计划筛选规则:按投产时间或精工期限两种口径切换,默认按投产时间。",
"顶部显示本周计划数、生产中、已完成、逾期风险、完成率。",
"中部按周一到周日分列,每列列出订单/零件卡片;底部保留明细表格,便于导出。",
]:
add_bullet(doc, item)
add_para(doc, "最小改造方案:继续调用现有 `车间生产管理_生产计划_查询数据`,前端按日期过滤并分组。")
add_para(doc, "推荐方案:后端过程增加开始时间、结束时间参数,由 SQL Server 过滤,减少月份数据量过大时的前端压力。")
doc.add_heading("2.2 设备后续工作时间显示到小时", level=2)
add_para(doc, "现有生产计划页面点击设备后,会打开设备后续已派工任务弹窗,样式接近 APS 时间轴。建议增强为小时级展示。")
for item in [
"显示字段从日期改为 yyyy-MM-dd HH:mm。",
"时间轴横向粒度由“天”增强为“天 + 小时刻度”。",
"任务卡片显示订单号/合同号、零件名称、图号、工序、操作者、设备、分配时间、预计完成时间、开始加工时间、完成时间。",
"如果没有预计完成时间,则按分配时间 + 计划工时/设备能力计算临时结束时间,并标记为“估算”。",
]:
add_bullet(doc, item)
doc.add_heading("2.3 销售合同计划", level=2)
add_para(doc, "销售合同计划不建议等同于生产任务计划。它应从“合同交付承诺”看“生产是否支撑交付”,核心不是设备排产,而是合同节点和生产状态对齐。")
add_para(doc, "建议层级:销售合同 -> 订单 -> 产品/部件 -> 生产计划 -> 工艺/派工/完工。")
add_table(
doc,
["字段", "来源", "用途"],
[
["合同编号", "PDM_项目名称或合同信息相关视图", "合同主键展示"],
["客户/收货人", "客户关系或订单关联客户", "识别交付对象"],
["合同签订日期", "合同信息", "计划起点"],
["交货日期/精工期限", "订单或生产计划", "风险判断"],
["订单编号", "PDM_订单信息_视图、合同管理_订单信息_基础表", "关联生产"],
["产品名称", "PDM 产品/组件视图", "合同产品范围"],
["计划数量", "生产计划视图", "生产负荷"],
["完成率", "生产计划或工艺完工统计", "进度展示"],
["当前工序/设备", "工艺计划、派工数据", "当前进展"],
["风险状态", "计算字段", "正常、临期、逾期、无生产计划"],
],
[3.0, 6.5, 6.5],
)
add_table(
doc,
["状态", "判断"],
[
["正常", "精工期限未到,生产进度匹配"],
["临期", "距交付日期小于等于 7 天且未完成"],
["逾期", "当前日期超过交付日期且未完成"],
["无计划", "合同/订单已存在但没有生产计划"],
["已完成", "生产计划全部完成"],
],
[3.0, 13.0],
)
doc.add_heading("2.4 设备门牌看板", level=2)
add_para(doc, "“医院诊室门口样式”建议做成现场大屏/看板页面,不放在复杂表格里。页面以设备为单位,每台设备一张门牌卡,重点展示“正在生产什么、下一项生产什么”。")
add_table(
doc,
["模块", "展示内容"],
[
["设备抬头", "设备名称 / 工位号 / 状态灯"],
["正在生产", "订单号、零件名称、图号、工序、操作者、已用时/计划工时"],
["下一项", "订单号、零件名称、图号、工序、计划开始时间"],
["辅助信息", "后续队列数、更新时间、异常状态"],
],
[3.0, 13.0],
)
for item in [
"设备状态颜色复用现有设备监控状态:运行、等待、关机、报警、断网。",
"当前任务优先取 MES 实时加工/工位零件接口。",
"下一项任务取该设备未完成、未开始或已派工未加工的最早任务。",
"看板自动刷新,建议 30 秒一次。",
"点击卡片进入设备后续工作 APS 弹窗。",
]:
add_bullet(doc, item)
doc.add_heading("三、流程图", level=1)
add_flow(doc, "3.1 周计划查询流程", ["进入生产计划", "选择月份", "生成周次", "选择周次/口径", "查询数据", "按日期过滤", "分组展示", "导出周计划"])
add_flow(doc, "3.2 设备后续工作流程", ["点击设备", "传入设备/工位", "查询后续派工", "补齐时间字段", "格式化到小时", "分组", "渲染 APS 轴"])
add_flow(doc, "3.3 销售合同计划流程", ["销售合同", "关联订单", "关联产品", "关联生产计划", "关联工艺派工", "计算风险", "合同计划看板", "跳转明细"])
add_flow(doc, "3.4 设备门牌看板流程", ["设备清单", "实时状态", "当前加工", "后续任务", "合并门牌数据", "当前任务", "下一任务", "自动刷新"])
doc.add_heading("四、数据源设计", level=1)
doc.add_heading("4.1 已有前端页面和接口", level=2)
add_table(
doc,
["功能", "文件/接口", "说明"],
[
["生产计划", "src/views/SeikoWorkshop/ProductionPlan/index.vue", "当前生产计划主页面"],
["生产任务查询", "src/views/SeikoWorkshop/ProductionTaskQuery/index.vue", "生产任务、工艺、派工入口"],
["设备监控", "src/views/SeikoWorkshop/EquipmentMonitoringNew/index.vue;src/views/DeviceManagement/EquipmentStatusMonitoring/index.vue", "设备实时状态和设备跳转"],
["合同查询", "src/views/SalesManagement/ContractSearch/index.vue;src/views/SalesManagement/ContractSearchNew/index.vue", "销售合同信息"],
["订单进度", "src/views/SalesManagement/OrderProgress/index.vue", "销售订单进度展示"],
],
[3.0, 8.0, 5.0],
)
doc.add_heading("4.2 已有后端过程/视图", level=2)
add_table(
doc,
["数据用途", "已识别数据源"],
[
["生产计划主数据", "车间生产管理_生产计划_查询数据"],
["生产计划视图", "车间生产管理_生产计划_视图_新"],
["生产任务查询", "精工车间_生成任务_查询数据"],
["订单下拉", "生产任务查询_订单信息_列表_查询数据"],
["订单产品", "订单信息_产品信息_查询数据"],
["零件追溯工序", "车间生产管理工艺_追溯加工_查询工序"],
["设备当前零件", "MES_机加工MES_工位零件图号查询_设备监控"],
["设备待加工队列", "MES_机加工MES_待加工零件_查询_设备监控"],
["设备状态", "MES_机加工MES_设备数据采集_工位状态_查询_新;MES_机加工MES_设备状态查询_初始化"],
["合同/项目", "PDM_项目名称_全部_查询数据;合同信息管理_合同信息_查询_分页"],
["订单基础关联", "合同管理_订单信息_基础表;PDM_订单信息_视图"],
],
[4.0, 12.0],
)
doc.add_heading("4.3 建议新增后端接口", level=2)
add_table(
doc,
["接口", "name", "核心返回字段"],
[
["周计划查询", "车间生产管理_生产计划_周计划_查询数据", "周次、日期、状态、合同编号、订单号、投产时间、精工期限、完成率、当前设备、OP010~OP110"],
["设备小时级任务", "车间生产管理_设备后续任务_小时计划_查询数据", "设备名称、工位号、订单号、合同编号、工序、操作者、分配时间、开始加工、预计完成、完成时间、计划工时M"],
["销售合同计划", "销售管理_销售合同计划_查询数据", "合同编号、客户、交付日期、订单号、产品名称、计划数量、完成率、当前工序、当前设备、风险状态"],
["设备门牌看板", "车间生产管理_设备门牌看板_查询数据", "设备状态、当前任务、下一任务、后续队列数、更新时间"],
],
[3.0, 6.0, 7.0],
)
doc.add_heading("五、实施顺序", level=1)
for item in [
"先做设备后续任务时间显示到小时,只改显示和查询字段,风险最低。",
"做周计划前端视图,先复用月计划数据过滤,确认业务口径。",
"做设备门牌看板,先复用设备监控和待加工队列接口,后续再合并成单接口。",
"做销售合同计划,需要合同、订单、生产计划多源联查,建议最后做。",
]:
add_bullet(doc, item)
doc.add_heading("六、验收口径", level=1)
add_table(
doc,
["需求", "验收方式"],
[
["周计划", "选择月份和周次后,只显示该周对应计划;周一到周日分组正确"],
["设备后续小时", "点击设备后,分配时间、开始加工、预计完成、完成时间显示到小时分钟"],
["销售合同计划", "能按合同看到关联订单、生产完成率、风险状态,并能跳转明细"],
["设备门牌看板", "每台设备清楚显示当前任务、下一项任务、状态颜色和更新时间"],
],
[4.0, 12.0],
)
doc.add_heading("七、注意事项", level=1)
for item in [
"周计划必须确认日期口径:按投产时间、精工期限,还是两者都支持。",
"销售合同计划需要统一合同编号来源,优先使用已补充的关联合同编号,其次再使用订单备注/MK 关联逻辑。",
"设备门牌看板若用于现场大屏,建议单独配置自动刷新间隔,避免频繁查询影响 MES 采集接口。",
"所有新增接口仍按项目规范 POST 到 MESCommonBase.ashx,携带 UserID 和 ModularID。",
]:
add_bullet(doc, item)
doc.add_paragraph()
p = doc.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.RIGHT
run = p.add_run("修改人:Ld 修改时间:2026-08-12 14:24:23;")
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.from_string("555555")
doc.save(OUT)
if __name__ == "__main__":
build()