Browse Source

成品入仓同步

unknown 1 month ago
parent
commit
5d4f02802b
1 changed files with 135 additions and 127 deletions
  1. 135 127
      application/api/controller/Synchronization.php

+ 135 - 127
application/api/controller/Synchronization.php

@@ -2094,144 +2094,152 @@ class Synchronization extends Api
     }
     }
 
 
     /**
     /**
-     * 成品入仓数据同步中间校验接口
-     * @desc 逐条工单独立校验,一单一条操作日志
-     * 前置校验:先查询【成品入仓】表,校验该工单是否存在末板数据,无末版直接判定同步失败
-     * 固定三步校验逻辑:
-     * 第一步:查询【工单_印件资料】
-     * 第二步:查询【工单_bom资料】提取有效物料
-     * 第三步:查询【物料_收发记录】提取已有台账物料
-     * 比对第二步物料集合与第三步物料集合:完全一致则同步成功,否则同步失败
-     * 无论成功/失败,每条工单单独写入一条操作日志
-     * @request POST
-     * @body JSON 支持单条对象 / 多条数组批量提交
+     * 成品入仓数据同步中间表
+     * @param int|string $uniqId 成品入仓 UniqId
+     * @param string $insertType 插入类型:新增/修改/删除
+     * @return bool
+     * @throws \Exception 同步失败时抛出,便于调用方提示
      */
      */
