render_supply_flow.ps1 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. Add-Type -AssemblyName System.Drawing
  2. $desktop = [Environment]::GetFolderPath("Desktop")
  3. $output = Join-Path $desktop "供应监测决策流程图.png"
  4. $width = 3600
  5. $height = 1850
  6. $bmp = New-Object System.Drawing.Bitmap($width, $height)
  7. $g = [System.Drawing.Graphics]::FromImage($bmp)
  8. $g.SmoothingMode = [System.Drawing.Drawing2D.SmoothingMode]::AntiAlias
  9. $g.TextRenderingHint = [System.Drawing.Text.TextRenderingHint]::ClearTypeGridFit
  10. $g.Clear([System.Drawing.Color]::White)
  11. $fontFamily = "Microsoft YaHei"
  12. $font = New-Object System.Drawing.Font($fontFamily, 28, [System.Drawing.FontStyle]::Regular)
  13. $boldFont = New-Object System.Drawing.Font($fontFamily, 30, [System.Drawing.FontStyle]::Bold)
  14. $titleFont = New-Object System.Drawing.Font($fontFamily, 44, [System.Drawing.FontStyle]::Bold)
  15. $labelFont = New-Object System.Drawing.Font($fontFamily, 24, [System.Drawing.FontStyle]::Bold)
  16. $black = [System.Drawing.Color]::FromArgb(35, 35, 35)
  17. $lineColor = [System.Drawing.Color]::FromArgb(72, 92, 120)
  18. $blueFill = [System.Drawing.Color]::FromArgb(235, 244, 255)
  19. $greenFill = [System.Drawing.Color]::FromArgb(235, 250, 241)
  20. $yellowFill = [System.Drawing.Color]::FromArgb(255, 249, 225)
  21. $redFill = [System.Drawing.Color]::FromArgb(255, 238, 238)
  22. $grayFill = [System.Drawing.Color]::FromArgb(247, 249, 252)
  23. $strokeBlue = [System.Drawing.Color]::FromArgb(69, 125, 197)
  24. $strokeGreen = [System.Drawing.Color]::FromArgb(46, 140, 88)
  25. $strokeYellow = [System.Drawing.Color]::FromArgb(196, 142, 35)
  26. $strokeRed = [System.Drawing.Color]::FromArgb(196, 76, 76)
  27. $strokeGray = [System.Drawing.Color]::FromArgb(130, 145, 165)
  28. function New-Pen($color, $width) {
  29. $pen = New-Object System.Drawing.Pen($color, $width)
  30. $pen.StartCap = [System.Drawing.Drawing2D.LineCap]::Round
  31. $pen.EndCap = [System.Drawing.Drawing2D.LineCap]::Round
  32. return $pen
  33. }
  34. $linePen = New-Pen $lineColor 4
  35. $arrowPen = New-Pen $lineColor 4
  36. $arrowPen.CustomEndCap = New-Object System.Drawing.Drawing2D.AdjustableArrowCap(8, 8)
  37. $textBrush = New-Object System.Drawing.SolidBrush($black)
  38. $labelBrush = New-Object System.Drawing.SolidBrush([System.Drawing.Color]::FromArgb(55, 75, 100))
  39. $sf = New-Object System.Drawing.StringFormat
  40. $sf.Alignment = [System.Drawing.StringAlignment]::Center
  41. $sf.LineAlignment = [System.Drawing.StringAlignment]::Center
  42. $sf.FormatFlags = [System.Drawing.StringFormatFlags]::LineLimit
  43. function Draw-RoundRect($graphics, $rect, $radius, $fill, $stroke) {
  44. $path = New-Object System.Drawing.Drawing2D.GraphicsPath
  45. $d = $radius * 2
  46. $path.AddArc($rect.X, $rect.Y, $d, $d, 180, 90)
  47. $path.AddArc($rect.Right - $d, $rect.Y, $d, $d, 270, 90)
  48. $path.AddArc($rect.Right - $d, $rect.Bottom - $d, $d, $d, 0, 90)
  49. $path.AddArc($rect.X, $rect.Bottom - $d, $d, $d, 90, 90)
  50. $path.CloseFigure()
  51. $graphics.FillPath((New-Object System.Drawing.SolidBrush($fill)), $path)
  52. $graphics.DrawPath((New-Object System.Drawing.Pen($stroke, 4)), $path)
  53. }
  54. function Draw-Node($id, $x, $y, $w, $h, $text, $fill, $stroke) {
  55. $rect = New-Object System.Drawing.RectangleF($x, $y, $w, $h)
  56. Draw-RoundRect $g $rect 22 $fill $stroke
  57. $inner = New-Object System.Drawing.RectangleF($x + 18, $y + 10, $w - 36, $h - 20)
  58. $g.DrawString($text, $font, $textBrush, $inner, $sf)
  59. $script:nodes[$id] = $rect
  60. }
  61. function Draw-Diamond($id, $x, $y, $w, $h, $text, $fill, $stroke) {
  62. $path = New-Object System.Drawing.Drawing2D.GraphicsPath
  63. $path.AddPolygon(@(
  64. (New-Object System.Drawing.PointF(($x + $w / 2), $y)),
  65. (New-Object System.Drawing.PointF(($x + $w), ($y + $h / 2))),
  66. (New-Object System.Drawing.PointF(($x + $w / 2), ($y + $h))),
  67. (New-Object System.Drawing.PointF($x, ($y + $h / 2)))
  68. ))
  69. $g.FillPath((New-Object System.Drawing.SolidBrush($fill)), $path)
  70. $g.DrawPath((New-Object System.Drawing.Pen($stroke, 4)), $path)
  71. $inner = New-Object System.Drawing.RectangleF($x + 40, $y + 18, $w - 80, $h - 36)
  72. $g.DrawString($text, $boldFont, $textBrush, $inner, $sf)
  73. $script:nodes[$id] = New-Object System.Drawing.RectangleF($x, $y, $w, $h)
  74. }
  75. function Center($rect) {
  76. return New-Object System.Drawing.PointF(($rect.X + $rect.Width / 2), ($rect.Y + $rect.Height / 2))
  77. }
  78. function EdgePoint($rect, $side) {
  79. switch ($side) {
  80. "L" { return New-Object System.Drawing.PointF($rect.X, ($rect.Y + $rect.Height / 2)) }
  81. "R" { return New-Object System.Drawing.PointF(($rect.X + $rect.Width), ($rect.Y + $rect.Height / 2)) }
  82. "T" { return New-Object System.Drawing.PointF(($rect.X + $rect.Width / 2), $rect.Y) }
  83. "B" { return New-Object System.Drawing.PointF(($rect.X + $rect.Width / 2), ($rect.Y + $rect.Height)) }
  84. }
  85. }
  86. function Draw-Arrow($from, $fromSide, $to, $toSide, $label = "") {
  87. $a = EdgePoint $nodes[$from] $fromSide
  88. $b = EdgePoint $nodes[$to] $toSide
  89. $g.DrawLine($arrowPen, $a, $b)
  90. if ($label -ne "") {
  91. $mx = ($a.X + $b.X) / 2
  92. $my = ($a.Y + $b.Y) / 2
  93. $labelRect = New-Object System.Drawing.RectangleF($mx - 42, $my - 32, 84, 44)
  94. $g.FillRectangle([System.Drawing.Brushes]::White, $labelRect)
  95. $g.DrawString($label, $labelFont, $labelBrush, $labelRect, $sf)
  96. }
  97. }
  98. function Draw-PolylineArrow($points, $label = "", $labelX = 0, $labelY = 0) {
  99. for ($i = 0; $i -lt $points.Count - 2; $i++) {
  100. $g.DrawLine($linePen, $points[$i], $points[$i + 1])
  101. }
  102. $g.DrawLine($arrowPen, $points[$points.Count - 2], $points[$points.Count - 1])
  103. if ($label -ne "") {
  104. $labelRect = New-Object System.Drawing.RectangleF($labelX - 42, $labelY - 32, 84, 44)
  105. $g.FillRectangle([System.Drawing.Brushes]::White, $labelRect)
  106. $g.DrawString($label, $labelFont, $labelBrush, $labelRect, $sf)
  107. }
  108. }
  109. $nodes = @{}
  110. $titleRect = New-Object System.Drawing.RectangleF(0, 35, $width, 70)
  111. $g.DrawString("供应监测补货决策流程", $titleFont, $textBrush, $titleRect, $sf)
  112. Draw-Node "A" 80 735 500 180 "更新数据`n预测需求 / 现有库存 / 在途库存`n半成品库存 / 已下单未要求来货" $blueFill $strokeBlue
  113. Draw-Node "B" 700 735 430 180 "核算现有可用量`n现有库存 + 半成品可组装量" $blueFill $strokeBlue
  114. Draw-Diamond "C" 1240 680 380 290 "现有可用量`n是否覆盖需求?" $yellowFill $strokeYellow
  115. Draw-Node "D" 1780 330 360 140 "现有库存可覆盖" $greenFill $strokeGreen
  116. Draw-Diamond "E" 2300 285 360 230 "是否需要`n组装半成品?" $yellowFill $strokeYellow
  117. Draw-Node "F" 2830 190 340 130 "无需来货 / 下单" $greenFill $strokeGreen
  118. Draw-Node "G" 2830 420 340 150 "安排半成品组装`n转为成品库存" $greenFill $strokeGreen
  119. Draw-Node "H" 1780 830 360 150 "现有可用量不足`n计算缺口" $redFill $strokeRed
  120. Draw-Diamond "I" 2300 795 360 230 "在途库存`n是否覆盖缺口?" $yellowFill $strokeYellow
  121. Draw-Node "J" 2830 710 340 150 "跟进在途到货`n更新到货计划" $greenFill $strokeGreen
  122. Draw-Node "K" 2830 960 340 130 "在途后仍有缺口" $redFill $strokeRed
  123. Draw-Diamond "L" 2300 1210 360 250 "已下单未要求来货`n是否覆盖缺口?" $yellowFill $strokeYellow
  124. Draw-Node "M" 2830 1180 340 160 "安排来货`n通知供应商发货 / 到货" $greenFill $strokeGreen
  125. Draw-Node "N" 1780 1275 360 160 "已下单量仍不足`n计算新增下单量" $redFill $strokeRed
  126. Draw-Diamond "O" 1240 1225 380 230 "是否急需?" $yellowFill $strokeYellow
  127. Draw-Node "P" 700 1125 430 150 "新增加急下单`n优先排产" $redFill $strokeRed
  128. Draw-Node "Q" 700 1390 430 130 "新增常规下单" $grayFill $strokeGray
  129. Draw-Node "S" 2830 610 340 130 "更新组装计划`n回写库存跟踪" $blueFill $strokeBlue
  130. Draw-Node "T" 2830 890 340 130 "更新在途到货计划`n回写库存跟踪" $blueFill $strokeBlue
  131. Draw-Node "U" 2830 1385 340 130 "更新来货计划`n回写库存跟踪" $blueFill $strokeBlue
  132. Draw-Node "V" 700 1610 430 130 "更新下单计划`n回写库存跟踪" $blueFill $strokeBlue
  133. Draw-Node "R" 1780 1610 420 130 "持续跟踪销售与库存" $greenFill $strokeGreen
  134. Draw-Arrow "A" "R" "B" "L"
  135. Draw-Arrow "B" "R" "C" "L"
  136. Draw-Arrow "C" "R" "D" "L" "是"
  137. Draw-Arrow "C" "R" "H" "L" "否"
  138. Draw-Arrow "D" "R" "E" "L"
  139. Draw-Arrow "E" "R" "F" "L" "否"
  140. Draw-Arrow "E" "R" "G" "L" "是"
  141. Draw-Arrow "H" "R" "I" "L"
  142. Draw-Arrow "I" "R" "J" "L" "是"
  143. Draw-Arrow "I" "R" "K" "L" "否"
  144. Draw-PolylineArrow @((EdgePoint $nodes["K"] "B"), (New-Object System.Drawing.PointF(3000, 1130)), (New-Object System.Drawing.PointF(2480, 1130)), (EdgePoint $nodes["L"] "T"))
  145. Draw-Arrow "L" "R" "M" "L" "是"
  146. Draw-PolylineArrow @((EdgePoint $nodes["L"] "L"), (New-Object System.Drawing.PointF(2160, 1335)), (EdgePoint $nodes["N"] "R")) "否" 2200 1335
  147. Draw-Arrow "N" "L" "O" "R"
  148. Draw-Arrow "O" "L" "P" "R" "是"
  149. Draw-PolylineArrow @((EdgePoint $nodes["O"] "B"), (New-Object System.Drawing.PointF(1430, 1455)), (EdgePoint $nodes["Q"] "R")) "否" 1300 1455
  150. Draw-PolylineArrow @((EdgePoint $nodes["G"] "B"), (New-Object System.Drawing.PointF(3000, 595)), (EdgePoint $nodes["S"] "T"))
  151. Draw-PolylineArrow @((EdgePoint $nodes["J"] "B"), (New-Object System.Drawing.PointF(3000, 875)), (EdgePoint $nodes["T"] "T"))
  152. Draw-PolylineArrow @((EdgePoint $nodes["M"] "B"), (New-Object System.Drawing.PointF(3000, 1365)), (EdgePoint $nodes["U"] "T"))
  153. Draw-Arrow "P" "B" "V" "T"
  154. Draw-Arrow "Q" "B" "V" "T"
  155. Draw-PolylineArrow @((EdgePoint $nodes["F"] "B"), (New-Object System.Drawing.PointF(3000, 1645)), (EdgePoint $nodes["R"] "R"))
  156. Draw-PolylineArrow @((EdgePoint $nodes["S"] "B"), (New-Object System.Drawing.PointF(3000, 1665)), (EdgePoint $nodes["R"] "R"))
  157. Draw-PolylineArrow @((EdgePoint $nodes["T"] "B"), (New-Object System.Drawing.PointF(3000, 1680)), (EdgePoint $nodes["R"] "R"))
  158. Draw-PolylineArrow @((EdgePoint $nodes["U"] "B"), (New-Object System.Drawing.PointF(3000, 1700)), (EdgePoint $nodes["R"] "R"))
  159. Draw-Arrow "V" "R" "R" "L"
  160. $bmp.Save($output, [System.Drawing.Imaging.ImageFormat]::Png)
  161. $g.Dispose()
  162. $bmp.Dispose()
  163. Write-Output $output