|
|
@@ -3,8 +3,6 @@
|
|
|
namespace App\Service;
|
|
|
|
|
|
use App\Model\AuxiliaryAccountDetails;
|
|
|
-use App\Model\DailyDwOrderDetails;
|
|
|
-use App\Model\DailyPwOrderDetails;
|
|
|
use App\Model\Depart;
|
|
|
use App\Model\Device;
|
|
|
use App\Model\DeviceDepartDetails;
|
|
|
@@ -14,8 +12,6 @@ use App\Model\ExpenseClaimsDetails;
|
|
|
use App\Model\Fee;
|
|
|
use App\Model\Item;
|
|
|
use App\Model\ItemDetails;
|
|
|
-use App\Model\MonthlyDdOrder;
|
|
|
-use App\Model\MonthlyDdOrderDetails;
|
|
|
use App\Model\MonthlyPsOrder;
|
|
|
use App\Model\MonthlyPsOrderDetails;
|
|
|
use App\Service\Statistic\StatisticCommonService;
|
|
|
@@ -24,6 +20,71 @@ use Illuminate\Support\Facades\DB;
|
|
|
class StatisticService extends StatisticCommonService
|
|
|
{
|
|
|
public function employeeDayHourStatistic($data, $user)
|
|
|
+ {
|
|
|
+ // 1. 验证并获取月份边界
|
|
|
+ list($status, $month_start, $month_end) = $this->commonRule($data);
|
|
|
+ if (!$status) return [false, $month_start];
|
|
|
+
|
|
|
+ // 2. 获取原始数据
|
|
|
+ $dayEmployeeList = $this->getItemEmployeeDayWorkList($user, $data, $month_start, $month_end);
|
|
|
+ if (empty($dayEmployeeList)) {
|
|
|
+ return [true, []];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 提取 ID 批量查询关联数据(合并 Item 查询)
|
|
|
+ $itemIds = array_unique(array_filter(array_column($dayEmployeeList, 'item_id')));
|
|
|
+ $employeeIds = array_unique(array_filter(array_column($dayEmployeeList, 'employee_id')));
|
|
|
+
|
|
|
+ $items = Item::whereIn('id', $itemIds)->get(['id', 'title', 'code'])->keyBy('id');
|
|
|
+ $employeeKeyList = Employee::whereIn('id', $employeeIds)->pluck('title', 'id')->toArray();
|
|
|
+
|
|
|
+ // 4. 【核心优化】单次遍历:同时计算 count、sum 并补全基础信息
|
|
|
+ $employeeCounts = [];
|
|
|
+ $sums = [];
|
|
|
+
|
|
|
+ foreach ($dayEmployeeList as &$item) {
|
|
|
+ $employeeId = $item['employee_id'] ?? null;
|
|
|
+ $itemId = $item['item_id'] ?? null;
|
|
|
+ $orderDate = $item['order_date'] ?? '';
|
|
|
+
|
|
|
+ // 补全名称(避免在 map 里重复调用集合)
|
|
|
+ $item['employee_name'] = $employeeKeyList[$employeeId] ?? "未知员工({$employeeId})";
|
|
|
+ $itemProject = $items->get($itemId);
|
|
|
+ $item['item_title'] = $itemProject->title ?? "未知项目({$itemId})";
|
|
|
+ $item['item_code'] = $itemProject->code ?? "未知项目({$itemId})";
|
|
|
+
|
|
|
+ // 组装唯一 Key: "employeeId_orderDate"
|
|
|
+ $groupKey = "{$employeeId}_{$orderDate}";
|
|
|
+
|
|
|
+ // 累加计数
|
|
|
+ $employeeCounts['employee_work_count'][$groupKey] = ($employeeCounts['employee_work_count'][$groupKey] ?? 0) + 1;
|
|
|
+
|
|
|
+ // 累加小时工时(转为分位整数存储,防止浮点数失真)
|
|
|
+ $hours = round(($item['total_work'] ?? 0) / 60, 2);
|
|
|
+ $sums['employee_work_count'][$groupKey] = ($sums['employee_work_count'][$groupKey] ?? 0) + (int)round($hours * 100);
|
|
|
+ }
|
|
|
+ unset($item); // 释放引用避免后续污染
|
|
|
+
|
|
|
+ $wordKeys = [
|
|
|
+ "employee_work_count" => [
|
|
|
+ "key" => "total_work",
|
|
|
+ "value" => "total_work_hours",
|
|
|
+ "type" => "hour",
|
|
|
+ ]
|
|
|
+ ];
|
|
|
+
|
|
|
+ // 5. 第二次遍历:倒扣尾差计算
|
|
|
+ // 因为这里需要倒扣,必须按顺序执行 calculateClosure
|
|
|
+ foreach ($dayEmployeeList as &$item) {
|
|
|
+ $groupKey = "{$item['employee_id']}_{$item['order_date']}";
|
|
|
+ $this->calculateClosure($groupKey, $item, $employeeCounts, $sums, $wordKeys);
|
|
|
+ }
|
|
|
+ unset($item);
|
|
|
+
|
|
|
+ return [true, $dayEmployeeList];
|
|
|
+ }
|
|
|
+
|
|
|
+ public function employeeDayHourStatistic1($data, $user)
|
|
|
{
|
|
|
//传参月份、项目编码、项目名称 不允许跨年查询月份
|
|
|
//项目编码、项目名称、人员名称、工时、日期
|