BizIngest.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. <?php
  2. namespace app\common\library\ps;
  3. use app\common\model\ps\Product;
  4. use app\common\model\ps\Workorder;
  5. use think\Exception;
  6. /**
  7. * 产品/工单统一入库(页面、AI 导入、Open API 共用)
  8. */
  9. class BizIngest
  10. {
  11. /**
  12. * @param array $payload
  13. * @param int $userId
  14. * @return Product
  15. * @throws Exception
  16. */
  17. public static function saveProduct(array $payload, $userId = 0)
  18. {
  19. $factoryId = FactoryContext::requireId();
  20. $code = self::str($payload, ['code', 'product_code', 'no'], 64);
  21. $name = self::str($payload, ['name', 'product_name', 'title'], 100);
  22. if ($code === '' && $name === '') {
  23. throw new Exception('产品缺少编码或名称');
  24. }
  25. if ($code === '') {
  26. $code = 'P' . date('ymdHis') . substr((string)mt_rand(100, 999), 0, 3);
  27. }
  28. if ($name === '') {
  29. $name = $code;
  30. }
  31. $processes = self::normalizeProcesses($payload);
  32. $row = (new Product())->where('factory_id', $factoryId)->where('code', $code)->find();
  33. $data = [
  34. 'code' => $code,
  35. 'name' => $name,
  36. 'spec' => self::str($payload, ['spec'], 100),
  37. 'unit' => self::str($payload, ['unit'], 20) ?: '件',
  38. 'qty' => self::num($payload, ['qty', 'quantity', 'total_qty']),
  39. 'sheet_qty' => self::num($payload, ['sheet_qty', 'per_sheet', 'tldx']),
  40. 'remark' => self::str($payload, ['remark'], 255),
  41. 'status' => 'normal',
  42. 'creator_user_id' => $userId,
  43. ];
  44. if ($row) {
  45. unset($data['creator_user_id']);
  46. $row->allowField(true)->save($data);
  47. } else {
  48. $row = new Product();
  49. $row->allowField(true)->save($data);
  50. }
  51. ProcessWriter::save($row->id, $processes, 'product');
  52. return $row;
  53. }
  54. /**
  55. * @param array $payload
  56. * @param int $userId
  57. * @return Workorder
  58. * @throws Exception
  59. */
  60. public static function saveWorkorder(array $payload, $userId = 0)
  61. {
  62. $factoryId = FactoryContext::requireId();
  63. $no = self::str($payload, ['no', 'workorder_no', 'code'], 64);
  64. if ($no === '') {
  65. $no = 'WO' . date('ymdHis') . substr((string)mt_rand(100, 999), 0, 3);
  66. }
  67. $productId = (int)($payload['product_id'] ?? 0);
  68. $productCode = self::str($payload, ['product_code'], 64);
  69. if ($productId <= 0 && $productCode !== '') {
  70. $product = (new Product())->where('factory_id', $factoryId)->where('code', $productCode)->find();
  71. if (!$product) {
  72. $product = self::saveProduct([
  73. 'code' => $productCode,
  74. 'name' => self::str($payload, ['product_name', 'name'], 100) ?: $productCode,
  75. 'spec' => self::str($payload, ['spec'], 100),
  76. 'unit' => self::str($payload, ['unit'], 20),
  77. 'processes' => [],
  78. ], $userId);
  79. }
  80. $productId = (int)$product->id;
  81. }
  82. $processes = self::normalizeProcesses($payload);
  83. if (!$processes && $productId > 0) {
  84. $product = Product::with('processes')->find($productId);
  85. $processes = $product ? $product['processes'] : [];
  86. }
  87. $qty = self::num($payload, ['qty', 'quantity', 'total_qty']);
  88. $row = (new Workorder())->where('factory_id', $factoryId)->where('no', $no)->find();
  89. $data = [
  90. 'no' => $no,
  91. 'product_id' => $productId,
  92. 'qty' => $qty,
  93. 'sheet_qty' => self::num($payload, ['sheet_qty', 'per_sheet', 'tldx']),
  94. 'batch_no' => self::str($payload, ['batch_no', 'batch'], 64),
  95. 'customer' => self::str($payload, ['customer'], 100),
  96. 'plan_date' => self::date($payload, ['plan_date', 'date']),
  97. 'remark' => self::str($payload, ['remark'], 255),
  98. 'status' => self::str($payload, ['status'], 20) ?: 'draft',
  99. 'creator_user_id' => $userId,
  100. ];
  101. if ($row) {
  102. unset($data['creator_user_id']);
  103. $row->allowField(true)->save($data);
  104. } else {
  105. $row = new Workorder();
  106. $row->allowField(true)->save($data);
  107. }
  108. ProcessWriter::save($row->id, $processes, 'workorder');
  109. return $row;
  110. }
  111. /**
  112. * @param array $payload
  113. * @return array
  114. */
  115. public static function normalizeProcesses($payload)
  116. {
  117. $rows = [];
  118. if (isset($payload['processes']) && is_array($payload['processes'])) {
  119. $rows = $payload['processes'];
  120. } elseif (isset($payload['process_list']) && is_array($payload['process_list'])) {
  121. $rows = $payload['process_list'];
  122. }
  123. $out = [];
  124. $seq = 1;
  125. foreach ($rows as $row) {
  126. if (!is_array($row)) {
  127. continue;
  128. }
  129. $name = self::str($row, ['name', 'process_name', 'title'], 100);
  130. $code = self::str($row, ['code', 'process_code', 'no'], 64);
  131. if ($name === '' && $code === '') {
  132. continue;
  133. }
  134. $out[] = [
  135. 'seq' => isset($row['seq']) && $row['seq'] !== '' ? (int)$row['seq'] : $seq,
  136. 'code' => $code,
  137. 'name' => $name !== '' ? $name : $code,
  138. 'workstation' => self::str($row, ['workstation', 'station'], 64),
  139. 'standard_time' => self::str($row, ['standard_time', 'time'], 32),
  140. 'qc_points' => self::str($row, ['qc_points', 'qc'], 255),
  141. 'remark' => self::str($row, ['remark'], 255),
  142. ];
  143. $seq++;
  144. }
  145. return $out;
  146. }
  147. protected static function str(array $data, array $keys, $max = 255)
  148. {
  149. foreach ($keys as $key) {
  150. if (!isset($data[$key])) {
  151. continue;
  152. }
  153. $v = trim((string)$data[$key]);
  154. if ($v !== '') {
  155. return mb_substr($v, 0, $max);
  156. }
  157. }
  158. return '';
  159. }
  160. protected static function num(array $data, array $keys)
  161. {
  162. foreach ($keys as $key) {
  163. if (!isset($data[$key]) || $data[$key] === '') {
  164. continue;
  165. }
  166. return (float)$data[$key];
  167. }
  168. return 0;
  169. }
  170. protected static function date(array $data, array $keys)
  171. {
  172. $v = self::str($data, $keys, 32);
  173. if ($v === '') {
  174. return null;
  175. }
  176. $ts = strtotime($v);
  177. return $ts ? date('Y-m-d', $ts) : null;
  178. }
  179. }