物资管理大屏消耗趋势对比接口优化

This commit is contained in:
2025-12-17 09:28:27 +08:00
parent c1f5cc33b0
commit 2fd1736766
6 changed files with 248 additions and 64 deletions

View File

@ -5,6 +5,7 @@ import lombok.RequiredArgsConstructor;
import org.dromara.bigscreen.domain.vo.InventoryStructureAnalysisVo;
import org.dromara.bigscreen.domain.vo.designAndArrivalComparisonVo;
import org.dromara.bigscreen.domain.vo.wzxqysjdhdbVo;
import org.dromara.bigscreen.domain.vo.xhqsdbVo;
import org.dromara.bigscreen.service.IMaterialsManagementService;
import org.dromara.cailiaoshebei.domain.bo.BusPurchaseDocBo;
import org.dromara.cailiaoshebei.domain.vo.BusPurchaseDocVo;
@ -94,6 +95,14 @@ public class MaterialsManagementController extends BaseController {
return R.ok(busMrpBaseService.wzxqysjdhdb(projectId));
}
/**
* 消耗趋势对比
*/
@GetMapping("/xhqsdb")
public R<List<xhqsdbVo>> xhqsdb(Long projectId) {
return R.ok(materialsManagementService.xhqsdb(projectId));
}
/**
* 获取材料使用详情列表
*/

View File

@ -0,0 +1,35 @@
package org.dromara.bigscreen.domain.vo;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 物资需求与实际到货对比vo
*/
@Data
public class xhqsdbVo implements Serializable {
/**
* 名称
*/
public String name;
/**
* 规格
*/
public String specification;
/**
* 出库量
*/
public BigDecimal outTotalPrices;
/**
* 使用量
*/
public BigDecimal useTotalPrices;
}

View File

@ -2,6 +2,8 @@ package org.dromara.bigscreen.service;
import org.dromara.bigscreen.domain.vo.InventoryStructureAnalysisVo;
import org.dromara.bigscreen.domain.vo.wzxqysjdhdbVo;
import org.dromara.bigscreen.domain.vo.xhqsdbVo;
import org.dromara.project.domain.vo.project.BusProjectGisVo;
import java.util.List;
@ -17,4 +19,11 @@ public interface IMaterialsManagementService {
* @return
*/
InventoryStructureAnalysisVo inventoryStructureAnalysis(Long projectId);
/**
* 消耗趋势对比
* @param projectId
* @return
*/
List<xhqsdbVo> xhqsdb(Long projectId);
}

View File

