m0_70156489 1 месяц назад
Родитель
Сommit
d9e1186bd3

+ 292 - 285
application/api/controller/MonthlyGarments.php

@@ -1,286 +1,293 @@
-<?php
-
-namespace app\api\controller;
-
-
-use app\common\controller\Api;
-use Monolog\Handler\IFTTTHandler;
-use Overtrue\Socialite\Providers\WeWorkProvider;
-use think\Db;
-use think\Request;
-use function fast\e;
-
-/**
- *
- * 生产单衣进度管理
- */
-class MonthlyGarments extends Api
-{
-    protected $noNeedLogin = ['*'];
-    protected $noNeedRight = ['*'];
-
-     /**
- * 样衣进度左侧数据
- */
-    public function getDateTree()
-    {
-        if (!$this->request->isGet()) {
-            $this->error('请求错误');
-        }
-
-        $results = \db('月度样衣进度')
-            ->field([
-                'DATE_FORMAT(Sys_rq, "%Y-%m")' => '年月',
-                '客户编号',
-                'COUNT(*) as total'
-            ])
-            ->whereNull('Mod_rq')
-            ->group('年月, 客户编号')
-            ->order('年月 DESC')
-            ->select();
-
-        $formattedData = [];
-
-        foreach ($results as $row) {
-            $yearMonth = $row['年月'];
-            $customerCode = $row['客户编号'];
-            $total = $row['total'];
-
-            if (!isset($formattedData[$yearMonth])) {
-                $formattedData[$yearMonth] = [];
-            }
-
-            $formattedData[$yearMonth][] = [
-                '客户编号' => $customerCode,
-                'total' => $total
-            ];
-        }
-
-        krsort($formattedData);
-
-        $this->success('成功', $formattedData);
-    }
-
-    /**
-     * 样衣进度列表数据(支持分页)
-     * @param string sys_rq 年月,如 2026-09
-     * @param string customer 客户编号
-     * @param string search 搜索
-     * @param int page 页码,默认1
-     * @param int pageSize|limit 每页条数,默认30
-     */
-    public function getMonthlyGarmentsList()
-    {
-        if (!$this->request->isGet()) {
-            $this->error('请求错误');
-        }
-
-        $yearMonth = $this->request->param('sys_rq', '');
-        $customerCode = $this->request->param('customer', '');
-        $search = $this->request->param('search', '');
-        $page = max(1, intval($this->request->param('page', 1)));
-        $limit = intval($this->request->param('pageSize', 0));
-        if ($limit <= 0) {
-            $limit = intval($this->request->param('limit', 30));
-        }
-        $limit = max(1, min(200, $limit));
-        $offset = ($page - 1) * $limit;
-
-        $query = \db('月度样衣进度')
-            ->whereNull('Mod_rq');
-
-        if ($yearMonth) {
-            $query->where('DATE_FORMAT(Sys_rq, "%Y-%m")', $yearMonth);
-        }
-
-        if ($customerCode === '__EMPTY__') {
-            $query->where(function ($q) {
-                $q->whereNull('客户编号')->whereOr('客户编号', '');
-            });
-        } elseif ($customerCode) {
-            $query->where('客户编号', $customerCode);
-        }
-
-        if ($search) {
-            $query->where(function ($q) use ($search) {
-                $q->where('客户编号', 'like', "%{$search}%")
-                  ->whereOr('款号', 'like', "%{$search}%")
-                  ->whereOr('款式', 'like', "%{$search}%");
-            });
-        }
-
-        $total = (int)(clone $query)->count();
-        $results = $query
-            ->order('UniqId DESC')
-            ->limit($offset, $limit)
-            ->select();
-
-        foreach ($results as &$row) {
-            if (!empty($row['下单日期'])) {
-                $row['下单日期'] = date('Y-m-d', strtotime($row['下单日期']));
-            }
-            if (!empty($row['计划交办日期'])) {
-                $row['计划交办日期'] = date('Y-m-d', strtotime($row['计划交办日期']));
-            }
-        }
-        unset($row);
-
-        $this->success('成功', [
-            'result' => $results,
-            'total' => $total,
-            'page' => $page,
-            'pageSize' => $limit,
-        ]);
-    }
-
- /**
-     * 样衣进度新增数据
- */
-    public function saveMonthlyGarments()
-    {
-        if (!$this->request->isPost()) {
-            $this->error('请求错误');
-        }
-
-        $data = $this->request->post();
-
-        $customerCode = $data['客户编号'] ?? '';
-        $styleNo = $data['款号'] ?? '';
-        $style = $data['款式'] ?? '';
-        $sampleType = $data['样办种类'] ?? '';
-        $department = $data['做办部门'] ?? '';
-        $quantity = isset($data['数量']) && $data['数量'] !== '' ? (int)$data['数量'] : 0;
-        $orderDate = (!empty($data['下单日期'])) ? "'{$data['下单日期']}'" : 'NULL';
-        $fabricProgress = $data['面料进度'] ?? '';
-        $auxiliaryProgress = $data['辅料进度'] ?? '';
-        $planDeliveryDate = (!empty($data['计划交办日期'])) ? "'{$data['计划交办日期']}'" : 'NULL';
-        $actualDeliveryDate = (!empty($data['实际交办日期'])) ? "'{$data['实际交办日期']}'" : 'NULL';
-        $remark = $data['备注'] ?? '';
-        $sysId = $data['Sys_id'] ?? '';
-        $sysRq = date('Y-m-d H:i:s');
-
-        $sql = "INSERT INTO `月度样衣进度` (`客户编号`, `款号`, `款式`, `样办种类`, `做办部门`, `数量`, `下单日期`, `面料进度`, `辅料进度`, `计划交办日期`, `实际交办日期`, `备注`, `Sys_id`, `Sys_rq`, `Mod_rq`) VALUES ('{$customerCode}', '{$styleNo}', '{$style}', '{$sampleType}', '{$department}', {$quantity}, {$orderDate}, '{$fabricProgress}', '{$auxiliaryProgress}', {$planDeliveryDate}, {$actualDeliveryDate}, '{$remark}', '{$sysId}', '{$sysRq}', NULL)";
-        
-        $result = \db()->execute($sql);
-
-        if ($result !== false) {
-            $lastId = \db('月度样衣进度')->getLastInsID();
-            $this->success('保存成功', ['id' => $lastId]);
-        } else {
-            $this->error('保存失败');
-        }
-    }
-     /**
- * 样衣进度修改数据
- */
-    public function updateMonthlyGarments()
-    {
-        if (!$this->request->isPost()) {
-            $this->error('请求错误');
-        }
-
-        $data = $this->request->post();
-        $uniqId = $data['UniqId'] ?? '';
-        $nickName = $data['nickName'] ?? '';
-
-        if (!$uniqId) {
-            $this->error('UniqId不能为空');
-        }
-
-        $oldData = \db('月度样衣进度')->where('UniqId', $uniqId)->find();
-
-        $customerCode = $data['客户编号'] ?? '';
-        $styleNo = $data['款号'] ?? '';
-        $style = $data['款式'] ?? '';
-        $sampleType = $data['样办种类'] ?? '';
-        $department = $data['做办部门'] ?? '';
-        $quantity = isset($data['数量']) && $data['数量'] !== '' ? (int)$data['数量'] : 0;
-        $orderDate = (!empty($data['下单日期'])) ? "'{$data['下单日期']}'" : 'NULL';
-        $fabricProgress = $data['面料进度'] ?? '';
-        $auxiliaryProgress = $data['辅料进度'] ?? '';
-        $planDeliveryDate = (!empty($data['计划交办日期'])) ? "'{$data['计划交办日期']}'" : 'NULL';
-        $actualDeliveryDate = (!empty($data['实际交办日期'])) ? "'{$data['实际交办日期']}'" : 'NULL';
-        $remark = $data['备注'] ?? '';
-        $sysRq = date('Y-m-d H:i:s');
-
-        $sql = "UPDATE `月度样衣进度` SET `客户编号`='{$customerCode}', `款号`='{$styleNo}', `款式`='{$style}', `样办种类`='{$sampleType}', `做办部门`='{$department}', `数量`={$quantity}, `下单日期`={$orderDate}, `面料进度`='{$fabricProgress}', `辅料进度`='{$auxiliaryProgress}', `计划交办日期`={$planDeliveryDate}, `实际交办日期`={$actualDeliveryDate}, `备注`='{$remark}', `Sys_rq`='{$sysRq}' WHERE `UniqId`='{$uniqId}'";
-
-        $result = \db()->query($sql);
-
-        if ($result !== false) {
-            $this->saveLogs($uniqId, $oldData, $data, $nickName);
-            $this->success('修改成功');
-        } else {
-            $this->error('修改失败');
-        }
-    }
-
- 
-
-    public function deleteMonthlyGarments()
-    {
-        if (!$this->request->isPost()) {
-            $this->error('请求错误');
-        }
-
-        $data = $this->request->post();
-        $uniqId = $data['UniqId'] ?? '';
-        $nickName = $data['nickName'] ?? '';
-
-        if (!$uniqId) {
-            $this->error('UniqId不能为空');
-        }
-
-        $modRq = date('Y-m-d H:i:s');
-        $sql = "UPDATE `月度样衣进度` SET `Mod_rq`='{$modRq}' WHERE `UniqId`='{$uniqId}'";
-        $result = \db()->query($sql);
-
-        if ($result !== false) {
-            $this->success('删除成功');
-        } else {
-            $this->error('删除失败');
-        }
-    }
-
-    /**
-     * 样衣进度存储日志数据
-     */
-    private function saveLogs($uniqId, $oldData, $newData, $operator)
-    {
-        $fields = ['客户编号', '款号', '款式', '样办种类', '做办部门', '数量', '下单日期', '面料进度', '辅料进度', '计划交办日期', '实际交办日期', '备注'];
-        $modifyTime = date('Y-m-d H:i:s');
-
-        foreach ($fields as $field) {
-            $oldValue = $oldData[$field] ?? '';
-            $newValue = $newData[$field] ?? '';
-
-            if ((string)$oldValue !== (string)$newValue) {
-                $sql = "INSERT INTO `样衣进度日志` (`Uniqid`, `ModifyField`, `OriginalValue`, `Modified`, `修改人`, `修改日期`) VALUES ('{$uniqId}', '{$field}', '{$oldValue}', '{$newValue}', '{$operator}', '{$modifyTime}')";
-                \db()->query($sql);
-            }
-        }
-    }
-
-    /**
-     * 样衣进度日志数据
-     */
-    public function getLogs()
-    {
-        if (!$this->request->isGet()) {
-            $this->error('请求错误');
-        }
-
-        $uniqId = $this->request->get('UniqId') ?? '';
-
-        if (!$uniqId) {
-            $this->error('UniqId不能为空');
-        }
-
-        $logs = \db('样衣进度日志')
-            ->where('Uniqid', $uniqId)
-            ->order('修改日期', 'desc')
-            ->select();
-
-        $this->success('获取成功', ['result' => $logs, 'total' => count($logs)]);
-    }
+<?php
+
+namespace app\api\controller;
+
+
+use app\common\controller\Api;
+use Monolog\Handler\IFTTTHandler;
+use Overtrue\Socialite\Providers\WeWorkProvider;
+use think\Db;
+use think\Request;
+use function fast\e;
+
+/**
+ *
+ * 生产单衣进度管理
+ */
+class MonthlyGarments extends Api
+{
+    protected $noNeedLogin = ['*'];
+    protected $noNeedRight = ['*'];
+
+     /**
+ * 样衣进度左侧数据
+ */
+    public function getDateTree()
+    {
+        if (!$this->request->isGet()) {
+            $this->error('请求错误');
+        }
+
+        $results = \db('月度样衣进度')
+            ->field([
+                'DATE_FORMAT(Sys_rq, "%Y-%m")' => '年月',
+                '客户编号',
+                'COUNT(*) as total'
+            ])
+            ->whereNull('Mod_rq')
+            ->group('年月, 客户编号')
+            ->order('年月 DESC')
+            ->select();
+
+        $formattedData = [];
+
+        foreach ($results as $row) {
+            $yearMonth = $row['年月'];
+            $customerCode = $row['客户编号'];
+            $total = $row['total'];
+
+            if (!isset($formattedData[$yearMonth])) {
+                $formattedData[$yearMonth] = [];
+            }
+
+            $formattedData[$yearMonth][] = [
+                '客户编号' => $customerCode,
+                'total' => $total
+            ];
+        }
+
+        krsort($formattedData);
+
+        $this->success('成功', $formattedData);
+    }
+
+    /**
+     * 样衣进度列表数据(支持分页)
+     * @param string sys_rq 年月,如 2026-09
+     * @param string customer 客户编号
+     * @param string search 搜索
+     * @param int page 页码,默认1
+     * @param int pageSize|limit 每页条数,默认30
+     */
+    public function getMonthlyGarmentsList()
+    {
+        if (!$this->request->isGet()) {
+            $this->error('请求错误');
+        }
+
+        $yearMonth = $this->request->param('sys_rq', '');
+        $customerCode = $this->request->param('customer', '');
+        $search = $this->request->param('search', '');
+        $page = max(1, intval($this->request->param('page', 1)));
+        $limit = intval($this->request->param('pageSize', 0));
+        if ($limit <= 0) {
+            $limit = intval($this->request->param('limit', 30));
+        }
+        $limit = max(1, min(200, $limit));
+        $offset = ($page - 1) * $limit;
+
+        // 不要 clone 查询对象:ThinkPHP 预处理绑定会被 count 吃掉,再 select 会报 2031
+        $applyFilters = function ($query) use ($yearMonth, $customerCode, $search) {
+            $query->whereNull('Mod_rq');
+
+            if ($yearMonth) {
+                $monthStart = $yearMonth . '-01 00:00:00';
+                $monthEnd = date('Y-m-d H:i:s', strtotime($monthStart . ' +1 month'));
+                $query->where('Sys_rq', '>=', $monthStart)
+                    ->where('Sys_rq', '<', $monthEnd);
+            }
+
+            if ($customerCode === '__EMPTY__') {
+                $query->where(function ($q) {
+                    $q->whereNull('客户编号')->whereOr('客户编号', '');
+                });
+            } elseif ($customerCode) {
+                $query->where('客户编号', $customerCode);
+            }
+
+            if ($search) {
+                $query->where(function ($q) use ($search) {
+                    $q->where('客户编号', 'like', "%{$search}%")
+                      ->whereOr('款号', 'like', "%{$search}%")
+                      ->whereOr('款式', 'like', "%{$search}%");
+                });
+            }
+
+            return $query;
+        };
+
+        $total = (int)$applyFilters(\db('月度样衣进度'))->count();
+        $results = $applyFilters(\db('月度样衣进度'))
+            ->order('UniqId DESC')
+            ->limit($offset, $limit)
+            ->select();
+
+        foreach ($results as &$row) {
+            if (!empty($row['下单日期'])) {
+                $row['下单日期'] = date('Y-m-d', strtotime($row['下单日期']));
+            }
+            if (!empty($row['计划交办日期'])) {
+                $row['计划交办日期'] = date('Y-m-d', strtotime($row['计划交办日期']));
+            }
+        }
+        unset($row);
+
+        $this->success('成功', [
+            'result' => $results,
+            'total' => $total,
+            'page' => $page,
+            'pageSize' => $limit,
+        ]);
+    }
+
+ /**
+     * 样衣进度新增数据
+ */
+    public function saveMonthlyGarments()
+    {
+        if (!$this->request->isPost()) {
+            $this->error('请求错误');
+        }
+
+        $data = $this->request->post();
+
+        $customerCode = $data['客户编号'] ?? '';
+        $styleNo = $data['款号'] ?? '';
+        $style = $data['款式'] ?? '';
+        $sampleType = $data['样办种类'] ?? '';
+        $department = $data['做办部门'] ?? '';
+        $quantity = isset($data['数量']) && $data['数量'] !== '' ? (int)$data['数量'] : 0;
+        $orderDate = (!empty($data['下单日期'])) ? "'{$data['下单日期']}'" : 'NULL';
+        $fabricProgress = $data['面料进度'] ?? '';
+        $auxiliaryProgress = $data['辅料进度'] ?? '';
+        $planDeliveryDate = (!empty($data['计划交办日期'])) ? "'{$data['计划交办日期']}'" : 'NULL';
+        $actualDeliveryDate = (!empty($data['实际交办日期'])) ? "'{$data['实际交办日期']}'" : 'NULL';
+        $remark = $data['备注'] ?? '';
+        $sysId = $data['Sys_id'] ?? '';
+        $sysRq = date('Y-m-d H:i:s');
+
+        $sql = "INSERT INTO `月度样衣进度` (`客户编号`, `款号`, `款式`, `样办种类`, `做办部门`, `数量`, `下单日期`, `面料进度`, `辅料进度`, `计划交办日期`, `实际交办日期`, `备注`, `Sys_id`, `Sys_rq`, `Mod_rq`) VALUES ('{$customerCode}', '{$styleNo}', '{$style}', '{$sampleType}', '{$department}', {$quantity}, {$orderDate}, '{$fabricProgress}', '{$auxiliaryProgress}', {$planDeliveryDate}, {$actualDeliveryDate}, '{$remark}', '{$sysId}', '{$sysRq}', NULL)";
+        
+        $result = \db()->execute($sql);
+
+        if ($result !== false) {
+            $lastId = \db('月度样衣进度')->getLastInsID();
+            $this->success('保存成功', ['id' => $lastId]);
+        } else {
+            $this->error('保存失败');
+        }
+    }
+     /**
+ * 样衣进度修改数据
+ */
+    public function updateMonthlyGarments()
+    {
+        if (!$this->request->isPost()) {
+            $this->error('请求错误');
+        }
+
+        $data = $this->request->post();
+        $uniqId = $data['UniqId'] ?? '';
+        $nickName = $data['nickName'] ?? '';
+
+        if (!$uniqId) {
+            $this->error('UniqId不能为空');
+        }
+
+        $oldData = \db('月度样衣进度')->where('UniqId', $uniqId)->find();
+
+        $customerCode = $data['客户编号'] ?? '';
+        $styleNo = $data['款号'] ?? '';
+        $style = $data['款式'] ?? '';
+        $sampleType = $data['样办种类'] ?? '';
+        $department = $data['做办部门'] ?? '';
+        $quantity = isset($data['数量']) && $data['数量'] !== '' ? (int)$data['数量'] : 0;
+        $orderDate = (!empty($data['下单日期'])) ? "'{$data['下单日期']}'" : 'NULL';
+        $fabricProgress = $data['面料进度'] ?? '';
+        $auxiliaryProgress = $data['辅料进度'] ?? '';
+        $planDeliveryDate = (!empty($data['计划交办日期'])) ? "'{$data['计划交办日期']}'" : 'NULL';
+        $actualDeliveryDate = (!empty($data['实际交办日期'])) ? "'{$data['实际交办日期']}'" : 'NULL';
+        $remark = $data['备注'] ?? '';
+        $sysRq = date('Y-m-d H:i:s');
+
+        $sql = "UPDATE `月度样衣进度` SET `客户编号`='{$customerCode}', `款号`='{$styleNo}', `款式`='{$style}', `样办种类`='{$sampleType}', `做办部门`='{$department}', `数量`={$quantity}, `下单日期`={$orderDate}, `面料进度`='{$fabricProgress}', `辅料进度`='{$auxiliaryProgress}', `计划交办日期`={$planDeliveryDate}, `实际交办日期`={$actualDeliveryDate}, `备注`='{$remark}', `Sys_rq`='{$sysRq}' WHERE `UniqId`='{$uniqId}'";
+
+        $result = \db()->query($sql);
+
+        if ($result !== false) {
+            $this->saveLogs($uniqId, $oldData, $data, $nickName);
+            $this->success('修改成功');
+        } else {
+            $this->error('修改失败');
+        }
+    }
+
+ 
+
+    public function deleteMonthlyGarments()
+    {
+        if (!$this->request->isPost()) {
+            $this->error('请求错误');
+        }
+
+        $data = $this->request->post();
+        $uniqId = $data['UniqId'] ?? '';
+        $nickName = $data['nickName'] ?? '';
+
+        if (!$uniqId) {
+            $this->error('UniqId不能为空');
+        }
+
+        $modRq = date('Y-m-d H:i:s');
+        $sql = "UPDATE `月度样衣进度` SET `Mod_rq`='{$modRq}' WHERE `UniqId`='{$uniqId}'";
+        $result = \db()->query($sql);
+
+        if ($result !== false) {
+            $this->success('删除成功');
+        } else {
+            $this->error('删除失败');
+        }
+    }
+
+    /**
+     * 样衣进度存储日志数据
+     */
+    private function saveLogs($uniqId, $oldData, $newData, $operator)
+    {
+        $fields = ['客户编号', '款号', '款式', '样办种类', '做办部门', '数量', '下单日期', '面料进度', '辅料进度', '计划交办日期', '实际交办日期', '备注'];
+        $modifyTime = date('Y-m-d H:i:s');
+
+        foreach ($fields as $field) {
+            $oldValue = $oldData[$field] ?? '';
+            $newValue = $newData[$field] ?? '';
+
+            if ((string)$oldValue !== (string)$newValue) {
+                $sql = "INSERT INTO `样衣进度日志` (`Uniqid`, `ModifyField`, `OriginalValue`, `Modified`, `修改人`, `修改日期`) VALUES ('{$uniqId}', '{$field}', '{$oldValue}', '{$newValue}', '{$operator}', '{$modifyTime}')";
+                \db()->query($sql);
+            }
+        }
+    }
+
+    /**
+     * 样衣进度日志数据
+     */
+    public function getLogs()
+    {
+        if (!$this->request->isGet()) {
+            $this->error('请求错误');
+        }
+
+        $uniqId = $this->request->get('UniqId') ?? '';
+
+        if (!$uniqId) {
+            $this->error('UniqId不能为空');
+        }
+
+        $logs = \db('样衣进度日志')
+            ->where('Uniqid', $uniqId)
+            ->order('修改日期', 'desc')
+            ->select();
+
+        $this->success('获取成功', ['result' => $logs, 'total' => count($logs)]);
+    }
 }

+ 249 - 9
application/api/controller/ReportingWork.php

@@ -767,11 +767,12 @@ class ReportingWork extends Api
         ]);
     }
 
