cqp 13 ore în urmă
părinte
comite
32c6a2d2a4
3 a modificat fișierele cu 183 adăugiri și 660 ștergeri
  1. 64 3
      app/Exports/ExportOrder2.php
  2. 0 160
      app/Service/ExportFileService.php
  3. 119 497
      app/Service/StatisticsService.php

+ 64 - 3
app/Exports/ExportOrder2.php

@@ -436,6 +436,10 @@ class ExportOrder2 extends DefaultValueBinder implements WithCustomValueBinder ,
                 $sheet->mergeCells('A8:A32');
                 $sheet->setCellValue('A8', '销售支出');
 
+                // --- 新增:利润区域合并 ---
+                $sheet->mergeCells('A33:A38');
+                $sheet->setCellValue('A33', '利润');
+
                 $items = [
                     5  => "收入",
                     6  => "成本",
@@ -465,6 +469,12 @@ class ExportOrder2 extends DefaultValueBinder implements WithCustomValueBinder ,
                     30 => "其他(3)为后续准备",
                     31 => "其他(4)为后续准备",
                     32 => "销售支出小计",
+                    33 => "实际利润",
+                    34 => "公司确定收入(加)",
+                    35 => "公司确定支出(减)",
+                    36 => "",
+                    37 => "",
+                    38 => "净利润",
                 ];
 
                 foreach ($items as $rowNum => $text) {
@@ -475,7 +485,7 @@ class ExportOrder2 extends DefaultValueBinder implements WithCustomValueBinder ,
                 // 4. 样式设置
                 // ==========================
                 $lastCol = 'Z';
-                $sheet->getStyle("A1:{$lastCol}32")
+                $sheet->getStyle("A1:{$lastCol}38")
                     ->getAlignment()
                     ->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER)
                     ->setVertical(\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER)
@@ -493,7 +503,7 @@ class ExportOrder2 extends DefaultValueBinder implements WithCustomValueBinder ,
                 // ==========================
                 // 假设 $this->data 是一个二维数组,每一行代表从 C 列到 Z 列的值
                 $dataRowIndex = 0;
-                for ($row = 5; $row <= 32; $row++) {
+                for ($row = 5; $row <= 38; $row++) {
                     $rowValues = $this->data[$dataRowIndex] ?? [];
                     $colIndex = 0;
                     // 从 C (Index 3) 到 Z (Index 26)
@@ -505,6 +515,48 @@ class ExportOrder2 extends DefaultValueBinder implements WithCustomValueBinder ,
                     }
                     $dataRowIndex++;
                 }
+
+//                $dataRowIndex = 0;
+//                for ($row = 5; $row <= 38; $row++) {
+//                    $rowValues = $this->data[$dataRowIndex] ?? [];
+//                    $colIndex = 0;
+//
+//                    for ($col = 3; $col <= 26; $col++) { // C 到 Z
+//                        $colLetter = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($col);
+//
+//                        // 判定是否为公式行
+//                        if ($row == 7) {
+//                            // 毛利 = 收入 - 成本 (修正了多余的括号)
+//                            $sheet->setCellValue($colLetter . $row, "={$colLetter}5-{$colLetter}6");
+//                        } elseif ($row == 32) {
+//                            // 销售支出小计: 8 到 31 行
+//                            $sheet->setCellValue($colLetter . $row, "=SUM({$colLetter}8:{$colLetter}31)");
+//                        } elseif ($row == 33) {
+//                            // 实际利润: 毛利(7) - 支出小计(32)
+//                            $sheet->setCellValue($colLetter . $row, "={$colLetter}7-{$colLetter}32");
+//                        } elseif ($row == 38) {
+//                            // 净利润: 实际利润(33) + 收入(34) - 支出(35)
+//                            $sheet->setCellValue($colLetter . $row, "={$colLetter}33+{$colLetter}34-{$colLetter}35");
+//                        } else {
+//                            // 【重要】普通数据行填充
+//                            $val = $rowValues[$colIndex] ?? 0;
+//
+//                            if (is_numeric($val) && $val != 0) {
+//                                // 强制转为数值,否则 SUM 公式可能识别为文本导致结果为 0
+//                                $sheet->setCellValueExplicit(
+//                                    $colLetter . $row,
+//                                    (float)$val,
+//                                    \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_NUMERIC
+//                                );
+//                            } else {
+//                                // 值为 0 或非数字时
+//                                $sheet->setCellValue($colLetter . $row, $val);
+//                            }
+//                        }
+//                        $colIndex++; // 确保每处理一列,索引+1
+//                    }
+//                    $dataRowIndex++; // 确保每处理一行,索引+1
+//                }
             },
         ];
     }
@@ -613,6 +665,9 @@ class ExportOrder2 extends DefaultValueBinder implements WithCustomValueBinder ,
                 $sheet->mergeCells('A9:A33');
                 $sheet->setCellValue('A9', '销售支出');
 
+                $sheet->mergeCells('A34:A39');
+                $sheet->setCellValue('A34', '利润');
+
                 $items = [
                     5  => "回款销售收入",
                     6  => "票扣费用(返利、调整等)",
@@ -643,6 +698,12 @@ class ExportOrder2 extends DefaultValueBinder implements WithCustomValueBinder ,
                     31 => "其他(3)为后续准备",
                     32 => "其他(4)为后续准备",
                     33 => "销售支出小计",
+                    34 => "实际利润",
+                    35 => "公司确定收入(加)",
+                    36 => "公司确定支出(减)",
+                    37 => "",
+                    38 => "",
+                    39 => "开票净利润",
                 ];
 
                 foreach ($items as $rowNum => $text) {
@@ -653,7 +714,7 @@ class ExportOrder2 extends DefaultValueBinder implements WithCustomValueBinder ,
                 // 4. 样式设置
                 // ==========================
                 $lastCol = 'AB';
-                $sheet->getStyle("A1:{$lastCol}33")
+                $sheet->getStyle("A1:{$lastCol}39")
                     ->getAlignment()
                     ->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER)
                     ->setVertical(\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER)

