13693261870
2025-07-02 6708810c4de34dfb9513061432d656f91d56ee3a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
package com.ruoyi.buss.controller;
 
import com.ruoyi.buss.common.DateUtils;
import com.ruoyi.buss.domain.DmHarbor2;
import com.ruoyi.buss.domain.DsTask;
import com.ruoyi.buss.domain.DsTaskList2;
import com.ruoyi.buss.domain.dto.AllocationReqDTO;
import com.ruoyi.buss.domain.dto.DsTaskQueryParam;
import com.ruoyi.buss.domain.vo.TaskListStatis;
import com.ruoyi.buss.service.IDmHarbor2Service;
import com.ruoyi.buss.service.IDsTaskList2Service;
import com.ruoyi.buss.service.IDsTaskService;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.web.domain.server.Sys;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
 
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
 
@Tag(name = "基地任务接口")
@RestController
@RequestMapping("/buss/task/ex")
public class DMTaskController extends BaseController {
 
    @Autowired
    private IDsTaskService iDsTaskService;
    @Autowired
    private IDsTaskList2Service iDsTaskListService;
    @Autowired
    private IDmHarbor2Service iDmHarborService;
 
    @Operation(summary = "获取所有任务列表")
    @PostMapping("/histask/list")
    @ResponseBody
    public AjaxResult getTaskList(@RequestBody DsTaskQueryParam param) {
        if(null != param.getEtime()){
            param.setEtime(DateUtils.setToNextDayZero(param.getEtime()));
        }
        List<DsTask> dsTaskList = iDsTaskService.selectDsTaskListByParam(param);
        return success(dsTaskList);
    }
 
    @Operation(summary = "任务完成接口_通过ID")
    @PostMapping("/complete/{id}")
    @ResponseBody
    public AjaxResult complete(@Parameter(name = "id", required = true, description = "任务ID") @PathVariable("id") Long id) {
        DsTaskList2 taskList2 = iDsTaskListService.selectDsTaskListByPkid(id);
        if(null != taskList2){
            taskList2.setStatus("10");
            taskList2.setUpdateBy(getUsername());
            int flag = iDsTaskListService.updateDsTaskList(taskList2);
            if(flag == 1){
                return success("任务完成成功");
            }
            return error("任务完成失败");
        }
        return error("未获取到任务");
    }
 
    @Operation(summary = "任务完成接口_通过任务Id和舷号")
    @PostMapping("/complete/taskandship/{taskid}/{shipno}")
    @ResponseBody
    public AjaxResult completeWithShipAndTaskId(@Parameter(name = "taskid", required = true, description = "任务ID") @PathVariable("taskid") Long taskid,
                                                @Parameter(name = "shipno", required = true, description = "舷号") @PathVariable("shipno") String shipno) {
        DsTaskList2 queryParam = new DsTaskList2();
        queryParam.setTaskId(taskid);
        queryParam.setShipNo(shipno);
        List<DsTaskList2> taskList2 = iDsTaskListService.selectDsTaskListList(queryParam);
        if(null != taskList2 && taskList2.size() > 0){
            DsTaskList2 tmpTask = taskList2.get(0);
            tmpTask.setStatus("10");
            tmpTask.setUpdateBy(getUsername());
            int flag = iDsTaskListService.updateDsTaskList(tmpTask);
            if(flag == 1){
                return success("任务完成成功");
            }
            return error("任务完成失败");
        }
        return error("未获取到任务");
    }
 
    @Operation(summary = "任务列表_默认获取正在执行的任务")
    @PostMapping("/list")
    @ResponseBody
    public AjaxResult runningTask(@Parameter(name = "deptid", required = false, description = "部门编码") @RequestParam(value = "deptid", required = false) Long deptid,
                                  @Parameter(name = "status", description = "状态编码") @RequestParam(value = "status", required = false, defaultValue = "2") String status) {
        if(StringUtils.isBlank(status)){status = "2";}
        DsTaskList2 queryParam = new DsTaskList2();
        queryParam.setStatus(status);
        if(null != deptid){queryParam.setDeptId(deptid);}
        List<DsTaskList2> taskList2 = iDsTaskListService.selectDsTaskListList(queryParam);
        return success(taskList2);
    }
 