-        /**
-     * 查询机台报工记录
+    /**
+     * 查询当前机台报工记录,并返回近半年报工订单列表
      * @ApiMethod (GET)
      * @param string $date 日期
      * @param string $machine 机台编号
+     * @param string $majorprocess 大工序(不传则 orders 返回空)
      * @return array
      * @throws \think\db\exception\DataNotFoundException
      * @throws \think\db\exception\ModelNotFoundException
@@ -783,12 +784,14 @@ class ReportingWork extends Api
             $this->error('请求方法错误');
         }
         $params = $this->request->param();
-        if (empty($params['date'])) {
-            $this->error('日期不能为空');
-        }
-        if (empty($params['machine'])) {
-            $this->error('机台编号不能为空');
-        }
+        // if (empty($params['date'])) {
+        //     $this->error('日期不能为空');
+        // }
+        // if (empty($params['machine'])) {
+        //     $this->error('机台编号不能为空');
+        // }
+
+        //按照日期查询当前报工记录
         $rows = db('设备_工分计酬')->alias('a')
             ->join('工单_基本资料 b', 'a.work_order = b.订单编号', 'LEFT')
             ->where('a.del_rq', null)
@@ -819,7 +822,36 @@ class ReportingWork extends Api
                 ')
             ->order('a.process_code asc,a.staff_no asc,a.sys_rq desc')
             ->select();
-        $this->success('成功', $rows);
+
+        // 按大工序查询近半年报工订单;未传 majorprocess 时直接返回空
+        $orders = [];
+        if (!empty($params['majorprocess'])) {
+            $since = date('Y-m-d H:i:s', strtotime('-3 months'));
+            $orders = db('设备_工分计酬')->alias('a')
+                ->join('工单_基本资料 b', 'a.work_order = b.订单编号', 'LEFT')
+                ->where('a.del_rq', null)
+                ->where('b.Mod_rq', null)
+                ->where('a.sys_rq', '>=', $since)
+                ->where('a.majorprocess', $params['majorprocess'])
+                ->field('
+                    a.work_order as 订单编号,
+                    b.生产款号,
+                    b.款式,
+                    b.订单数量,
+                    MAX(a.sys_rq) as sys_rq
+                ')
+                ->group('a.work_order,b.生产款号,b.款式,b.订单数量')
+                ->order('sys_rq desc')
+                ->select();
+        }
+
+        $count = count($orders);
+
+        $this->success('成功', [
+            'records' => $rows ?: [],
+            'count' => $count,
+            'orders' => $orders ?: []
+        ]);
     }
 
     /**
@@ -983,4 +1015,212 @@ SQL;
     {
         return round(floatval($number) * floatval($standardScore) * 0.067, 2);
     }
+
+    /**
+     * 左侧菜单 - 工分产量报工
+     * 三级结构:大工序 → 机台编号 → 上报日期
+     * @ApiMethod (GET)
+     */
+    public function WorkpointsOutput()
+    {
+        if (!$this->request->isGet()) {
+            $this->error('请求方法错误');
+        }
+
+        $list = db('设备_工分计酬')
+            ->where('del_rq', null)
+            ->where('machine', '<>', '')
+            ->field('majorprocess, machine, sys_rq')
+            ->select();
+
+        $map = [];
+        foreach ($list as $row) {
+            $proc = trim((string)($row['majorprocess'] ?? ''));
+            $machine = trim((string)($row['machine'] ?? ''));
+            $date = trim((string)($row['sys_rq'] ?? ''));
+            if ($proc === '' || $machine === '' || $date === '') continue;
+
+            $dateOnly = substr($date, 0, 10);
+
+            if (!isset($map[$proc])) $map[$proc] = [];
+            if (!isset($map[$proc][$machine])) $map[$proc][$machine] = [];
+
+            if (!in_array($dateOnly, $map[$proc][$machine])) {
+                $map[$proc][$machine][] = $dateOnly;
+            }
+        }
+
+        $data = [];
+        $procOrder = ['裁剪', '车缝', '手工', '大烫', '总检', '包装'];
+        $procSorted = array_keys($map);
+        usort($procSorted, function ($a, $b) use ($procOrder) {
+            $ai = array_search($a, $procOrder);
+            $bi = array_search($b, $procOrder);
+            $ai = $ai === false ? 999 : $ai;
+            $bi = $bi === false ? 999 : $bi;
+            return $ai - $bi;
+        });
+
+        foreach ($procSorted as $proc) {
+            $machines = $map[$proc];
+            $children1 = [];
+            $machineKeys = array_keys($machines);
+            sort($machineKeys, SORT_NATURAL); // 机台编号自然排序 1,2,3...
+            foreach ($machineKeys as $machine) {
+                $dates = $machines[$machine];
+                rsort($dates);
+                $children2 = [];
+                foreach ($dates as $i => $d) {
+                    $children2[] = [
+                        'id' => "date-{$proc}-{$machine}-{$i}",
+                        'label' => $d,
+                        'sys_rq' => $d,
+                    ];
+                }
+                $children1[] = [
+                    'id' => "machine-{$proc}-{$machine}",
+                    'label' => $machine,
+                    'machine' => $machine,
+                    'children' => $children2,
+                ];
+            }
+            $data[] = [
+                'id' => "proc-{$proc}",
+                'label' => $proc,
+                'majorprocess' => $proc,
+                'children' => $children1,
+            ];
+        }
+
+        $this->success('成功', $data);
+    }
+
+    /**
+     * 工分产量报工列表
+     * @ApiMethod (GET)
+     * @param string search 关键词搜索(订单编号、员工编号、员工姓名),与菜单模式二选一
+     * @param string majorprocess 大工序(菜单模式必填)
+     * @param string machine 机台编号(菜单模式必填)
+     * @param string sys_rq 上报日期(菜单模式必填,Y-m-d)
+     * @param int page 页码,默认1
+     * @param int limit 每页条数,默认50
+     */
+    public function WorkpointsOutputList()
+    {
+        if (!$this->request->isGet()) {
+            $this->error('请求方法错误');
+        }
+        $params = $this->request->param();
+
+        $page = max(1, intval($params['page'] ?? 1));
+        $limit = max(1, min(200, intval($params['limit'] ?? 50)));
+        $offset = ($page - 1) * $limit;
+
+        // 关键词搜索模式
+        if (!empty($params['search'])) {
+            $search = trim($params['search']);
+            $staffNo = !empty($params['staff_no']) ? trim($params['staff_no']) : '';
+            $staffName = !empty($params['staff_name']) ? trim($params['staff_name']) : '';
+
+            // 先查出生产款号匹配的工单编号
+            $matchingWorkOrders = db('工单_基本资料')
+                ->where('Mod_rq', null)
+                ->where('生产款号', 'like', "%{$search}%")
+                ->column('订单编号');
+
+            $searchLike = "%{$search}%";
+            $staffNoLike = $staffNo ? "%{$staffNo}%" : '';
+            $staffNameLike = $staffName ? "%{$staffName}%" : '';
+
+            // 拼接 OR 条件
+            $orderSql = !empty($matchingWorkOrders)
+                ? " OR `work_order` IN ('" . implode("','", array_map('addslashes', $matchingWorkOrders)) . "')"
+                : "";
+
+            $whereSql = "(`del_rq` IS NULL AND (`work_order` LIKE '$searchLike' OR `staff_no` LIKE '$searchLike' OR `staff_name` LIKE '$searchLike'$orderSql))";
+
+            if ($staffNo) {
+                $whereSql .= " AND `staff_no` LIKE '$staffNoLike'";
+            }
+            if ($staffName) {
+                $whereSql .= " AND `staff_name` LIKE '$staffNameLike'";
+            }
+
+            $total = (int)db('设备_工分计酬')
+                ->where($whereSql)
+                ->count();
+
+            $rows = db('设备_工分计酬')
+                ->where($whereSql)
+                ->order('sys_rq desc,process_code asc,staff_no asc')
+                ->limit($offset, $limit)
+                ->select();
+        } else {
+            // 菜单选择模式
+            $query = db('设备_工分计酬')
+                ->field('id,work_order,majorprocess,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')
+                ->where('del_rq', null);
+
+            if (!empty($params['majorprocess'])) {
+                $query->where('majorprocess', $params['majorprocess']);
+            }
+            if (!empty($params['machine'])) {
+                $query->where('machine', $params['machine']);
+            }
+            if (!empty($params['sys_rq'])) {
+                $query->where('sys_rq', 'like', $params['sys_rq'] . '%');
+            }
+            $query->order('sys_rq desc,process_code asc,staff_no asc');
+
+            $total = (int)$query->count();
+            $rows = $query->limit($offset, $limit)->select();
+        }
+        // 批量查询生产款号和款式
+        $workOrders = array_unique(array_filter(array_column($rows, 'work_order')));
+        $orderMap = [];
+        if (!empty($workOrders)) {
+            $orderRows = db('工单_基本资料')
+                ->whereIn('订单编号', $workOrders)
+                ->whereNull('Mod_rq')
+                ->field('订单编号,生产款号,款式')
+                ->select();
+            foreach ($orderRows as $row) {
+                $orderMap[$row['订单编号']] = [
+                    '生产款号' => $row['生产款号'],
+                    '款式' => $row['款式'],
+                ];
+            }
+        }
+
+        // 返回明细数据
+        $list = [];
+        foreach ($rows as $row) {
+            $orderInfo = $orderMap[$row['work_order']] ?? [];
+            $list[] = [
+                'id' => $row['id'],
+                '小组' => $row['majorprocess'],
+                '员工编号' => $row['staff_no'],
+                '员工姓名' => $row['staff_name'],
+                '工序名称' => $row['process_name'],
+                '设备编号' => $row['machine'],
+                '报工数量' => $row['number'],
+                '计件单价' => $row['money'],
+                '工序产值' => $row['production_score'],
+                '报工日期' => substr($row['sys_rq'], 0, 10),
+                '订单编号' => $row['work_order'],
+                '生产款号' => $orderInfo['生产款号'] ?? '',
+                '款式' => $orderInfo['款式'] ?? '',
+                'sys_id' => $row['sys_id'],
+            ];
+        }
+
+        $this->success('成功', [
+            'total' => $total,
+            'page' => $page,
+            'limit' => $limit,
+            'list' => $list,
+        ]);
+    }
 }