+ 0 - 160
app/Service/ExportFileService.php

@@ -375,166 +375,6 @@ class ExportFileService extends Service
         return [true, $this->saveExportData2($return)];
     }
 
-    public function eveold($ergs,$user){
-        $service = new StatisticsService();
-        $result = $service->getChannelReport($ergs);
-        if(empty($result)) return [false, '暂无数据'];
-
-        $title = array_column($result,'channel');
-        if(empty($title)) return [false, '暂无数据'];
-
-        // 2. 字段顺序(22 个)
-        $fieldOrder = [
-            'receipt_amount',
-            'cost',
-            'profit',
-            'settle_amount',
-            'gl_amount',
-            'wl_amount',
-            'ht_amount',
-            'zk_amount',
-            'cx_amount',
-            'tg_amount',
-            'cl_amount',
-            'kq_amount',
-            'zp_amount',
-            'gg_amount',
-            'kd_amount',
-            'xsqt_amount',
-            'ry_amount',
-            'sb_amount',
-            'amount1',
-            'sj_amount',
-            'amount2',
-            'total'
-        ];
-
-        // 3. 构建 channel => data 的映射,方便查找
-        $channelDataMap = [];
-        foreach ($result as $item) {
-            $channelDataMap[$item['channel']] = [
-                'monthly' => $item['monthly'],
-                'cumulative' => $item['cumulative']
-            ];
-        }
-
-        // 4. 按字段逐行构建 $data
-        $data = [];
-        foreach ($fieldOrder as $field) {
-            $row = [];
-            $m_fin = $c_fin = 0;
-            foreach ($title as $channel) {
-                $m = $channelDataMap[$channel]['monthly'][$field] ?? '0.00000';
-                $c = $channelDataMap[$channel]['cumulative'][$field] ?? '0.00000';
-                $row[] = $m;
-                $row[] = $c;
-                $m_fin = bcadd($m_fin, $m,2);
-                $c_fin = bcadd($c_fin, $c,2);
-            }
-            $row[] = $m_fin;
-            $row[] = $c_fin;
-            $data[] = $row;
-        }
-        $title[] = '合计';
-
-        $export = new ExportOrder2($data,'jc',[]);
-        $export->mergeStart = 'D';
-
-        $numChannels = count($title);
-        $totalColumns = $numChannels * 2;
-        $endColumnIndex = 3 + $totalColumns - 1; // D is index 3
-        $export->mergeEnd = $this->numberToExcelColumn($endColumnIndex);
-//        $export->mergeEnd = 'AC';
-        $export->mergeTitles = $title;
-
-        if(empty($file_name)) $file_name = self::$filename . "_". date("Y-m-d") . "_". rand(1000,9999);
-        $filename =  $file_name . '.' . 'xlsx';
-        $bool = Excel::store($export,"/public/export/{$filename}", null, 'Xlsx', []);
-
-        return [true, $filename];
-    }
-
-    public function twlold($ergs,$user){
-        $service = new StatisticsService();
-        $result = $service->getChannelReportRoad($ergs);
-        if(empty($result)) return [false, '暂无数据'];
-
-        $title_type = array_column($result,'channel');
-        if(empty($title_type)) return [false, '暂无数据'];
-        $title = [];
-        foreach ($title_type as $value){
-            $title[] = ItemReportRoad::$order_type[$value];
-        }
-
-        // 2. 字段顺序(22 个)
-        $fieldOrder = [
-            'receipt_amount',
-            'cost',
-            'profit',
-            'settle_amount',
-            'gl_amount',
-            'wl_amount',
-            'ht_amount',
-            'zk_amount',
-            'cx_amount',
-            'tg_amount',
-            'cl_amount',
-            'kq_amount',
-            'zp_amount',
-            'gg_amount',
-            'kd_amount',
-            'xsqt_amount',
-            'ry_amount',
-            'sb_amount',
-            'amount1',
-            'sj_amount',
-            'amount2',
-            'total'
-        ];
-
-        // 3. 构建 channel => data 的映射,方便查找
-        $channelDataMap = [];
-        foreach ($result as $item) {
-            $channelDataMap[$item['channel']] = [
-                'monthly' => $item['monthly'],
-                'cumulative' => $item['cumulative']
-            ];
-        }
-
-        // 4. 按字段逐行构建 $data
-        $data = [];
-        foreach ($fieldOrder as $field) {
-            $row = [];
-            $m_fin = $c_fin = 0;
-            foreach ($title_type as $channel) {
-                $m = $channelDataMap[$channel]['monthly'][$field] ?? '0.00000';
-                $c = $channelDataMap[$channel]['cumulative'][$field] ?? '0.00000';
-                $row[] = $m;
-                $row[] = $c;
-                $m_fin = bcadd($m_fin, $m,2);
-                $c_fin = bcadd($c_fin, $c,2);
-            }
-            $row[] = $m_fin;
-            $row[] = $c_fin;
-            $data[] = $row;
-        }
-        $title[] = '合计';
-
-        $export = new ExportOrder2($data,'jc2',[]);
-        $export->mergeStart = 'D';
-        $numChannels = count($title);
-        $totalColumns = $numChannels * 2;
-        $endColumnIndex = 3 + $totalColumns - 1; // D is index 3
-        $export->mergeEnd = $this->numberToExcelColumn($endColumnIndex);
-        $export->mergeTitles = $title;
-
-        if(empty($file_name)) $file_name = self::$filename . "_". date("Y-m-d") . "_". rand(1000,9999);
-        $filename =  $file_name . '.' . 'xlsx';
-        $bool = Excel::store($export,"/public/export/{$filename}", null, 'Xlsx', []);
-
-        return [true, $filename];
-    }
-
     public function eve($ergs,$user){
         $service = new StatisticsService();
         $result = $service->getChannelReportItem($ergs); // 得到 5 - 33 行的二维数组

+ 119 - 497
app/Service/StatisticsService.php

@@ -950,448 +950,7 @@ class StatisticsService extends Service
         return $data;
     }
 
