Browse Source

Merge branch 'master' of https://git.7in6.com/liuhairui/mes-dc-server-api

zck 1 month ago
parent
commit
dc136b96bd

+ 43 - 43
application/api/controller/ReportingWork.php

@@ -90,33 +90,16 @@ class ReportingWork extends Api
         if (empty($params['majorprocess'])) {
             $this->error('大工序不能为空');
         }
-        $data = [];
-        if($params['majorprocess'] == '车缝'){
-           //获取部件资料
-           $data = db('工单_部件资料')
-                ->where('work_order', $params['workorder'])
-                ->where('del_rq', null)
-                ->where('status', 1)
-                ->field('part_code as 部件编号,part_name as 部件名称')
-                ->order('part_code')
-                ->select();
-            if (empty($data)) {
-                $this->error('未找到部件资料');
-            }
-        }else{
-            $data = db('工单_基础工艺资料')
-                ->where('work_order', $params['workorder'])
-                ->where('big_process', $params['majorprocess'])
-                ->where('del_rq', null)
-                ->where('status', 0)
-                ->field('process_code as 工艺编号,process_name as 工艺名称,standard_hour as 标准工时,
-                standard_score as 标准工分,coefficient as 系数,remark as 备注')
-                ->order('process_code')
-                ->select();
-            if (empty($data)) {
-                $this->error('未找到工艺数据');
-            }
-        }
+        $data = db('工单_部件资料')
+            ->where('work_order', $params['workorder'])
+            ->where('part_type', $params['majorprocess'])
+            ->whereNull('del_rq')
+            ->where('status', 1)
+            ->field('part_code as 部件编号,part_name as 部件名称')
+            ->select();
+        usort($data, function ($a, $b) {
+            return strnatcmp((string)$a['部件编号'], (string)$b['部件编号']);
+        });
         $this->success('成功', $data);
     }
 
@@ -146,13 +129,14 @@ class ReportingWork extends Api
         $data = db('工单_基础工艺资料')
             ->where('work_order', $params['workorder'])
             ->where('part_code', $params['part_code'])
-            ->where('big_process', '车缝')
-            ->where('del_rq', null)
+            ->whereNull('del_rq')
             ->where('status', 0)