@ -5,14 +5,12 @@ import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jakarta.annotation.Resource;
import org.dromara.bigscreen.domain.vo.InventoryStructureAnalysisVo;
import org.dromara.bigscreen.domain.vo.wzxqysjdhdbVo;
import org.dromara.bigscreen.domain.vo.xhqsdbVo;
import org.dromara.bigscreen.enums.WuZhiEnum;
import org.dromara.bigscreen.service.IMaterialsManagementService;
import org.dromara.materials.domain.MatMaterialIssueItem;
import org.dromara.materials.domain.MatMaterialReceiveItem;
import org.dromara.materials.service.IMatMaterialIssueItemService;
import org.dromara.materials.service.IMatMaterialReceiveItemService;
import org.dromara.materials.service.IMatMaterialsInventoryService;
import org.dromara.materials.service.IMatMaterialsService;
import org.dromara.materials.domain.*;
import org.dromara.materials.service.*;
import org.dromara.project.domain.vo.project.BusProjectGisVo;
import org.dromara.tender.domain.BusBillofquantitiesLimitList;
import org.dromara.tender.service.IBusBillofquantitiesLimitListService;
@ -22,8 +20,8 @@ import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
@Service
public class MaterialsManagementServiceImpl implements IMaterialsManagementService {
@ -42,6 +40,12 @@ public class MaterialsManagementServiceImpl implements IMaterialsManagementServi
@Lazy
@Resource
private IBusBillofquantitiesLimitListService billofquantitiesLimitListService;
@Lazy
@Resource
private IMatMaterialsInventoryService materialsInventoryService;
@Lazy
@Resource
private IMatMaterialsUseRecordService matMaterialsUseRecordService;
@Override
@ -85,10 +89,10 @@ public class MaterialsManagementServiceImpl implements IMaterialsManagementServi
.between(MatMaterialReceiveItem::getCreateTime, monthStart, currentTime));
if (CollUtil.isEmpty(matMaterialReceiveItems)) {
vo.setEnterTotalPrices(BigDecimal.ZERO);
}else {
} else {
// 计算本月入库金额
BigDecimal enterTotalPrices = matMaterialReceiveItems.stream()
.map(item -> item.getAcceptedQuantity().multiply(item.getUnitPrice() != null? item.getUnitPrice() : BigDecimal.ZERO))
.map(item -> item.getAcceptedQuantity().multiply(item.getUnitPrice() != null ? item.getUnitPrice() : BigDecimal.ZERO))
.reduce(BigDecimal.ZERO, BigDecimal::add);
vo.setEnterTotalPrices(enterTotalPrices.setScale(4, BigDecimal.ROUND_HALF_UP));
}
@ -99,10 +103,10 @@ public class MaterialsManagementServiceImpl implements IMaterialsManagementServi
.between(MatMaterialReceiveItem::getCreateTime, lastMonthFirstDay, lastMonthLastDay));
if (CollUtil.isEmpty(oldMatMaterialReceiveItems)) {
vo.setOldEnterTotalPrices(BigDecimal.ZERO);
}else {
} else {
// 计算上月入库金额
BigDecimal oldEnterTotalPrices = oldMatMaterialReceiveItems.stream()
.map(item -> item.getAcceptedQuantity().multiply(item.getUnitPrice() != null? item.getUnitPrice() : BigDecimal.ZERO))
.map(item -> item.getAcceptedQuantity().multiply(item.getUnitPrice() != null ? item.getUnitPrice() : BigDecimal.ZERO))
.reduce(BigDecimal.ZERO, BigDecimal::add);
vo.setOldEnterTotalPrices(oldEnterTotalPrices.setScale(4, BigDecimal.ROUND_HALF_UP));
}
@ -116,9 +120,9 @@ public class MaterialsManagementServiceImpl implements IMaterialsManagementServi
//计算本月出库金额
if (CollUtil.isEmpty(matMaterialIssueItems)) {
vo.setLeaveTotalPrices(BigDecimal.ZERO);
}else {
} else {
BigDecimal leaveTotalPrices = matMaterialIssueItems.stream()
.map(item -> item.getIssuedQuantity().multiply(item.getUnitPrice() != null? item.getUnitPrice() : BigDecimal.ZERO))
.map(item -> item.getIssuedQuantity().multiply(item.getUnitPrice() != null ? item.getUnitPrice() : BigDecimal.ZERO))
.reduce(BigDecimal.ZERO, BigDecimal::add);
vo.setLeaveTotalPrices(leaveTotalPrices.setScale(4, BigDecimal.ROUND_HALF_UP));
}
@ -131,9 +135,9 @@ public class MaterialsManagementServiceImpl implements IMaterialsManagementServi
//计算上月出库金额
if (CollUtil.isEmpty(oldMatMaterialIssueItems)) {
vo.setOldLeaveTotalPrices(BigDecimal.ZERO);
}else {
} else {
BigDecimal oldLeaveTotalPrices = oldMatMaterialIssueItems.stream()
.map(item -> item.getIssuedQuantity().multiply(item.getUnitPrice() != null? item.getUnitPrice() : BigDecimal.ZERO))
.map(item -> item.getIssuedQuantity().multiply(item.getUnitPrice() != null ? item.getUnitPrice() : BigDecimal.ZERO))
.reduce(BigDecimal.ZERO, BigDecimal::add);
vo.setOldLeaveTotalPrices(oldLeaveTotalPrices.setScale(4, BigDecimal.ROUND_HALF_UP));
}
@ -141,10 +145,10 @@ public class MaterialsManagementServiceImpl implements IMaterialsManagementServi
List<MatMaterialReceiveItem> totalMatMaterialReceiveItems = materialReceiveItemService.getBaseMapper().selectList(new LambdaQueryWrapper<MatMaterialReceiveItem>().eq(MatMaterialReceiveItem::getProjectId, projectId));
if (CollUtil.isEmpty(totalMatMaterialReceiveItems)) {
vo.setInventoryTotalPrices(BigDecimal.ZERO);
}else {
} else {
// 计算总入库存金额
BigDecimal inventoryTotalPrices = totalMatMaterialReceiveItems.stream()
.map(item -> item.getAcceptedQuantity().multiply(item.getUnitPrice() != null? item.getUnitPrice() : BigDecimal.ZERO))
.map(item -> item.getAcceptedQuantity().multiply(item.getUnitPrice() != null ? item.getUnitPrice() : BigDecimal.ZERO))
.reduce(BigDecimal.ZERO, BigDecimal::add);
vo.setInventoryTotalPrices(inventoryTotalPrices.setScale(4, BigDecimal.ROUND_HALF_UP));
}
@ -153,10 +157,10 @@ public class MaterialsManagementServiceImpl implements IMaterialsManagementServi
List<MatMaterialIssueItem> totalMatMaterialIssueItems = materialIssueItemService.getBaseMapper().selectList(new LambdaQueryWrapper<MatMaterialIssueItem>().eq(MatMaterialIssueItem::getProjectId, projectId));
if (CollUtil.isEmpty(totalMatMaterialIssueItems)) {
vo.setOutTotalPrices(BigDecimal.ZERO);
}else {
} else {
// 计算总出库金额
BigDecimal outTotalPrices = totalMatMaterialIssueItems.stream()
.map(item -> item.getIssuedQuantity().multiply(item.getUnitPrice() != null? item.getUnitPrice() : BigDecimal.ZERO))
.map(item -> item.getIssuedQuantity().multiply(item.getUnitPrice() != null ? item.getUnitPrice() : BigDecimal.ZERO))
.reduce(BigDecimal.ZERO, BigDecimal::add);
vo.setOutTotalPrices(outTotalPrices.setScale(4, BigDecimal.ROUND_HALF_UP));
}
@ -210,4 +214,68 @@ public class MaterialsManagementServiceImpl implements IMaterialsManagementServi
vo.setNowInventoryTotalPrices(nowInventoryTotalPrices);
return vo;
}
/**
* 消耗趋势对比
*
* @param projectId
* @return
*/
@Override
public List<xhqsdbVo> xhqsdb(Long projectId) {
List<xhqsdbVo> list = new ArrayList<>();
List<MatMaterialsInventory> inventories = materialsInventoryService.getBaseMapper()
.selectList(new LambdaQueryWrapper<MatMaterialsInventory>()
.eq(MatMaterialsInventory::getProjectId, projectId)
.eq(MatMaterialsInventory::getOutPut, "2"));
if (CollUtil.isEmpty(inventories)) {
return List.of();
}
HashMap<Long, BigDecimal> inventoryHashMap = new HashMap<>();
inventories.forEach(item -> {
if (inventoryHashMap.containsKey(item.getMaterialsId())){
inventoryHashMap.put(item.getMaterialsId(), inventoryHashMap.get(item.getMaterialsId()).add(new BigDecimal(item.getNumber())));
}else {
inventoryHashMap.put(item.getMaterialsId(), new BigDecimal(item.getNumber()));
}
});
Set<Long> mids = inventories.stream().map(MatMaterialsInventory::getMaterialsId).collect(Collectors.toSet());
if (CollUtil.isEmpty(mids)){
return List.of();
}
List<MatMaterials> materials = materialsService.getBaseMapper().selectList(new LambdaQueryWrapper<MatMaterials>()
.eq(MatMaterials::getProjectId, projectId)
.in(MatMaterials::getId, mids));
if (CollUtil.isEmpty(materials)) {
return List.of();
}
Map<Long, String> map1 = materials.stream()
.collect(Collectors.toMap(MatMaterials::getId, MatMaterials::getMaterialsName));
Set<Long> ids = inventories.stream()
.map(MatMaterialsInventory::getId)
.collect(Collectors.toSet());
if (CollUtil.isEmpty(ids)) {
return List.of();
}
List<MatMaterialsUseRecord> useRecords = matMaterialsUseRecordService.getBaseMapper()
.selectList(new LambdaQueryWrapper<MatMaterialsUseRecord>()
.eq(MatMaterialsUseRecord::getProjectId, projectId)
.in(MatMaterialsUseRecord::getInventoryId, ids));
if (CollUtil.isEmpty(useRecords)) {
return List.of();
}
Map<Long, BigDecimal> map = useRecords.stream()
.collect(Collectors.groupingBy(
MatMaterialsUseRecord::getInventoryId,
Collectors.reducing(BigDecimal.ZERO, MatMaterialsUseRecord::getUseNumber, BigDecimal::add)
));
inventoryHashMap.forEach((key, value) -> {
xhqsdbVo vo = new xhqsdbVo();
vo.setName(map1.get(key));
vo.setOutTotalPrices( value);
vo.setUseTotalPrices(map.getOrDefault(key, BigDecimal.ZERO));
list.add(vo);
});
return list;
}
}