+ 358 - 357
application/api/controller/StaffSalary.php

@@ -1,357 +1,358 @@
-<?php
-namespace app\api\controller;
-
-use app\common\controller\Api;
-use \think\Request;
-use think\Db;
-/**
- * 员工工资查询
-*/
-class StaffSalary extends Api
-{
-
-    protected $noNeedLogin = ['*'];
-    protected $noNeedRight = ['*'];
-
-//    public function GetReportingWorkMonth()
-//    {
-//        if (!$this->request->isGet()) {
-//            $this->error('请求方法错误');
-//        }
-//        $data = db('设备_工分计酬')
-//            ->where('del_rq', null)
-//            ->field('DISTINCT DATE_FORMAT(date, "%Y-%m") as month')
-//            ->order('date desc')
-//            ->select();
-//
-//        //获取员工部门
-//        $big_process = db('人员_基本资料')
-//            ->field('DISTINCT big_process')
-//            ->where('big_process','<>','')
-//            ->select();
-//        foreach ($big_process as $v) {
-//            $big_process_name[] = $v['big_process'];
-//        }
-//        $result = [];
-//        foreach ($data as $v) {
-//            $result[$v['month']] = $big_process_name;
-//        }
-//
-//        $this->success('成功', $result);
-//    }
-    /**
-     * 查询报工数据月份(年-年月-日期-工序-小组五级树)
-     * @ApiMethod (GET)
-     * @return array
-     * @throws \think\db\exception\DataNotFoundException
-     * @throws \think\db\exception\ModelNotFoundException
-     * @throws \think\exception\DbException
-     */
-    public function GetReportingWorkMonth()
-    {
-        if (!$this->request->isGet()) {
-            $this->error('请求方法错误');
-        }
-
-        $rows = db('设备_工分计酬')
-            ->where('del_rq', null)
-            ->where('sys_rq', 'not null')
-            ->field('LEFT(sys_rq, 10) as date, IF(majorprocess IS NULL OR majorprocess = "", "其他", majorprocess) as process, rtrim(sys_id) as sys_id')
-            ->group('LEFT(sys_rq, 10), process, sys_id')
-            ->order('sys_rq desc, process asc, sys_id asc')
-            ->select();
-
-        if (empty($rows)) {
-            $this->success('成功', []);
-        }
-
-        $treeMap = [];
-        foreach ($rows as $row) {
-            $date = $row['date'];
-            if (empty($date)) {
-                continue;
-            }
-            // 拆分年、年月、日期
-            $year = substr($date, 0, 4);
-            $yearMonth = substr($date, 0, 7);
-            $process = $row['process'];
-            $sysId = $row['sys_id'] !== '' ? $row['sys_id'] : '未知';
-
-            // 构建五级结构
-            if (!isset($treeMap[$year])) {
-                $treeMap[$year] = [];
-            }
-            if (!isset($treeMap[$year][$yearMonth])) {
-                $treeMap[$year][$yearMonth] = [];
-            }
-            if (!isset($treeMap[$year][$yearMonth][$date])) {
-                $treeMap[$year][$yearMonth][$date] = [
-                    'processes' => [],
-                ];
-            }
-            if (!isset($treeMap[$year][$yearMonth][$date]['processes'][$process])) {
-                $treeMap[$year][$yearMonth][$date]['processes'][$process] = [];
-            }
-            if (!in_array($sysId, $treeMap[$year][$yearMonth][$date]['processes'][$process], true)) {
-                $treeMap[$year][$yearMonth][$date]['processes'][$process][] = $sysId;
-            }
-        }
-
-        // 工序固定排序
-        $processOrder = ['裁剪', '车缝', '手工', '大烫', '总检', '包装', '其他'];
-        $result = [];
-        krsort($treeMap);
-
-        foreach ($treeMap as $year => $yearMonths) {
-            $yearNode = [
-                'label' => (string)$year,
-                'value' => (string)$year,
-                'children' => [],
-            ];
-
-            krsort($yearMonths);
-            foreach ($yearMonths as $yearMonth => $dates) {
-                $yearMonthNode = [
-                    'label' => $yearMonth,
-                    'value' => $yearMonth,
-                    'children' => [],
-                ];
-
-                krsort($dates);
-                foreach ($dates as $dateKey => $dateData) {
-                    $processChildren = [];
-                    $sortedProcesses = $this->sortProcessList(array_keys($dateData['processes']), $processOrder);
-                    foreach ($sortedProcesses as $process) {
-                        $groups = $dateData['processes'][$process];
-                        sort($groups);
-                        $groupChildren = [];
-                        foreach ($groups as $group) {
-                            $groupChildren[] = [
-                                'label' => $group,
-                                'value' => $group,
-                            ];
-                        }
-                        $processChildren[] = [
-                            'label' => $process,
-                            'value' => $process,
-                            'children' => $groupChildren,
-                        ];
-                    }
-
-                    $dateNode = [
-                        'label' => $dateKey,
-                        'value' => $dateKey,
-                        'children' => $processChildren,
-                    ];
-                    $yearMonthNode['children'][] = $dateNode;
-                }
-
-                $yearNode['children'][] = $yearMonthNode;
-            }
-
-            $result[] = $yearNode;
-        }
-
-        $this->success('成功', $result);
-    }
-
-    /**
-     * 按指定顺序排序工序
-     * @param array $processList
-     * @param array $order
-     * @return array
-     */
-    private function sortProcessList(array $processList, array $order): array
-    {
-        $sorted = [];
-        foreach ($order as $item) {
-            if (in_array($item, $processList)) {
-                $sorted[] = $item;
-                unset($processList[array_search($item, $processList)]);
-            }
-        }
-        return array_merge($sorted, $processList);
-    }
-
-
-    /**
-     * 查询员工工资列表
-     * @ApiMethod (GET)
-     * @param string $sys_rq 可选,左侧树日期:2026 / 2026-06 / 2026-06-08
-     * @param string $big_process 可选,大工序
-     * @param string $group 可选,小组
-     * @param string $search 可选,顶部搜索:订单编号/员工编号/员工姓名(也兼容 keyword、work_order、staff_no、staff_name)
-     * @return array
-     * @throws \think\db\exception\DataNotFoundException
-     * @throws \think\db\exception\ModelNotFoundException
-     * @throws \think\exception\DbException
-     */
-    public function GetStaffSalaryList()
-    {
-        if (!$this->request->isGet()) {
-            $this->error('请求方法错误');
-        }
-        $rawParam = $this->request->param();
-        $param = [];
-        foreach ($rawParam as $key => $value) {
-            $normKey = strtolower(rtrim(str_replace([' ', ' '], '', (string)$key), '_'));
-            if ($normKey === '') {
-                continue;
-            }
-            if (!array_key_exists($normKey, $param) || $param[$normKey] === '' || $param[$normKey] === null) {
-                $param[$normKey] = $value;
-            }
-        }
-
-        $sysRq = !empty($param['sys_rq']) ? trim((string)$param['sys_rq']) : '';
-        $bigProcess = !empty($param['big_process']) ? trim((string)$param['big_process']) : '';
-        $group = !empty($param['group']) ? trim((string)$param['group']) : '';
-        $search = '';
-        foreach (['search', 'keyword', 'work_order', 'staff_no', 'staff_name'] as $key) {
-            if (!empty($param[$key])) {
-                $search = trim((string)$param[$key]);
-                break;
-            }
-        }
-
-        //日期 或 搜索
-        if ($sysRq === '' && $search === '') {
-            $this->error('请选择左侧日期,或输入订单编号/员工编号/姓名进行查询');
-        }
-
-        if ($sysRq !== '') {
-            if (!preg_match('/^\d{4}(-\d{2})?(-\d{2})?$/', $sysRq)) {
-                $this->error('sys_rq 格式错误,请使用 2026 / 2026-06 / 2026-06-08 格式');
-            }
-        }
-
-        // 直接查报工计酬表,支持无日期仅按订单/员工搜索
-        $query = db('设备_工分计酬')->whereNull('del_rq');
-
-        if ($sysRq !== '') {
-            $query->where('sys_rq', 'like', $sysRq . '%');
-        }
-        if ($bigProcess !== '') {
-            $query->where('majorprocess', $bigProcess);
-        }
-        if ($group !== '') {
-            $query->where('sys_id', $group);
-        }
-        if ($search !== '') {
-            // 订单编号 / 员工编号 / 员工姓名 模糊匹配
-            $query->where('work_order|staff_no|staff_name', 'like', '%' . $search . '%');
-        }
-
-        $salaryRows = $query
-            ->field('staff_no,staff_name,DATE_FORMAT(IFNULL(sys_rq, date), "%Y-%m-%d") as date,sum(salary) as salary,sys_id')
-            ->group('staff_no,DATE_FORMAT(IFNULL(sys_rq, date), "%Y-%m-%d"),sys_id')
-            ->order('staff_no asc,date asc')
-            ->select();
-
-        if (empty($salaryRows)) {
-            // $this->error('当前条件下暂无工资数据');
-        }
-
-        $grouped = [];
-        foreach ($salaryRows as $row) {
-            $staffNo = $row['staff_no'];
-            $name = !empty($row['staff_name']) ? $row['staff_name'] : '';
-            if (!isset($grouped[$staffNo])) {
-                $grouped[$staffNo] = [
-                    'staff' => $staffNo . '-' . $name,
-                    'total_salary' => 0,
-                    'children' => [],
-                ];
-            }
-            $grouped[$staffNo]['children'][] = [
-                '员工编号' => $staffNo,
-                '员工姓名' => $name,
-                '日期' => $row['date'],
-                '工资' => $row['salary'],
-                '小组' => $row['sys_id'],
-            ];
-            $grouped[$staffNo]['total_salary'] += $row['salary'];
-        }
-
-        $this->success('成功', array_values($grouped));
-    }
-
-    /**
-     * 查询员工工资详情
-     *
-     */
-    public function GetStaffSalaryDetail()
-    {
-        if (!$this->request->isGet()){
-            $this->error('请求方法错误');
-        }
-        $param = $this->request->param();
-        if (empty($param['staff_no'])) {
-            $this->error('请选择员工');
-        }
-        if(empty($param['date'])){
-            $this->error('请选择日期');
-        }
-        $where = [
-            'a.staff_no' => $param['staff_no'],
-            'a.sys_rq' => ['like', $param['date'] . '%'],
-            'a.del_rq' => null,
-            'c.mod_rq' => null,
-        ];
-        $list = db('设备_工分计酬')
-            ->alias('a')
-            ->join('工单_部件资料 b', 'a.work_order = b.work_order and a.part_code = b.part_code', 'left')
-            ->join('工单_基本资料 c', 'a.work_order = c.订单编号', 'left')
-            ->field('a.id,a.work_order as 订单编号,DATE_FORMAT(a.date, "%Y-%m-%d") as 日期,a.sys_rq,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_code as 工序编号,a.process_name as 工序名称,a.standard_hour as 标准工时,a.standard_score as 标准分数,
-            a.coefficient as 系数,a.sys_id as 设备编号,c.生产款号,c.款式')
-            ->where($where)
-            ->order('a.sys_rq asc,a.process_code asc')
-            ->select();
-        if(empty($list)){
-            $this->error('没有数据');
-        }
-        $this->success('成功', $list);
-    }
-
-
-    /**
-     * 查询月份员工工资数据
-     * @ApiMethod (GET)
-     * @return array
-     * @throws \think\db\exception\DataNotFoundException
-     * @throws \think\db\exception\ModelNotFoundException
-     * @throws \think\exception\DbException
-     */
-    public function GetStaffSalaryMonth()
-    {
-        if (!$this->request->isGet()){
-            $this->error('请求方法错误');
-        }
-        $param = $this->request->param();
-        if (empty($param['month'])) {
-            $this->error('请选择月份');
-        }
-        $where = [
-            'date' => ['like', $param['month'] . '%'],
-            'del_rq' => null,
-        ];
-        if (!empty($param['search'])) {
-            $where['staff_no|staff_name'] = ['like', '%' . $param['search'] . '%'];
-        }
-        $list = db('设备_工分计酬')
-            ->where($where)
-            ->field('staff_no,staff_name,sum(salary) as salary')
-            ->group('staff_no,staff_name')
-            ->field('staff_no,staff_name,DATE_FORMAT(date, "%Y-%m-%d") as date,sum(salary) as salary')
-            ->group('staff_no,DATE_FORMAT(date, "%Y-%m-%d")')
-            ->order('staff_no asc,sys_rq asc')
-            ->select();
-        if(empty($list)){
-            $this->error('没有数据');
-        }
-        $this->success('成功', $list);
-    }
-
-}
+<?php
+namespace app\api\controller;
+
+use app\common\controller\Api;
+use \think\Request;
+use think\Db;
+/**
+ * 员工工资查询
+*/
+class StaffSalary extends Api
+{
+
+    protected $noNeedLogin = ['*'];
+    protected $noNeedRight = ['*'];
+
+//    public function GetReportingWorkMonth()
+//    {
+//        if (!$this->request->isGet()) {
+//            $this->error('请求方法错误');
+//        }
+//        $data = db('设备_工分计酬')
+//            ->where('del_rq', null)
+//            ->field('DISTINCT DATE_FORMAT(date, "%Y-%m") as month')
+//            ->order('date desc')
+//            ->select();
+//
+//        //获取员工部门
+//        $big_process = db('人员_基本资料')
+//            ->field('DISTINCT big_process')
+//            ->where('big_process','<>','')
+//            ->select();
+//        foreach ($big_process as $v) {
+//            $big_process_name[] = $v['big_process'];
+//        }
+//        $result = [];
+//        foreach ($data as $v) {
+//            $result[$v['month']] = $big_process_name;
+//        }
+//
+//        $this->success('成功', $result);
+//    }
+    /**
+     * 查询报工数据月份(年-年月-日期-工序-小组五级树)
+     * @ApiMethod (GET)
+     * @return array
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
+    public function GetReportingWorkMonth()
+    {
+        if (!$this->request->isGet()) {
+            $this->error('请求方法错误');
+        }
+
+        $rows = db('设备_工分计酬')
+            ->where('del_rq', null)
+            ->where('sys_rq', 'not null')
+            ->field('LEFT(sys_rq, 10) as date, IF(majorprocess IS NULL OR majorprocess = "", "其他", majorprocess) as process, rtrim(sys_id) as sys_id')
+            ->group('LEFT(sys_rq, 10), process, sys_id')
+            ->order('sys_rq desc, process asc, sys_id asc')
+            ->select();
+
+        if (empty($rows)) {
+            $this->success('成功', []);
+        }
+
+        $treeMap = [];
+        foreach ($rows as $row) {
+            $date = $row['date'];
+            if (empty($date)) {
+                continue;
+            }
+            // 拆分年、年月、日期
+            $year = substr($date, 0, 4);
+            $yearMonth = substr($date, 0, 7);
+            $process = $row['process'];
+            $sysId = $row['sys_id'] !== '' ? $row['sys_id'] : '未知';
+
+            // 构建五级结构
+            if (!isset($treeMap[$year])) {
+                $treeMap[$year] = [];
+            }
+            if (!isset($treeMap[$year][$yearMonth])) {
+                $treeMap[$year][$yearMonth] = [];
+            }
+            if (!isset($treeMap[$year][$yearMonth][$date])) {
+                $treeMap[$year][$yearMonth][$date] = [
+                    'processes' => [],
+                ];
+            }
+            if (!isset($treeMap[$year][$yearMonth][$date]['processes'][$process])) {
+                $treeMap[$year][$yearMonth][$date]['processes'][$process] = [];
+            }
+            if (!in_array($sysId, $treeMap[$year][$yearMonth][$date]['processes'][$process], true)) {
+                $treeMap[$year][$yearMonth][$date]['processes'][$process][] = $sysId;
+            }
+        }
+
+        // 工序固定排序
+        $processOrder = ['裁剪', '车缝', '手工', '大烫', '总检', '包装', '其他'];
+        $result = [];
+        krsort($treeMap);
+
+        foreach ($treeMap as $year => $yearMonths) {
+            $yearNode = [
+                'label' => (string)$year,
+                'value' => (string)$year,
+                'children' => [],
+            ];
+
+            krsort($yearMonths);
+            foreach ($yearMonths as $yearMonth => $dates) {
+                $yearMonthNode = [
+                    'label' => $yearMonth,
+                    'value' => $yearMonth,
+                    'children' => [],
+                ];
+
+                krsort($dates);
+                foreach ($dates as $dateKey => $dateData) {
+                    $processChildren = [];
+                    $sortedProcesses = $this->sortProcessList(array_keys($dateData['processes']), $processOrder);
+                    foreach ($sortedProcesses as $process) {
+                        $groups = $dateData['processes'][$process];
+                        sort($groups);
+                        $groupChildren = [];
+                        foreach ($groups as $group) {
+                            $groupChildren[] = [
+                                'label' => $group,
+                                'value' => $group,
+                            ];
+                        }
+                        $processChildren[] = [
+                            'label' => $process,
+                            'value' => $process,
+                            'children' => $groupChildren,
+                        ];
+                    }
+
+                    $dateNode = [
+                        'label' => $dateKey,
+                        'value' => $dateKey,
+                        'children' => $processChildren,
+                    ];
+                    $yearMonthNode['children'][] = $dateNode;
+                }
+
+                $yearNode['children'][] = $yearMonthNode;
+            }
+
+            $result[] = $yearNode;
+        }
+
+        $this->success('成功', $result);
+    }
+
+    /**
+     * 按指定顺序排序工序
+     * @param array $processList
+     * @param array $order
+     * @return array
+     */
+    private function sortProcessList(array $processList, array $order): array
+    {
+        $sorted = [];
+        foreach ($order as $item) {
+            if (in_array($item, $processList)) {
+                $sorted[] = $item;
+                unset($processList[array_search($item, $processList)]);
+            }
+        }
+        return array_merge($sorted, $processList);
+    }
+
+
+    /**
+     * 查询员工工资列表
+     * @ApiMethod (GET)
+     * @param string $sys_rq 可选,左侧树日期:2026 / 2026-06 / 2026-06-08
+     * @param string $big_process 可选,大工序
+     * @param string $group 可选,小组
+     * @param string $search 可选,顶部搜索:订单编号/员工编号/员工姓名(也兼容 keyword、work_order、staff_no、staff_name)
+     * @return array
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
+    public function GetStaffSalaryList()
+    {
+        if (!$this->request->isGet()) {
+            $this->error('请求方法错误');
+        }
+        $rawParam = $this->request->param();
+        $param = [];
+        foreach ($rawParam as $key => $value) {
+            $normKey = strtolower(rtrim(str_replace([' ', ' '], '', (string)$key), '_'));
+            if ($normKey === '') {
+                continue;
+            }
+            if (!array_key_exists($normKey, $param) || $param[$normKey] === '' || $param[$normKey] === null) {
+                $param[$normKey] = $value;
+            }
+        }
+
+        $sysRq = !empty($param['sys_rq']) ? trim((string)$param['sys_rq']) : '';
+        $bigProcess = !empty($param['big_process']) ? trim((string)$param['big_process']) : '';
+        $group = !empty($param['group']) ? trim((string)$param['group']) : '';
+        $search = '';
+        foreach (['search', 'keyword', 'work_order', 'staff_no', 'staff_name'] as $key) {
+            if (!empty($param[$key])) {
+                $search = trim((string)$param[$key]);
+                break;
+            }
+        }
+
+        //日期 或 搜索
+        if ($sysRq === '' && $search === '') {
+            $this->error('请选择左侧日期,或输入订单编号/员工编号/姓名进行查询');
+        }
+
+        if ($sysRq !== '') {
+            if (!preg_match('/^\d{4}(-\d{2})?(-\d{2})?$/', $sysRq)) {
+                $this->error('sys_rq 格式错误,请使用 2026 / 2026-06 / 2026-06-08 格式');
+            }
+        }
+
+        // 直接查报工计酬表,支持无日期仅按订单/员工搜索
+        $query = db('设备_工分计酬')->whereNull('del_rq');
+
+        if ($sysRq !== '') {
+            $query->where('sys_rq', 'like', $sysRq . '%');
+        }
+        if ($bigProcess !== '') {
+            $query->where('majorprocess', $bigProcess);
+        }
+        if ($group !== '') {
+            $query->where('sys_id', $group);
+        }
+        if ($search !== '') {
+            // 订单编号 / 员工编号 / 员工姓名 模糊匹配
+            $query->where('work_order|staff_no|staff_name', 'like', '%' . $search . '%');
+        }
+
+        $salaryRows = $query
+            ->field('staff_no,staff_name,DATE_FORMAT(IFNULL(sys_rq, date), "%Y-%m-%d") as date,sum(salary) as salary,sys_id')
+            ->group('staff_no,DATE_FORMAT(IFNULL(sys_rq, date), "%Y-%m-%d"),sys_id')
+            ->order('staff_no asc,date asc')
+            ->select();
+
+        if (empty($salaryRows)) {
+            // $this->error('当前条件下暂无工资数据');
+        }
+
+        $grouped = [];
+        foreach ($salaryRows as $row) {
+            $staffNo = $row['staff_no'];
+            $name = !empty($row['staff_name']) ? $row['staff_name'] : '';
+            if (!isset($grouped[$staffNo])) {
+                $grouped[$staffNo] = [
+                    'staff' => $staffNo . '-' . $name,
+                    'total_salary' => 0,
+                    'children' => [],
+                ];
+            }
+            $grouped[$staffNo]['children'][] = [
+                '员工编号' => $staffNo,
+                '员工姓名' => $name,
+                '日期' => $row['date'],
+                '工资' => $row['salary'],
+                '小组' => $row['sys_id'],
+            ];
+            $grouped[$staffNo]['total_salary'] += $row['salary'];
+        }
+
+        $this->success('成功', array_values($grouped));
+    }
+
+    /**
+     * 查询员工工资详情
+     *
+     */
+    public function GetStaffSalaryDetail()
+    {
+        if (!$this->request->isGet()){
+            $this->error('请求方法错误');
+        }
+        $param = $this->request->param();
+        if (empty($param['staff_no'])) {
+            $this->error('请选择员工');
+        }
+        if(empty($param['date'])){
+            $this->error('请选择日期');
+        }
+        $where = [
+            'a.staff_no' => $param['staff_no'],
+            'a.sys_rq' => ['like', $param['date'] . '%'],
+            'a.del_rq' => null,
+            'c.mod_rq' => null,
+            'b.del_rq' => null,
+        ];
+        $list = db('设备_工分计酬')
+            ->alias('a')
+            ->join('工单_部件资料 b', 'a.work_order = b.work_order and a.part_code = b.part_code', 'left')
+            ->join('工单_基本资料 c', 'a.work_order = c.订单编号', 'left')
+            ->field('a.id,a.work_order as 订单编号,DATE_FORMAT(a.date, "%Y-%m-%d") as 日期,a.sys_rq,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_code as 工序编号,a.process_name as 工序名称,a.standard_hour as 标准工时,a.standard_score as 标准分数,
+            a.coefficient as 系数,a.sys_id as 设备编号,c.生产款号,c.款式')
+            ->where($where)
+            ->order('a.sys_rq asc,a.process_code asc')
+            ->select();
+        if(empty($list)){
+            $this->error('没有数据');
+        }
+        $this->success('成功', $list);
+    }
+
+
+    /**
+     * 查询月份员工工资数据
+     * @ApiMethod (GET)
+     * @return array
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
+    public function GetStaffSalaryMonth()
+    {
+        if (!$this->request->isGet()){
+            $this->error('请求方法错误');
+        }
+        $param = $this->request->param();
+        if (empty($param['month'])) {
+            $this->error('请选择月份');
+        }
+        $where = [
+            'date' => ['like', $param['month'] . '%'],
+            'del_rq' => null,
+        ];
+        if (!empty($param['search'])) {
+            $where['staff_no|staff_name'] = ['like', '%' . $param['search'] . '%'];
+        }
+        $list = db('设备_工分计酬')
+            ->where($where)
+            ->field('staff_no,staff_name,sum(salary) as salary')
+            ->group('staff_no,staff_name')
+            ->field('staff_no,staff_name,DATE_FORMAT(date, "%Y-%m-%d") as date,sum(salary) as salary')
+            ->group('staff_no,DATE_FORMAT(date, "%Y-%m-%d")')
+            ->order('staff_no asc,sys_rq asc')
+            ->select();
+        if(empty($list)){
+            $this->error('没有数据');
+        }
+        $this->success('成功', $list);
+    }
+
+}

+ 1 - 1
application/api/controller/WorkOrderProcess.php

@@ -624,7 +624,7 @@ class WorkOrderProcess extends Api
             if ($hasReport > 0) {
                 $this->error(
                     '工序' . $process['process_code'] . '「' . $process['process_name']
-                    . '」已有报工记录,禁止删除。如需停用请联系管理员处理历史报工后再操作'
+                    . '」已有报工记录,禁止删除。'
                 );
             }
         }