|
|
@@ -0,0 +1,310 @@
|
|
|
+package com.management.platform.controller;
|
|
|
+
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSONArray;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
+import com.management.platform.entity.ConstructionMain;
|
|
|
+import com.management.platform.entity.ConstructionStage;
|
|
|
+import com.management.platform.entity.ProjectConstructionStage;
|
|
|
+import com.management.platform.entity.ReportProjectConstruction;
|
|
|
+import com.management.platform.mapper.ProjectMapper;
|
|
|
+import com.management.platform.mapper.ReportProjectConstructionMapper;
|
|
|
+import com.management.platform.service.ConstructionMainService;
|
|
|
+import com.management.platform.service.ConstructionStageService;
|
|
|
+import com.management.platform.service.ProjectConstructionStageService;
|
|
|
+import com.management.platform.service.ReportProjectConstructionService;
|
|
|
+import com.management.platform.util.ExcelUtil;
|
|
|
+import com.management.platform.util.HttpRespMsg;
|
|
|
+import org.apache.poi.ss.usermodel.*;
|
|
|
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
+import org.springframework.web.bind.annotation.RequestMapping;
|
|
|
+
|
|
|
+import org.springframework.web.bind.annotation.RestController;
|
|
|
+import org.springframework.web.multipart.MultipartFile;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import java.io.InputStream;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Arrays;
|
|
|
+import java.util.List;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * <p>
|
|
|
+ * 前端控制器
|
|
|
+ * </p>
|
|
|
+ *
|
|
|
+ * @author Seyason
|
|
|
+ * @since 2026-04-19
|
|
|
+ */
|
|
|
+@RestController
|
|
|
+@RequestMapping("/project-construction-stage")
|
|
|
+public class ProjectConstructionStageController {
|
|
|
+ @Value("${upload.path}")
|
|
|
+ private String uploadPath;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private ProjectConstructionStageService projectConstructionStageService;
|
|
|
+ @Resource
|
|
|
+ private ConstructionStageService constructionStageService;
|
|
|
+ @Resource
|
|
|
+ private ConstructionMainService constructionMainService;
|
|
|
+ @Autowired
|
|
|
+ private ReportProjectConstructionMapper reportProjectConstructionMapper;
|
|
|
+ @Resource
|
|
|
+ private ProjectMapper projectMapper;
|
|
|
+
|
|
|
+ @RequestMapping("/save")
|
|
|
+ public HttpRespMsg save(String json, Integer projectId) {
|
|
|
+ HttpRespMsg msg = new HttpRespMsg();
|
|
|
+ List<ConstructionStage> constructionStages = JSONArray.parseArray(json, ConstructionStage.class);
|
|
|
+ List<ProjectConstructionStage> projectConstructionStageList = projectConstructionStageService.list(new QueryWrapper<ProjectConstructionStage>().eq("project_id", projectId));
|
|
|
+ List<Integer> removeIds = projectConstructionStageList.stream().map(ProjectConstructionStage::getId).collect(Collectors.toList());
|
|
|
+ List<ProjectConstructionStage> data = new ArrayList<>();
|
|
|
+ for (ConstructionStage constructionStage : constructionStages) {
|
|
|
+ ProjectConstructionStage stage = new ProjectConstructionStage();
|
|
|
+ stage.setProjectId(projectId);
|
|
|
+ stage.setStageId(constructionStage.getId());
|
|
|
+ stage.setPercent(constructionStage.getPercent());
|
|
|
+ stage.setDesignNumber(constructionStage.getDesignNumber());
|
|
|
+ ProjectConstructionStage oldItem = projectConstructionStageList.stream().filter(pro->pro.getStageId().equals(constructionStage.getId())).findFirst().orElse(null);
|
|
|
+ if (oldItem != null) {
|
|
|
+ removeIds.remove(oldItem.getId());
|
|
|
+ stage.setId(oldItem.getId());
|
|
|
+ }
|
|
|
+ data.add(stage);
|
|
|
+ }
|
|
|
+ if (removeIds.size() > 0) {
|
|
|
+ projectConstructionStageService.removeByIds(removeIds);
|
|
|
+ }
|
|
|
+ projectConstructionStageService.saveOrUpdateBatch(data);
|
|
|
+ return msg;
|
|
|
+ }
|
|
|
+
|
|
|
+ @RequestMapping("get")
|
|
|
+ public HttpRespMsg get(Integer projectId, String constructionType) {
|
|
|
+ HttpRespMsg msg = new HttpRespMsg();
|
|
|
+ if (constructionType == null) {
|
|
|
+ return msg;
|
|
|
+ }
|
|
|
+ //没有数据,返回基础的项目施工的节点数据
|
|
|
+ String[] types = constructionType.split(",");
|
|
|
+ List<ConstructionStage> stages = constructionStageService.list(new QueryWrapper<ConstructionStage>().in("construction_type", Arrays.asList(types)).orderByAsc("construction_type").orderByAsc("main_id"));
|
|
|
+ List<ConstructionMain> mainList = constructionMainService.list(new QueryWrapper<ConstructionMain>().in("construction_type", Arrays.asList(types)));
|
|
|
+ for (ConstructionStage stage : stages) {
|
|
|
+ stage.setDesignNumber(0.0);
|
|
|
+ ConstructionMain main = mainList.stream().filter(mainItem->mainItem.getId().equals(stage.getMainId())).findFirst().orElse(null);
|
|
|
+ if (main != null) {
|
|
|
+ stage.setMainName(main.getName());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ List<ProjectConstructionStage> projectConstructionStages = (projectId == null || projectId == -1) ? new ArrayList<>() : projectConstructionStageService.list(new QueryWrapper<ProjectConstructionStage>().eq("project_id", projectId));
|
|
|
+ if (!projectConstructionStages.isEmpty()) {
|
|
|
+ stages.forEach(stage -> {
|
|
|
+ projectConstructionStages.stream().filter(p -> p.getStageId().equals(stage.getId())).findFirst().ifPresent(p -> {
|
|
|
+ stage.setDesignNumber(p.getDesignNumber());
|
|
|
+ stage.setPercent(p.getPercent());
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ msg.data = stages;
|
|
|
+ return msg;
|
|
|
+ }
|
|
|
+
|
|
|
+ @RequestMapping("getByProjectId")
|
|
|
+ public HttpRespMsg getByProjectId(Integer projectId, Integer reportId) {
|
|
|
+ HttpRespMsg msg = new HttpRespMsg();
|
|
|
+ List<ProjectConstructionStage> projectConstructionStages = projectConstructionStageService.list(new QueryWrapper<ProjectConstructionStage>().eq("project_id", projectId));
|
|
|
+ List<Integer> stageIds = projectConstructionStages.stream().map(ProjectConstructionStage::getStageId).collect(Collectors.toList());
|
|
|
+
|
|
|
+ //没有数据,返回基础的项目施工的节点数据
|
|
|
+ List<ConstructionStage> stages = constructionStageService.list(new QueryWrapper<ConstructionStage>().in("id", stageIds).orderByAsc("construction_type").orderByAsc("main_id").orderByAsc("id"));
|
|
|
+ if (reportId != null) {
|
|
|
+ List<ReportProjectConstruction> rpcList = reportProjectConstructionMapper.selectList(new QueryWrapper<ReportProjectConstruction>().eq("report_id", reportId));
|
|
|
+ for (ConstructionStage stage : stages) {
|
|
|
+ rpcList.stream().filter(rpc->rpc.getConstructionStageId().equals(stage.getId())).findFirst().ifPresent(rpc->stage.setFinishNumber(rpc.getFinishNumber()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ msg.data = stages;
|
|
|
+ return msg;
|
|
|
+ }
|
|
|
+
|
|
|
+ @RequestMapping("export")
|
|
|
+ public HttpRespMsg export(Integer projectId, String constructionType) {
|
|
|
+ String pName = null;
|
|
|
+ if (projectId != null) {
|
|
|
+ pName = projectMapper.selectById(projectId).getProjectName();
|
|
|
+ }
|
|
|
+ HttpRespMsg msg = get(projectId, constructionType);
|
|
|
+ List<ConstructionStage> stages = (List<ConstructionStage>) msg.data;
|
|
|
+ List<List<String>> data = new ArrayList<>();
|
|
|
+ List<String> header = new ArrayList<>();
|
|
|
+ //id, 一级工程分类,施工分项,施工节点,占比,设计量
|
|
|
+ header.add("id");
|
|
|
+ header.add("一级工程分类");
|
|
|
+ header.add("施工分项");
|
|
|
+ header.add("施工节点");
|
|
|
+ header.add("占比(%)");
|
|
|
+ header.add("设计量");
|
|
|
+ header.add("单位");
|
|
|
+ data.add(header);
|
|
|
+ for (ConstructionStage stage : stages) {
|
|
|
+ List<String> list = new ArrayList<String>();
|
|
|
+ list.add(""+stage.getId());
|
|
|
+ list.add(stage.getConstructionType());
|
|
|
+ list.add(stage.getMainName());
|
|
|
+ list.add(stage.getName());
|
|
|
+ list.add(""+stage.getPercent());
|
|
|
+ list.add(""+stage.getDesignNumber());
|
|
|
+ list.add(stage.getUnit());
|
|
|
+ data.add(list);
|
|
|
+ }
|
|
|
+ HttpRespMsg retMsg = new HttpRespMsg();
|
|
|
+ String fileName = (pName == null?"":(pName+"-"))+"项目施工节点设置"+"_"+System.currentTimeMillis();
|
|
|
+
|
|
|
+ retMsg.data = ExcelUtil.exportGeneralExcelByTitleAndList(fileName, data, uploadPath);
|
|
|
+ return retMsg;
|
|
|
+ }
|
|
|
+
|
|
|
+ @RequestMapping("import")
|
|
|
+ public HttpRespMsg importData(Integer projectId, MultipartFile file) {
|
|
|
+ HttpRespMsg msg = new HttpRespMsg();
|
|
|
+ try {
|
|
|
+ if (file == null || file.isEmpty()) {
|
|
|
+ msg.setError("文件不能为空");
|
|
|
+ return msg;
|
|
|
+ }
|
|
|
+ if (projectId == null) {
|
|
|
+ msg.setError("项目ID不能为空");
|
|
|
+ return msg;
|
|
|
+ }
|
|
|
+ // 读取Excel文件
|
|
|
+ InputStream inputStream = file.getInputStream();
|
|
|
+ Workbook workbook = new XSSFWorkbook(inputStream);
|
|
|
+ Sheet sheet = workbook.getSheetAt(0);
|
|
|
+
|
|
|
+ // 解析Excel数据
|
|
|
+ List<ConstructionStage> constructionStages = new ArrayList<>();
|
|
|
+
|
|
|
+ // 从第二行开始读取数据(第一行是表头)
|
|
|
+ for (int i = 1; i <= sheet.getLastRowNum(); i++) {
|
|
|
+ Row row = sheet.getRow(i);
|
|
|
+ if (row == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ // 读取各列数据
|
|
|
+ Cell idCell = row.getCell(0);
|
|
|
+ Cell percentCell = row.getCell(4);
|
|
|
+ Cell designNumberCell = row.getCell(5);
|
|
|
+ if (idCell == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ ConstructionStage stage = new ConstructionStage();
|
|
|
+
|
|
|
+ // 读取ID
|
|
|
+ if (idCell.getCellTypeEnum() == CellType.NUMERIC) {
|
|
|
+ stage.setId((int) idCell.getNumericCellValue());
|
|
|
+ } else if (idCell.getCellTypeEnum() == CellType.STRING) {
|
|
|
+ stage.setId(Integer.parseInt(idCell.getStringCellValue()));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 读取占比
|
|
|
+ if (percentCell != null) {
|
|
|
+ if (percentCell.getCellTypeEnum() == CellType.NUMERIC) {
|
|
|
+ stage.setPercent((double) percentCell.getNumericCellValue());
|
|
|
+ } else if (percentCell.getCellTypeEnum() == CellType.STRING) {
|
|
|
+ String value = percentCell.getStringCellValue();
|
|
|
+ if (value != null && !value.trim().isEmpty()) {
|
|
|
+ stage.setPercent(Double.parseDouble(value));
|
|
|
+ } else {
|
|
|
+ stage.setPercent(0.0);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ stage.setPercent(0.0);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ stage.setPercent(0.0);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 读取设计量
|
|
|
+ if (designNumberCell != null) {
|
|
|
+ if (designNumberCell.getCellTypeEnum() == CellType.NUMERIC) {
|
|
|
+ stage.setDesignNumber(designNumberCell.getNumericCellValue());
|
|
|
+ } else if (designNumberCell.getCellTypeEnum() == CellType.STRING) {
|
|
|
+ String value = designNumberCell.getStringCellValue();
|
|
|
+ if (value != null && !value.trim().isEmpty()) {
|
|
|
+ stage.setDesignNumber(Double.parseDouble(value));
|
|
|
+ } else {
|
|
|
+ stage.setDesignNumber(0.0);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ stage.setDesignNumber(0.0);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ stage.setDesignNumber(0.0);
|
|
|
+ }
|
|
|
+
|
|
|
+ constructionStages.add(stage);
|
|
|
+ } catch (Exception e) {
|
|
|
+ // 跳过解析失败的行
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ workbook.close();
|
|
|
+ inputStream.close();
|
|
|
+
|
|
|
+ if (constructionStages.isEmpty()) {
|
|
|
+ msg.setError("没有可导入的数据");
|
|
|
+ return msg;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 使用与save接口相同的逻辑处理数据
|
|
|
+ List<ProjectConstructionStage> projectConstructionStageList = projectConstructionStageService.list(
|
|
|
+ new QueryWrapper<ProjectConstructionStage>().eq("project_id", projectId)
|
|
|
+ );
|
|
|
+ List<Integer> removeIds = projectConstructionStageList.stream()
|
|
|
+ .map(ProjectConstructionStage::getId)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ List<ProjectConstructionStage> data = new ArrayList<>();
|
|
|
+
|
|
|
+ for (ConstructionStage constructionStage : constructionStages) {
|
|
|
+ ProjectConstructionStage stage = new ProjectConstructionStage();
|
|
|
+ stage.setProjectId(projectId);
|
|
|
+ stage.setStageId(constructionStage.getId());
|
|
|
+ stage.setPercent(constructionStage.getPercent());
|
|
|
+ stage.setDesignNumber(constructionStage.getDesignNumber());
|
|
|
+
|
|
|
+ ProjectConstructionStage oldItem = projectConstructionStageList.stream()
|
|
|
+ .filter(pro -> pro.getStageId().equals(constructionStage.getId()))
|
|
|
+ .findFirst()
|
|
|
+ .orElse(null);
|
|
|
+
|
|
|
+ if (oldItem != null) {
|
|
|
+ removeIds.remove(oldItem.getId());
|
|
|
+ stage.setId(oldItem.getId());
|
|
|
+ }
|
|
|
+ data.add(stage);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (removeIds.size() > 0) {
|
|
|
+ projectConstructionStageService.removeByIds(removeIds);
|
|
|
+ }
|
|
|
+ projectConstructionStageService.saveOrUpdateBatch(data);
|
|
|
+
|
|
|
+ msg.msg = "导入成功,共导入 " + constructionStages.size() + " 条数据";
|
|
|
+ } catch (Exception e) {
|
|
|
+ msg.setError("导入失败:" + e.getMessage());
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return msg;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|