Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
package org.nl.wms.pda_manage.cockpit.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaIgnore;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nl.common.anno.Log;
|
||||
import org.nl.common.domain.exception.BadRequestException;
|
||||
import org.nl.wms.pda_manage.cockpit.service.CockpitService;
|
||||
import org.nl.wms.pda_manage.cockpit.service.dao.PointInfo;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @Author: gbx
|
||||
* @Description: 看板接口
|
||||
* @Date: 2024/11/4
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/board")
|
||||
@Slf4j
|
||||
@SaIgnore
|
||||
public class CockpitController {
|
||||
|
||||
@Autowired
|
||||
private CockpitService cockpitService;
|
||||
|
||||
|
||||
@PostMapping("/queryPickingPoint")
|
||||
@Log("查询拣选台")
|
||||
public ResponseEntity<Object> queryPickingPoint() {
|
||||
return new ResponseEntity<>(cockpitService.queryPickingPoint(), HttpStatus.OK);
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/synthesizeInfo")
|
||||
@Log("货位综合分析")
|
||||
public ResponseEntity<Object> synthesizeInfo() {
|
||||
return new ResponseEntity<>(cockpitService.synthesizeInfo(), HttpStatus.OK);
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/getMaterialsInfo")
|
||||
@Log("领料分析")
|
||||
public ResponseEntity<Object> getMaterialsInfo() {
|
||||
return new ResponseEntity<>(cockpitService.getMaterialsInfo(), HttpStatus.OK);
|
||||
}
|
||||
|
||||
@PostMapping("/pickingInfo")
|
||||
@Log("拣选任务")
|
||||
public ResponseEntity<Object> pickingInfo(@RequestBody PointInfo pointInfo) {
|
||||
if (pointInfo == null) {
|
||||
throw new BadRequestException("拣选站台编号不能为空");
|
||||
}
|
||||
return new ResponseEntity<>(cockpitService.pickingInfo(pointInfo.getCode()), HttpStatus.OK);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package org.nl.wms.pda_manage.cockpit.service;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.nl.wms.dispatch_manage.point.service.dao.SchBasePoint;
|
||||
import org.nl.wms.pda_manage.cockpit.service.dao.TaskInfo;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author: gbx
|
||||
* @Description:
|
||||
* @Date: 2024/11/4
|
||||
*/
|
||||
public interface CockpitService {
|
||||
|
||||
/**
|
||||
* 查询拣选台
|
||||
*/
|
||||
List<SchBasePoint> queryPickingPoint();
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 货位综合分析
|
||||
*/
|
||||
JSONObject synthesizeInfo();
|
||||
|
||||
|
||||
/**
|
||||
* 领料分析
|
||||
*/
|
||||
JSONObject getMaterialsInfo();
|
||||
|
||||
/**
|
||||
* 拣选任务
|
||||
*/
|
||||
List<TaskInfo> pickingInfo(String code);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package org.nl.wms.pda_manage.cockpit.service.dao;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author gbx
|
||||
* @since 2024-01-08
|
||||
*/
|
||||
@Data
|
||||
public class DayData {
|
||||
private String item_name;
|
||||
private String item_qty;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package org.nl.wms.pda_manage.cockpit.service.dao;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 点位
|
||||
*
|
||||
* @author gbx
|
||||
* @since 2024-01-11
|
||||
*/
|
||||
@Data
|
||||
public class PointInfo {
|
||||
private String code;
|
||||
private String stor_code;
|
||||
private String point_code;
|
||||
private String product_area;
|
||||
private String vehicle_code;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package org.nl.wms.pda_manage.cockpit.service.dao;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.apache.poi.hpsf.Decimal;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 任务
|
||||
*
|
||||
* @author gbx
|
||||
* @since 2024-01-11
|
||||
*/
|
||||
@Data
|
||||
@ToString
|
||||
public class TaskInfo {
|
||||
private BigDecimal qty;
|
||||
private String vehicle_code;
|
||||
private String create_time;
|
||||
private String update_time;
|
||||
private String stor_code;
|
||||
private String task_type;
|
||||
private String material_name;
|
||||
private String material_code;
|
||||
private String material_spec;
|
||||
private BigDecimal assign_qty;
|
||||
private BigDecimal single_weight;
|
||||
//理论数量
|
||||
private BigDecimal theory_qty;
|
||||
//称重
|
||||
private BigDecimal actual_weight=BigDecimal.ZERO;
|
||||
//剩余数量
|
||||
private BigDecimal remaining_qty;
|
||||
private String form_data;
|
||||
private String product_area;
|
||||
}
|
||||
@@ -0,0 +1,440 @@
|
||||
package org.nl.wms.pda_manage.cockpit.service.impl;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.nl.wms.base_manage.material.service.dao.MdMeMaterialbase;
|
||||
import org.nl.wms.dispatch_manage.point.service.dao.SchBasePoint;
|
||||
import org.nl.wms.dispatch_manage.point.service.impl.SchBasePointServiceImpl;
|
||||
import org.nl.wms.pda_manage.cockpit.service.CockpitService;
|
||||
import org.nl.wms.pda_manage.cockpit.service.dao.PointInfo;
|
||||
import org.nl.wms.pda_manage.cockpit.service.dao.TaskInfo;
|
||||
import org.nl.wms.pda_manage.cockpit.service.mapper.CockpitMapper;
|
||||
import org.nl.wms.stor_manage.struct.service.dao.StIvtStructattr;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Author: gbx
|
||||
* @Description:
|
||||
* @Date: 2024/11/4
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
@EnableScheduling
|
||||
public class CockpitServiceImpl implements CockpitService {
|
||||
|
||||
@Autowired
|
||||
private CockpitMapper cockpitMapper;
|
||||
|
||||
|
||||
@Resource
|
||||
@Qualifier("meshandlerPool")
|
||||
private ThreadPoolExecutor pool;
|
||||
|
||||
@Resource
|
||||
private SchBasePointServiceImpl schBasePointServiceImpl;
|
||||
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd");
|
||||
LocalDate today = LocalDate.now();
|
||||
|
||||
|
||||
/**
|
||||
* 查询拣选台
|
||||
*/
|
||||
@Override
|
||||
public List<SchBasePoint> queryPickingPoint() {
|
||||
return schBasePointServiceImpl.list(new LambdaQueryWrapper<SchBasePoint>().eq(SchBasePoint::getRegion_code, "PICK01").eq(SchBasePoint::getIs_used, true));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 货位综合分析
|
||||
*/
|
||||
@Override
|
||||
public JSONObject synthesizeInfo() {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
//货位使用
|
||||
CompletableFuture<List<Map<String, Object>>> task1 = CompletableFuture.supplyAsync(() -> {
|
||||
Integer total1 = 0;
|
||||
Integer used1 = 0;
|
||||
Integer free1 = 0;
|
||||
String percent1 = "0%";
|
||||
Integer total2 = 0;
|
||||
Integer used2 = 0;
|
||||
Integer free2 = 0;
|
||||
String percent2 = "0%";
|
||||
JSONObject item1 = new JSONObject();
|
||||
JSONObject item3 = new JSONObject();
|
||||
long startTime1 = System.currentTimeMillis();
|
||||
//库存信息
|
||||
List<StIvtStructattr> ivtList = cockpitMapper.queryStorage();
|
||||
if (ObjectUtil.isNotEmpty(ivtList)) {
|
||||
//料箱库
|
||||
List<StIvtStructattr> fstockList = ivtList.stream().filter(r -> "FStockId".equals(r.getStor_code())).collect(Collectors.toList());
|
||||
if (ObjectUtil.isNotEmpty(fstockList)) {
|
||||
total1 = fstockList.size();
|
||||
if (total1 > 0) {
|
||||
// 计算已使用的数量
|
||||
long used = fstockList.stream().filter(r -> StringUtils.isNotEmpty(r.getVehicle_code())).count();
|
||||
used1 = (int) used;
|
||||
free1 = total1 - used1;
|
||||
double percentage = (double) used1 / total1 * 100;
|
||||
BigDecimal bd = new BigDecimal(percentage).setScale(2, RoundingMode.HALF_UP);
|
||||
double roundedPercentage = bd.doubleValue();
|
||||
percent1 = roundedPercentage + "%";
|
||||
}
|
||||
}
|
||||
//托盘库
|
||||
List<StIvtStructattr> fstockPalletList = ivtList.stream().filter(r -> "FStockPallet".equals(r.getStor_code())).collect(Collectors.toList());
|
||||
if (ObjectUtil.isNotEmpty(fstockPalletList)) {
|
||||
total2 = fstockPalletList.size();
|
||||
if (total2 > 0) {
|
||||
long used = fstockPalletList.stream().filter(r -> StringUtils.isNotEmpty(r.getVehicle_code())).count();
|
||||
used2 = (int) used;
|
||||
free2 = total2 - used2;
|
||||
double percentage = (double) used2 / total2 * 100;
|
||||
BigDecimal bd = new BigDecimal(percentage).setScale(2, RoundingMode.HALF_UP);
|
||||
double roundedPercentage = bd.doubleValue();
|
||||
percent2 = roundedPercentage + "%";
|
||||
}
|
||||
}
|
||||
}
|
||||
item1.put("total", total1);
|
||||
item1.put("used", used1);
|
||||
item1.put("free", free1);
|
||||
item1.put("percent", percent1);
|
||||
item3.put("total", total2);
|
||||
item3.put("used", used2);
|
||||
item3.put("free", free2);
|
||||
item3.put("percent", percent2);
|
||||
jsonObject.put("lx_used", item1);
|
||||
jsonObject.put("tp_used", item3);
|
||||
log.info("获取货位使用信息耗时:{}", System.currentTimeMillis() - startTime1);
|
||||
return null;
|
||||
}, pool);
|
||||
task1.exceptionally((e) -> {
|
||||
log.error("获取货位使用信息异常:{}", e.getMessage(), e);
|
||||
return null;
|
||||
});
|
||||
CompletableFuture<List<Map<String, Object>>> task2 = CompletableFuture.supplyAsync(() -> {
|
||||
long startTime2 = System.currentTimeMillis();
|
||||
Integer total1 = 0;
|
||||
Integer box1 = 0;
|
||||
String time1 = "0h";
|
||||
Integer total2 = 0;
|
||||
Integer box2 = 0;
|
||||
String time2 = "0h";
|
||||
Integer total3 = 0;
|
||||
Integer box3 = 0;
|
||||
String time3 = "0h";
|
||||
Integer total4 = 0;
|
||||
Integer box4 = 0;
|
||||
String time4 = "0h";
|
||||
JSONArray item2 = new JSONArray();
|
||||
JSONArray item4 = new JSONArray();
|
||||
JSONObject obj1 = new JSONObject();
|
||||
JSONObject obj2 = new JSONObject();
|
||||
JSONObject obj3 = new JSONObject();
|
||||
JSONObject obj4 = new JSONObject();
|
||||
obj1.put("total", total1);
|
||||
obj1.put("box", box1);
|
||||
obj1.put("time", time1);
|
||||
obj2.put("total", total2);
|
||||
obj2.put("box", box2);
|
||||
obj2.put("time", time2);
|
||||
obj3.put("total", total3);
|
||||
obj3.put("box", box3);
|
||||
obj3.put("time", time3);
|
||||
obj4.put("total", total4);
|
||||
obj4.put("box", box4);
|
||||
obj4.put("time", time4);
|
||||
List<TaskInfo> taskList = cockpitMapper.getTaskListByDays(0);
|
||||
if (ObjectUtil.isNotEmpty(taskList)) {
|
||||
//料箱库入库
|
||||
List<TaskInfo> stockList1 = taskList.stream()
|
||||
.filter(r -> Integer.parseInt(r.getTask_type()) <= 14 && "FStockId".equals(r.getStor_code()))
|
||||
.collect(Collectors.toList());
|
||||
if (ObjectUtil.isNotEmpty(stockList1)) {
|
||||
obj1 = getElapsedTime(obj1, stockList1);
|
||||
}
|
||||
//料箱库出库
|
||||
List<TaskInfo> stockList2 = taskList.stream()
|
||||
.filter(r -> Integer.parseInt(r.getTask_type()) >= 20 && Integer.parseInt(r.getTask_type()) <= 25 && "FStockId".equals(r.getStor_code()))
|
||||
.collect(Collectors.toList());
|
||||
if (ObjectUtil.isNotEmpty(stockList2)) {
|
||||
obj2 = getElapsedTime(obj2, stockList2);
|
||||
}
|
||||
//托盘库入库
|
||||
List<TaskInfo> stockList3 = taskList.stream().filter(r -> "30".equals(r.getTask_type()) && "FStockPallet".equals(r.getStor_code())).collect(Collectors.toList());
|
||||
if (ObjectUtil.isNotEmpty(stockList3)) {
|
||||
obj3 = getElapsedTime(obj3, stockList3);
|
||||
}
|
||||
//托盘库出库
|
||||
List<TaskInfo> stockList4 = taskList.stream().filter(r -> "40".equals(r.getTask_type()) && "FStockPallet".equals(r.getStor_code())).collect(Collectors.toList());
|
||||
if (ObjectUtil.isNotEmpty(stockList4)) {
|
||||
obj4 = getElapsedTime(obj4, stockList4);
|
||||
}
|
||||
}
|
||||
item2.add(obj1);
|
||||
item2.add(obj2);
|
||||
item4.add(obj3);
|
||||
item4.add(obj4);
|
||||
jsonObject.put("lx_task", item2);
|
||||
jsonObject.put("tp_task", item4);
|
||||
log.info("获取今日出入库任务信息耗时:{}", System.currentTimeMillis() - startTime2);
|
||||
return null;
|
||||
}, pool);
|
||||
task2.exceptionally((e) ->
|
||||
{
|
||||
log.error("获取今日出入库任务信息异常:{}", e.getMessage(), e);
|
||||
return null;
|
||||
});
|
||||
CompletableFuture<List<Map<String, Object>>> task3 = CompletableFuture.supplyAsync(() -> {
|
||||
long startTime3 = System.currentTimeMillis();
|
||||
JSONArray jsonArray1 = new JSONArray();
|
||||
JSONArray jsonArray2 = new JSONArray();
|
||||
//前5名
|
||||
JSONObject obj0 = new JSONObject();
|
||||
//其他
|
||||
JSONObject obj1 = new JSONObject();
|
||||
JSONObject obj2 = new JSONObject();
|
||||
JSONObject obj3 = new JSONObject();
|
||||
List<MdMeMaterialbase> materList = cockpitMapper.getMaterInfos();
|
||||
if (ObjectUtil.isNotEmpty(materList)) {
|
||||
List<MdMeMaterialbase> fstockList = materList.stream().filter(r -> "FStockId".equals(r.getProduct_area())).collect(Collectors.toList());
|
||||
List<MdMeMaterialbase> fstockPalletList = materList.stream().filter(r -> "FStockPallet".equals(r.getProduct_area())).collect(Collectors.toList());
|
||||
if (ObjectUtil.isNotEmpty(fstockList)) {
|
||||
getMaterialAnalysis(jsonArray1, obj0, obj1, fstockList);
|
||||
} else {
|
||||
obj0.put("total", "0");
|
||||
jsonArray1.add(obj0);
|
||||
}
|
||||
if (ObjectUtil.isNotEmpty(fstockPalletList)) {
|
||||
getMaterialAnalysis(jsonArray2, obj2, obj3, fstockPalletList);
|
||||
} else {
|
||||
obj1.put("total", "0");
|
||||
jsonArray2.add(obj1);
|
||||
}
|
||||
} else {
|
||||
obj0.put("total", "0");
|
||||
obj1.put("total", "0");
|
||||
jsonArray1.add(obj0);
|
||||
jsonArray2.add(obj1);
|
||||
}
|
||||
jsonObject.put("lx_inventory", jsonArray1);
|
||||
jsonObject.put("tp_inventory", jsonArray2);
|
||||
log.info("获取实时物料库存信息耗时:{}", System.currentTimeMillis() - startTime3);
|
||||
return null;
|
||||
}, pool);
|
||||
task3.exceptionally((e) ->
|
||||
{
|
||||
log.error("获取实时物料库存信息异常:{}", e.getMessage(), e);
|
||||
return null;
|
||||
});
|
||||
CompletableFuture<List<Map<String, Object>>> task4 = CompletableFuture.supplyAsync(() -> {
|
||||
long startTime4 = System.currentTimeMillis();
|
||||
List<Map<String, Object>> lx_in_default = new ArrayList<>();
|
||||
List<Map<String, Object>> lx_out_default = new ArrayList<>();
|
||||
List<Map<String, Object>> tp_in_default = new ArrayList<>();
|
||||
List<Map<String, Object>> tp_out_default = new ArrayList<>();
|
||||
List<TaskInfo> result = cockpitMapper.getTaskCountsByDays();
|
||||
//料箱库入库
|
||||
List<TaskInfo> stockList1 = result.stream()
|
||||
.filter(r -> Integer.parseInt(r.getTask_type()) <= 14 && "FStockId".equals(r.getStor_code()))
|
||||
.collect(Collectors.toList());
|
||||
//料箱库出库
|
||||
List<TaskInfo> stockList2 = result.stream()
|
||||
.filter(r -> Integer.parseInt(r.getTask_type()) >= 20 && Integer.parseInt(r.getTask_type()) <= 25 && "FStockId".equals(r.getStor_code()))
|
||||
.collect(Collectors.toList());
|
||||
//托盘库入库
|
||||
List<TaskInfo> stockList3 = result.stream().filter(r -> "30".equals(r.getTask_type()) && "FStockPallet".equals(r.getStor_code())).collect(Collectors.toList());
|
||||
//托盘库出库
|
||||
List<TaskInfo> stockList4 = result.stream().filter(r -> "40".equals(r.getTask_type()) && "FStockPallet".equals(r.getStor_code())).collect(Collectors.toList());
|
||||
//计算每天的数量
|
||||
getWeekWorkStatistics(stockList1, lx_in_default, 7);
|
||||
getWeekWorkStatistics(stockList2, lx_out_default, 7);
|
||||
getWeekWorkStatistics(stockList3, tp_in_default, 7);
|
||||
getWeekWorkStatistics(stockList4, tp_out_default, 7);
|
||||
jsonObject.put("lx_in_week", lx_in_default);
|
||||
jsonObject.put("lx_out_week", lx_out_default);
|
||||
jsonObject.put("tp_in_week", tp_in_default);
|
||||
jsonObject.put("tp_out_week", tp_out_default);
|
||||
log.info("获取7天出入库趋势信息耗时:{}", System.currentTimeMillis() - startTime4);
|
||||
return null;
|
||||
}, pool);
|
||||
task4.exceptionally((e) ->
|
||||
{
|
||||
log.error("获取7天出入库趋势信息异常:{}", e.getMessage(), e);
|
||||
return null;
|
||||
});
|
||||
CompletableFuture<Void> allQuery = CompletableFuture.allOf(task1, task2, task3, task4);
|
||||
CompletableFuture<JSONObject> future = allQuery.thenApply((result) -> jsonObject).exceptionally((e) -> {
|
||||
log.error("获取综合信息异常:{}", e.getMessage(), e);
|
||||
return null;
|
||||
});
|
||||
future.join();
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 拣选任务
|
||||
*/
|
||||
@Override
|
||||
public List<TaskInfo> pickingInfo(String code) {
|
||||
List<TaskInfo> taskList = cockpitMapper.getPickingTask(code);
|
||||
taskList.forEach(r -> {
|
||||
if (StringUtils.isNotBlank(r.getForm_data())) {
|
||||
PointInfo pointInfo = JSON.parseObject(r.getForm_data(), PointInfo.class);
|
||||
if (StringUtils.isNotBlank(pointInfo.getProduct_area())) {
|
||||
r.setProduct_area(pointInfo.getProduct_area());
|
||||
}
|
||||
}
|
||||
BigDecimal theoryQty = BigDecimal.ZERO;
|
||||
//根据称重信息计算理论数量
|
||||
if (r.getActual_weight().compareTo(BigDecimal.ZERO) > 0) {
|
||||
//计算理论重量
|
||||
theoryQty = r.getActual_weight().divide(r.getSingle_weight(), 0, RoundingMode.DOWN);
|
||||
r.setActual_weight(r.getActual_weight().setScale(2, RoundingMode.DOWN));
|
||||
}
|
||||
r.setTheory_qty(theoryQty);
|
||||
//计算剩余数量
|
||||
BigDecimal remaining_qty = r.getQty().subtract(theoryQty).max(BigDecimal.ZERO).setScale(0, RoundingMode.DOWN);
|
||||
r.setRemaining_qty(remaining_qty);
|
||||
//小数点
|
||||
r.setSingle_weight(r.getSingle_weight().setScale(2, RoundingMode.DOWN));
|
||||
r.setAssign_qty(r.getAssign_qty().setScale(0, RoundingMode.DOWN));
|
||||
r.setQty(r.getQty().setScale(0, RoundingMode.DOWN));
|
||||
});
|
||||
return taskList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 领料分析
|
||||
*/
|
||||
@Override
|
||||
public JSONObject getMaterialsInfo() {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
|
||||
private static void getMaterialAnalysis(JSONArray jsonArray, JSONObject obj0, JSONObject obj1, List<MdMeMaterialbase> materList) {
|
||||
//物料分组
|
||||
Map<String, BigDecimal> groupedMaterials = materList.stream()
|
||||
.collect(Collectors.groupingBy(
|
||||
MdMeMaterialbase::getMaterial_name,
|
||||
Collectors.reducing(BigDecimal.ZERO, MdMeMaterialbase::getNet_weight, BigDecimal::add)
|
||||
));
|
||||
//排序
|
||||
List<Map.Entry<String, BigDecimal>> sortedMaterials = groupedMaterials.entrySet().stream()
|
||||
.sorted((m1, m2) -> m2.getValue().compareTo(m1.getValue()))
|
||||
.collect(Collectors.toList());
|
||||
// 计算所有物料的总数量
|
||||
BigDecimal total = sortedMaterials.stream()
|
||||
.map(Map.Entry::getValue)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
List<Map.Entry<String, BigDecimal>> top5Materials = sortedMaterials.stream()
|
||||
.limit(5)
|
||||
.collect(Collectors.toList());
|
||||
obj0.put("total", total);
|
||||
jsonArray.add(obj0);
|
||||
//前5名物料占比
|
||||
for (Map.Entry<String, BigDecimal> entry : top5Materials) {
|
||||
BigDecimal percentage = entry.getValue().multiply(new BigDecimal("100")).divide(total, 2, RoundingMode.HALF_UP);
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("name", entry.getKey());
|
||||
obj.put("qty", entry.getValue());
|
||||
obj.put("percent", percentage + "%");
|
||||
jsonArray.add(obj);
|
||||
}
|
||||
//其他物料
|
||||
BigDecimal otherWeight = sortedMaterials.stream()
|
||||
.skip(5)
|
||||
.map(Map.Entry::getValue)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
if (otherWeight.compareTo(BigDecimal.ZERO) > 0) {
|
||||
//其他物料占比
|
||||
BigDecimal otherPercentage = otherWeight.multiply(new BigDecimal("100")).divide(total, 2, RoundingMode.HALF_UP);
|
||||
obj1.put("name", "其他");
|
||||
obj1.put("qty", otherWeight);
|
||||
obj1.put("percent", otherPercentage + "%");
|
||||
jsonArray.add(obj1);
|
||||
}
|
||||
}
|
||||
|
||||
private static JSONObject getElapsedTime(JSONObject item, List<TaskInfo> stockList1) {
|
||||
//计算数量
|
||||
BigDecimal total = stockList1.stream().map(TaskInfo::getQty)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add).setScale(0, RoundingMode.HALF_UP);
|
||||
item.put("total", total);
|
||||
//计算箱数
|
||||
int box = stockList1.stream()
|
||||
.mapToInt(taskInfo -> taskInfo.getVehicle_code().split(",").length)
|
||||
.sum();
|
||||
item.put("box", box);
|
||||
//计算时间间隔
|
||||
Duration totalDuration = stockList1.stream()
|
||||
.map(task -> {
|
||||
if (StringUtils.isNotBlank(task.getCreate_time()) && StringUtils.isNotBlank(task.getUpdate_time())) {
|
||||
LocalDateTime createTime = LocalDateTime.parse(task.getCreate_time(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||
LocalDateTime updateTime = LocalDateTime.parse(task.getUpdate_time(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||
return Duration.between(createTime, updateTime);
|
||||
} else {
|
||||
return Duration.ZERO;
|
||||
}
|
||||
})
|
||||
.reduce(Duration.ZERO, Duration::plus);
|
||||
double totalHours = totalDuration.toMillis() / 1000.0 / 3600.0;
|
||||
BigDecimal roundedTotalHours = BigDecimal.valueOf(totalHours).setScale(1, RoundingMode.HALF_UP);
|
||||
item.put("time", roundedTotalHours + "h");
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
private void getWeekWorkStatistics(List<TaskInfo> real_qty, List<Map<String, Object>> real_qty_default, Integer days) {
|
||||
for (int i = 0; i < days; i++) {
|
||||
Map<String, Object> item = new HashMap<>();
|
||||
item.put("total_qty", "0");
|
||||
item.put("date", today.minusDays(i).format(formatter));
|
||||
real_qty_default.add(item);
|
||||
}
|
||||
if (ObjectUtil.isNotEmpty(real_qty)) {
|
||||
Map<String, BigDecimal> ghRealQtyMap = real_qty.stream()
|
||||
.collect(Collectors.toMap(
|
||||
TaskInfo::getCreate_time,
|
||||
TaskInfo::getQty
|
||||
));
|
||||
real_qty_default.forEach(tbItem -> {
|
||||
String date = (String) tbItem.get("date");
|
||||
if (ghRealQtyMap.containsKey(date)) {
|
||||
tbItem.put("total_qty", ghRealQtyMap.get(date));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package org.nl.wms.pda_manage.cockpit.service.mapper;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.nl.wms.base_manage.material.service.dao.MdMeMaterialbase;
|
||||
import org.nl.wms.base_manage.sect.service.dao.StIvtSectattr;
|
||||
import org.nl.wms.dispatch_manage.task.service.dao.SchBaseTask;
|
||||
import org.nl.wms.pda_manage.cockpit.service.dao.TaskInfo;
|
||||
import org.nl.wms.stor_manage.struct.service.dao.StIvtStructattr;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Author: gbx
|
||||
* @Description:
|
||||
* @Date: 2024/11/4
|
||||
*/
|
||||
public interface CockpitMapper {
|
||||
|
||||
//查询仓位
|
||||
List<StIvtStructattr> queryStorage();
|
||||
|
||||
//按天数查询任务信息
|
||||
List<TaskInfo> getTaskListByDays(@Param("days") int days);
|
||||
|
||||
//查询任务数量
|
||||
List<TaskInfo> getTaskCountsByDays();
|
||||
|
||||
//查询拣选任务
|
||||
List<TaskInfo> getPickingTask(@Param("code") String code);
|
||||
|
||||
//查询仓位物料分布
|
||||
List<MdMeMaterialbase> getMaterInfos();
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="org.nl.wms.pda_manage.cockpit.service.mapper.CockpitMapper">
|
||||
<select id="queryStorage" resultType="org.nl.wms.stor_manage.struct.service.dao.StIvtStructattr">
|
||||
SELECT
|
||||
stor_code,
|
||||
vehicle_code
|
||||
FROM
|
||||
st_ivt_structattr
|
||||
WHERE
|
||||
stor_code IN ('FStockId','FStockPallet')
|
||||
AND is_used = '1'
|
||||
</select>
|
||||
<select id="getTaskListByDays" resultType="org.nl.wms.pda_manage.cockpit.service.dao.TaskInfo">
|
||||
SELECT
|
||||
i.`bill_type` as task_type,
|
||||
i.create_time,
|
||||
i.update_time,
|
||||
d.stor_code,
|
||||
d.qty,
|
||||
d.vehicle_code
|
||||
FROM
|
||||
`st_ivt_iostorinvdtl` d
|
||||
LEFT JOIN st_ivt_iostorinv i ON d.inv_id = i.id
|
||||
WHERE
|
||||
d.`status` = '80'
|
||||
AND i.create_time >=
|
||||
<choose>
|
||||
<when test="days == 0">
|
||||
CURDATE()
|
||||
</when>
|
||||
<otherwise>
|
||||
CURDATE() - INTERVAL #{days} DAY
|
||||
</otherwise>
|
||||
</choose>
|
||||
</select>
|
||||
<select id="getTaskCountsByDays" resultType="org.nl.wms.pda_manage.cockpit.service.dao.TaskInfo">
|
||||
SELECT
|
||||
i.`bill_type` as task_type,
|
||||
DATE_FORMAT(i.create_time,'%m-%d') as create_time ,
|
||||
d.stor_code,
|
||||
d.qty,
|
||||
d.vehicle_code
|
||||
FROM
|
||||
`st_ivt_iostorinvdtl` d
|
||||
LEFT JOIN st_ivt_iostorinv i ON d.inv_id = i.id
|
||||
WHERE
|
||||
d.`status` = '80'
|
||||
AND i.create_time >= CURDATE() - INTERVAL 7 DAY
|
||||
</select>
|
||||
<select id="getPickingTask" resultType="org.nl.wms.pda_manage.cockpit.service.dao.TaskInfo">
|
||||
SELECT
|
||||
p.`code` as task_type,
|
||||
d.vehicle_code,
|
||||
m.material_name,
|
||||
m.material_spec,
|
||||
d.qty,
|
||||
d.assign_qty,
|
||||
m.single_weight,
|
||||
p.form_data
|
||||
FROM
|
||||
pm_form_data d
|
||||
INNER JOIN pm_form_data p
|
||||
ON d.parent_id = p.id
|
||||
LEFT JOIN md_me_materialbase m
|
||||
ON d.material_id = m.material_id
|
||||
WHERE
|
||||
JSON_UNQUOTE(JSON_EXTRACT(p.form_data, '$.point_code')) = #{code}
|
||||
AND p.status = '10'
|
||||
ORDER BY d.create_time
|
||||
LIMIT 2;
|
||||
</select>
|
||||
<select id="getMaterInfos" resultType="org.nl.wms.base_manage.material.service.dao.MdMeMaterialbase">
|
||||
SELECT t.stor_code as product_area,
|
||||
m.material_name,
|
||||
w.material_id,
|
||||
w.qty as net_weight
|
||||
FROM st_ivt_structattr t
|
||||
LEFT JOIN
|
||||
(SELECT w.*, ROW_NUMBER() OVER ( PARTITION BY w.struct_code ORDER BY w.update_time DESC ) AS rn
|
||||
FROM st_ivt_structivtflow w)
|
||||
AS w ON t.vehicle_code = w.vehicle_code
|
||||
AND t.struct_code = w.struct_code
|
||||
LEFT JOIN md_me_materialbase m ON W.material_id = m.material_id
|
||||
WHERE w.rn = 1;
|
||||
</select>
|
||||
</mapper>
|
||||
Reference in New Issue
Block a user