348 lines
18 KiB
Python
348 lines
18 KiB
Python
# 修改人: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()
|