-    public function getChannelReport($data)
-    {
-        if(empty($data['order_time'])) return [false, '年月不能为空'];
-        $yearMonth = $data['order_time'];
-
-        // 1. 解析输入
-        [$year, $month] = explode('-', $yearMonth);
-        $year = (int)$year;
-        $month = (int)$month;
-
-        $currentMonthTs = mktime(0, 0, 0, $month, 1, $year);
-        $yearStartTs = mktime(0, 0, 0, 1, 1, $year);
-
-        // 2. 获取所有相关数据
-        $records = DB::table('item_report')
-            ->whereBetween('time', [$yearStartTs, $currentMonthTs])
-            ->whereNotNull('channel_details') // 可选:排除空渠道
-            ->get();
-
-        // 3. 初始化结果容器
-        $channels = [];
-
-        foreach ($records as $record) {
-            $channel = $record->channel_details;
-
-            if (!isset($channels[$channel])) {
-                // 初始化当月和累计
-                $channels[$channel] = [
-                    'monthly' => array_fill_keys($this->getAmountFieldNames(), 0),
-                    'cumulative' => array_fill_keys($this->getAmountFieldNames(), 0),
-                ];
-            }
-
-            // 判断是否是当月
-            $isCurrentMonth = ($record->time == $currentMonthTs);
-
-            // 累加所有字段(包括 NULL 处理)
-            foreach ($this->getAmountFieldNames() as $field) {
-                $value = $record->$field ?? 0;
-                $channels[$channel]['cumulative'][$field] += $value;
-                if ($isCurrentMonth) {
-                    $channels[$channel]['monthly'][$field] += $value;
-                }
-            }
-        }
-
-        // 4. 插入 amount1 和 amount2,并格式化输出
-        $finalResult = [];
-        foreach ($channels as $channel => $data) {
-            $finalResult[] = [
-                'channel' => $channel,
-                'monthly' => $this->injectAmount1And2($data['monthly']),
-                'cumulative' => $this->injectAmount1And2($data['cumulative']),
-            ];
-        }
-
-        return $finalResult;
-    }
-
-    private function getAmountFieldNames()
-    {
-        return [
-            'receipt_amount',
-            'cost',
-            'profit',
-            'settle_amount',
-            'gl_amount',
-            'wl_amount',
-            'ht_amount',
-            'zk_amount',
-            'cx_amount',
-            'tg_amount',
-            'cl_amount',
-            'kq_amount',
-            'zp_amount',
-            'gg_amount',
-            'kd_amount',
-            'xsqt_amount',
-            'ry_amount',
-            'sb_amount',
-            'sj_amount', // 注意:包含 sj_amount
-        ];
-    }
-
-    private function injectAmount1And2($data)
-    {
-        $result = [];
-        $expenseFields = [
-            'settle_amount',
-            'gl_amount',
-            'wl_amount',
-            'ht_amount',
-            'zk_amount',
-            'cx_amount',
-            'tg_amount',
-            'cl_amount',
-            'kq_amount',
-            'zp_amount',
-            'gg_amount',
-            'kd_amount',
-            'xsqt_amount',
-            'ry_amount',
-            'sb_amount',
-            'sj_amount', // 注意:sj_amount 要包含
-        ];
-
-        // 第一步:按顺序构建带 amount1/2 的数组
-        foreach ($data as $key => $value) {
-            if ($key === 'sj_amount') {
-                $result['amount1'] = '0.00';
-                $result['sj_amount'] = number_format($value, 2, '.', '');
-                $result['amount2'] = '0.00';
-            } else {
-                $result[$key] = number_format($value, 2, '.', '');
-            }
-        }
-
-        // 第二步:计算 total(仅 expenseFields 中的字段,从 $data 原始值取,避免字符串运算)
-        $total = 0;
-        foreach ($expenseFields as $field) {
-            $val = $data[$field] ?? 0;
-            $total += is_numeric($val) ? (float)$val : 0;
-        }
-
-        $result['total'] = number_format($total, 2, '.', '');
-
-        return $result;
-    }
-
-    public function getChannelReportRoad($data)
-    {
-        if(empty($data['order_time'])) return [false, '年月不能为空'];
-        $yearMonth = $data['order_time'];
-
-        // 1. 解析输入
-        [$year, $month] = explode('-', $yearMonth);
-        $year = (int)$year;
-        $month = (int)$month;
-
-        $currentMonthTs = mktime(0, 0, 0, $month, 1, $year);
-        $yearStartTs = mktime(0, 0, 0, 1, 1, $year);
-
-        // 2. 获取所有相关数据
-        $records = DB::table('item_report_road')
-            ->whereBetween('time', [$yearStartTs, $currentMonthTs])
-            ->whereNotNull('employee_title_type') //
-            ->get();
-
-        // 3. 初始化结果容器
-        $channels = [];
-
-        foreach ($records as $record) {
-            $channel = $record->employee_title_type;
-
-            if (!isset($channels[$channel])) {
-                // 初始化当月和累计
-                $channels[$channel] = [
-                    'monthly' => array_fill_keys($this->getAmountFieldNames(), 0),
-                    'cumulative' => array_fill_keys($this->getAmountFieldNames(), 0),
-                ];
-            }
-
-            // 判断是否是当月
-            $isCurrentMonth = ($record->time == $currentMonthTs);
-
-            // 累加所有字段(包括 NULL 处理)
-            foreach ($this->getAmountFieldNames() as $field) {
-                $value = $record->$field ?? 0;
-                $channels[$channel]['cumulative'][$field] += $value;
-                if ($isCurrentMonth) {
-                    $channels[$channel]['monthly'][$field] += $value;
-                }
-            }
-        }
-
-        // 4. 插入 amount1 和 amount2,并格式化输出
-        $finalResult = [];
-        foreach ($channels as $channel => $data) {
-            $finalResult[] = [
-                'channel' => $channel,
-                'monthly' => $this->injectAmount1And2($data['monthly']),
-                'cumulative' => $this->injectAmount1And2($data['cumulative']),
-            ];
-        }
-
-        return $finalResult;
-    }
-
-    private function getAmountFieldManNames()
-    {
-        return [
-            'receipt_amount', 'receipt_not_amount', 'cost', 'profit', 'profit_not',
-            'settle_amount', 'gl_amount', 'gl_not_amount', 'wl_amount', 'wl_not_amount',
-            'ht_amount', 'zk_amount', 'cx_amount', 'tg_amount', 'cl_amount',
-            'kq_amount', 'zp_amount', 'gg_amount', 'kd_amount', 'xsqt_amount',
-            'ry_amount', 'sb_amount', 'sj_amount', 'sj_not_amount', 'sx_amount',
-            'sx_not_amount', 'other_ck_amount', 'cg_amount'
-        ];
-    }
-
-    private function injectAmountMan($data)
-    {
-        $result = [];
-        // 参与 total 计算的费用字段 (排除收入、成本和利润)
-        $expenseFields = [
-            'settle_amount', 'gl_amount', 'gl_not_amount', 'wl_amount', 'wl_not_amount',
-            'ht_amount', 'zk_amount', 'cx_amount', 'tg_amount', 'cl_amount',
-            'kq_amount', 'zp_amount', 'gg_amount', 'kd_amount', 'xsqt_amount',
-            'ry_amount', 'sb_amount', 'sj_amount', 'sj_not_amount', 'sx_amount',
-            'sx_not_amount', 'other_ck_amount', 'cg_amount'
-        ];
-
-        // 第一步:格式化并插入占位符
-        foreach ($this->getAmountFieldManNames() as $key) {
-            $val = $data[$key] ?? 0;
-
-            if ($key === 'sj_amount') {
-                $result['amount1'] = '0.00'; // 占位
-                $result['sj_amount'] = number_format((float)$val, 2, '.', '');
-                $result['amount2'] = '0.00'; // 占位
-            } else {
-                $result[$key] = number_format((float)$val, 2, '.', '');
-            }
-        }
-
-        // 第二步:计算费用总额
-        $total = 0;
-        foreach ($expenseFields as $field) {
-            $total += (float)($data[$field] ?? 0);
-        }
-        $result['total'] = number_format($total, 2, '.', '');
-
-        return $result;
-    }
-
     public function getChannelReportMan1($data)
