|
@@ -3,41 +3,49 @@ package org.springblade.business.controller;
|
|
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
+import com.fasterxml.jackson.core.JsonProcessingException;
|
|
|
+import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
|
|
import io.swagger.annotations.Api;
|
|
|
import io.swagger.annotations.ApiOperation;
|
|
|
import io.swagger.annotations.ApiParam;
|
|
|
import lombok.AllArgsConstructor;
|
|
|
+import org.apache.commons.lang.StringUtils;
|
|
|
+import org.apache.poi.ss.usermodel.*;
|
|
|
+import org.apache.poi.ss.util.CellRangeAddress;
|
|
|
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
|
|
import org.jsoup.Jsoup;
|
|
|
import org.jsoup.nodes.Document;
|
|
|
+import org.jsoup.nodes.Element;
|
|
|
+import org.jsoup.select.Elements;
|
|
|
import org.springblade.business.dto.TrialSummaryRecordDTO;
|
|
|
import org.springblade.business.dto.TrialSummaryRecordPageDTO;
|
|
|
import org.springblade.business.entity.TrialSelfInspectionRecord;
|
|
|
import org.springblade.business.entity.TrialSummaryRecord;
|
|
|
import org.springblade.business.service.impl.TrialSelfInspectionRecordServiceImpl;
|
|
|
import org.springblade.business.service.impl.TrialSummaryRecordServiceImpl;
|
|
|
-import org.springblade.business.utils.PdfGenerator;
|
|
|
import org.springblade.business.vo.TrialSummaryRecordVO;
|
|
|
import org.springblade.common.constant.CommonConstant;
|
|
|
import org.springblade.common.utils.CommonUtil;
|
|
|
+import org.springblade.common.utils.SnowFlakeUtil;
|
|
|
import org.springblade.core.log.exception.ServiceException;
|
|
|
-import org.springblade.core.oss.model.BladeFile;
|
|
|
import org.springblade.core.tool.api.R;
|
|
|
import org.springblade.core.tool.utils.*;
|
|
|
import org.springblade.manager.entity.ContractInfo;
|
|
|
+import org.springblade.manager.entity.ExcelTab;
|
|
|
import org.springblade.manager.entity.TrialSummaryClassificationConfiguration;
|
|
|
import org.springblade.manager.entity.TrialSummaryExcelTabReflection;
|
|
|
import org.springblade.resource.feign.NewIOSSClient;
|
|
|
+import org.springblade.resource.vo.NewBladeFile;
|
|
|
import org.springblade.system.cache.ParamCache;
|
|
|
import org.springblade.system.entity.Dict;
|
|
|
import org.springframework.jdbc.core.BeanPropertyRowMapper;
|
|
|
import org.springframework.jdbc.core.JdbcTemplate;
|
|
|
+import org.springframework.mock.web.MockMultipartFile;
|
|
|
import org.springframework.web.bind.annotation.*;
|
|
|
import org.springframework.web.multipart.MultipartFile;
|
|
|
|
|
|
-import java.io.File;
|
|
|
-import java.io.FileInputStream;
|
|
|
-import java.io.InputStream;
|
|
|
+import java.io.*;
|
|
|
import java.time.LocalDate;
|
|
|
import java.time.format.DateTimeFormatter;
|
|
|
import java.util.*;
|
|
@@ -49,7 +57,7 @@ import java.util.stream.Collectors;
|
|
|
@RestController
|
|
|
@AllArgsConstructor
|
|
|
@RequestMapping("/trial/summary")
|
|
|
-@Api(value = "试验汇总", tags = "试验汇总接口")
|
|
|
+@Api(value = "试验汇总接口", tags = "试验汇总接口")
|
|
|
public class TrialSummaryController {
|
|
|
|
|
|
private final JdbcTemplate jdbcTemplate;
|
|
@@ -171,55 +179,89 @@ public class TrialSummaryController {
|
|
|
LocalDate startDate = LocalDate.parse(dto.getStartDate(), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
|
|
LocalDate endDate = LocalDate.parse(dto.getEndDate(), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
|
|
List<TrialSelfInspectionRecord> records = trialSelfInspectionRecordServiceImpl.getBaseMapper().selectList(Wrappers.<TrialSelfInspectionRecord>lambdaQuery()
|
|
|
+ .select(TrialSelfInspectionRecord::getId)
|
|
|
.in(TrialSelfInspectionRecord::getNodeId, Func.toLongList(classC.getTrialTreeIds()))
|
|
|
.eq(TrialSelfInspectionRecord::getContractId, dto.getContractId())
|
|
|
.eq(TrialSelfInspectionRecord::getDetectionCategory, dto.getDetectionType())
|
|
|
.between(TrialSelfInspectionRecord::getReportDate, startDate, endDate)
|
|
|
);
|
|
|
-
|
|
|
- //TODO 会存在多个相同表,取数据应该取多组相同数据records的id对应实体表的group_id;生成的新的pdf数据还要入库,就是每个框框都要入库,后续其他接口还要使用
|
|
|
-
|
|
|
+ if (records.size() <= 0) {
|
|
|
+ throw new ServiceException("未获取到该报告时间段范围内的试验自检记录信息,操作失败");
|
|
|
+ }
|
|
|
+ List<Long> recordIds = records.stream().map(TrialSelfInspectionRecord::getId).collect(Collectors.toList());
|
|
|
|
|
|
String sql_2 = "SELECT * FROM m_trial_summary_excel_tab_reflection WHERE excel_id = ?";
|
|
|
- List<TrialSummaryExcelTabReflection> excelTabReflections = jdbcTemplate.query(sql_2, new Object[]{classC.getExcelId()}, new BeanPropertyRowMapper<>(TrialSummaryExcelTabReflection.class));
|
|
|
+ List<TrialSummaryExcelTabReflection> excelTabReflections = jdbcTemplate.query(sql_2,
|
|
|
+ new Object[]{classC.getExcelId()}, new BeanPropertyRowMapper<>(TrialSummaryExcelTabReflection.class));
|
|
|
Map<String, List<TrialSummaryExcelTabReflection>> maps = excelTabReflections.stream()
|
|
|
.collect(Collectors.groupingBy(
|
|
|
- reflection -> reflection.getTrialTabName() + "##" + reflection.getTrialTabId()
|
|
|
+ reflection -> reflection.getTrialTabName() + "###" + reflection.getTrialTabId()
|
|
|
));
|
|
|
- Map<String, Object> map = new HashMap<>();
|
|
|
+ Map<String, Object> map = new LinkedHashMap<>();
|
|
|
for (Map.Entry<String, List<TrialSummaryExcelTabReflection>> entry : maps.entrySet()) {
|
|
|
- String tabName = entry.getKey().split("##")[0];
|
|
|
- String tabPkeyId = entry.getKey().split("##")[1];
|
|
|
+ String tabName = entry.getKey().split("###")[0];
|
|
|
+ String tabPkeyId = entry.getKey().split("###")[1];
|
|
|
|
|
|
List<TrialSummaryExcelTabReflection> value = entry.getValue();
|
|
|
Map<String, String> elementKeyWithHtmlKeyNameMap = value.stream().collect(Collectors.toMap(TrialSummaryExcelTabReflection::getElementKey, TrialSummaryExcelTabReflection::getHtmlKeyName));
|
|
|
Set<String> elementKeys = elementKeyWithHtmlKeyNameMap.keySet();
|
|
|
|
|
|
- String sql_3 = "SELECT " + String.join(",", elementKeys) + " FROM " + tabName + " WHERE p_key_id = " + tabPkeyId + " ";
|
|
|
- Map<String, Object> tabDataMap = jdbcTemplate.queryForMap(sql_3);
|
|
|
+ String sql_3 = "SELECT " + String.join(",", elementKeys) + " FROM " + tabName + " WHERE p_key_id = " + tabPkeyId + " AND group_id in(" + StringUtils.join(recordIds, ",") + ")";
|
|
|
+ List<Map<String, Object>> tabDataList = jdbcTemplate.queryForList(sql_3);
|
|
|
+ if (tabDataList.isEmpty()) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
|
|
|
for (String elementKey : elementKeys) {
|
|
|
String htmlKeyName = elementKeyWithHtmlKeyNameMap.getOrDefault(elementKey, null);
|
|
|
if (ObjectUtil.isEmpty(htmlKeyName)) {
|
|
|
continue;
|
|
|
}
|
|
|
- Object tabData = tabDataMap.getOrDefault(elementKey, null);
|
|
|
- map.put(htmlKeyName, tabData);
|
|
|
+ for (Map<String, Object> stringObjectMap : tabDataList) {
|
|
|
+ Object tabData = stringObjectMap.getOrDefault(elementKey, null);
|
|
|
+
|
|
|
+ String tabDataStr = (String) tabData;
|
|
|
+ //跨行
|
|
|
+ if (tabDataStr.contains("☆")) {
|
|
|
+ String[] split = tabDataStr.split("☆");
|
|
|
+ for (String valueRow : split) {
|
|
|
+ String[] splitValues = valueRow.split(Pattern.quote("_^_"));
|
|
|
+ String valueInput = splitValues[0];
|
|
|
+ String indexKey = splitValues[1];
|
|
|
+ String keyName = elementKey + "__" + indexKey;
|
|
|
+ map.put(keyName, valueInput);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ //非跨行
|
|
|
+ String[] splitValues = tabDataStr.split(Pattern.quote("_^_"));
|
|
|
+ String valueInput = splitValues[0];
|
|
|
+ String indexKey = splitValues[1];
|
|
|
+ String keyName = elementKey + "__" + indexKey;
|
|
|
+ map.put(keyName, valueInput);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ Map<String, String> needsSavedData = new LinkedHashMap<>();
|
|
|
String htmlString = this.html(classC.getHtmlUrl());
|
|
|
- String assign = this.replace(htmlString, map);
|
|
|
- MultipartFile pdfFile = PdfGenerator.generatePdf(assign);
|
|
|
- if (pdfFile != null) {
|
|
|
- BladeFile bladeFile = newIOSSClient.uploadFileByInputStream(pdfFile);
|
|
|
- if (bladeFile != null) {
|
|
|
- TrialSummaryRecord obj = BeanUtil.copyProperties(dto, TrialSummaryRecord.class);
|
|
|
- if (obj != null) {
|
|
|
- obj.setSummaryNumber(sn);
|
|
|
- obj.setPdfUrl(bladeFile.getLink());
|
|
|
- if (trialSummaryRecordServiceImpl.save(obj)) {
|
|
|
- return R.success("操作成功");
|
|
|
+ Map<String, String> indexMap = this.indexMap(htmlString, map, needsSavedData);
|
|
|
+ if (indexMap.size() > 0) {
|
|
|
+ ExcelTab excelTab = jdbcTemplate.query("SELECT file_url FROM m_excel_tab WHERE id = ?", new Object[]{classC.getExcelId()}, new BeanPropertyRowMapper<>(ExcelTab.class)).stream().findAny().orElse(null);
|
|
|
+ if (excelTab != null) {
|
|
|
+ MultipartFile multipartFile = this.writeDataToMultipartFile(excelTab.getFileUrl(), indexMap);
|
|
|
+ if (multipartFile != null) {
|
|
|
+ NewBladeFile newBladeFile = newIOSSClient.excelToPdf(multipartFile);
|
|
|
+ if (newBladeFile != null) {
|
|
|
+ TrialSummaryRecord obj = BeanUtil.copyProperties(dto, TrialSummaryRecord.class);
|
|
|
+ if (obj != null) {
|
|
|
+ obj.setId(SnowFlakeUtil.getId());
|
|
|
+ obj.setSummaryNumber(sn);
|
|
|
+ obj.setPdfUrl(newBladeFile.getPdfUrl());
|
|
|
+ if (trialSummaryRecordServiceImpl.save(obj) && saveData(needsSavedData, obj, classC)) {
|
|
|
+ return R.success("操作成功");
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -228,6 +270,108 @@ public class TrialSummaryController {
|
|
|
return R.fail("操作失败");
|
|
|
}
|
|
|
|
|
|
+ private boolean saveData(Map<String, String> needsSavedData, TrialSummaryRecord obj, TrialSummaryClassificationConfiguration classC) throws JsonProcessingException {
|
|
|
+ if (needsSavedData.size() > 0) {
|
|
|
+ ObjectMapper objectMapper = new ObjectMapper();
|
|
|
+ String json = objectMapper.writeValueAsString(needsSavedData);
|
|
|
+ if (ObjectUtil.isNotEmpty(json)) {
|
|
|
+ jdbcTemplate.update("INSERT INTO u_trial_summary_record_data_json(id,record_id,excel_id,json_data) VALUES (?,?,?,?)"
|
|
|
+ , new Object[]{SnowFlakeUtil.getId(), obj.getId(), classC.getExcelId(), json}
|
|
|
+ );
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 数据写入excel
|
|
|
+ *
|
|
|
+ * @param fileUrl
|
|
|
+ * @param indexMap
|
|
|
+ * @return
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ private MultipartFile writeDataToMultipartFile(String fileUrl, Map<String, String> indexMap) throws Exception {
|
|
|
+ InputStream modInput = CommonUtil.getOSSInputStream(fileUrl);
|
|
|
+ if (modInput != null) {
|
|
|
+ try (Workbook workbook = new XSSFWorkbook(modInput)) {
|
|
|
+ Sheet sheet = workbook.getSheetAt(0);
|
|
|
+ for (Map.Entry<String, String> entry : indexMap.entrySet()) {
|
|
|
+ String key = entry.getKey();
|
|
|
+ String value = entry.getValue();
|
|
|
+ String[] coordinates = key.split("@");
|
|
|
+ String x = coordinates[0];
|
|
|
+ String y = coordinates[1];
|
|
|
+
|
|
|
+ int x1 = Integer.parseInt(x.split(":")[0]) - 1;
|
|
|
+ int x2 = Integer.parseInt(x.split(":")[1]) - 1;
|
|
|
+ int y1 = Integer.parseInt(y.split(":")[0]) - 1;
|
|
|
+ int y2 = Integer.parseInt(y.split(":")[1]) - 1;
|
|
|
+
|
|
|
+ mergeAndCenterCells(sheet, x1, x2, y1, y2, value);
|
|
|
+ }
|
|
|
+ try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
|
|
|
+ workbook.write(byteArrayOutputStream);
|
|
|
+ try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray())) {
|
|
|
+ return new MockMultipartFile("file", fileUrl, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", byteArrayInputStream);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void mergeAndCenterCells(Sheet sheet, int x1, int x2, int y1, int y2, String value) {
|
|
|
+ if (!isAlreadyMerged(sheet, x1, x2, y1, y2)) {
|
|
|
+ CellRangeAddress mergedRegion = new CellRangeAddress(y1, y2, x1, x2);
|
|
|
+ sheet.addMergedRegion(mergedRegion);
|
|
|
+ }
|
|
|
+
|
|
|
+ Row row = sheet.getRow(y1);
|
|
|
+ if (row == null) {
|
|
|
+ row = sheet.createRow(y1);
|
|
|
+ }
|
|
|
+
|
|
|
+ Cell cell = row.createCell(x1);
|
|
|
+ cell.setCellValue(value);
|
|
|
+
|
|
|
+ CellStyle style = sheet.getWorkbook().createCellStyle();
|
|
|
+ style.setAlignment(HorizontalAlignment.CENTER);
|
|
|
+ style.setVerticalAlignment(VerticalAlignment.CENTER);
|
|
|
+
|
|
|
+ style.setBorderBottom(BorderStyle.THIN);
|
|
|
+ style.setBottomBorderColor(IndexedColors.BLACK.getIndex());
|
|
|
+ style.setBorderTop(BorderStyle.THIN);
|
|
|
+ style.setTopBorderColor(IndexedColors.BLACK.getIndex());
|
|
|
+ style.setBorderLeft(BorderStyle.THIN);
|
|
|
+ style.setLeftBorderColor(IndexedColors.BLACK.getIndex());
|
|
|
+ style.setBorderRight(BorderStyle.THIN);
|
|
|
+ style.setRightBorderColor(IndexedColors.BLACK.getIndex());
|
|
|
+
|
|
|
+ cell.setCellStyle(style);
|
|
|
+ }
|
|
|
+
|
|
|
+ private static boolean isAlreadyMerged(Sheet sheet, int x1, int x2, int y1, int y2) {
|
|
|
+ for (int i = sheet.getNumMergedRegions() - 1; i >= 0; i--) {
|
|
|
+ CellRangeAddress existingRegion = sheet.getMergedRegion(i);
|
|
|
+ if (existingRegion.getFirstColumn() == x1
|
|
|
+ && existingRegion.getLastColumn() == x2
|
|
|
+ && existingRegion.getFirstRow() == y1
|
|
|
+ && existingRegion.getLastRow() == y2) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取htmlString
|
|
|
+ *
|
|
|
+ * @param fileUrl
|
|
|
+ * @return
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
private String html(String fileUrl) throws Exception {
|
|
|
String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
|
|
|
String sys_file_net_url = ParamCache.getValue(CommonConstant.SYS_FILE_NET_URL);
|
|
@@ -245,32 +389,46 @@ public class TrialSummaryController {
|
|
|
return doc.select("table").first() + "";
|
|
|
}
|
|
|
|
|
|
- private String replace(String template, Map<String, Object> values) {
|
|
|
- String patternString = "\\{(\\w+)}";
|
|
|
- Pattern pattern = Pattern.compile(patternString);
|
|
|
- Matcher matcher = pattern.matcher(template);
|
|
|
- StringBuffer result = new StringBuffer();
|
|
|
- while (matcher.find()) {
|
|
|
- String key = matcher.group(1);
|
|
|
- if (values.containsKey(key)) {
|
|
|
- matcher.appendReplacement(result, values.get(key).toString());
|
|
|
+ /**
|
|
|
+ * 获取坐标对应数据Map
|
|
|
+ *
|
|
|
+ * @param htmlString
|
|
|
+ * @param values
|
|
|
+ * @param needsSavedData 需要保存入库的数据(历史记录,其他接口需要使用)
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private Map<String, String> indexMap(String htmlString, Map<String, Object> values, Map<String, String> needsSavedData) {
|
|
|
+ Map<String, String> resultIndex = new LinkedHashMap<>();
|
|
|
+ Document doc = Jsoup.parse(htmlString);
|
|
|
+ Elements elInputs = doc.select("el-input");
|
|
|
+ for (Element elInput : elInputs) {
|
|
|
+ String keyName = elInput.attr("keyname");
|
|
|
+ if (values.containsKey(keyName)) {
|
|
|
+ String value = values.get(keyName).toString();
|
|
|
+ String colIndex_1 = elInput.attr("x1");
|
|
|
+ String colIndex_2 = elInput.attr("x2");
|
|
|
+ String rowIndex_1 = elInput.attr("y1");
|
|
|
+ String rowIndex_2 = elInput.attr("y2");
|
|
|
+ resultIndex.put(colIndex_1 + ":" + colIndex_2 + "@" + rowIndex_1 + ":" + rowIndex_2, value);
|
|
|
+ needsSavedData.put(keyName, value);
|
|
|
}
|
|
|
}
|
|
|
- matcher.appendTail(result);
|
|
|
- return result + "";
|
|
|
+ return resultIndex;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 构建汇总编号(删除占用,is_deleted=1也需判断)
|
|
|
+ *
|
|
|
+ * @param dto
|
|
|
+ * @return
|
|
|
+ */
|
|
|
private String build(TrialSummaryRecordDTO dto) {
|
|
|
- List<TrialSummaryRecord> trialSummaryRecords = trialSummaryRecordServiceImpl.getBaseMapper().selectList(Wrappers.<TrialSummaryRecord>lambdaQuery()
|
|
|
- .select(TrialSummaryRecord::getSummaryNumber)
|
|
|
- .eq(TrialSummaryRecord::getClassId, dto.getClassId())
|
|
|
- .eq(TrialSummaryRecord::getContractId, dto.getContractId())
|
|
|
- );
|
|
|
-
|
|
|
+ List<TrialSummaryRecord> trialSummaryRecords = jdbcTemplate.query("SELECT * FROM u_trial_summary_record WHERE class_id = ? AND contract_id = ?",
|
|
|
+ new Object[]{dto.getClassId(), dto.getContractId()},
|
|
|
+ new BeanPropertyRowMapper<>(TrialSummaryRecord.class));
|
|
|
if (trialSummaryRecords.isEmpty()) {
|
|
|
return "HZ-0001";
|
|
|
}
|
|
|
-
|
|
|
Pattern pattern = Pattern.compile("HZ-(\\d+)");
|
|
|
int maxNumber = trialSummaryRecords.stream()
|
|
|
.map(TrialSummaryRecord::getSummaryNumber)
|