-    public function syncFinishStockMiddle()
+    public function syncFinishStockMiddle($uniqId, $insertType = '新增')
     {
     {
-        if (!$this->request->isPost()) {
-            return json(['code' => 0, 'msg' => '仅支持POST请求']);
-        }
-        $jsonStr = file_get_contents('php://input');
-        $param   = json_decode($jsonStr, true);
-        if (!is_array($param)) {
-            return json(['code' => 0, 'msg' => 'JSON参数解析失败']);
-        }
-
-        // 兼容单条、多条入参格式
-        $taskList = isset($param[0]) && is_array($param[0]) ? $param : [$param];
-        $resultList = [];
-        // 循环处理每一条工单
-        foreach ($taskList as $item) {
-            $gdbh    = trim($item['Gdbh'] ?? '');
-            $yjno    = trim($item['yjno'] ?? '');
-            $sysId   = $item['sys_id'] ?? '';
-            $type    = $item['type'] ?? '';
-            $syncRq  = date('Y-m-d H:i:s');
-            // 默认标记为失败
-            $status  = '同步失败';
-            $msg     = '';
-            $yjmc    = '';
-            $yjdh    = '';
-            $wlbmStr = '';
-            $bomCodes = [];
-
-            try {
-                if (empty($gdbh) || empty($yjno)) {
-                    throw new Exception('工单编号或印件号为空');
-                }
+        if (empty($uniqId)) {
+            throw new \Exception('同步失败:UniqId 为空');
+        }
 
 
-                // 【前置校验】查询成品入仓表,判断该工单是否存在末板数据
-                $cprc = Db::name('成品入仓')
-                    ->where([
-                        'jjcp_gdbh' => $gdbh,
-                        'jjcp_yjno' => $yjno,
-                        'jjcp_smb'  => '末 板'
-                    ])
-                    ->field('jjcp_gdbh,jjcp_yjno,jjcp_smb,jjcp_cpmc')
-                    ->find();
-                // 未查询到末版数据,直接抛出异常终止当前工单后续流程
-                if (empty($cprc)) {
-                    throw new Exception("工单【{$gdbh}】印件号【{$yjno}】未录入末版数据,无法继续同步");
-                }
+        $record = db('成品入仓')->where('UniqId', $uniqId)->find();
+        if (empty($record)) {
+            throw new \Exception('同步失败:未找到成品入仓记录 UniqId=' . $uniqId);
+        }
 
 
-                // 第一步 查询工单_印件资料
-                $yinInfo = Db::name('工单_印件资料')
-                    ->where([
-                        'Yj_Gdbh' => $gdbh,
-                        'yj_Yjno' => $yjno
-                    ])
-                    ->field('Yj_Gdbh,yj_Yjdh,yj_yjmc,yj_Yjno')
-                    ->find();
-                if (empty($yinInfo)) {
-                    throw new Exception('工单_印件资料无数据');
-                }
-                $yjmc = $yinInfo['yj_yjmc'];
-                $yjdh = $yinInfo['yj_Yjdh'];
-
-                // 第二步 查询工单_bom资料
-                $bomCodes = Db::name('工单_bom资料')
-                    ->where([
-                        'BOM_工单编号' => $gdbh,
-                        'BOM_产品编号' => $yjdh
-                    ])
-                    ->where('BOM_实际用量', '<>', 0)
-                    ->group('BOM_物料编码')
-                    ->column('BOM_物料编码');
-                if (empty($bomCodes)) {
-                    throw new Exception('工单_bom资料无有效物料数据');
-                }
-                $wlbmStr = implode(',', $bomCodes);
-
-                // 第三步 查询物料_收发记录
-                $receiveCodes = Db::name('物料_收发记录')
-                    ->whereIn('st_wlbh', $bomCodes)
-                    ->group('st_wlbh')
-                    ->column('st_wlbh');
-
-                //对比第二步、第三步物料是否完全一致
-                $diffCodes = array_diff($bomCodes, $receiveCodes);
-                if (!empty($diffCodes)) {
-                    throw new Exception('物料_收发记录缺失物料:' . implode('、', $diffCodes));
-                }
+        // 测试库:database.db8(MySQL);正式库可改为 database.db3(SQL Server)
+        $targetDb = Db::connect(config('database.db8'));
+        $targetTable = 'U8_成品入仓';
 
 
-                //全部校验通过
-                $status = '同步成功';
-                $msg    = '工单_印件资料、工单_bom资料、物料_收发记录,校验全部一致';
+        $syncTime = date('Y-m-d H:i:s');
+        $isEndBoard = (strpos((string)$record['jjcp_smb'], '末') !== false) ? '末板' : '';
+        $id = 0;
+        $errorMsg = '';
 
 
-            } catch (Exception $e) {
-                // 捕获所有异常,记录失败原因
-                $msg = $e->getMessage();
-            }
+        try {
+            $maxId = (int)$targetDb->name($targetTable)->max('id');
+            $id = $maxId + 1;
 
 
-            //插入日志,成功、失败日志
-            $logInsert = [
-                'Gdbh'       => $gdbh,
-                'wlbm'       => $wlbmStr,
-                'yjmc'       => $yjmc,
-                'Yjdh'       => $yjdh,
-                'Yjno'       => $yjno,
-                'sys_id'     => $sysId,
-                'sys_rq'     => $syncRq,
-                'type'       => $type,
-                'status'     => $status,
-                'status_msg' => $msg
+            $data = [
+                'id'          => $id,                                  // 主键ID(目标表不自增,按条数递增)
+                'MESCode'     => '000000',                             // 默认编码
+                'dDate'       => $record['jjcp_sj'],                   // 入仓日期
+                'cWhCode'     => $record['仓库编号'],                   // 仓库编码
+                'cMoCode'     => $record['jjcp_gdbh'],                 // 工单编号
+                'cMemo'       => $record['jjcp_desc'],                 // 备注
+                'cInvCode'    => $record['jjcp_cpdh'],                 // 物料编码
+                'cInvName'    => $record['jjcp_cpmc'],                 // 物料名称
+                'iQty'        => $record['jjcp_sl'],                   // 数量
+                'cBatch'      => $record['订单编号'],                   // 批次号
+                'username'    => $record['Sys_id'],                    // 用户名
+                '是否末版'    => $isEndBoard,                          // 是否末版
+                'MES插入类型' => $insertType,                          // 插入类型
+                'MES传递时间' => $syncTime,                            // 传递时间
+                'U8接收时间'  => null,                                 // 接收时间为空
+                'U8接收状态'  => '0',                                  // 状态默认 0
+                '印件编码'    => $record['jjcp_cpdh'],                 // 印件编码
+                '印件名称'    => $record['jjcp_cpmc'],                 // 印件名称
+                '成品编码'    => $record['成品编码'],                   // 成品编码
+                '成品名称'    => $record['成品名称'],                   // 成品名称
+                'UniqId'      => $record['UniqId'],                    // 唯一ID
             ];
             ];
 
 
-            echo "<pre>";print_r($logInsert);echo "<pre>";
-//            Db::name('工单_成品入仓同步操作日志')->insert($logInsert);
+            // 中文字段名不能走 ThinkPHP 命名绑定(PDO 会截断 :data__MES插入类型),改用位置绑定
+            $this->insertFinishStockMiddle($targetDb, $targetTable, $data);
 
 
-            $resultList[] = [
-                '工单编号' => $gdbh,
-                '印件号'   => $yjno,
-                '状态'     => $status,
-                '说明'     => $msg
-            ];
+            $this->writeFinishStockSyncLog($record, $uniqId, $insertType, $syncTime, true, '同步成功');
+        } catch (\Exception $e) {
+            $errorMsg = $e->getMessage();
+            $this->writeFinishStockSyncLog($record, $uniqId, $insertType, $syncTime, false, $errorMsg);
+            throw new \Exception('同步中间表失败:' . $errorMsg);
+        }
+
+        return true;
+    }
+
+    /**
+     * 写入成品入仓同步操作日志
+     * 表字段:Gdbh/wlbm/yjmc/Yjdh/Yjno/sys_id/sys_rq/type/status/status_msg/UniqId
+     * @param array $record 成品入仓记录
+     * @param int|string $uniqId
+     * @param string $insertType 新增/修改/删除
+     * @param string $syncTime
+     * @param bool $success
+     * @param string $statusMsg
+     */
+    protected function writeFinishStockSyncLog($record, $uniqId, $insertType, $syncTime, $success, $statusMsg = '')
+    {
+        // 操作人取成品入仓 Sys_id(通常为字符串,如 [272/超级用户])
+        $sysId = $record['Sys_id'] ?? ($record['sys_id'] ?? '');
+
+        $log = [
+            'Gdbh'       => $record['jjcp_gdbh'] ?? '',
+            'wlbm'       => $record['jjcp_cpdh'] ?? '',
+            'yjmc'       => $record['jjcp_cpmc'] ?? '',
+            'Yjdh'       => $record['jjcp_cpdh'] ?? '',                 // 印件代号
+            'Yjno'       => (int)($record['jjcp_yjno'] ?? 0),
+            'sys_id'     => (string)$sysId,                              // 操作人
+            'sys_rq'     => $syncTime,
+            'type'       => $insertType,
+            'status'     => $success ? '同步成功' : '同步失败',
+            'status_msg' => $success ? '' : (string)$statusMsg,
+            'UniqId'     => (int)$uniqId,
+        ];
+
+        try {
+            $maxId = (int)db('工单_成品入仓同步操作日志')->max('id');
+            $log['id'] = $maxId + 1;
+            $sql = db('工单_成品入仓同步操作日志')->fetchSql(true)->insert($log);
+            $result = db()->query($sql);
+            if ($result === false) {
+                throw new \Exception('日志 insert 返回 false');
+            }
+        } catch (\Exception $e) {
+            // 不阻断主流程
+        }
+    }
+
+    /**
+     * 中间表插入(兼容 MySQL / SQL Server 中文字段,使用位置绑定)
+     * @param \think\db\Connection $targetDb
+     * @param string $table
+     * @param array $data
+     */
+    protected function insertFinishStockMiddle($targetDb, $table, array $data)
+    {
+        $dbType = strtolower((string)$targetDb->getConfig('type'));
+        $isSqlsrv = (strpos($dbType, 'sqlsrv') !== false || strpos($dbType, 'sqlserver') !== false);
+
+        $quote = function ($name) use ($isSqlsrv) {
+            if ($isSqlsrv) {
+                return '[' . str_replace(']', ']]', $name) . ']';
+            }
+            return '`' . str_replace('`', '``', $name) . '`';
+        };
+
+        $fields = [];
+        $placeholders = [];
+        $values = [];
+        foreach ($data as $field => $value) {
+            $fields[] = $quote($field);
+            $placeholders[] = '?';
+            $values[] = $value;
         }
         }
 
 
-        return json([
-            'code' => 1,
-            'msg'  => '同步处理完成',
-            'data' => $resultList
-        ]);
+        $sql = sprintf(
+            'INSERT INTO %s (%s) VALUES (%s)',
+            $quote($table),
+            implode(', ', $fields),
+            implode(', ', $placeholders)
+        );
+
+        $result = $targetDb->execute($sql, $values);
+        if ($result === false) {
+            throw new \Exception('中间表 insert 返回 false');
+        }
     }
     }
 }
 }