|
@@ -1179,31 +1179,26 @@ class DeviceWorkService extends Service
|
|
|
if (empty($list)) return [false, '提交数据不能为空'];
|
|
if (empty($list)) return [false, '提交数据不能为空'];
|
|
|
|
|
|
|
|
$topDepartId = $user['top_depart_id'];
|
|
$topDepartId = $user['top_depart_id'];
|
|
|
- $month = $data['month'];
|
|
|
|
|
|
|
+ $month = $data['month']; // 格式如: "2026-03"
|
|
|
$now = time();
|
|
$now = time();
|
|
|
|
|
|
|
|
- // 1. 预加载设备名称映射 (使用 title 或 name 字段)
|
|
|
|
|
|
|
+ // 1. 预加载映射
|
|
|
$deviceIds = collect($list)->pluck('device_id')->unique()->toArray();
|
|
$deviceIds = collect($list)->pluck('device_id')->unique()->toArray();
|
|
|
- $deviceMap = DB::table('device')
|
|
|
|
|
- ->whereIn('id', $deviceIds)
|
|
|
|
|
- ->pluck('title', 'id')
|
|
|
|
|
- ->toArray();
|
|
|
|
|
|
|
+ $deviceMap = DB::table('device')->whereIn('id', $deviceIds)->pluck('title', 'id')->toArray();
|
|
|
|
|
|
|
|
- // --- 2. 重新分组:在分组的同时,利用原始索引记录行号 ---
|
|
|
|
|
|
|
+ // 2. 重新分组并记录行号
|
|
|
$groupedByOrder = [];
|
|
$groupedByOrder = [];
|
|
|
foreach ($list as $index => $item) {
|
|
foreach ($list as $index => $item) {
|
|
|
- $item['_line'] = $index + 1; // 记录原始行号(从1开始)
|
|
|
|
|
- // 以日期字符串作为分组 Key 之一
|
|
|
|
|
|
|
+ $item['_line'] = $index + 1;
|
|
|
$groupKey = $item['order_time'] . '_' . $item['item_id'];
|
|
$groupKey = $item['order_time'] . '_' . $item['item_id'];
|
|
|
$groupedByOrder[$groupKey][] = $item;
|
|
$groupedByOrder[$groupKey][] = $item;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 冲突校验器容器:记录 [设备ID][日期字符串] 下已占用的时间段
|
|
|
|
|
$deviceTimeline = [];
|
|
$deviceTimeline = [];
|
|
|
|
|
|
|
|
DB::beginTransaction();
|
|
DB::beginTransaction();
|
|
|
try {
|
|
try {
|
|
|
- // A. 清理该月份旧数据
|
|
|
|
|
|
|
+ // A. 清理旧数据
|
|
|
$monthStart = $this->changeDateToDate($month);
|
|
$monthStart = $this->changeDateToDate($month);
|
|
|
$monthEnd = strtotime('+1 month', $monthStart) - 1;
|
|
$monthEnd = strtotime('+1 month', $monthStart) - 1;
|
|
|
|
|
|
|
@@ -1218,14 +1213,12 @@ class DeviceWorkService extends Service
|
|
|
DB::table('daily_dw_order_details')->whereIn('main_id', $oldOrderIds)->update(['del_time' => $now]);
|
|
DB::table('daily_dw_order_details')->whereIn('main_id', $oldOrderIds)->update(['del_time' => $now]);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // B. 遍历重组后的分组,生成单据
|
|
|
|
|
|
|
+ // B. 遍历重组后的分组
|
|
|
foreach ($groupedByOrder as $details) {
|
|
foreach ($groupedByOrder as $details) {
|
|
|
$first = $details[0];
|
|
$first = $details[0];
|
|
|
- // 【修正】统一将前端日期字符串转为时间戳入库
|
|
|
|
|
$orderTimestamp = strtotime($first['order_time']);
|
|
$orderTimestamp = strtotime($first['order_time']);
|
|
|
$itemId = $first['item_id'];
|
|
$itemId = $first['item_id'];
|
|
|
|
|
|
|
|
- // 写入设备日工时主表
|
|
|
|
|
$mainId = DB::table('daily_dw_order')->insertGetId([
|
|
$mainId = DB::table('daily_dw_order')->insertGetId([
|
|
|
'code' => '',
|
|
'code' => '',
|
|
|
'item_id' => $itemId,
|
|
'item_id' => $itemId,
|
|
@@ -1242,30 +1235,28 @@ class DeviceWorkService extends Service
|
|
|
$devId = $d['device_id'];
|
|
$devId = $d['device_id'];
|
|
|
$devName = $deviceMap[$devId] ?? "设备(ID:{$devId})";
|
|
$devName = $deviceMap[$devId] ?? "设备(ID:{$devId})";
|
|
|
|
|
|
|
|
- // 【修正】强制后端计算分钟数,防止前端传错或篡改
|
|
|
|
|
|
|
+ // --- 新增:校验 order_time 是否属于当前选择的 month ---
|
|
|
|
|
+ if (date("Y-m", strtotime($d['order_time'])) !== $month) {
|
|
|
|
|
+ return [false, "第 {$rowNum} 行:日期[{$d['order_time']}]不属于保存月份[{$month}],请修正!"];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
$s = (int)$d['start_hour'] * 60 + (int)$d['start_min'];
|
|
$s = (int)$d['start_hour'] * 60 + (int)$d['start_min'];
|
|
|
$e = (int)$d['end_hour'] * 60 + (int)$d['end_min'];
|
|
$e = (int)$d['end_hour'] * 60 + (int)$d['end_min'];
|
|
|
$calcTotalMin = $e - $s;
|
|
$calcTotalMin = $e - $s;
|
|
|
|
|
|
|
|
- // --- 校验逻辑 ---
|
|
|
|
|
-
|
|
|
|
|
- // 校验1:逻辑合法性
|
|
|
|
|
if ($calcTotalMin <= 0) {
|
|
if ($calcTotalMin <= 0) {
|
|
|
return [false, "第 {$rowNum} 行:设备[{$devName}]在[{$d['order_time']}]的结束时间必须晚于开始时间"];
|
|
return [false, "第 {$rowNum} 行:设备[{$devName}]在[{$d['order_time']}]的结束时间必须晚于开始时间"];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 校验2:跨单据冲突校验
|
|
|
|
|
|
|
+ // 冲突校验
|
|
|
$dateStr = $d['order_time'];
|
|
$dateStr = $d['order_time'];
|
|
|
if (isset($deviceTimeline[$devId][$dateStr])) {
|
|
if (isset($deviceTimeline[$devId][$dateStr])) {
|
|
|
foreach ($deviceTimeline[$devId][$dateStr] as $exist) {
|
|
foreach ($deviceTimeline[$devId][$dateStr] as $exist) {
|
|
|
- // 碰撞算法: (开始A < 结束B) 且 (结束A > 开始B)
|
|
|
|
|
if ($s < $exist['e'] && $e > $exist['s']) {
|
|
if ($s < $exist['e'] && $e > $exist['s']) {
|
|
|
- return [false, "第 {$rowNum} 行:设备[{$devName}]在[{$dateStr}]存在时间冲突({$d['start_time']}-{$d['end_time']}),请检查!"];
|
|
|
|
|
|
|
+ return [false, "第 {$rowNum} 行:设备[{$devName}]在[{$dateStr}]存在时间冲突({$d['start_time']}-{$d['end_time']})"];
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- // 记录当前时间段
|
|
|
|
|
$deviceTimeline[$devId][$dateStr][] = ['s' => $s, 'e' => $e];
|
|
$deviceTimeline[$devId][$dateStr][] = ['s' => $s, 'e' => $e];
|
|
|
|
|
|
|
|
$insertDetails[] = [
|
|
$insertDetails[] = [
|
|
@@ -1276,15 +1267,12 @@ class DeviceWorkService extends Service
|
|
|
'start_time_min' => $d['start_min'],
|
|
'start_time_min' => $d['start_min'],
|
|
|
'end_time_hour' => $d['end_hour'],
|
|
'end_time_hour' => $d['end_hour'],
|
|
|
'end_time_min' => $d['end_min'],
|
|
'end_time_min' => $d['end_min'],
|
|
|
- 'total_work_min' => $calcTotalMin, // 使用后端计算结果
|
|
|
|
|
|
|
+ 'total_work_min' => $calcTotalMin,
|
|
|
'crt_time' => $now,
|
|
'crt_time' => $now,
|
|
|
];
|
|
];
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- // 执行明细批量插入
|
|
|
|
|
DB::table('daily_dw_order_details')->insert($insertDetails);
|
|
DB::table('daily_dw_order_details')->insert($insertDetails);
|
|
|
|
|
|
|
|
- // C. 回填单号
|
|
|
|
|
$code = $this->generateBillNo([
|
|
$code = $this->generateBillNo([
|
|
|
'top_depart_id' => $topDepartId,
|
|
'top_depart_id' => $topDepartId,
|
|
|
'type' => DailyDwOrder::Order_type,
|
|
'type' => DailyDwOrder::Order_type,
|