|
@@ -18,6 +18,7 @@ import com.spire.xls.ExcelPicture;
|
|
|
import com.spire.xls.FileFormat;
|
|
|
import com.spire.xls.Worksheet;
|
|
|
import com.spire.xls.collections.PicturesCollection;
|
|
|
+import io.swagger.models.auth.In;
|
|
|
import lombok.AllArgsConstructor;
|
|
|
import org.apache.commons.collections4.CollectionUtils;
|
|
|
import org.apache.commons.lang.StringUtils;
|
|
@@ -59,6 +60,7 @@ import org.springblade.core.tool.node.ForestNodeMerger;
|
|
|
import org.springblade.core.tool.utils.DateUtil;
|
|
|
import org.springblade.core.tool.utils.*;
|
|
|
import org.springblade.manager.bean.TableInfo;
|
|
|
+import org.springblade.manager.dto.BatchAddNumbersDTO;
|
|
|
import org.springblade.manager.dto.FormData;
|
|
|
import org.springblade.manager.entity.*;
|
|
|
import org.springblade.manager.enums.ExecuteType;
|
|
@@ -88,6 +90,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|
|
import org.springframework.transaction.support.DefaultTransactionDefinition;
|
|
|
|
|
|
import java.io.*;
|
|
|
+import java.net.HttpURLConnection;
|
|
|
import java.net.URL;
|
|
|
import java.nio.file.Files;
|
|
|
import java.text.ParseException;
|
|
@@ -867,7 +870,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
|
|
|
String file_path = FileUtils.getSysLocalFileUrl();
|
|
|
String filecode = SnowFlakeUtil.getId() + "";
|
|
|
String dataUrl = file_path + "/excel/" + filecode + ".xlsx";
|
|
|
- java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
|
|
|
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
|
|
connection.setRequestMethod("GET");
|
|
|
connection.setConnectTimeout(5 * 1000);
|
|
|
InputStream inputStream = connection.getInputStream();
|
|
@@ -3405,7 +3408,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
|
|
|
return list;
|
|
|
}
|
|
|
|
|
|
- private boolean tableContextReplace(org.apache.poi.ss.usermodel.Workbook workbook, String oldContext, String newContext){
|
|
|
+ private boolean tableContextReplace(Workbook workbook, String oldContext, String newContext){
|
|
|
Sheet sheet = workbook.getSheetAt(0);
|
|
|
sheet.setForceFormulaRecalculation(true);
|
|
|
int rowNum = sheet.getLastRowNum();
|
|
@@ -3497,7 +3500,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
|
|
|
}
|
|
|
|
|
|
//获取清表excel文件
|
|
|
- org.apache.poi.ss.usermodel.Workbook workbook = WorkbookFactory.create(Objects.requireNonNull(CommonUtil.getOSSInputStreamTow(excelTab.getFileUrl())));
|
|
|
+ Workbook workbook = WorkbookFactory.create(Objects.requireNonNull(CommonUtil.getOSSInputStreamTow(excelTab.getFileUrl())));
|
|
|
Sheet sheet = workbook.getSheetAt(0);
|
|
|
sheet.setForceFormulaRecalculation(true);
|
|
|
Header header = sheet.getHeader();
|
|
@@ -4534,7 +4537,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
|
|
|
newStyle.cloneStyleFrom(cell.getCellStyle());
|
|
|
newStyle.setFont(redFont);
|
|
|
newStyle.setShrinkToFit(true);
|
|
|
- cell.setCellStyle(newStyle);
|
|
|
+ //cell.setCellStyle(newStyle);
|
|
|
if(dqid.contains("||")){
|
|
|
String[] split = dqid.split("\\|\\|");
|
|
|
for (String singleDqid : split) {
|
|
@@ -4544,6 +4547,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
|
|
|
sign.add(dqid);
|
|
|
}
|
|
|
cell.setCellValue(dqid);
|
|
|
+ System.out.println(111);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -4577,8 +4581,142 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
|
|
|
FileUtils.excelToPdf(excelPath, pdfPath);
|
|
|
PdfAddimgUtil.pdfAddImgInfo(pdfPath, String.join(",", sign),textMap);
|
|
|
return R.data(FileUtils.getNetUrl(pdfPath));
|
|
|
+
|
|
|
}
|
|
|
|
|
|
+// @Override
|
|
|
+// public R getPriWbsPdfByPId(Long pkeyId) throws Exception {
|
|
|
+// // 1. 获取文件存储路径
|
|
|
+// String file_path = FileUtils.getSysLocalFileUrl();
|
|
|
+//
|
|
|
+// // 2. 查询 WbsTreePrivate 数据
|
|
|
+// WbsTreePrivate wbsTreePrivate = this.wbsTreePrivateService.getOne(
|
|
|
+// Wrappers.<WbsTreePrivate>lambdaQuery()
|
|
|
+// .eq(WbsTreePrivate::getPKeyId, pkeyId)
|
|
|
+// );
|
|
|
+// if (wbsTreePrivate == null) {
|
|
|
+// return R.fail("未获取到该表单的信息");
|
|
|
+// }
|
|
|
+// if (wbsTreePrivate.getHtmlUrl() == null) {
|
|
|
+// return R.fail("htmlUrl is null");
|
|
|
+// }
|
|
|
+//
|
|
|
+// // 3. 定义 PDF 和 Excel 存储路径
|
|
|
+// String pdfPath = file_path + "/pdf/" + pkeyId + ".pdf";
|
|
|
+// String excelPath = file_path + "/pdf/" + pkeyId + ".xlsx";
|
|
|
+//
|
|
|
+// // 4. 删除已存在的旧文件(避免缓存问题)
|
|
|
+// File tabPdf = ResourceUtil.getFile(pdfPath);
|
|
|
+// if (tabPdf.exists()) {
|
|
|
+// tabPdf.delete();
|
|
|
+// }
|
|
|
+//
|
|
|
+// // 5. 获取清表信息(Excel 模板)
|
|
|
+// ExcelTab excelTab = this.getById(wbsTreePrivate.getExcelId());
|
|
|
+// if (excelTab == null) {
|
|
|
+// return R.fail("未获取到清表信息");
|
|
|
+// }
|
|
|
+//
|
|
|
+// // 6. 从 OSS 获取 Excel 模板输入流
|
|
|
+// InputStream excelInp = CommonUtil.getOSSInputStream(excelTab.getFileUrl());
|
|
|
+// Workbook workbook;
|
|
|
+// String suffix = excelTab.getFileUrl().substring(excelTab.getFileUrl().lastIndexOf("."));
|
|
|
+//
|
|
|
+// // 7. 根据文件后缀创建 Workbook(支持 .xls 和 .xlsx)
|
|
|
+// if (".xls".equalsIgnoreCase(suffix)) {
|
|
|
+// workbook = new HSSFWorkbook(excelInp);
|
|
|
+// } else if (".xlsx".equalsIgnoreCase(suffix)) {
|
|
|
+// workbook = new XSSFWorkbook(excelInp);
|
|
|
+// } else {
|
|
|
+// return R.fail("不支持的 Excel 格式");
|
|
|
+// }
|
|
|
+//
|
|
|
+// // 8. 获取第一个 Sheet 并强制重新计算公式
|
|
|
+// Sheet sheet = workbook.getSheetAt(0);
|
|
|
+// sheet.setForceFormulaRecalculation(true);
|
|
|
+//
|
|
|
+// // 9. 解析 HTML 并提取 dqid
|
|
|
+// List<String> sign = new ArrayList<>();
|
|
|
+// if (StringUtils.isNotEmpty(wbsTreePrivate.getHtmlUrl())) {
|
|
|
+// InputStream htmlInputStream = FileUtils.getInputStreamByUrl(wbsTreePrivate.getHtmlUrl());
|
|
|
+// String htmlString = IoUtil.readToString(htmlInputStream);
|
|
|
+//
|
|
|
+// // 10. 使用 Jsoup 解析 HTML
|
|
|
+// Document doc = Jsoup.parse(htmlString);
|
|
|
+//
|
|
|
+// // 11. 查找所有含 dqid 的元素(不再限定在 table 内)
|
|
|
+// Elements dqidElements = doc.getElementsByAttribute("dqid");
|
|
|
+// System.out.println("找到 " + dqidElements.size() + " 个含 dqid 的元素");
|
|
|
+//
|
|
|
+// for (Element element : dqidElements) {
|
|
|
+// String dqid = element.attr("dqid");
|
|
|
+// System.out.println("处理 dqid: " + dqid);
|
|
|
+//
|
|
|
+// // 12. 检查是否有 x1 和 y1 属性(用于定位 Excel 单元格)
|
|
|
+// if (element.hasAttr("x1") && element.hasAttr("y1")) {
|
|
|
+// int x1 = Func.toInt(element.attr("x1"));
|
|
|
+// int y1 = Func.toInt(element.attr("y1"));
|
|
|
+// System.out.println("坐标: x1=" + x1 + ", y1=" + y1);
|
|
|
+//
|
|
|
+// // 13. 获取 Excel 单元格(行和列索引从 0 开始)
|
|
|
+// Row row = sheet.getRow(y1 - 1);
|
|
|
+// if (row == null) {
|
|
|
+// System.out.println("警告: 第 " + (y1 - 1) + " 行不存在,自动创建");
|
|
|
+// row = sheet.createRow(y1 - 1);
|
|
|
+// }
|
|
|
+//
|
|
|
+// Cell cell = row.getCell(x1 - 1, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
|
|
|
+// System.out.println("单元格原始值: " + cell.getStringCellValue());
|
|
|
+//
|
|
|
+// // 14. 强制设置单元格为文本格式(避免科学计数法问题)
|
|
|
+// CellStyle textStyle = workbook.createCellStyle();
|
|
|
+// textStyle.setDataFormat(workbook.createDataFormat().getFormat("@"));
|
|
|
+// cell.setCellStyle(textStyle);
|
|
|
+//
|
|
|
+// // 15. 设置 dqid 值
|
|
|
+// cell.setCellValue(dqid);
|
|
|
+// System.out.println("成功写入 dqid: " + dqid);
|
|
|
+//
|
|
|
+// // 16. 处理多个 dqid(用 || 分隔的情况)
|
|
|
+// if (dqid.contains("||")) {
|
|
|
+// String[] split = dqid.split("\\|\\|");
|
|
|
+// Collections.addAll(sign, split);
|
|
|
+// } else {
|
|
|
+// sign.add(dqid);
|
|
|
+// }
|
|
|
+// } else {
|
|
|
+// System.out.println("警告: 元素缺少 x1 或 y1 属性,跳过");
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+//
|
|
|
+// // 17. 查询电签配置信息
|
|
|
+// TextdictInfoVO textdictInfo = new TextdictInfoVO();
|
|
|
+// textdictInfo.setType(2);
|
|
|
+// textdictInfo.setExcelId(wbsTreePrivate.getExcelId() + "");
|
|
|
+// textdictInfo.setTabId(pkeyId + "");
|
|
|
+// textdictInfo.setShowType(1);
|
|
|
+//
|
|
|
+// Query query = new Query();
|
|
|
+// query.setCurrent(0);
|
|
|
+// query.setSize(100);
|
|
|
+// IPage<TextdictInfoVO> pages = textdictInfoService.selectTextdictInfoPage(Condition.getPage(query), textdictInfo);
|
|
|
+// Map<Long, TextdictInfo> textMap = pages.getRecords().stream()
|
|
|
+// .collect(Collectors.toMap(TextdictInfo::getId, Function.identity()));
|
|
|
+//
|
|
|
+// // 18. 写入 Excel 文件
|
|
|
+// try (FileOutputStream outputStream = new FileOutputStream(excelPath)) {
|
|
|
+// workbook.write(outputStream);
|
|
|
+// }
|
|
|
+//
|
|
|
+// // 19. 转换为 PDF 并添加电子签名
|
|
|
+// FileUtils.excelToPdf(excelPath, pdfPath);
|
|
|
+// PdfAddimgUtil.pdfAddImgInfo(pdfPath, String.join(",", sign), textMap);
|
|
|
+//
|
|
|
+// // 20. 返回 PDF 网络路径
|
|
|
+// return R.data(FileUtils.getNetUrl(pdfPath));
|
|
|
+// }
|
|
|
+
|
|
|
|
|
|
/**
|
|
|
* 试验 委托单 单pdf
|
|
@@ -4619,7 +4757,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
|
|
|
}
|
|
|
|
|
|
//获取清表excel文件
|
|
|
- org.apache.poi.ss.usermodel.Workbook workbook = WorkbookFactory.create(Objects.requireNonNull(CommonUtil.getOSSInputStreamTow(excelTab.getFileUrl())));
|
|
|
+ Workbook workbook = WorkbookFactory.create(Objects.requireNonNull(CommonUtil.getOSSInputStreamTow(excelTab.getFileUrl())));
|
|
|
Sheet sheet = workbook.getSheetAt(0);
|
|
|
sheet.setForceFormulaRecalculation(true);
|
|
|
|
|
@@ -6128,6 +6266,307 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
|
|
|
FileUtil.writeToFile(writefile, doc.html(), Boolean.parseBoolean("UTF-8"));
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public R batchAddNumbers(BatchAddNumbersDTO dto) throws Exception {
|
|
|
+ //先查出当前节点下所有的表单
|
|
|
+ String selectAllNodeTable;
|
|
|
+ if(dto.getClassify().equals("1")){
|
|
|
+ selectAllNodeTable="select * from m_wbs_tree_contract where p_id="+dto.getNodeId()+" and table_owner in (1,2,3) and is_deleted=0";
|
|
|
+ }else {
|
|
|
+ selectAllNodeTable="select * from m_wbs_tree_contract where p_id="+dto.getNodeId()+" and table_owner in (4,5,6) and is_deleted=0";
|
|
|
+ }
|
|
|
+ List<WbsTreeContract> tables = jdbcTemplate.query(selectAllNodeTable, new BeanPropertyRowMapper<>(WbsTreeContract.class));
|
|
|
+ String selectTable="select * from m_wbs_tree_contract where p_key_id="+dto.getPkeyId();
|
|
|
+ WbsTreeContract wbsContract = jdbcTemplate.queryForObject(selectTable, new BeanPropertyRowMapper<>(WbsTreeContract.class));
|
|
|
+ Long excelId = wbsContract.getExcelId();
|
|
|
+ String nodeName = wbsContract.getNodeName();
|
|
|
+ int sufix =0;
|
|
|
+ if(nodeName.contains("_")){
|
|
|
+ sufix = Integer.parseInt(nodeName.substring(nodeName.lastIndexOf("_") +1));
|
|
|
+ }
|
|
|
+ List<WbsTreeContract>resultList=new ArrayList<>();
|
|
|
+ for (WbsTreeContract table : tables) {
|
|
|
+ if(Objects.equals(table.getExcelId(), excelId)){
|
|
|
+ if(sufix!=0&&table.getNodeName().contains("_")){
|
|
|
+ int suffix = Integer.parseInt(table.getNodeName().substring(nodeName.lastIndexOf("_") +1));
|
|
|
+ if(suffix>=sufix){
|
|
|
+ resultList.add(table);
|
|
|
+ }
|
|
|
+ }else if(sufix==0){
|
|
|
+ resultList.add(table);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ resultList.sort(new ExcelTabServiceImpl.WbsTreeContractComparator());
|
|
|
+ List<String> numbers = generateNumbers(dto);
|
|
|
+ Map<WbsTreeContract, Map<String,String>> reData = new HashMap<>();
|
|
|
+ String key = dto.getKey();
|
|
|
+ String[] strings = key.split("__");
|
|
|
+ int i=0;
|
|
|
+ boolean flag=false;
|
|
|
+ for (WbsTreeContract contract : resultList) {
|
|
|
+ if(flag){
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ Map<String,String> map=new HashMap<>();
|
|
|
+ String fileUrl = contract.getHtmlUrl();
|
|
|
+ InputStream fileInputStream = FileUtils.getInputStreamByUrl(fileUrl);
|
|
|
+ String htmlString = IoUtil.readToString(fileInputStream);
|
|
|
+ Document doc = Jsoup.parse(htmlString);
|
|
|
+ Elements keyNames = doc.getElementsByAttribute("keyname");
|
|
|
+ for (Element keyName : keyNames) {
|
|
|
+ String result = keyName.attr("keyname");
|
|
|
+ if(result.contains(strings[0])){
|
|
|
+ if (i < numbers.size()) {
|
|
|
+ map.put(result, numbers.get(i));
|
|
|
+ i++;
|
|
|
+ } else {
|
|
|
+ flag=true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(!map.isEmpty()){
|
|
|
+ reData.put(contract,map);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //保存数据入库并且生成pdf
|
|
|
+ saveDataAndGeneratePdf(reData,dto.getNodeId(),dto.getClassify(),wbsContract.getContractId(),wbsContract.getProjectId());
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void saveDataAndGeneratePdf(Map<WbsTreeContract, Map<String, String>> reData,String nodeId,String classify,String contractId,String projectId) throws Exception {
|
|
|
+ for (Map.Entry<WbsTreeContract, Map<String, String>> entry : reData.entrySet()) {
|
|
|
+ Map<String, String> dataInfo2 = entry.getValue();
|
|
|
+ WbsTreeContract wbsTreeContract = entry.getKey();
|
|
|
+ //计算数据
|
|
|
+ LinkedHashMap<String, List<String>> dataMap = dataInfo2.keySet().stream().filter(e -> e.contains("__")).collect(Collectors.groupingBy(e -> e.split("__")[0], LinkedHashMap<String, List<String>>::new, Collectors.toList()));
|
|
|
+ LinkedHashMap<String, String> dataMap2 = new LinkedHashMap<>();
|
|
|
+ //字段组合
|
|
|
+ for (String k : dataMap.keySet()) {
|
|
|
+ if (dataMap.get(k).size() > 1 && !dataMap.get(k).contains("000Z")) {
|
|
|
+ String[] ziduan = dataMap.get(k).toArray(new String[]{});
|
|
|
+ String temp = "";
|
|
|
+ for (int i = 0; i < ziduan.length - 1; i++) {
|
|
|
+ for (int j = 0; j < ziduan.length - i - 1; j++) {
|
|
|
+ int tr = Integer.parseInt((ziduan[j].split("__")[1]).split("_")[0]);
|
|
|
+ int td = Integer.parseInt(ziduan[j].split("__")[1].split("_")[1]);
|
|
|
+ int tr_1 = Integer.parseInt(ziduan[j + 1].split("__")[1].split("_")[0]);
|
|
|
+ int td_1 = Integer.parseInt(ziduan[j + 1].split("__")[1].split("_")[1]);
|
|
|
+ if (tr > tr_1 && td == td_1) { //纵向排序
|
|
|
+ temp = ziduan[j];
|
|
|
+ ziduan[j] = ziduan[j + 1];
|
|
|
+ ziduan[j + 1] = temp;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ StringBuilder lastStr = new StringBuilder(dataInfo2.get(ziduan[0]) + "_^_" + ziduan[0].split("__")[1]);
|
|
|
+ for (int i = 1; i < ziduan.length; i++) {
|
|
|
+ String keyData = dataInfo2.get(ziduan[i]);
|
|
|
+ if (keyData!=null && Func.isNotEmpty(keyData)) {
|
|
|
+ lastStr.append("☆").append(dataInfo2.get(ziduan[i])).append("_^_").append(ziduan[i].split("__")[1]);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ dataMap2.put(k, lastStr.toString());
|
|
|
+ } else {
|
|
|
+ String dataVal = dataInfo2.get(dataMap.get(k).get(0));
|
|
|
+ if(StringUtils.isNotEmpty(dataVal)){
|
|
|
+ dataMap2.put(k, dataVal + "_^_" + dataMap.get(k).get(0).split("__")[1]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Optional<String> Key = dataMap2.keySet().stream().findFirst();
|
|
|
+ if(Key.isPresent()){
|
|
|
+ String sql="update "+wbsTreeContract.getInitTableName()+" set "+Key.get()+" = '"+dataMap2.get(Key.get())+"' where p_key_id = "+wbsTreeContract.getPKeyId();
|
|
|
+ jdbcTemplate.update(sql);
|
|
|
+ }
|
|
|
+ getBussPdfInfo(wbsTreeContract.getPKeyId());
|
|
|
+ }
|
|
|
+ getBussPdfs(nodeId, classify, contractId, projectId);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成符合要求的编号列表
|
|
|
+ * @param dto 包含编号生成规则的参数对象
|
|
|
+ * @return 生成的编号列表
|
|
|
+ */
|
|
|
+ public static List<String> generateNumbers(BatchAddNumbersDTO dto) {
|
|
|
+ List<String> result = new ArrayList<>();
|
|
|
+
|
|
|
+ if (dto.getType() == 1) {
|
|
|
+ // 处理独立编号
|
|
|
+ result = generateSinglePartNumbers(
|
|
|
+ dto.getIncreType1(),
|
|
|
+ dto.getCycleType1(),
|
|
|
+ dto.getCycleTypeGroup1(),
|
|
|
+ dto.getStartNumber1(),
|
|
|
+ dto.getEndNumber1()
|
|
|
+ );
|
|
|
+ } else if (dto.getType() == 2) {
|
|
|
+ // 处理组合编号
|
|
|
+ List<String> part1List = generateSinglePartNumbers(
|
|
|
+ dto.getIncreType1(),
|
|
|
+ dto.getCycleType1(),
|
|
|
+ dto.getCycleTypeGroup1(),
|
|
|
+ dto.getStartNumber1(),
|
|
|
+ dto.getEndNumber1()
|
|
|
+ );
|
|
|
+
|
|
|
+ List<String> part2List = generateSinglePartNumbers(
|
|
|
+ dto.getIncreType2(),
|
|
|
+ dto.getCycleType2(),
|
|
|
+ dto.getCycleTypeGroup2(),
|
|
|
+ dto.getStartNumber2(),
|
|
|
+ dto.getEndNumber2()
|
|
|
+ );
|
|
|
+
|
|
|
+ // 组合两部分编号
|
|
|
+ for (String part1 : part1List) {
|
|
|
+ for (String part2 : part2List) {
|
|
|
+ result.add(part1 + dto.getSeparator() + part2);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成单部分编号(独立编号或组合编号的一部分)
|
|
|
+ * @param increType 递增类型:1常规递增 2奇数递增 3偶数递增
|
|
|
+ * @param cycleType 循环类型:1固定循环 2递增循环
|
|
|
+ * @param cycleGroup 循环组数
|
|
|
+ * @param startNum 开始编号
|
|
|
+ * @param endNum 结束编号
|
|
|
+ * @return 生成的单部分编号列表
|
|
|
+ */
|
|
|
+ private static List<String> generateSinglePartNumbers(
|
|
|
+ Integer increType,
|
|
|
+ Integer cycleType,
|
|
|
+ Integer cycleGroup,
|
|
|
+ Integer startNum,
|
|
|
+ Integer endNum
|
|
|
+ ) {
|
|
|
+ List<String> result = new ArrayList<>();
|
|
|
+ // 获取符合递增条件的基础编号列表
|
|
|
+ List<String> baseNumbers = getBaseNumbers(increType, startNum, endNum);
|
|
|
+
|
|
|
+ if (cycleType == 1) {
|
|
|
+ // 固定循环:每个编号重复n次
|
|
|
+ for (String num : baseNumbers) {
|
|
|
+ for (int i = 0; i < cycleGroup; i++) {
|
|
|
+ result.add(num);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else if (cycleType == 2) {
|
|
|
+ // 递增循环:整个序列重复n次
|
|
|
+ for (int i = 0; i < cycleGroup; i++) {
|
|
|
+ result.addAll(baseNumbers);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取符合递增条件的基础编号列表
|
|
|
+ * @param increType 递增类型
|
|
|
+ * @param startNum 开始编号
|
|
|
+ * @param endNum 结束编号
|
|
|
+ * @return 符合条件的基础编号列表
|
|
|
+ */
|
|
|
+ private static List<String> getBaseNumbers(Integer increType, Integer startNum, Integer endNum) {
|
|
|
+ List<String> baseNumbers = new ArrayList<>();
|
|
|
+
|
|
|
+ for (int i = startNum; i <= endNum; i++) {
|
|
|
+ boolean isQualified = false;
|
|
|
+
|
|
|
+ if (increType == 1) {
|
|
|
+ // 常规递增:所有数字都符合条件
|
|
|
+ isQualified = true;
|
|
|
+ } else if (increType == 2) {
|
|
|
+ // 奇数递增:只保留奇数
|
|
|
+ isQualified = (i % 2 != 0);
|
|
|
+ } else if (increType == 3) {
|
|
|
+ // 偶数递增:只保留偶数
|
|
|
+ isQualified = (i % 2 == 0);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (isQualified) {
|
|
|
+ baseNumbers.add(String.valueOf(i));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return baseNumbers;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static class WbsTreeContractComparator implements Comparator<WbsTreeContract> {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int compare(WbsTreeContract o1, WbsTreeContract o2) {
|
|
|
+ // 先比较 sort 属性
|
|
|
+ Integer sort1 = o1.getSort();
|
|
|
+ Integer sort2 = o2.getSort();
|
|
|
+ if (sort1 == null && sort2 == null) {
|
|
|
+ // 两个 sort 都为空,认为相等
|
|
|
+ return 0;
|
|
|
+ } else if (sort1 != null && sort2 != null && sort1 == 0 && sort2 == 0) {
|
|
|
+ // 两个 sort 都不为空,并且都是0
|
|
|
+ return 0;
|
|
|
+ } else if (sort1 == null) {
|
|
|
+ // 第一个 sort 为空,排在后面
|
|
|
+ return 1;
|
|
|
+ } else if (sort2 == null) {
|
|
|
+ // 第二个 sort 为空,排在前面
|
|
|
+ return -1;
|
|
|
+ } else {
|
|
|
+ // 两个 sort 都不为空,按 sort 排序
|
|
|
+ int sortComparison = Integer.compare(sort1, sort2);
|
|
|
+ if (sortComparison != 0) {
|
|
|
+ return sortComparison;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果 sort 相同,比较 nodeName
|
|
|
+ String name1 = o1.getNodeName();
|
|
|
+ String name2 = o2.getNodeName();
|
|
|
+ String[] split1 = name1.split("__");
|
|
|
+ String[] split2 = name2.split("__");
|
|
|
+ if (split1[0].equals(split2[0])) {
|
|
|
+ try {
|
|
|
+ return compareTo(split1, split2);
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
+ // 如果无法将字符串转换为数字,则按照字符串比较
|
|
|
+ return name1.compareTo(name2);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ split1 = split1[0].split("_PL_");
|
|
|
+ split2 = split2[0].split("_PL_");
|
|
|
+ try {
|
|
|
+ return compareTo(split1, split2);
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
+ return name1.compareTo(name2);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static int compareTo(String[] split1, String[] split2) {
|
|
|
+ if (split1.length > 1 && split2.length > 1) {
|
|
|
+ int number1 = Integer.parseInt(split1[1]);
|
|
|
+ int number2 = Integer.parseInt(split2[1]);
|
|
|
+ return Integer.compare(number1, number2);
|
|
|
+ } else if (split1.length == 1 && split2.length == 1) {
|
|
|
+ return 0;
|
|
|
+ } else if (split1.length > 1) {
|
|
|
+ return 1;
|
|
|
+ } else {
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
// 获取解析样式
|
|
|
public static Map<String, String> getHtmlStyle(Document doc) {
|
|
|
Map<String, String> styleMap = new HashMap<>();
|