物资管理大屏接口

This commit is contained in:
2025-12-16 17:09:10 +08:00
parent 975d3e6f32
commit ea626dfeff
33 changed files with 910 additions and 15 deletions

View File

@ -0,0 +1,105 @@
package org.dromara.bigscreen.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
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.service.IMaterialsManagementService;
import org.dromara.cailiaoshebei.domain.bo.BusPurchaseDocBo;
import org.dromara.cailiaoshebei.domain.vo.BusPurchaseDocVo;
import org.dromara.cailiaoshebei.service.IBusMrpBaseService;
import org.dromara.cailiaoshebei.service.IBusPurchaseDocService;
import org.dromara.common.core.domain.R;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.web.core.BaseController;
import org.dromara.materials.domain.dto.materials.MatMaterialsQueryReq;
import org.dromara.materials.domain.vo.materials.MatMaterialsUseDetailVo;
import org.dromara.materials.service.IMatMaterialsService;
import org.dromara.project.domain.vo.project.BusProjectGisVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 物资管理
*/
@Validated
@RestController
@RequiredArgsConstructor
@RequestMapping("/materialsManagement")
public class MaterialsManagementController extends BaseController {
@Autowired
private IMaterialsManagementService materialsManagementService;
@Autowired
private IBusPurchaseDocService busPurchaseDocService;
@Autowired
private IBusMrpBaseService busMrpBaseService;
@Autowired
private IMatMaterialsService materialsService;
/**
* 库存结构分析
* @return
*/
@GetMapping("/inventoryStructureAnalysis")
public R<InventoryStructureAnalysisVo> inventoryStructureAnalysis(Long projectId) {
return R.ok(materialsManagementService.inventoryStructureAnalysis(projectId));
}
/**
* 采购单
* @return
*/
@GetMapping("/purchaseNote")
public R<List<BusPurchaseDocVo>> purchaseNote(Long projectId) {
return R.ok(busPurchaseDocService.purchaseNote(projectId));
}
/**
* 获取采购单详情
* @return
*/
@GetMapping("/purchaseNoteDetail")
public R<BusPurchaseDocVo> purchaseNoteDetail(Long id) {
return R.ok(busPurchaseDocService.queryById(id));
}
/**
* 获取采购单详情PDF
*/
@GetMapping("/purchaseNoteDetailPdf")
public R<String> purchaseNoteDetailPdf(Long id) {
return R.ok(busPurchaseDocService.queryPicBase64ById(id));
}
/**
* 设计量与到货量对比
*/
@GetMapping("/designAndArrivalComparison")
public R<List<designAndArrivalComparisonVo>> designAndArrivalComparison(Long projectId) {
return R.ok(busMrpBaseService.designAndArrivalComparison(projectId));
}
/**
* 物资需求与实际到货对比
*/
@GetMapping("/wzxqysjdhdb")
public R<List<wzxqysjdhdbVo>> wzxqysjdhdb(Long projectId) {
return R.ok(busMrpBaseService.wzxqysjdhdb(projectId));
}
/**
* 获取材料使用详情列表
*/
@GetMapping("/listUseDetail")
public R<List<MatMaterialsUseDetailVo>> listUseDetail(Long projectId) {
return R.ok(materialsService.listUseDetail(projectId));
}
}

View File

@ -0,0 +1,68 @@
package org.dromara.bigscreen.domain.vo;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
@Data
public class InventoryStructureAnalysisVo implements Serializable {
/**
* 本月入库总价
*/
public BigDecimal enterTotalPrices;
/**
* 上月入库总价
*/
public BigDecimal oldEnterTotalPrices;
/**
* 本月出库总价
*/
public BigDecimal leaveTotalPrices;
/**
* 上月出库总价
*/
public BigDecimal oldLeaveTotalPrices;
/**
* 库存总价
*/
public BigDecimal inventoryTotalPrices;
/**
* 出库总价
*/
public BigDecimal outTotalPrices;
/**
* 库存逆变器总价
*/
public BigDecimal inventoryInverterTotalPrices;
/**
* 库存箱变总价
*/
public BigDecimal inventoryBoxTransformerTotalPrices;
/**
* 库存光伏支架总价
*/
public BigDecimal inventoryPhotovoltaicSupportTotalPrices;
/**
* 库存环网柜总价
*/
public BigDecimal inventoryCircuitBreakerTotalPrices;
/**
* 当前库存总价
*/
public BigDecimal nowInventoryTotalPrices;
}

View File

@ -0,0 +1,40 @@
package org.dromara.bigscreen.domain.vo;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 设计量与到货量对比
*/
@Data
public class designAndArrivalComparisonVo implements Serializable {
/**
* 名称
*/
public String name;
/**
* 规格
*/
public String specification;
/**
* 单位
*/
public String unit;
/**
* 设计量
*/
public BigDecimal designTotalPrices;
/**
* 到货量
*/
public BigDecimal arrivalTotalPrices;
}

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 wzxqysjdhdbVo implements Serializable {
/**
* 名称
*/
public String name;
/**
* 规格
*/
public String specification;
/**
* 设计量
*/
public BigDecimal designTotalPrices;
/**
* 到货量
*/
public BigDecimal arrivalTotalPrices;
}

View File