    @Operation(summary = "基地任务下发")
    @Log(title = "基地任务下发", businessType = BusinessType.UPDATE)
    @PostMapping("/apply/{taskid}")
    @ResponseBody
    public AjaxResult apply(@Parameter(name = "taskid", required = true, description = "任务ID") @PathVariable("taskid") Long taskid) {
        DsTask dsTask = iDsTaskService.selectDsTaskByPKID(taskid);
        dsTask.setStatus("1");
        dsTask.setUpdateBy(getUsername());
        int flag = iDsTaskService.updateDsTask(dsTask);
        List<DsTaskList2> taskList2s = iDsTaskListService.selectDsTaskListByTaskId(taskid);
        for(DsTaskList2 task : taskList2s){
            task.setStatus("1");
            iDsTaskListService.updateDsTaskList(task);
        }
        if(flag == 1){
            return success(dsTask);
        }
        return error("下发失败,请重试");
    }
 
    @Operation(summary = "根据任务ID获取任务列表")
    @GetMapping("/taskId/{taskid}")
    @ResponseBody
    public AjaxResult getByTaskId(@Parameter(name = "taskid", required = true, description = "任务ID") @PathVariable("taskid") Long taskid) {
        List<DsTaskList2> dsTaskList2s = iDsTaskListService.selectDsTaskListByTaskId(taskid);
        return success(covertTaskToStatis(dsTaskList2s));
    }
 
    /**
     * 码头调度分配接口
     *
     */
    @Operation(summary = "码头调度分配")
    @PostMapping("/allocation")
    @ResponseBody
    public AjaxResult allocation(@RequestBody AllocationReqDTO reqDTO) {
        String shipnos = reqDTO.getShipnos();
        String rule = reqDTO.getRule();
        String harborIds = reqDTO.getHarborids();
 
//        if(StringUtils.isBlank(shipnos)){
//            return error("舷号不能为空");
//        }
        String[] shipArr = shipnos.split(",");
        List<DsTaskList2> taskLists = iDsTaskListService.selectCurrentDsTaskListWithShipNoV2(shipArr);
        if(taskLists.size() == 0){
            return error("所选舰艇为空,请重新检查参数");
        }
        
        if (StringUtils.isBlank(harborIds)) {
            return error("码头ID不能为空");
        }
        String[] harborIdArr = harborIds.split(",");
        List<Long> harborIdList = Arrays.stream(harborIdArr)
                                        .map(Long::parseLong)
                                        .collect(Collectors.toList());
        List<DmHarbor2> harborList = iDmHarborService.selectDmHarborByPKIDs(harborIdList);
 
        // 重新组织数据结构,然后发送
        List<DsTaskList2> allocTaskList = allocationHarbor(taskLists, harborList, rule);
        // 重新设定对象结构,按照码头分组
        return success(covertTaskToStatis(allocTaskList));
    }
 
    /**
     * 新增保存任务列表信息
     */
    @Operation(summary = "调配信息更新接口")
    @PostMapping("/tasklist/add")
    @ResponseBody
    public AjaxResult addTaskListSave(@RequestBody List<DsTaskList2> taskList) {
        // 缺少数据非空以及合法性校验
 
        // 删除已经存在的船舰数据
        List<DsTaskList2> dsTaskList2s = iDsTaskListService.selectCurrentDsTaskListV2();
        // 增加一个任务并保存
        DsTask dsTask = new DsTask();
        String taskName = String.format("任务: %tF # %d", new Date(), System.currentTimeMillis());
        dsTask.setNAME(taskName);
        int addTag = iDsTaskService.insertDsTask(dsTask);
 
 
        try{
            if(addTag > 0){
                // 使用Map优化查找效率
                Map<Long, DsTaskList2> existingTaskMap = dsTaskList2s.stream()
                    .collect(Collectors.toMap(DsTaskList2::getPKID, Function.identity()));
                
                // 批量更新任务列表
                List<DsTaskList2> tasksToUpdate = taskList.stream()
                    .filter(tmpTaskList -> existingTaskMap.containsKey(tmpTaskList.getPKID()))
                    .map(tmpTaskList -> {
                        DsTaskList2 existingTask = existingTaskMap.get(tmpTaskList.getPKID());
                        existingTask.setTaskId(dsTask.getPKID());
                        existingTask.setHarborName(tmpTaskList.getHarborName());
                        existingTask.setHarborId(tmpTaskList.getHarborId());
                        existingTask.setDeptId(tmpTaskList.getDeptId());
                        existingTask.setDeptName(tmpTaskList.getDeptName());
                        return existingTask;
                    })
                    .collect(Collectors.toList());
                
                // 批量更新数据库
                if (!tasksToUpdate.isEmpty()) {
                    iDsTaskListService.batchUpdateDsTaskList(tasksToUpdate);
                }
                return success(dsTask);
            }
        }catch (Exception e){
            iDsTaskService.deleteDsTaskByPKID(dsTask.getPKID());
        }
 
        return error("创建任务失败,请重试");
    }
 