-    {
-        if(empty($data['order_time'])) return [false, '年月不能为空'];
-        $yearMonth = $data['order_time']; // 格式如 2026-02
-
-        [$year, $month] = explode('-', $yearMonth);
-        $year = (int)$year;
-        $month = (int)$month;
-
-        // 当前选择月的第一天戳
-        $currentMonthTs = mktime(0, 0, 0, $month, 1, $year);
-        // 去年7月1日的时间戳 (例如输入2026-02,则起始为2025-07-01)
-        $startTs = mktime(0, 0, 0, 7, 1, $year - 1);
-
-        // 从业务员报表获取数据
-        $records = DB::table('item_report_man')
-            ->whereBetween('time', [$startTs, $currentMonthTs])
-            ->get();
-
-        $channels = [];
-        $allFields = $this->getAmountFieldManNames();
-
-        foreach ($records as $record) {
-            // 以渠道财务分组
-            $channel = $record->channel_finance ?: '未知渠道';
-
-            if (!isset($channels[$channel])) {
-                $channels[$channel] = [
-                    'monthly'    => array_fill_keys($allFields, 0),
-                    'cumulative' => array_fill_keys($allFields, 0),
-                ];
-            }
-
-            $isCurrentMonth = ((int)$record->time === $currentMonthTs);
-
-            foreach ($allFields as $field) {
-                $val = (float)($record->$field ?? 0);
-                // 累计去年7月至今
-                $channels[$channel]['cumulative'][$field] += $val;
-                // 仅当月
-                if ($isCurrentMonth) {
-                    $channels[$channel]['monthly'][$field] += $val;
-                }
-            }
-        }
-
-        $finalResult = [];
-        foreach ($channels as $channelName => $values) {
-            $finalResult[] = [
-                'channel'    => $channelName,
-                'monthly'    => $this->injectAmountMan($values['monthly']),
-                'cumulative' => $this->injectAmountMan($values['cumulative']),
-            ];
-        }
-
-        return $finalResult;
-    }
-
-    public function getChannelReportMan2($data)
-    {
-        if (empty($data['order_time'])) return [false, '年月不能为空'];
-        $yearMonth = $data['order_time'];
-
-        [$year, $month] = explode('-', $yearMonth);
-        $year = (int)$year;
-        $month = (int)$month;
-
-        // 1. 计算时间范围
-        $currentMonthTs = mktime(0, 0, 0, $month, 1, $year);
-        // 财年规则:如果当前月 >= 7月,起始是当年7月;否则是去年7月
-        $startYear = ($month >= 7) ? $year : $year - 1;
-        $startTs = mktime(0, 0, 0, 7, 1, $startYear);
-
-        // 2. 一次性获取所有相关记录
-        $records = DB::table('item_report_man')
-            ->whereBetween('time', [$startTs, $currentMonthTs])
-            ->get();
-
-        // 3. 定义金额字段(按 B5-B27 的顺序排列,方便后面直接填充 row)
-        $rowFieldMapping = [
-            5  => 'receipt_amount',   6  => 'cost',            7  => 'profit',
-            8  => 'settle_amount',    9  => 'gl_amount',       10 => 'wl_amount',
-            11 => 'ht_amount',        12 => 'zk_amount',       13 => 'cx_amount',
-            14 => 'tg_amount',        15 => 'cl_amount',       16 => 'kq_amount',
-            17 => 'zp_amount',        18 => 'gg_amount',       19 => 'kd_amount',
-            20 => 'xsqt_amount',      21 => 'ry_amount',       22 => 'sb_amount',
-            23 => '退货亏损',          24 => 'cg_amount',       25 => 'sj_amount',
-            26 => 'sx_amount',        27 => 'other_ck_amount'
-        ];
-
-        // 4. 初始化列容器(C到Z)
-        $columns = [];
-        $columnKeys = range('C', 'Z');
-        foreach ($columnKeys as $col) {
-            $columns[$col] = array_fill(5, 28, 0); // 5-32行,初始化为0
-        }
-
-        // 5. 遍历分拣数据
-        foreach ($records as $record) {
-            $empId = (int)$record->employee_id_1;
-            $finance = $record->channel_finance;
-            $isCurrent = ((int)$record->time === $currentMonthTs);
-
-            foreach ($rowFieldMapping as $rowIdx => $field) {
-                $val = (float)($record->$field ?? 0);
-
-                // 规则分拣 (C, D, G, H, K, L, O, Q, R, U, W)
-                // C: 2+社区
-                if ($empId === 2 && $finance === '社区') {
-                    if ($isCurrent) $columns['C'][$rowIdx] += $val;
-                    $columns['F'][$rowIdx] += $val; // 累计
-                }
-                // D: (2+通路) + (5+通路)
-                if (($empId === 2 || $empId === 5) && $finance === '通路') {
-                    if ($isCurrent) $columns['D'][$rowIdx] += $val;
-                    $columns['F'][$rowIdx] += $val; // 累计到F
-                }
-                // G: 3+通路
-                if ($empId === 3 && $finance === '通路') {
-                    if ($isCurrent) $columns['G'][$rowIdx] += $val;
-                    $columns['J'][$rowIdx] += $val;
-                }
-                // H: 3+联华加盟
-                if ($empId === 3 && $finance === '联华加盟') {
-                    if ($isCurrent) $columns['H'][$rowIdx] += $val;
-                    $columns['J'][$rowIdx] += $val;
-                }
-                // K: 23+通路
-                if ($empId === 23 && $finance === '通路') {
-                    if ($isCurrent) $columns['K'][$rowIdx] += $val;
-                    $columns['N'][$rowIdx] += $val;
-                }
-                // L: 23+智鲸
-                if ($empId === 23 && $finance === '智鲸') {
-                    if ($isCurrent) $columns['L'][$rowIdx] += $val;
-                    $columns['N'][$rowIdx] += $val;
-                }
-                // O: (7,8,54) + (通路,大卖场)
-                if (in_array($empId, [7, 8, 54]) && in_array($finance, ['通路', '大卖场'])) {
-                    if ($isCurrent) $columns['O'][$rowIdx] += $val;
-                    $columns['P'][$rowIdx] += $val;
-                }
-                // Q: 48+通路
-                if ($empId === 48 && $finance === '通路') {
-                    if ($isCurrent) $columns['Q'][$rowIdx] += $val;
-                    $columns['T'][$rowIdx] += $val;
-                }
-                // R: 48+大卖场
-                if ($empId === 48 && $finance === '大卖场') {
-                    if ($isCurrent) $columns['R'][$rowIdx] += $val;
-                    $columns['T'][$rowIdx] += $val;
-                }
-                // U: 行政
-                if ($finance === '行政') {
-                    if ($isCurrent) $columns['U'][$rowIdx] += $val;
-                    $columns['V'][$rowIdx] += $val;
-                }
-                // W: 鲍总
-                if ($finance === '鲍总') {
-                    if ($isCurrent) $columns['W'][$rowIdx] += $val;
-                    $columns['X'][$rowIdx] += $val;
-                }
-            }
-        }
-
-        // 6. 计算横向合计列
-        for ($i = 5; $i <= 27; $i++) {
-            $columns['E'][$i] = $columns['C'][$i] + $columns['D'][$i]; // 张+霍当月合计
-            $columns['I'][$i] = $columns['G'][$i] + $columns['H'][$i]; // 金小勇当月合计
-            $columns['M'][$i] = $columns['K'][$i] + $columns['L'][$i]; // 沈强当月合计
-            $columns['S'][$i] = $columns['Q'][$i] + $columns['R'][$i]; // 叶南汝当月合计
-
-            // Y: 当月总计 (所有当月列累加)
-            $columns['Y'][$i] = $columns['C'][$i] + $columns['D'][$i] + $columns['G'][$i] +
-                $columns['H'][$i] + $columns['K'][$i] + $columns['L'][$i] +
-                $columns['O'][$i] + $columns['Q'][$i] + $columns['R'][$i] +
-                $columns['U'][$i] + $columns['W'][$i];
-
-            // Z: 年累计总计 (所有累计列累加)
-            $columns['Z'][$i] = $columns['F'][$i] + $columns['J'][$i] + $columns['N'][$i] +
-                $columns['P'][$i] + $columns['T'][$i] + $columns['V'][$i] + $columns['X'][$i];
-        }
-
-        // 7. 组装最终供 Excel 填充的数组 (5行到32行)
-        $finalData = [];
-        for ($row = 5; $row <= 32; $row++) {
-            $rowData = [];
-            // 从 C 到 Z 循环取数据
-            foreach (range('C', 'Z') as $colLetter) {
-                $val = $columns[$colLetter][$row] ?? 0;
-                // 28-32行填空字符串,其他格式化
-                if ($row > 27 && $row < 32) {
-                    $rowData[] = '';
-                } elseif ($row == 32) {
-                    // 如果需要算小计可以在这里加,目前先填空字符串
-                    $rowData[] = '';
-                } else {
-                    $rowData[] = $val == 0 ? '0.00' : number_format($val, 2, '.', '');
-                }
-            }
-            $finalData[] = $rowData;
-        }
-
-        return $finalData;
-    }
-
-    public function getChannelReportMan($data)
     {
         if (empty($data['order_time'])) return [false, '年月不能为空'];
         $yearMonth = $data['order_time'];
@@ -1511,35 +1070,73 @@ class StatisticsService extends Service
                 $columns['T'][$i] + $columns['V'][$i] + $columns['X'][$i];
         }
 