View File

@ -111,6 +111,9 @@ public class BusPurchaseDocServiceImpl extends ServiceImpl<BusPurchaseDocMapper,
@Override
public BusPurchaseDocVo queryById(Long id) {
BusPurchaseDocVo busPurchaseDocVo = baseMapper.selectVoById(id);
if (busPurchaseDocVo == null){
return busPurchaseDocVo;
}
BusPlanDocAssociationBo busPlanDocAssociationBo = new BusPlanDocAssociationBo();
busPlanDocAssociationBo.setDocId(id);
List<BusPlanDocAssociationVo> busPlanDocAssociationVos = planDocAssociationService.queryList(busPlanDocAssociationBo);
@ -582,11 +585,21 @@ public class BusPurchaseDocServiceImpl extends ServiceImpl<BusPurchaseDocMapper,
@Override
public List<BusPurchaseDocVo> purchaseNote(Long projectId) {
return baseMapper.selectVoList(new LambdaQueryWrapper<BusPurchaseDoc>()
List<BusPurchaseDocVo> busPurchaseDocVos = baseMapper.selectVoList(new LambdaQueryWrapper<BusPurchaseDoc>()
.eq(BusPurchaseDoc::getProjectId, projectId)
.eq(BusPurchaseDoc::getDocType, "1")
.eq(BusPurchaseDoc::getStatus, BusinessStatusEnum.FINISH.getStatus())
.orderByDesc(BusPurchaseDoc::getCreateTime));
if (busPurchaseDocVos == null){
return List.of();
}
busPurchaseDocVos.forEach(v -> {
BusMrpBase byId = mrpBaseService.getById(v.getMrpBaseId());
if (byId != null) {
v.setPlanCode(byId.getPlanCode());
}
});
return busPurchaseDocVos;
}
/**

View File

@ -122,49 +122,8 @@ public class BigScreenWebSocketServer {
getProgressBigScreenData(maps, projectId);
break;
case 5:
if (materialsService != null) {
InventoryStructureAnalysisVo vo = managementService.inventoryStructureAnalysis(projectId);
if (vo != null) {
Map<String, String> map = new HashMap<>();
map.put("type", "inventoryStructureAnalysis");
map.put("data", JSONUtil.toJsonStr(vo));
maps.add(map);
}
}
if (purchaseDocService != null) {
List<BusPurchaseDocVo> purchaseDocVos = purchaseDocService.purchaseNote(projectId);
if (purchaseDocVos != null && !purchaseDocVos.isEmpty()) {
Map<String, String> map = new HashMap<>();
map.put("type", "purchaseNote");
map.put("data", JSONUtil.toJsonStr(purchaseDocVos));
maps.add(map);
}
}
if (mrpBaseService != null) {
List<designAndArrivalComparisonVo> designAndArrivalComparisonVos = mrpBaseService.designAndArrivalComparison(projectId);
if (designAndArrivalComparisonVos != null && !designAndArrivalComparisonVos.isEmpty()) {
Map<String, String> map = new HashMap<>();
map.put("type", "designAndArrivalComparison");
map.put("data", JSONUtil.toJsonStr(designAndArrivalComparisonVos));
maps.add(map);
}
List<wzxqysjdhdbVo> wzxqysjdhdbVos = mrpBaseService.wzxqysjdhdb(projectId);
if (wzxqysjdhdbVos != null && !wzxqysjdhdbVos.isEmpty()) {
Map<String, String> map = new HashMap<>();
map.put("type", "wzxqysjdhdb");
map.put("data", JSONUtil.toJsonStr(wzxqysjdhdbVos));
maps.add(map);
}
}
if (materialsService != null) {
List<MatMaterialsUseDetailVo> useDetailVos = materialsService.listUseDetail(projectId);
if (useDetailVos != null && !useDetailVos.isEmpty()) {
Map<String, String> map = new HashMap<>();
map.put("type", "listUseDetail");
map.put("data", JSONUtil.toJsonStr(useDetailVos));
maps.add(map);
}
}
//物资管理大屏
generateLargeScreenData(materialsService, managementService, projectId, maps, purchaseDocService, mrpBaseService);
break;
case 6:
break;
@ -193,6 +152,68 @@ public class BigScreenWebSocketServer {
});
}
/**
* 获取物资管理大屏数据
*/
private static void generateLargeScreenData(IMatMaterialsService materialsService, IMaterialsManagementService managementService, Long projectId, List<Map<String, String>> maps, IBusPurchaseDocService purchaseDocService, IBusMrpBaseService mrpBaseService) {
if (materialsService != null) {
//库存结构分析
InventoryStructureAnalysisVo vo = managementService.inventoryStructureAnalysis(projectId);
if (vo != null) {
Map<String, String> map = new HashMap<>();
map.put("type", "inventoryStructureAnalysis");
map.put("data", JSONUtil.toJsonStr(vo));
maps.add(map);
}
//消耗趋势对比
List<xhqsdbVo> xhqsdb = managementService.xhqsdb(projectId);
if (xhqsdb != null && !xhqsdb.isEmpty()) {
Map<String, String> map = new HashMap<>();
map.put("type", "xhqsdb");
map.put("data", JSONUtil.toJsonStr(xhqsdb));
maps.add(map);
}
}
if (purchaseDocService != null) {
//采购单
List<BusPurchaseDocVo> purchaseDocVos = purchaseDocService.purchaseNote(projectId);
if (purchaseDocVos != null && !purchaseDocVos.isEmpty()) {
Map<String, String> map = new HashMap<>();
map.put("type", "purchaseNote");
map.put("data", JSONUtil.toJsonStr(purchaseDocVos));
maps.add(map);
}
}
if (mrpBaseService != null) {
//设计量与到货量对比
List<designAndArrivalComparisonVo> designAndArrivalComparisonVos = mrpBaseService.designAndArrivalComparison(projectId);
if (designAndArrivalComparisonVos != null && !designAndArrivalComparisonVos.isEmpty()) {
Map<String, String> map = new HashMap<>();
map.put("type", "designAndArrivalComparison");
map.put("data", JSONUtil.toJsonStr(designAndArrivalComparisonVos));
maps.add(map);
}
//物资需求与实际到货对比
List<wzxqysjdhdbVo> wzxqysjdhdbVos = mrpBaseService.wzxqysjdhdb(projectId);
if (wzxqysjdhdbVos != null && !wzxqysjdhdbVos.isEmpty()) {
Map<String, String> map = new HashMap<>();
map.put("type", "wzxqysjdhdb");
map.put("data", JSONUtil.toJsonStr(wzxqysjdhdbVos));
maps.add(map);
}
}
if (materialsService != null) {
//物资跟踪管理台账
List<MatMaterialsUseDetailVo> useDetailVos = materialsService.listUseDetail(projectId);
if (useDetailVos != null && !useDetailVos.isEmpty()) {
Map<String, String> map = new HashMap<>();
map.put("type", "listUseDetail");
map.put("data", JSONUtil.toJsonStr(useDetailVos));
maps.add(map);
}
}
}
/**
* 接收客户端消息
*/
@ -201,6 +222,35 @@ public class BigScreenWebSocketServer {
log.info("📥 收到会话[{}]订阅ID{})消息:{}", session.getId(), currentSubscriptionId, message);
// 可选:回复客户端
//todo 填充不同类型大屏获取数据的方法判断
String subscriptionId = SESSION_TO_SUBSCRIPTION.get(session.getId());
if (subscriptionId == null || subscriptionId.isEmpty()) {
log.warn("⚠️ 订阅ID为空发送失败");
return;
}
String[] split = subscriptionId.split("-");
Long projectId = Long.parseLong(split[0]);
long type = Long.parseLong(split[1]);
switch ((int) type) {
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
// 进度管理大屏
break;
case 5:
//物资管理大屏
break;
case 6:
break;
case 7:
break;
default:
break;
}
try {
session.getBasicRemote().sendText("服务端已收到消息:" + message);