    /**
     * 查询任务列表信息列表
     */
    @Operation(summary = "NEW-获取当日需要分配的舰艇信息")
    @PostMapping("/current/list")
    @ResponseBody
    public AjaxResult curListV2() {
        List<DsTaskList2> list = iDsTaskListService.selectCurrentDsTaskListV2();
        return success(list);
    }
 
    /**
     * 查询任务列表信息列表
     */
    @Operation(summary = "获取当日需要分配的舰艇信息V1")
    @PostMapping("/current/list/v1")
    @ResponseBody
    public AjaxResult curListV1() {
        List<DsTaskList2> list = iDsTaskListService.selectCurrentDsTaskList();
        return success(list);
    }
 
 
    /**
     * 对泊位按照规则进行分配
     * @param list
     * @param rule
     * @return
     */
    private List<DsTaskList2> allocationHarbor(List<DsTaskList2> list, List<DmHarbor2> harborList, String rule){
        List<DsTaskList2> dsTaskList2s = new ArrayList<>();
        if(null != list && list.size() > 0){
            switch (rule){
                case "ZSBD":        // 战术编队
                    // 前提说明:油量都是指oil_a 字段,  剩余油量指港口油存量减去已经分配舰艇需要的油需求量,可用泊位为 berth_no  港口顺序是指  已分配舰艇数量/可用泊位 正序排列
                    // 1 先筛选出有战术编队的舰艇,根据战术编队进行分组,
                    // 2 分别计算每组总的加油量,并计算该组的最大水深,
                    // 3 如果该战术编队的位置区域字段值不为空,首选根据港口水深判断该区域是否满足,如果满足再判断该区域港口已有油量满足需求,如果都满足则分配该港口,
                    // 4 如果有一个条件不满足则获取下一个港口进行判断,如果所有港口都不满足则选择第一个港口,并在remark 字段增加判断失败的原因。
                    // 5 如果位置区域字段为空,则根据港口顺序依次选择港口进行判断,每个港口先根据港口水深判断该区域是否满足,如果满足再判断该区域港口已有油量满足需求,如果都满足则分配该港口,
                    // 6 如果有条件不满足则依次选择下一个港口进行判断直到港口遍历完,如果还未找到则分配第一个港口,并在remark 字段增加判断失败的原因
                // 1-先筛选出有战术编队的舰艇,根据战术编队进行分组,
                Map<String, List<DsTaskList2>> tacticalGroupMap = list.stream()
                        .collect(Collectors.groupingBy(task -> task.getGrpName() != null && !task.getGrpName().isEmpty() ? task.getGrpName() : UUID.randomUUID().toString()));
                Map<Long, Double> allocatedOilMap = new HashMap<>();
                // 1.1- 计算该组总的oil_a量,根据总oil_a量选择合适的港口,
                for (Map.Entry<String, List<DsTaskList2>> entry : tacticalGroupMap.entrySet()) {
                    List<DsTaskList2> groupTasks = entry.getValue();
                    double totalOilB = groupTasks.stream().mapToDouble(task -> {
                        double oilA = 0.0;
                        if (task.getOilB() != null) oilA += task.getOilB();
                        return oilA;
                    }).sum();
                    double maxDepth = groupTasks.stream().mapToDouble(task -> task.getDraft() != null ? task.getDraft() : 0).max().orElse(0);
 
                    DmHarbor2 selectedHarbor = null;
                    List<DmHarbor2> suitableHarbors = harborList.stream()
                            .filter(harbor -> (harbor.getOilB() != null && harbor.getOilB() >= totalOilB) && harbor.getDraft() >= maxDepth)
                            .collect(Collectors.toList());
 
                    if (!suitableHarbors.isEmpty()) {
                        if (StringUtils.isNotBlank(groupTasks.get(0).getPosArea())) {
                            selectedHarbor = suitableHarbors.stream()
                                    .filter(harbor -> harbor.getHarborName() != null && harbor.getHarborName().equals(groupTasks.get(0).getPosArea()) && (harbor.getAllocatedShipCount() != null ? harbor.getAllocatedShipCount() : 0) < harbor.getBerthNo())
                                    .findFirst()
                                    .orElse(suitableHarbors.stream()
                                            .filter(harbor -> (harbor.getAllocatedShipCount() != null ? harbor.getAllocatedShipCount() : 0) < harbor.getBerthNo())
                                            .findFirst()
                                            .orElse(suitableHarbors.get(0)));
                        } else {
                            selectedHarbor = suitableHarbors.stream()
                                    .filter(harbor -> (harbor.getOilB() != null ? harbor.getOilB() : 0) - (harbor.getAllocatedOilA() != null ? harbor.getAllocatedOilA() : 0) >= totalOilB && (harbor.getAllocatedShipCount() != null ? harbor.getAllocatedShipCount() : 0) < harbor.getBerthNo())
                                    .findFirst()
                                    .orElse(suitableHarbors.stream()
                                            .filter(harbor -> (harbor.getAllocatedShipCount() != null ? harbor.getAllocatedShipCount() : 0) < harbor.getBerthNo())
                                            .findFirst()
                                            .orElse(suitableHarbors.get(0)));
                        }
                    } else {
                        selectedHarbor = harborList.stream()
                                .filter(harbor -> (harbor.getAllocatedShipCount() != null ? harbor.getAllocatedShipCount() : 0) < harbor.getBerthNo())
                                .min(Comparator.comparingDouble(harbor -> (double) (harbor.getBerthNo() - (harbor.getAllocatedShipCount() != null ? harbor.getAllocatedShipCount() : 0)) / harbor.getBerthNo()))
                                .orElse(harborList.get(0));
                    }
 
                    DmHarbor2 finalSelectedHarbor = selectedHarbor;
                    groupTasks.forEach(task -> {
                        if (finalSelectedHarbor != null) {
                            task.setHarborId(finalSelectedHarbor.getPKID());
                            task.setHarborName(finalSelectedHarbor.getHarborName());
                            task.setDeptId(finalSelectedHarbor.getDeptId());
                            task.setDeptName(finalSelectedHarbor.getDeptName());
                            double allocatedOilA = finalSelectedHarbor.getAllocatedOilA() != null ? finalSelectedHarbor.getAllocatedOilA() : 0;
                            finalSelectedHarbor.setAllocatedOilA(allocatedOilA + (task.getOilB() != null ? task.getOilB() : 0));
                            int allocatedShipCount = finalSelectedHarbor.getAllocatedShipCount() != null ? finalSelectedHarbor.getAllocatedShipCount() : 0;
                            finalSelectedHarbor.setAllocatedShipCount(allocatedShipCount + 1);
                            dsTaskList2s.add(task);
                        }
 
                        // 重新计算空置比
                        harborList.forEach(harbor -> {
                            int currentAllocatedShipCount = harbor.getAllocatedShipCount() != null ? harbor.getAllocatedShipCount() : 0;
                            double vacancyRatio = (double) (harbor.getBerthNo() - currentAllocatedShipCount) / harbor.getBerthNo();
                            // 可以在此处使用vacancyRatio进行进一步的逻辑处理
                        });
                    });
                }
                break;
                case "JTXH":        // 舰艇型号
                    // 1- 先根据舰艇型号进行分组,根据分组信息,如果同一组的优先分配同一个码头,
                    // 1.1- 计算每一组的总加油量,根据加油量选择合适的港口,
                    // 1.2- 如果多个港口加油量都可以满足则按照位置区域选择港口,
                    // 1.3- 如果无位置区域,则选择第一个港口。
                // 1- 先根据舰艇型号进行分组
                Map<String, List<DsTaskList2>> shipTypeGroupMap = list.stream()
                        .collect(Collectors.groupingBy(DsTaskList2::getShipType));
 
                for (Map.Entry<String, List<DsTaskList2>> entry : shipTypeGroupMap.entrySet()) {
                    List<DsTaskList2> groupTasks = entry.getValue();
                    double totalOilB = groupTasks.stream().mapToDouble(task -> {
                        double oilB = 0.0;
                        if (task.getOilB() != null) oilB += task.getOilB();
                        return oilB;
                    }).sum();
                    double maxDepth = groupTasks.stream().mapToDouble(task -> task.getDraft() != null ? task.getDraft() : 0).max().orElse(0);
 
                    DmHarbor2 selectedHarbor = null;
                    boolean harborFound = false;
 
                    // 3- 如果分组的位置区域字段值不为空
                    if (groupTasks != null && !groupTasks.isEmpty() && groupTasks.get(0).getPosArea() != null && !groupTasks.get(0).getPosArea().isEmpty()) {
                        for (DmHarbor2 harbor : harborList) {
                            if (harbor != null && harbor.getDraft() >= maxDepth && 
                                (harbor.getOilB() != null && harbor.getAllocatedOilA() != null && 
                                 (harbor.getOilB() - harbor.getAllocatedOilA() >= totalOilB)) && 
                                harbor.getHarborName() != null && 
                                harbor.getHarborName().equals(groupTasks.get(0).getPosArea())) {
                                selectedHarbor = harbor;
                                harborFound = true;
                                break;
                            }
                        }
                    }
 
                    // 5- 如果位置区域字段为空
                    if (!harborFound) {
                        for (DmHarbor2 harbor : harborList.stream().sorted(Comparator.comparingDouble(h -> {
                            int allocatedShipCount = h.getAllocatedShipCount() != null ? h.getAllocatedShipCount() : 0;
                            return (double) allocatedShipCount / (h.getBerthNo() != null ? h.getBerthNo() : 1);
                        })).collect(Collectors.toList())) {
                            double allocatedOilA = harbor.getAllocatedOilA() != null ? harbor.getAllocatedOilA() : 0;
                            if (harbor.getDraft() >= maxDepth && 
                                (harbor.getOilB() != null && (harbor.getOilB() - allocatedOilA >= totalOilB))) {
                                selectedHarbor = harbor;
                                harborFound = true;
                                break;
                            }
                        }
                    }
 
                    // 4- 如果所有港口都不满足则选择第一个港口,并在remark 字段增加判断失败的原因
                    if (!harborFound && !harborList.isEmpty()) {
                        selectedHarbor = harborList.get(0);
                        groupTasks.forEach(task -> task.setRemark("所有港口均不满足条件"));
                    }
 
                    DmHarbor2 finalSelectedHarbor = selectedHarbor;
                    groupTasks.forEach(task -> {
                        if (finalSelectedHarbor != null) {
                            task.setHarborId(finalSelectedHarbor.getPKID());
                            task.setHarborName(finalSelectedHarbor.getHarborName());
                            finalSelectedHarbor.setAllocatedOilA((finalSelectedHarbor.getAllocatedOilA() != null ? finalSelectedHarbor.getAllocatedOilA() : 0) + (task.getOilB() != null ? task.getOilB() : 0));
                            finalSelectedHarbor.setAllocatedShipCount((finalSelectedHarbor.getAllocatedShipCount() != null ? finalSelectedHarbor.getAllocatedShipCount() : 0) + 1);
                            dsTaskList2s.add(task);
                        } else {
                            task.setRemark("未找到合适的港口");
                        }
                    });
                }
                break;
                case "BJZD":        // 补给重点
                for (DsTaskList2 task : list) {
                    Double taskDraft = task.getDraft() != null ? task.getDraft() : 0.0;
                    boolean ammoSupplyNeeded = (task.getAmmoD() != null && task.getAmmoD() > 0) ||
                                               (task.getAmmoO() != null && task.getAmmoO() > 0) ||
                                               (task.getAmmoP() != null && task.getAmmoP() > 0) ||
                                               (task.getAmmoS() != null && task.getAmmoS() > 0);
                    //harborList.stream().mapToDouble(h -> h.getDraft() != null ? h.getDraft() : 0.0).min().orElse(0.0);
                    DmHarbor2 selectedHarbor = null;
                    boolean harborFound = false;
                    if (ammoSupplyNeeded) {
                        boolean canDockAtQingyuOrJiaotou = harborList.stream()
                                .anyMatch(harbor -> (harbor.getHarborName().equals("青屿") || harbor.getHarborName().equals("礁头")) &&
                                                     harbor.getDraft() >= taskDraft);
 
                        if (canDockAtQingyuOrJiaotou) {
                            for (DmHarbor2 harbor : harborList) {
                                if ((harbor.getHarborName().equals("青屿") || harbor.getHarborName().equals("礁头")) &&
                                    harbor.getDraft() >= taskDraft &&
                                    (harbor.getOilB() - (harbor.getAllocatedOilA() != null ? harbor.getAllocatedOilA() : 0) >= task.getOilB()) &&
                                    (harbor.getAllocatedShipCount() != null ? harbor.getAllocatedShipCount() : 0) / (harbor.getBerthNo() != null ? harbor.getBerthNo() : 1) < 1) {
                                    selectedHarbor = harbor;
                                    harborFound = true;
                                    break;
                                }
                            }
                        } else {
                            for (DmHarbor2 harbor : harborList) {
                                if (harbor.getDraft() >= taskDraft) {
                                    selectedHarbor = harbor;
                                    harborFound = true;
                                    break;
                                }
                            }
                        }
                    }
                    
                    if (!harborFound) {
                        for (DmHarbor2 harbor : harborList) {
                            if (harbor.getDraft() >= taskDraft) {
                                selectedHarbor = harbor;
                                break;
                            }
                        }
                    }
 
                    if (selectedHarbor != null) {
                        task.setHarborId(selectedHarbor.getPKID());
                        task.setHarborName(selectedHarbor.getHarborName());
                        selectedHarbor.setAllocatedOilA((selectedHarbor.getAllocatedOilA() != null ? selectedHarbor.getAllocatedOilA() : 0) + (task.getOilB() != null ? task.getOilB() : 0));
                        selectedHarbor.setAllocatedShipCount((selectedHarbor.getAllocatedShipCount() != null ? selectedHarbor.getAllocatedShipCount() : 0) + 1);
                        dsTaskList2s.add(task);
                    } else {
                        task.setRemark("未找到合适的港口");
                    }
                }
                break;
                case "WZQJ":        // 位置区间
                // 1- 先按照包含位置区间的进行分组
                // 2- 剩余的按照泊位数量占比进行分配,
                // 3- 如果占比类似则按照顺序进行区分。
                // 1- 先按照是否包含位置区间进行区分
                // 1- 先按照位置区间进行分组
                Map<String, List<DsTaskList2>> posAreaGroupMap = list.stream()
                        .collect(Collectors.groupingBy(task -> {
                            String posArea = task.getPosArea();
                            return (posArea != null && !posArea.isEmpty()) ? posArea : UUID.randomUUID().toString();
                        }));
 
                // 2- 分别计算每组总的加油量,以及最大水深,
                for (Map.Entry<String, List<DsTaskList2>> entry : posAreaGroupMap.entrySet()) {
                    List<DsTaskList2> groupTasks = entry.getValue();
                    double totalOilB = groupTasks.stream().mapToDouble(task -> {
                        Double oilB = task.getOilB();
                        return (oilB != null) ? oilB : 0.0;
                    }).sum();
                    double maxDepth = groupTasks.stream().mapToDouble(task -> {
                        Double draft = task.getDraft();
                        return (draft != null) ? draft : 0.0;
                    }).max().orElse(0.0);
 
                    DmHarbor2 selectedHarbor = null;
                    boolean harborFound = false;
 
                    // 3- 先遍历位置区间不为空的组
                    if (groupTasks.get(0).getPosArea() != null && !groupTasks.get(0).getPosArea().isEmpty()) {
                        for (DmHarbor2 harbor : harborList) {
                            Double harborDraft = harbor.getDraft() != null ? harbor.getDraft() : 0.0;
                            Double harborOilB = harbor.getOilB() != null ? harbor.getOilB() : 0.0;
                            Double allocatedOilA = harbor.getAllocatedOilA() != null ? harbor.getAllocatedOilA() : 0.0;
 
                            if (harborDraft >= maxDepth && (harborOilB - allocatedOilA >= totalOilB)) {
                                selectedHarbor = harbor;
                                harborFound = true;
                                break;
                            }
                        }
                    }
 
                    // 5- 再遍历位置区间为空的组
                    if (!harborFound) {
                        for (DmHarbor2 harbor : harborList.stream()
                                .sorted(Comparator.comparingDouble(h -> {
                                    int allocatedShipCount = h.getAllocatedShipCount() != null ? h.getAllocatedShipCount() : 0;
                                    long berthNo = h.getBerthNo() != null ? h.getBerthNo() : 1;
                                    return (double) allocatedShipCount / berthNo;
                                }))
                                .collect(Collectors.toList())) {
                            Double harborDraft = harbor.getDraft() != null ? harbor.getDraft() : 0.0;
                            Double harborOilB = harbor.getOilB() != null ? harbor.getOilB() : 0.0;
                            Double allocatedOilA = harbor.getAllocatedOilA() != null ? harbor.getAllocatedOilA() : 0.0;
 
                            if (harborDraft >= maxDepth && (harborOilB - allocatedOilA >= totalOilB)) {
                                selectedHarbor = harbor;
                                harborFound = true;
                                break;
                            }
                        }
                    }
 
                    if (!harborFound) {
                        selectedHarbor = harborList.stream()
                                .min(Comparator.comparingDouble(h -> {
                                    int allocatedShipCount = h.getAllocatedShipCount() != null ? h.getAllocatedShipCount() : 0;
                                    long berthNo = h.getBerthNo() != null ? h.getBerthNo() : 1;
                                    return (double) allocatedShipCount / berthNo;
                                }))
                                .orElse(harborList.get(0));
                    }
 
                    DmHarbor2 finalSelectedHarbor = selectedHarbor;
                    groupTasks.forEach(task -> {
                        task.setHarborId(finalSelectedHarbor.getPKID());
                        task.setHarborName(finalSelectedHarbor.getHarborName());
                        task.setDeptId(finalSelectedHarbor.getDeptId());
                        task.setDeptName(finalSelectedHarbor.getDeptName());
                        double allocatedOilA = finalSelectedHarbor.getAllocatedOilA() != null ? finalSelectedHarbor.getAllocatedOilA() : 0.0;
                        finalSelectedHarbor.setAllocatedOilA(allocatedOilA + (task.getOilB() != null ? task.getOilB() : 0.0));
                        int allocatedShipCount = finalSelectedHarbor.getAllocatedShipCount() != null ? finalSelectedHarbor.getAllocatedShipCount() : 0;
                        finalSelectedHarbor.setAllocatedShipCount(allocatedShipCount + 1);
                        dsTaskList2s.add(task);
                    });
                }
                break;
                default:
                    if(null != harborList && harborList.size() > 0){
                        int harborLen1 = harborList.size();
                        int shipCount1 = list.size();
                        int harborWithShipCount1 =  (int)Math.ceil((double) shipCount1 / harborLen1);
                        for(int i=0; i <shipCount1; i++){
                            DsTaskList2 task = list.get(i);
                            int harborTag = (int) Math.ceil((double)(i+1) / harborWithShipCount1) - 1;
                            DmHarbor2 dmHarbor2 = harborList.get(harborTag);
                            task.setHarborId(dmHarbor2.getPKID());
                            task.setHarborName(dmHarbor2.getHarborName());
                            dsTaskList2s.add(task);
                        }
                    }
            }
        }
        return dsTaskList2s;
    }
    
