unknown 1 місяць тому
батько
коміт
b8d3c0a75e

+ 181 - 524
application/api/controller/CostAccounting.php

@@ -346,83 +346,6 @@ class CostAccounting extends Api
         }
     }
 
-
-    /**
-     * 各月工单人工明细
-     * @return void
-     * @throws \think\db\exception\BindParamException
-     * @throws \think\db\exception\DataNotFoundException
-     * @throws \think\db\exception\ModelNotFoundException
-     * @throws \think\exception\DbException
-     * @throws \think\exception\PDOException
-     */
-    public function ChromaticityAdd()
-    {
-        if ($this->request->isGet() === false) {
-            $this->error('请求错误');
-        }
-        $param = $this->request->param();
-        if (empty($param)) {
-            $this->error('参数错误');
-        }
-        $list = db('绩效工资汇总')
-            ->alias('a')
-            ->join('工单_工艺资料 b','a.sczl_gdbh = b.Gy0_gdbh and a.sczl_yjno = b.Gy0_yjno and a.sczl_gxh = b.Gy0_gxh')
-            ->join('设备_基本资料 c','a.sczl_jtbh = c.设备编号','LEFT')
-            ->join('工单_印件资料 d','a.sczl_gdbh = d.Yj_Gdbh and a.sczl_yjno = d.yj_Yjno')
-            ->field('a.sczl_gdbh as 工单编号,a.sczl_yjno as 印件号,a.sczl_gxh as 工序号,sum(a.班组车头产量) as 班组车头产量,b.Gy0_gxmc as 工序名称,
-            a.sczl_ms as 墨色数,c.使用部门,b.印刷方式,b.版距,b.工价系数,a.sczl_jtbh,d.yj_yjmc as 印件名称,sum(a.车头产量占用机时) as 占用机时,a.sys_rq as 年月,
-            a.工序难度系数,sum(a.班组换算产量) as 班组换算产量,a.千件工价')
-            ->where('a.sys_ny', $param['month'])
-            ->group('a.sczl_gdbh,a.sczl_yjno,a.sczl_gxh,a.sczl_jtbh')
-            ->select();
-        $data = [];
-        foreach ($list as $k => $v) {
-            if ($v['版距'] === '0.0'){
-                $list[$k]['版距'] = 1000;
-            }
-            if ($v['墨色数'] === '0.00'){
-                $list[$k]['墨色数'] = 1;
-            }
-            if (strpos($v['工序名称'],'切废')){
-                $list[$k]['墨色数'] = 0.2;
-            }
-            $chanliang = $v['班组车头产量']*$v['工序难度系数'] + $v['班组换算产量'];
-            $data[] = [
-                '车间名称' => $v['使用部门'],
-                'sys_ny' => $param['month'],
-                'sczl_gdbh' => $v['工单编号'],
-                '印件名称' => $v['印件名称'],
-                'sczl_yjno' => $v['印件号'],
-                'sczl_gxh' => $v['工序号'],
-                '工序名称' => $v['工序名称'],
-                'sczl_jtbh' => $v['sczl_jtbh'],
-                '卷张换算系数' => $list[$k]['版距']/1000,
-                '占用机时' => $v['占用机时'],
-                '班组车头产量' => $v['班组车头产量'],
-                'sczl_ms' => $list[$k]['墨色数'],
-                '工序难度系数' => $v['工序难度系数'],
-                '班组换算产量' => $v['班组换算产量'],
-                '千件工价' => $v['千件工价'],
-                '计件产量' => $chanliang,
-                '水电分摊因子' => $v['占用机时'],
-                '材料分摊因子' => $chanliang,
-                '人工分摊因子' => ($chanliang/1000)*$v['千件工价'],
-                'Sys_id' => $param['sys_id'],
-                'Sys_rq' => date('Y-m-d H:i:s', time())
-            ];
-        }
-        db('成本v23_月度成本明细')->where('sys_ny', $param['month'])->delete();
-        $sql = db('成本v23_月度成本明细')->fetchSql(true)->insertAll($data);
-        $res = db()->query($sql);
-        if ($res !== false) {
-            $this->success('成功');
-        }else{
-            $this->error('失败');
-        }
-    }
-
-
     /**
      * 各月工单色度数
      * @return void
@@ -909,496 +832,230 @@ class CostAccounting extends Api
     }
 
     /**
-     * 获取各车间人工分摊因子比例
-     * @param string $month 年月
-     * @return array
+     * 获取月份工序成本左侧菜单
+     * @return void
      */
-    protected function WageRatio($month)
+    public function getProcessTab()
     {
-        try {
-            // 使用一次查询获取所有需要的数据
-            $result = db('成本v23_月度成本明细')
-                ->where('sys_ny', $month)
-                ->whereNotNull('车间名称')
-                ->field('
-                    SUM(人工分摊因子) as total,
-                    rtrim(车间名称) as workshop_name,
-                    SUM(人工分摊因子) as workshop_total
-                ')
-                ->group('车间名称')
-                ->select();
-
-            if (empty($result)) {
-                return [];
-            }
-
-            // 计算总人工分摊因子
-            $total = array_sum(array_column($result, 'workshop_total'));
-
-            // 计算每个车间的比例
-            $data = [];
-            foreach ($result as $item) {
-                if ($total > 0) {
-                    $data[$item['workshop_name']] = number_format($item['workshop_total'] / $total, 2);
-                } else {
-                    $data[$item['workshop_name']] = 0;
-                }
-            }
-
-            return $data;
-        } catch (\Exception $e) {
-            // 记录日志
-            \think\facade\Log::error('WageRatio计算失败: ' . $e->getMessage());
-            return [];
+        if ($this->request->isGet() === false) {
+            $this->error('请求错误');
         }
-    }
-
-    /**
-     * 获取指定部门各月的色度数数据
-     * @param string $month 年月
-     * @param string $sist 部门
-     * @return array
-     */
-    protected function WageRatioMonth($month, $sist)
-    {
-        try {
-            // 使用一次查询获取数据和总数
-            $query = db('成本_各月色度数')
-                ->where(['年月' => $month, '部门' => $sist]);
-
-            // 计算总数
-            $total = $query->value('SUM(sczl_cl * CASE 
-                WHEN sczl_ms = 0 OR sczl_ms IS NULL OR sczl_ms = \'\' THEN 1 
-                ELSE sczl_ms 
-            END)');
-
-            // 获取列表数据
-            $list = $query->field("
-                sczl_gdbh,
-                sczl_yjno,
-                sczl_gxh,
-                sczl_jtbh,
-                sczl_cl,
-                CASE 
-                    WHEN sczl_ms = 0 OR sczl_ms IS NULL OR sczl_ms = '' 
-                    THEN 1 
-                    ELSE sczl_ms 
-                END as sczl_ms
-            ")->select();
-
-            return [
-                'total' => $total ?: 0, // 防止空值
-                'list' => $list ?: [],  // 防止空值
-            ];
-        } catch (\Exception $e) {
-            \think\facade\Log::error('WageRatioMonth查询失败: ' . $e->getMessage());
-            return ['total' => 0, 'list' => []];
+        $months = db('成本v23_月度成本明细')
+            ->field('sys_ny AS year_month')
+            ->group('Sys_ny')
+            ->order('Sys_ny DESC')
+            ->column('Sys_ny');
+        $sist = ['01、切纸机组','02、胶印机组', '03、卷凹机组', '04、圆烫机组','05、圆切机组', '06、单凹机组',
+            '07、丝印机组','08、喷码机组','09、烫金机组','10、模切机组','11、检品机组','12、覆膜机组' ];
+        $data = [];
+        foreach ($months as $month) {
+            $data[$month] = $sist;
         }
+        $this->success('成功', $data);
     }
 
     /**
-     * 计算工资分配
-     * @param string $month 年月
-     * @param string $sist 部门
-     * @param float $ratio 比例
-     * @param string $type 类型
-     * @param float $amount 金额
-     * @return array
+     * 获取月份工序成本列表
+     * @return void
+     * @throws \think\Exception
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
      */
-    protected function WageRatioCalculation($month, $sist, $ratio, $type, $amount)
+    public function ProcessCostAccountingList()
     {
-        try {
-            $data = [];
-            $chromaNumber = $this->WageRatioMonth($month, $sist);
-
-            if (empty($chromaNumber['list']) || $chromaNumber['total'] == 0) {
-                return [];
-            }
-
-            $money = $ratio * $amount;
-            $name = $type === '部门人员工资' ? '车间人工' : '部门人工附加';
-
-            foreach ($chromaNumber['list'] as $item) {
-                if ($chromaNumber['total'] > 0) {
-                    $perAmount = ($item['sczl_cl'] * $item['sczl_ms'] / $chromaNumber['total']) * $money;
-                    $data[] = [
-                        'name' => $name,
-                        'money' => round($perAmount, 2),
-                        'sczl_gdbh' => $item['sczl_gdbh'],
-                        'sczl_yjno' => $item['sczl_yjno'],
-                        'sczl_gxh' => $item['sczl_gxh'],
-                        'sczl_jtbh' => $item['sczl_jtbh'],
-                    ];
-                }
-            }
-
-            return $data;
-        } catch (\Exception $e) {
-            \think\facade\Log::error('WageRatioCalculation计算失败: ' . $e->getMessage());
-            return [];
+        if ($this->request->isGet() === false) {
+            $this->error('请求错误');
+        }
+        $param = $this->request->param();
+        if (empty($param)) {
+            $this->error('参数错误');
+        }
+        $page = $this->request->param('page', 1);
+        $pageSize = $this->request->param('limit', 30);
+        $total = db('成本v23_月度成本明细')
+            ->alias('a')
+            ->join('设备_基本资料 b', 'a.sczl_jtbh = b.设备编号')
+            ->where('b.设备编组', $param['sist'])
+            ->where('a.sys_ny', $param['month'])
+            ->count();
+        $list = db('成本v23_月度成本明细')
+            ->alias('a')
+            ->join('设备_基本资料 b', 'a.sczl_jtbh = b.设备编号')
+            ->where('b.设备编组', $param['sist'])
+            ->where('a.sys_ny', $param['month'])
+            ->field('a.*')
+            ->order('a.sczl_gdbh')
+            ->page($page, $pageSize)
+            ->select();
+        $data = [
+            'total' => $total,
+            'list' => $list,
+        ];
+        if (empty($list)) {
+            $this->error('未找到数据');
+        }else{
+            $this->success('成功', $data);
         }
     }
 
     /**
-     * 工资费用分配主函数(优化版)
+     * 计算完工成本明细
+     * @return void
+     * @throws \think\Exception
+     * @throws \think\db\exception\BindParamException
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     * @throws \think\exception\PDOException
      */
-    public function WageExpensesList()
+    public function CalculateCompletedCost()
     {
-
-        // 参数验证
-        if (!$this->request->isGet()) {
-            throw new \Exception('请求错误,仅支持GET请求');
+        if ($this->request->isGet() === false) {
+            $this->error('请求错误');
         }
-
         $param = $this->request->param();
-        if (empty($param) || !isset($param['month'])) {
-            throw new \Exception('参数错误,缺少必要参数');
-        }
-
-        $month = trim($param['month']);
-
-        // 获取工资比例
-        $wageRatio = $this->WageRatio($month);
-        if (empty($wageRatio)) {
-            throw new \Exception('未找到该月的人工分摊因子数据');
+        if (empty($param)) {
+            $this->error('参数错误');
         }
+        $month = substr($param['month'], 0, 4) . '-' . substr($param['month'], 4, 2);
+        $field = [
+            'a.jjcp_gdbh as 工单编号',
+            'sum(b.车间人工) as 车间人工',
+            'sum(b.部门人工附加) as 部门人工附加',
+            'sum(c.金额) as 直接材料',
+            'sum(b.分摊材料) as 分摊材料',
+            'sum(b.直接水电) as 直接水电',
+            'sum(b.分摊水电) as 分摊水电',
+            'sum(b.废气处理) as 废气处理',
+            'sum(b.锅炉 + b.热水锅炉) as 锅炉',
+            'sum(b.空压机) as 空压机',
+            'sum(b.真空鼓风机) as 真空鼓风机',
+            'sum(b.中央空调) as 中央空调',
+            'sum(b.分摊其他) as 分摊其他'
+        ];
 
-        // 获取月度工资数据
-        $monthWage = db('成本_各月其他费用')
-            ->where('sys_ny', $month)
-            ->field('部门人员工资,管理人员工资')
-            ->find();
+        $list = db('成品入仓')
+            ->alias('a')
+            ->join('成本v23_月度成本明细 b', 'a.jjcp_gdbh = b.sczl_gdbh')
+            ->join('材料出库单列表 c', 'a.jjcp_gdbh = c.表体生产订单号', 'left')
+            ->field($field)
+            ->where('a.jjcp_sj', 'like', $month.'%')
+            ->group('a.jjcp_gdbh')
+            ->select();
 
-        if (empty($monthWage)) {
-            throw new \Exception('未找到该月的工资数据');
+        if (empty($list)) {
+            $this->error('未找到完工工单');
         }
 
-        // 准备批量更新数据
-        $updateData = [];
-        $updateCount = 0;
-
-        // 遍历所有车间
-        foreach ($wageRatio as $workshopName => $ratio) {
-            // 计算两种类型的工资分配
-            $updateTypes = [
-                '部门人员工资' => '车间人工',
-                '管理人员工资' => '部门人工附加'
-            ];
-
-            foreach ($updateTypes as $wageType => $fieldName) {
-                if (!isset($monthWage[$wageType])) {
-                    continue;
-                }
+        // 获取所有工单编号
+        $gdbhList = array_column($list, '工单编号');
 
-                $calculatedData = $this->WageRatioCalculation(
-                    $month,
-                    $workshopName,
-                    $ratio,
-                    $wageType,
-                    $monthWage[$wageType]
-                );
+        // 删除已存在的工单数据
+        db('成本v23_完工工单车间成本汇总')
+            ->where('工单编号', 'in', $gdbhList)
+            ->delete();
 
-                // 收集更新数据
-                foreach ($calculatedData as $item) {
-                    if (!empty($item['sczl_gdbh'])) {
-                        // 构建唯一标识作为更新条件
-                        $conditions = [
-                            'sczl_gdbh' => $item['sczl_gdbh'],
-                            'sczl_gxh' => $item['sczl_gxh'] ?? null,
-                            'sczl_jtbh' => $item['sczl_jtbh'] ?? null,
-                            'sczl_yjno' => $item['sczl_yjno'] ?? null,
-                        ];
-
-                        // 生成唯一标识字符串
-                        $uniqCondition = http_build_query(array_filter($conditions));
-
-                        $updateData[] = [
-                            'condition' => $uniqCondition, // 用于去重的条件
-                            'conditions' => $conditions,   // 实际查询条件
-                            'field' => $item['name'],
-                            'value' => $item['money'],
-                            'month' => $month
-                        ];
-                        $updateCount++;
-                    }
-                }
-            }
+        foreach ($list as $k => $v) {
+            $list[$k]['考核直接材料'] = $v['直接材料'];
+            $list[$k]['成本合计'] = $v['直接材料'] + $v['车间人工'] + $v['部门人工附加'] + $v['分摊材料'] + $v['直接水电'] + $v['分摊水电'] + $v['废气处理'] +
+                $v['锅炉'] + $v['空压机'] + $v['真空鼓风机'] + $v['中央空调'] + $v['分摊其他'];
+            $list[$k]['Sys_id'] = $param['sys_id'];
+            $list[$k]['Sys_rq'] = date('Y-m-d H:i:s', time());
         }
 
-        // 批量更新
-        $updatedRows = $this->batchUpdateData($updateData,$month);
-
-        // 返回成功结果
-        return json([
-            'code' => 200,
-            'msg' => '工资分配完成',
-            'data' => [
-                'updated_rows' => $updatedRows,
-                'update_count' => $updateCount,
-                'workshop_count' => count($wageRatio)
-            ]
-        ]);
+        $sql = db('成本v23_完工工单车间成本汇总')->fetchSql(true)->insertAll($list);
+        $res = db()->query($sql);
+        if ($res !== false) {
+            $this->success('计算成功');
+        }else{
+            $this->error('计算失败');
+        }
     }
 
+
     /**
-     * 批量更新数据(原生SQL版本)
-     * @param array $updateData 更新数据
-     * @param string $month 月份
-     * @return int 更新的行数
+     * 完工工单成本左侧菜单
+     * @return void
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
      */
-    private function batchUpdateData(array $updateData, string $month)
+    public function GetCompletionWorkOrderCostTab()
     {
-        if (empty($updateData)) {
-            return 0;
+        if ($this->request->isGet() === false) {
+            $this->error('请求错误');
         }
-
-        $updatedRows = 0;
-
-        // 按字段分组
-        $groupedData = [];
-        foreach ($updateData as $item) {
-            $field = $item['field'];
-            $groupedData[$field][] = $item;
+        $list = db('成本v23_完工工单车间成本汇总')
+            ->alias('a')
+            ->join('工单_基本资料 b', 'a.工单编号 = b.Gd_gdbh')
+            ->join('产品_基本资料 c', 'b.成品代号 = c.产品编号')
+            ->where('b.成品代号', '<>', '')
+            ->where('c.客户编号', '<>', '')
+            ->where('c.客户名称', '<>', '')
+            ->field([
+                'TRIM(c.客户名称) as 客户名称',
+                'TRIM(c.客户编号) as 客户编号'
+            ])
+            ->group('客户编号, 客户名称')
+            ->order('客户编号')
+            ->select();
+        if (empty($list)) {
+            $this->error('未找到完工数据');
         }
-
-        // 对每个字段进行批量更新
-        foreach ($groupedData as $field => $items) {
-
-                // 构建CASE WHEN语句
-                $caseWhens = [];
-                $gdbhList = [];
-
-                foreach ($items as $item) {
-                    $baseCondition = "sczl_gdbh = '{$item['conditions']['sczl_gdbh']}'";
-
-                    // 添加其他可选条件
-                    $conditions = [$baseCondition];
-
-                    if (!empty($item['conditions']['sczl_gxh'])) {
-                        $conditions[] = "sczl_gxh = '{$item['conditions']['sczl_gxh']}'";
-                    }
-                    if (!empty($item['conditions']['sczl_jtbh'])) {
-                        $conditions[] = "sczl_jtbh = '{$item['conditions']['sczl_jtbh']}'";
-                    }
-                    if (!empty($item['conditions']['sczl_yjno'])) {
-                        $conditions[] = "sczl_yjno = '{$item['conditions']['sczl_yjno']}'";
-                    }
-
-                    $whenCondition = implode(' AND ', $conditions);
-                    $caseWhens[] = "WHEN {$whenCondition} THEN {$item['value']}";
-
-                    $gdbhList[] = $item['conditions']['sczl_gdbh'];
-                }
-
-                if (empty($caseWhens)) {
-                    continue;
-                }
-
-                // 去重
-                $gdbhList = array_unique($gdbhList);
-                $gdbhStr = implode("','", $gdbhList);
-                $caseStr = implode(' ', $caseWhens);
-
-                // 构建SQL
-                $sql = "UPDATE 成本v23_月度成本明细 
-                   SET {$field} = CASE {$caseStr} ELSE {$field} END 
-                   WHERE sczl_gdbh IN ('{$gdbhStr}') AND sys_ny = '{$month}'";
-
-                // 执行SQL
-                $result = db()->execute($sql);
-                $updatedRows += $result;
-
-            }
-
-        return $updatedRows;
-    }
-
-    /**
-     * 获取工资分配详情(调试用)
-     */
-    public function getWageDistributionDetail($month)
-    {
-        $wageRatio = $this->WageRatio($month);
-        $distribution = [];
-
-        foreach ($wageRatio as $workshop => $ratio) {
-            $distribution[$workshop] = [
-                'ratio' => $ratio,
-                'data' => $this->WageRatioMonth($month, $workshop)
-            ];
+        $data = [];
+        foreach ($list as $k => $v) {
+            $data[] = $v['客户编号'] .'-->'.$v['客户名称'];
         }
-
-        return $distribution;
+        $this->success('成功', $data);
     }
 
-    /**
-     * 计算工艺材料分摊
-     * @param $month
-     * @return bool
-     */
-    public function calculationChroma($month)
-    {
-        try {
-            // 1. 批量获取数据,减少数据库查询次数
-            $date = substr($month, 0, 4) . '-' . substr($month, 4, 2);
-
-            // 获取分摊材料总金额
-            $totalMoney = db('材料出库单列表')
-                ->where([
-                    '出库日期' => ['like', $date . '%'],
-                    '部门' => '印刷成本中心'
-                ])
-                ->whereNull('表体生产订单号')
-                ->field('SUM(金额) as money')
-                ->find();
-
-            if (!$totalMoney || $totalMoney['money'] <= 0) {
-                return false;
-            }
-
-            // 获取工单工艺数据及总色度数
-            $processData = db('成本v23_月度成本明细')
-                ->whereNotNull('车间名称')
-                ->where('sys_ny', $month)
-                ->field('Uniqid, 班组车头产量*sczl_ms as 色度数, SUM(班组车头产量*sczl_ms) OVER() as total_chroma')
-                ->order('Uniqid asc')
-                ->select();
-
-            if (empty($processData)) {
-                return false;
-            }
-
-            // 从第一条数据中获取总色度数
-            $totalChroma = $processData[0]['total_chroma'] ?? 0;
-
-            if ($totalChroma <= 0) {
-                return false; // 防止除以零
-            }
-
-            // 2. 批量更新数据,减少数据库操作次数
-            $updateData = [];
-            foreach ($processData as $process) {
-                $money = round($totalMoney['money'] * ($process['色度数'] / $totalChroma), 2);
-                $updateData[] = [
-                    'Uniqid' => $process['Uniqid'],
-                    '分摊材料' => $money
-                ];
-            }
-
-            // 批量更新(使用fetchSql构建安全的SQL)
-            if (!empty($updateData)) {
-                return $this->batchUpdateWithFetchSql('成本v23_月度成本明细', $updateData, 'Uniqid');
-            }
-
-            return false;
-
-        } catch (\Exception $e) {
-            // 记录错误日志
-            \think\Log::error('工艺材料分摊计算失败: ' . $e->getMessage());
-            return false;
-        }
-    }
 
     /**
-     * 使用fetchSql方法批量更新数据(安全处理中文字段名)
-     * @param string $table 表名
-     * @param array $data 更新数据数组
-     * @param string $pk 主键字段名
-     * @return bool
+     * 完工工单成本列表
+     * @return void
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
      */
-    protected function batchUpdateWithFetchSql($table, $data, $pk = 'Uniqid')
+    public function CompletionWorkOrderCostList()
     {
-        if (empty($data)) {
-            return false;
+        if ($this->request->isGet() === false) {
+            $this->error('请求错误');
         }
-
-        try {
-            // 方法一:使用查询构建器配合fetchSql
-            $ids = array_column($data, $pk);
-
-            // 开始事务
-            db()->startTrans();
-
-            // 先查询现有数据
-            $query = db($table)
-                ->whereIn($pk, $ids)
-                ->field($pk)
-                ->fetchSql(true)
-                ->select();
-            $sql = $query;
-
-            // 构造批量更新SQL
-            $updateSql = "UPDATE `{$table}` SET ";
-
-            // 获取所有需要更新的字段(排除主键)
-            $fields = array_keys($data[0]);
-            $updateFields = array_diff($fields, [$pk]);
-
-            $cases = [];
-            foreach ($updateFields as $field) {
-                $caseSql = "`{$field}` = CASE ";
-                foreach ($data as $item) {
-                    $caseSql .= "WHEN `{$pk}` = '{$item[$pk]}' THEN '{$item[$field]}' ";
-                }
-                $caseSql .= "ELSE `{$field}` END";
-                $cases[] = $caseSql;
-            }
-
-            $updateSql .= implode(', ', $cases);
-            $updateSql .= " WHERE `{$pk}` IN ('" . implode("','", $ids) . "')";
-
-            // 执行更新
-            $result = db()->execute($updateSql);
-
-            db()->commit();
-            return $result !== false;
-
-        } catch (\Exception $e) {
-            db()->rollback();
-            \think\Log::error('批量更新失败: ' . $e->getMessage());
-
-            // 如果批量更新失败,回退到单条更新(也使用fetchSql)
-            return $this->singleUpdateFallback($table, $data, $pk);
+        $param = $this->request->param();
+        if (empty($param)) {
+            $this->error('参数错误');
         }
-    }
-
-    /**
-     * 单条更新回退方案(使用fetchSql)
-     */
-    protected function singleUpdateFallback($table, $data, $pk)
-    {
-        $success = true;
-
-        foreach ($data as $item) {
-            try {
-                // 使用fetchSql构建安全的更新语句
-                $updateData = [];
-                foreach ($item as $key => $value) {
-                    if ($key !== $pk) {
-                        $updateData[$key] = $value;
-                    }
-                }
-
-                $sql = db($table)
-                    ->where($pk, $item[$pk])
-                    ->update($updateData)
-                    ->fetchSql(true);
-
-                // 获取SQL并执行
-                $result = db()->execute($sql);
-
-                if ($result === false) {
-                    $success = false;
-                    \think\Log::error('单条更新失败 - SQL: ' . $sql);
-                }
-
-            } catch (\Exception $e) {
-                $success = false;
-                \think\Log::error('单条更新异常: ' . $e->getMessage());
-            }
+        $where = [];
+        if (isset($param['code'])) {
+            $where['b.成品代号'] = ['like',$param['code'].'%'];
         }
+        $page = $this->request->param('page', 1);
+        $pageSize = $this->request->param('limit', 30);
+        if (isset($search)){
+            $where['a.工单编号|b.成本名称'] = ['like','%'.$search.'%'];
+        }
+        $list = db('成本v23_完工工单车间成本汇总')
+            ->alias('a')
+            ->join('工单_基本资料 b', 'a.工单编号 = b.Gd_gdbh')
+            ->field('a.*, TRIM(b.成品代号) as 成品代号, TRIM(b.成品名称) as 成品名称')
+            ->where($where)
+            ->page($page, $pageSize)
+            ->select();
+        if (empty($list)) {
+            $this->error('未找到完工成本数据');
+        }
+        $total = db('成本v23_完工工单车间成本汇总')
+            ->alias('a')
+            ->join('工单_基本资料 b', 'a.工单编号 = b.Gd_gdbh')
+            ->where($where)
+            ->count();
 
-        return $success;
+         $data = [
+            'total' => $total,
+            'list' => $list,
+        ];
+        $this->success('成功', $data);
     }
-
 }

+ 1 - 560
application/api/controller/CostCalculation.php

@@ -5,7 +5,6 @@ namespace app\api\controller;
 use app\common\controller\Api;
 use think\Db;
 use think\Queue;
-use app\service\UnifiedCostCalculationService;
 use think\Request;
 
 class CostCalculation extends Api
@@ -13,564 +12,6 @@ class CostCalculation extends Api
     protected $noNeedLogin = ['*'];
     protected $noNeedRight = ['*'];
 
-//    // 楼层编组映射(优化版)
-//    const FLOOR_GROUP_MAP = [
-//        '1' => ['02、胶印机组', '03、卷凹机组', '06、单凹机组', '05、圆切机组', '04、圆烫机组', '10、模切机组', '09、烫金机组'],     // 1楼编组
-//        '2' => ['01、切纸机组', '11、检品机组', '07、丝印机组', '12、覆膜机组', '08、喷码机组'],                     // 2楼编组
-//    ];
-//
-//    // 科目名称常量(简化版)
-//    const SUBJECT_WASTE_GAS = '废气处理(RTO)';
-//    const SUBJECT_BOILER = '锅炉';
-//    const SUBJECT_AIR_COMPRESSOR = '空压机';
-//    const SUBJECT_HOT_WATER_BOILER = '热水锅炉';
-//    const SUBJECT_VACUUM_BLOWER = '真空鼓风机';
-//    const SUBJECT_CENTRAL_AIR_CONDITIONER = '中央空调';
-//    const SUBJECT_TOTAL_TO_APPORTION = '待分摊总额';
-//
-//    // 需要分配到卷凹机组的科目列表
-//    const ROLL_COATER_ONLY_SUBJECTS = [
-//        self::SUBJECT_BOILER,
-//        self::SUBJECT_HOT_WATER_BOILER,
-//    ];
-//
-//    // 简化科目列表
-//    const SIMPLIFIED_SUBJECTS = [
-//        self::SUBJECT_WASTE_GAS,
-//        self::SUBJECT_BOILER,
-//        self::SUBJECT_AIR_COMPRESSOR,
-//        self::SUBJECT_HOT_WATER_BOILER,
-//        self::SUBJECT_VACUUM_BLOWER,
-//        self::SUBJECT_CENTRAL_AIR_CONDITIONER,
-//        self::SUBJECT_TOTAL_TO_APPORTION,
-//    ];
-//
-//    /**
-//     * 根据设备编号获取楼层信息
-//     */
-//    protected function getFloorByMachineCode($machineCode)
-//    {
-//        static $machineFloorCache = [];
-//
-//        if (isset($machineFloorCache[$machineCode])) {
-//            return $machineFloorCache[$machineCode];
-//        }
-//
-//        // 查询设备编组
-//        $group = Db::name('设备_基本资料')
-//            ->where('sys_sbID', '<>','')
-//            ->where('设备编号', $machineCode)
-//            ->value('设备编组');
-//
-//        if (!$group) {
-//            $machineFloorCache[$machineCode] = null;
-//            return null;
-//        }
-//
-//        // 根据编组判断楼层
-//        foreach (self::FLOOR_GROUP_MAP as $floor => $groups) {
-//            foreach ($groups as $groupName) {
-//                if (strpos($group, $groupName) !== false) {
-//                    $machineFloorCache[$machineCode] = $floor;
-//                    return $floor;
-//                }
-//            }
-//        }
-//
-//        $machineFloorCache[$machineCode] = null;
-//        return null;
-//    }
-//
-//    /**
-//     * 根据楼层获取该楼层的所有机台
-//     */
-//    protected function getMachinesByFloor($floor, $month)
-//    {
-//        // 获取该楼层的所有编组
-//        $groups = self::FLOOR_GROUP_MAP[$floor] ?? [];
-//        if (empty($groups)) {
-//            return [];
-//        }
-//
-//        try {
-//            // 方法1:使用更简单的查询条件构建方式
-//            $query = Db::name('成本v23_月度成本明细')
-//                ->alias('c')
-//                ->join('设备_基本资料 e', 'c.sczl_jtbh = e.设备编号', 'LEFT')
-//                ->where('c.sys_ny', $month)
-//                ->where('e.设备编号', '<>', '')
-//                ->whereIn('e.设备编组', $groups);
-//
-//
-//            $query->field([
-//                'c.sczl_jtbh' => '机台编号',
-//                'c.占用机时',
-//                'e.设备编组',
-//                'c.sczl_gdbh' => '工单编号',
-//                'c.sczl_yjno' => '印件号',
-//                'c.sczl_gxh' => '工序号',
-//                'c.Uniqid',
-//                'c.车间名称'
-//            ]);
-//
-//            $machines = $query->select();
-//
-//            return $machines ?: [];
-//
-//        } catch (\Exception $e) {
-//            throw new \Exception('查询机台数据失败: ' . $e->getMessage());
-//
-//        }
-//    }
-//
-//    /**
-//     * 获取所有机台(不分楼层)
-//     */
-//    protected function getAllMachines($month)
-//    {
-//        return Db::name('成本v23_月度成本明细')
-//            ->alias('c')
-//            ->join('设备_基本资料 e', 'c.sczl_jtbh = e.设备编号')
-//            ->where('c.sys_ny', $month)
-//            ->where('e.设备编号', '<>', '')
-//            ->field([
-//                'c.sczl_jtbh' => '机台编号',
-//                'c.占用机时',
-//                'e.设备编组',
-//                'c.sczl_gdbh' => '工单编号',
-//                'c.sczl_yjno' => '印件号',
-//                'c.sczl_gxh' => '工序号',
-//                'c.Uniqid',
-//                'c.车间名称'
-//            ])
-//            ->select();
-//    }
-//
-//    /**
-//     * 获取卷凹机组的所有机台
-//     */
-//    protected function getRollCoaterMachines($month)
-//    {
-//        return Db::name('成本v23_月度成本明细')
-//            ->alias('c')
-//            ->join('设备_基本资料 e', 'c.sczl_jtbh = e.设备编号')
-//            ->where('c.sys_ny', $month)
-//            ->where('e.设备编号', '<>', '')
-//            ->where('e.设备编组', 'like', '%03、卷凹机组%')
-//            ->field([
-//                'c.sczl_jtbh' => '机台编号',
-//                'c.占用机时',
-//                'e.设备编组',
-//                'c.sczl_gdbh' => '工单编号',
-//                'c.sczl_yjno' => '印件号',
-//                'c.sczl_gxh' => '工序号',
-//                'c.Uniqid',
-//                'c.车间名称'
-//            ])
-//            ->select();
-//    }
-//
-//    /**
-//     * 主计算方法
-//     */
-//    public function costCalculation()
-//    {
-//        if (!$this->request->isGet()) {
-//            $this->error('请求错误');
-//        }
-//
-//        $param = $this->request->param();
-//        if (empty($param['month'])) {
-//            $this->error('请选择月份');
-//        }
-//
-//        $month = $param['month'];
-//        $sysId = $param['sys_id'] ?? '';
-//
-//
-//        // 计算分摊
-//        $apportionmentResults = $this->calculateApportionment($month);
-//
-//        // 格式化结果并保存
-//        $formattedResults = $this->formatApportionmentResults($apportionmentResults, $month, $sysId);
-//        $this->saveApportionmentCoefficients($formattedResults, $month);
-//
-//        // 进行二次分配(到工单)
-//        $this->allocateToWorkOrders($month);
-//
-//        $this->success('成本分摊计算成功');
-//    }
-//
-//    /**
-//     * 计算分摊(核心方法)
-//     */
-//    protected function calculateApportionment($month)
-//    {
-//        // 获取水电气分摊数据
-//        $utilityData = $this->getUtilityData($month);
-//
-//        $results = [];
-//
-//        foreach ($utilityData as $item) {
-//            $subject = $this->simplifySubjectName($item['科目名称']);
-//            $amount = $this->calculateAmount($item);
-//
-//            if ($subject === self::SUBJECT_TOTAL_TO_APPORTION) {
-//                // 待分摊总额按楼层分摊
-//                $floorResults = $this->allocateByFloor($amount, $month);
-//
-//                foreach ($floorResults as $floor => $machineAllocations) {
-//                    foreach ($machineAllocations as $machineCode => $machineAmount) {
-//                        if (!isset($results[$machineCode])) {
-//                            $results[$machineCode] = [];
-//                        }
-//                        $results[$machineCode][$subject] = $machineAmount;
-//                    }
-//                }
-//            } elseif (in_array($subject, self::ROLL_COATER_ONLY_SUBJECTS)) {
-//                // 锅炉和热水锅炉只分配到卷凹机组
-//                $rollCoaterResults = $this->allocateToRollCoaterOnly($amount, $month);
-//
-//                foreach ($rollCoaterResults as $machineCode => $machineAmount) {
-//                    if (!isset($results[$machineCode])) {
-//                        $results[$machineCode] = [];
-//                    }
-//                    if (!isset($results[$machineCode][$subject])) {
-//                        $results[$machineCode][$subject] = $machineAmount;
-//                    }
-//                }
-//            } else {
-//                // 其他科目按所有机台分摊
-//                $globalResults = $this->allocateGlobally($amount, $month);
-//                foreach ($globalResults as $machineCode => $machineAmount) {
-//                    if (!isset($results[$machineCode])) {
-//                        $results[$machineCode] = [];
-//                    }
-//                    $results[$machineCode][$subject] = $machineAmount;
-//                }
-//            }
-//        }
-//
-//        return $results;
-//    }
-//
-//    /**
-//     * 获取水电气数据
-//     */
-//    protected function getUtilityData($month)
-//    {
-//        return Db::name('成本_各月水电气')
-//            ->where('Sys_ny', $month)
-//            ->whereLike('费用类型', '%分摊%')
-//            ->select();
-//    }
-//
-//    /**
-//     * 简化科目名称
-//     */
-//    protected function simplifySubjectName($subjectName)
-//    {
-//        $simplifiedMap = [
-//            '废气处理(RTO)' => self::SUBJECT_WASTE_GAS,
-//            '锅炉' => self::SUBJECT_BOILER,
-//            '热水锅炉' => self::SUBJECT_HOT_WATER_BOILER,
-//            '空压机' => self::SUBJECT_AIR_COMPRESSOR,
-//            '真空鼓风机' => self::SUBJECT_VACUUM_BLOWER,
-//            '中央空调' => self::SUBJECT_CENTRAL_AIR_CONDITIONER,
-//            '待分摊总额' => self::SUBJECT_TOTAL_TO_APPORTION,
-//        ];
-//
-//        foreach ($simplifiedMap as $keyword => $simplified) {
-//            if (strpos($subjectName, $keyword) !== false) {
-//                return $simplified;
-//            }
-//        }
-//
-//        return $subjectName;
-//    }
-//
-//    /**
-//     * 计算金额
-//     */
-//    protected function calculateAmount($item)
-//    {
-//        $electricity = ($this->getSafeNumericValue($item['耗电量']) * $this->getSafeNumericValue($item['单位电价']));
-//        $gas = ($this->getSafeNumericValue($item['耗气量']) * $this->getSafeNumericValue($item['单位气价']));
-//
-//        return round($electricity + $gas, 2);
-//    }
-//
-//    /**
-//     * 按楼层分摊
-//     */
-//    protected function allocateByFloor($totalAmount, $month)
-//    {
-//        $results = [];
-//
-//        // 计算每个楼层的总机时
-//        $floorTotalHours = [];
-//        foreach ([1, 2] as $floor) {
-//            $machines = $this->getMachinesByFloor($floor, $month);
-//            $totalHours = 0;
-//            foreach ($machines as $machine) {
-//                $totalHours += $machine['占用机时'];
-//            }
-//            $floorTotalHours[$floor] = $totalHours;
-//        }
-//
-//        $allFloorsTotal = array_sum($floorTotalHours);
-//        if ($allFloorsTotal <= 0) {
-//            return $results;
-//        }
-//
-//        // 按楼层比例分摊
-//        foreach ($floorTotalHours as $floor => $hours) {
-//            $floorAmount = round($totalAmount * ($hours / $allFloorsTotal), 2);
-//
-//            // 在楼层内按机台分摊
-//            $machines = $this->getMachinesByFloor($floor, $month);
-//            $floorResults = $this->allocateWithinGroup($floorAmount, $machines);
-//
-//            $results[$floor] = $floorResults;
-//        }
-//
-//        return $results;
-//    }
-//
-//    /**
-//     * 全局分摊(不分楼层)
-//     */
-//    protected function allocateGlobally($totalAmount, $month)
-//    {
-//        $machines = $this->getAllMachines($month);
-//        return $this->allocateWithinGroup($totalAmount, $machines);
-//    }
-//
-//    /**
-//     * 只分摊到卷凹机组
-//     */
-//    protected function allocateToRollCoaterOnly($totalAmount, $month)
-//    {
-//        $machines = $this->getRollCoaterMachines($month);
-//        return $this->allocateWithinGroup($totalAmount, $machines);
-//    }
-//
-//    /**
-//     * 在组内按机台运行时间分摊
-//     */
-//    protected function allocateWithinGroup($totalAmount, $machines)
-//    {
-//        $results = [];
-//
-//        if (empty($machines)) {
-//            return $results;
-//        }
-//
-//        $totalHours = 0;
-//        $machineHours = [];
-//
-//        foreach ($machines as $machine) {
-//            $hours = floatval($machine['占用机时']);
-//            $machineCode = $machine['机台编号'];
-//
-//            if ($hours > 0) {
-//                $totalHours += $hours;
-//                if (!isset($machineHours[$machineCode])) {
-//                    $machineHours[$machineCode] = $hours;
-//                } else {
-//                    $machineHours[$machineCode] += $hours;
-//                }
-//            }
-//        }
-//
-//        if ($totalHours <= 0) {
-//            return $results;
-//        }
-//
-//        foreach ($machineHours as $machineCode => $hours) {
-//            $results[$machineCode] = round($totalAmount * ($hours / $totalHours), 2);
-//        }
-//
-//        return $results;
-//    }
-//
-//    /**
-//     * 格式化分摊结果
-//     */
-//    protected function formatApportionmentResults($results, $month, $sysId)
-//    {
-//        $formatted = [];
-//        $now = date('Y-m-d H:i:s');
-//
-//        foreach ($results as $machineCode => $subjects) {
-//            foreach ($subjects as $subject => $amount) {
-//                $formatted[] = [
-//                    'Sys_ny' => $month,
-//                    '科目名称' => $subject,
-//                    '设备编号' => $machineCode,
-//                    '分摊系数' => 1,
-//                    '分摊金额' => $amount,
-//                    'Sys_id' => $sysId,
-//                    'Sys_rq' => $now,
-//                ];
-//            }
-//        }
-//
-//        return $formatted;
-//    }
-//
-//    /**
-//     * 保存分摊系数
-//     */
-//    protected function saveApportionmentCoefficients($data, $month)
-//    {
-//        // 删除旧数据
-//        Db::name('成本_各月分摊系数')->where('Sys_ny', $month)->delete();
-//
-//        if (!empty($data)) {
-//            $sql = Db::name('成本_各月分摊系数')->fetchSql(true)->insertAll($data);
-//            \db()->query($sql);
-//        }
-//    }
-//
-//    /**
-//     * 分摊到工单(二次分配)
-//     */
-//    protected function allocateToWorkOrders($month)
-//    {
-//        // 获取所有机台的分摊系数(每机时费用)
-//        $coefficients = $this->getMachineCoefficients($month);
-//
-//        // 获取所有机台的工单
-//        $workOrders = $this->getWorkOrdersByMonth($month);
-//
-//        $updates = [];
-//        foreach ($workOrders as $order) {
-//            $machineCode = $order['机台编号'];
-//
-//            if (!isset($coefficients[$machineCode])) {
-//                continue;
-//            }
-//
-//            $machineCoeffs = $coefficients[$machineCode];
-//            $hours = floatval($order['占用机时']);
-//
-//            if ($hours <= 0) {
-//                continue;
-//            }
-//
-//            // 计算各科目分摊金额
-//            $updateData = [
-//                '直接水电' => round($hours * 0.69, 2), // 直接水电费
-//            ];
-//
-//            foreach ($machineCoeffs as $subject => $rate) {
-//                $subjectKey = ($subject === '待分摊总额') ? '分摊水电' : $subject;
-//                $updateData[$subjectKey] = round($hours * $rate, 2);
-//            }
-//
-//            // 构建更新条件
-//            $where = [
-//                'sys_ny' => $month,
-//                'sczl_gdbh' => $order['工单编号'],
-//                'sczl_yjno' => $order['印件号'],
-//                'sczl_gxh' => $order['工序号'],
-//                'sczl_jtbh' => $machineCode,
-//            ];
-//
-//            $updates[] = [
-//                'where' => $where,
-//                'data' => $updateData
-//            ];
-//        }
-//
-//        // 批量更新
-//        $this->batchUpdateWorkOrders($updates, $month);
-//    }
-//
-//    /**
-//     * 获取机台分摊系数(每机时费用)
-//     */
-//    protected function getMachineCoefficients($month)
-//    {
-//        // 查询分摊系数和机台运行时间
-//        $data = Db::name('成本_各月分摊系数')
-//            ->alias('c')
-//            ->join('成本v23_月度成本明细 d', 'd.sys_ny = c.Sys_ny AND d.sczl_jtbh = c.设备编号')
-//            ->where('c.Sys_ny', $month)
-//            ->field([
-//                'c.设备编号',
-//                'c.科目名称',
-//                'c.分摊金额',
-//                'SUM(d.占用机时)' => 'total_hours'
-//            ])
-//            ->group('c.设备编号, c.科目名称')
-//            ->select();
-//
-//        $coefficients = [];
-//
-//        foreach ($data as $item) {
-//            $machineCode = $item['设备编号'];
-//            $subject = $item['科目名称'];
-//            $amount = floatval($item['分摊金额']);
-//            $hours = floatval($item['total_hours']);
-//
-//            if ($hours > 0) {
-//                $rate = round($amount / $hours, 4);
-//
-//                if (!isset($coefficients[$machineCode])) {
-//                    $coefficients[$machineCode] = [];
-//                }
-//
-//                $coefficients[$machineCode][$subject] = $rate;
-//            }
-//        }
-//
-//        return $coefficients;
-//    }
-//
-//    /**
-//     * 获取所有工单
-//     */
-//    protected function getWorkOrdersByMonth($month)
-//    {
-//        return Db::name('成本v23_月度成本明细')
-//            ->where('sys_ny', $month)
-//            ->field([
-//                'sczl_gdbh' => '工单编号',
-//                'sczl_yjno' => '印件号',
-//                'sczl_gxh' => '工序号',
-//                'sczl_jtbh' => '机台编号',
-//                '占用机时'
-//            ])
-//            ->select();
-//    }
-//
-//    /**
-//     * 批量更新工单数据
-//     */
-//    protected function batchUpdateWorkOrders($updates, $month)
-//    {
-//        $db = Db::name('成本v23_月度成本明细');
-//
-//        foreach ($updates as $update) {
-//            $sql = $db->where($update['where'])->fetchSql(true)->update($update['data']);
-//            $db->query($sql);
-//        }
-//    }
-//
-//    /**
-//     * 安全数值获取
-//     */
-//    protected function getSafeNumericValue($value)
-//    {
-//        if ($value === null || $value === '' || $value === false) {
-//            return 0;
-//        }
-//        return floatval($value);
-//    }
-
-// app/controller/UnifiedCostController.php
 
     /**
      * 执行成本计算
@@ -637,7 +78,7 @@ class CostCalculation extends Api
         $taskData['task_id'] = $taskId;
 
         // 提交到成本计算队列
-        $jobHandlerClassName = 'app\job\CostCalculationJob';
+        $jobHandlerClassName = 'app\job\UnifiedCostCalculationJob';
         $queueName = 'cost_calculation';
 
         $jobId = Queue::push($jobHandlerClassName, $taskData, $queueName);