@ -0,0 +1,22 @@
package org.dromara.bigscreen.enums;
public enum WuZhiEnum {
LBQ("逆变器"),
GFZJ("光伏支架"),
XB("箱变"),
HWG("环网柜");
private final String TypeName;
public String getTypeName() {
return TypeName;
}
WuZhiEnum(String TypeName) {
this.TypeName = TypeName;
}
}

View File

@ -0,0 +1,20 @@
package org.dromara.bigscreen.service;
import org.dromara.bigscreen.domain.vo.InventoryStructureAnalysisVo;
import org.dromara.project.domain.vo.project.BusProjectGisVo;
import java.util.List;
/**
* 物资管理大屏Service接口
*/
public interface IMaterialsManagementService {
/**
* 库存结构分析
* @param projectId
* @return
*/
InventoryStructureAnalysisVo inventoryStructureAnalysis(Long projectId);
}

View File

@ -0,0 +1,203 @@
package org.dromara.bigscreen.service.impl;
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.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.project.domain.vo.project.BusProjectGisVo;
import org.dromara.tender.domain.BusBillofquantitiesLimitList;
import org.dromara.tender.service.IBusBillofquantitiesLimitListService;
import org.springframework.context.annotation.Lazy;
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;
@Service
public class MaterialsManagementServiceImpl implements IMaterialsManagementService {
@Lazy
@Resource
private IMatMaterialReceiveItemService materialReceiveItemService;
@Lazy
@Resource
private IMatMaterialIssueItemService materialIssueItemService;
@Lazy
@Resource
private IMatMaterialsService materialsService;
@Lazy
@Resource
private IBusBillofquantitiesLimitListService billofquantitiesLimitListService;
@Override
public InventoryStructureAnalysisVo inventoryStructureAnalysis(Long projectId) {
InventoryStructureAnalysisVo vo = new InventoryStructureAnalysisVo();
// 获取当月第一天
LocalDateTime monthStart = LocalDateTime.now()
// 调整到当月第一天
.with(TemporalAdjusters.firstDayOfMonth())
// 重置时分秒毫秒为0
.withHour(0)
.withMinute(0)
.withSecond(0)
.withNano(0);
// 获取当前时间
LocalDateTime currentTime = LocalDateTime.now();
// 获取上月第一天
LocalDateTime lastMonthFirstDay = LocalDateTime.now()
// 先回退一个月
.minusMonths(1)
// 调整到当月第一天
.with(TemporalAdjusters.firstDayOfMonth())
// 重置时间为 00:00:00.000000000
.withHour(0)
.withMinute(0)
.withSecond(0);
// 获取上月最后一天
LocalDateTime lastMonthLastDay = LocalDateTime.now()
// 先回退一个月
.minusMonths(1)
// 调整到当月最后一天
.with(TemporalAdjusters.lastDayOfMonth())
// 设置时间为 23:59:59.999999999纳秒最大值对应毫秒级的999
.withHour(23)
.withMinute(59)
.withSecond(59);
// 获取当月入库数据
List<MatMaterialReceiveItem> matMaterialReceiveItems = materialReceiveItemService.getBaseMapper().selectList(new LambdaQueryWrapper<MatMaterialReceiveItem>()
.eq(MatMaterialReceiveItem::getProjectId, projectId)
.ne(MatMaterialReceiveItem::getAcceptedQuantity, BigDecimal.ZERO)
.between(MatMaterialReceiveItem::getCreateTime, monthStart, currentTime));
if (CollUtil.isEmpty(matMaterialReceiveItems)){
vo.setEnterTotalPrices(BigDecimal.ZERO);
}
// 计算本月入库金额
matMaterialReceiveItems.forEach(item -> {
vo.setEnterTotalPrices(vo.getEnterTotalPrices().add(item.getAcceptedQuantity().multiply(item.getUnitPrice())));
});
vo.setEnterTotalPrices(vo.getEnterTotalPrices().setScale(4, BigDecimal.ROUND_HALF_UP));
// 获取上月入库数据
List<MatMaterialReceiveItem> oldMatMaterialReceiveItems = materialReceiveItemService.getBaseMapper().selectList(new LambdaQueryWrapper<MatMaterialReceiveItem>()
.eq(MatMaterialReceiveItem::getProjectId, projectId)
.ne(MatMaterialReceiveItem::getAcceptedQuantity, BigDecimal.ZERO)
.between(MatMaterialReceiveItem::getCreateTime, lastMonthFirstDay, lastMonthLastDay));
if (CollUtil.isEmpty(oldMatMaterialReceiveItems)){
vo.setOldEnterTotalPrices(BigDecimal.ZERO);
}
// 计算上月入库金额
oldMatMaterialReceiveItems.forEach(item -> {
vo.setOldEnterTotalPrices(vo.getOldEnterTotalPrices().add(item.getAcceptedQuantity().multiply(item.getUnitPrice())));
});
vo.setOldEnterTotalPrices(vo.getOldEnterTotalPrices().setScale(4, BigDecimal.ROUND_HALF_UP));
// 获取当月出库数据
List<MatMaterialIssueItem> matMaterialIssueItems = materialIssueItemService.getBaseMapper()
.selectList(new LambdaQueryWrapper<MatMaterialIssueItem>()
.eq(MatMaterialIssueItem::getProjectId, projectId)
.ne(MatMaterialIssueItem::getIssuedQuantity, BigDecimal.ZERO)
.between(MatMaterialIssueItem::getCreateTime, monthStart, currentTime));
//计算本月出库金额
if (CollUtil.isEmpty(matMaterialIssueItems)){
vo.setLeaveTotalPrices(BigDecimal.ZERO);
}
matMaterialIssueItems.forEach(item -> {
vo.setLeaveTotalPrices(vo.getLeaveTotalPrices().add(item.getIssuedQuantity().multiply(item.getUnitPrice())));
});
vo.setLeaveTotalPrices(vo.getLeaveTotalPrices().setScale(4, BigDecimal.ROUND_HALF_UP));
// 获取上月出库数据
List<MatMaterialIssueItem> oldMatMaterialIssueItems = materialIssueItemService.getBaseMapper()
.selectList(new LambdaQueryWrapper<MatMaterialIssueItem>()
.eq(MatMaterialIssueItem::getProjectId, projectId)
.ne(MatMaterialIssueItem::getIssuedQuantity, BigDecimal.ZERO)
.between(MatMaterialIssueItem::getCreateTime, lastMonthFirstDay, lastMonthLastDay));
//计算上月出库金额
if (CollUtil.isEmpty(oldMatMaterialIssueItems)){
vo.setOldLeaveTotalPrices(BigDecimal.ZERO);
}
oldMatMaterialIssueItems.forEach(item -> {
vo.setOldLeaveTotalPrices(vo.getOldLeaveTotalPrices().add(item.getIssuedQuantity().multiply(item.getUnitPrice())));
});
vo.setOldLeaveTotalPrices(vo.getOldLeaveTotalPrices().setScale(4, BigDecimal.ROUND_HALF_UP));
//获取总入库存金额 入库 * 单价
List<MatMaterialReceiveItem> totalMatMaterialReceiveItems = materialReceiveItemService.getBaseMapper().selectList(new LambdaQueryWrapper<MatMaterialReceiveItem>().eq(MatMaterialReceiveItem::getProjectId, projectId));
if (CollUtil.isEmpty(totalMatMaterialReceiveItems)){
vo.setInventoryTotalPrices(BigDecimal.ZERO);
}
totalMatMaterialReceiveItems.forEach(item -> {
vo.setInventoryTotalPrices(vo.getInventoryTotalPrices().add(item.getAcceptedQuantity().multiply(item.getUnitPrice())));
});
vo.setInventoryTotalPrices(vo.getInventoryTotalPrices().setScale(4, BigDecimal.ROUND_HALF_UP));
// 获取总出库金额 出库 * 单价
List<MatMaterialIssueItem> totalMatMaterialIssueItems = materialIssueItemService.getBaseMapper().selectList(new LambdaQueryWrapper<MatMaterialIssueItem>().eq(MatMaterialIssueItem::getProjectId, projectId));
if (CollUtil.isEmpty(totalMatMaterialIssueItems)){
vo.setOutTotalPrices(BigDecimal.ZERO);
}
totalMatMaterialIssueItems.forEach(item -> {
vo.setOutTotalPrices(vo.getOutTotalPrices().add(item.getIssuedQuantity().multiply(item.getUnitPrice())));
});
vo.setOutTotalPrices(vo.getOutTotalPrices().setScale(4, BigDecimal.ROUND_HALF_UP));
// 获取施工图一览大类名下所有小类名
List<BusBillofquantitiesLimitList> limitLists = billofquantitiesLimitListService.getBaseMapper().selectList(new LambdaQueryWrapper<BusBillofquantitiesLimitList>()
.eq(BusBillofquantitiesLimitList::getProjectId, projectId)
.eq(BusBillofquantitiesLimitList::getPid, "0")
.eq(BusBillofquantitiesLimitList::getType, "3")
.eq(BusBillofquantitiesLimitList::getName, WuZhiEnum.LBQ.getTypeName()).or()
.eq(BusBillofquantitiesLimitList::getName, WuZhiEnum.GFZJ.getTypeName()).or()
.eq(BusBillofquantitiesLimitList::getName, WuZhiEnum.XB.getTypeName()).or()
.eq(BusBillofquantitiesLimitList::getName, WuZhiEnum.HWG.getTypeName())
);
List<String> lBQNames = new ArrayList<>();
List<String> sFZJNames = new ArrayList<>();
List<String> xBNames = new ArrayList<>();
List<String> hWGNames = new ArrayList<>();
for (BusBillofquantitiesLimitList item : limitLists) {
if (item.getName().equals(WuZhiEnum.LBQ.getTypeName())) {
lBQNames.add(item.getName());
continue;
}
if (item.getName().equals(WuZhiEnum.GFZJ.getTypeName())) {
sFZJNames.add(item.getName());
continue;
}
if (item.getName().equals(WuZhiEnum.XB.getTypeName())) {
xBNames.add(item.getName());
continue;
}
if (item.getName().equals(WuZhiEnum.HWG.getTypeName())) {
hWGNames.add(item.getName());
}
}
//获取库存逆变器总价
BigDecimal inventoryInverterTotalPrices = materialsService.selectTotalPricesByNames(projectId,lBQNames);
vo.setInventoryInverterTotalPrices(inventoryInverterTotalPrices);
//获取库存箱变总价
BigDecimal inventoryBoxTransformerTotalPrices = materialsService.selectTotalPricesByNames(projectId,xBNames);
vo.setInventoryBoxTransformerTotalPrices(inventoryBoxTransformerTotalPrices);
//获取库存光伏支架总价
BigDecimal inventoryPhotovoltaicSupportTotalPrices = materialsService.selectTotalPricesByNames(projectId,sFZJNames);
vo.setInventoryPhotovoltaicSupportTotalPrices(inventoryPhotovoltaicSupportTotalPrices);
//获取库存环网柜总价
BigDecimal inventoryCircuitBreakerTotalPrices = materialsService.selectTotalPricesByNames(projectId,hWGNames);
vo.setInventoryCircuitBreakerTotalPrices(inventoryCircuitBreakerTotalPrices);
//获取当前库存总价
BigDecimal nowInventoryTotalPrices = materialsService.selectTotalPrices(projectId);
vo.setNowInventoryTotalPrices(nowInventoryTotalPrices);
return vo;
}
}

