zhangzeli
5 天以前 7a8a994feafb8ef8333a9590bd637630c42609d6
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
 
 
package com.by4cloud.platform.processing.controller;
 
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.by4cloud.platform.common.core.util.R;
import com.by4cloud.platform.common.log.annotation.SysLog;
import com.by4cloud.platform.common.security.annotation.Inner;
import com.by4cloud.platform.processing.entity.*;
import com.by4cloud.platform.processing.service.*;
import com.by4cloud.platform.yunxiao.api.feign.RemotePonderation;
import com.by4cloud.platform.yunxiao.entity.ContractOrder;
import com.by4cloud.platform.yunxiao.entity.Ponderation;
import com.by4cloud.platform.yunxiao.utils.NumUtils;
import org.json.JSONException;
import org.springframework.security.access.prepost.PreAuthorize;
import com.by4cloud.platform.common.excel.annotation.ResponseExcel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
 
import javax.management.Query;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;
 
/**
 * 计划表
 *
 * @author zzl
 * @date 2025-10-17 09:47:25
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/plan" )
@Api(value = "plan", tags = "计划表管理")
public class PlanController {
 
    private final  PlanService planService;
 
    private final CarAvgTareService carAvgTareService;
 
    private final LoadUnloadAvgTimeService loadUnloadAvgTimeService;
 
    private final TransitAvgSchService transitAvgSchService;
 
    private final CustomerUseCarService customerUseCarService;
 
    private final RemotePonderation remotePonderation;
 
    /**
     * 分页查询
     * @param page 分页对象
     * @param plan 计划表
     * @return
     */
    @ApiOperation(value = "分页查询", notes = "分页查询")
    @GetMapping("/page" )
    @PreAuthorize("@pms.hasPermission('processing_plan_view')" )
    public R getPlanPage(Page page, Plan plan) {
        QueryWrapper<Plan> wrapper = new QueryWrapper<>();
        wrapper.eq(plan.getFyCompId()!=null,"fy_comp_id", plan.getFyCompId());
        wrapper.eq(plan.getCustomerId()!=null,"customer_id", plan.getCustomerId());
        wrapper.eq(plan.getCoalId()!=null,"coal_id", plan.getCoalId());
        wrapper.eq(plan.getMonth()!=null,"month", plan.getMonth());
        wrapper.orderByDesc("id");
        return R.ok(planService.page(page, wrapper));
    }
 
 
    /**
     * 通过id查询计划表
     * @param id id
     * @return R
     */
    @ApiOperation(value = "通过id查询", notes = "通过id查询")
    @GetMapping("/{id}" )
    @PreAuthorize("@pms.hasPermission('processing_plan_view')" )
    public R getById(@PathVariable("id" ) Integer id) {
        return R.ok(planService.getById(id));
    }
 
    /**
     * 新增计划表
     * @param plan 计划表
     * @return R
     */
    @ApiOperation(value = "新增计划表", notes = "新增计划表")
    @SysLog("新增计划表" )
    @PostMapping
    @PreAuthorize("@pms.hasPermission('processing_plan_add')" )
    public R save(@RequestBody Plan plan) {
        plan.setStatus(0);
        return R.ok(planService.save(plan));
    }
 
    /**
     * 修改计划表
     * @param plan 计划表
     * @return R
     */
    @ApiOperation(value = "修改计划表", notes = "修改计划表")
    @SysLog("修改计划表" )
    @PutMapping
    @PreAuthorize("@pms.hasPermission('processing_plan_edit')" )
    public R updateById(@RequestBody Plan plan) {
        return R.ok(planService.updateById(plan));
    }
 
    /**
     * 通过id删除计划表
     * @param id id
     * @return R
     */
    @ApiOperation(value = "通过id删除计划表", notes = "通过id删除计划表")
    @SysLog("通过id删除计划表" )
    @DeleteMapping("/{id}" )
    @PreAuthorize("@pms.hasPermission('processing_plan_del')" )
    public R removeById(@PathVariable Integer id) {
        return R.ok(planService.removeById(id));
    }
 
 
    /**
     * 导出excel 表格
     * @param plan 查询条件
     * @return excel 文件流
     */
    @ResponseExcel
    @GetMapping("/export")
    @PreAuthorize("@pms.hasPermission('processing_plan_export')" )
    public List<Plan> export(Plan plan) {
        return planService.list(Wrappers.query(plan));
    }
 
    /**
     * 根据计划生成磅单
     * @param id id
     * @return R
     */
    @ApiOperation(value = "根据计划生成磅单", notes = "根据计划生成磅单")
    @GetMapping("/genPonderationByPlan/{id}" )
    public R genPonderationByPlan(@PathVariable("id" ) Integer id) {
        Plan plan = planService.getById(id);
        if (plan.getStatus().equals(2)) return R.failed("计划已生成磅单");
        CustomerUseCar customerUseCar = customerUseCarService.getOne(new QueryWrapper<CustomerUseCar>().lambda()
                .eq(CustomerUseCar::getCompId,plan.getFyCompId())
                .eq(CustomerUseCar::getCustomerAddressId,plan.getCustomerAddressId())
                .last("limit 1"));
        if (customerUseCar == null){
            return R.failed("未找到客户使用车辆信息");
        }
        if (StrUtil.isEmpty(customerUseCar.getUseCars())) return R.failed("客户使用车辆信息为空");
        String[] carArray = customerUseCar.getUseCars().split(",");
        //客户使用车辆信息
        List<String> customerUseCars = Arrays.stream(carArray)
                .filter(s -> !s.trim().isEmpty()) // 过滤空字符串
                .collect(Collectors.toList());
        List<CarAvgTare> carAvgTares = carAvgTareService.list(new QueryWrapper<CarAvgTare>()
                .apply("FIND_IN_SET (vehicle_no,'"+ customerUseCar.getUseCars() +"' )")); //平均皮重
        if (carAvgTares.size()==0){
            return R.failed("未找到平均皮重信息");
        }
        List<LoadUnloadAvgTime> loadTimes = loadUnloadAvgTimeService.list(new QueryWrapper<LoadUnloadAvgTime>().lambda()
                .eq(LoadUnloadAvgTime::getCompId,plan.getFyCompId())
                .eq(LoadUnloadAvgTime::getCoalId,plan.getCoalId())); // 装载时间数据
        if (loadTimes.size()==0){
            return R.failed("未找到平均装卸时间信息");
        }
        List<TransitAvgSch> transitTimes = transitAvgSchService.list(new QueryWrapper<TransitAvgSch>().lambda()
                .eq(TransitAvgSch::getCustomerAddressId,plan.getCustomerAddressId())); // 运输时间数据
        if (transitTimes.size()==0){
            return R.failed("未找到平均运输时间数据信息");
        }
 
        // 4. 调用生成器
        R<List<LocalDate>> rDays = remotePonderation.getUseDays(plan.getFyCompId(),plan.getCoalId(),plan.getCustomerId(),plan.getMonth());
        List<LocalDate> validDates = new ArrayList<>();
        if (rDays !=null && rDays.getCode() == 0){
            validDates = rDays.getData();
        }
        if (validDates == null && validDates.size()==0) return R.failed("未找到化验日期");
        R<JSONObject> rMt = remotePonderation.getContractMt(plan.getFyCompId(),plan.getFiledId(),plan.getCoalId(),plan.getCustomerId(),plan.getCustomerAddressId(),plan.getMonth());
        Double contractMt = null;
        Integer orderId =null;
        if (rMt!=null){
            if (rMt.getCode()==0){
                JSONObject obj = rMt.getData();
                Object o = obj.get("contractMt");
                Object o1 = obj.get("orderId");
                if (o1!=null){
                    orderId = (Integer) o1;
                }
                if (o!=null){
                    contractMt = (Double) o;
                }
            }
        }
        if (contractMt == null) return R.failed("未找到合同水分");
        planService.update(new UpdateWrapper<Plan>().lambda().eq(Plan::getId,plan.getId())
                .set(Plan::getStatus,1));
        List<Ponderation> result = new ArrayList<>();
        try {
            result = planService.generateByDailyTarget(
                    plan, contractMt,
                    customerUseCars, carAvgTares,
                    loadTimes, transitTimes, validDates
            );
        }catch (Exception e){
            planService.update(new UpdateWrapper<Plan>().lambda().eq(Plan::getId,plan.getId())
                    .set(Plan::getStatus,3)
                    .set(Plan::getMsg,"生成失败:"+e.getMessage()));
        }
        if (result.size()==0){
            return R.failed("生成失败:未生成磅单");
        }
 
 
        // 5. 输出测试结果
        System.out.println("\n===== 结果汇总 =====");
        Double d = NumUtils.accurateDouble(result.stream().mapToDouble(Ponderation::getExecutive).sum(),2);
 
        //生成订单
        R<ContractOrder> orderR = remotePonderation.genOrderByPonList(d,orderId,plan.getIsSc(),plan.getId());
        if (orderR.getCode()!=0){
            planService.update(new UpdateWrapper<Plan>().lambda().eq(Plan::getId,plan.getId())
                    .set(Plan::getStatus,3)
                    .set(Plan::getMsg,"生成订单失败"+orderR.getMsg()));
            return R.failed("生成订单失败:"+orderR.getMsg());
        }
        ContractOrder order = orderR.getData();
        result.forEach(e -> {
            e.setIsSc(plan.getIsSc());
            e.setOrderId(order.getId());
            e.setOrderNumber(order.getNumber());
            e.setCoalPrice(order.getPrice());
            e.setCustomerAddressId(plan.getCustomerAddressId());
            e.setPlanId(plan.getId());
        });
        //保存磅单
        R r = remotePonderation.savePonderationList(result);
        if (r.getCode()==0){
            String msg = "生成成功:"+result.size()+"条,总湿煤量:"+d+"吨";
            planService.update(new UpdateWrapper<Plan>().lambda().eq(Plan::getId,plan.getId())
                    .set(Plan::getStatus,2)
                    .set(Plan::getMsg,msg));
        }else{
            planService.update(new UpdateWrapper<Plan>().lambda().eq(Plan::getId,plan.getId())
                    .set(Plan::getStatus,3)
                    .set(Plan::getMsg,"生成失败"));
        }
 
        // 按日期分组统计
//        Map<LocalDate, List<Ponderation>> dailyGroups = result.stream()
//                .collect(Collectors.groupingBy(pd -> {
//                    try {
//                        return pd.getCreateTime();
//                    } catch (Exception e) {
//                        return null;
//                    }
//                }));
//
//        dailyGroups.forEach((date, pds) -> {
//            if (date == null) return;
//            double dailyWetTotal = pds.stream().mapToDouble(Ponderation::getExecutive).sum();
//            System.out.printf("日期:%s,磅单数量:%d,总湿煤量:%.3f吨%n",
//                    date, pds.size(), dailyWetTotal);
//        });
 
        return R.ok(planService.getById(id));
    }
 
 
    /**
     * 导出excel 表格
     * @param
     * @return excel 文件流
     */
    @GetMapping("/test")
    @Inner(false)
    public List<Plan> test(Integer id) throws ParseException {
        // 1. 构建测试用的调整计划(Plan)
        Plan plan = planService.getById(id);
 
 
        // 3. 其他基础参数
        Double contractShui = 8.0; // 合同水分8%
        List<String> customerUseCars = Arrays.asList(
                "蒙B89304", "蒙KE2563", "蒙KJ8805", "蒙J96171", "蒙KK6930",
                "蒙KH6888", "蒙KA7628", "蒙B98074", "蒙KK5732", "蒙BA9621",
                "蒙B94915", "蒙KH3680", "蒙BA3739", "蒙KD0089", "蒙KG2566",
                "蒙BA9828", "蒙KN9535", "蒙B96122", "蒙KM6893", "蒙KQ0387",
                "蒙KL3388", "蒙KP0056", "蒙L19799", "蒙KK1717", "蒙KP1558",
                "蒙KN7319", "蒙BA2585", "蒙BA7295", "蒙KP8160", "蒙BA5195",
                "蒙BA3147", "蒙B83116", "蒙KJ1999", "蒙KJ2184", "蒙B88556",
                "蒙BA9919", "蒙L32942", "蒙KJ6722", "蒙BA4097", "蒙BB2580",
                "蒙KM8893", "蒙BB0009", "蒙BB3820", "蒙KD2315", "蒙KM0330",
                "蒙BC2566", "蒙BA3380", "蒙BA1629", "蒙L97419", "蒙L75659",
                "蒙BA2318", "蒙BB8013", "蒙BB8953", "蒙KJ3855", "蒙B93311",
                "蒙BA1821", "蒙KM6878", "蒙BA6376", "蒙B95225", "蒙B93408",
                "蒙KL6083", "蒙KE6162", "蒙B88437", "蒙KE8216", "蒙B96769",
                "晋BR0646", "蒙KB8319", "蒙A9T456", "蒙BB0851", "蒙KJ2637",
                "蒙BB7744", "蒙KM9558", "蒙B91481", "蒙KL3532", "蒙KP9639",
                "蒙KM3578", "蒙KQ2998", "蒙KJ0213", "蒙KM7836", "蒙KL3876",
                "蒙KL5887", "蒙KK0829", "鲁RQ2305", "蒙KE6806", "蒙KE2667",
                "蒙BB0128", "蒙KG6011", "蒙BA1237", "蒙KB1728", "蒙KL6716",
                "蒙KL8522", "蒙KB1028", "蒙BB7292", "蒙L97625", "蒙KK0957",
                "蒙B94838", "蒙BA3670", "蒙L66938", "蒙KN9772"
        );//测试车辆
        List<CarAvgTare> carAvgTares = carAvgTareService.list(); //平均皮重
        List<LoadUnloadAvgTime> loadTimes = loadUnloadAvgTimeService.list(new QueryWrapper<LoadUnloadAvgTime>().lambda()
                .eq(LoadUnloadAvgTime::getCompId,plan.getFyCompId())
                .eq(LoadUnloadAvgTime::getCoalId,plan.getCoalId())); // 装载时间数据
        List<TransitAvgSch> transitTimes = transitAvgSchService.list(new QueryWrapper<TransitAvgSch>().lambda()
                .eq(TransitAvgSch::getCustomerAddressId,plan.getCustomerAddressId())); // 运输时间数据
        List<LocalDate> holidays = new ArrayList<>(); // 测试月份无节假日
 
 
        // 4. 调用生成器
 
        List<Ponderation> result = planService.generateByDailyTarget(
                plan, contractShui,
                customerUseCars, carAvgTares,
                loadTimes, transitTimes, holidays
        );
 
 
        // 5. 输出测试结果
        System.out.println("\n===== 测试结果汇总 =====");
        System.out.println("总生成磅单数量:" + result.size());
 
        // 按日期分组统计
        Map<LocalDate, List<Ponderation>> dailyGroups = result.stream()
                .collect(Collectors.groupingBy(pd -> {
                    try {
                        return new SimpleDateFormat("yyyy-MM-dd").parse(pd.getInTime()).toInstant()
                                .atZone(java.time.ZoneId.systemDefault()).toLocalDate();
                    } catch (ParseException e) {
                        return null;
                    }
                }));
 
        dailyGroups.forEach((date, pds) -> {
            if (date == null) return;
            double dailyWetTotal = pds.stream().mapToDouble(Ponderation::getExecutive).sum();
            System.out.printf("日期:%s,磅单数量:%d,总湿煤量:%.3f吨%n",
                    date, pds.size(), dailyWetTotal);
        });
        return planService.list(Wrappers.query(plan));
    }
 
    // 辅助方法:创建测试用的调整计划
    private static Plan createTestPlan() throws ParseException {
        Plan plan = new Plan();
        plan.setMonth(new SimpleDateFormat("yyyy-MM").parse("2024-09")); // 目标月份:2024年9月
        plan.setFyCompId(101); // 发运矿别ID
        plan.setCustomerId(201); // 客户ID
        plan.setCoalId(301); // 煤种ID(1/3焦煤)
        plan.setQuantity(5000.0); // 总干煤目标:5000吨
        return plan;
    }
 
 
 
 
    // 辅助方法:创建测试用的车辆皮重数据
    private static List<CarAvgTare> createTestCarAvgTares() {
        List<CarAvgTare> list = new ArrayList<>();
        list.add(createCarAvgTare("冀A12345", 13.0, 13.5, 13.2, 0.5));
        list.add(createCarAvgTare("冀B67890", 12.5, 13.0, 12.8, 0.5));
        list.add(createCarAvgTare("冀C11223", 13.2, 13.8, 13.5, 0.6));
        return list;
    }
 
    private static CarAvgTare createCarAvgTare(String vehicleNo, double minTare, double maxTare, double avgTare, double diff) {
        CarAvgTare car = new CarAvgTare();
        car.setVehicleNo(vehicleNo);
        car.setMinTare(minTare);
        car.setMaxTare(maxTare);
        car.setAvgTare(avgTare);
        car.setWeightDifference(diff);
        return car;
    }
 
 
    // 辅助方法:创建测试用的装载时间数据
    private static List<LoadUnloadAvgTime> createTestLoadTimes() {
        LoadUnloadAvgTime time = new LoadUnloadAvgTime();
        time.setCoalId(301); // 匹配煤种ID
        time.setMinTime(30); // 最小30分钟
        time.setAvgTime(45); // 平均45分钟
        time.setMaxTime(60); // 最大60分钟
        return Collections.singletonList(time);
    }
 
 
    // 辅助方法:创建测试用的运输时间数据
    private static List<TransitAvgSch> createTestTransitTimes() {
        TransitAvgSch time = new TransitAvgSch();
        time.setFyCompId(101); // 匹配发运矿别ID
        time.setCustomerAddressId(201); // 匹配客户ID
        time.setTransitType(1); // 路运
        time.setMinTime(60); // 最小60分钟
        time.setAvgTime(90); // 平均90分钟
        return Collections.singletonList(time);
    }
}