-            ->field('process_code as 工艺编号,process_name as 工艺名称,standard_hour as 标准工时,
-            standard_score as 标准工分,coefficient as 系数,remark as 备注')
-            ->order('process_code')
+            ->field('process_code as 工艺编号,process_name as 工艺名称,standard_hour as 标准工时,standard_minutes as 标准分钟,
+            standard_score as 标准工分,coefficient as 系数,remark as 备注,money as 金额')
             ->select();
+        usort($data, function ($a, $b) {
+            return strnatcmp((string)$a['工艺编号'], (string)$b['工艺编号']);
+        });
         $this->success('成功', $data);
     }
 
@@ -226,6 +210,12 @@ class ReportingWork extends Api
             // if (!isset($item['standard_hour']) || $item['standard_hour'] === '') {
             //     $this->error('第' . $rowNo . '条标准工时不能为空');
             // }
+            // if (!isset($item['money']) || $item['money'] === '') {
+            //     $this->error('第' . $rowNo . '条金额不能为空');
+            // }
+            // if (empty($item['standard_minutes'])) {
+            //     $this->error('第' . $rowNo . '条标准分钟不能为空');
+            // }
             if (!isset($item['standard_score']) || $item['standard_score'] === '') {
                 $this->error('第' . $rowNo . '条标准工分不能为空');
             }
@@ -235,12 +225,13 @@ class ReportingWork extends Api
 
             $standardHour = floatval($item['standard_hour']);
             $standardScore = floatval($item['standard_score']);
-            $coefficient = isset($item['coefficient']) && $item['coefficient'] !== '' ? floatval($item['coefficient']) : 1;
+            $money = floatval($item['money']);
+            $coefficient = isset($item['coefficient']) && $item['coefficient'] !== '' ? floatval($item['coefficient']) : 'C';
             $number = floatval($item['number']);
-
-            $productionHour = $standardHour * $number * $coefficient;
-            $productionScore = $standardScore * $number * $coefficient;
-
+            $standardMinutes = floatval($item['standard_minutes']);
+            $productionHour = $standardHour * $number;
+            $productionScore = $standardScore * $number;
+            $productionMoney = $money * $number;
             $partCode = null;
             if (isset($item['part_code']) && $item['part_code'] !== '') {
                 $partCode = intval($item['part_code']);
@@ -257,11 +248,13 @@ class ReportingWork extends Api
                 'process_name' => $item['process_name'],
                 'standard_hour' => $standardHour,
                 'standard_score' => $standardScore,
+                'standard_minutes' => $standardMinutes,
+                'money' => $money,
                 'coefficient' => $coefficient,
                 'number' => $number,
                 'production_hour' => round($productionHour, 4),
                 'production_score' => round($productionScore, 4),
-                'salary' => round($productionScore*0.5,2),
+                'salary' => round($productionMoney, 4),
                 'machine' => isset($item['machine']) ? $item['machine'] : '',
                 'sys_id' => isset($item['sys_id']) ? $item['sys_id'] : '',
                 'sys_rq' => $now,
@@ -359,9 +352,11 @@ class ReportingWork extends Api
 
         $rows = db('设备_工分计酬')
             ->where('del_rq', null)
-            ->where('date', $params['date'])
+            ->where('date', 'like', $params['date'] . '%')
             ->where('machine', $params['machine'])
-            ->field('id,work_order,majorprocess,part_code,process_code,process_name,staff_no,staff_name,standard_hour,standard_score,coefficient,number,production_hour,production_score,machine,sys_id,sys_rq')
+            ->field('id,work_order,majorprocess,part_code,process_code,process_name,staff_no,staff_name,standard_hour,
+            standard_score,money,coefficient,number,production_hour,production_score,
+            salary,machine,sys_id,sys_rq')
             ->order('process_code asc,staff_no asc')
             ->select();
 
@@ -386,10 +381,12 @@ class ReportingWork extends Api
                 'staff_name' => $row['staff_name'],
                 'standard_hour' => $row['standard_hour'],
                 'standard_score' => $row['standard_score'],
+                'money' => $row['money'],
                 'coefficient' => $row['coefficient'],
                 'number' => $row['number'],
                 'production_hour' => $row['production_hour'],
                 'production_score' => $row['production_score'],
+                'salary' => $row['salary'],
                 'sys_id' => $row['sys_id'],
                 'sys_rq' => $row['sys_rq'],
                 'id' => $row['id'],
@@ -427,7 +424,8 @@ class ReportingWork extends Api
             'number' => $params['number'],
             'production_hour' => $params['production_hour'],
             'production_score' => $params['production_score'],
-            'salary' => $params['production_score'] * 0.5,
+            'money' => $params['money'],
+            'salary' => $params['money'] * $params['number'],
         ];
         $result = db('设备_工分计酬')
             ->where('id', $params['id'])
@@ -495,8 +493,10 @@ class ReportingWork extends Api
             ->where('del_rq', null)
             ->where('date', 'like', $params['date'] . '%')
             ->where('machine', $params['machine'])
-            ->field('work_order,majorprocess,part_code,process_code,process_name,staff_no,staff_name,standard_hour,standard_score,coefficient,number,production_hour,production_score,machine,sys_id,sys_rq')
-            ->order('process_code asc,staff_no asc')
+            ->field('work_order,majorprocess,part_code,process_code,process_name,staff_no,staff_name,
+            standard_hour,standard_score,money,coefficient,number,production_hour,
+            production_score,salary,machine,sys_id,sys_rq,id')
+            ->order('process_code asc,staff_no asc,sys_rq desc')
             ->select();
         $this->success('成功', $rows);
     }

+ 4 - 3
application/api/controller/StaffSalary.php

@@ -36,6 +36,7 @@ class StaffSalary extends Api
         //获取员工部门
         $big_process = db('人员_基本资料')
             ->field('DISTINCT big_process')
+            ->where('big_process','<>','')
             ->select();
         foreach ($big_process as $v) {
             $big_process_name[] = $v['big_process'];
@@ -80,7 +81,7 @@ class StaffSalary extends Api
             ->group('a.staff_no,a.staff_name')
             ->select();
         if(empty($staff)){
-            $this->error('该部门没有员工');
+            $this->error('该工序没有报工数据');
         }
 
         $staffMap = [];
@@ -94,7 +95,7 @@ class StaffSalary extends Api
             ->where('del_rq', null)
             ->where('date', 'like', $param['month'] . '%')
             ->where('staff_no', 'in', $staffNos)
-            ->field('staff_no,staff_name,DATE_FORMAT(date, "%Y-%m-%d") as date,sum(salary) as salary')
+            ->field('staff_no,staff_name,DATE_FORMAT(date, "%Y-%m-%d") as date,sum(salary) as salary,sys_id')
             ->group('staff_no,DATE_FORMAT(date, "%Y-%m-%d")')
             ->order('staff_no asc,date asc')
             ->select();
@@ -151,7 +152,7 @@ class StaffSalary extends Api
             ->field('a.work_order as 订单编号,DATE_FORMAT(a.date, "%Y-%m-%d") as 日期,b.part_name as 部件名称,
             a.part_code as 部件编号,a.salary as 工资,a.number as 数量,a.production_hour as 生产工时,a.production_score as 生产分数,
             a.machine as 设备名称,a.process_name as 工序名称,a.standard_hour as 标准工时,a.standard_score as 标准分数,
-            a.coefficient as 系数')
+            a.coefficient as 系数,a.sys_id as 设备编号')
             ->where($where)
             ->order('a.date asc,a.process_code asc')
             ->select();

+ 92 - 0
application/api/controller/WorkOrder.php

@@ -5774,4 +5774,96 @@ class WorkOrder extends Api
         $this->success('成功', $list);
     }
 
+
+
+    /**
+     * 修改订单备注和完工日期
+     * @param id 工单ID
+     * @param remark 备注
+     * @param finish_date 工单完工日期
+     * @param sys_id 操作人
+     */
+    public function updateOrderRemarkAndFinishDate()
+    {
+        if (!$this->request->isPost()) {
+            $this->error('请求方式错误');
+        }
+        $params = $this->request->post();
+        if (empty($params['id'])) {
+            $this->error('工单ID不能为空');
+        }
+        if (empty($params['sys_id'])) {
+            $this->error('操作人不能为空');
+        }
+
+        $workOrder = Db::table('工单_基本资料')
+            ->where('Uniqid', intval($params['id']))
+            ->whereNull('Mod_rq')
+            ->field('Uniqid,订单编号,remark,工单完工日期')
+            ->find();
+        if (empty($workOrder)) {
+            $this->error('工单不存在');
+        }
+
+        $remark = isset($params['remark']) ? $params['remark'] : '';
+        $finishDate = isset($params['工单完工日期']) ? $params['工单完工日期'] : '';
+        $updateData = [];
+        $logList = [];
+        $operTime = date('Y-m-d H:i:s');
+        $orderNo = $workOrder['订单编号'];
+
+        $fieldMap = [
+            'remark' => ['label' => '备注', 'new' => $remark],
+            '工单完工日期' => ['label' => '工单完工日期', 'new' => $finishDate],
+        ];
+        foreach ($fieldMap as $field => $item) {
+            $oldValue = isset($workOrder[$field]) ? $workOrder[$field] : '';
+            $newValue = $item['new'];
+            if ((string)$oldValue === (string)$newValue) {
+                continue;
+            }
+            $updateData[$field] = $newValue;
+            $logList[] = [
+                'order_no' => $orderNo,
+                'change_field' => $item['label'],
+                'old_value' => $oldValue === null ? '' : (string)$oldValue,
+                'new_value' => (string)$newValue,
+                'oper_type' => '修改工单备注和完工日期',
+                'oper_user_name' => $params['sys_id'],
+                'oper_time' => $operTime,
+            ];
+        }
+
+        if (empty($updateData)) {
+            $this->error('数据未发生变化');
+        }
+
+        Db::startTrans();
+        try {
+            $updateSql = Db::table('工单_基本资料')
+                ->where('Uniqid', intval($params['id']))
+                ->whereNull('Mod_rq')
+                ->fetchSql(true)
+                ->update($updateData);
+            $updateResult = db()->query($updateSql);
+            if ($updateResult === false) {
+                throw new \Exception('更新工单失败');
+            }
+            if ($updateResult === 0) {
+                throw new \Exception('未找到可更新的工单');
+            }
+            $logResult = Db::name('work_order_operation_log')->insertAll($logList);
+            if ($logResult === false || $logResult === 0) {
+                throw new \Exception('写入操作日志失败');
+            }
+            Db::commit();
+        } catch (\think\exception\HttpResponseException $e) {
+            throw $e;
+        } catch (\Exception $e) {
+            Db::rollback();
+            $this->error('修改失败:' . $e->getMessage());
+        }
+        $this->success('修改成功');
+    }
+
 }

+ 624 - 50
application/api/controller/WorkOrderProcess.php

@@ -361,15 +361,15 @@ class WorkOrderProcess extends Api
         if (empty($params['big_process'])) {
             $this->error('大工艺不能为空');
         }
-        if (empty($params['standard_hour'])) {
-            $this->error('标准工时不能为空');
-        }
-        if (empty($params['standard_score'])) {
-            $this->error('标准公分不能为空');
-        }
-        if (empty($params['coefficient'])) {
-            $params['coefficient'] = 1;
-        }
+        // if (empty($params['standard_hour'])) {
+        //     $this->error('标准工时不能为空');
+        // }
+        // if (empty($params['standard_score'])) {
+        //     $this->error('标准公分不能为空');
+        // // }
+        // if (empty($params['coefficient'])) {
+        //     $params['coefficient'] = 'C';
+        // }
         if (empty($params['sys_id'])) {
             $this->error('系统人不能为空');
         }
@@ -835,54 +835,51 @@ class WorkOrderProcess extends Api
             $seenSeq[$seqKey] = true;
         }
         $now = date('Y-m-d H:i:s');
-        $partNameToCode = [];
+        $partMap = [];
         $nextPartCode = 0;
         foreach ($data as $row) {
-            $partName = isset($row['部件名称']) ? $row['部件名称'] : '';
-            if ($partName === '' || isset($partNameToCode[$partName])) {
+            $partName = isset($row['部件名称']) ? trim((string)$row['部件名称']) : '';
+            if ($partName === '') {
                 continue;
             }
-            $partNameToCode[$partName] = ++$nextPartCode;
+            $partType = isset($row['生产工序']) ? trim((string)$row['生产工序']) : '';
+            if (!isset($partMap[$partName])) {
+                $partMap[$partName] = [
+                    'part_code' => ++$nextPartCode,
+                    'part_type' => $partType,
+                ];
+            } elseif ($partType !== '' && $partMap[$partName]['part_type'] === '') {
+                $partMap[$partName]['part_type'] = $partType;
+            }
         }
+
         $workOrderParts = [];
-        $i = 0;
-        foreach ($partNameToCode as $partName => $partCode) {
-            $workOrderParts[$i++] = [
+        foreach ($partMap as $partName => $partInfo) {
+            $workOrderParts[] = [
                 'work_order' => $params['workorder'],
                 'part_name' => $partName,
-                'part_code' => $partCode,
-                'part_type' => '',
+                'part_code' => $partInfo['part_code'],
+                'part_type' => $partInfo['part_type'],
                 'remark' => '',
                 'status' => 1,
                 'sys_id' => $params['sys_id'],
                 'sys_rq' => $now,
             ];
         }
-        Db::startTrans();
-        try {
-            //删除数据库现有的工单部件数据
-            Db::name('工单_部件资料')->where('work_order', $params['workorder'])->delete();
-            //插入工单部件数据
-            $partInsertCount = Db::name('工单_部件资料')->insertAll($workOrderParts);
-            if ($partInsertCount === false) {
-                throw new \Exception('工单部件导入失败');
-            }
-            //提交事务
-            Db::commit();
-        } catch (\Exception $e) {
-            Db::rollback();
-            $this->error($e->getMessage());
-        }
 
         $workOrderProcesses = [];
         foreach ($data as $value) {
-            $name = isset($value['部件名称']) ? $value['部件名称'] : '';
-            $partCode = ($name !== '' && isset($partNameToCode[$name])) ? $partNameToCode[$name] : '';
+            $seq = isset($value['序号']) ? $value['序号'] : null;
+            if ($seq === null || $seq === '') {
+                continue;
+            }
+            $name = isset($value['部件名称']) ? trim((string)$value['部件名称']) : '';
+            $partCode = ($name !== '' && isset($partMap[$name])) ? $partMap[$name]['part_code'] : '';
             $workOrderProcesses[] = [
                 'work_order' => $params['workorder'],
                 'part_code' => $partCode,
                 'part_name' => $name,
-                'process_code' => $value['序号'],
+                'process_code' => $seq,
                 'process_name' => $value['工序名称'],
                 'big_process' => $value['生产工序'],
                 'standard_hour' => $value['秒'],
@@ -895,22 +892,35 @@ class WorkOrderProcess extends Api
                 'sys_rq' => $now,
             ];
         }
+
         Db::startTrans();
         try {
-            //删除数据库现有的工单工艺数据
+            Db::name('工单_部件资料')->where('work_order', $params['workorder'])->delete();
+            if (!empty($workOrderParts)) {
+                $partInsertCount = Db::name('工单_部件资料')->insertAll($workOrderParts);
+                if ($partInsertCount === false || $partInsertCount === 0) {
+                    throw new \Exception('工单部件导入失败');
+                }
+            }
             Db::name('工单_基础工艺资料')->where('work_order', $params['workorder'])->delete();
-            //插入工单工艺数据
+            if (empty($workOrderProcesses)) {
+                throw new \Exception('没有可导入的工序数据');
+            }
             $processInsertCount = Db::name('工单_基础工艺资料')->insertAll($workOrderProcesses);
-            if ($processInsertCount === false) {
+            if ($processInsertCount === false || $processInsertCount === 0) {
                 throw new \Exception('工单工艺导入失败');
             }
-            //提交事务
             Db::commit();
+        } catch (\think\exception\HttpResponseException $e) {
+            throw $e;
         } catch (\Exception $e) {
             Db::rollback();
-            $this->error($e->getMessage());
+            $this->error('导入失败:' . $e->getMessage());
         }
-        $this->success('导入成功');
+        $this->success('导入成功', [
+            'part_count' => count($workOrderParts),
+            'process_count' => count($workOrderProcesses),
+        ]);
     }
 
     /**
@@ -995,11 +1005,31 @@ class WorkOrderProcess extends Api
             ->where($where)
             ->field('id,part_code as 部件编号,part_name as 部件名称,process_code as 工序编号,process_name as 工序名称,
             big_process as 大工序,standard_hour as 秒,standard_minutes as 分,standard_score as 定额分,money as 金额,
-            coefficient as 难度系数,remark as 备注,status as 状态')
+            coefficient as 难度系数,remark as 备注,status as 状态,pid')
             ->select();
         if (empty($workOrderProcess)) {
             $this->error('工单工艺不存在');
         }
+
+        $pidList = [];
+        foreach ($workOrderProcess as $row) {
+            if (!empty($row['pid'])) {
+                $pidList[(int)$row['pid']] = true;
+            }
+        }
+        $parentCodeMap = [];
+        if (!empty($pidList)) {
+            $parentCodeMap = Db::table('工单_基础工艺资料')
+                ->whereIn('id', array_keys($pidList))
+                ->column('process_code', 'id');
+        }
+        foreach ($workOrderProcess as &$row) {
+            $row['母工序编号'] = !empty($row['pid']) && isset($parentCodeMap[(int)$row['pid']])
+                ? $parentCodeMap[(int)$row['pid']]
+                : '';
+        }
+        unset($row);
+
         $this->success('成功', $workOrderProcess);
     }
 
@@ -1118,9 +1148,10 @@ class WorkOrderProcess extends Api
     }
 
     /**
-     * 确认拆分工序:母工序置为已拆分,按数量生成子工序
+     * 确认拆分工序:number>0 时母工序置为已拆分并生成子工序(子工序 pid 为母工序 id);
+     * number=0 时恢复母工序 status=0 并软删除其子工序
      * @param id 工艺ID
-     * @param number 拆分数量
+     * @param number 拆分数量(0 表示取消拆分)
      * @param sys_id 操作人员
      * @param sys_rq 操作时间(可选,默认当前时间)
      */
@@ -1133,7 +1164,7 @@ class WorkOrderProcess extends Api
         if (empty($params['id'])) {
             $this->error('工艺ID不能为空');
         }
-        if (empty($params['number']) ) {
+        if (!isset($params['number']) || $params['number'] === '' || $params['number'] === null) {
             $this->error('拆分工序数量不能为空');
         }
         if (empty($params['sys_id'])) {
@@ -1142,16 +1173,92 @@ class WorkOrderProcess extends Api
 
         $splitCount = intval($params['number']);
         $operTime = !empty($params['sys_rq']) ? $params['sys_rq'] : date('Y-m-d H:i:s');
+        $processId = intval($params['id']);
 
         $process = Db::table('工单_基础工艺资料')
-            ->where('id', intval($params['id']))
-            ->where('status', 'in', [0, '0'])
+            ->where('id', $processId)
+            ->whereNull('del_rq')
             ->find();
         if (empty($process)) {
-            $this->error('工序不存在或已确认拆分');
+            $this->error('工序不存在');
         }
 
         $workorder = $process['work_order'];
+
+        if ($splitCount === 0) {
+            $children = Db::table('工单_基础工艺资料')
+                ->where('pid', $processId)
+                ->whereNull('del_rq')
+                ->field('id,process_code')
+                ->select();
+
+            $logList = [
+                [
+                    'order_no' => $workorder,
+                    'process_code' => $process['process_code'],
+                    'change_field' => '状态',
+                    'old_value' => '1',
+                    'new_value' => '0',
+                    'oper_type' => '取消拆分工序',
+                    'oper_user_name' => $params['sys_id'],
+                    'oper_time' => $operTime,
+                ],
+            ];
+            foreach ($children as $child) {
+                $logList[] = [
+                    'order_no' => $workorder,
+                    'process_code' => $child['process_code'],
+                    'change_field' => '工序拆分',
+                    'old_value' => (string)$process['process_code'],
+                    'new_value' => '删除子工序',
+                    'oper_type' => '取消拆分工序',
+                    'oper_user_name' => $params['sys_id'],
+                    'oper_time' => $operTime,
+                ];
+            }
+
+            Db::startTrans();
+            try {
+                if (!empty($children)) {
+                    $deleteResult = Db::table('工单_基础工艺资料')
+                        ->where('pid', $processId)
+                        ->whereNull('del_rq')
+                        ->update(['del_rq' => $operTime]);
+                    if ($deleteResult === false) {
+                        throw new \Exception('删除子工序失败');
+                    }
+                }
+                $updateResult = Db::table('工单_基础工艺资料')
+                    ->where('id', $processId)
+                    ->whereNull('del_rq')
+                    ->update(['status' => 0]);
+                if ($updateResult === false) {
+                    throw new \Exception('恢复母工序状态失败');
+                }
+                if (!empty($logList)) {
+                    $logResult = Db::name('work_order_operation_log')->insertAll($logList);
+                    if ($logResult === false || $logResult === 0) {
+                        throw new \Exception('写入操作日志失败');
+                    }
+                }
+                Db::commit();
+            } catch (\think\exception\HttpResponseException $e) {
+                throw $e;
+            } catch (\Exception $e) {
+                Db::rollback();
+                $this->error('取消拆分失败:' . $e->getMessage());
+            }
+            $this->success('取消拆分工序成功', ['count' => count($children)]);
+            return;
+        }
+
+        if ($splitCount < 1) {
+            $this->error('拆分工序数量必须大于0');
+        }
+
+        if (!in_array($process['status'], [0, '0'], true)) {
+            $this->error('工序不存在或已确认拆分');
+        }
         $processCodes = Db::table('工单_基础工艺资料')
             ->where('work_order', $workorder)
             ->whereNull('del_rq')
@@ -1200,6 +1307,7 @@ class WorkOrderProcess extends Api
                     ? $process['coefficient'] : 'C',
                 'remark' => isset($process['remark']) && $process['remark'] !== null ? $process['remark'] : '',
                 'status' => 0,
+                'pid' => $processId,
                 'sys_id' => $params['sys_id'],
                 'sys_rq' => $operTime,
             ];
@@ -1288,5 +1396,471 @@ class WorkOrderProcess extends Api
         return $values;
     }
 
-   
+   /**
+    * 根据款号查询工单信息
+    * @param search 搜索内容
+    * @return array
+    * @throws \think\db\exception\DataNotFoundException
+    * @throws \think\db\exception\ModelNotFoundException
+    * @throws \think\exception\DbException
+    */
+   public function getWorkOrderInfoByStyle()
+   {
+        if (!$this->request->isGet()) {
+            $this->error('请求方法错误');
+        }
+        $params = $this->request->param();
+        if (empty($params['search'])) {
+            $this->error('搜索内容不能为空');
+        }
+        $where = [
+            'a.订单编号|a.生产款号|a.款式' => ['like', '%' . $params['search'] . '%'],
+            'a.Mod_rq' => null,
+        ];
+        $workOrder = db('工单_基本资料')->alias('a')
+            ->join('工单_基础工艺资料 b', 'a.订单编号 = b.work_order')
+            ->field('a.订单编号,a.生产款号,a.款式,a.客户编号')
+            ->where($where)
+            ->group('a.订单编号')
+            ->select();
+        if (empty($workOrder)) {
+            $this->error('未找到工单信息');
+        }
+        $this->success('成功', $workOrder);
+    }
+
+
+
+    /**
+     * 复制目标工单的部件与工艺到当前工单
+     * @param target_workorder 目标工单编号
+     * @param current_workorder 当前工单编号
+     * @param sys_id 操作人
+     */
+    public function copyProcessToCurrentWorkOrder()
+    {
+        if (!$this->request->isPost()) {
+            $this->error('请求方法错误');
+        }
+        $params = $this->request->post();
+        if (empty($params['target_workorder'])) {
+            $this->error('目标工单编号不能为空');
+        }
+        if (empty($params['current_workorder'])) {
+            $this->error('当前工单编号不能为空');
+        }
+        if (empty($params['sys_id'])) {
+            $this->error('操作人不能为空');
+        }
+        if ($params['target_workorder'] === $params['current_workorder']) {
+            $this->error('目标工单与当前工单不能相同');
+        }
+
+        if (!$this->workOrderExists($params['target_workorder'])) {
+            $this->error('目标工单不存在');
+        }
+        if (!$this->workOrderExists($params['current_workorder'])) {
+            $this->error('当前工单不存在');
+        }
+
+        $targetWorkOrderInfo = $this->getWorkOrderInfo($params['target_workorder']);
+        if (empty($targetWorkOrderInfo['partInfo']) && empty($targetWorkOrderInfo['processInfo'])) {
+            $this->error('目标工单没有可复制的部件或工艺');
+        }
+
+        $currentWorkOrderInfo = $this->getWorkOrderInfo($params['current_workorder']);
+        $oldPartCount = count($currentWorkOrderInfo['partInfo']);
+        $oldProcessCount = count($currentWorkOrderInfo['processInfo']);
+
+        $now = date('Y-m-d H:i:s');
+        $partInsertList = $this->buildWorkOrderPartCopyRows(
+            $targetWorkOrderInfo['partInfo'],
+            $params['current_workorder'],
+            $params['sys_id'],
+            $now
+        );
+        $processInsertList = $this->buildWorkOrderProcessCopyRows(
+            $targetWorkOrderInfo['processInfo'],
+            $params['current_workorder'],
+            $params['sys_id'],
+            $now
+        );
+
+        $logData = [
+            'order_no' => $params['current_workorder'],
+            'change_field' => $params['target_workorder'],
+            'old_value' => sprintf('部件%d条,工艺%d条', $oldPartCount, $oldProcessCount),
+            'new_value' => sprintf('部件%d条,工艺%d条', count($partInsertList), count($processInsertList)),
+            'oper_type' => '复制工单工艺',
+            'oper_user_name' => $params['sys_id'],
+            'oper_time' => $now,
+        ];
+
+        Db::startTrans();
+        try {
+            if ($oldPartCount > 0 || $oldProcessCount > 0) {
+                $partDeleteResult = Db::table('工单_部件资料')
+                    ->where('work_order', $params['current_workorder'])
+                    ->whereNull('del_rq')
+                    ->update(['del_rq' => $now]);
+                if ($partDeleteResult === false) {
+                    throw new \Exception('清除当前工单部件失败');
+                }
+                $processDeleteResult = Db::table('工单_基础工艺资料')
+                    ->where('work_order', $params['current_workorder'])
+                    ->whereNull('del_rq')
+                    ->update(['del_rq' => $now]);
+                if ($processDeleteResult === false) {
+                    throw new \Exception('清除当前工单工艺失败');
+                }
+            }
+
+            if (!empty($partInsertList)) {
+                $partInsertResult = Db::name('工单_部件资料')->insertAll($partInsertList);
+                if ($partInsertResult === false || $partInsertResult === 0) {
+                    throw new \Exception('复制部件失败');
+                }
+            }
+            if (!empty($processInsertList)) {
+                $processInsertResult = Db::name('工单_基础工艺资料')->insertAll($processInsertList);
+                if ($processInsertResult === false || $processInsertResult === 0) {
+                    throw new \Exception('复制工艺失败');
+                }
+            }
+
+            $logResult = Db::name('work_order_operation_log')->insert($logData);
+            if ($logResult === false || $logResult === 0) {
+                throw new \Exception('写入操作日志失败');
+            }
+            Db::commit();
+        } catch (\think\exception\HttpResponseException $e) {
+            throw $e;
+        } catch (\Exception $e) {
+            Db::rollback();
+            $this->error('复制失败:' . $e->getMessage());
+        }
+
+        $this->success('复制成功', [
+            'part_count' => count($partInsertList),
+            'process_count' => count($processInsertList),
+        ]);
+    }
+
+    /**
+     * 判断工单是否存在
+     * @param string $workorder
+     * @return bool
+     */
+    private function workOrderExists($workorder)
+    {
+        return Db::table('工单_基本资料')
+                ->where('订单编号', $workorder)
+                ->whereNull('Mod_rq')
+                ->count() > 0;
+    }
+
+    /**
+     * 查询工单部件与工艺(未删除、工艺仅 status=0)
+     * @param string $workorder
+     * @return array
+     */
+    private function getWorkOrderInfo($workorder)
+    {
+        $partInfo = db('工单_部件资料')
+            ->where('work_order', $workorder)
+            ->whereNull('del_rq')
+            ->field('part_code,part_name,remark,part_type,status')
+            ->order('part_code')
+            ->select();
+
+        $processInfo = db('工单_基础工艺资料')
+            ->where('work_order', $workorder)
+            ->whereNull('del_rq')
+            ->where('status', 0)
+            ->field('part_code,part_name,process_code,process_name,standard_hour,standard_minutes,
+                standard_score,money,coefficient,remark,big_process')
+            ->order('process_code')
+            ->select();
+
+        return [
+            'partInfo' => $partInfo ?: [],
+            'processInfo' => $processInfo ?: [],
+        ];
+    }
+
+    /**
+     * 组装待复制的部件数据
+     */
+    private function buildWorkOrderPartCopyRows($partList, $workOrder, $sysId, $operTime)
+    {
+        $rows = [];
+        foreach ($partList as $part) {
+            $rows[] = [
+                'work_order' => $workOrder,
+                'part_code' => $part['part_code'],
+                'part_name' => $part['part_name'],
+                'remark' => isset($part['remark']) ? $part['remark'] : '',
+                'part_type' => isset($part['part_type']) ? $part['part_type'] : '',
+                'status' => 0,
+                'sys_id' => $sysId,
+                'sys_rq' => $operTime,
+            ];
+        }
+        return $rows;
+    }
+
+    /**
+     * 组装待复制的工艺数据
+     */
+    private function buildWorkOrderProcessCopyRows($processList, $workOrder, $sysId, $operTime)
+    {
+        $rows = [];
+        foreach ($processList as $process) {
+            $rows[] = [
+                'work_order' => $workOrder,
+                'part_code' => $process['part_code'],
+                'part_name' => isset($process['part_name']) ? $process['part_name'] : '',
+                'process_code' => $process['process_code'],
+                'process_name' => $process['process_name'],
+                'big_process' => $process['big_process'],
+                'standard_hour' => $process['standard_hour'],
+                'standard_minutes' => $process['standard_minutes'],
+                'standard_score' => $process['standard_score'],
+                'money' => $process['money'],
+                'coefficient' => $process['coefficient'],
+                'remark' => isset($process['remark']) ? $process['remark'] : '',
+                'status' => 0,
+                'pid' => 0,
+                'sys_id' => $sysId,
+                'sys_rq' => $operTime,
+            ];
+        }
+        return $rows;
+    }
+
+
+    /**
+     * 批量新增工序资料(请求体为 JSON 数组,每条含 work_order 等字段)
+     * @param processList 工序信息
+     * @return array
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     **/
+    public function batchAddProcess()
+    {
+        if (!$this->request->isPost()) {
+            $this->error('请求方法错误');
+        }
+
+        $processList = $this->parseBatchProcessList();
+        if (empty($processList)) {
+            $this->error('工艺数据不能为空');
+        }
+
+        $requiredFields = [
+            'work_order' => '工单编号',
+            'part_code' => '部件编号',
+            'part_name' => '部件名称',
+            'process_code' => '工序编号',
+            'process_name' => '工序名称',
+            'big_process' => '大工序',
+            'standard_hour' => '秒',
+            'standard_score' => '定额分',
+            'coefficient' => '难度系数',
+            'standard_minutes' => '分',
+            'money' => '金额',
+            'remark' => '备注',
+            'sys_id' => '操作人员',
+        ];
+
+        $workorder = '';
+        $now = date('Y-m-d H:i:s');
+        $insertList = [];
+        $processCodeMap = [];
+        $newBatchStatus0Sum = 0;
+
+        foreach ($processList as $index => $process) {
+            $rowNo = $index + 1;
+            if (!is_array($process)) {
+                $this->error('第' . $rowNo . '条工艺数据格式错误');
+            }
+            // foreach ($requiredFields as $field => $label) {
+            //     if (!isset($process[$field]) || $process[$field] === '' || $process[$field] === null) {
+            //         $this->error('第' . $rowNo . '条' . $label . '不能为空');
+            //     }
+            // }
+
+            $itemWorkOrder = trim($process['work_order']);
+            if ($workorder === '') {
+                $workorder = $itemWorkOrder;
+            } elseif ($itemWorkOrder !== $workorder) {
+                $this->error('第' . $rowNo . '条工单编号与其它数据不一致');
+            }
+
+            $processCode = (string)$process['process_code'];
+            if (isset($processCodeMap[$processCode])) {
+                $this->error('批量数据中存在重复的工序编号:' . $processCode);
+            }
+            $processCodeMap[$processCode] = true;
+
+            $status = isset($process['status']) ? $process['status'] : 0;
+            if (in_array($status, [0, '0'], true)) {
+                $newBatchStatus0Sum += floatval($process['standard_score']);
+            }
+
+            $insertList[] = [
+                'work_order' => $workorder,
+                'part_code' => $process['part_code'],
+                'part_name' => $process['part_name'],
+                'process_code' => $processCode,
+                'process_name' => $process['process_name'],
+                'big_process' => $process['big_process'],
+                'standard_hour' => $process['standard_hour'],
+                'standard_minutes' => $process['standard_minutes'],
+                'standard_score' => $process['standard_score'],
+                'coefficient' => $process['coefficient'],
+                'money' => $process['money'],
+                'remark' => $process['remark'],
+                'status' => $status,
+                'sys_id' => $process['sys_id'],
+                'sys_rq' => $now,
+            ];
+        }
+
+        $existingCodes = Db::table('工单_基础工艺资料')
+            ->where('work_order', $workorder)
+            ->whereIn('process_code', array_keys($processCodeMap))
+            ->whereNull('del_rq')
+            ->column('process_code');
+        if (!empty($existingCodes)) {
+            $this->error('工序编号已存在:' . $existingCodes[0]);
+        }
+
+        $workOrder = Db::table('工单_基本资料')
+            ->where('订单编号', $workorder)
+            ->where('Mod_rq', null)
+            ->field('订单编号,计划制造工分')
+            ->find();
+        if (empty($workOrder)) {
+            $this->error('工单不存在');
+        }
+
+        $existingTotal = Db::table('工单_基础工艺资料')
+            ->where('work_order', $workorder)
+            ->where('status', 0)
+            ->whereNull('del_rq')
+            ->sum('standard_score');
+        $existingTotal = $existingTotal ? floatval($existingTotal) : 0;
+        if ($existingTotal + $newBatchStatus0Sum > floatval($workOrder['计划制造工分'])) {
+            $this->error('工序定额分和大于制造工分,请确认之后再修改');
+        }
+
+        Db::startTrans();
+        try {
+            $insertResult = Db::name('工单_基础工艺资料')->insertAll($insertList);
+            if ($insertResult === false || $insertResult === 0) {
+                throw new \Exception('批量新增工序失败');
+            }
+            Db::commit();
+        } catch (\think\exception\HttpResponseException $e) {
+            throw $e;
+        } catch (\Exception $e) {
+            Db::rollback();
+            $this->error('批量新增工序资料失败');
+        }
+        $this->success('批量新增工序资料成功', ['count' => count($insertList)]);
+    }
+
+    /**
+     * 解析批量工序请求体(form 数组 / JSON 数组 / 单字段 JSON 字符串)
+     * @return array
+     */
+    private function parseBatchProcessList()
+    {
+        $params = $this->request->post();
+        if (isset($params[0]) && is_array($params[0])) {
+            return $params;
+        }
+
+        $decoded = json_decode($this->request->getInput(), true);
+        if (is_array($decoded) && isset($decoded[0]) && is_array($decoded[0])) {
+            return $decoded;
+        }
+
+        $jsonStr = is_string($params) ? $params : (count($params) === 1 ? reset($params) : null);
+        if (is_string($jsonStr)) {
+            $decoded = json_decode($jsonStr, true);
+            return is_array($decoded) ? $decoded : [];
+        }
+
+        return [];
+    }
+
+
+
+    /**
+     * 工序产量核查:按工单查询报工汇总(工单信息 / 工序列表 / 人员报工明细)
+     * @param workorder 工单编号
+     * @return array
+     */
+    public function checkProcessProduction()
+    {
+        if (!$this->request->isGet()) {
+            $this->error('请求方法错误');
+        }
+        $params = $this->request->param();
+        if (empty($params['workorder'])) {
+            $this->error('工单编号不能为空');
+        }
+
+        $list = Db::name('设备_工分计酬')->alias('a')
+            ->join('工单_基本资料 b', 'a.work_order = b.订单编号 AND b.Mod_rq IS NULL', 'LEFT')
+            ->where('a.work_order', $params['workorder'])
+            ->whereNull('a.del_rq')
+            ->field('b.订单编号,b.生产款号,b.款式,a.process_code as 工序号,a.process_name as 工序名称,a.staff_name as 员工姓名,
+                SUM(a.number) as 数量,MIN(a.date) as 开工日期,MAX(a.date) as 完工日期,
+                SUM(a.salary) as 金额,SUM(a.production_hour) as 工时,SUM(a.salary) as 工资')
+            ->group('b.订单编号,b.生产款号,b.款式,a.process_code,a.process_name,a.staff_no,a.staff_name')
+            ->order('a.process_code asc,a.staff_no asc')
+            ->select();
+
+        if (empty($list)) {
+            $this->error('未找到报工数据');
+        }
+
+        $data = [
+            '订单编号' => $list[0]['订单编号'],
+            '生产款号' => $list[0]['生产款号'],
+            '款式' => $list[0]['款式'],
+            '工序列表' => [],
+        ];
+
+        $processMap = [];
+        foreach ($list as $row) {
+            $processKey = (string)$row['工序号'] . '|' . (string)$row['工序名称'];
+            if (!isset($processMap[$processKey])) {
+                $processMap[$processKey] = [
+                    '工序号' => $row['工序号'],
+                    '工序名称' => $row['工序名称'],
+                    'staffs' => [],
+                ];
+            }
+
+            $startDate = !empty($row['开工日期']) ? date('Y-m-d', strtotime($row['开工日期'])) : '';
+            $endDate = !empty($row['完工日期']) ? date('Y-m-d', strtotime($row['完工日期'])) : '';
+            $processMap[$processKey]['staffs'][] = [
+                '员工姓名' => $row['员工姓名'],
+                '数量' => floatval($row['数量']),
+                '开工日期' => $startDate,
+                '完工日期' => $endDate,
+                '金额' => round(floatval($row['金额']), 4),
+                '工时' => round(floatval($row['工时']), 4),
+                '工资' => round(floatval($row['工资']), 4),
+            ];
+        }
+        $data['工序列表'] = array_values($processMap);
+
+        $this->success('成功', $data);
+    }
 }