11 changed files with 486 additions and 3 deletions
@ -0,0 +1,50 @@ |
|||||
|
package org.nl.wms.bigscreen_manage.controller; |
||||
|
|
||||
|
|
||||
|
import cn.dev33.satoken.annotation.SaIgnore; |
||||
|
import com.alibaba.fastjson.JSONObject; |
||||
|
import lombok.RequiredArgsConstructor; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.nl.common.base.TableDataInfo; |
||||
|
import org.nl.common.logging.annotation.Log; |
||||
|
import org.nl.wms.bigscreen_manage.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.RequestBody; |
||||
|
import org.springframework.web.bind.annotation.RequestMapping; |
||||
|
import org.springframework.web.bind.annotation.RestController; |
||||
|
|
||||
|
import java.util.ArrayList; |
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* <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(@RequestBody JSONObject stors) { |
||||
|
List<String> list = new ArrayList<>(); |
||||
|
list.add("GW"); |
||||
|
list.add("GW"); |
||||
|
List<JSONObject> data = bigScreenService.getData(list); |
||||
|
return new ResponseEntity<>(TableDataInfo.build(data), HttpStatus.OK); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,24 @@ |
|||||
|
package org.nl.wms.bigscreen_manage.service; |
||||
|
|
||||
|
|
||||
|
import com.alibaba.fastjson.JSONObject; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* <p> |
||||
|
* 大屏显示 服务类 |
||||
|
* </p> |
||||
|
* |
||||
|
* @author Liuxy |
||||
|
* @since 2025-06-24 |
||||
|
*/ |
||||
|
public interface BigScreenService { |
||||
|
|
||||
|
/** |
||||
|
* 获取大屏数据 |
||||
|
*根据配置的仓库 |
||||
|
* @return PdaResponse |
||||
|
*/ |
||||
|
List<JSONObject> getData(List<String> stors); |
||||
|
} |
@ -0,0 +1,11 @@ |
|||||
|
package org.nl.wms.bigscreen_manage.service.dto; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
|
||||
|
@Data |
||||
|
public class IvtAnalyse { |
||||
|
private String stor_code; |
||||
|
private String material_id; |
||||
|
private String material_name; |
||||
|
private Integer sum_qty; |
||||
|
} |
@ -0,0 +1,355 @@ |
|||||
|
package org.nl.wms.bigscreen_manage.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.wms.basedata_manage.service.IStructattrService; |
||||
|
import org.nl.wms.basedata_manage.service.dao.Structattr; |
||||
|
import org.nl.wms.basedata_manage.service.dao.mapper.BsrealStorattrMapper; |
||||
|
import org.nl.wms.bigscreen_manage.service.BigScreenService; |
||||
|
import org.nl.wms.bigscreen_manage.service.dto.IvtAnalyse; |
||||
|
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 org.springframework.util.CollectionUtils; |
||||
|
|
||||
|
import javax.annotation.Resource; |
||||
|
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; |
||||
|
|
||||
|
@Resource |
||||
|
private IOutBillService iOutBillService; |
||||
|
|
||||
|
@Resource |
||||
|
private BsrealStorattrMapper screenMapper; |
||||
|
|
||||
|
@Resource |
||||
|
private IOStorInvDisMapper ioStorInvDisMapper; |
||||
|
|
||||
|
@Autowired |
||||
|
private ISchBaseTaskService iSchBaseTaskService; |
||||
|
|
||||
|
@Override |
||||
|
public List<JSONObject> getData(List<String> stors) { |
||||
|
// String storCode = "GW";
|
||||
|
List result = new ArrayList<>(); |
||||
|
if (CollectionUtils.isEmpty(stors)){ |
||||
|
return result; |
||||
|
} |
||||
|
for (String storCode : stors) { |
||||
|
JSONObject item = new JSONObject(); |
||||
|
//1.【货位使用】数据
|
||||
|
item.put("title","GW仓库"); |
||||
|
item.put("pointUse", pointUse(storCode)); |
||||
|
// //2.【实时库存分析】数据
|
||||
|
item.put("ivtAnalyse", ivtAnalyse(storCode)); |
||||
|
//3.【出入库趋势】数据
|
||||
|
item.put("inAndOutTrend", inAndOutTrend(storCode)); |
||||
|
// //4.【今日出入库】数据
|
||||
|
item.put("toDayInAndOut", toDayInAndOut(storCode)); |
||||
|
// //5.【今日出入库】数据
|
||||
|
item.put("realTask", realTask(storCode)); |
||||
|
//6.【未完成单据】数据
|
||||
|
item.put("unIos", unIos(storCode)); |
||||
|
result.add(item); |
||||
|
} |
||||
|
return result; |
||||
|
} |
||||
|
/** |
||||
|
//
|
||||
|
// * 货位使用
|
||||
|
// *
|
||||
|
// * @return JSONObject {
|
||||
|
// * total_qty: 总货位数
|
||||
|
// * use_qty: 已用货位
|
||||
|
// * emp_qty: 空余货位
|
||||
|
// * use_percentage: 百分比(使用货位百分比)
|
||||
|
// * }
|
||||
|
// */
|
||||
|
private JSONObject pointUse(String storCode) { |
||||
|
// 返回数据
|
||||
|
JSONObject result = new JSONObject(); |
||||
|
// 查询所有未删除且启用仓位
|
||||
|
int emp_qty = iStructattrService.count( |
||||
|
new QueryWrapper<Structattr>().lambda() |
||||
|
.eq(Structattr::getIs_used, Boolean.TRUE) |
||||
|
.eq(Structattr::getStor_code, storCode) |
||||
|
.isNull(Structattr::getStoragevehicle_code)); |
||||
|
int use_qty = iStructattrService.count( |
||||
|
new QueryWrapper<Structattr>().lambda() |
||||
|
.eq(Structattr::getIs_used, Boolean.TRUE) |
||||
|
.eq(Structattr::getStor_code, storCode) |
||||
|
.isNotNull(Structattr::getStoragevehicle_code)); |
||||
|
int total_qty = iStructattrService.count( |
||||
|
new QueryWrapper<Structattr>().lambda() |
||||
|
.eq(Structattr::getIs_used, Boolean.TRUE) |
||||
|
.eq(Structattr::getStor_code, storCode)); |
||||
|
// 总货位数
|
||||
|
result.put("total_qty", total_qty); |
||||
|
// 已用货位数
|
||||
|
result.put("use_qty", use_qty); |
||||
|
// 空余货位
|
||||
|
result.put("emp_qty", emp_qty); |
||||
|
// 使用货位百分比
|
||||
|
double use_percentage = NumberUtil.mul(NumberUtil.div(use_qty, total_qty), 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(String storCode) { |
||||
|
JSONObject result = new JSONObject(); |
||||
|
List<IvtAnalyse> list = screenMapper.sumMaterQty(storCode); |
||||
|
int sum = list.stream().mapToInt(IvtAnalyse::getSum_qty).sum(); |
||||
|
result.put("total_qty", sum); |
||||
|
List<JSONObject> topFiveList = new ArrayList<>(); |
||||
|
int i = 0; |
||||
|
int top5 = 0; |
||||
|
for (IvtAnalyse json : list) { |
||||
|
if (i==5){break;} |
||||
|
JSONObject item = new JSONObject(); |
||||
|
item.put("ivt_qty", json.getSum_qty()); |
||||
|
item.put("material_name", json.getMaterial_name()); |
||||
|
double percentage = NumberUtil.mul(json.getSum_qty()/sum, 100); |
||||
|
item.put("percentage", NumberUtil.round(percentage, 2)); |
||||
|
topFiveList.add(item); |
||||
|
i++; |
||||
|
top5 = top5+json.getSum_qty(); |
||||
|
} |
||||
|
if (sum>top5){ |
||||
|
JSONObject other = new JSONObject(); |
||||
|
other.put("ivt_qty", sum-top5); |
||||
|
other.put("material_name", "其他物料"); |
||||
|
other.put("percentage", NumberUtil.round(1-top5/sum, 2)); |
||||
|
topFiveList.add(other); |
||||
|
} |
||||
|
result.put("data", topFiveList); |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 出入库趋势 |
||||
|
* |
||||
|
* @return JSONObject { |
||||
|
* in: [{date:日期,qty:数量}] |
||||
|
* out: [{date:日期,qty:数量}] |
||||
|
* } |
||||
|
*/ |
||||
|
private JSONObject inAndOutTrend(String storCode) { |
||||
|
// 获取七天天数集合
|
||||
|
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::getStor_code, storCode) |
||||
|
.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(String storCode) { |
||||
|
// 查询今天出入库单据
|
||||
|
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::getStor_code, storCode) |
||||
|
.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::getStor_code, storCode) |
||||
|
.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(String storCode) { |
||||
|
List<SchBaseTask> list = iSchBaseTaskService.list( |
||||
|
new QueryWrapper<SchBaseTask>().lambda() |
||||
|
.le(SchBaseTask::getTask_status, TaskStatus.FINISHED.getCode()) |
||||
|
.eq(SchBaseTask::getIs_delete, IOSConstant.IS_DELETE_NO) |
||||
|
.ge(SchBaseTask::getCreate_time,DateUtil.today()) |
||||
|
); |
||||
|
list.stream().forEach(item -> { |
||||
|
item.setTask_status(TaskStatus.convertName(item.getTask_status())); |
||||
|
}); |
||||
|
return list; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 未完成单据 |
||||
|
* |
||||
|
* @return List<IOStorInv>{ |
||||
|
* 出入库实体类 |
||||
|
* } |
||||
|
*/ |
||||
|
private List<IOStorInv> unIos(String storCode) { |
||||
|
|
||||
|
List<IOStorInv> list = iOutBillService.list( |
||||
|
new QueryWrapper<IOStorInv>().lambda() |
||||
|
.eq(IOStorInv::getIs_delete, IOSConstant.IS_DELETE_NO) |
||||
|
.eq(IOStorInv::getStor_code, storCode) |
||||
|
.ne(IOStorInv::getBill_status, IOSEnum.BILL_STATUS.code("完成")) |
||||
|
); |
||||
|
list.stream().forEach(item -> { |
||||
|
item.setIo_type(item.getIo_type().equals(IOSEnum.IO_TYPE.code("入库"))?"入库":"出库"); |
||||
|
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("分配完"); |
||||
|
} |
||||
|
item.setBill_type("dict.getLabel()"); |
||||
|
}); |
||||
|
return list; |
||||
|
} |
||||
|
} |
Loading…
Reference in new issue