View File

@ -94,6 +94,12 @@ public class BusMaterialbatchdemandplan extends BaseEntity {
*/
private BigDecimal demandQuantity;
/**
* 单价
*/
private BigDecimal unitPrice;
/**
* 计划到场时间
*/

View File

@ -93,6 +93,11 @@ public class BusMaterialbatchdemandplanBo extends BaseEntity {
*/
private BigDecimal demandQuantity;
/**
* 单价
*/
private BigDecimal unitPrice;
/**
* 计划到场时间
*/

View File

@ -118,6 +118,11 @@ public class BusMaterialbatchdemandplanVo implements Serializable {
@ExcelProperty(value = "需求数量")
private BigDecimal demandQuantity;
/**
* 单价
*/
private BigDecimal unitPrice;
/**
* 计划到场时间
*/

View File

@ -1,5 +1,7 @@
package org.dromara.cailiaoshebei.service;
import org.dromara.bigscreen.domain.vo.designAndArrivalComparisonVo;
import org.dromara.bigscreen.domain.vo.wzxqysjdhdbVo;
import org.dromara.cailiaoshebei.domain.bo.BusMrpBaseReq;
import org.dromara.cailiaoshebei.domain.dto.BusMrpDto;
import org.dromara.cailiaoshebei.domain.dto.BusMrpExportDto;
@ -90,4 +92,14 @@ public interface IBusMrpBaseService extends IService<BusMrpBase>{
Map<String, Object> remaining(Long projectId,Long limitListId,Long mrpBaseId);
List<BusMrpBaseVo> getListByName(BusMrpBaseReq req);
/**
* 设计量与到货量对比
*/
List<designAndArrivalComparisonVo> designAndArrivalComparison(Long projectId);
/**
* 物资需求与实际到货对比
*/
List<wzxqysjdhdbVo> wzxqysjdhdb(Long projectId);
}

View File

@ -105,4 +105,6 @@ public interface IBusPurchaseDocService extends IService<BusPurchaseDoc> {
* @return 是否修改成功
*/
Boolean updateFeedback(FeedbackDto dto);
List<BusPurchaseDocVo> purchaseNote(Long projectId);
}

View File

@ -4,7 +4,10 @@ import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.dromara.bigscreen.domain.vo.designAndArrivalComparisonVo;
import org.dromara.bigscreen.domain.vo.wzxqysjdhdbVo;
import org.dromara.cailiaoshebei.domain.BusMaterialbatchdemandplan;
import org.dromara.cailiaoshebei.domain.BusPlanDocAssociation;
import org.dromara.cailiaoshebei.domain.bo.BusMaterialbatchdemandplanBo;
@ -32,10 +35,15 @@ import lombok.RequiredArgsConstructor;
import org.dromara.common.utils.excel.ExcelDynamicReader;
import org.dromara.design.domain.BusBillofquantities;
import org.dromara.design.service.IBusBillofquantitiesService;
import org.dromara.materials.domain.MatMaterialReceiveItem;
import org.dromara.materials.service.IMatMaterialReceiveItemService;
import org.dromara.tender.domain.BusBillofquantitiesLimitList;
import org.dromara.tender.domain.BusTenderPlanningLimitList;
import org.dromara.tender.enums.LimitListTypeEnum;
import org.dromara.tender.service.IBusBillofquantitiesLimitListService;
import org.dromara.tender.service.IBusTenderPlanningLimitListService;
import org.jetbrains.annotations.NotNull;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
import org.dromara.cailiaoshebei.domain.bo.BusMrpBaseBo;
@ -70,6 +78,10 @@ public class BusMrpBaseServiceImpl extends ServiceImpl<BusMrpBaseMapper, BusMrpB
private final IBusTenderPlanningLimitListService tenderPlanningLimitListService;
@Lazy
@Resource
private IMatMaterialReceiveItemService matMaterialReceiveItemService;
/**
@ -327,6 +339,7 @@ public class BusMrpBaseServiceImpl extends ServiceImpl<BusMrpBaseMapper, BusMrpB
if (busBillofquantities != null) {
map.put("specification",busBillofquantities.getSpecification());
map.put("unit",busBillofquantities.getUnit());
map.put("unitPrice",busBillofquantities.getUnitPrice());
map.put("remark",busBillofquantities.getRemark());
map.put("name",busBillofquantities.getName());
}
@ -365,6 +378,80 @@ public class BusMrpBaseServiceImpl extends ServiceImpl<BusMrpBaseMapper, BusMrpB
.eq(BusMrpBase::getStatus,BusinessStatusEnum.FINISH.getStatus()).in(BusMrpBase::getId,mrpIds));
}
@Override
public List<designAndArrivalComparisonVo> designAndArrivalComparison(Long projectId) {
// 获取施工图一览的所有材料数据
List<BusBillofquantitiesLimitList> limitLists = busBillofquantitiesService.getBaseMapper().selectList(new LambdaQueryWrapper<BusBillofquantitiesLimitList>()
.eq(BusBillofquantitiesLimitList::getProjectId, projectId)
.eq(BusBillofquantitiesLimitList::getType, LimitListTypeEnum.SPECIAL.getCode())
.isNotNull(BusBillofquantitiesLimitList::getQuantity));
Map<Long, BigDecimal> wuZiMap = getWuZiMap(projectId);
// 根据批次需求计划的物资id获取到施工图一览对应数据
List<designAndArrivalComparisonVo> list = new ArrayList<>();
limitLists.forEach(limitList -> {
designAndArrivalComparisonVo vo = new designAndArrivalComparisonVo();
vo.setName(limitList.getName());
vo.setSpecification(limitList.getSpecification());
vo.setUnit(limitList.getUnit());
vo.setDesignTotalPrices(limitList.getQuantity());
vo.setArrivalTotalPrices(wuZiMap.getOrDefault(limitList.getId(), BigDecimal.ZERO));
list.add(vo);
});
return list;
}
@NotNull
private Map<Long, BigDecimal> getWuZiMap(Long projectId) {
// 获取所有入库数据 mat_material_receive_item
List<MatMaterialReceiveItem> matMaterialReceiveItems = matMaterialReceiveItemService.getBaseMapper()
.selectList(new LambdaQueryWrapper<MatMaterialReceiveItem>()
.eq(MatMaterialReceiveItem::getProjectId, projectId));
//将相同计划批次数据进行分组合并
Set<Long> planIds = matMaterialReceiveItems.stream()
.map(MatMaterialReceiveItem::getPlanId)
.collect(Collectors.toSet());
Map<Long, BigDecimal> planMap = matMaterialReceiveItems.stream()
.collect(Collectors.groupingBy(
MatMaterialReceiveItem::getPlanId,
Collectors.reducing(BigDecimal.ZERO, MatMaterialReceiveItem::getQuantity, BigDecimal::add)
));
// 根据入库数据反查批次需求计划数据 bus_materialbatchdemandplan
List<BusMaterialbatchdemandplan> materialbatchdemandplans = planservice.getBaseMapper().selectList(new LambdaQueryWrapper<BusMaterialbatchdemandplan>()
.eq(BusMaterialbatchdemandplan::getProjectId, projectId)
.in(BusMaterialbatchdemandplan::getId, planIds));
Map<Long, BigDecimal> wuZiMap = new HashMap<>();
materialbatchdemandplans.forEach(materialbatchdemandplan -> {
//merge()方法如果键存在则合并值,否则直接放入
wuZiMap.merge(
materialbatchdemandplan.getSuppliespriceId(),
planMap.get(materialbatchdemandplan.getId()),
BigDecimal::add
);
});
return wuZiMap;
}
@Override
public List<wzxqysjdhdbVo> wzxqysjdhdb(Long projectId) {
// 获取施工图一览的所有材料数据
List<BusBillofquantitiesLimitList> limitLists = busBillofquantitiesService.getBaseMapper().selectList(new LambdaQueryWrapper<BusBillofquantitiesLimitList>()
.eq(BusBillofquantitiesLimitList::getProjectId, projectId)
.eq(BusBillofquantitiesLimitList::getType, LimitListTypeEnum.SPECIAL.getCode())
.isNotNull(BusBillofquantitiesLimitList::getQuantity));
Map<Long, BigDecimal> wuZiMap = getWuZiMap(projectId);
// 根据批次需求计划的物资id获取到施工图一览对应数据
List<wzxqysjdhdbVo> list = new ArrayList<>();
limitLists.forEach(limitList -> {
wzxqysjdhdbVo vo = new wzxqysjdhdbVo();
vo.setName(limitList.getName());
vo.setSpecification(limitList.getSpecification());
vo.setDesignTotalPrices(limitList.getQuantity());
vo.setArrivalTotalPrices(wuZiMap.getOrDefault(limitList.getId(), BigDecimal.ZERO));
list.add(vo);
});
return list;
}
/**
* 总体流程监听(例如: 草稿,撤销,退回,作废,终止,已完成,单任务完成等)
* 正常使用只需#processEvent.flowCode=='leave1'

View File

@ -575,6 +575,15 @@ public class BusPurchaseDocServiceImpl extends ServiceImpl<BusPurchaseDocMapper,
return updateById(busPurchaseDoc);
}
@Override
public List<BusPurchaseDocVo> purchaseNote(Long projectId) {
return baseMapper.selectVoList(new LambdaQueryWrapper<BusPurchaseDoc>()
.eq(BusPurchaseDoc::getProjectId, projectId)
.eq(BusPurchaseDoc::getDocType, "1")
.eq(BusPurchaseDoc::getStatus, BusinessStatusEnum.FINISH.getStatus())
.orderByDesc(BusPurchaseDoc::getCreateTime));
}
/**
* 根据实体获取替换数据
*

View File

@ -54,6 +54,11 @@ public class MatMaterialIssueItem extends BaseEntity {
*/
private String unit;
/**
* 单价
*/
private BigDecimal unitPrice;
/**
* 库存
*/

View File

@ -59,6 +59,11 @@ public class MatMaterialReceiveItem extends BaseEntity {
*/
private BigDecimal quantity;
/**
* 单价
*/
private BigDecimal unitPrice;
/**
* 验收
*/

View File

@ -7,6 +7,7 @@ import lombok.EqualsAndHashCode;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import java.io.Serial;
import java.math.BigDecimal;
/**
* 材料名称对象 mat_materials
@ -68,6 +69,11 @@ public class MatMaterials extends BaseEntity {
*/
private String weightId;
/**
* 单价
*/
private BigDecimal unitPrice;
/**
* 备注
*/

View File

@ -45,6 +45,11 @@ public class MatMaterialIssueItemDto {
@NotBlank(message = "单位不能为空")
private String unit;
/**
* 单价
*/
private BigDecimal unitPrice;
/**
* 库存
*/

View File

@ -4,6 +4,8 @@ import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
@Data
@NoArgsConstructor
@AllArgsConstructor
@ -13,6 +15,7 @@ public class MatMaterialIssueItemWordDto {
private String name; // 名称
private String specification; // 规格
private String unit; // 单位
private BigDecimal unitPrice; //单价
private Integer stockQuantity; // 库存数量
private Integer issuedQuantity; // 领取数量
private Integer remainingQuantity;// 剩余数量

View File

@ -50,6 +50,11 @@ public class MatMaterialReceiveItemDto {
*/
private BigDecimal shortageQuantity;
/**
* 单价
*/
private BigDecimal unitPrice;
/**
* 备注
*/

View File

@ -4,6 +4,8 @@ import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
/**
* @author lilemy
* @date 2025/7/6 14:04
@ -38,6 +40,11 @@ public class MatMaterialReceiveItemWordDto {
*/
private Integer quantity;
/**
* 单价
*/
private BigDecimal unitPrice;
/**
* 验收
*/

View File

@ -4,6 +4,7 @@ import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Map;
/**
@ -61,6 +62,11 @@ public class MatMaterialsCreateReq implements Serializable {
*/
private String weightId;
/**
* 单价
*/
private BigDecimal unitPrice;
/**
* 备注
*/

View File

@ -4,6 +4,7 @@ import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* @author lilemy
@ -50,6 +51,11 @@ public class MatMaterialsQueryReq implements Serializable {
*/
private String weightId;
/**
* 单价
*/
private BigDecimal unitPrice;
/**
* 预计材料数量
*/

View File

@ -4,6 +4,7 @@ import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Map;
/**
@ -61,6 +62,12 @@ public class MatMaterialsUpdateReq implements Serializable {
*/
private String weightId;
/**
* 单价
*/
private BigDecimal unitPrice;
/**
* 备注
*/

View File

@ -52,6 +52,12 @@ public class MatMaterialIssueItemVo implements Serializable {
*/
private String unit;
/**
* 单价
*/
private BigDecimal unitPrice;
/**
* 库存
*/

View File

@ -52,6 +52,11 @@ public class MatMaterialReceiveItemVo implements Serializable {
*/
private String unit;
/**
* 单价
*/
private BigDecimal unitPrice;
/**
* 数量
*/

View File

@ -37,6 +37,11 @@ public class MatMaterialsNumberVo implements Serializable {
*/
private String weightId;
/**
* 单价
*/
private BigDecimal unitPrice;
/**
* 库存数量
*/

View File

@ -11,6 +11,7 @@ import org.dromara.tender.domain.vo.TenderSupplierInputVo;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;
@ -93,6 +94,11 @@ public class MatMaterialsVo implements Serializable {
@ExcelProperty(value = "备注")
private String remark;
/**
* 单价
*/
private BigDecimal unitPrice;
/**
* 预计材料数量
*/

View File

@ -3,6 +3,7 @@ package org.dromara.materials.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import org.dromara.common.core.domain.R;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.materials.domain.MatMaterials;
@ -16,6 +17,7 @@ import org.dromara.materials.domain.dto.materials.MatMaterialsQueryReq;
import org.dromara.materials.domain.dto.materials.MatMaterialsUpdateReq;
import org.dromara.materials.domain.vo.materials.*;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;
@ -187,4 +189,26 @@ public interface IMatMaterialsService extends IService<MatMaterials> {
* @return 材料库存数据列表
*/
List<MatMaterialsExcelVo> queryExcelList(MatMaterialsQueryReq req);
/**
* 根据项目id和材料名称获取当前库存总价
* @param projectId
* @param lBQNames
* @return
*/
BigDecimal selectTotalPricesByNames(Long projectId, List<String> lBQNames);
/**
* 根据项目id获取当前库存总价
* @param projectId
* @return
*/
BigDecimal selectTotalPrices(Long projectId);
/**
* 大屏获取物资跟踪管理台账
* @param projectId
* @return
*/
List<MatMaterialsUseDetailVo> listUseDetail(Long projectId);
}

View File

@ -565,6 +565,7 @@ public class MatMaterialIssueServiceImpl extends ServiceImpl<MatMaterialIssueMap
BeanUtils.copyProperties(item, itemDto);
itemDto.setNo(i);
itemDto.setIssuedQuantity(item.getIssuedQuantity() != null ? item.getIssuedQuantity().intValue() : 0);
itemDto.setUnitPrice(item.getUnitPrice() != null ? item.getUnitPrice() : BigDecimal.ZERO);
itemDto.setRemainingQuantity(item.getRemainingQuantity() != null ? item.getRemainingQuantity().intValue() : 0);
itemDto.setStockQuantity(item.getStockQuantity().intValue());
dtoItems.add(itemDto);

View File

@ -586,6 +586,7 @@ public class MatMaterialReceiveServiceImpl extends ServiceImpl<MatMaterialReceiv
BeanUtils.copyProperties(item, itemDto);
itemDto.setNo(i);
itemDto.setQuantity(item.getQuantity().intValue());
itemDto.setUnitPrice(item.getUnitPrice());
itemDto.setShortageQuantity(item.getShortageQuantity().intValue());
itemDto.setAcceptedQuantity(item.getAcceptedQuantity().intValue());
dtoItems.add(itemDto);

View File

@ -379,6 +379,7 @@ public class MatMaterialsServiceImpl extends ServiceImpl<MatMaterialsMapper, Mat
matMaterials.setWeightId(item.getUnit());
matMaterials.setQuantityCount(item.getQuantity().toString());
matMaterials.setFormCode(formCode);
matMaterials.setUnitPrice(item.getUnitPrice());
matMaterials.setWarehouseId(item.getWarehouseId());
save(matMaterials);
Long materialsId = matMaterials.getId();
@ -470,6 +471,7 @@ public class MatMaterialsServiceImpl extends ServiceImpl<MatMaterialsMapper, Mat
}
BeanUtils.copyProperties(m, numberVo);
numberVo.setInventoryNumber(BigDecimal.valueOf(inv.getResidue()));
numberVo.setUnitPrice(m.getUnitPrice());
return numberVo;
})
.filter(Objects::nonNull)
@ -769,6 +771,109 @@ public class MatMaterialsServiceImpl extends ServiceImpl<MatMaterialsMapper, Mat
return excelVoList;
}
/**
* 根据材料名称查询材料库存总价数据
* @param projectId
* @param lBQNames
* @return
*/
@Override
public BigDecimal selectTotalPricesByNames(Long projectId, List<String> lBQNames) {
if (CollUtil.isEmpty(lBQNames)) {
return BigDecimal.ZERO;
}
// 根据材料名称获取材料列表数据
List<MatMaterials> matMaterials = baseMapper.selectList(new LambdaQueryWrapper<MatMaterials>().eq(MatMaterials::getProjectId, projectId).in(MatMaterials::getMaterialsName, lBQNames));
if (CollUtil.isEmpty(matMaterials)) {
return BigDecimal.ZERO;
}
// 获取材料id和单价
Map<Long, BigDecimal> map = matMaterials.stream()
.collect(Collectors.toMap(
MatMaterials::getId,
MatMaterials::getUnitPrice
));
// 获取材料id
List<Long> ids = matMaterials.stream().map(MatMaterials::getId).toList();
// 获取材料库存数据
List<MatMaterialsInventory> inventories = materialsInventoryService.selectLatestByMaterialIds(ids);
if (CollUtil.isEmpty(inventories)){
return BigDecimal.ZERO;
}
// 计算材料总价
return inventories.stream()
.map(inventory -> map.getOrDefault(inventory.getMaterialsId(), BigDecimal.ZERO)
.multiply(BigDecimal.valueOf(inventory.getNumber())))
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
@Override
public BigDecimal selectTotalPrices(Long projectId) {
// 根据材料名称获取材料列表数据
List<MatMaterials> matMaterials = baseMapper.selectList(new LambdaQueryWrapper<MatMaterials>().eq(MatMaterials::getProjectId, projectId));
if (CollUtil.isEmpty(matMaterials)) {
return BigDecimal.ZERO;
}
// 获取材料id和单价
Map<Long, BigDecimal> map = matMaterials.stream()
.collect(Collectors.toMap(
MatMaterials::getId,
MatMaterials::getUnitPrice
));
// 获取材料id
List<Long> ids = matMaterials.stream().map(MatMaterials::getId).toList();
// 获取材料库存数据
List<MatMaterialsInventory> inventories = materialsInventoryService.selectLatestByMaterialIds(ids);
if (CollUtil.isEmpty(inventories)){
return BigDecimal.ZERO;
}
// 计算材料总价
return inventories.stream()
.map(inventory -> map.getOrDefault(inventory.getMaterialsId(), BigDecimal.ZERO)
.multiply(BigDecimal.valueOf(inventory.getNumber())))
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
@Override
public List<MatMaterialsUseDetailVo> listUseDetail(Long projectId) {
// 查询数据库
List<MatMaterials> matMaterials = baseMapper.selectList(new LambdaQueryWrapper<MatMaterials>().eq(MatMaterials::getProjectId, projectId));
if (CollUtil.isEmpty(matMaterials)) {
return List.of();
}
// 查询材料出入库列表
List<Long> ids = matMaterials.stream().map(MatMaterials::getId).toList();
List<MatMaterialsInventory> materialsInventoryList = materialsInventoryService.lambdaQuery()
.in(MatMaterialsInventory::getMaterialsId, ids)
.list();
List<MatMaterialsInventory> putList = materialsInventoryList.stream()
.filter(inventory -> inventory.getOutPut().equals(MatMaterialsInventoryOutPutEnum.PUT.getValue()))
.toList();
// 查询使用列表
List<MatMaterialsInventory> outList = materialsInventoryList.stream()
.filter(inventory -> inventory.getOutPut().equals(MatMaterialsInventoryOutPutEnum.OUT.getValue()))
.toList();
List<MatMaterialsUseRecord> useList = new ArrayList<>();
if (CollUtil.isNotEmpty(outList)) {
List<Long> outIds = outList.stream().map(MatMaterialsInventory::getId).toList();
useList = materialsUseRecordService.lambdaQuery()
.in(MatMaterialsUseRecord::getInventoryId, outIds)
.list();
}
// 查询仓库列表
Set<Long> warehouseIds = matMaterials.stream().map(MatMaterials::getWarehouseId).collect(Collectors.toSet());
List<MatWarehouse> warehouseList = new ArrayList<>();
if (CollUtil.isNotEmpty(warehouseIds)) {
warehouseList = warehouseService.lambdaQuery()
.in(MatWarehouse::getId, warehouseIds)
.list();
}
List<MatMaterialsUseDetailVo> useDetailList = this.getUseDetailList(matMaterials, putList, outList, useList, warehouseList);
return useDetailList;
}
/**
* 构建一行导出数据

View File

@ -4,20 +4,32 @@ import cn.hutool.json.JSONUtil;
import jakarta.websocket.*;
import jakarta.websocket.server.ServerEndpoint;
import lombok.extern.slf4j.Slf4j;
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.service.IMaterialsManagementService;
import org.dromara.cailiaoshebei.domain.vo.BusPurchaseDocVo;
import org.dromara.cailiaoshebei.service.IBusMrpBaseService;
import org.dromara.cailiaoshebei.service.IBusPurchaseDocService;
import org.dromara.common.core.utils.SpringUtils;
import org.dromara.gps.domain.bo.GpsEquipmentSonBo;
import org.dromara.gps.domain.vo.GpsEquipmentSonVo;
import org.dromara.gps.service.IGpsEquipmentSonService;
import org.dromara.materials.domain.vo.materials.MatMaterialsUseDetailVo;
import org.dromara.materials.service.IMatMaterialsService;
import org.dromara.websocket.websocket.domain.vo.VehicleVo;
import org.springframework.stereotype.Component;
import java.io.IOException;
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.ConcurrentHashMap;
import static kotlin.reflect.jvm.internal.impl.builtins.StandardNames.FqNames.list;
/**
* 大屏 WebSocket 服务端(支持订阅消息)
* 端点路径:/websocket/bigScreen
@ -72,25 +84,81 @@ public class BigScreenWebSocketServer {
try {
String[] split = currentSubscriptionId.split("-");
//todo 填充不同类型大屏获取基础数据的方法判断
IGpsEquipmentSonService service = SpringUtils.getBean(IGpsEquipmentSonService.class);
GpsEquipmentSonBo bo = new GpsEquipmentSonBo();
bo.setUserId(Long.parseLong(split[0]));
bo.setTripId(Long.parseLong(split[1]));
List<GpsEquipmentSonVo> list = service.getNewVehicleList(bo);
if (list == null || list.isEmpty()) {
IMaterialsManagementService managementService = SpringUtils.getBean(IMaterialsManagementService.class);
IBusPurchaseDocService purchaseDocService = SpringUtils.getBean(IBusPurchaseDocService.class);
IBusMrpBaseService mrpBaseService = SpringUtils.getBean(IBusMrpBaseService.class);
IMatMaterialsService materialsService = SpringUtils.getBean(IMatMaterialsService.class);
Long projectId = Long.parseLong(split[0]);
long type = Long.parseLong(split[1]);
List<Map<String, String>> maps = new ArrayList<>();
switch ((int) type){
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
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);
}
}
break;
case 6:
break;
case 7:
break;
default:
break;
}
if (maps.isEmpty()) {
session.getBasicRemote().sendText("初始化数据为空");
log.warn("会话[{}]未获取到初始化数据", session.getId());
return;
}
List<VehicleVo> vehicleVos = new ArrayList<>();
for (GpsEquipmentSonVo ueClient : list) {
VehicleVo vo = new VehicleVo();
vo.setLocLatitude(ueClient.getLocLatitude());
vo.setLocLongitude(ueClient.getLocLongitude());
vehicleVos.add(vo);
}
session.getBasicRemote().sendText(JSONUtil.toJsonStr(vehicleVos));
log.info("📤 已向会话[{}]推送初始化数据,长度:{}字节", session.getId(), vehicleVos.size());
session.getBasicRemote().sendText(JSONUtil.toJsonStr(maps));
log.info("📤 已向会话[{}]推送初始化数据,长度:{}字节", session.getId(), maps.size());
} catch (Exception e) {
log.error("会话[{}]初始化数据处理失败", session.getId(), e);
try {