Files
MES_Manage_View_V20/work/system-technical-document/build-standard-technical-document.ps1

843 lines
64 KiB
PowerShell
Raw 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.
param(
[string]$OutputDirectory = ''
)
$ErrorActionPreference = 'Stop'
Add-Type -AssemblyName System.Drawing
$scriptRoot = $PSScriptRoot
$root = (Resolve-Path (Join-Path $scriptRoot '..\..')).Path
$docDir = if ($OutputDirectory) { $OutputDirectory } else { Join-Path $root 'doc' }
$assetDir = Join-Path $scriptRoot 'assets'
$fileBase = '大连元利流体技术有限公司MES系统标准技术文档_V1.1_2026-07-24'
$docxPath = Join-Path $docDir ($fileBase + '.docx')
$pdfPath = Join-Path $docDir ($fileBase + '.pdf')
$buildLog = Join-Path $scriptRoot 'build.log'
New-Item -ItemType Directory -Force -Path $docDir, $assetDir | Out-Null
[IO.File]::WriteAllText($buildLog, "开始生成 $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')`r`n", [Text.Encoding]::UTF8)
function Write-ProgressLog {
param([string]$Message)
[IO.File]::AppendAllText($buildLog, "$(Get-Date -Format 'HH:mm:ss') $Message`r`n", [Text.Encoding]::UTF8)
}
function New-Canvas {
param([int]$Width = 1800, [int]$Height = 980)
$bitmap = New-Object System.Drawing.Bitmap $Width, $Height
$graphics = [System.Drawing.Graphics]::FromImage($bitmap)
$graphics.SmoothingMode = [System.Drawing.Drawing2D.SmoothingMode]::AntiAlias
$graphics.TextRenderingHint = [System.Drawing.Text.TextRenderingHint]::AntiAliasGridFit
$graphics.Clear([System.Drawing.Color]::FromArgb(248, 250, 252))
return @($bitmap, $graphics)
}
function Draw-Box {
param(
[System.Drawing.Graphics]$Graphics,
[int]$X,
[int]$Y,
[int]$Width,
[int]$Height,
[string]$Title,
[string]$Detail,
[System.Drawing.Color]$Fill,
[System.Drawing.Color]$Border = [System.Drawing.Color]::FromArgb(64, 80, 96)
)
$rect = New-Object System.Drawing.Rectangle $X, $Y, $Width, $Height
$brush = New-Object System.Drawing.SolidBrush $Fill
$pen = New-Object System.Drawing.Pen $Border, 3
$Graphics.FillRectangle($brush, $rect)
$Graphics.DrawRectangle($pen, $rect)
$titleFont = New-Object System.Drawing.Font 'Microsoft YaHei', 21, ([System.Drawing.FontStyle]::Bold), ([System.Drawing.GraphicsUnit]::Pixel)
$detailFont = New-Object System.Drawing.Font 'Microsoft YaHei', 16, ([System.Drawing.FontStyle]::Regular), ([System.Drawing.GraphicsUnit]::Pixel)
$textBrush = New-Object System.Drawing.SolidBrush ([System.Drawing.Color]::FromArgb(30, 41, 59))
$format = New-Object System.Drawing.StringFormat
$format.Alignment = [System.Drawing.StringAlignment]::Center
$format.LineAlignment = [System.Drawing.StringAlignment]::Center
$titleRect = New-Object System.Drawing.RectangleF ($X + 12), ($Y + 8), ($Width - 24), ([Math]::Min(48, $Height * 0.36))
$detailRect = New-Object System.Drawing.RectangleF ($X + 14), ($Y + 48), ($Width - 28), ($Height - 54)
$Graphics.DrawString($Title, $titleFont, $textBrush, $titleRect, $format)
$Graphics.DrawString($Detail, $detailFont, $textBrush, $detailRect, $format)
$format.Dispose(); $textBrush.Dispose(); $detailFont.Dispose(); $titleFont.Dispose(); $pen.Dispose(); $brush.Dispose()
}
function Draw-Arrow {
param([System.Drawing.Graphics]$Graphics, [int]$X1, [int]$Y1, [int]$X2, [int]$Y2, [string]$Label = '')
$pen = New-Object System.Drawing.Pen ([System.Drawing.Color]::FromArgb(71, 85, 105)), 4
$pen.CustomEndCap = New-Object System.Drawing.Drawing2D.AdjustableArrowCap 6, 7
$Graphics.DrawLine($pen, $X1, $Y1, $X2, $Y2)
if ($Label) {
$font = New-Object System.Drawing.Font 'Microsoft YaHei', 14, ([System.Drawing.FontStyle]::Regular), ([System.Drawing.GraphicsUnit]::Pixel)
$brush = New-Object System.Drawing.SolidBrush ([System.Drawing.Color]::FromArgb(71, 85, 105))
$Graphics.DrawString($Label, $font, $brush, (($X1 + $X2) / 2 - 40), (($Y1 + $Y2) / 2 - 25))
$brush.Dispose(); $font.Dispose()
}
$pen.Dispose()
}
function Save-Canvas {
param([System.Drawing.Bitmap]$Bitmap, [System.Drawing.Graphics]$Graphics, [string]$Path)
$Graphics.Dispose()
$Bitmap.Save($Path, [System.Drawing.Imaging.ImageFormat]::Png)
$Bitmap.Dispose()
}
function Build-Diagrams {
$blue = [System.Drawing.Color]::FromArgb(219, 234, 254)
$teal = [System.Drawing.Color]::FromArgb(204, 251, 241)
$amber = [System.Drawing.Color]::FromArgb(254, 243, 199)
$green = [System.Drawing.Color]::FromArgb(220, 252, 231)
$gray = [System.Drawing.Color]::FromArgb(226, 232, 240)
$red = [System.Drawing.Color]::FromArgb(254, 226, 226)
$canvas = New-Canvas 1800 960; $b = $canvas[0]; $g = $canvas[1]
Draw-Box $g 60 80 270 150 '用户访问层' 'Chrome / Edge`nPC 与车间终端' $blue
Draw-Box $g 420 80 350 150 'MES 前端' 'Vue 2.7 + Element UI`n动态菜单、业务交互、报表' $teal
Draw-Box $g 860 80 380 150 'MES 通用服务' 'HTTPS / MESCommonBase.ashx`n过程调用、上传下载、日志' $amber
Draw-Box $g 1330 80 390 150 'SQL Server' 'YL_MESDB`n业务数据、视图、存储过程' $green
Draw-Arrow $g 330 155 420 155 'HTTPS'; Draw-Arrow $g 770 155 860 155 'JSON'; Draw-Arrow $g 1240 155 1330 155 'T-SQL'
Draw-Box $g 420 380 350 140 'SAP B1 代理服务' 'B1 Service Layer`nGET / POST / PATCH' $blue
Draw-Box $g 860 380 380 140 'TM 开放接口' '领料、库存及相关业务接口' $teal
Draw-Box $g 1330 380 390 140 '文件服务' '图纸、附件上传与下载' $gray
Draw-Arrow $g 595 230 595 380 '业务集成'; Draw-Arrow $g 1050 230 1050 380 '业务集成'; Draw-Arrow $g 1525 230 1525 380 '文件'
Draw-Box $g 420 680 350 140 'AGV / 物流接口' '搬运任务下发与状态维护' $amber
Draw-Box $g 860 680 380 140 '设备 / MQTT' '设备变量读取、写入与状态采集' $red
Draw-Box $g 1330 680 390 140 '质量与看板接口' 'SPC、趋势图、实时监控' $blue
Draw-Arrow $g 595 520 595 680; Draw-Arrow $g 1050 520 1050 680; Draw-Arrow $g 1525 520 1525 680
Save-Canvas $b $g (Join-Path $assetDir 'logical-architecture.png')
$canvas = New-Canvas 1900 820; $b = $canvas[0]; $g = $canvas[1]
$steps = @(
@('ERP 订单', '销售订单、物料、BOM', $blue),
@('工艺准备', '标准工艺、生产工艺、图纸', $teal),
@('计划排产', '工位、人员、数量、时间', $amber),
@('任务下发', '创建工序任务、进入执行队列', $green),
@('生产执行', '收料、开工、报工、送检', $blue),
@('质量闭环', '检验、判定、不合格处置', $red),
@('完工交付', '工时校验、关闭、入库、发货', $green)
)
$xPositions = @(30, 300, 570, 840, 1110, 1380, 1650); $y = 220; $boxWidth = 220; $boxHeight = 165
for ($i = 0; $i -lt $steps.Count; $i++) { Draw-Box $g $xPositions[$i] $y $boxWidth $boxHeight $steps[$i][0] $steps[$i][1] $steps[$i][2] }
$labels = @('生成', '排产', '下发', '执行', '检验', '交付')
for ($i = 0; $i -lt $labels.Count; $i++) { Draw-Arrow $g ($xPositions[$i] + $boxWidth) ($y + 82) $xPositions[$i + 1] ($y + 82) $labels[$i] }
Draw-Arrow $g ($xPositions[6] + 110) ($y + $boxHeight) ($xPositions[6] + 110) 560
Draw-Arrow $g ($xPositions[6] + 110) 560 ($xPositions[0] + 110) 560 '异常、返工、计划调整反馈'
Save-Canvas $b $g (Join-Path $assetDir 'business-flow.png')
$canvas = New-Canvas 1800 900; $b = $canvas[0]; $g = $canvas[1]
Draw-Box $g 80 100 300 150 '账号登录' '用户名、密码验证' $blue
Draw-Box $g 500 100 300 150 '角色选择' '一个账号可对应多个角色' $teal
Draw-Box $g 920 100 360 150 '菜单权限读取' '按角色加载菜单及增删改查权限' $amber
Draw-Box $g 1400 100 300 150 '动态路由' '仅挂载可访问页面' $green
Draw-Arrow $g 380 175 500 175; Draw-Arrow $g 800 175 920 175; Draw-Arrow $g 1280 175 1400 175
Draw-Box $g 300 500 360 160 '页面业务请求' '携带 UserID、UserName、ModularID' $blue
Draw-Box $g 800 500 360 160 '服务端校验与执行' '校验身份、参数与业务规则' $teal
Draw-Box $g 1300 500 360 160 '审计与结果' '记录操作上下文并返回结果' $gray
Draw-Arrow $g 1550 250 480 500 '进入业务页面'; Draw-Arrow $g 660 580 800 580; Draw-Arrow $g 1160 580 1300 580
Save-Canvas $b $g (Join-Path $assetDir 'permission-flow.png')
$canvas = New-Canvas 1800 900; $b = $canvas[0]; $g = $canvas[1]
Draw-Box $g 80 110 330 170 '浏览器终端' '访问 MES Web 站点`n建议统一受管浏览器版本' $blue
Draw-Box $g 530 110 340 170 'Web 静态资源' 'index.html、JS、CSS`nstatic/config.js 环境配置' $teal
Draw-Box $g 990 110 340 170 '应用服务' '10101MES 通用服务`n9996B1/TM 代理服务' $amber
Draw-Box $g 1410 110 310 170 '数据库服务' '192.168.2.92`nSQL Server / YL_MESDB' $green
Draw-Arrow $g 410 195 530 195 'HTTPS'; Draw-Arrow $g 870 195 990 195 'HTTPS'; Draw-Arrow $g 1330 195 1410 195 '内网'
Draw-Box $g 300 570 360 150 'SAP B1' 'ERP 主数据、订单、库存' $blue
Draw-Box $g 800 570 360 150 '文件与图纸' '上传、下载、在线预览' $gray
Draw-Box $g 1300 570 360 150 'AGV / 设备侧' '9981 AGV 接口及设备通信' $red
Draw-Arrow $g 1160 280 480 570; Draw-Arrow $g 1160 280 980 570; Draw-Arrow $g 1160 280 1480 570
Save-Canvas $b $g (Join-Path $assetDir 'deployment-topology.png')
}
Build-Diagrams
Write-ProgressLog '已生成四张技术架构与流程图'
$modulePages = [ordered]@{
'系统管理' = @('人员管理', '角色管理', '菜单管理', '工位管理', '报工操作记录')
'设备管理' = @('设备信息维护', '设备数据', '设备历史数据', '实时数据')
'研发管理' = @('设计任务', '设计报工', '设计工时校验', '设计工时报表', '研发财务工时')
'工艺管理' = @('工序管理', '制定标准工艺', '生产工艺', '工艺查询', '工艺任务', '图纸维护', '工艺维护', '查看图纸', '采购图纸查询')
'计划排产' = @('机加件排产', '装配件排产', '机加件已排产', '机加件未排产', '优先装配', '计划用表', '装配未排产', '生产订单关闭', '工位任务汇总', '装配已排产', '系统类装配任务', '阀类装配任务', '及时齐套跟踪结果')
'生产管理' = @('生产计划跟踪', '加工中心', '过程异常管控', '工时校验', '外协管理', '人员绑定', '装配中心', '班次管理', '工时报表', '加急件管理', '拣配任务', '采购外协管理', '工时查询', '机加正在进行中', '装配状态', '外协报表', '工时修正', '物料机器人', '手续确认报表', '发货通知列表', '结算工时')
'异常提醒' = @('机加及时开工', '外协及时开工', '加急任务列表', '装配及时送检')
'质量管理' = @('终检', '采购入库检', '销售退货检', '原材料退库检', '序检收检', '质量检验标准', '其他入库检', '质检明细', '不合格品处置', '质检报工', '测试装配任务', '及时检验报表', '产品合格率(工位)')
'销售订单管理' = @('销售订单状态')
}
$moduleDesign = @(
@('系统管理', '账号、角色、菜单、工位及操作审计', '人员/角色/菜单基础数据', '全部业务模块的登录与权限基础'),
@('设备管理', '维护设备台账并查看实时与历史数据', '设备、工位、采集变量', '生产执行、设备看板和设备分析'),
@('研发管理', '设计任务分派、报工、校验与财务工时', '研发项目、任务、人员、报工记录', '工时统计、成本核算和项目复盘'),
@('工艺管理', '维护工序、标准工艺、订单工艺及图纸', '物料、工序、标准工艺、订单工艺、图纸', '计划排产、任务下发、生产执行和检验标准'),
@('计划排产', '将订单工艺分配到工位、人员和时间', '生产订单、工艺路线、资源与日历', '生产任务、齐套跟踪、工位负荷和异常提醒'),
@('生产管理', '执行收料、开工、暂停、报工、送检和工时闭环', '工序任务、人员、设备、物料和操作记录', '质量检验、完工关闭、工时报表和交付状态'),
@('异常提醒', '识别未及时开工、未及时送检和加急事项', '计划时间、实际时间、任务状态', '计划调整、现场督办和管理看板'),
@('质量管理', '执行质量标准、检验、判定与不合格处置', '检验任务、标准、实测值、量具和处置记录', '任务流转、入库、返工/让步/报废和质量统计'),
@('销售订单管理', '汇总订单从计划到交付的全流程状态', 'SAP 销售订单与 MES 生产/质量/交付数据', '交付协调、客户响应和经营分析')
)
$techStack = @(
@('前端框架', 'Vue.js', '2.7.16', '单页应用与组件体系'),
@('UI 组件', 'Element UI', '2.15.14', '表单、表格、弹窗、分页'),
@('路由', 'Vue Router', '3.6.5', '动态权限路由'),
@('状态管理', 'Vuex', '3.6.2', '用户、角色、标签页等全局状态'),
@('HTTP', 'Axios', '0.21.4', 'MES、SAP B1、TM 与其他服务调用'),
@('图表', 'ECharts', '5.4.3', '看板和统计图'),
@('日历排程', 'FullCalendar', '6.1.x', '计划日历与排产交互'),
@('设备通信', 'MQTT.js', '4.3.7', '设备与实时数据通信'),
@('文档与报表', 'xlsx / jsPDF / pdfjs / docxtemplater', '见 package.json', '导入导出、PDF预览和模板生成'),
@('构建工具', 'Webpack', '5.89.0', '开发服务、生产构建和代码分包'),
@('数据库', 'Microsoft SQL Server', '2019 / 兼容级别150', 'YL_MESDB 业务数据与过程层')
)
$word = $null; $doc = $null
try {
$word = New-Object -ComObject Word.Application
$word.Visible = $false
$word.DisplayAlerts = 0
$doc = $word.Documents.Add()
$selection = $word.Selection
$normal = $doc.Styles.Item(-1)
$section = $doc.Sections.Item(1)
$section.PageSetup.PaperSize = 7
$section.PageSetup.TopMargin = $word.CentimetersToPoints(2.3)
$section.PageSetup.BottomMargin = $word.CentimetersToPoints(2.0)
$section.PageSetup.LeftMargin = $word.CentimetersToPoints(2.4)
$section.PageSetup.RightMargin = $word.CentimetersToPoints(2.1)
$section.PageSetup.HeaderDistance = $word.CentimetersToPoints(1.0)
$section.PageSetup.FooterDistance = $word.CentimetersToPoints(1.0)
$section.PageSetup.DifferentFirstPageHeaderFooter = -1
$normal.Font.NameFarEast = '宋体'; $normal.Font.Name = 'Arial'; $normal.Font.Size = 10.5
$normal.ParagraphFormat.LineSpacingRule = 1
$normal.ParagraphFormat.LineSpacing = 18
$normal.ParagraphFormat.SpaceAfter = 6
foreach ($item in @(@(-2, 16, 0x8F4A31), @(-3, 13, 0x8F4A31), @(-4, 11, 0x6B594F))) {
$style = $doc.Styles.Item($item[0])
$style.Font.NameFarEast = '微软雅黑'; $style.Font.Name = 'Arial'; $style.Font.Size = $item[1]
$style.Font.Bold = 1; $style.Font.Color = $item[2]
$style.ParagraphFormat.KeepWithNext = -1; $style.ParagraphFormat.SpaceBefore = 10; $style.ParagraphFormat.SpaceAfter = 6
}
function Move-End { $selection.SetRange($doc.Content.End - 1, $doc.Content.End - 1) }
function Add-Text {
param([string]$Text, [double]$Size = 10.5, [bool]$Bold = $false, [int]$Align = 0, [int]$Color = 0, [double]$Before = 0, [double]$After = 6, [double]$FirstIndentCm = 0.74)
$selection.Style = $normal
$selection.Font.NameFarEast = '宋体'; $selection.Font.Name = 'Arial'; $selection.Font.Size = $Size
$selection.Font.Bold = [int]$Bold; $selection.Font.Color = $Color
$selection.ParagraphFormat.Alignment = $Align; $selection.ParagraphFormat.SpaceBefore = $Before; $selection.ParagraphFormat.SpaceAfter = $After
$selection.ParagraphFormat.FirstLineIndent = $word.CentimetersToPoints($FirstIndentCm)
$selection.TypeText($Text); $selection.TypeParagraph()
}
function Add-Heading {
param([string]$Text, [int]$Level = 1)
$styleId = switch ($Level) { 1 { -2 } 2 { -3 } default { -4 } }
$selection.Style = $doc.Styles.Item($styleId)
$selection.TypeText($Text); $selection.TypeParagraph(); $selection.Style = $normal
}
function Add-Bullet {
param([string]$Text, [int]$Level = 1)
$selection.Style = $normal
$selection.Range.ListFormat.ApplyBulletDefault()
$selection.ParagraphFormat.LeftIndent = $word.CentimetersToPoints(0.75 + (($Level - 1) * 0.65))
$selection.ParagraphFormat.FirstLineIndent = $word.CentimetersToPoints(-0.5)
$selection.TypeText($Text); $selection.TypeParagraph(); $selection.Range.ListFormat.RemoveNumbers()
$selection.ParagraphFormat.LeftIndent = 0; $selection.ParagraphFormat.FirstLineIndent = 0
}
function Add-Number {
param([string]$Text)
$selection.Style = $normal
$selection.Range.ListFormat.ApplyNumberDefault(); $selection.ParagraphFormat.LeftIndent = $word.CentimetersToPoints(0.75)
$selection.TypeText($Text); $selection.TypeParagraph(); $selection.Range.ListFormat.RemoveNumbers(); $selection.ParagraphFormat.LeftIndent = 0
}
function Add-Table {
param([object[]]$Rows, [double[]]$WidthsCm = @(), [double]$FontSize = 8.7)
if ($Rows.Count -eq 0) { return }
Write-ProgressLog ("写入表格:{0}行 x {1}列,首项={2}" -f $Rows.Count, $Rows[0].Count, [string]$Rows[0][0])
$table = $doc.Tables.Add($selection.Range, $Rows.Count, $Rows[0].Count)
$table.Borders.Enable = 1; $table.AllowAutoFit = -1
$table.Range.Font.NameFarEast = '宋体'; $table.Range.Font.Name = 'Arial'; $table.Range.Font.Size = $FontSize
$table.Range.ParagraphFormat.SpaceAfter = 0; $table.Range.ParagraphFormat.LineSpacingRule = 0
for ($r = 0; $r -lt $Rows.Count; $r++) {
for ($c = 0; $c -lt $Rows[$r].Count; $c++) {
$cell = $table.Cell($r + 1, $c + 1)
$cell.Range.Text = [string]$Rows[$r][$c]
$cell.VerticalAlignment = 1
}
}
for ($c = 0; $c -lt $WidthsCm.Count -and $c -lt $table.Columns.Count; $c++) {
$table.Columns.Item($c + 1).Width = $word.CentimetersToPoints($WidthsCm[$c])
}
$table.Rows.Item(1).Range.Bold = 1
$table.Rows.Item(1).Range.Font.NameFarEast = '微软雅黑'
$table.Rows.Item(1).Range.ParagraphFormat.Alignment = 1
$table.Rows.Item(1).Shading.BackgroundPatternColor = 0xE6D8D0
$table.Rows.Item(1).HeadingFormat = -1
$table.Rows.AllowBreakAcrossPages = 0
if ($Rows.Count -le 6) {
for ($rowIndex = 1; $rowIndex -lt $table.Rows.Count; $rowIndex++) {
$table.Rows.Item($rowIndex).Range.ParagraphFormat.KeepWithNext = -1
}
}
$selection.SetRange($table.Range.End, $table.Range.End); $selection.TypeParagraph()
}
function Add-Note {
param([string]$Title, [string]$Text, [string]$Kind = 'info')
$table = $doc.Tables.Add($selection.Range, 1, 1)
$table.Borders.Enable = 1
$cell = $table.Cell(1, 1); $cell.Range.Text = "$Title$Text"
$cell.Range.Font.NameFarEast = '微软雅黑'; $cell.Range.Font.Name = 'Arial'; $cell.Range.Font.Size = 9.5
$cell.Range.ParagraphFormat.SpaceAfter = 0
$cell.Shading.BackgroundPatternColor = switch ($Kind) { 'warn' { 0xD9F2FF } 'risk' { 0xD9E2F3 } default { 0xEAF4E4 } }
$selection.SetRange($table.Range.End, $table.Range.End); $selection.TypeParagraph()
}
function Add-Image {
param([string]$Path, [double]$WidthCm = 16.0, [string]$Caption = '')
$selection.ParagraphFormat.Alignment = 1; $selection.ParagraphFormat.FirstLineIndent = 0
$shape = $selection.InlineShapes.AddPicture($Path, $false, $true)
$shape.LockAspectRatio = -1; $shape.Width = $word.CentimetersToPoints($WidthCm)
$selection.TypeParagraph()
if ($Caption) { Add-Text $Caption 9 $false 1 0 0 8 0 }
}
function Add-PageBreak { $selection.InsertBreak(7) }
# 封面
Add-Text '大连元利流体技术有限公司' 18 $true 1 0x8F4A31 65 12 0
Add-Text 'MES 系统标准技术文档' 28 $true 1 0x51352A 70 16 0
Add-Text 'System Technical Specification' 15 $false 1 0x6B594F 0 70 0
$coverRows = @(
@('文档编号', 'YL-MES-TECH-001'),
@('系统版本', 'V1.1.0'),
@('文档版本', 'V1.1'),
@('基线日期', '2026-07-24'),
@('文档属性', '内部技术资料'),
@('适用范围', 'MES 实施、开发、测试、运维及审计')
)
Add-Table $coverRows @(4.2, 9.0) 10
Add-Text '编制依据:当前前端源代码、正式菜单配置、正式数据库只读元数据及现有业务技术资料' 9.5 $false 1 0x666666 55 0 0
Add-PageBreak
Add-Heading '文档控制' 1
Add-Heading '修订记录' 2
Add-Table @(
@('版本', '日期', '修订内容', '状态'),
@('V1.0', '2026-07-24', '首次形成系统级标准技术文档,覆盖现状架构、部署、权限、数据、接口、运维与验收规范', '正式基线'),
@('V1.1', '2026-07-24', '修订核心业务流程图,消除主流程与异常回流线重叠并明确箭头方向', '图形修订')
) @(2.0, 2.8, 10.0, 2.2)
Add-Heading '审批与分发' 2
Add-Table @(
@('角色', '职责', '签署/日期'),
@('业务负责人', '确认业务边界和关键流程', ''),
@('技术负责人', '确认架构、接口、数据与变更方案', ''),
@('运维负责人', '确认部署、备份、监控和应急流程', ''),
@('质量/测试负责人', '确认测试范围与验收证据', '')
) @(3.2, 9.2, 4.6)
Add-Note '保密要求' '本文档包含正式环境拓扑、内部接口约定和数据库对象信息,仅限授权的实施、开发、测试、运维及审计人员使用。账号、口令、私钥和 SAP 会话信息不得写入正文或版本库。' 'warn'
Add-PageBreak
Add-Heading '目录' 1
$tocRange = $selection.Range
[void]$doc.TablesOfContents.Add($tocRange, $true, 1, 3)
Move-End; Add-PageBreak
Add-Heading '1 文档说明' 1
Add-Heading '1.1 目的' 2
Add-Text '本文档定义 MES 系统当前技术实现基线,并给出部署、配置、权限、数据、接口、运维、变更和验收的统一要求。它用于技术交接和持续维护,不替代面向最终用户的操作手册。'
Add-Heading '1.2 适用对象' 2
foreach ($t in @('实施人员:确认网络、服务、数据库、外部系统和上线条件。','开发人员:理解代码结构、请求约定、模块边界、数据链路和变更规则。','测试人员:依据关键状态、接口契约和验收清单设计测试。','运维人员:执行部署、监控、备份、恢复、故障定位和应急处置。','审计与管理人员:核对权限、日志、变更记录和数据保护措施。')) { Add-Bullet $t }
Add-Heading '1.3 事实与规范的区分' 2
Add-Table @(
@('标识', '含义', '使用方式'),
@('当前实现', '由代码、配置或正式数据库只读元数据确认的现状', '用于复现和维护当前系统'),
@('标准要求', '后续建设、变更和运维应遵循的控制要求', '作为评审和验收依据'),
@('改进建议', '现状可运行但存在安全、可维护性或恢复能力风险', '纳入版本计划,评估后实施')
) @(3.0, 7.0, 7.0)
Add-Heading '1.4 基线与范围' 2
Add-Table @(
@('项目', '基线值'),
@('项目目录', 'MES_Manage_View_V20'),
@('前端版本', 'package.json1.1.0'),
@('功能范围', '9个一级业务模块75个正式启用功能页面'),
@('前端规模', '99个 Vue 页面文件、28个 API 脚本、8个共享 Vue 组件'),
@('数据库', 'YL_MESDBSQL Server 2019兼容级别150'),
@('数据库规模', '61张用户表、27个视图、425个存储过程、2个函数'),
@('数据库容量', '约19.44 GB其中数据约16.62 GB、日志约2.82 GB'),
@('统计日期', '2026-07-24只读采集')
) @(4.2, 12.8)
Add-Heading '2 系统概述' 1
Add-Heading '2.1 建设目标' 2
Add-Text 'MES 连接 SAP 业务订单与车间执行过程,以工艺和计划为主线,将生产任务落实到工位、设备和人员,记录物料流转、生产操作、工时与质量结果,并向管理侧提供异常、齐套、进度、质量和交付视图。'
Add-Heading '2.2 系统边界' 2
Add-Table @(
@('系统/域', 'MES 负责', '外部系统负责'),
@('订单与主数据', '接收并使用订单、物料、BOM、供应商等信息', 'SAP B1 维护 ERP 主数据、财务和库存权威记录'),
@('工艺与计划', '标准/生产工艺、排产、任务下发、工位和时间安排', '外部系统提供订单需求和部分资源信息'),
@('生产执行', '收料、开工、暂停、报工、送检、人员/设备工时', '设备侧提供状态或执行反馈'),
@('质量', '检验任务、标准、实测值、判定及不合格处置', 'SAP/库存侧承接入库、退货等结果'),
@('物流与交付', '拣配、AGV任务、发货通知及订单状态汇总', 'SAP/仓储侧完成库存和交付凭证')
) @(3.2, 7.1, 6.7)
Add-Heading '2.3 功能模块' 2
$rows = @()
$rows += ,@('模块', '核心职责', '主要输入', '主要输出')
foreach ($moduleRow in $moduleDesign) { $rows += ,$moduleRow }
Add-Table $rows @(2.6, 4.8, 4.9, 4.8) 8.2
Add-Heading '2.4 核心业务主线' 2
Add-Image (Join-Path $assetDir 'business-flow.png') 16.3 '图2-1 MES 核心业务闭环'
Add-Note '状态控制原则' '任何会改变订单、工艺、任务、工时、检验或库存状态的操作,都必须在服务端再次校验当前状态和数量边界;前端按钮可见性不能代替业务校验。' 'warn'
Add-Heading '3 总体技术架构' 1
Add-Heading '3.1 逻辑架构' 2
Add-Image (Join-Path $assetDir 'logical-architecture.png') 16.3 '图3-1 系统逻辑架构'
Add-Text '浏览器加载 Vue 单页应用。常规 MES 请求经统一 Axios 实例发送到 MESCommonBase.ashx前端通过统一请求载荷指定执行类型、过程名称、参数、分页和操作上下文。SAP B1、TM、文件、AGV和设备数据通过独立接口访问。'
Add-Heading '3.2 分层职责' 2
Add-Table @(
@('层次', '职责', '主要实现'),
@('表现层', '查询、表格、表单、弹窗、状态提示和报表', 'Vue / Element UI / ECharts / FullCalendar'),
@('前端业务层', '页面状态、输入校验、交互编排、路由与权限菜单', 'views、store、router、utils、api'),
@('应用服务层', '身份上下文、请求解析、过程调用、上传下载、外部系统代理', 'MESCommonBase.ashx、B1/TM代理、文件服务'),
@('数据逻辑层', '业务校验、状态流转、事务、查询和聚合', 'SQL Server 存储过程、视图、函数'),
@('集成层', 'SAP、TM、AGV、设备/PLC、文件与质量数据交换', 'HTTPS/JSON、Service Layer、MQTT及专用接口')
) @(3.0, 7.2, 6.8)
Add-Heading '3.3 架构约束' 2
foreach ($t in @('正式环境页面只能通过受控服务访问业务数据,不允许浏览器直连数据库。','写操作必须在数据库事务或等效原子边界内完成,并返回明确的成功、失败和业务原因。','跨系统操作应定义幂等键或重复提交校验,避免任务、报工、检验和库存记录重复。','前端不得持久化数据库密码、SAP密码、服务私钥或其他长期凭据。','所有外部接口失败都应保留可定位的业务编号、请求时间和错误摘要。')) { Add-Bullet $t }
Add-Heading '4 技术栈与代码结构' 1
Add-Heading '4.1 技术栈基线' 2
$techRows = @()
$techRows += ,@('类别', '技术', '版本', '用途')
foreach ($techRow in $techStack) { $techRows += ,$techRow }
Add-Table $techRows @(3.0, 4.0, 3.0, 7.0)
Add-Heading '4.2 源码目录' 2
Add-Table @(
@('路径', '职责', '变更注意事项'),
@('src/views', '业务页面和模块组件', '大型页面改动需覆盖状态、权限和接口回归'),
@('src/api', '封装登录、基础数据、B1、TM及专项接口', '保持请求参数和返回结构兼容'),
@('src/router', '基础路由、动态菜单树和组件映射', '菜单 component 必须能解析到真实页面'),
@('src/store', '用户、角色、权限、标签页和应用状态', '登出时清理身份与缓存'),
@('src/utils', '统一请求、认证 Cookie、CRUD、PDF和设备工具', '共享工具变更需扩大回归范围'),
@('static/config.js', '运行时环境地址', '按环境发布,不写入账号口令'),
@('config / build', '开发代理与 Webpack 构建', '生产构建关闭 source map核对资源路径'),
@('db_backups', '数据库变更和回退证据', '一事一脚本,具备前置检查、事务和验证')
) @(4.0, 6.0, 7.0)
Add-Heading '4.3 模块代码规模' 2
Add-Table @(
@('目录', 'Vue 文件数', '说明'),
@('ProductionManagement', '36', '生产、工时、外协、物流及研发相关页面,复杂度最高'),
@('QualityManagement', '15', '检验、标准、处置和统计'),
@('PlanManagement', '13', '机加与装配排产、齐套、关闭及汇总'),
@('ProcessManagement', '9', '工序、工艺、图纸与工艺任务'),
@('SystemMaintenance', '6', '人员、角色、菜单、工位和日志'),
@('Device/Anomalous/Sale 等', '20', '设备、异常提醒、销售状态及框架页面')
) @(6.0, 3.0, 8.0)
Add-Heading '4.4 编码与提交规范' 2
foreach ($t in @('所有源文件统一使用 UTF-8发现乱码注释或字符串时在独立变更中修复并回归。','新增页面必须同时完成页面组件、菜单配置、权限配置、接口契约和用户/技术文档。','共享组件和全局工具不承载单一页面的特殊规则;跨三个以上页面的稳定重复逻辑才考虑抽取。','禁止在代码中提交正式密码、个人令牌、数据库连接串和私钥。','数据库脚本必须包含对象存在性检查、事务边界、错误回滚、影响说明和只读验证语句。')) { Add-Bullet $t }
Add-Heading '5 部署架构与环境配置' 1
Add-Heading '5.1 正式环境拓扑' 2
Add-Image (Join-Path $assetDir 'deployment-topology.png') 16.3 '图5-1 当前部署与集成拓扑'
Add-Heading '5.2 当前运行时端点' 2
Add-Table @(
@('用途', '当前配置', '来源/说明'),
@('MES 通用接口', 'https://192.168.2.92:10101/submit/MESCommonBase.ashx', 'static/config.js常规业务请求'),
@('MES 服务根地址', 'https://192.168.2.92:10101', '文件上传下载等'),
@('SAP B1 代理', 'https://192.168.2.92:9996/b1s', '前端 b1s.js 统一 POST 代理'),
@('TM 代理', 'https://192.168.2.92:9996/openapi', '前端 tm.js 统一 POST 代理'),
@('AGV 搬运接口', 'http://192.168.2.92:9981/api/zk/call_agv_move_web', '物料机器人页面当前实现'),
@('数据库', '192.168.2.92 / YL_MESDB', '凭据单独保管,不进入文档和代码')
) @(4.0, 8.3, 4.7) 8.4
Add-Note '安全边界' '上表用于技术维护和网络检查不代表对所有终端开放。应通过服务器防火墙、反向代理和访问控制限制来源AGV 当前为 HTTP 地址,应评估升级为 HTTPS 或限定在隔离网络。' 'risk'
Add-Heading '5.3 前端构建与发布' 2
Add-Number '安装 Node.js 20 及 npm 9 或更高兼容版本,执行 npm ci 安装锁定依赖。'
Add-Number '在目标环境准备 static/config.js只配置服务地址不加入账号和密码。'
Add-Number '执行 npm run build生成 dist 目录。构建脚本会清理 dist/static/config.js因此发布包中必须由环境配置步骤补回该文件。'
Add-Number '将 dist 发布至 Web 服务,启用 HTTPS、正确 MIME 类型、静态缓存和 index.html 回退。'
Add-Number '使用非管理员账号完成登录、菜单、查询、写操作权限和附件访问冒烟测试。'
Add-Heading '5.4 发布目录要求' 2
Add-Table @(
@('内容', '缓存策略', '发布要求'),
@('index.html', '不缓存或短缓存', '确保新版本入口及时生效'),
@('带 contenthash 的 JS/CSS', '长期缓存', '文件名变化自动失效'),
@('static/config.js', '不缓存或短缓存', '按环境独立管理,发布后检查端点'),
@('图片、字体和图标', '长期缓存', '检查跨域、MIME和中文文件名'),
@('图纸/附件', '按业务权限', '不得以公共静态目录绕过鉴权')
) @(4.2, 4.2, 8.6)
Add-Heading '5.5 回退条件' 2
foreach ($t in @('登录或动态菜单无法正常加载。','核心查询、保存、下发、报工或检验出现批量失败。','数据库脚本验证失败或数据状态不一致。','SAP、TM、文件、AGV等关键集成产生不可接受的业务中断。','出现越权、敏感信息泄露或无法审计的写操作。')) { Add-Bullet $t }
Add-Heading '6 配置管理' 1
Add-Heading '6.1 配置分类' 2
Add-Table @(
@('配置类别', '位置', '管理要求'),
@('前端运行时地址', 'static/config.js', '环境独立、发布时注入、禁止密码'),
@('开发代理', 'config/index.js', '仅开发使用,不作为正式环境反向代理依据'),
@('菜单与页面权限', '登录基础数据_二级菜单', '按角色维护,变更需校验动态路由'),
@('人员与角色', '系统管理相关基础数据', '最小权限、离职停用、定期复核'),
@('工位、班次和字典', '业务基础数据', '变更前评估对排产、工时和统计的影响'),
@('数据库连接与服务凭据', '服务端安全配置', '密钥库/受限配置,不写入前端或文档'),
@('外部系统端点', '前端运行时配置或服务端配置', '区分开发、测试、正式,纳入连通性检查')
) @(4.0, 5.5, 7.5)
Add-Heading '6.2 配置变更控制' 2
foreach ($t in @('配置变更必须记录变更人、时间、原值、新值、原因、验证结果和回退值。','正式环境配置不得直接从开发环境复制覆盖,必须逐项比对。','菜单路径、组件路径和权限位变更后,需要清除登录缓存并使用目标角色重新登录验证。','工位、班次、字典和状态类配置变更应验证历史数据展示不受破坏。')) { Add-Bullet $t }
Add-Heading '7 身份、权限与安全' 1
Add-Heading '7.1 权限流程' 2
Add-Image (Join-Path $assetDir 'permission-flow.png') 16.3 '图7-1 登录、菜单与业务请求权限链路'
Add-Heading '7.2 当前实现' 2
Add-Table @(
@('环节', '当前机制', '控制重点'),
@('登录', '用户名和密码由统一 MES 接口验证', '必须使用可信 HTTPS 证书'),
@('角色', '账号可关联多个角色;角色编号写入 Admin-Token Cookie', '角色选择后重新加载菜单'),
@('菜单', '按角色读取菜单数据getTreeData 构建树并动态 addRoutes', '组件路径必须受白名单/构建产物约束'),
@('页面权限', '菜单记录含 AddData/DeleteData/EditData/SearchData 权限位', '按钮权限与后端写权限保持一致'),
@('请求上下文', '公共请求包含 UserID、UserName、ModularID', '服务端不可只信任前端传值'),
@('登出', '清理用户、账号、角色 Cookie', '同时使服务端会话或令牌失效')
) @(3.2, 7.4, 6.4)
Add-Heading '7.3 标准安全要求' 2
foreach ($t in @('前端权限只用于界面控制,服务端必须对每次查询和写操作校验身份、角色、模块和数据范围。','Cookie 应设置 Secure、SameSite 和合理有效期;如架构允许,应使用 HttpOnly 会话令牌。','密码不得出现在日志、异常消息、浏览器存储、截图和文档中。','所有写操作记录操作人、模块、业务主键、动作、时间、结果和必要的变更摘要。','高风险操作包括删除、订单关闭、任务重置、工时修正、批量下发和质量放行,应增加二次确认与权限分离。','定期复核停用账号、重复角色、过宽菜单和长期未使用权限。')) { Add-Bullet $t }
Add-Heading '7.4 当前风险与改进优先级' 2
Add-Table @(
@('级别', '现状观察', '建议'),
@('高', '角色编号存于可由前端读取的 Cookie前端路由守卫将 roles 固定为 admin', '确保服务端基于可信会话重新鉴权;评估更安全的令牌与 Cookie 属性'),
@('高', '正式端点直接写在 static/config.jsAGV 使用 HTTP', '端点环境化并限制网络来源AGV 使用 HTTPS 或隔离网络'),
@('中', 'MES 通用 Axios 超时为1,500,000毫秒25分钟', '按业务分类设置超时、取消请求和服务端作业化'),
@('中', '部分源码中文注释显示编码异常', '统一 UTF-8禁止乱码进入新提交'),
@('中', '页面与数据库过程高度耦合', '建立接口契约、回归测试和变更影响清单')
) @(1.8, 7.1, 8.1) 8.2
Add-Heading '8 请求与接口设计' 1
Add-Heading '8.1 MES 通用请求' 2
Add-Text '常规页面通过统一服务地址 POST JSON。CreateData 将过程执行所需信息序列化,并补充当前用户和页面上下文。不同历史模块存在多个 type 编号,维护时应以对应服务端实现和现有页面为准,不得仅凭编号推断读写性质。'
Add-Table @(
@('字段', '含义', '标准要求'),
@('type', '后端执行/返回策略标识', '新增类型必须形成接口契约'),
@('name', '服务端过程或业务命令名称', '禁止由最终用户自由输入'),
@('param', '参数数组序列化结果', '参数化执行,禁止拼接 SQL'),
@('pageSize / pageList', '分页和页码信息', '大数据查询必须分页'),
@('UserID / UserName', '操作用户上下文', '服务端从可信身份核验,不可盲信'),
@('ModularID', '当前页面路由/模块标识', '用于权限和审计,必须与授权菜单匹配')
) @(3.5, 6.0, 7.5)
Add-Heading '8.2 SAP B1 与 TM 代理' 2
Add-Text 'b1s.js 和 tm.js 将外部 GET、POST、PATCH 统一封装为对代理服务的 POST请求体包含 func、cmd 和序列化 content。代理层负责与真正外部接口通信并返回结果。该设计避免浏览器直接保存 SAP 凭据,但仍需在代理层实施命令白名单、权限、超时和日志。'
Add-Table @(
@('接口族', '超时', '成功返回', '失败处理'),
@('B1 代理', '100秒', '{ success: true, data }', '提取 SAP error.message 或网络错误'),
@('TM 代理', '100秒', '{ success: true, data }', '复用相同错误提取逻辑'),
@('MES 通用接口', '1500秒', 'Axios response', '当前统一实例未集中定义响应拦截器'),
@('AGV', '页面 Axios 默认行为', '校验返回 ids 包含任务号', '失败后不应更新 MES 任务为 RUNNING')
) @(3.0, 2.4, 5.5, 6.1)
Add-Heading '8.3 接口标准' 2
foreach ($t in @('所有写接口必须定义业务主键、幂等规则、允许状态、数量边界和事务范围。','统一返回结构至少包含 success/code/message/data/traceId业务失败不使用模糊的“操作失败”。','查询接口明确分页、排序、最大导出量和日期范围;导出应与查询权限一致。','跨系统调用记录请求时间、目标系统、业务编号、结果码和耗时,但对密码、令牌、个人敏感信息脱敏。','对网络超时、重复提交和外部系统成功但 MES 更新失败定义补偿或人工对账流程。')) { Add-Bullet $t }
Add-Heading '9 数据架构' 1
Add-Heading '9.1 正式数据库基线' 2
Add-Table @(
@('项目', '当前值', '说明'),
@('数据库', 'YL_MESDB', 'MES 主业务数据库'),
@('数据库引擎', 'SQL Server 2019 RTM 15.0.2000.5', '建议评估累计更新补丁'),
@('兼容级别', '150', 'SQL Server 2019'),
@('排序规则', 'Chinese_PRC_CI_AS', '中文、不区分大小写、不区分重音'),
@('恢复模式', 'SIMPLE', '当前不支持日志链上的时间点恢复'),
@('用户表 / 视图', '61 / 27', '只读元数据统计'),
@('存储过程 / 函数', '425 / 2', '业务逻辑主要集中在过程层'),
@('容量', '总计约19.44 GB', '数据约16.62 GB、日志约2.82 GB')
) @(4.0, 5.4, 7.6)
Add-Heading '9.2 核心数据域' 2
Add-Table @(
@('数据域', '代表性对象', '关键关系'),
@('订单与任务', 'MES_接口_生产计划、生产任务、子任务', '订单拆分为工序任务,任务关联工艺、工位、人员和数量'),
@('工艺与图纸', '基础表_工序、标准工艺库、生产工艺库、零件/工艺图纸', '标准工艺可生成订单工艺,订单工艺下发任务'),
@('生产与工时', '操作记录、报工记录、工时校验表', '开始/暂停/结束形成时段,报工和校验形成结算依据'),
@('质量', '质检记录、检测零件、检测数据、检验标准、不合格处置', '任务产生检验,检验结果影响后续流转和统计'),
@('资源', '设备台账、资源主数据、工位人员绑定、班次', '排产和执行以有效工位、设备、人员和班次为约束'),
@('权限与审计', '人员、角色、人员角色、二级菜单、操作日志', '账号经角色获得菜单与操作权限,业务请求留痕'),
@('集成与缓存', '物料、BOM、设备实时缓存、历史状态、附件', '承接 SAP、设备、文件等外部数据')
) @(3.2, 6.6, 7.2) 8.2
Add-Heading '9.3 关键状态模型' 2
Add-Table @(
@('对象', '典型状态/动作', '控制要求'),
@('生产订单', '未准备工艺 → 已准备工艺 → 已排产 → 执行中 → 完工/关闭', '状态转换需检查工艺、任务、数量和未完成工时'),
@('工序任务', '待下发/可执行 → 已开工 → 暂停/恢复 → 已报工/完成', '重复开始、越量报工和跨状态操作必须拦截'),
@('工艺', '生成/编辑 → 保存启用 → 下发任务', '字段即时保存与整条启用要区分;结构变更后重新启用'),
@('质检任务', '待检 → 检验中 → 合格/不合格 → 处置/放行', '实测值、判定、数量和处置结果保持一致'),
@('工时', '操作记录 → 计算工时 → 校验/修正 → 结算', '原始记录保留,修正需审计并可追溯')
) @(3.2, 7.0, 6.8)
Add-Heading '9.4 数据完整性与事务' 2
Add-Note '现状观察' '61张用户表仅检测到8个外键约束较多关联完整性可能由存储过程和业务代码维护。技术变更必须核对逻辑外键、孤儿数据和删除影响。' 'risk'
foreach ($t in @('订单、任务、工艺、操作记录、报工和检验之间使用稳定业务主键关联。','批量下发、报工、检验保存、订单关闭等跨表写入在同一事务中完成。','数量字段统一精度和单位,写入前校验非负、累计不超计划及合格/不合格合计关系。','删除优先采用业务停用或软删除;确需物理删除时先检查下游引用并记录审计。','时间统一保存完整日期时间,明确计划时间、操作时间、服务器时间和班次边界。')) { Add-Bullet $t }
Add-Heading '9.5 备份与恢复' 2
Add-Table @(
@('项目', '最低要求', '验证证据'),
@('全量备份', '每日一次,保留周期按公司制度', '备份作业日志与文件校验'),
@('差异/日志备份', '若要求时间点恢复,将数据库切换为 FULL 并建立日志备份链', '恢复演练可定位到目标时间'),
@('异地副本', '至少一份与数据库主机故障域隔离', '抽查可读与保留周期'),
@('恢复演练', '季度或重大版本前执行', '恢复耗时、数据校验、问题清单'),
@('变更前备份', '数据库结构/过程或批量数据变更前执行', '脚本、备份和回退编号互相引用')
) @(4.0, 8.0, 5.0)
Add-Heading '10 关键业务技术设计' 1
Add-Heading '10.1 工艺到任务下发' 2
Add-Number '维护工序基础数据和物料标准工艺。标准工艺是后续订单生成生产工艺的来源。'
Add-Number '为生产订单生成订单专用生产工艺;调整工序顺序、工时、车间、设备和说明。'
Add-Number '保存当前订单工艺,使其进入可用于计划和任务生成的启用状态。字段即时保存不等同于整条工艺启用。'
Add-Number '整单下发按工艺路线生成全部工序任务;单工序下发仅用于补发目标工序。必须防止重复任务。'
Add-Number '任务进入计划和生产执行后,工艺结构变更必须评估已排产、已开工、工时和质量记录。'
Add-Heading '10.2 计划排产到生产执行' 2
Add-Table @(
@('阶段', '写入/改变', '下游影响'),
@('排产', '工位、人员、数量、计划开始/完成、外协分组等', '工位负荷、任务可执行时间、物料准备和异常判断'),
@('收料/领料', '物料接收或领用状态', '允许后续开始并形成物料追踪'),
@('开工', '任务进入执行状态并形成开始记录', '设备/人员占用、在制进度和工时开始'),
@('暂停/恢复', '记录暂停区间和原因', '净工时、设备状态和异常统计'),
@('报工/结束', '完成数量、工时、操作记录和任务进度', '质量送检、后工序、完工判断和工时报表'),
@('送检/收检', '检验任务或跨工序接收结果', '质量闭环及后续工序可执行性')
) @(3.1, 6.8, 7.1)
Add-Heading '10.3 工时闭环' 2
Add-Text '系统以操作记录为原始事实,结合开始、暂停、恢复和结束时间计算生产/辅助工时;报工记录承载完成数量和确认信息;工时校验和工时修正用于处理异常。任何修正都应保留原值、修正值、原因、操作人和时间,结算工时只使用已满足校验规则的数据。'
Add-Heading '10.4 质量闭环' 2
Add-Text '质量任务从生产送检、采购入库、销售退货、原材料退库或其他入库场景产生。检验标准提供项目、上下限、比例和量具要求;检验结果记录实测值、合格/不合格数量和判定。非合格结果进入返工、让步、报废或其他处置,并反馈生产、库存和统计。'
Add-Heading '10.5 异常与交付' 2
Add-Text '异常提醒依据计划与实际时间、任务状态和加急标记形成。销售订单状态页面汇总 SAP 和 MES 的计划、齐套、拣配、发料、装配、送检、入库和发货状态。汇总页面原则上只读展示,不应成为绕过原业务模块直接改状态的入口。'
Add-Heading '11 模块技术边界' 1
foreach ($m in $moduleDesign) {
Add-Heading ("11.{0} {1}" -f ([array]::IndexOf($moduleDesign, $m) + 1), $m[0]) 2
Add-Table @(
@('项目', '说明'),
@('核心职责', $m[1]),
@('主要输入', $m[2]),
@('主要输出/影响', $m[3]),
@('页面范围', ($modulePages[$m[0]] -join '、'))
) @(3.5, 13.5) 8.4
}
Add-Heading '12 文件、设备与外部集成' 1
Add-Heading '12.1 图纸与附件' 2
Add-Table @(
@('环节', '实现', '控制要求'),
@('上传', 'MESUploadFile.ashx', '校验扩展名、MIME、大小、病毒和业务归属'),
@('存储', '文件服务目录与数据库元数据', '文件名不可作为唯一标识,保留哈希/版本/上传人'),
@('下载/预览', 'webpage/part/ 与 PDF 预览组件', '与业务记录权限一致,避免目录遍历'),
@('删除', '业务删除记录或状态', '保留审计,防止已下发工艺失去依据')
) @(3.0, 6.0, 8.0)
Add-Heading '12.2 AGV' 2
Add-Text '物料机器人页面先在 MES 创建搬运任务,再调用 AGV 接口下发 ContainerTransportOrder只有接口返回任务号成功后才将 MES 状态更新为 RUNNING。应补充超时后的任务查询、重复下发幂等和“AGV成功但MES更新失败”的对账补偿。'
Add-Heading '12.3 设备与 MQTT' 2
Add-Text '公共工具支持 Cmd_Opc_Read 和 Cmd_Opc_Write通过设备 API 读取或写入 TagListMQTT 用于实时数据订阅。写设备命令属于高风险操作必须限制目标客户端、Tag 白名单、数值范围和操作权限,并记录请求与设备响应。'
Add-Heading '12.4 SAP B1' 2
Add-Text 'SAP B1 是订单、物料、BOM、采购、库存等数据的重要外部来源。MES 通过代理执行 Service Layer 请求。集成设计必须明确主数据权威方、同步方向、时间窗口、失败重试、重复数据判定和日常对账。'
Add-Heading '13 日志、监控与审计' 1
Add-Heading '13.1 日志分类' 2
Add-Table @(
@('日志', '内容', '用途'),
@('用户操作日志', '用户、模块、动作、业务主键、结果、时间', '责任追溯和安全审计'),
@('API 请求/响应日志', '命令、参数摘要、耗时、结果码、traceId', '接口故障定位;敏感字段脱敏'),
@('数据库作业日志', '备份、同步、清理和计划任务结果', '运维检查和恢复依据'),
@('外部集成日志', 'SAP/TM/AGV/设备调用状态和业务编号', '跨系统对账和补偿'),
@('前端错误', '页面、用户、版本、错误栈和时间', '定位浏览器端异常')
) @(3.8, 8.0, 5.2)
Add-Heading '13.2 监控指标' 2
foreach ($t in @('站点与接口可用率、证书有效期、HTTP 5xx 和超时率。','MES 通用接口、B1、TM、AGV接口的P50/P95响应时间和失败率。','数据库 CPU、内存、数据/日志空间、阻塞、死锁、慢查询和备份状态。','订单同步延迟、待下发任务、超时任务、未闭环工时、待检和不合格处置积压。','文件服务容量、上传失败率和无业务引用文件。')) { Add-Bullet $t }
Add-Heading '13.3 告警分级' 2
Add-Table @(
@('级别', '示例', '响应目标'),
@('P1', '系统不可用、数据破坏、越权或批量错误写入', '立即响应,停止相关写入并启动应急'),
@('P2', '核心模块不可用、SAP/AGV关键链路中断', '30分钟内响应并给出绕行/恢复方案'),
@('P3', '单一报表、导出或非核心页面异常', '工作时间内响应并纳入修复计划'),
@('P4', '体验、文案或低风险数据展示问题', '按版本排期')
) @(2.0, 10.0, 5.0)
Add-Heading '14 性能与容量' 1
Add-Heading '14.1 查询规范' 2
foreach ($t in @('列表查询默认分页,日期范围和导出量设置上限。','常用筛选字段建立与查询计划匹配的索引,避免对列进行不可搜索的函数包装。','页面首次加载不并发请求无关的大数据字典和全部明细;明细按需展开。','导出超过同步阈值时转后台任务,并提供下载状态。','对25分钟的通用超时进行业务分类避免浏览器长期占用连接。')) { Add-Bullet $t }
Add-Heading '14.2 容量基线与趋势' 2
Add-Text '当前数据库约19.44 GB。运维应每月记录数据文件、日志文件、核心大表行数、附件容量和增长率当预计剩余空间不足三个月时提前扩容或归档。归档必须保持订单、任务、工时、质量和审计记录之间的可追溯性。'
Add-Heading '14.3 性能验收建议' 2
Add-Table @(
@('场景', '建议目标', '备注'),
@('登录与菜单', '正常内网条件下5秒内完成', '包含动态路由构建'),
@('普通分页查询', 'P95不超过5秒', '合理筛选范围'),
@('复杂统计报表', 'P95不超过15秒', '超过阈值采用异步'),
@('保存/状态操作', 'P95不超过5秒', '不含不可控外部系统等待'),
@('关键外部接口', '定义独立超时、重试和熔断', '避免整页无期限等待')
) @(4.0, 5.0, 8.0)
Add-Heading '15 运维与故障处理' 1
Add-Heading '15.1 日常检查' 2
Add-Table @(
@('频率', '检查项'),
@('每日', '站点/API可用、数据库空间、备份结果、同步/作业、P1/P2告警、待处理外部接口失败'),
@('每周', '慢查询、阻塞/死锁、异常日志趋势、菜单权限变更、附件增长和关键业务积压'),
@('每月', '容量趋势、账号权限复核、证书/密码到期、依赖漏洞、恢复点与监控覆盖'),
@('每季度', '恢复演练、应急演练、技术债评审和关键业务全链路回归')
) @(3.0, 14.0)
Add-Heading '15.2 故障定位顺序' 2
Add-Number '确认影响范围:单用户、单角色、单页面、单接口、单数据库对象或全系统。'
Add-Number '记录时间、用户、页面、业务编号、操作和错误信息,不要求用户重复高风险操作。'
Add-Number '检查浏览器网络请求、服务可用性、外部系统状态和数据库阻塞/错误。'
Add-Number '使用 traceId、业务主键和操作人关联前端、服务、数据库与外部接口日志。'
Add-Number '需要数据修复时先备份和评估影响,使用经评审脚本,完成后验证上下游一致性。'
Add-Heading '15.3 常见故障矩阵' 2
Add-Table @(
@('现象', '优先检查', '禁止做法'),
@('登录后无菜单', '角色、菜单启用、组件路径、Cookie和getInfo返回', '直接给管理员权限绕过'),
@('页面一直加载', '网络请求、25分钟超时、数据库阻塞和返回规模', '连续刷新并重复写操作'),
@('保存成功但列表未变', '返回结果、事务提交、查询条件、缓存和刷新逻辑', '未核对数据就再次新增'),
@('SAP/AGV失败', '外部接口日志、业务编号、幂等状态和MES本地状态', '盲目重复下发'),
@('工时/数量不一致', '操作记录、报工、检验、修正审计和累计边界', '直接覆盖原始记录'),
@('图纸打不开', '文件元数据、物理文件、权限、MIME和路径', '将目录改为匿名公开')
) @(4.0, 8.5, 4.5) 8.2
Add-Heading '16 变更、发布与回退' 1
Add-Heading '16.1 标准变更流程' 2
Add-Number '提出变更:说明问题、范围、业务规则、数据影响、权限影响和验收标准。'
Add-Number '技术分析:定位页面、共享工具、接口、过程、表、视图、菜单和外部系统影响。'
Add-Number '实施:代码和数据库脚本分离管理;正式凭据不进入版本库。'
Add-Number '验证:静态检查、单元/定向测试、接口测试、数据库只读验证和关键链路回归。'
Add-Number '发布:备份、窗口确认、脚本执行、前端发布、配置核对和冒烟测试。'
Add-Number '观察与回退:监控错误率和业务状态;达到回退条件时按预案恢复。'
Add-Heading '16.2 数据库脚本规范' 2
foreach ($t in @('文件名包含动作、模块、日期;不覆盖历史脚本。','先备份被修改对象定义;脚本使用 TRY/CATCH、事务和 XACT_ABORT。','对象创建/修改具备前置检查,重复执行不会产生重复业务数据。','禁止在同一脚本中混入无关结构变更和业务数据修复。','附带只读验证查询和明确回退方案;正式执行结果写入变更记录。')) { Add-Bullet $t }
Add-Heading '16.3 前端发布检查' 2
Add-Table @(
@('阶段', '检查项'),
@('构建前', '锁文件一致、Node/npm版本、ESLint、git diff --check、无敏感信息'),
@('构建后', 'index、JS/CSS、图标字体、懒加载页面、static/config.js'),
@('发布后', 'HTTPS、缓存、登录、目标角色菜单、核心查询/写入、附件、导出'),
@('观察期', '前端错误、接口失败、数据库阻塞和用户反馈')
) @(3.5, 13.5)
Add-Heading '17 测试与验收' 1
Add-Heading '17.1 测试层次' 2
Add-Table @(
@('层次', '覆盖重点', '证据'),
@('静态检查', 'ESLint、编码、敏感信息、脚本语法', '命令输出与检查报告'),
@('组件/函数', '校验、状态计算、导出字段和共享工具', '自动化测试结果'),
@('接口', '参数、权限、分页、错误、幂等和事务', '请求响应样例与数据库核对'),
@('业务链路', '工艺→排产→下发→生产→质量→关闭/交付', '测试记录和状态截图'),
@('角色权限', '不同角色的菜单、按钮和数据范围', '权限矩阵'),
@('非功能', '性能、恢复、安全、兼容性和容量', '压测/演练/扫描报告')
) @(3.2, 8.0, 5.8)
Add-Heading '17.2 核心回归场景' 2
foreach ($t in @('登录、单/多角色选择、菜单加载和退出。','标准工艺生成生产工艺、编辑、保存启用、整单和单工序下发。','机加与装配排产、计划时间/工位/人员/数量调整及已排产查询。','收料、开工、暂停、恢复、报工、送检和工时计算。','采购/过程/终检、实测值保存、不合格处置及下游状态。','订单关闭、齐套、发货通知和销售订单全流程状态。','SAP、TM、图纸附件、AGV和设备接口的成功与失败分支。')) { Add-Bullet $t }
Add-Heading '17.3 上线验收门槛' 2
Add-Note '上线条件' 'P1/P2缺陷为0核心链路通过数据库脚本、回退和备份验证完成权限矩阵通过目标角色验证监控和应急联系人就绪文档与变更记录已更新。' 'warn'
Add-Heading '18 风险与技术债' 1
Add-Table @(
@('优先级', '风险/技术债', '影响', '建议行动'),
@('P0', '正式凭据与权限完全依赖前端将造成越权风险', '数据安全与审计', '确认服务端强制鉴权,开展权限穿透测试'),
@('P1', '数据库为 SIMPLE 恢复模式', '无法时间点恢复', '依据RPO/RTO决定是否切换FULL并建立日志备份'),
@('P1', 'SQL Server 2019 RTM 未体现累计更新', '稳定性与安全补丁', '测试后升级到受支持CU'),
@('P1', 'AGV接口使用HTTP且地址硬编码', '传输安全与环境切换', '服务端代理/HTTPS/配置化'),
@('P1', '通用请求超时25分钟', '资源占用与用户重复操作', '分类超时、取消、异步任务和幂等'),
@('P2', '大型单文件页面和过程耦合度高', '维护成本与回归风险', '按业务域拆分并建立契约测试'),
@('P2', '外键较少,关系主要靠过程维护', '孤儿数据和删除风险', '补充数据质量检查,逐步增加约束'),
@('P2', '源码存在编码异常', '可读性和误改风险', '统一UTF-8并加入检查')
) @(2.0, 5.4, 4.0, 5.6) 8.0
Add-Heading '19 附录A正式功能页面清单' 1
$moduleNo = 1
foreach ($key in $modulePages.Keys) {
Add-Heading ("A.{0} {1}" -f $moduleNo, $key) 2
$rows = @()
$rows += ,@('序号', '页面名称', '技术归属')
for ($i = 0; $i -lt $modulePages[$key].Count; $i++) {
$rows += ,@(($i + 1).ToString(), $modulePages[$key][$i], $key)
}
Add-Table $rows @(2.0, 9.0, 6.0)
$moduleNo++
}
Add-Heading '20 附录B关键对象参考' 1
Add-Heading 'B.1 代表性数据库对象' 2
Add-Table @(
@('类别', '代表对象', '用途'),
@('生产计划', 'MES_接口_生产计划、MES_接口_生产计划_生产任务', '订单和工序任务主数据'),
@('工艺', '基础表_工序、标准工艺库、生产工艺库', '工序与路线'),
@('工时', 'YL_加工中心_操作记录表、YL_加工中心_报工记录', '开始、暂停、结束和报工事实'),
@('质量', 'YL_质量检验_质检记录及检测明细', '检验结果与实测数据'),
@('资源', 'MES_资源主数据、设备台账、工位人员绑定表、班次表', '工位设备与人员班次'),
@('权限', '登录基础数据_人员信息、角色信息、人员权限角色、二级菜单', '身份、角色和菜单权限'),
@('日志', '_日志、记录_日志_项目运行日志', '用户操作与接口请求响应')
) @(3.0, 8.0, 6.0) 8.2
Add-Heading 'B.2 关键前端入口' 2
Add-Table @(
@('文件', '职责'),
@('src/main.js', '注册 Vue、Element UI、公共指令、CRUD、图表和根实例'),
@('src/permission.js', '登录白名单、动态菜单加载和路由守卫'),
@('src/router/getTreeData.js', '将数据库菜单转换为路由树'),
@('src/utils/request.js', 'MES 通用 Axios 实例和文件地址'),
@('src/utils/curd.js', '统一请求载荷、通用表格操作和设备读写辅助'),
@('src/api/b1s.js / tm.js', 'SAP B1 与 TM 代理封装'),
@('static/config.js', '正式运行时服务地址')
) @(6.0, 11.0)
Add-Heading '21 附录C上线与运维检查表' 1
Add-Table @(
@('编号', '检查项', '结果', '责任人/日期'),
@('C-01', '前端构建、版本号、资源和 static/config.js 正确', '□通过 □不通过', ''),
@('C-02', 'HTTPS证书、端口、防火墙和DNS/地址可用', '□通过 □不通过', ''),
@('C-03', '数据库备份完成且可读取,回退脚本已准备', '□通过 □不通过', ''),
@('C-04', '数据库脚本执行与只读验证完成', '□通过 □不通过', ''),
@('C-05', '目标角色菜单、按钮与数据权限验证完成', '□通过 □不通过', ''),
@('C-06', '核心业务链路与外部接口冒烟通过', '□通过 □不通过', ''),
@('C-07', '日志、监控、告警和应急联系人就绪', '□通过 □不通过', ''),
@('C-08', '变更记录、技术文档和用户文档已更新', '□通过 □不通过', ''),
@('C-09', '观察期和回退决策人已明确', '□通过 □不通过', '')
) @(1.8, 9.4, 3.4, 3.0) 8.2
# 页眉页脚
$header = $section.Headers.Item(1).Range
$header.Text = '大连元利流体技术有限公司 MES 系统标准技术文档'
$header.Font.NameFarEast = '微软雅黑'; $header.Font.Name = 'Arial'; $header.Font.Size = 8.5; $header.Font.Color = 0x777777
$header.ParagraphFormat.Alignment = 2
$footer = $section.Footers.Item(1).Range
$footer.Text = '内部技术资料 | '
$footer.Font.NameFarEast = '微软雅黑'; $footer.Font.Name = 'Arial'; $footer.Font.Size = 8.5; $footer.Font.Color = 0x777777
$footer.ParagraphFormat.Alignment = 1
$footer.Collapse(0)
[void]$footer.Fields.Add($footer, 33)
foreach ($toc in $doc.TablesOfContents) { $toc.Update() }
[void]$doc.Fields.Update()
$doc.Repaginate()
try {
$doc.BuiltInDocumentProperties.Item('Title').Value = '大连元利流体技术有限公司MES系统标准技术文档'
$doc.BuiltInDocumentProperties.Item('Subject').Value = 'MES系统架构、部署、数据、接口、权限、运维与验收技术基线'
$doc.BuiltInDocumentProperties.Item('Author').Value = 'MESWORK'
} catch {
Write-ProgressLog '当前 Office 兼容层不支持写入内置文档属性,已跳过属性写入'
}
$doc.SaveAs2($docxPath, 16)
$doc.ExportAsFixedFormat($pdfPath, 17)
$pages = $doc.ComputeStatistics(2)
Write-ProgressLog "已生成 DOCX 和 PDF$pages"
try { $doc.Close($false) } catch { Write-ProgressLog 'Office 已保存文档,但关闭文档时返回兼容层异常' }
$doc = $null
try { $word.Quit() } catch { Write-ProgressLog 'Office 进程已退出,但 Quit 调用返回 RPC 兼容层异常' }
$word = $null
[GC]::Collect(); [GC]::WaitForPendingFinalizers()
[pscustomobject]@{
Docx = $docxPath
Pdf = $pdfPath
Pages = $pages
Modules = $modulePages.Count
PagesInScope = ($modulePages.Values | ForEach-Object { $_.Count } | Measure-Object -Sum).Sum
} | Format-List
}
catch {
Write-ProgressLog ("生成失败:" + $_.Exception.Message)
if ($null -ne $doc) { try { $doc.Close($false) } catch {} }
if ($null -ne $word) { try { $word.Quit() } catch {} }
[GC]::Collect(); [GC]::WaitForPendingFinalizers()
throw
}