unknown 2 mesiacov pred
rodič
commit
917750f3a1

+ 98 - 18
application/api/controller/CostAccounting.php

@@ -440,14 +440,19 @@ class CostAccounting extends Api
         if (empty($param)) {
             $this->error('参数错误');
         }
-        $month = substr($param['month'], 0, 4) . '-' . substr($param['month'], 4, 2);
-        $list = db('设备_产量计酬')
+        $monthArr = db('成本v23_月度成本明细')->where(['sys_ny' => $param['month']])->select();
+        if (empty($monthArr)) {
+            $this->error('请先创建月度数据...');
+        }
+        $sist = ['胶印车间','凹丝印车间','印后车间','检验车间'];
+        $list = db('成本v23_月度成本明细')
             ->alias('a')
             ->join('设备_基本资料 b','a.sczl_jtbh = b.设备编号')
             ->join('工单_工艺资料 c','a.sczl_gdbh = c.Gy0_gdbh and a.sczl_yjno = c.Gy0_yjno and a.sczl_gxh = c.Gy0_gxh')
-            ->field('a.sczl_gdbh,a.sczl_yjno,a.sczl_gxh,a.sczl_jtbh,a.sczl_gxmc,sum(a.sczl_cl) as 产量,a.sczl_jtbh,a.sczl_ms,b.使用部门,
-            sum(a.sczl_设备运行工时) as 通电工时,a.sczl_dedh,c.Gy0_gxmc')
-            ->where('a.sczl_rq','like', $month.'%')
+            ->field('a.sczl_gdbh,a.sczl_yjno,a.sczl_gxh,a.sczl_jtbh,a.工序名称,sum(a.计件产量) as 产量,a.sczl_jtbh,a.sczl_ms,b.使用部门,
+            sum(a.占用机时) as 通电工时,c.Gy0_dedh,c.Gy0_gxmc')
+            ->where('a.sys_ny', $param['month'])
+            ->whereIn('车间名称',$sist)
             ->group('a.sczl_gdbh,a.sczl_yjno,a.sczl_gxh,a.sczl_jtbh')
             ->select();
         if (empty($list)) {
@@ -467,9 +472,9 @@ class CostAccounting extends Api
                 'sczl_yjno' => $v['sczl_yjno'],
                 'sczl_gxh' => $v['sczl_gxh'],
                 'sczl_jtbh' => $v['sczl_jtbh'],
-                'sczl_gxmc' => $v['sczl_gxmc'],
+                'sczl_gxmc' => $v['工序名称'],
                 'sczl_ms' => $v['sczl_ms'],
-                'sczl_dedh' => $v['sczl_dedh'],
+                'sczl_dedh' => $v['Gy0_dedh'],
                 '通电时间' => $v['通电工时'],
                 'sczl_cl' => $v['产量'],
                 '部门' => $v['使用部门'],
@@ -1019,15 +1024,90 @@ class CostAccounting extends Api
 //    }
 
 
-    public function materialRequisition()
-    {
-        if ($this->request->isGet() === false) {
-            $this->error('请求错误');
-        }
-        $param = $this->request->param();
-        if (empty($param)) {
-            $this->error('参数错误');
-        }
-        
-    }
+
+    //查询各月工单数据
+//    public function setMonthWorkOrder()
+//    {
+//        if ($this->request->isGet() === false) {
+//            $this->error('请求错误');
+//        }
+//        $param = $this->request->param();
+//        if (empty($param)) {
+//            $this->error('参数错误');
+//        }
+//        $Printinglist = 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.sczl_cl) as 班组车头产量,b.Gy0_gxmc as 工序名称,
+//            a.sczl_ms as 墨色数,rtrim(c.使用部门) as 使用部门,rtrim(b.印刷方式) as 印刷方式,b.版距,b.工价系数,a.sczl_jtbh,d.yj_yjmc as 印件名称,
+//            sum(a.sczl_设备运行工时) as 占用机时,a.sys_rq as 年月,b.工价系数 as 工序难度系数,b.千件工价')
+//            ->where('a.sys_rq','like',$param['month'].'%')
+//            ->group('a.sczl_gdbh,a.sczl_yjno,a.sczl_gxh,a.sczl_jtbh')
+//            ->select();
+        //查询外发加工、拆片工单
+//        $disassemblingList = db('db_sczl')
+//            ->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.sczl_cl) as 班组车头产量,b.Gy0_gxmc as 工序名称,
+//            a.sczl_ms as 墨色数,rtrim(c.使用部门) as 使用部门,rtrim(b.印刷方式) as 印刷方式,b.版距,b.工价系数,a.sczl_jtbh,d.yj_yjmc as 印件名称,
+//            sum(a.sczl_设备运行工时) as 占用机时,a.sys_rq as 年月,b.工价系数 as 工序难度系数,b.千件工价')
+//            ->where('a.sys_rq','like',$param['month'].'%')
+//            ->group('a.sczl_gdbh,a.sczl_yjno,a.sczl_gxh,a.sczl_jtbh')
+//            ->select();
+        //查询包装工序
+//        $field = 'a.sczl_gdbh1,a.sczl_gdbh2,a.sczl_gdbh3,a.sczl_gdbh4,a.sczl_gdbh5,a.sczl_gdbh6,a.sczl_yjGx1,
+//            a.sczl_yjGx2,a.sczl_yjGx3,a.sczl_yjGx4,a.sczl_yjGx5,a.sczl_yjGx6,a.sczl_cl1,a.sczl_cl2,a.sczl_cl3,a.sczl_cl4,a.sczl_cl5,
+//            a.sczl_cl6,a.sczl_PgCl1,a.sczl_PgCl2,a.sczl_PgCl3,a.sczl_PgCl4,a.sczl_PgCl5,a.sczl_PgCl6';
+//        $PackagingList = db('db_包装计件')
+//            ->alias('a')
+//
+//            ->field($field)
+//            ->where('sczl_rq','like',$param['month'].'%')
+//            ->select();
+//        foreach ($PackagingList as $k => $v) {
+//
+//        }
+//        halt($PackagingList);
+//        $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())
+//            ];
+//        }
+//    }
+
 }

+ 948 - 0
application/api/controller/CostCalculation.php

@@ -1 +1,949 @@
 <?php
+
+
+namespace app\api\controller;
+
+use app\common\controller\Api;
+
+class CostCalculation extends Api
+{
+
+    protected $noNeedLogin = ['*'];
+    protected $noNeedRight = ['*'];
+
+    // 车间常量
+    const WORKSHOP_ROLLER_PRESS = '03、卷凹机组';
+    const WORKSHOP_LIST_ALL = ['凹丝印车间', '胶印车间', '印后车间', '检验车间'];
+
+    // 科目名称关键词
+    const SUBJECT_WASTE_GAS = '废气处理';
+    const SUBJECT_BOILER = '锅炉';
+    const SUBJECT_HOT_WATER_BOILER = '热水锅炉';
+    const SUBJECT_AIR_COMPRESSOR_A = '空压机A';
+    const SUBJECT_AIR_COMPRESSOR_B = '空压机B';
+    const SUBJECT_VACUUM_BLOWER_A = '真空鼓风机A';
+    const SUBJECT_VACUUM_BLOWER_B = '真空鼓风机B';
+    const SUBJECT_CENTRAL_AIR_CONDITIONER_A = '中央空调A';
+    const SUBJECT_CENTRAL_AIR_CONDITIONER_B = '中央空调B';
+    const SUBJECT_TOTAL_TO_APPORTION = '待分摊总额';
+
+    /**
+     * 统一的安全数值获取方法
+     * 处理空字符串和null值,转换为0
+     */
+    protected function getSafeNumericValue($value)
+    {
+        if ($value === null || $value === '' || $value === false) {
+            return 0;
+        }
+        return floatval($value);
+    }
+
+    /**
+     * 安全的金额计算
+     */
+    protected function calculateSafeAmount($quantity, $unitPrice)
+    {
+        $safeQuantity = $this->getSafeNumericValue($quantity);
+        $safeUnitPrice = $this->getSafeNumericValue($unitPrice);
+        return $safeQuantity * $safeUnitPrice;
+    }
+
+    public function costCalculation()
+    {
+        if (!$this->request->isGet()) {
+            $this->error('请求错误');
+        }
+
+        $param = $this->request->param();
+        if (empty($param['month'])) {
+            $this->error('请选择月份');
+        }
+
+        $month = $param['month'];
+
+        // 计算车间水电气分摊(返回统计结果)
+        $apportionmentResults = $this->apportionmentOne($month);
+
+        // 格式化最终结果
+        $formattedResults = $this->formatFinalResults($apportionmentResults,$month,$param['sys_id']);
+        $machine = [];
+        foreach ($formattedResults as $formattedResult) {
+            $machine[] = $formattedResult['设备编号'];
+        }
+        $machineList = array_unique($machine);
+        $machineWorkOrder = [];
+        foreach ($machineList as $machine) {
+            $machineWorkOrder[$machine] = $this->getMachineWorkOrder($machine, $month);
+        }
+
+        $apportionData = db('成本_各月分摊系数')->where(['Sys_ny' => $month])->select();
+        if (!empty($apportionData)) {
+            db('成本_各月分摊系数')->where(['Sys_ny' => $month])->delete();
+        }
+        $apportionSql = db('成本_各月分摊系数')->fetchSql(true)->insertAll($formattedResults);
+        $apportionResults = db()->query($apportionSql);
+
+        //查询车间机台色度数
+        $machineTotal = $this->getMachineTotal($month);
+        $data = [];
+        foreach ($machineWorkOrder as $machineCode => $orders) {
+            // 检查机台编号是否存在于第二个数组中
+            if (!isset($machineTotal[$machineCode])) {
+                continue; // 如果机台在分摊数组中不存在,跳过
+            }
+
+            $machineRates = $machineTotal[$machineCode]; // 获取该机台的费用单价
+
+            // 遍历该机台下的所有工单
+            foreach ($orders as $order) {
+                $occupationHours = (float)$order['占用机时']; // 占用机时
+
+                // 创建新记录(基础信息)
+                $newRecord = [
+                    'sczl_gdbh' => $order['工单编号'],
+                    'sczl_yjno' => $order['印件号'],
+                    'sczl_gxh' => $order['工序号'],
+                    'sczl_jtbh' => $order['机台编号']
+                ];
+
+                // 动态添加所有科目分摊金额(基于第二个数组中的科目名称)
+                foreach ($machineRates as $subject => $rate) {
+                    if ($subject === '待分摊总额') {
+                        $subject = '分摊水电';
+                    }
+                    $newRecord[$subject] = round($occupationHours * $rate, 2);
+                    $newRecord['直接水电'] = round($occupationHours * 0.69, 2);
+                }
+
+                $data[] = $newRecord;
+            }
+        }
+        $i = 0;
+        foreach ($data as $item) {
+            $gdbh = $item['sczl_gdbh'];
+            $yjno = $item['sczl_yjno'];
+            $gxh = $item['sczl_gxh'];
+            $jtbh = $item['sczl_jtbh'];
+            unset($item['sczl_gdbh'], $item['sczl_yjno'], $item['sczl_gxh'], $item['sczl_jtbh']);
+            $sql = db('成本v23_月度成本明细')
+                ->where([
+                    'sys_ny' => $month,
+                    'sczl_gdbh' => $gdbh,
+                    'sczl_yjno' => $yjno,
+                    'sczl_gxh' => $gxh,
+                    'sczl_jtbh' => $jtbh,
+                ])
+                ->fetchSql(true)
+                ->update($item);
+            $res = db()->query($sql);
+            if ($res === false) {
+                $i++;
+            }
+        }
+        if ($i > 0) {
+            $this->error('失败');
+        }
+
+    }
+
+
+    /**
+     * 计算水电气分摊费用(优化版)
+     */
+    protected function apportionmentOne($month)
+    {
+        $utilityList = db('成本_各月水电气')
+            ->where('Sys_ny', $month)
+            ->whereLike('费用类型', '%分摊%')
+            ->select();
+
+        if (empty($utilityList)) {
+            return [];
+        }
+
+        // 初始化统计数据结构
+        $machineSummary = [];        // 按机台统计
+        $subjectSummary = [];        // 按科目统计
+        $workshopSummary = [];       // 按车间统计
+        $apportionmentResults = [];  // 原始分摊结果
+        $allMachineData = [];        // 所有机台数据
+
+        // 先处理所有分摊项目
+        foreach ($utilityList as $item) {
+            // 确保数值安全
+            $item['耗电量'] = $this->getSafeNumericValue($item['耗电量']);
+            $item['单位电价'] = $this->getSafeNumericValue($item['单位电价']);
+            $item['耗气量'] = $this->getSafeNumericValue($item['耗气量']);
+            $item['单位气价'] = $this->getSafeNumericValue($item['单位气价']);
+
+            $result = $this->processUtilityItem($item, $month);
+            if ($result) {
+                $apportionmentResults[] = $result;
+
+                // 合并所有机台数据
+                $this->mergeMachineData($result['data'], $allMachineData, $item['科目名称']);
+            }
+        }
+
+        // 按机台+科目进行汇总统计
+        $this->summarizeByMachineAndSubject($allMachineData, $machineSummary, $subjectSummary, $workshopSummary);
+
+        // 对统计结果进行排序
+        ksort($machineSummary);
+        return $machineSummary;
+    }
+
+    /**
+     * 合并所有机台数据
+     */
+    protected function mergeMachineData($machineData, &$allMachineData, $subjectName)
+    {
+        if (empty($machineData)) {
+            return;
+        }
+
+        foreach ($machineData as $machine) {
+            $machineId = $machine['机台编号'] ?? '';
+            $workshop = $machine['车间名称'] ?? '未知车间';
+            $workOrder = $machine['工单编号'] ?? '';
+            $processNo = $machine['工序号'] ?? '';
+            $printNo = $machine['印件号'] ?? '';
+            $machineTime = floatval($machine['占用机时'] ?? 0);
+            $uniqid = $machine['Uniqid'] ?? '';
+
+            if (empty($machineId)) {
+                continue;
+            }
+
+            // 初始化机台数据
+            if (!isset($allMachineData[$machineId])) {
+                $allMachineData[$machineId] = [
+                    '机台编号' => $machineId,
+                    '车间名称' => $workshop,
+                    '占用机时' => $machineTime,
+                    '工单编号' => $workOrder,
+                    '工序号' => $processNo,
+                    '印件号' => $printNo,
+                    'Uniqid' => $uniqid,
+                    '科目明细' => [],
+                    '工单列表' => [],
+                    '科目总计' => 0
+                ];
+            }
+
+            // 更新机台基础信息(如果有更完整的信息)
+            if (empty($allMachineData[$machineId]['工单编号']) && !empty($workOrder)) {
+                $allMachineData[$machineId]['工单编号'] = $workOrder;
+            }
+            if (empty($allMachineData[$machineId]['工序号']) && !empty($processNo)) {
+                $allMachineData[$machineId]['工序号'] = $processNo;
+            }
+            if (empty($allMachineData[$machineId]['印件号']) && !empty($printNo)) {
+                $allMachineData[$machineId]['印件号'] = $printNo;
+            }
+
+            // 记录工单(去重)
+            if (!empty($workOrder) && !in_array($workOrder, $allMachineData[$machineId]['工单列表'])) {
+                $allMachineData[$machineId]['工单列表'][] = $workOrder;
+            }
+
+            // 合并科目金额
+            $apportionmentTypes = ['分摊水电', '废气处理', '锅炉', '热水锅炉',
+                '空压机A', '空压机B', '真空鼓风机A', '真空鼓风机B',
+                '中央空调A', '中央空调B'];
+
+            $machineTotal = 0;
+            foreach ($apportionmentTypes as $type) {
+                if (isset($machine[$type]) && floatval($machine[$type]) > 0) {
+                    $amount = floatval($machine[$type]);
+                    $machineTotal += $amount;
+
+                    // 初始化科目明细
+                    if (!isset($allMachineData[$machineId]['科目明细'][$type])) {
+                        $allMachineData[$machineId]['科目明细'][$type] = [
+                            'subject_name' => $type,
+                            'total_amount' => 0,
+                            'source_count' => 0,
+                            'source_subjects' => ''
+                        ];
+                    }
+
+                    // 累加金额
+                    $allMachineData[$machineId]['科目明细'][$type]['total_amount'] += $amount;
+                    $allMachineData[$machineId]['科目明细'][$type]['source_count']++;
+
+                    // 记录来源科目
+                    $allMachineData[$machineId]['科目明细'][$type]['source_subjects'] = $subjectName;
+
+                }
+            }
+
+            // 更新机台总计
+            $allMachineData[$machineId]['科目总计'] += $machineTotal;
+        }
+    }
+
+    /**
+     * 按机台+科目进行汇总统计
+     */
+    protected function summarizeByMachineAndSubject($allMachineData, &$machineSummary, &$subjectSummary, &$workshopSummary)
+    {
+        foreach ($allMachineData as $machineId => $machineInfo) {
+            $workshop = $machineInfo['车间名称'];
+
+            // 1. 按机台统计
+            $machineSummary[$machineId] = [
+                '机台编号' => $machineId,
+                '车间名称' => $workshop,
+                '工单数量' => count($machineInfo['工单列表']),
+                '占用机时' => $machineInfo['占用机时'],
+                '科目总计' => round($machineInfo['科目总计'], 2),
+                '科目明细' => [],
+                '工单列表' => $machineInfo['工单列表']
+            ];
+
+            // 处理科目明细
+            foreach ($machineInfo['科目明细'] as $subjectType => $subjectDetail) {
+                $amount = round($subjectDetail['total_amount'], 2);
+                $machineSummary[$machineId]['科目明细'][$subjectType] = [
+                    'amount' => $amount,
+                    'source_count' => $subjectDetail['source_count'],
+                    'source_subjects' => $subjectDetail['source_subjects'],
+                    'percentage' => $machineInfo['科目总计'] > 0
+                        ? round(($subjectDetail['total_amount'] / $machineInfo['科目总计']) * 100, 2)
+                        : 0
+                ];
+            }
+
+            // 2. 按科目统计
+            foreach ($machineInfo['科目明细'] as $subjectType => $subjectDetail) {
+                $amount = round($subjectDetail['total_amount'], 2);
+
+                // 初始化科目统计
+                if (!isset($subjectSummary[$subjectType])) {
+                    $subjectSummary[$subjectType] = [
+                        'subject_name' => $subjectType,
+                        'total_amount' => 0,
+                        'machine_count' => 0,
+                        'workshop_distribution' => [],
+                        'machine_list' => []
+                    ];
+                }
+
+                // 累加科目总计
+                $subjectSummary[$subjectType]['total_amount'] += $subjectDetail['total_amount'];
+                $subjectSummary[$subjectType]['machine_count']++;
+
+                // 按车间分布
+                if (!isset($subjectSummary[$subjectType]['workshop_distribution'][$workshop])) {
+                    $subjectSummary[$subjectType]['workshop_distribution'][$workshop] = 0;
+                }
+                $subjectSummary[$subjectType]['workshop_distribution'][$workshop] += $subjectDetail['total_amount'];
+
+                // 机台列表
+                $subjectSummary[$subjectType]['machine_list'][] = [
+                    'machine_id' => $machineId,
+                    'workshop' => $workshop,
+                    'amount' => $amount,
+                    'percentage' => $subjectSummary[$subjectType]['total_amount'] > 0
+                        ? round(($subjectDetail['total_amount'] / $subjectSummary[$subjectType]['total_amount']) * 100, 2)
+                        : 0
+                ];
+            }
+
+            // 3. 按车间统计
+            if (!isset($workshopSummary[$workshop])) {
+                $workshopSummary[$workshop] = [
+                    'workshop_name' => $workshop,
+                    'machine_count' => 0,
+                    'total_amount' => 0,
+                    'subject_distribution' => [],
+                    'machine_list' => []
+                ];
+            }
+
+            $workshopSummary[$workshop]['machine_count']++;
+            $workshopSummary[$workshop]['total_amount'] += $machineInfo['科目总计'];
+
+            // 车间内科目分布
+            foreach ($machineInfo['科目明细'] as $subjectType => $subjectDetail) {
+                if (!isset($workshopSummary[$workshop]['subject_distribution'][$subjectType])) {
+                    $workshopSummary[$workshop]['subject_distribution'][$subjectType] = 0;
+                }
+                $workshopSummary[$workshop]['subject_distribution'][$subjectType] += $subjectDetail['total_amount'];
+            }
+
+            // 车间内机台列表
+            $workshopSummary[$workshop]['machine_list'][] = [
+                'machine_id' => $machineId,
+                'total_amount' => round($machineInfo['科目总计'], 2),
+                'subject_count' => count($machineInfo['科目明细']),
+                'work_order_count' => count($machineInfo['工单列表'])
+            ];
+        }
+
+        // 对科目统计进行后处理
+        $this->processSubjectSummary($subjectSummary);
+
+        // 对车间统计进行后处理
+        $this->processWorkshopSummary($workshopSummary);
+    }
+
+
+    /**
+     * 处理科目统计
+     */
+    protected function processSubjectSummary(&$subjectSummary)
+    {
+        foreach ($subjectSummary as &$subject) {
+            // 金额四舍五入
+            $subject['total_amount'] = round($subject['total_amount'], 2);
+
+            // 车间分布百分比
+            foreach ($subject['workshop_distribution'] as $workshop => &$amount) {
+                $amount = round($amount, 2);
+            }
+
+            // 按金额排序机台列表
+            usort($subject['machine_list'], function($a, $b) {
+                return $b['amount'] <=> $a['amount'];
+            });
+
+            // 计算机台平均金额
+            $subject['avg_per_machine'] = $subject['machine_count'] > 0
+                ? round($subject['total_amount'] / $subject['machine_count'], 2)
+                : 0;
+        }
+    }
+
+    /**
+     * 处理车间统计
+     */
+    protected function processWorkshopSummary(&$workshopSummary)
+    {
+        foreach ($workshopSummary as &$workshop) {
+            // 金额四舍五入
+            $workshop['total_amount'] = round($workshop['total_amount'], 2);
+
+            // 科目分布百分比
+            $workshop['subject_percentage'] = [];
+            foreach ($workshop['subject_distribution'] as $subjectType => $amount) {
+                $roundedAmount = round($amount, 2);
+                $workshop['subject_distribution'][$subjectType] = $roundedAmount;
+
+                if ($workshop['total_amount'] > 0) {
+                    $workshop['subject_percentage'][$subjectType] =
+                        round(($roundedAmount / $workshop['total_amount']) * 100, 2);
+                }
+            }
+
+            // 按金额排序机台列表
+            usort($workshop['machine_list'], function($a, $b) {
+                return $b['total_amount'] <=> $a['total_amount'];
+            });
+
+            // 计算机台平均金额
+            $workshop['avg_per_machine'] = $workshop['machine_count'] > 0
+                ? round($workshop['total_amount'] / $workshop['machine_count'], 2)
+                : 0;
+
+            // 统计科目种类数
+            $workshop['subject_count'] = count($workshop['subject_distribution']);
+        }
+    }
+
+    /**
+     * 处理单个水电费用项
+     */
+    protected function processUtilityItem($item, $month)
+    {
+        $subjectName = $item['科目名称'];
+
+        // 使用switch-like结构提高可读性
+        $processMap = [
+            self::SUBJECT_TOTAL_TO_APPORTION => 'processTotalApportionment',
+            self::SUBJECT_WASTE_GAS => 'processWasteGas',
+            self::SUBJECT_BOILER => 'processBoiler',
+            self::SUBJECT_AIR_COMPRESSOR_A => 'processAirCompressorA',
+            self::SUBJECT_AIR_COMPRESSOR_B => 'processAirCompressorB',
+            self::SUBJECT_VACUUM_BLOWER_A => 'processVacuumBlowerA',
+            self::SUBJECT_VACUUM_BLOWER_B => 'processVacuumBlowerB',
+            self::SUBJECT_CENTRAL_AIR_CONDITIONER_A => 'processCentralAirConditionerA',
+            self::SUBJECT_CENTRAL_AIR_CONDITIONER_B => 'processCentralAirConditionerB',
+            self::SUBJECT_HOT_WATER_BOILER => 'processHotWaterBoiler',
+        ];
+
+        // 检查是否完全匹配
+        if (isset($processMap[$subjectName])) {
+            $method = $processMap[$subjectName];
+            return $this->$method($item, $month);
+        }
+
+        // 检查是否包含关键词
+        foreach ($processMap as $keyword => $method) {
+            if (strpos($subjectName, $keyword) !== false) {
+                // 特殊处理:如果包含"锅炉"但不包含"热水锅炉"
+                if ($keyword === self::SUBJECT_BOILER && strpos($subjectName, self::SUBJECT_HOT_WATER_BOILER) !== false) {
+                    continue;
+                }
+                return $this->$method($item, $month);
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * 处理待分摊总额
+     */
+    protected function processTotalApportionment($item, $month)
+    {
+        $money = $this->calculateSafeAmount($item['耗电量'], $item['单位电价']);
+        $data = $this->getMachineTime($item['部门名称'], $month);
+
+        foreach ($data['machine'] as &$machine) {
+            $machine['分摊水电'] = $this->calculateApportionment($money, $machine['占用机时'], $data['sist']);
+        }
+
+        return [
+            'type' => 'total_apportionment',
+            'data' => $data['machine']
+        ];
+    }
+
+    /**
+     * 处理废气处理
+     */
+    protected function processWasteGas($item, $month)
+    {
+        $electricityMoney = $this->calculateSafeAmount($item['耗电量'], $item['单位电价']);
+        $gasMoney = $this->calculateSafeAmount($item['耗气量'], $item['单位气价']);
+        $data = $this->getMachineTime(self::WORKSHOP_ROLLER_PRESS, $month);
+
+        foreach ($data['machine'] as &$machine) {
+            $machine['分摊水电'] = $this->calculateApportionment($electricityMoney, $machine['占用机时'], $data['sist']);
+            $machine['废气处理'] = $this->calculateApportionment($gasMoney, $machine['占用机时'], $data['sist']);
+        }
+
+        return [
+            'type' => 'waste_gas',
+            'data' => $data['machine']
+        ];
+    }
+
+    /**
+     * 处理锅炉
+     */
+    protected function processBoiler($item, $month)
+    {
+        $electricityMoney = $this->calculateSafeAmount($item['耗电量'], $item['单位电价']);
+        $gasMoney = $this->calculateSafeAmount($item['耗气量'], $item['单位气价']);
+        $data = $this->getMachineTime(self::WORKSHOP_ROLLER_PRESS, $month);
+
+        foreach ($data['machine'] as &$machine) {
+            $machine['分摊水电'] = $this->calculateApportionment($electricityMoney, $machine['占用机时'], $data['sist']);
+            $machine['锅炉'] = $this->calculateApportionment($gasMoney, $machine['占用机时'], $data['sist']);
+        }
+
+        return [
+            'type' => 'boiler',
+            'data' => $data['machine']
+        ];
+    }
+
+    /**
+     * 处理空压机A
+     */
+    protected function processAirCompressorA($item, $month)
+    {
+        return $this->processGeneralElectricEquipment($item, $month, self::SUBJECT_AIR_COMPRESSOR_A);
+    }
+
+    /**
+     * 处理空压机B
+     */
+    protected function processAirCompressorB($item, $month)
+    {
+        return $this->processGeneralElectricEquipment($item, $month, self::SUBJECT_AIR_COMPRESSOR_B);
+    }
+
+    /**
+     * 处理真空鼓风机A
+     */
+    protected function processVacuumBlowerA($item, $month)
+    {
+        return $this->processGeneralElectricEquipment($item, $month, self::SUBJECT_VACUUM_BLOWER_A);
+    }
+
+    /**
+     * 处理真空鼓风机B
+     */
+    protected function processVacuumBlowerB($item, $month)
+    {
+        return $this->processGeneralElectricEquipment($item, $month, self::SUBJECT_VACUUM_BLOWER_B);
+    }
+
+    /**
+     * 处理中央空调A
+     */
+    protected function processCentralAirConditionerA($item, $month)
+    {
+        return $this->processGeneralElectricEquipment($item, $month, self::SUBJECT_CENTRAL_AIR_CONDITIONER_A);
+    }
+
+    /**
+     * 处理中央空调B
+     */
+    protected function processCentralAirConditionerB($item, $month)
+    {
+        return $this->processGeneralElectricEquipment($item, $month, self::SUBJECT_CENTRAL_AIR_CONDITIONER_B);
+    }
+
+    /**
+     * 处理热水锅炉
+     */
+    protected function processHotWaterBoiler($item, $month)
+    {
+        return $this->processGeneralElectricEquipment($item, $month, '热水锅炉');
+    }
+
+    /**
+     * 通用电气设备处理(适用于所有车间)
+     */
+    protected function processGeneralElectricEquipment($item, $month, $equipmentType)
+    {
+        $money = $this->calculateSafeAmount($item['耗电量'], $item['单位电价']);
+        $data = $this->getMachineTime(self::WORKSHOP_LIST_ALL, $month);
+
+        foreach ($data['machine'] as &$machine) {
+            $machine[$equipmentType] = $this->calculateApportionment($money, $machine['占用机时'], $data['sist']);
+        }
+
+        return [
+            'type' => $equipmentType,
+            'data' => $data['machine']
+        ];
+    }
+
+    /**
+     * 计算分摊金额
+     */
+    protected function calculateApportionment($totalAmount, $machineTime, $totalTime)
+    {
+        if ($totalTime <= 0) {
+            return 0;
+        }
+        return round($totalAmount * ($machineTime / $totalTime), 2);
+    }
+
+    /**
+     * 查询车间机台通电机时数据(优化版)
+     */
+    protected function getMachineTime($workshop, $month)
+    {
+        $where = [
+            'a.sys_ny' => $month,
+            'b.sys_sbID' => ['<>','']
+        ];
+
+        // 构建车间查询条件
+        if (is_array($workshop)) {
+            $where['a.车间名称'] = ['in', $workshop];
+        } else {
+            if (strpos($workshop, '机组') !== false) {
+                $where['b.设备编组'] = $workshop;
+            } elseif (strpos($workshop, '车间') !== false) {
+                $where['a.车间名称'] = $workshop;
+            }
+        }
+
+        // 查询机台数据
+        $machine = db('成本v23_月度成本明细')
+            ->alias('a')
+            ->join('设备_基本资料 b', 'a.sczl_jtbh = b.设备编号', 'left')
+            ->field('rtrim(车间名称) as 车间名称,a.sczl_gdbh as 工单编号,a.sczl_yjno as 印件号,a.sczl_gxh as 工序号,a.sczl_jtbh as 机台编号,a.占用机时,a.Uniqid')
+            ->where($where)
+            ->select();
+
+        // 查询总时长
+        $totalTime = db('成本v23_月度成本明细')
+            ->alias('a')
+            ->join('设备_基本资料 b', 'a.sczl_jtbh = b.设备编号', 'left')
+            ->where($where)
+            ->value('sum(a.占用机时) as 占用机时', 0);
+
+        return [
+            'machine' => $machine,
+            'sist' => $totalTime
+        ];
+    }
+
+
+    /**
+     * 统计分摊结果
+     */
+    protected function summarizeApportionment($result, $department, $subject,
+                                              &$summaryByDepartment, &$summaryBySubject,
+                                              &$summaryByDepartmentSubject)
+    {
+        $resultType = $result['type'];
+        $machineData = $result['data'];
+
+        if (empty($machineData)) {
+            return;
+        }
+
+        // 清洗部门名称
+        $cleanDepartment = trim($department);
+        $cleanSubject = trim($subject);
+
+        // 初始化统计键
+        if (!isset($summaryByDepartment[$cleanDepartment])) {
+            $summaryByDepartment[$cleanDepartment] = [];
+        }
+        if (!isset($summaryBySubject[$resultType])) {
+            $summaryBySubject[$resultType] = [];
+        }
+        if (!isset($summaryByDepartmentSubject[$cleanDepartment])) {
+            $summaryByDepartmentSubject[$cleanDepartment] = [];
+        }
+        if (!isset($summaryByDepartmentSubject[$cleanDepartment][$resultType])) {
+            $summaryByDepartmentSubject[$cleanDepartment][$resultType] = [
+                'department' => $cleanDepartment,
+                'subject' => $cleanSubject,
+                'result_type' => $resultType,
+                'total_amount' => 0,
+                'machine_count' => 0,
+                'work_order_count' => 0
+            ];
+        }
+
+        // 按车间和机台统计
+        foreach ($machineData as $machine) {
+            // 获取车间名称(已使用rtrim清洗过)
+            $workshop = isset($machine['车间名称']) ? $machine['车间名称'] : '未知车间';
+
+            // 统计按部门
+            if (!isset($summaryByDepartment[$cleanDepartment][$workshop])) {
+                $summaryByDepartment[$cleanDepartment][$workshop] = [
+                    'total_amount' => 0,
+                    'machine_count' => 0,
+                    'subjects' => []
+                ];
+            }
+
+            // 统计按科目
+            if (!isset($summaryBySubject[$resultType][$workshop])) {
+                $summaryBySubject[$resultType][$workshop] = [
+                    'total_amount' => 0,
+                    'machine_count' => 0,
+                    'departments' => []
+                ];
+            }
+
+            // 计算此机台的总分摊金额
+            $machineTotal = 0;
+            $apportionmentTypes = ['分摊水电', '废气处理', '锅炉', '热水锅炉',
+                '空压机A', '空压机B', '真空鼓风机A', '真空鼓风机B',
+                '中央空调A', '中央空调B'];
+
+            foreach ($apportionmentTypes as $type) {
+                if (isset($machine[$type])) {
+                    $amount = floatval($machine[$type]);
+                    $machineTotal += $amount;
+
+                    // 按部门+车间统计各科目金额
+                    if (!isset($summaryByDepartment[$cleanDepartment][$workshop]['subjects'][$type])) {
+                        $summaryByDepartment[$cleanDepartment][$workshop]['subjects'][$type] = 0;
+                    }
+                    $summaryByDepartment[$cleanDepartment][$workshop]['subjects'][$type] += $amount;
+
+                    // 按科目+车间统计各部门金额
+                    if (!in_array($cleanDepartment, $summaryBySubject[$resultType][$workshop]['departments'])) {
+                        $summaryBySubject[$resultType][$workshop]['departments'][] = $cleanDepartment;
+                    }
+                }
+            }
+
+            // 更新统计信息
+            if ($machineTotal > 0) {
+                $summaryByDepartment[$cleanDepartment][$workshop]['total_amount'] += $machineTotal;
+                $summaryByDepartment[$cleanDepartment][$workshop]['machine_count']++;
+
+                $summaryBySubject[$resultType][$workshop]['total_amount'] += $machineTotal;
+                $summaryBySubject[$resultType][$workshop]['machine_count']++;
+
+                $summaryByDepartmentSubject[$cleanDepartment][$resultType]['total_amount'] += $machineTotal;
+                $summaryByDepartmentSubject[$cleanDepartment][$resultType]['machine_count']++;
+
+                // 统计工单数(去重)
+                if (!isset($summaryByDepartmentSubject[$cleanDepartment][$resultType]['work_orders'])) {
+                    $summaryByDepartmentSubject[$cleanDepartment][$resultType]['work_orders'] = [];
+                }
+                if (isset($machine['工单编号'])) {
+                    $summaryByDepartmentSubject[$cleanDepartment][$resultType]['work_orders'][] = $machine['工单编号'];
+                }
+            }
+        }
+
+        // 计算工单数(去重)
+        foreach ($summaryByDepartmentSubject[$cleanDepartment] as $type => &$data) {
+            if (isset($data['work_orders'])) {
+                $data['work_order_count'] = count(array_unique($data['work_orders']));
+                unset($data['work_orders']);
+            }
+        }
+
+        // 为部门统计添加汇总信息
+        $this->addSummaryToDepartment($summaryByDepartment[$cleanDepartment]);
+
+        // 为科目统计添加汇总信息
+        $this->addSummaryToSubject($summaryBySubject[$resultType]);
+    }
+
+
+    /**
+     * 为部门统计添加汇总信息
+     */
+    protected function addSummaryToDepartment(&$departmentData)
+    {
+        $totalAmount = 0;
+        $totalMachines = 0;
+
+        foreach ($departmentData as $workshop => $data) {
+            if ($workshop === 'summary') continue;
+
+            $totalAmount += $data['total_amount'];
+            $totalMachines += $data['machine_count'];
+        }
+
+        $departmentData['summary'] = [
+            'total_amount' => round($totalAmount, 2),
+            'total_machines' => $totalMachines,
+            'workshop_count' => count($departmentData) - 1
+        ];
+    }
+
+    /**
+     * 为科目统计添加汇总信息
+     */
+    protected function addSummaryToSubject(&$subjectData)
+    {
+        $totalAmount = 0;
+        $totalMachines = 0;
+        $allDepartments = [];
+
+        foreach ($subjectData as $workshop => $data) {
+            if ($workshop === 'summary') continue;
+
+            $totalAmount += $data['total_amount'];
+            $totalMachines += $data['machine_count'];
+            $allDepartments = array_merge($allDepartments, $data['departments']);
+        }
+
+        $subjectData['summary'] = [
+            'total_amount' => round($totalAmount, 2),
+            'total_machines' => $totalMachines,
+            'workshop_count' => count($subjectData) - 1,
+            'department_count' => count(array_unique($allDepartments))
+        ];
+    }
+
+
+    /**
+     * 格式化最终统计结果
+     */
+    protected function formatFinalResults($apportionmentResults,$month,$sys)
+    {
+        $data = [];
+        foreach ($apportionmentResults as $key => $value) {
+            foreach ($value['科目明细'] as $item) {
+                $data[] = [
+                    'Sys_ny' => $month,
+                    '科目名称' => $item['source_subjects'],
+                    '设备编号' => $key,
+                    '分摊系数' => 1,
+                    '分摊金额' => $item['amount'],
+                    'Sys_id' => $sys,
+                    'Sys_rq' => date('Y-m-d H:i:s',time()),
+                ];
+            }
+        }
+        return $data;
+    }
+
+    /**
+     * 获取车间机台生产工单
+     * @param $sist
+     * @param $month
+     * @return bool|\PDOStatement|string|\think\Collection
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
+    protected function getMachineWorkOrder($machine,$month)
+    {
+        $list = db('成本v23_月度成本明细')
+            ->where([
+                'sys_ny' => $month,
+                'sczl_jtbh' => $machine,
+                ])
+            ->field([
+                'sczl_gdbh' => '工单编号',
+                'sczl_yjno' => '印件号',
+                'sczl_gxh' => '工序号',
+                'sczl_jtbh' => '机台编号',
+                '占用机时',
+                ])
+            ->group('工单编号,印件号,工序号')
+            ->select();
+        return $list;
+    }
+
+    /**
+     * 查询车间机台色度数
+     * @param $month
+     * @return bool|\PDOStatement|string|\think\Collection
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
+    protected function getMachineTotal($month)
+    {
+        $list = db('成本_各月分摊系数')
+            ->alias('a')
+            ->join('成本v23_月度成本明细 b', 'b.sys_ny = a.Sys_ny and b.sczl_jtbh = a.设备编号','LEFT')
+            ->where([
+                'a.Sys_ny' => $month,
+                'b.车间名称' => ['in', self::WORKSHOP_LIST_ALL],
+                ])
+            ->field([
+                'b.sczl_jtbh' => '机台编号',
+                'sum(b.占用机时)' => '占用机时',
+                'a.分摊金额',
+                'a.科目名称',
+            ])
+            ->group('机台编号,a.科目名称')
+            ->select();
+        foreach ($list as $key => $item) {
+            $list[$key]['金额'] = round($item['分摊金额']/$item['占用机时'], 2);
+        }
+        $data = [];
+        foreach ($list as $item) {
+            $machineCode = $item['机台编号'];
+            $subjectName = explode('(',$item['科目名称']);
+            $amount = $item['金额'];
+
+            // 如果这个机台编号还没有在结果数组中,初始化它
+            if (!isset($data[$machineCode])) {
+                $data[$machineCode] = [];
+            }
+
+            // 将科目名称和金额添加到对应的机台编号下
+            $data[$machineCode][$subjectName[0]] = $amount;
+        }
+        return $data;
+    }
+
+}