Browse Source

工资计算

unknown 3 months ago
parent
commit
8fe3dcfcff
1 changed files with 249 additions and 55 deletions
  1. 249 55
      application/api/controller/GluingSalary.php

+ 249 - 55
application/api/controller/GluingSalary.php

@@ -96,83 +96,277 @@ class GluingSalary extends Api
      * @throws \think\db\exception\ModelNotFoundException
      * @throws \think\exception\DbException
      */
+//    public function getList()
+//    {
+//
+//        if(!$this->request->isGet()){
+//            $this->error('请求方式错误');
+//        }
+//        $req = $this->request->param();
+//        if (isset($req['search'])){
+//            $where = [
+//                'sczl_rq' => ['like',$req['date'].'%'],
+//                'bh|name' => ['like',$req['search'].'%'],
+//            ];
+//            $res = db('糊盒工资汇总')
+//                ->where($where)
+//                ->group('bh, sczl_rq')
+//                ->field('bh as 员工编号, DATE_FORMAT(sczl_rq, "%Y.%m.%d") as 日期, name as 姓名, sum(salary) as 计件工资')
+//                ->select();
+//        }else{
+//            $where = [
+//                'a.sczl_rq' => ['like',$req['date'].'%'],
+//                'b.所在部门' => ['like', $req['department'] . '%']
+//            ];
+//            $res = db('糊盒工资汇总')
+//                ->alias('a')
+//                ->join('人事_基本资料 b', 'b.员工编号 = a.bh')
+//                ->where($where)
+//                ->group('a.bh, a.sczl_rq')
+//                ->field('a.bh as 员工编号, DATE_FORMAT(a.sczl_rq, "%Y.%m.%d") as 日期, a.name as 姓名, sum(a.salary) as 计件工资')
+//                ->select();
+//        }
+//
+//        $processedData = [];
+//
+//        foreach ($res as $item) {
+//            // 用「员工编号」作为唯一分组键(编号唯一,比编号+姓名更简洁)
+//            $empNo = $item['员工编号'];
+//
+//            // 转换工资为浮点型(避免字符串拼接导致计算错误)
+//            $salary = (float)$item['计件工资'];
+//
+//            if (!isset($processedData[$empNo])) {
+//                // 初始化该员工的分组数据
+//                $processedData[$empNo] = [
+//                    '员工编号' => $empNo,
+//                    '姓名' => $item['姓名'],
+//                    '月工资总和' => 0.00, // 初始化为浮点型,保证精度
+//                    '每日明细' => []     // 存储按时间排序的每日工资
+//                ];
+//            }
+//
+//            // 累加月工资总和
+//            $processedData[$empNo]['月工资总和'] += $salary;
+//            $processedData[$empNo]['月工资总和'] = number_format($processedData[$empNo]['月工资总和'],2);
+//            // 将当前日期的工资存入明细(保留原始字段)
+//            $processedData[$empNo]['每日明细'][] = [
+//                '日期' => $item['日期'],
+//                '计件工资' => $item['计件工资'] // 保留原始字符串格式,避免精度丢失
+//            ];
+//        }
+//
+//        // 对每个员工的「每日明细」按日期升序排序
+//        foreach ($processedData as &$empData) {
+//            usort($empData['每日明细'], function($a, $b) {
+//                // 将日期字符串转换为时间戳进行比较
+//                $timeA = strtotime(str_replace('.', '-', $a['日期']));
+//                $timeB = strtotime(str_replace('.', '-', $b['日期']));
+//                return $timeA - $timeB; // 升序排序(从小到大)
+//            });
+//        }
+//        unset($empData); // 释放引用,避免后续误操作
+//
+//        // 转换为索引数组(可选,便于前端遍历)
+//        $finalData = array_values($processedData);
+//
+//        $this->success('成功',$finalData);
+//    }
     public function getList()
     {
-
-        if(!$this->request->isGet()){
+        // 1. 请求验证
+        if (!$this->request->isGet()) {
             $this->error('请求方式错误');
         }
+
         $req = $this->request->param();
-        if (isset($req['search'])){
-            $where = [
-                'sczl_rq' => ['like',$req['date'].'%'],
-                'bh|name' => ['like',$req['search'].'%'],
-            ];
-            $res = db('糊盒工资汇总')
-                ->where($where)
-                ->group('bh, sczl_rq')
-                ->field('bh as 员工编号, DATE_FORMAT(sczl_rq, "%Y.%m.%d") as 日期, name as 姓名, sum(salary) as 计件工资')
-                ->select();
-        }else{
-            $where = [
-                'a.sczl_rq' => ['like',$req['date'].'%'],
-                'b.所在部门' => ['like', $req['department'] . '%']
-            ];
-            $res = db('糊盒工资汇总')
-                ->alias('a')
-                ->join('人事_基本资料 b', 'b.员工编号 = a.bh')
-                ->where($where)
-                ->group('a.bh, a.sczl_rq')
-                ->field('a.bh as 员工编号, DATE_FORMAT(a.sczl_rq, "%Y.%m.%d") as 日期, a.name as 姓名, sum(a.salary) as 计件工资')
-                ->select();
+
+        // 2. 获取查询条件
+        $where = $this->buildWhereConditions($req);
+
+        // 3. 执行查询
+        $res = $this->executeQuery($req, $where);
+
+        if (empty($res)) {
+            $this->success('成功', []);
+        }
+
+        // 4. 处理数据
+        $finalData = $this->processResultData($res);
+
+        $this->success('成功', $finalData);
+    }
+
+    /**
+     * 构建查询条件
+     */
+    private function buildWhereConditions(array $req): array
+    {
+        $where = [];
+
+        // 确保日期条件始终存在
+        if (!empty($req['date'])) {
+            $where['sczl_rq'] = ['like', $req['date'] . '%'];
         }
 
+        // 如果有搜索条件,添加员工编号/姓名的模糊查询
+        if (!empty($req['search'])) {
+            $where['bh|name'] = ['like', $req['search'] . '%'];
+        }
+
+        return $where;
+    }
+
+    /**
+     * 执行数据库查询
+     */
+    private function executeQuery(array $req, array $where)
+    {
+        $query = db('糊盒工资汇总');
+
+        // 判断是否需要联表查询
+        if (empty($req['search']) && !empty($req['department'])) {
+            return $this->executeJoinedQuery($query, $req, $where);
+        }
+
+        return $this->executeSimpleQuery($query, $where);
+    }
+
+    /**
+     * 执行简单查询(不需要联表)
+     */
+    private function executeSimpleQuery($query, array $where)
+    {
+        return $query
+            ->where($where)
+            ->group('bh, sczl_rq')
+            ->field([
+                'bh as 员工编号',
+                'DATE_FORMAT(sczl_rq, "%Y.%m.%d") as 日期',
+                'name as 姓名',
+                'sum(salary) as 计件工资'
+            ])
+            ->select();
+    }
+
+    /**
+     * 执行联表查询(需要部门筛选)
+     */
+    private function executeJoinedQuery($query, array $req, array $where)
+    {
+        // 移除原始的sczl_rq条件,改用别名
+        if (isset($where['sczl_rq'])) {
+            unset($where['sczl_rq']);
+            $where['a.sczl_rq'] = ['like', $req['date'] . '%'];
+        }
+
+        // 添加部门条件
+        $where['b.所在部门'] = ['like', $req['department'] . '%'];
+
+        return $query
+            ->alias('a')
+            ->join('人事_基本资料 b', 'b.员工编号 = a.bh')
+            ->where($where)
+            ->group('a.bh, a.sczl_rq')
+            ->field([
+                'a.bh as 员工编号',
+                'DATE_FORMAT(a.sczl_rq, "%Y.%m.%d") as 日期',
+                'a.name as 姓名',
+                'sum(a.salary) as 计件工资'
+            ])
+            ->select();
+    }
+
+    /**
+     * 处理查询结果数据
+     */
+    private function processResultData(array $results): array
+    {
         $processedData = [];
 
-        foreach ($res as $item) {
-            // 用「员工编号」作为唯一分组键(编号唯一,比编号+姓名更简洁)
+        foreach ($results as $item) {
             $empNo = $item['员工编号'];
-
-            // 转换工资为浮点型(避免字符串拼接导致计算错误)
             $salary = (float)$item['计件工资'];
 
             if (!isset($processedData[$empNo])) {
-                // 初始化该员工的分组数据
-                $processedData[$empNo] = [
-                    '员工编号' => $empNo,
-                    '姓名' => $item['姓名'],
-                    '月工资总和' => 0.00, // 初始化为浮点型,保证精度
-                    '每日明细' => []     // 存储按时间排序的每日工资
-                ];
+                $processedData[$empNo] = $this->initEmployeeData($item);
             }
 
-            // 累加月工资总和
-            $processedData[$empNo]['月工资总和'] += $salary;
-            $processedData[$empNo]['月工资总和'] = number_format($processedData[$empNo]['月工资总和'],2);
-            // 将当前日期的工资存入明细(保留原始字段)
-            $processedData[$empNo]['每日明细'][] = [
-                '日期' => $item['日期'],
-                '计件工资' => $item['计件工资'] // 保留原始字符串格式,避免精度丢失
-            ];
+            $processedData[$empNo] = $this->updateEmployeeData(
+                $processedData[$empNo],
+                $item,
+                $salary
+            );
         }
 
-        // 对每个员工的「每日明细」按日期升序排序
+        // 对每个员工的数据进行排序并格式化最终数据
+        $processedData = $this->formatFinalData($processedData);
+
+        return array_values($processedData);
+    }
+
+    /**
+     * 初始化员工数据结构
+     */
+    private function initEmployeeData(array $item): array
+    {
+        return [
+            '员工编号' => $item['员工编号'],
+            '姓名' => $item['姓名'],
+            '月工资总和' => 0.00,
+            '每日明细' => []
+        ];
+    }
+
+    /**
+     * 更新员工数据
+     */
+    private function updateEmployeeData(array $empData, array $item, float $salary): array
+    {
+        // 累加工资总和
+        $empData['月工资总和'] += $salary;
+
+        // 添加每日明细
+        $empData['每日明细'][] = [
+            '日期' => $item['日期'],
+            '计件工资' => $item['计件工资']
+        ];
+
+        return $empData;
+    }
+
+    /**
+     * 对每日明细按日期排序并格式化最终数据
+     */
+    private function formatFinalData(array $processedData): array
+    {
         foreach ($processedData as &$empData) {
-            usort($empData['每日明细'], function($a, $b) {
-                // 将日期字符串转换为时间戳进行比较
-                $timeA = strtotime(str_replace('.', '-', $a['日期']));
-                $timeB = strtotime(str_replace('.', '-', $b['日期']));
-                return $timeA - $timeB; // 升序排序(从小到大)
-            });
-        }
-        unset($empData); // 释放引用,避免后续误操作
+            // 1. 对每日明细排序
+            $empData['每日明细'] = $this->sortDailyDetails($empData['每日明细']);
 
-        // 转换为索引数组(可选,便于前端遍历)
-        $finalData = array_values($processedData);
+            // 2. 强制格式化月工资总和为两位小数
+            $empData['月工资总和'] = number_format($empData['月工资总和'], 2, '.', '');
+        }
+        unset($empData);
 
-        $this->success('成功',$finalData);
+        return $processedData;
     }
 
+    /**
+     * 对每日明细按日期排序
+     */
+    private function sortDailyDetails(array $dailyDetails): array
+    {
+        usort($dailyDetails, function($a, $b) {
+            // 使用更简单的日期转换方式
+            $timeA = strtotime(str_replace('.', '-', $a['日期']));
+            $timeB = strtotime(str_replace('.', '-', $b['日期']));
+
+            return $timeA <=> $timeB;
+        });
+
+        return $dailyDetails;
+    }
 
     /**
      *下方详情