6 changed files with 483 additions and 0 deletions
@ -0,0 +1,40 @@ |
|||
package org.nl.wms.pda.bigscreen_management.controller; |
|||
|
|||
|
|||
import cn.dev33.satoken.annotation.SaIgnore; |
|||
import lombok.RequiredArgsConstructor; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.nl.common.logging.annotation.Log; |
|||
import org.nl.wms.pda.bigscreen_management.service.BigScreenService; |
|||
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.RequestMapping; |
|||
import org.springframework.web.bind.annotation.RestController; |
|||
|
|||
/** |
|||
* <p> |
|||
* 大屏显示 控制层 |
|||
* </p> |
|||
* |
|||
* @author Liuxy |
|||
* @since 2025-06-24 |
|||
*/ |
|||
@RestController |
|||
@RequiredArgsConstructor |
|||
@RequestMapping("/api/bigScreen") |
|||
@Slf4j |
|||
public class BigScreenController { |
|||
|
|||
@Autowired |
|||
private BigScreenService bigScreenService; |
|||
|
|||
@PostMapping("/getData") |
|||
@Log("大屏数据") |
|||
@SaIgnore |
|||
public ResponseEntity<Object> getData() { |
|||
return new ResponseEntity<>(bigScreenService.getData(), HttpStatus.OK); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,21 @@ |
|||
package org.nl.wms.pda.bigscreen_management.service; |
|||
|
|||
import org.nl.wms.pda.util.PdaResponse; |
|||
|
|||
/** |
|||
* <p> |
|||
* 大屏显示 服务类 |
|||
* </p> |
|||
* |
|||
* @author Liuxy |
|||
* @since 2025-06-24 |
|||
*/ |
|||
public interface BigScreenService { |
|||
|
|||
/** |
|||
* 获取大屏数据 |
|||
* |
|||
* @return PdaResponse |
|||
*/ |
|||
PdaResponse getData(); |
|||
} |
@ -0,0 +1,392 @@ |
|||
package org.nl.wms.pda.bigscreen_management.service.impl; |
|||
|
|||
import cn.hutool.core.date.DateField; |
|||
import cn.hutool.core.date.DateTime; |
|||
import cn.hutool.core.date.DateUtil; |
|||
import cn.hutool.core.util.NumberUtil; |
|||
import cn.hutool.core.util.ObjectUtil; |
|||
import com.alibaba.fastjson.JSONObject; |
|||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
|||
import org.nl.system.service.dict.dao.Dict; |
|||
import org.nl.system.service.dict.dao.mapper.SysDictMapper; |
|||
import org.nl.wms.basedata_manage.service.IStructattrService; |
|||
import org.nl.wms.basedata_manage.service.dao.Structattr; |
|||
import org.nl.wms.basedata_manage.service.dao.mapper.MdPbStoragevehicleextMapper; |
|||
import org.nl.wms.pda.bigscreen_management.service.BigScreenService; |
|||
import org.nl.wms.pda.util.PdaResponse; |
|||
import org.nl.wms.sch_manage.enums.TaskStatus; |
|||
import org.nl.wms.sch_manage.service.ISchBaseTaskService; |
|||
import org.nl.wms.sch_manage.service.dao.SchBaseTask; |
|||
import org.nl.wms.warehouse_management.enums.IOSConstant; |
|||
import org.nl.wms.warehouse_management.enums.IOSEnum; |
|||
import org.nl.wms.warehouse_management.service.IOutBillService; |
|||
import org.nl.wms.warehouse_management.service.dao.IOStorInv; |
|||
import org.nl.wms.warehouse_management.service.dao.IOStorInvDis; |
|||
import org.nl.wms.warehouse_management.service.dao.mapper.IOStorInvDisMapper; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.stereotype.Service; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
import java.util.stream.Collectors; |
|||
|
|||
/** |
|||
* <p> |
|||
* 大屏显示 实现类 |
|||
* </p> |
|||
* |
|||
* @author Liuxy |
|||
* @since 2025-06-24 |
|||
*/ |
|||
@Service |
|||
public class BigScreenServiceImpl implements BigScreenService { |
|||
|
|||
/** |
|||
* 仓位服务 |
|||
*/ |
|||
@Autowired |
|||
private IStructattrService iStructattrService; |
|||
|
|||
/** |
|||
* 载具扩展属性mapper服务 |
|||
*/ |
|||
@Autowired |
|||
private MdPbStoragevehicleextMapper mdPbStoragevehicleextMapper; |
|||
|
|||
/** |
|||
* 出入库服务 |
|||
*/ |
|||
@Autowired |
|||
private IOutBillService iOutBillService; |
|||
|
|||
/** |
|||
* 分配明细mapper服务 |
|||
*/ |
|||
@Autowired |
|||
private IOStorInvDisMapper ioStorInvDisMapper; |
|||
|
|||
/** |
|||
* 任务服务 |
|||
*/ |
|||
@Autowired |
|||
private ISchBaseTaskService iSchBaseTaskService; |
|||
|
|||
/** |
|||
* 字典服务 |
|||
*/ |
|||
@Autowired |
|||
private SysDictMapper sysDictMapper; |
|||
|
|||
@Override |
|||
public PdaResponse getData() { |
|||
JSONObject result = new JSONObject(); |
|||
//1.【货位使用】数据
|
|||
result.put("pointUse", pointUse()); |
|||
//2.【实时库存分析】数据
|
|||
result.put("ivtAnalyse", ivtAnalyse()); |
|||
//3.【出入库趋势】数据
|
|||
result.put("inAndOutTrend", inAndOutTrend()); |
|||
//4.【今日出入库】数据
|
|||
result.put("toDayInAndOut", toDayInAndOut()); |
|||
//5.【今日出入库】数据
|
|||
result.put("realTask", realTask()); |
|||
//6.【未完成单据】数据
|
|||
result.put("unIos", unIos()); |
|||
return PdaResponse.requestParamOk(result); |
|||
} |
|||
|
|||
/** |
|||
* 货位使用 |
|||
* |
|||
* @return JSONObject { |
|||
* total_qty: 总货位数 |
|||
* use_qty: 已用货位 |
|||
* emp_qty: 空余货位 |
|||
* use_percentage: 百分比(使用货位百分比) |
|||
* } |
|||
*/ |
|||
private JSONObject pointUse() { |
|||
// 返回数据
|
|||
JSONObject result = new JSONObject(); |
|||
// 查询所有未删除且启用仓位
|
|||
List<Structattr> attrList = iStructattrService.list( |
|||
new QueryWrapper<Structattr>().lambda() |
|||
.eq(Structattr::getIs_used, IOSConstant.IS_DELETE_YES) |
|||
.eq(Structattr::getIs_delete, IOSConstant.IS_DELETE_NO) |
|||
); |
|||
// 总货位数
|
|||
result.put("total_qty", attrList.size()); |
|||
// 已用货位数
|
|||
long use_qty = attrList.stream() |
|||
.filter(row -> ObjectUtil.isNotEmpty(row.getStoragevehicle_code())) |
|||
.count(); |
|||
result.put("use_qty", use_qty); |
|||
// 空余货位
|
|||
result.put("emp_qty", attrList.size() - use_qty); |
|||
// 使用货位百分比
|
|||
double use_percentage = NumberUtil.mul(NumberUtil.div(use_qty, attrList.size()), 100); |
|||
result.put("use_percentage", NumberUtil.round(use_percentage, 2)); |
|||
return result; |
|||
} |
|||
|
|||
/** |
|||
* 实时库存分析 |
|||
* |
|||
* @return JSONObject { |
|||
* total_qty: 总数 |
|||
* data: [ |
|||
* material_name: 物料名称 |
|||
* ivt_qty: 库存数量 |
|||
* percentage: 百分比 |
|||
* ] |
|||
* } |
|||
*/ |
|||
private JSONObject ivtAnalyse() { |
|||
// 返回数据
|
|||
JSONObject result = new JSONObject(); |
|||
// 查询所有库存
|
|||
List<JSONObject> ivtList = mdPbStoragevehicleextMapper.getBigScreenIvt(); |
|||
// 总数
|
|||
double total_qty = ivtList.stream() |
|||
.map(row -> row.getDoubleValue("canuse_qty")) |
|||
.reduce(Double::sum).orElse(0.0); |
|||
result.put("total_qty", NumberUtil.round(total_qty, 2)); |
|||
|
|||
// 查询排名前五的物料库存
|
|||
List<JSONObject> topFiveList; |
|||
List<JSONObject> otherList = null; |
|||
if (ivtList.size() < 5) { |
|||
topFiveList = ivtList; |
|||
} else { |
|||
topFiveList = ivtList.subList(0, 5); |
|||
otherList = ivtList.subList(5, ivtList.size()); |
|||
} |
|||
// 组织数据(物料前五)
|
|||
for (JSONObject json : topFiveList) { |
|||
// 库存数量
|
|||
json.put("ivt_qty", NumberUtil.round(json.getDoubleValue("canuse_qty"), 2)); |
|||
// 百分比
|
|||
double percentage = NumberUtil.mul(NumberUtil.div(json.getDoubleValue("canuse_qty"), total_qty), 100); |
|||
json.put("percentage", NumberUtil.round(percentage, 2)); |
|||
} |
|||
|
|||
// 计算其他物料
|
|||
if (ObjectUtil.isNotEmpty(otherList)) { |
|||
JSONObject jsonOther = new JSONObject(); |
|||
jsonOther.put("material_name", "其他"); |
|||
double ivt_qty = otherList.stream() |
|||
.map(row -> row.getDoubleValue("canuse_qty")) |
|||
.reduce(Double::sum).orElse(0.0); |
|||
jsonOther.put("ivt_qty", NumberUtil.round(ivt_qty, 2)); |
|||
// 百分比
|
|||
double percentage = NumberUtil.mul(NumberUtil.div(ivt_qty, total_qty), 100); |
|||
jsonOther.put("percentage", NumberUtil.round(percentage, 2)); |
|||
topFiveList.add(jsonOther); |
|||
} |
|||
|
|||
result.put("data", topFiveList); |
|||
return result; |
|||
} |
|||
|
|||
/** |
|||
* 出入库趋势 |
|||
* |
|||
* @return JSONObject { |
|||
* in: [{date:日期,qty:数量}] |
|||
* out: [{date:日期,qty:数量}] |
|||
* } |
|||
*/ |
|||
private JSONObject inAndOutTrend() { |
|||
// 获取七天天数集合
|
|||
DateTime dateTime = DateUtil.offsetDay(DateUtil.parseDate(DateUtil.today()), -6); |
|||
List<String> dateList = DateUtil.rangeToList(dateTime, DateUtil.parse(DateUtil.today()), DateField.DAY_OF_YEAR).stream() |
|||
.map(DateTime::toString) |
|||
.map(row -> row.substring(0, 10)) |
|||
.collect(Collectors.toList()); |
|||
// 查询七天内的出入库数据
|
|||
List<IOStorInv> allIosList = iOutBillService.list( |
|||
new QueryWrapper<IOStorInv>().lambda() |
|||
.in(IOStorInv::getBiz_date, dateList) |
|||
.eq(IOStorInv::getIs_delete, IOSConstant.IS_DELETE_NO) |
|||
.eq(IOStorInv::getBill_status, IOSEnum.BILL_STATUS.code("完成")) |
|||
); |
|||
|
|||
// 查询入库单据
|
|||
List<IOStorInv> inIosList = allIosList.stream() |
|||
.filter(row -> row.getIo_type().equals(IOSEnum.IO_TYPE.code("入库"))) |
|||
.collect(Collectors.toList()); |
|||
// 查询出库单据
|
|||
List<IOStorInv> outIosList = allIosList.stream() |
|||
.filter(row -> row.getIo_type().equals(IOSEnum.IO_TYPE.code("出库"))) |
|||
.collect(Collectors.toList()); |
|||
// 组织数据
|
|||
List<JSONObject> inList = new ArrayList<>(); |
|||
List<JSONObject> outList = new ArrayList<>(); |
|||
for (String date : dateList) { |
|||
// 处理入库数量
|
|||
JSONObject jsonIn = new JSONObject(); |
|||
jsonIn.put("date", date); |
|||
double in_qty = inIosList.stream() |
|||
.filter(row -> row.getBiz_date().equals(date)) |
|||
.map(row -> row.getTotal_qty().doubleValue()) |
|||
.reduce(Double::sum).orElse(0.00); |
|||
jsonIn.put("qty", NumberUtil.round(in_qty, 2)); |
|||
inList.add(jsonIn); |
|||
|
|||
// 处理出库数据
|
|||
JSONObject jsonOut = new JSONObject(); |
|||
jsonOut.put("date", date); |
|||
double out_qty = outIosList.stream() |
|||
.filter(row -> row.getBiz_date().equals(date)) |
|||
.map(row -> row.getTotal_qty().doubleValue()) |
|||
.reduce(Double::sum).orElse(0.00); |
|||
jsonOut.put("qty", NumberUtil.round(out_qty, 2)); |
|||
outList.add(jsonOut); |
|||
} |
|||
|
|||
JSONObject result = new JSONObject(); |
|||
result.put("in", inList); |
|||
result.put("out", outList); |
|||
return result; |
|||
} |
|||
|
|||
/** |
|||
* 今日出入库 |
|||
* |
|||
* @return JSONObject { |
|||
* in: {total_qty:总数量,vehicle_qty:托盘数量} |
|||
* out: {total_qty:总数量,vehicle_qty:托盘数量} |
|||
* } |
|||
*/ |
|||
private JSONObject toDayInAndOut() { |
|||
// 查询今天出入库单据
|
|||
List<IOStorInv> inList = iOutBillService.list( |
|||
new QueryWrapper<IOStorInv>().lambda() |
|||
.eq(IOStorInv::getBiz_date, DateUtil.today()) |
|||
.eq(IOStorInv::getIs_delete, IOSConstant.IS_DELETE_NO) |
|||
.eq(IOStorInv::getIo_type, IOSEnum.IO_TYPE.code("入库")) |
|||
.eq(IOStorInv::getBill_status, IOSEnum.BILL_STATUS.code("完成")) |
|||
); |
|||
// 查询今天出库单据
|
|||
List<IOStorInv> outList = iOutBillService.list( |
|||
new QueryWrapper<IOStorInv>().lambda() |
|||
.eq(IOStorInv::getBiz_date, DateUtil.today()) |
|||
.eq(IOStorInv::getIs_delete, IOSConstant.IS_DELETE_NO) |
|||
.eq(IOStorInv::getIo_type, IOSEnum.IO_TYPE.code("出库")) |
|||
.eq(IOStorInv::getBill_status, IOSEnum.BILL_STATUS.code("完成")) |
|||
); |
|||
|
|||
// 入库
|
|||
JSONObject jsonIn = new JSONObject(); |
|||
// 总数量
|
|||
double total_qty_in = inList.stream() |
|||
.map(row -> row.getTotal_qty().doubleValue()) |
|||
.reduce(Double::sum).orElse(0.0); |
|||
jsonIn.put("total_qty", NumberUtil.round(total_qty_in, 2)); |
|||
|
|||
// 托盘数
|
|||
List<IOStorInvDis> inDisList = new ArrayList<>(); |
|||
if (ObjectUtil.isNotEmpty(inList)) { |
|||
inDisList = ioStorInvDisMapper.selectList( |
|||
new QueryWrapper<IOStorInvDis>().lambda() |
|||
.in(IOStorInvDis::getIostorinv_id, inList.stream() |
|||
.map(IOStorInv::getIostorinv_id) |
|||
.collect(Collectors.toList()) |
|||
) |
|||
); |
|||
} |
|||
jsonIn.put("vehicle_qty", inDisList.size()); |
|||
|
|||
// 出库
|
|||
JSONObject jsonOut = new JSONObject(); |
|||
// 总数量
|
|||
double total_qty_out = outList.stream() |
|||
.map(row -> row.getTotal_qty().doubleValue()) |
|||
.reduce(Double::sum).orElse(0.0); |
|||
jsonOut.put("total_qty", NumberUtil.round(total_qty_out, 2)); |
|||
// 托盘数
|
|||
List<IOStorInvDis> outDisList = new ArrayList<>(); |
|||
if (ObjectUtil.isNotEmpty(outList)) { |
|||
outDisList = ioStorInvDisMapper.selectList( |
|||
new QueryWrapper<IOStorInvDis>().lambda() |
|||
.in(IOStorInvDis::getIostorinv_id, outList.stream() |
|||
.map(IOStorInv::getIostorinv_id) |
|||
.collect(Collectors.toList()) |
|||
) |
|||
); |
|||
} |
|||
jsonOut.put("vehicle_qty", outDisList.size()); |
|||
|
|||
JSONObject result = new JSONObject(); |
|||
result.put("in", jsonIn); |
|||
result.put("out", jsonOut); |
|||
return result; |
|||
} |
|||
|
|||
/** |
|||
* 实时任务 |
|||
* |
|||
* @return List<SchBaseTask> { |
|||
* 任务实体列 |
|||
* } |
|||
*/ |
|||
private List<SchBaseTask> realTask() { |
|||
List<SchBaseTask> list = iSchBaseTaskService.list( |
|||
new QueryWrapper<SchBaseTask>().lambda() |
|||
.in(SchBaseTask::getTask_status, TaskStatus.CREATE.getCode() |
|||
, TaskStatus.ISSUED.getCode(), TaskStatus.EXECUTING.getCode() |
|||
) |
|||
.eq(SchBaseTask::getIs_delete, IOSConstant.IS_DELETE_NO) |
|||
); |
|||
list.stream().forEach(item -> { |
|||
if (item.getTask_status().equals(TaskStatus.CREATE.getCode())) { |
|||
item.setTask_status(TaskStatus.CREATE.getName()); |
|||
} |
|||
if (item.getTask_status().equals(TaskStatus.ISSUED.getCode())) { |
|||
item.setTask_status(TaskStatus.ISSUED.getName()); |
|||
} |
|||
if (item.getTask_status().equals(TaskStatus.EXECUTING.getCode())) { |
|||
item.setTask_status(TaskStatus.EXECUTING.getName()); |
|||
} |
|||
}); |
|||
|
|||
return list; |
|||
} |
|||
|
|||
/** |
|||
* 未完成单据 |
|||
* |
|||
* @return List<IOStorInv>{ |
|||
* 出入库实体类 |
|||
* } |
|||
*/ |
|||
private List<IOStorInv> unIos() { |
|||
List<Dict> dicts = sysDictMapper.selectList( |
|||
new QueryWrapper<Dict>().lambda() |
|||
.in(Dict::getCode, "ST_INV_IN_TYPE", "ST_INV_OUT_TYPE") |
|||
); |
|||
|
|||
List<IOStorInv> list = iOutBillService.list( |
|||
new QueryWrapper<IOStorInv>().lambda() |
|||
.eq(IOStorInv::getIs_delete, IOSConstant.IS_DELETE_NO) |
|||
.ne(IOStorInv::getBill_status, IOSEnum.BILL_STATUS.code("完成")) |
|||
); |
|||
list.stream().forEach(item -> { |
|||
item.setIo_type(item.getIo_type().equals(IOSEnum.IO_TYPE.code("入库")) ? IOSConstant.IOS_IO_TYPE_IN : IOSConstant.IOS_IO_TYPE_OUT); |
|||
if (item.getBill_status().equals(IOSEnum.BILL_STATUS.code("生成"))) { |
|||
item.setBill_status("生成"); |
|||
} |
|||
if (item.getBill_status().equals(IOSEnum.BILL_STATUS.code("分配中"))) { |
|||
item.setBill_status("分配中"); |
|||
} |
|||
if (item.getBill_status().equals(IOSEnum.BILL_STATUS.code("分配完"))) { |
|||
item.setBill_status("分配完"); |
|||
} |
|||
Dict dict = dicts.stream() |
|||
.filter(row -> row.getValue().equals(item.getBill_type())) |
|||
.findFirst().orElse(null); |
|||
item.setBill_type(dict.getLabel()); |
|||
}); |
|||
return list; |
|||
} |
|||
} |
Loading…
Reference in new issue