-        // 纵向小计 (第 32 行 = 8 到 31 行累加)
+        // 6. 计算横向合计与纵向小计
+        // 定义哪些列是“当月”数据列
+        $monthlyCols = ['C', 'D', 'G', 'H', 'K', 'L', 'O', 'Q', 'R', 'U', 'W', 'Y'];
+        // 定义哪些列是“合计”或“年累计”汇总列
+        $summaryCols = ['E', 'F', 'I', 'J', 'M', 'N', 'P', 'S', 'T', 'V', 'X', 'Y', 'Z'];
+
+        // --- 纵向小计 (第32行:销售支出小计) ---
         foreach ($columnKeys as $col) {
-            $subTotal = 0;
-            for ($r = 8; $r <= 31; $r++) {
-                $subTotal += (float)($columns[$col][$r] ?? 0);
+            // 只有“当月”列才计算小计,汇总列按你要求不算(设为0或空)
+            if (in_array($col, $monthlyCols)) {
+                $subTotal = 0;
+                for ($r = 8; $r <= 31; $r++) {
+                    $subTotal += (float)($columns[$col][$r] ?? 0);
+                }
+                $columns[$col][32] = $subTotal;
+
+                // --- 利润分析区计算 (33-38行) ---
+                // 实际利润 (33) = 毛利(7) - 支出小计(32)
+                $realProfit = (float)$columns[$col][7] - (float)$columns[$col][32];
+                $columns[$col][33] = $realProfit;
+                // 净利润 (38) 初始等于实际利润
+                $columns[$col][38] = $realProfit;
+            } else {
+                // 合计列和年累计列,第32、33、38行全部置空
+                $columns[$col][32] = '';
+                $columns[$col][33] = '';
+                $columns[$col][38] = '';
             }
-            $columns[$col][32] = $subTotal;
         }
 
-        // 7. 最终格式化
+        // --- 横向合计 (E, I, M, S, Y, Z 等) ---
+        // 注意:这里只处理 5-27 行的横向累加,因为 32 行以后不需要在合计列显示数据
+        for ($i = 5; $i <= 27; $i++) {
+            $columns['E'][$i] = $columns['C'][$i] + $columns['D'][$i];
+            $columns['I'][$i] = $columns['G'][$i] + $columns['H'][$i];
+            $columns['M'][$i] = $columns['K'][$i] + $columns['L'][$i];
+            $columns['S'][$i] = $columns['Q'][$i] + $columns['R'][$i];
+
+            // Y/Z 总计
+            $columns['Y'][$i] = $columns['C'][$i] + $columns['D'][$i] + $columns['G'][$i] + $columns['H'][$i] +
+                $columns['K'][$i] + $columns['L'][$i] + $columns['O'][$i] + $columns['Q'][$i] +
+                $columns['R'][$i] + $columns['U'][$i] + $columns['W'][$i];
+
+            $columns['Z'][$i] = $columns['F'][$i] + $columns['J'][$i] + $columns['N'][$i] + $columns['P'][$i] +
+                $columns['T'][$i] + $columns['V'][$i] + $columns['X'][$i];
+        }
+
+        // 7. 最终格式化 (确保输出 5-38 行)
         $finalData = [];
-        for ($row = 5; $row <= 32; $row++) {
+        for ($row = 5; $row <= 38; $row++) {
             $rowData = [];
             foreach ($columnKeys as $colLetter) {
-                $val = $columns[$colLetter][$row] ?? 0;
-
-                if ($row >= 28 && $row <= 31) {
-                    $rowData[] = ''; // 预留行填空
+                $val = $columns[$colLetter][$row] ?? '';
+                if ($row >= 28 && $row <= 31 && !is_numeric($val)) {
+                    $rowData[] = '';
+                } elseif ($val === '') {
+                    $rowData[] = '';
                 } else {
-                    $rowData[] = ($val == 0) ? '0.00' : number_format($val, 2, '.', '');
+                    $rowData[] = is_numeric($val) ? number_format((float)$val, 2, '.', '') : $val;
                 }
             }
             $finalData[] = $rowData;
         }
-
         return $finalData;
     }
 
-    public function getChannelReportItem1($data)
+    public function getChannelReportMan($data)
     {
         if (empty($data['order_time'])) return [false, '年月不能为空'];
         $yearMonth = $data['order_time'];
@@ -1548,45 +1145,43 @@ class StatisticsService extends Service
         $year = (int)$year;
         $month = (int)$month;
 
-        // 1. 计算时间范围:7月财年规则
         $currentMonthTs = mktime(0, 0, 0, $month, 1, $year);
         $startYear = ($month >= 7) ? $year : $year - 1;
         $startTs = mktime(0, 0, 0, 7, 1, $startYear);
 
-        // 2. 一次性获取数据
-        $records = DB::table('item_report')
+        $records = DB::table('item_report_man')
             ->whereBetween('time', [$startTs, $currentMonthTs])
             ->get();
 
-        // 3. 字段映射 (注意 24 行,若数据库无字段则设为 null 会自动补 0)
         $rowFieldMapping = [
-            5  => 'receipt_amount',   6  => 'pk_amount',       7  => 'cost',    8  => 'profit',
-            9  => 'settle_amount',    10  => 'gl_amount',      11 => 'wl_amount',
-            12 => 'ht_amount',        13 => 'zk_amount',       14 => 'cx_amount',
-            15 => 'tg_amount',        16 => 'cl_amount',       17 => 'kq_amount',
-            18 => 'zp_amount',        19 => 'gg_amount',       20 => 'kd_amount',
-            21 => 'xsqt_amount',      22 => 'ry_amount',       23 => 'sb_amount',
-            24 => null,               // 退货亏损 (不良仓),暂无字段映射,填充0
-            25 => 'cg_amount',        26 => 'sj_amount',
-            27 => 'sx_amount',        28 => 'other_ck_amount'
+            5  => 'receipt_not_amount',   6  => 'cost',            7  => 'profit_not',
+            8  => 'settle_amount',    9  => 'gl_not_amount',       10 => 'wl_not_amount',
+            11 => 'ht_amount',        12 => 'zk_amount',       13 => 'cx_amount',
+            14 => 'tg_amount',        15 => 'cl_amount',       16 => 'kq_amount',
+            17 => 'zp_amount',        18 => 'gg_amount',       19 => 'kd_amount',
+            20 => 'xsqt_amount',      21 => 'ry_amount',       22 => 'sb_amount',
+            23 => null,
+            24 => 'cg_amount',        25 => 'sj_not_amount',
+            26 => 'sx_not_amount',    27 => 'other_ck_amount'
         ];
 
-        // 4. 初始化列容器 (C 到 Z)
         $columns = [];
-        $columnKeys = range('C', 'AB');
+        $columnKeys = range('C', 'Z');
         foreach ($columnKeys as $col) {
-            $columns[$col] = array_fill(5, 33, 0); // 覆盖 5-33 
+            $columns[$col] = array_fill(5, 34, 0); // 初始化到38
         }
 
-        // 5. 数据分拣累加
+        // 1. 基础数据分拣 (5-27行)
         foreach ($records as $record) {
-            $channel_details = $record->channel_details;
+            $empId = (int)$record->employee_id_1;
+            $finance = $record->channel_finance;
             $isCurrent = ((int)$record->time === $currentMonthTs);
 
             foreach ($rowFieldMapping as $rowIdx => $field) {
                 $val = $field ? (float)($record->$field ?? 0) : 0;
 
-                if ($channel_details === '大卖场') {
+                // 张春勇、霍尚琳
+                if ($empId === 2 && $finance === '社区') {
                     if ($isCurrent) $columns['C'][$rowIdx] += $val;
                     $columns['F'][$rowIdx] += $val;
                 }
@@ -1612,7 +1207,7 @@ class StatisticsService extends Service
                     if ($isCurrent) $columns['L'][$rowIdx] += $val;
                     $columns['N'][$rowIdx] += $val;
                 }
-                // 王利英等组合 (O/P列)
+                // 王利英等组合
                 if (in_array($empId, [7, 8, 54]) && in_array($finance, ['通路', '大卖场'])) {
                     if ($isCurrent) $columns['O'][$rowIdx] += $val;
                     $columns['P'][$rowIdx] += $val;
@@ -1639,48 +1234,60 @@ class StatisticsService extends Service
             }
         }
 
-        // 6. 计算合计列与纵向小计
+        // 2. 计算横向合计 (5-27行)
         for ($i = 5; $i <= 27; $i++) {
-            // 合计列
             $columns['E'][$i] = $columns['C'][$i] + $columns['D'][$i];
             $columns['I'][$i] = $columns['G'][$i] + $columns['H'][$i];
             $columns['M'][$i] = $columns['K'][$i] + $columns['L'][$i];
             $columns['S'][$i] = $columns['Q'][$i] + $columns['R'][$i];
 
-            // Y/Z 总计
+            // Y (当月)
             $columns['Y'][$i] = $columns['C'][$i] + $columns['D'][$i] + $columns['G'][$i] + $columns['H'][$i] +
                 $columns['K'][$i] + $columns['L'][$i] + $columns['O'][$i] + $columns['Q'][$i] +
                 $columns['R'][$i] + $columns['U'][$i] + $columns['W'][$i];
 
+            // Z (年累计总合计)
             $columns['Z'][$i] = $columns['F'][$i] + $columns['J'][$i] + $columns['N'][$i] + $columns['P'][$i] +
                 $columns['T'][$i] + $columns['V'][$i] + $columns['X'][$i];
         }
 
-        // 纵向小计 (第 32 行 = 8 到 31 行累加)
+        // 3. 计算纵向小计与利润分析 (全列应用,包括合计列)
         foreach ($columnKeys as $col) {
+            // 32行:销售支出小计 (8-31行)
             $subTotal = 0;
             for ($r = 8; $r <= 31; $r++) {
                 $subTotal += (float)($columns[$col][$r] ?? 0);
             }
             $columns[$col][32] = $subTotal;
+
+            // 33行:实际利润 = 毛利(7行) - 支出小计(32行)
+            $realProfit = (float)$columns[$col][7] - (float)$columns[$col][32];
+            $columns[$col][33] = $realProfit;
+
+            // 38行:净利润 (初始 = 实际利润)
+            $columns[$col][38] = $realProfit;
+
+            // 34-37行置空
+            $columns[$col][34] = ''; $columns[$col][35] = '';
+            $columns[$col][36] = ''; $columns[$col][37] = '';
         }
 
-        // 7. 最终格式化
+        // 4. 格式化输出 (5-38行)
         $finalData = [];
-        for ($row = 5; $row <= 32; $row++) {
+        for ($row = 5; $row <= 38; $row++) {
             $rowData = [];
             foreach ($columnKeys as $colLetter) {
-                $val = $columns[$colLetter][$row] ?? 0;
-
-                if ($row >= 28 && $row <= 31) {
-                    $rowData[] = ''; // 预留行填空
+                $val = $columns[$colLetter][$row] ?? '';
+                if ($row >= 28 && $row <= 31 && !is_numeric($val)) {
+                    $rowData[] = '';
+                } elseif ($val === '') {
+                    $rowData[] = '';
                 } else {
-                    $rowData[] = ($val == 0) ? '0.00' : number_format($val, 2, '.', '');
+                    $rowData[] = is_numeric($val) ? number_format((float)$val, 2, '.', '') : $val;
                 }
             }
             $finalData[] = $rowData;
         }
-
         return $finalData;
     }
 
@@ -1761,7 +1368,7 @@ class StatisticsService extends Service
             }
         }
 
-        // 6. 计算横向合计 (AA, AB) 与 纵向小计 (第 33 行)
+        // 6. 计算横向合计 (AA, AB)
         $channelStartCols = array_values($channelMap);
         for ($row = 5; $row <= 28; $row++) {
             foreach ($channelStartCols as $sCol) {
@@ -1773,28 +1380,43 @@ class StatisticsService extends Service
             }
         }
 
-        // 计算纵向小计 (第 33 行 = 9 到 28 行的累加,跳过预留行)
+        // --- 纵向计算与利润分析 (全列应用) ---
         foreach ($columnKeys as $col) {
+            // 33. 销售支出小计 = 9 到 28 行累加 (所有列都算)
             $subTotal = 0;
             for ($r = 9; $r <= 28; $r++) {
                 $subTotal += (float)($columns[$col][$r] ?? 0);
             }
             $columns[$col][33] = $subTotal;
-        }
 
-        // 7. 最终格式化输出
+            // 34. 实际利润 = 第 8 行(回款销售毛利) - 第 33 行(销售支出小计)
+            $realProfit = (float)$columns[$col][8] - (float)$columns[$col][33];
+            $columns[$col][34] = $realProfit;
+
+            // 39. 开票净利润 (初始等于实际利润)
+            $columns[$col][39] = $realProfit;
 
+            // 35-38 行保持初始化为空 (用于手动填写或预留)
+            $columns[$col][35] = '';
+            $columns[$col][36] = '';
+            $columns[$col][37] = '';
+            $columns[$col][38] = '';
+        }
+
+        // 7. 最终格式化输出 (保持行号作为 Key)
         $finalData = [];
-        for ($row = 5; $row <= 33; $row++) {
-            // 关键:29-32行我们直接不生成数据,或者生成空
-            if ($row >= 29 && $row <= 32) continue;
+        for ($row = 5; $row <= 39; $row++) {
+            if ($row >= 29 && $row <= 32) continue; // 跳过 B 列的那四个“其他”空行
 
             $rowData = [];
             foreach ($columnKeys as $colLetter) {
-                $val = $columns[$colLetter][$row] ?? 0;
-                $rowData[] = ($val == 0) ? '0.00' : number_format($val, 2, '.', '');
+                $val = $columns[$colLetter][$row] ?? '';
+                if ($val === '' || $val === 0 || $val === 0.0) {
+                    $rowData[] = '0.00';
+                } else {
+                    $rowData[] = is_numeric($val) ? number_format((float)$val, 2, '.', '') : $val;
+                }
             }
-            // 使用行号作为 Key
             $finalData[$row] = $rowData;
         }