    /**
     * 把结果列表重新转换为统计格式
     * @param allocTaskList
     * @return
     */
    private List<TaskListStatis> covertTaskToStatis(List<DsTaskList2> allocTaskList){
        List<TaskListStatis> taskListStatis = new ArrayList<>();
        Map<Long, List<DsTaskList2>> tmpTaskMap = new HashMap<>();
        allocTaskList.stream().forEach(item -> {
            Long harborId = item.getHarborId();
            List<DsTaskList2> itemTaskLists = new ArrayList<>();
            if(tmpTaskMap.containsKey(harborId)){
                itemTaskLists = tmpTaskMap.get(harborId);
            }
            itemTaskLists.add(item);
            tmpTaskMap.put(harborId, itemTaskLists);
        });
 
        tmpTaskMap.forEach((harborId, tasks) -> {
            TaskListStatis statis = new TaskListStatis();
            DmHarbor2 harbor = iDmHarborService.selectDmHarborByPKID(harborId);
            statis.setHarbor(harbor);
            statis.setTasks(tasks);
 
            // 统计tasks数值字段的值
            DsTaskList2 taskStatis = new DsTaskList2();
            tasks.forEach(task -> {
                taskStatis.setOilB((taskStatis.getOilB() == null ? 0 : taskStatis.getOilB()) + (task.getOilB() == null ? 0 : task.getOilB()));
                taskStatis.setOilG((taskStatis.getOilG() == null ? 0 : taskStatis.getOilG()) + (task.getOilG() == null ? 0 : task.getOilG()));
                taskStatis.setOilA((taskStatis.getOilA() == null ? 0 : taskStatis.getOilA()) + (task.getOilA() == null ? 0 : task.getOilA()));
                taskStatis.setAmmoD((taskStatis.getAmmoD() == null ? 0 : taskStatis.getAmmoD()) + (task.getAmmoD() == null ? 0 : task.getAmmoD()));
                taskStatis.setAmmoP((taskStatis.getAmmoP() == null ? 0 : taskStatis.getAmmoP()) + (task.getAmmoP() == null ? 0 : task.getAmmoP()));
                taskStatis.setAmmoS((taskStatis.getAmmoS() == null ? 0 : taskStatis.getAmmoS()) + (task.getAmmoS() == null ? 0 : task.getAmmoS()));
                taskStatis.setAmmoO((taskStatis.getAmmoO() == null ? 0 : taskStatis.getAmmoO()) + (task.getAmmoO() == null ? 0 : task.getAmmoO()));
                taskStatis.setWATER((taskStatis.getWATER() == null ? 0 : taskStatis.getWATER()) + (task.getWATER() == null ? 0 : task.getWATER()));
                taskStatis.setWaterP((taskStatis.getWaterP() == null ? 0 : taskStatis.getWaterP()) + (task.getWaterP() == null ? 0 : task.getWaterP()));
                taskStatis.setFOOD((taskStatis.getFOOD() == null ? 0 : taskStatis.getFOOD()) + (task.getFOOD() == null ? 0 : task.getFOOD()));
                taskStatis.setFoodW((taskStatis.getFoodW() == null ? 0 : taskStatis.getFoodW()) + (task.getFoodW() == null ? 0 : task.getFoodW()));
                taskStatis.setFoodO((taskStatis.getFoodO() == null ? 0 : taskStatis.getFoodO()) + (task.getFoodO() == null ? 0 : task.getFoodO()));
            });
 
            statis.setStatis(taskStatis);
            taskListStatis.add(statis);
        });
 
        return  taskListStatis;
    }
 
    /**
     * 根据对象ID获取对应对象
     * @param list
     * @param id
     * @return
     */
    private DsTaskList2 getDsTaskListById(List<DsTaskList2> list, Long id){
        for(DsTaskList2 task : list){
            if(task.getPKID() == id){
                return task;
            }
        }
        return null;
    }
}