物资、里程碑进度execl导出
This commit is contained in:
@ -10,7 +10,6 @@ import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.apache.poi.ss.util.CellRangeAddressList;
|
||||
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.dromara.common.core.constant.HttpStatus;
|
||||
import org.dromara.common.core.domain.event.ProcessDeleteEvent;
|
||||
@ -36,7 +35,6 @@ import org.dromara.project.service.IBusProjectService;
|
||||
import org.dromara.system.domain.vo.SysUserVo;
|
||||
import org.dromara.system.service.ISysUserService;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.stereotype.Service;
|
||||
@ -91,12 +89,12 @@ public class DesVolumeCatalogServiceImpl extends ServiceImpl<DesVolumeCatalogMap
|
||||
* @return 卷册目录
|
||||
*/
|
||||
@Override
|
||||
public DesVolumeCatalogVo queryById(Long id,String type) {
|
||||
public DesVolumeCatalogVo queryById(Long id, String type) {
|
||||
DesVolumeCatalog volumeCatalog = this.getById(id);
|
||||
if (volumeCatalog == null) {
|
||||
throw new ServiceException("卷册目录信息不存在", HttpStatus.NOT_FOUND);
|
||||
}
|
||||
return this.getVo(volumeCatalog,type);
|
||||
return this.getVo(volumeCatalog, type);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -120,7 +118,7 @@ public class DesVolumeCatalogServiceImpl extends ServiceImpl<DesVolumeCatalogMap
|
||||
*/
|
||||
@Override
|
||||
public List<DesVolumeCatalogVo> queryList(DesVolumeCatalogQueryReq req) {
|
||||
return this.list(this.buildQueryWrapper(req)).stream().map(vo-> this.getVo(vo,req.getType())).toList();
|
||||
return this.list(this.buildQueryWrapper(req)).stream().map(vo -> this.getVo(vo, req.getType())).toList();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -130,10 +128,10 @@ public class DesVolumeCatalogServiceImpl extends ServiceImpl<DesVolumeCatalogMap
|
||||
* @return 卷册目录文件列表
|
||||
*/
|
||||
@Override
|
||||
public List<DesVolumeFile> queryFileListById(Long id,String type) {
|
||||
public List<DesVolumeFile> queryFileListById(Long id, String type) {
|
||||
return volumeFileService.lambdaQuery()
|
||||
.eq(DesVolumeFile::getVolumeCatalogId, id)
|
||||
.eq(StringUtils.isNotBlank(type),DesVolumeFile::getType, type)
|
||||
.eq(StringUtils.isNotBlank(type), DesVolumeFile::getType, type)
|
||||
.orderByAsc(DesVolumeFile::getStatus)
|
||||
.orderByDesc(DesVolumeFile::getCreateDept)
|
||||
.list();
|
||||
@ -178,7 +176,7 @@ public class DesVolumeCatalogServiceImpl extends ServiceImpl<DesVolumeCatalogMap
|
||||
volumeCatalog.setSerialNumber(serialNumber);
|
||||
boolean save = this.save(volumeCatalog);
|
||||
if (!save) {
|
||||
RedisUtils.setCacheObject("DesVolumeCatalog:serialNumber",serialNumber);
|
||||
RedisUtils.setCacheObject("DesVolumeCatalog:serialNumber", serialNumber);
|
||||
throw new ServiceException("卷册目录新增失败", HttpStatus.ERROR);
|
||||
}
|
||||
return true;
|
||||
@ -209,7 +207,7 @@ public class DesVolumeCatalogServiceImpl extends ServiceImpl<DesVolumeCatalogMap
|
||||
if (count > 0) {
|
||||
throw new ServiceException("卷册目录已存在", HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
Long count1 = desUserService.getCount(req.getPrincipal(),req.getSpecialty(),req.getProjectId());
|
||||
Long count1 = desUserService.getCount(req.getPrincipal(), req.getSpecialty(), req.getProjectId());
|
||||
if (count1 == 0) {
|
||||
throw new ServiceException("所选专业不包含该人员");
|
||||
}
|
||||
@ -219,7 +217,7 @@ public class DesVolumeCatalogServiceImpl extends ServiceImpl<DesVolumeCatalogMap
|
||||
desVolumeCatalogs.add(volumeCatalog);
|
||||
}
|
||||
baseMapper.insertBatch(desVolumeCatalogs);
|
||||
RedisUtils.setCacheObject("DesVolumeCatalog:serialNumber",serialNumber);
|
||||
RedisUtils.setCacheObject("DesVolumeCatalog:serialNumber", serialNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -290,14 +288,14 @@ public class DesVolumeCatalogServiceImpl extends ServiceImpl<DesVolumeCatalogMap
|
||||
* @return 卷册目录封装对象
|
||||
*/
|
||||
@Override
|
||||
public DesVolumeCatalogVo getVo(DesVolumeCatalog volumeCatalog,String type) {
|
||||
public DesVolumeCatalogVo getVo(DesVolumeCatalog volumeCatalog, String type) {
|
||||
DesVolumeCatalogVo vo = new DesVolumeCatalogVo();
|
||||
if (volumeCatalog == null) {
|
||||
return vo;
|
||||
}
|
||||
BeanUtils.copyProperties(volumeCatalog, vo);
|
||||
// 关联文件信息
|
||||
List<DesVolumeFile> volumeFiles = this.queryFileListById(volumeCatalog.getDesign(),type);
|
||||
List<DesVolumeFile> volumeFiles = this.queryFileListById(volumeCatalog.getDesign(), type);
|
||||
vo.setFileVoList(volumeFileService.getVoList(volumeFiles));
|
||||
// 关联查阅人信息
|
||||
List<DesVolumeFileViewer> allViewerList = volumeFileViewerService.lambdaQuery()
|
||||
@ -341,7 +339,7 @@ public class DesVolumeCatalogServiceImpl extends ServiceImpl<DesVolumeCatalogMap
|
||||
lqw.like(StringUtils.isNotBlank(documentName), DesVolumeCatalog::getDocumentName, documentName);
|
||||
lqw.eq(StringUtils.isNotBlank(volumeNumber), DesVolumeCatalog::getVolumeNumber, volumeNumber);
|
||||
lqw.eq(ObjectUtils.isNotEmpty(projectId), DesVolumeCatalog::getProjectId, projectId);
|
||||
lqw.eq(StringUtils.isNotBlank(auditStatus),DesVolumeCatalog::getAuditStatus, auditStatus);
|
||||
lqw.eq(StringUtils.isNotBlank(auditStatus), DesVolumeCatalog::getAuditStatus, auditStatus);
|
||||
return lqw;
|
||||
}
|
||||
|
||||
@ -361,7 +359,7 @@ public class DesVolumeCatalogServiceImpl extends ServiceImpl<DesVolumeCatalogMap
|
||||
if (CollUtil.isEmpty(volumeCatalogList)) {
|
||||
return volumeCatalogVoPage;
|
||||
}
|
||||
List<DesVolumeCatalogVo> volumeCatalogVoList = volumeCatalogList.stream().map(vo-> getVo(vo,null)).toList();
|
||||
List<DesVolumeCatalogVo> volumeCatalogVoList = volumeCatalogList.stream().map(vo -> getVo(vo, null)).toList();
|
||||
|
||||
// 查询文件数量
|
||||
LambdaQueryWrapper<DesVolumeFile> fileQueryWrapper = new LambdaQueryWrapper<>();
|
||||
@ -369,9 +367,9 @@ public class DesVolumeCatalogServiceImpl extends ServiceImpl<DesVolumeCatalogMap
|
||||
fileQueryWrapper.clear();
|
||||
fileQueryWrapper.eq(DesVolumeFile::getVolumeCatalogId, desVolumeCatalogVo.getDesign());
|
||||
List<DesVolumeFile> list = volumeFileService.list(fileQueryWrapper);
|
||||
if (list != null && !list.isEmpty()){
|
||||
if (list != null && !list.isEmpty()) {
|
||||
desVolumeCatalogVo.setFileCount((long) list.size());
|
||||
}else{
|
||||
} else {
|
||||
desVolumeCatalogVo.setFileCount(0L);
|
||||
}
|
||||
|
||||
@ -416,7 +414,7 @@ public class DesVolumeCatalogServiceImpl extends ServiceImpl<DesVolumeCatalogMap
|
||||
.orderByDesc(DesVolumeFile::getCreateTime)
|
||||
|
||||
);
|
||||
if(list.isEmpty()){
|
||||
if (list.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<Long> list1 = list.stream().map(DesVolumeFile::getVolumeCatalogId).distinct().toList();
|
||||
@ -435,21 +433,15 @@ public class DesVolumeCatalogServiceImpl extends ServiceImpl<DesVolumeCatalogMap
|
||||
Map<String, String> uniqueMajors = desUserService.getUserMajor(desUserBo);
|
||||
Map<String, String> userList = desUserService.getUserList(desUserBo);
|
||||
|
||||
|
||||
|
||||
//TODO 数据绑定下拉
|
||||
// String[] namesArray = names.toArray(String[]::new);
|
||||
|
||||
|
||||
// 2. 设置响应头
|
||||
// 设置响应头,指定Excel格式和下载文件名
|
||||
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||
response.setCharacterEncoding("utf-8");
|
||||
response.setHeader("Content-Disposition", "attachment; filename="+ URLEncoder.encode("收资清单模板.xlsx", StandardCharsets.UTF_8));
|
||||
response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("卷册目录模板.xlsx", StandardCharsets.UTF_8));
|
||||
|
||||
Workbook workbook = new XSSFWorkbook();
|
||||
// 创建主 Sheet 和隐藏 Sheet
|
||||
Sheet mainSheet = workbook.createSheet("收资清单模板");
|
||||
Sheet mainSheet = workbook.createSheet("卷册目录模板");
|
||||
Sheet dataSheet = workbook.createSheet("DropdownData");
|
||||
workbook.setSheetHidden(workbook.getSheetIndex(dataSheet), true);
|
||||
|
||||
@ -483,23 +475,22 @@ public class DesVolumeCatalogServiceImpl extends ServiceImpl<DesVolumeCatalogMap
|
||||
// 主 Sheet 设置表头
|
||||
Row sheetRow = mainSheet.createRow(0);
|
||||
String[] headers = {"子项名称", "专业", "专业编码",
|
||||
"人员", "人员编码", "卷册号","资料名称","计划出图时间"};
|
||||
"人员", "人员编码", "卷册号", "资料名称", "计划出图时间"};
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
Cell cell = sheetRow.createCell(i);
|
||||
cell.setCellValue(headers[i]);
|
||||
}
|
||||
|
||||
// 6. 设置专业下拉列表(第二列)
|
||||
setMajorDropdown(mainSheet,uniqueMajors.size());
|
||||
|
||||
setMajorDropdown(mainSheet, uniqueMajors.size());
|
||||
|
||||
|
||||
// 8. 设置人员下拉列表(第四列)
|
||||
setPersonDropdown(mainSheet, userList.size());
|
||||
|
||||
String formulaTemplate = "IFERROR(INDEX(DropdownData!$B$1:$B$" + uniqueMajors.size() + ", MATCH(B{rowNum}, DropdownData!$A$1:$A$" + uniqueMajors.size()+ ", 0)),\"\")";
|
||||
String formulaTemplate = "IFERROR(INDEX(DropdownData!$B$1:$B$" + uniqueMajors.size() + ", MATCH(B{rowNum}, DropdownData!$A$1:$A$" + uniqueMajors.size() + ", 0)),\"\")";
|
||||
|
||||
String formulaTemplate1 = "IFERROR(INDEX(DropdownData!$D$1:$D$" + userList.size() + ", MATCH(D{rowNum}, DropdownData!$C$1:$C$" + userList.size()+ ", 0)),\"\")";
|
||||
String formulaTemplate1 = "IFERROR(INDEX(DropdownData!$D$1:$D$" + userList.size() + ", MATCH(D{rowNum}, DropdownData!$C$1:$C$" + userList.size() + ", 0)),\"\")";
|
||||
|
||||
|
||||
for (int i = 1; i <= 100; i++) { // 从第2行到101行
|
||||
@ -544,7 +535,6 @@ public class DesVolumeCatalogServiceImpl extends ServiceImpl<DesVolumeCatalogMap
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 保护工作表,仅允许编辑未锁定的单元格
|
||||
mainSheet.protectSheet("123456"); // 空密码
|
||||
|
||||
@ -573,7 +563,6 @@ public class DesVolumeCatalogServiceImpl extends ServiceImpl<DesVolumeCatalogMap
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 创建可编辑单元格样式
|
||||
*/
|
||||
@ -599,7 +588,7 @@ public class DesVolumeCatalogServiceImpl extends ServiceImpl<DesVolumeCatalogMap
|
||||
/**
|
||||
* 设置专业下拉列表(第二列,索引1)
|
||||
*/
|
||||
private void setMajorDropdown(Sheet mainSheet,int majorCount) {
|
||||
private void setMajorDropdown(Sheet mainSheet, int majorCount) {
|
||||
DataValidationHelper helper = mainSheet.getDataValidationHelper();
|
||||
|
||||
// 专业数据范围:数据Sheet的A列(从第1行到专业数量行)
|
||||
@ -616,7 +605,6 @@ public class DesVolumeCatalogServiceImpl extends ServiceImpl<DesVolumeCatalogMap
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 设置人员下拉列表(第四列,索引3)
|
||||
*/
|
||||
@ -655,11 +643,11 @@ public class DesVolumeCatalogServiceImpl extends ServiceImpl<DesVolumeCatalogMap
|
||||
}
|
||||
desVolumeCatalog.setAuditStatus(processEvent.getStatus());
|
||||
//如果完成,变更状态为已完成
|
||||
if (processEvent.getStatus().equals("finish")){
|
||||
if (processEvent.getStatus().equals("finish")) {
|
||||
desVolumeCatalog.setDesignState("1");
|
||||
}
|
||||
|
||||
if(BusinessStatusEnum.FINISH.getStatus().equals(processEvent.getStatus())){
|
||||
if (BusinessStatusEnum.FINISH.getStatus().equals(processEvent.getStatus())) {
|
||||
ArrayList<DesDrawing> desDrawings = new ArrayList<>();
|
||||
|
||||
List<DesVolumeFile> list = volumeFileService.lambdaQuery().eq(DesVolumeFile::getVolumeCatalogId, id).list();
|
||||
@ -672,7 +660,7 @@ public class DesVolumeCatalogServiceImpl extends ServiceImpl<DesVolumeCatalogMap
|
||||
|
||||
desDrawings.add(desDrawing);
|
||||
//异步处理二维码
|
||||
self.addQRCodeToPDF(desVolumeFile.getId(),false)
|
||||
self.addQRCodeToPDF(desVolumeFile.getId(), false)
|
||||
.thenAccept(result -> log.info("图纸[{}-{} ]添加二维码成功", desVolumeFile.getFileName(), desVolumeFile.getId()))
|
||||
.exceptionally(ex -> {
|
||||
log.error("图纸[{}-{}]添加二维码失败", desVolumeFile.getFileName(), desVolumeFile.getId(), ex);
|
||||
|
@ -36,7 +36,7 @@ public class MatMaterialsUseDetailVo implements Serializable {
|
||||
/**
|
||||
* 供货单位
|
||||
*/
|
||||
private String companyName;
|
||||
private String supplier;
|
||||
|
||||
/**
|
||||
* 入库id
|
||||
@ -53,11 +53,6 @@ public class MatMaterialsUseDetailVo implements Serializable {
|
||||
*/
|
||||
private String operator;
|
||||
|
||||
/**
|
||||
* 交接单位
|
||||
*/
|
||||
private String recipient;
|
||||
|
||||
/**
|
||||
* 入库时间
|
||||
*/
|
||||
|
@ -170,12 +170,14 @@ public interface IMatMaterialsService extends IService<MatMaterials> {
|
||||
* 获取材料使用详情列表
|
||||
*
|
||||
* @param materials 材料
|
||||
* @param inventoryList 材料库存列表
|
||||
* @param putList 材料入库列表
|
||||
* @param outList 材料出库列表
|
||||
* @param useList 材料使用列表
|
||||
* @return 材料使用详情列表
|
||||
*/
|
||||
List<MatMaterialsUseDetailVo> getUseDetailList(List<MatMaterials> materials,
|
||||
List<MatMaterialsInventory> inventoryList,
|
||||
List<MatMaterialsInventory> putList,
|
||||
List<MatMaterialsInventory> outList,
|
||||
List<MatMaterialsUseRecord> useList);
|
||||
|
||||
/**
|
||||
|
@ -31,8 +31,10 @@ import org.dromara.materials.domain.dto.materialsinventory.MatMaterialsInventory
|
||||
import org.dromara.materials.domain.enums.MatMaterialsInventoryOutPutEnum;
|
||||
import org.dromara.materials.domain.enums.MatMaterialsInventoryReceiveStatusEnum;
|
||||
import org.dromara.materials.domain.vo.materials.*;
|
||||
import org.dromara.materials.domain.vo.materialsinventory.MatMaterialsInventoryOutUseVo;
|
||||
import org.dromara.materials.domain.vo.materialsinventory.MatMaterialsInventoryOutVo;
|
||||
import org.dromara.materials.domain.vo.materialsinventory.MatMaterialsInventoryVo;
|
||||
import org.dromara.materials.domain.vo.materialsuserecord.MatMaterialsUseRecordByOutVo;
|
||||
import org.dromara.materials.mapper.MatMaterialsMapper;
|
||||
import org.dromara.materials.service.*;
|
||||
import org.dromara.project.domain.BusProject;
|
||||
@ -613,84 +615,190 @@ public class MatMaterialsServiceImpl extends ServiceImpl<MatMaterialsMapper, Mat
|
||||
result.getSize(),
|
||||
result.getTotal()
|
||||
);
|
||||
/* if (CollUtil.isEmpty(materialsList)) {
|
||||
return materialsVoPage;
|
||||
}*/
|
||||
return null;
|
||||
if (CollUtil.isEmpty(materialsList)) {
|
||||
return TableDataInfo.build(materialsVoPage);
|
||||
}
|
||||
// 查询材料出入库列表
|
||||
List<Long> ids = materialsList.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();
|
||||
}
|
||||
List<MatMaterialsUseDetailVo> useDetailList = this.getUseDetailList(materialsList, putList, outList, useList);
|
||||
materialsVoPage.setRecords(useDetailList);
|
||||
return TableDataInfo.build(materialsVoPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取材料使用详情列表
|
||||
*
|
||||
* @param materials 材料
|
||||
* @param inventoryList 材料库存列表
|
||||
* @param putList 材料入库列表
|
||||
* @param outList 材料出库列表
|
||||
* @param useList 材料使用列表
|
||||
* @return 材料使用详情列表
|
||||
*/
|
||||
@Override
|
||||
public List<MatMaterialsUseDetailVo> getUseDetailList(List<MatMaterials> materials, List<MatMaterialsInventory> inventoryList, List<MatMaterialsUseRecord> useList) {
|
||||
return List.of();
|
||||
public List<MatMaterialsUseDetailVo> getUseDetailList(List<MatMaterials> materials,
|
||||
List<MatMaterialsInventory> putList,
|
||||
List<MatMaterialsInventory> outList,
|
||||
List<MatMaterialsUseRecord> useList) {
|
||||
Map<Long, MatMaterialsInventory> putMap = putList.stream()
|
||||
.collect(Collectors.toMap(MatMaterialsInventory::getMaterialsId, inventory -> inventory));
|
||||
return materials.stream().map(material -> {
|
||||
MatMaterialsUseDetailVo vo = new MatMaterialsUseDetailVo();
|
||||
BeanUtils.copyProperties(material, vo);
|
||||
Long id = material.getId();
|
||||
MatMaterialsInventory put = putMap.get(id);
|
||||
vo.setSupplier(put.getRecipient());
|
||||
vo.setInventoryId(put.getId());
|
||||
vo.setNumber(put.getNumber());
|
||||
vo.setOperator(put.getOperator());
|
||||
vo.setEnterTime(put.getCreateTime());
|
||||
if (CollUtil.isNotEmpty(outList)) {
|
||||
List<MatMaterialsInventory> outs = outList.stream()
|
||||
.filter(inventory -> inventory.getMaterialsId().equals(id))
|
||||
.toList();
|
||||
if (CollUtil.isNotEmpty(outs)) {
|
||||
List<MatMaterialsInventoryOutUseVo> outUseVos = outs.stream().map(inventory -> {
|
||||
MatMaterialsInventoryOutUseVo outUseVo = new MatMaterialsInventoryOutUseVo();
|
||||
BeanUtils.copyProperties(inventory, outUseVo);
|
||||
if (CollUtil.isNotEmpty(useList)) {
|
||||
List<MatMaterialsUseRecord> uses = useList.stream()
|
||||
.filter(record -> record.getInventoryId().equals(inventory.getId()))
|
||||
.toList();
|
||||
List<MatMaterialsUseRecordByOutVo> useRecordList = uses.stream().map(record -> {
|
||||
MatMaterialsUseRecordByOutVo useRecordVo = new MatMaterialsUseRecordByOutVo();
|
||||
BeanUtils.copyProperties(record, useRecordVo);
|
||||
return useRecordVo;
|
||||
}).toList();
|
||||
outUseVo.setUseList(useRecordList);
|
||||
}
|
||||
return outUseVo;
|
||||
}).toList();
|
||||
vo.setOutList(outUseVos);
|
||||
}
|
||||
|
||||
}
|
||||
return vo;
|
||||
}).toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取材料库存数据列表
|
||||
* 获取材料库存数据列表(导出 Excel 用)
|
||||
*
|
||||
* @param req 查询条件
|
||||
* @return 材料库存数据列表
|
||||
*/
|
||||
@Override
|
||||
public List<MatMaterialsExcelVo> queryExcelList(MatMaterialsQueryReq req) {
|
||||
// 查询数据库
|
||||
LambdaQueryWrapper<MatMaterials> lqw = this.buildQueryWrapper(req);
|
||||
List<MatMaterials> materials = this.list(lqw);
|
||||
if (CollUtil.isEmpty(materials)) {
|
||||
return List.of();
|
||||
}
|
||||
// 获取材料主键
|
||||
|
||||
List<Long> ids = materials.stream().map(MatMaterials::getId).toList();
|
||||
// 获取出入库记录
|
||||
|
||||
List<MatMaterialsInventory> inventoryList = materialsInventoryService.lambdaQuery()
|
||||
.in(MatMaterialsInventory::getMaterialsId, ids)
|
||||
.list();
|
||||
// 获取入库记录
|
||||
List<MatMaterialsInventory> putList = inventoryList.stream()
|
||||
.filter(inventory -> inventory.getOutPut().equals(MatMaterialsInventoryOutPutEnum.PUT.getValue()))
|
||||
.toList();
|
||||
Map<Long, MatMaterialsInventory> putMap = putList.stream()
|
||||
.collect(Collectors.toMap(MatMaterialsInventory::getMaterialsId, inventory -> inventory));
|
||||
// 获取使用记录
|
||||
|
||||
Map<Long, MatMaterialsInventory> putMap = inventoryList.stream()
|
||||
.filter(inv -> inv.getOutPut().equals(MatMaterialsInventoryOutPutEnum.PUT.getValue()))
|
||||
.collect(Collectors.toMap(MatMaterialsInventory::getMaterialsId, Function.identity()));
|
||||
|
||||
List<MatMaterialsInventory> outList = inventoryList.stream()
|
||||
.filter(inventory -> inventory.getOutPut().equals(MatMaterialsInventoryOutPutEnum.OUT.getValue()))
|
||||
.filter(inv -> inv.getOutPut().equals(MatMaterialsInventoryOutPutEnum.OUT.getValue()))
|
||||
.toList();
|
||||
List<MatMaterialsUseRecord> useList = new ArrayList<>();
|
||||
if (CollUtil.isEmpty(outList)) {
|
||||
List<Long> outIds = outList.stream().map(MatMaterialsInventory::getId).distinct().toList();
|
||||
// 获取使用记录
|
||||
useList = materialsUseRecordService.lambdaQuery()
|
||||
|
||||
Map<Long, List<MatMaterialsUseRecord>> useMap = new HashMap<>();
|
||||
if (CollUtil.isNotEmpty(outList)) {
|
||||
List<Long> outIds = outList.stream().map(MatMaterialsInventory::getId).toList();
|
||||
List<MatMaterialsUseRecord> useList = materialsUseRecordService.lambdaQuery()
|
||||
.in(MatMaterialsUseRecord::getInventoryId, outIds)
|
||||
.list();
|
||||
useMap = useList.stream().collect(Collectors.groupingBy(MatMaterialsUseRecord::getInventoryId));
|
||||
}
|
||||
|
||||
List<MatMaterialsExcelVo> excelVoList = new ArrayList<>();
|
||||
|
||||
for (MatMaterials material : materials) {
|
||||
MatMaterialsInventory put = putMap.get(material.getId());
|
||||
|
||||
List<MatMaterialsInventory> materialOutList = outList.stream()
|
||||
.filter(inv -> inv.getMaterialsId().equals(material.getId()))
|
||||
.toList();
|
||||
|
||||
boolean firstMaterialRow = true; // 记录材料是否是第一行
|
||||
|
||||
if (CollUtil.isEmpty(materialOutList)) {
|
||||
excelVoList.add(buildVo(material, put, null, null, firstMaterialRow, false));
|
||||
continue;
|
||||
}
|
||||
|
||||
for (MatMaterialsInventory out : materialOutList) {
|
||||
List<MatMaterialsUseRecord> outUseList = useMap.getOrDefault(out.getId(), List.of());
|
||||
boolean firstOutRow = true; // 记录出库是否是第一行
|
||||
|
||||
if (CollUtil.isEmpty(outUseList)) {
|
||||
excelVoList.add(buildVo(material, put, out, null, firstMaterialRow, firstOutRow));
|
||||
firstMaterialRow = false;
|
||||
} else {
|
||||
for (MatMaterialsUseRecord use : outUseList) {
|
||||
excelVoList.add(buildVo(material, put, out, use, firstMaterialRow, firstOutRow));
|
||||
firstMaterialRow = false;
|
||||
firstOutRow = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return excelVoList;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 构建一行导出数据
|
||||
*/
|
||||
private MatMaterialsExcelVo buildVo(MatMaterials material,
|
||||
MatMaterialsInventory put,
|
||||
MatMaterialsInventory out,
|
||||
MatMaterialsUseRecord use,
|
||||
boolean showMaterial,
|
||||
boolean showOut) {
|
||||
MatMaterialsExcelVo vo = new MatMaterialsExcelVo();
|
||||
Long id = material.getId();
|
||||
|
||||
// 材料信息(只显示一次)
|
||||
if (showMaterial) {
|
||||
vo.setMaterialsName(material.getMaterialsName());
|
||||
vo.setQuantityCount(material.getQuantityCount());
|
||||
// 拼接入库记录
|
||||
MatMaterialsInventory put = putMap.get(id);
|
||||
|
||||
if (put != null) {
|
||||
vo.setSupplier(put.getRecipient());
|
||||
vo.setPutNumber(put.getNumber());
|
||||
vo.setSigner(put.getOperator());
|
||||
if (put.getCreateTime() != null) {
|
||||
vo.setPutTime(DateUtils.parseDateToStr(FormatsType.YYYY_MM_DD_DOT, put.getCreateTime()));
|
||||
}
|
||||
List<MatMaterialsInventory> materialOutList = outList.stream()
|
||||
.filter(inventory -> inventory.getMaterialsId().equals(id))
|
||||
.toList();
|
||||
List<MatMaterialsUseRecord> materialUseList = new ArrayList<>();
|
||||
if (CollUtil.isNotEmpty(materialOutList)) {
|
||||
// 拼接第一条出库数据
|
||||
MatMaterialsInventory out = materialOutList.getFirst();
|
||||
}
|
||||
}
|
||||
|
||||
// 出库信息(同一条出库只显示一次)
|
||||
if (showOut && out != null) {
|
||||
vo.setRecipient(out.getRecipient());
|
||||
vo.setOutNumber(out.getNumber());
|
||||
vo.setOperator(out.getOperator());
|
||||
@ -700,89 +808,21 @@ public class MatMaterialsServiceImpl extends ServiceImpl<MatMaterialsMapper, Mat
|
||||
}
|
||||
vo.setResidue(out.getResidue());
|
||||
vo.setDisposition(out.getDisposition());
|
||||
materialUseList = useList.stream()
|
||||
.filter(record -> record.getInventoryId().equals(out.getId()))
|
||||
.toList();
|
||||
if (CollUtil.isNotEmpty(materialUseList)) {
|
||||
// 拼接第一条使用记录
|
||||
MatMaterialsUseRecord use = materialUseList.getFirst();
|
||||
vo.setUsePart(use.getUsePart());
|
||||
vo.setUseNumber(use.getUseNumber());
|
||||
if (use.getCreateTime() != null) {
|
||||
vo.setUseTime(DateUtils.parseDateToStr(FormatsType.YYYY_MM_DD_DOT, use.getCreateTime()));
|
||||
}
|
||||
vo.setSurplus(use.getResidueNumber());
|
||||
vo.setRemark(use.getRemark());
|
||||
}
|
||||
}
|
||||
List<MatMaterialsExcelVo> childList = new ArrayList<>();
|
||||
if (CollUtil.isNotEmpty(materialUseList)) {
|
||||
for (int i = 1; i < materialOutList.size(); i++) {
|
||||
MatMaterialsInventory out = materialOutList.get(i);
|
||||
List<MatMaterialsUseRecord> outUseList = materialUseList.stream()
|
||||
.filter(record -> record.getInventoryId().equals(out.getId()))
|
||||
.toList();
|
||||
if (CollUtil.isNotEmpty(outUseList)) {
|
||||
for (int j = 1; j < outUseList.size(); j++) {
|
||||
MatMaterialsExcelVo child = new MatMaterialsExcelVo();
|
||||
MatMaterialsUseRecord use = outUseList.get(j);
|
||||
if (j == 1) {
|
||||
// 拼接出库记录
|
||||
child.setRecipient(out.getRecipient());
|
||||
child.setOutNumber(out.getNumber());
|
||||
child.setOperator(out.getOperator());
|
||||
child.setShipper(out.getShipper());
|
||||
if (out.getCreateTime() != null) {
|
||||
child.setReceivingDate(DateUtils.parseDateToStr(FormatsType.YYYY_MM_DD_DOT, out.getCreateTime()));
|
||||
}
|
||||
child.setResidue(out.getResidue());
|
||||
child.setDisposition(out.getDisposition());
|
||||
}
|
||||
// 拼接使用记录
|
||||
vo.setUsePart(use.getUsePart());
|
||||
vo.setUseNumber(use.getUseNumber());
|
||||
if (use.getCreateTime() != null) {
|
||||
vo.setUseTime(DateUtils.parseDateToStr(FormatsType.YYYY_MM_DD_DOT, use.getCreateTime()));
|
||||
}
|
||||
vo.setSurplus(use.getResidueNumber());
|
||||
vo.setRemark(use.getRemark());
|
||||
childList.add(child);
|
||||
}
|
||||
} else {
|
||||
MatMaterialsExcelVo child = new MatMaterialsExcelVo();
|
||||
child.setRecipient(out.getRecipient());
|
||||
child.setOutNumber(out.getNumber());
|
||||
child.setOperator(out.getOperator());
|
||||
child.setShipper(out.getShipper());
|
||||
if (out.getCreateTime() != null) {
|
||||
child.setReceivingDate(DateUtils.parseDateToStr(FormatsType.YYYY_MM_DD_DOT, out.getCreateTime()));
|
||||
}
|
||||
child.setResidue(out.getResidue());
|
||||
child.setDisposition(out.getDisposition());
|
||||
childList.add(child);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
childList = materialOutList.stream()
|
||||
.skip(1)
|
||||
.map(out -> {
|
||||
MatMaterialsExcelVo v = new MatMaterialsExcelVo();
|
||||
v.setRecipient(out.getRecipient());
|
||||
v.setOutNumber(out.getNumber());
|
||||
v.setOperator(out.getOperator());
|
||||
v.setShipper(out.getShipper());
|
||||
if (out.getCreateTime() != null) {
|
||||
v.setReceivingDate(DateUtils.parseDateToStr(FormatsType.YYYY_MM_DD_DOT, out.getCreateTime()));
|
||||
}
|
||||
v.setResidue(out.getResidue());
|
||||
v.setDisposition(out.getDisposition());
|
||||
return v;
|
||||
}).toList();
|
||||
|
||||
// 使用信息(每条都显示)
|
||||
if (use != null) {
|
||||
vo.setUsePart(use.getUsePart());
|
||||
vo.setUseNumber(use.getUseNumber());
|
||||
if (use.getCreateTime() != null) {
|
||||
vo.setUseTime(DateUtils.parseDateToStr(FormatsType.YYYY_MM_DD_DOT, use.getCreateTime()));
|
||||
}
|
||||
excelVoList.add(vo);
|
||||
excelVoList.addAll(childList);
|
||||
vo.setSurplus(use.getResidueNumber());
|
||||
vo.setRemark(use.getRemark());
|
||||
}
|
||||
return excelVoList;
|
||||
|
||||
return vo;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package org.dromara.out.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
@ -32,6 +33,7 @@ import org.springframework.context.event.EventListener;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -109,7 +111,13 @@ public class OutConstructionValueServiceImpl extends ServiceImpl<OutConstruction
|
||||
List<BusProject> subProjectIds = projectService.lambdaQuery()
|
||||
.eq(BusProject::getPId, projectId)
|
||||
.list();
|
||||
lqw.in(OutConstructionValue::getProjectId, projectId, subProjectIds);
|
||||
if (CollUtil.isNotEmpty(subProjectIds)) {
|
||||
List<Long> ids = new ArrayList<>(subProjectIds.stream().map(BusProject::getId).toList());
|
||||
ids.add(projectId);
|
||||
lqw.in(OutConstructionValue::getProjectId, ids);
|
||||
} else {
|
||||
lqw.eq(OutConstructionValue::getProjectId, projectId);
|
||||
}
|
||||
}
|
||||
lqw.eq(bo.getMatrixId() != null, OutConstructionValue::getMatrixId, bo.getMatrixId());
|
||||
lqw.eq(bo.getProgressCategoryId() != null, OutConstructionValue::getProgressCategoryId, bo.getProgressCategoryId());
|
||||
@ -225,7 +233,7 @@ public class OutConstructionValueServiceImpl extends ServiceImpl<OutConstruction
|
||||
vo.setProjectName(busProjectVo.getProjectName());
|
||||
|
||||
//查询方阵以及子项目
|
||||
if (vo.getMatrixId() != null) {
|
||||
if (vo.getMatrixId() != null && vo.getMatrixId() != 0) {
|
||||
FacMatrix facMatrix = facMatrixService.getById(vo.getMatrixId());
|
||||
vo.setMatrixName(facMatrix.getMatrixName());
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package org.dromara.progress.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
@ -13,13 +14,17 @@ import org.dromara.common.idempotent.annotation.RepeatSubmit;
|
||||
import org.dromara.common.log.annotation.Log;
|
||||
import org.dromara.common.log.enums.BusinessType;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.dromara.progress.domain.PgsConstructionSchedulePlan;
|
||||
import org.dromara.progress.domain.dto.constructionscheduleplan.PgsConstructionSchedulePlanCreateReq;
|
||||
import org.dromara.progress.domain.dto.constructionscheduleplan.PgsConstructionSchedulePlanExcelDto;
|
||||
import org.dromara.progress.domain.dto.constructionscheduleplan.PgsConstructionSchedulePlanQueryReq;
|
||||
import org.dromara.progress.domain.dto.constructionscheduleplan.PgsConstructionSchedulePlanUpdateReq;
|
||||
import org.dromara.progress.domain.vo.constructionscheduleplan.PgsConstructionSchedulePlanVo;
|
||||
import org.dromara.progress.service.IPgsConstructionSchedulePlanService;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -58,6 +63,36 @@ public class PgsConstructionSchedulePlanController extends BaseController {
|
||||
ExcelUtil.exportExcel(list, "施工进度计划", PgsConstructionSchedulePlanVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据项目id导出施工进度计划模版
|
||||
*/
|
||||
@SaCheckPermission("progress:constructionSchedulePlan:exportTemplate")
|
||||
@Log(title = "施工进度计划", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/exportTemplate/{projectId}")
|
||||
public void exportExcelByProjectId(@NotNull(message = "项目id不能为空")
|
||||
@PathVariable Long projectId, HttpServletResponse response) {
|
||||
pgsConstructionSchedulePlanService.exportExcelByProjectId(projectId, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取施工进度计划模版
|
||||
*/
|
||||
@SaCheckPermission("progress:constructionSchedulePlan:readTemplate")
|
||||
@Log(title = "施工进度计划", businessType = BusinessType.IMPORT)
|
||||
@PostMapping("/readTemplate")
|
||||
public R<Void> readExcel(@RequestParam("file") MultipartFile file, Long projectId) {
|
||||
List<PgsConstructionSchedulePlanExcelDto> list = pgsConstructionSchedulePlanService.readExcel(file, projectId);
|
||||
if (CollUtil.isNotEmpty(list)) {
|
||||
List<PgsConstructionSchedulePlan> planList = list.stream().map(dto -> {
|
||||
PgsConstructionSchedulePlan plan = new PgsConstructionSchedulePlan();
|
||||
BeanUtils.copyProperties(dto, plan);
|
||||
return plan;
|
||||
}).toList();
|
||||
return toAjax(pgsConstructionSchedulePlanService.saveBatch(planList));
|
||||
}
|
||||
return toAjax(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取施工进度计划详细信息
|
||||
*
|
||||
|
@ -7,7 +7,7 @@ import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.util.Date;
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* 施工进度计划对象 pgs_construction_schedule_plan
|
||||
@ -57,22 +57,22 @@ public class PgsConstructionSchedulePlan extends BaseEntity {
|
||||
/**
|
||||
* 预计开始时间
|
||||
*/
|
||||
private Date planStartDate;
|
||||
private LocalDate planStartDate;
|
||||
|
||||
/**
|
||||
* 预计结束时间
|
||||
*/
|
||||
private Date planEndDate;
|
||||
private LocalDate planEndDate;
|
||||
|
||||
/**
|
||||
* 实际开始时间
|
||||
*/
|
||||
private Date practicalStartDate;
|
||||
private LocalDate practicalStartDate;
|
||||
|
||||
/**
|
||||
* 实际结束时间
|
||||
*/
|
||||
private Date practicalEndDate;
|
||||
private LocalDate practicalEndDate;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
|
@ -1,13 +1,12 @@
|
||||
package org.dromara.progress.domain.dto.constructionscheduleplan;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
@ -49,26 +48,22 @@ public class PgsConstructionSchedulePlanCreateReq implements Serializable {
|
||||
/**
|
||||
* 预计开始时间
|
||||
*/
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
|
||||
private Date planStartDate;
|
||||
private LocalDate planStartDate;
|
||||
|
||||
/**
|
||||
* 预计结束时间
|
||||
*/
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
|
||||
private Date planEndDate;
|
||||
private LocalDate planEndDate;
|
||||
|
||||
/**
|
||||
* 实际开始时间
|
||||
*/
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
|
||||
private Date practicalStartDate;
|
||||
private LocalDate practicalStartDate;
|
||||
|
||||
/**
|
||||
* 实际结束时间
|
||||
*/
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
|
||||
private Date practicalEndDate;
|
||||
private LocalDate practicalEndDate;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
|
@ -0,0 +1,71 @@
|
||||
package org.dromara.progress.domain.dto.constructionscheduleplan;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
* @date 2025-09-06 17:12
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class PgsConstructionSchedulePlanExcelDto {
|
||||
|
||||
/**
|
||||
* 项目ID
|
||||
*/
|
||||
private Long projectId;
|
||||
|
||||
/**
|
||||
* 父ID
|
||||
*/
|
||||
private Long parentId;
|
||||
|
||||
/**
|
||||
* 节点名称
|
||||
*/
|
||||
private String nodeName;
|
||||
|
||||
/**
|
||||
* 对应项目结构
|
||||
*/
|
||||
private Long projectStructure;
|
||||
|
||||
/**
|
||||
* 对应项目结构名称
|
||||
*/
|
||||
private String projectStructureName;
|
||||
|
||||
/**
|
||||
* 预计开始时间
|
||||
*/
|
||||
private LocalDate planStartDate;
|
||||
|
||||
/**
|
||||
* 预计结束时间
|
||||
*/
|
||||
private LocalDate planEndDate;
|
||||
|
||||
/**
|
||||
* 实际开始时间
|
||||
*/
|
||||
private LocalDate practicalStartDate;
|
||||
|
||||
/**
|
||||
* 实际结束时间
|
||||
*/
|
||||
private LocalDate practicalEndDate;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
}
|
@ -1,11 +1,10 @@
|
||||
package org.dromara.progress.domain.dto.constructionscheduleplan;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
@ -40,19 +39,16 @@ public class PgsConstructionSchedulePlanUpdateReq implements Serializable {
|
||||
/**
|
||||
* 实际开始时间
|
||||
*/
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
|
||||
private Date practicalStartDate;
|
||||
private LocalDate practicalStartDate;
|
||||
|
||||
/**
|
||||
* 实际结束时间
|
||||
*/
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
|
||||
private Date practicalEndDate;
|
||||
private LocalDate practicalEndDate;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
|
||||
private String status;
|
||||
|
||||
/**
|
||||
|
@ -2,7 +2,6 @@ package org.dromara.progress.domain.vo.constructionscheduleplan;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import lombok.Data;
|
||||
import org.dromara.common.excel.annotation.ExcelDictFormat;
|
||||
@ -11,7 +10,7 @@ import org.dromara.progress.domain.PgsConstructionSchedulePlan;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.time.LocalDate;
|
||||
|
||||
|
||||
/**
|
||||
@ -68,29 +67,25 @@ public class PgsConstructionSchedulePlanVo implements Serializable {
|
||||
* 预计开始时间
|
||||
*/
|
||||
@ExcelProperty(value = "预计开始时间")
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
||||
private Date planStartDate;
|
||||
private LocalDate planStartDate;
|
||||
|
||||
/**
|
||||
* 预计结束时间
|
||||
*/
|
||||
@ExcelProperty(value = "预计结束时间")
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
||||
private Date planEndDate;
|
||||
private LocalDate planEndDate;
|
||||
|
||||
/**
|
||||
* 实际开始时间
|
||||
*/
|
||||
@ExcelProperty(value = "实际开始时间")
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
||||
private Date practicalStartDate;
|
||||
private LocalDate practicalStartDate;
|
||||
|
||||
/**
|
||||
* 实际结束时间
|
||||
*/
|
||||
@ExcelProperty(value = "实际结束时间")
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
||||
private Date practicalEndDate;
|
||||
private LocalDate practicalEndDate;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
|
@ -2,11 +2,14 @@ package org.dromara.progress.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.dromara.progress.domain.PgsConstructionSchedulePlan;
|
||||
import org.dromara.progress.domain.dto.constructionscheduleplan.PgsConstructionSchedulePlanCreateReq;
|
||||
import org.dromara.progress.domain.dto.constructionscheduleplan.PgsConstructionSchedulePlanExcelDto;
|
||||
import org.dromara.progress.domain.dto.constructionscheduleplan.PgsConstructionSchedulePlanQueryReq;
|
||||
import org.dromara.progress.domain.dto.constructionscheduleplan.PgsConstructionSchedulePlanUpdateReq;
|
||||
import org.dromara.progress.domain.vo.constructionscheduleplan.PgsConstructionSchedulePlanVo;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@ -82,4 +85,20 @@ public interface IPgsConstructionSchedulePlanService extends IService<PgsConstru
|
||||
* @return 施工进度计划分页对象视图
|
||||
*/
|
||||
List<PgsConstructionSchedulePlanVo> getVoList(List<PgsConstructionSchedulePlan> constructionSchedulePlanList);
|
||||
|
||||
/**
|
||||
* 导出Excel
|
||||
*
|
||||
* @param projectId 项目id
|
||||
*/
|
||||
void exportExcelByProjectId(Long projectId, HttpServletResponse response);
|
||||
|
||||
/**
|
||||
* 读取Excel文件
|
||||
*
|
||||
* @param file Excel文件
|
||||
* @param projectId 项目ID
|
||||
* @return 读取的数据列表
|
||||
*/
|
||||
List<PgsConstructionSchedulePlanExcelDto> readExcel(MultipartFile file, Long projectId);
|
||||
}
|
||||
|
@ -2,23 +2,41 @@ package org.dromara.progress.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.apache.poi.ss.util.CellRangeAddressList;
|
||||
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.dromara.common.core.constant.HttpStatus;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.common.core.utils.ObjectUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.design.domain.bo.DesUserBo;
|
||||
import org.dromara.progress.domain.PgsConstructionSchedulePlan;
|
||||
import org.dromara.progress.domain.dto.constructionscheduleplan.PgsConstructionSchedulePlanCreateReq;
|
||||
import org.dromara.progress.domain.dto.constructionscheduleplan.PgsConstructionSchedulePlanExcelDto;
|
||||
import org.dromara.progress.domain.dto.constructionscheduleplan.PgsConstructionSchedulePlanQueryReq;
|
||||
import org.dromara.progress.domain.dto.constructionscheduleplan.PgsConstructionSchedulePlanUpdateReq;
|
||||
import org.dromara.progress.domain.vo.constructionscheduleplan.PgsConstructionSchedulePlanVo;
|
||||
import org.dromara.progress.mapper.PgsConstructionSchedulePlanMapper;
|
||||
import org.dromara.progress.service.IPgsConstructionSchedulePlanService;
|
||||
import org.dromara.project.service.IBusProjectService;
|
||||
import org.dromara.system.domain.vo.SysDictDataVo;
|
||||
import org.dromara.system.service.ISysDictDataService;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.LocalDate;
|
||||
import java.time.ZoneId;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 施工进度计划Service业务层处理
|
||||
@ -26,8 +44,16 @@ import java.util.List;
|
||||
* @author lilemy
|
||||
* @date 2025-08-01
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class PgsConstructionSchedulePlanServiceImpl extends ServiceImpl<PgsConstructionSchedulePlanMapper, PgsConstructionSchedulePlan> implements IPgsConstructionSchedulePlanService {
|
||||
public class PgsConstructionSchedulePlanServiceImpl extends ServiceImpl<PgsConstructionSchedulePlanMapper, PgsConstructionSchedulePlan>
|
||||
implements IPgsConstructionSchedulePlanService {
|
||||
|
||||
@Resource
|
||||
private IBusProjectService projectService;
|
||||
|
||||
@Resource
|
||||
private ISysDictDataService dictDataService;
|
||||
|
||||
/**
|
||||
* 查询施工进度计划
|
||||
@ -146,4 +172,350 @@ public class PgsConstructionSchedulePlanServiceImpl extends ServiceImpl<PgsConst
|
||||
public List<PgsConstructionSchedulePlanVo> getVoList(List<PgsConstructionSchedulePlan> constructionSchedulePlanList) {
|
||||
return constructionSchedulePlanList.stream().map(this::getVo).toList();
|
||||
}
|
||||
|
||||
// region
|
||||
|
||||
/**
|
||||
* 导出Excel
|
||||
*
|
||||
* @param projectId 项目id
|
||||
*/
|
||||
@Override
|
||||
public void exportExcelByProjectId(Long projectId, HttpServletResponse response) {
|
||||
DesUserBo desUserBo = new DesUserBo();
|
||||
desUserBo.setProjectId(projectId);
|
||||
Map<Long, String> projectStructureMap = projectService.getStructureAsList(projectId);
|
||||
List<SysDictDataVo> dictDataVos = dictDataService.selectByDictType("project_construction_status");
|
||||
Map<String, String> statusMap = new HashMap<>();
|
||||
for (SysDictDataVo vo : dictDataVos) {
|
||||
statusMap.put(vo.getDictValue(), vo.getDictLabel());
|
||||
}
|
||||
|
||||
|
||||
// 2. 设置响应头
|
||||
// 设置响应头,指定Excel格式和下载文件名
|
||||
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||
response.setCharacterEncoding("utf-8");
|
||||
response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("施工里程碑计划模版.xlsx", StandardCharsets.UTF_8));
|
||||
|
||||
Workbook workbook = new XSSFWorkbook();
|
||||
// 创建主 Sheet 和隐藏 Sheet
|
||||
Sheet mainSheet = workbook.createSheet("施工里程碑计划模版");
|
||||
Sheet dataSheet = workbook.createSheet("DropdownData");
|
||||
workbook.setSheetHidden(workbook.getSheetIndex(dataSheet), true);
|
||||
|
||||
// 3. 创建单元格样式
|
||||
CellStyle editableStyle = createEditableCellStyle(workbook); // 可编辑单元格样式
|
||||
CellStyle protectedStyle = createProtectedCellStyle(workbook); // 受保护单元格样式(ID列用
|
||||
//填充隐藏数据Sheet
|
||||
int rowIndex = 0;
|
||||
// 填充项目关联结构(A列和B列)
|
||||
for (Map.Entry<Long, String> entry : projectStructureMap.entrySet()) {
|
||||
Row row = dataSheet.createRow(rowIndex++);
|
||||
row.createCell(0).setCellValue(entry.getValue());
|
||||
row.createCell(1).setCellValue(entry.getKey().toString());
|
||||
}
|
||||
// 重置行索引,填充人员和人员ID(C列和D列)
|
||||
rowIndex = 0;
|
||||
for (Map.Entry<String, String> entry : statusMap.entrySet()) {
|
||||
Row row = dataSheet.getRow(rowIndex);
|
||||
if (row == null) {
|
||||
row = dataSheet.createRow(rowIndex);
|
||||
}
|
||||
row.createCell(4).setCellValue(entry.getValue());
|
||||
row.createCell(5).setCellValue(entry.getKey());
|
||||
rowIndex++;
|
||||
}
|
||||
// 主 Sheet 设置表头
|
||||
Row sheetRow = mainSheet.createRow(0);
|
||||
String[] headers = {"节点名称", "对应项目结构", "对应项目结构编码", "预计开始时间(格式:2025-09-06)",
|
||||
"预计结束时间", "实际开始时间", "实际结束时间", "状态", "状态编码", "备注"};
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
Cell cell = sheetRow.createCell(i);
|
||||
cell.setCellValue(headers[i]);
|
||||
}
|
||||
// 6. 设置专业下拉列表(第二列)
|
||||
setMajorDropdown(mainSheet, projectStructureMap.size());
|
||||
setStatusDropdown(mainSheet, statusMap.size());
|
||||
String formulaTemplate = "IFERROR(INDEX(DropdownData!$B$1:$B$" + projectStructureMap.size() + ", MATCH(B{rowNum}, DropdownData!$A$1:$A$" + projectStructureMap.size() + ", 0)),\"\")";
|
||||
String formulaTemplate1 = "IFERROR(INDEX(DropdownData!$F$1:$F$" + statusMap.size() + ", MATCH(H{rowNum}, DropdownData!$E$1:$E$" + statusMap.size() + ", 0)),\"\")";
|
||||
for (int i = 1; i <= 1000; i++) { // 从第2行到101行
|
||||
Row row = mainSheet.createRow(i);
|
||||
int currentRowNum = i + 1; // Excel行号从1开始
|
||||
String formula = formulaTemplate.replace("{rowNum}", String.valueOf(currentRowNum));
|
||||
|
||||
Cell cell = row.createCell(1);
|
||||
cell.setCellStyle(editableStyle); //专业不锁定
|
||||
|
||||
Cell idCell = row.createCell(2);
|
||||
idCell.setCellFormula(formula);
|
||||
idCell.setCellStyle(protectedStyle); // 应用隐藏公式样式
|
||||
|
||||
String formula1 = formulaTemplate1.replace("{rowNum}", String.valueOf(currentRowNum));
|
||||
|
||||
Cell cell1 = row.createCell(7);
|
||||
cell1.setCellStyle(editableStyle); //专业不锁定
|
||||
|
||||
Cell idCell1 = row.createCell(8);
|
||||
idCell1.setCellFormula(formula1);
|
||||
idCell1.setCellStyle(protectedStyle); // 应用隐藏公式样式
|
||||
|
||||
}
|
||||
|
||||
|
||||
for (int i = 1; i <= 100; i++) {
|
||||
Row row = mainSheet.getRow(i);
|
||||
if (row == null) {
|
||||
row = mainSheet.createRow(i);
|
||||
}
|
||||
Cell cell = row.createCell(0);
|
||||
cell.setCellStyle(editableStyle);
|
||||
|
||||
Cell cell3 = row.createCell(3);
|
||||
cell3.setCellStyle(editableStyle);
|
||||
|
||||
Cell cell4 = row.createCell(4);
|
||||
cell4.setCellStyle(editableStyle);
|
||||
|
||||
Cell cell5 = row.createCell(5);
|
||||
cell5.setCellStyle(editableStyle);
|
||||
|
||||
Cell cell6 = row.createCell(6);
|
||||
cell6.setCellStyle(editableStyle);
|
||||
|
||||
Cell cell9 = row.createCell(9);
|
||||
cell9.setCellStyle(editableStyle);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// 保护工作表,仅允许编辑未锁定的单元格
|
||||
mainSheet.protectSheet("123456"); // 空密码
|
||||
|
||||
// 核心:锁定表头(第1行)和前1列(包含ID列)
|
||||
mainSheet.createFreezePane(0, 1, 0, 1);
|
||||
|
||||
|
||||
// 调整列宽
|
||||
mainSheet.setColumnWidth(0, 20 * 256);
|
||||
mainSheet.setColumnWidth(1, 20 * 280);
|
||||
mainSheet.setColumnWidth(2, 20 * 280);
|
||||
mainSheet.setColumnWidth(3, 20 * 400);
|
||||
mainSheet.setColumnWidth(4, 20 * 200);
|
||||
mainSheet.setColumnWidth(5, 20 * 200);
|
||||
mainSheet.setColumnWidth(6, 20 * 200);
|
||||
mainSheet.setColumnWidth(7, 20 * 200);
|
||||
mainSheet.setColumnWidth(8, 20 * 100);
|
||||
mainSheet.setColumnWidth(9, 20 * 200);
|
||||
|
||||
// 直接写入响应输出流
|
||||
try {
|
||||
workbook.write(response.getOutputStream());
|
||||
workbook.close();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 创建可编辑单元格样式
|
||||
*/
|
||||
private CellStyle createEditableCellStyle(Workbook workbook) {
|
||||
CellStyle style = workbook.createCellStyle();
|
||||
style.setLocked(false); // 关键:允许编辑
|
||||
return style;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建受保护单元格样式(用于ID列)
|
||||
*/
|
||||
private CellStyle createProtectedCellStyle(Workbook workbook) {
|
||||
CellStyle style = workbook.createCellStyle();
|
||||
DataFormat dataFormat = workbook.createDataFormat();
|
||||
short formatIndex = dataFormat.getFormat("0"); // 匹配“自定义→0”格式
|
||||
style.setDataFormat(formatIndex);
|
||||
style.setHidden(true); // 隐藏公式
|
||||
style.setLocked(true);
|
||||
return style;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置专业下拉列表(第二列,索引1)
|
||||
*/
|
||||
private void setMajorDropdown(Sheet mainSheet, int majorCount) {
|
||||
DataValidationHelper helper = mainSheet.getDataValidationHelper();
|
||||
|
||||
// 专业数据范围:数据Sheet的A列(从第1行到专业数量行)
|
||||
String majorRange = "DropdownData!$A$1:$A$" + majorCount;
|
||||
|
||||
DataValidationConstraint constraint = helper.createFormulaListConstraint(majorRange);
|
||||
// 作用范围:第2行到100行,第二列
|
||||
CellRangeAddressList addressList = new CellRangeAddressList(1, 1000, 1, 1);
|
||||
|
||||
DataValidation validation = helper.createValidation(constraint, addressList);
|
||||
validation.setShowErrorBox(true);
|
||||
mainSheet.addValidationData(validation);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置专业下拉列表(第二列,索引1)
|
||||
*/
|
||||
private void setStatusDropdown(Sheet mainSheet, int majorCount) {
|
||||
DataValidationHelper helper = mainSheet.getDataValidationHelper();
|
||||
|
||||
// 专业数据范围:数据Sheet的A列(从第1行到专业数量行)
|
||||
String majorRange = "DropdownData!$E$1:$E$" + majorCount;
|
||||
|
||||
DataValidationConstraint constraint = helper.createFormulaListConstraint(majorRange);
|
||||
// 作用范围:第2行到100行,第二列
|
||||
CellRangeAddressList addressList = new CellRangeAddressList(1, 1000, 7, 7);
|
||||
|
||||
DataValidation validation = helper.createValidation(constraint, addressList);
|
||||
validation.setShowErrorBox(true);
|
||||
mainSheet.addValidationData(validation);
|
||||
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
|
||||
/**
|
||||
* 读取Excel文件
|
||||
*
|
||||
* @param file Excel文件
|
||||
* @param projectId 项目ID
|
||||
* @return 读取的数据列表
|
||||
*/
|
||||
@Override
|
||||
public List<PgsConstructionSchedulePlanExcelDto> readExcel(MultipartFile file, Long projectId) {
|
||||
List<PgsConstructionSchedulePlanExcelDto> dataList = new ArrayList<>();
|
||||
|
||||
try (InputStream inputStream = file.getInputStream();
|
||||
XSSFWorkbook workbook = new XSSFWorkbook(inputStream)) {
|
||||
|
||||
XSSFSheet sheet = workbook.getSheetAt(0);
|
||||
|
||||
// 从第二行(index=1)开始读取数据,跳过表头
|
||||
for (int rowIndex = 1; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
|
||||
Row row = sheet.getRow(rowIndex);
|
||||
if (hasValidData(row)) {
|
||||
|
||||
String nodeName = getCellValue(row.getCell(0));
|
||||
String projectStructureName = getCellValue(row.getCell(1));
|
||||
Long projectStructure = Long.valueOf(getCellValue(row.getCell(2)));
|
||||
LocalDate planStartDate = getLocalDateValue(row.getCell(3));
|
||||
LocalDate planEndDate = getLocalDateValue(row.getCell(4));
|
||||
LocalDate practicalStartDate = getLocalDateValue(row.getCell(5));
|
||||
LocalDate practicalEndDate = getLocalDateValue(row.getCell(6));
|
||||
String status = getCellValue(row.getCell(8));
|
||||
String remark = getCellValue(row.getCell(9));
|
||||
|
||||
PgsConstructionSchedulePlanExcelDto excelData = new PgsConstructionSchedulePlanExcelDto(
|
||||
projectId, 0L, nodeName, projectStructure, projectStructureName,
|
||||
planStartDate, planEndDate, practicalStartDate, practicalEndDate, status, remark
|
||||
);
|
||||
dataList.add(excelData);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("读取表格数据失败", e);
|
||||
throw new ServiceException("读取表格数据失败");
|
||||
}
|
||||
|
||||
return dataList;
|
||||
}
|
||||
|
||||
private static boolean hasValidData(Row row) {
|
||||
// 遍历行中的所有单元格
|
||||
for (int cellIndex = 0; cellIndex < row.getLastCellNum(); cellIndex++) {
|
||||
Cell cell = row.getCell(cellIndex, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
|
||||
String cellValue = getCellValue(cell).trim();
|
||||
|
||||
// 只要有一个单元格有非空值,就认为是有效行
|
||||
if (!cellValue.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static String getCellValue(Cell cell) {
|
||||
if (cell == null) {
|
||||
return "";
|
||||
}
|
||||
// 使用CellType枚举判断单元格类型(POI 4.0+版本推荐方式)
|
||||
CellType cellType = cell.getCellType();
|
||||
// 对于公式单元格,获取其计算结果的类型
|
||||
if (cellType == CellType.FORMULA) {
|
||||
cellType = cell.getCachedFormulaResultType();
|
||||
}
|
||||
|
||||
switch (cellType) {
|
||||
case STRING:
|
||||
return cell.getStringCellValue().trim();
|
||||
case NUMERIC:
|
||||
if (DateUtil.isCellDateFormatted(cell)) {
|
||||
Date date = cell.getDateCellValue();
|
||||
return date.toString();
|
||||
} else {
|
||||
// 处理数字类型,避免科学计数法
|
||||
return String.valueOf((long) cell.getNumericCellValue());
|
||||
}
|
||||
case BOOLEAN:
|
||||
return String.valueOf(cell.getBooleanCellValue());
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private static LocalDate getLocalDateValue(Cell cell) {
|
||||
if (cell == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
CellType cellType = cell.getCellType();
|
||||
if (cellType == CellType.FORMULA) {
|
||||
cellType = cell.getCachedFormulaResultType();
|
||||
}
|
||||
|
||||
try {
|
||||
if (cellType == CellType.NUMERIC) {
|
||||
if (DateUtil.isCellDateFormatted(cell)) {
|
||||
Date date = cell.getDateCellValue();
|
||||
return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
||||
} else {
|
||||
// 如果是数字但不是日期,就尝试转为 LocalDate (例如 20250730)
|
||||
double numericValue = cell.getNumericCellValue();
|
||||
String text = String.valueOf((long) numericValue);
|
||||
return LocalDate.parse(text);
|
||||
}
|
||||
} else if (cellType == CellType.STRING) {
|
||||
String text = cell.getStringCellValue().trim();
|
||||
if (text.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
// 尝试解析不同格式
|
||||
try {
|
||||
return LocalDate.parse(text); // 默认 ISO 格式 yyyy-MM-dd
|
||||
} catch (Exception e) {
|
||||
// 如果 Excel 是 yyyy/MM/dd 或 yyyy.MM.dd,可以额外处理
|
||||
try {
|
||||
return LocalDate.parse(text, java.time.format.DateTimeFormatter.ofPattern("yyyy/MM/dd"));
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
try {
|
||||
return LocalDate.parse(text, java.time.format.DateTimeFormatter.ofPattern("yyyy.MM.dd"));
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
return null; // 不识别的格式就返回 null
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -809,9 +809,15 @@ public class PgsProgressPlanDetailServiceImpl extends ServiceImpl<PgsProgressPla
|
||||
value.setProjectId(planDetail.getProjectId());
|
||||
value.setMatrixId(category.getMatrixId());
|
||||
value.setProgressCategoryId(progressCategoryId);
|
||||
int artificialNum = planDetail.getFinishedNumber().intValue();
|
||||
BigDecimal finishedNumber = planDetail.getFinishedNumber();
|
||||
BigDecimal aiFill = planDetail.getAiFill();
|
||||
// 如果完成数量为0, 则不保存
|
||||
if (finishedNumber.compareTo(BigDecimal.ZERO) == 0 && aiFill.compareTo(BigDecimal.ZERO) == 0) {
|
||||
continue;
|
||||
}
|
||||
int artificialNum = finishedNumber.intValue();
|
||||
value.setArtificialNum(artificialNum);
|
||||
int uavNum = planDetail.getAiFill().intValue();
|
||||
int uavNum = aiFill.intValue();
|
||||
value.setUavNum(uavNum);
|
||||
value.setPlanNum(planDetail.getPlanNumber().intValue());
|
||||
value.setReportDate(LocalDate.now());
|
||||
|
@ -11,6 +11,7 @@ import org.dromara.project.domain.vo.project.*;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
@ -197,6 +198,14 @@ public interface IBusProjectService extends IService<BusProject> {
|
||||
*/
|
||||
BusProjectStructureVo getStructure(Long projectId);
|
||||
|
||||
/**
|
||||
* 获取项目结构
|
||||
*
|
||||
* @param projectId 项目id
|
||||
* @return 结构(key 主键id,value 名称)
|
||||
*/
|
||||
Map<Long, String> getStructureAsList(Long projectId);
|
||||
|
||||
/**
|
||||
* 改变项目所属用户
|
||||
*
|
||||
|
@ -1066,6 +1066,57 @@ public class BusProjectServiceImpl extends ServiceImpl<BusProjectMapper, BusProj
|
||||
return vo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取项目结构
|
||||
*
|
||||
* @param projectId 项目id
|
||||
* @return 结构(key 主键id,value 名称)
|
||||
*/
|
||||
@Override
|
||||
public Map<Long, String> getStructureAsList(Long projectId) {
|
||||
Map<Long, String> map = new HashMap<>();
|
||||
// 获取项目
|
||||
BusProject project = this.getById(projectId);
|
||||
if (project == null) {
|
||||
throw new ServiceException("项目信息不存在", HttpStatus.NOT_FOUND);
|
||||
}
|
||||
map.put(project.getId(), "项目:" + project.getProjectName());
|
||||
|
||||
// 获取项目子项
|
||||
List<BusProject> subProjects = this.lambdaQuery()
|
||||
.eq(BusProject::getPId, projectId)
|
||||
.list();
|
||||
if (CollUtil.isNotEmpty(subProjects)) {
|
||||
for (BusProject subProject : subProjects) {
|
||||
map.put(subProject.getId(), "子项目:" + subProject.getProjectName());
|
||||
}
|
||||
// 获取方阵信息
|
||||
List<FacMatrix> matrixList = matrixService.lambdaQuery()
|
||||
.in(FacMatrix::getProjectId, subProjects.stream().map(BusProject::getId).toList())
|
||||
.list();
|
||||
if (CollUtil.isNotEmpty(matrixList)) {
|
||||
for (FacMatrix matrix : matrixList) {
|
||||
map.put(matrix.getId(), "方阵:" + matrix.getMatrixName());
|
||||
}
|
||||
}
|
||||
// 获取分项工程
|
||||
List<PgsProgressCategory> progressCategoryList = progressCategoryService.lambdaQuery()
|
||||
.in(PgsProgressCategory::getMatrixId, matrixList.stream().map(FacMatrix::getId).toList())
|
||||
.list();
|
||||
if (CollUtil.isNotEmpty(progressCategoryList)) {
|
||||
for (PgsProgressCategory progressCategory : progressCategoryList) {
|
||||
String matrixName = progressCategory.getMatrixName();
|
||||
if (StringUtils.isNotBlank(matrixName)) {
|
||||
map.put(progressCategory.getId(), "分项工程:" + matrixName + "-" + progressCategory.getName());
|
||||
} else {
|
||||
map.put(progressCategory.getId(), "分项工程:" + progressCategory.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* 改变项目所属用户
|
||||
*
|
||||
|
Reference in New Issue
Block a user