ソースを参照

Merge branch 'lvy' of http://219.151.181.73:3000/zhuwei/bladex into test-merge

# Conflicts:
#	blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java
#	blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/TextdictInfoMapper.xml
#	blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/TextdictInfoServiceImpl.java
lvy 3 週間 前
コミット
11ac68ede0
15 ファイル変更1124 行追加183 行削除
  1. 79 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/DqOperationLog.java
  2. 1 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/ExcelTabVo1.java
  3. 1 1
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TaskController.java
  4. 9 30
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/impl/EVDataServiceImpl.java
  5. 628 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java
  6. 25 6
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/TextdictInfoController.java
  7. 8 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/DqOperationLogMapper.java
  8. 25 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/DqOperationLogMapper.xml
  9. 2 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/TextdictInfoMapper.xml
  10. 12 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IDqOperationLogService.java
  11. 13 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/DqOperationLogServiceImpl.java
  12. 144 87
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java
  13. 121 31
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java
  14. 2 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/SignConfigServiceImpl.java
  15. 54 23
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/TextdictInfoServiceImpl.java

+ 79 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/DqOperationLog.java

@@ -0,0 +1,79 @@
+package org.springblade.manager.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+
+import io.swagger.annotations.ApiModelProperty;
+import org.springblade.core.mp.base.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.core.secure.BladeUser;
+import org.springblade.core.secure.utils.AuthUtil;
+
+import java.util.Date;
+
+
+@Data
+@TableName("u_dq_operation_log")
+@EqualsAndHashCode(callSuper = true)
+public class DqOperationLog extends BaseEntity {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty("项目id")
+    private Long projectId;
+
+    @ApiModelProperty("节点pKeyId")
+    private Long nodeId;
+
+    /**
+     * 操作类型
+     */
+    @ApiModelProperty("操作类型, 1:保存,2:删除")
+    private Integer operationType;
+
+    /**
+     * 参数
+     */
+    @ApiModelProperty("参数")
+    private String operationContent;
+
+    /**
+     * 旧内容
+     */
+    @ApiModelProperty("旧内容")
+    private String oldContent;
+
+    /**
+     * 新内容
+     */
+    @ApiModelProperty("新内容")
+    private String newContent;
+
+    /**
+     * textdict_info ids
+     */
+    @ApiModelProperty("textdict_info ids")
+    private String businessId;
+
+    @ApiModelProperty("操作人")
+    private String createUserName;
+
+
+
+    public DqOperationLog() {
+    }
+
+    public DqOperationLog(WbsTreePrivate wbsTreePrivate, BladeUser user, String businessId, Integer type, String param, String oldContent, String newContent) {
+        this.projectId = Long.parseLong(wbsTreePrivate.getProjectId());
+        this.nodeId = wbsTreePrivate.getPKeyId();
+        this.operationType = type;
+        this.operationContent = param;
+        this.createUserName = user.getUserName();
+        this.businessId = businessId;
+        this.oldContent = oldContent;
+        this.newContent = newContent;
+        this.setCreateTime(new Date());
+        this.setCreateUser(user.getUserId());
+        this.setCreateUserName(user.getUserName());
+    }
+}

+ 1 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/ExcelTabVo1.java

@@ -9,4 +9,5 @@ public class ExcelTabVo1 {
     private String htmlUrl;
     private String name;
     private String fileUrl;
+    private String tabName;
 }

+ 1 - 1
blade-service/blade-business/src/main/java/org/springblade/business/controller/TaskController.java

@@ -2065,7 +2065,7 @@ public class TaskController extends BladeController {
     public R<Object>reSigningEntrust(@RequestBody List<ReSigningEntrustDto> dtos, HttpServletRequest request){
         for (ReSigningEntrustDto dto : dtos) {
             if(dto.getStatus()!=null&&dto.getStatus()!=1){
-                String sql="SELECT t.id FROM u_task t WHERE t.form_data_id=(Select id from u_information_query WHERE wbs_id="+dto.getEntrustId()+")";
+                String sql="SELECT t.id FROM u_task t WHERE t.form_data_id=(Select id from u_information_query WHERE wbs_id="+dto.getEntrustId()+" and status in (1,2))";
                 dto.setTaskId(jdbcTemplate.queryForObject(sql, String.class));
             }
         }

+ 9 - 30
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/impl/EVDataServiceImpl.java

@@ -121,25 +121,14 @@ public class EVDataServiceImpl implements EVDataService {
                     SignBackPdfInfo(taskApp);
                     return;
                 } else {
-                    // 一个位置只留一个签字
+                    // 优先使用项目配置的电签
                     Map<Integer, SealStrategyVO> map = new HashMap<>();
                     strategyListByAXQ.forEach(item -> {
-                        String keyword = item.getKeyword();
-                        Integer lineNum = eVisaConfigMap.get(keyword);
-                        if (lineNum ==  null) {
-                            return;
-                        }
-                        SealStrategyVO vo = map.get(lineNum);
-                        if (vo == null) {
-                            map.put(lineNum, item);
-                        } else {
-                            String keyword1 = vo.getKeyword();
-                            if (keyword1 != null && keyword1.contains("✹") && !keyword.contains("✹")) {
-                                map.put(lineNum, item);
-                            }
+                        if (!item.getKeyword().contains("✹")) {
+                            map.put(eVisaConfigMap.get(item.getKeyword()), item);
                         }
                     });
-                    strategyListByAXQ = new ArrayList<>(map.values());
+                    strategyListByAXQ.removeIf(item -> item.getKeyword().contains("✹") && map.containsKey(eVisaConfigMap.get(item.getKeyword())));
                 }
 
                 //调用签字逻辑
@@ -156,25 +145,15 @@ public class EVDataServiceImpl implements EVDataService {
                 //添加电签策略
                 List<Map<String, Object>> strategyListByDFZX = getStrategyListByDFZX(taskApp, ids);
                 if (strategyListByDFZX != null && !strategyListByDFZX.isEmpty()) {
-                    // 一个位置只留一个签字
-                    Map<Integer, Map<String, Object>> map = new HashMap<>();
+                    // 优先使用项目配置的电签
+                    Map<Integer, Integer> map = new HashMap<>();
                     strategyListByDFZX.forEach(item -> {
                         String keyword = item.get("keyword") + "";
-                        Integer lineNum = eVisaConfigMap.get(keyword);
-                        if (lineNum ==  null) {
-                            return;
-                        }
-                        Map<String, Object> vo = map.get(lineNum);
-                        if (vo == null) {
-                            map.put(lineNum, item);
-                        } else {
-                            String keyword1 = vo.get("keyword") + "";
-                            if (!keyword1.equals("null") && keyword1.contains("✹") && !keyword.contains("✹")) {
-                                map.put(lineNum, item);
-                            }
+                        if (!keyword.contains("✹")) {
+                            map.put(eVisaConfigMap.get(keyword), 1);
                         }
                     });
-                    strategyListByDFZX = new ArrayList<>(map.values());
+                    strategyListByDFZX.removeIf(item -> (item.get("keyword") + "").contains("✹") && map.containsKey(eVisaConfigMap.get(item.get("keyword") + "")));
                 }
                 //调用签字逻辑
                 String s = signTaskBatchByDFZX(strategyListByDFZX, fileUrl, taskApp.getSigType(),taskApp.getRemarkType(),taskApp.getContractId());

+ 628 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java

@@ -44,12 +44,14 @@ import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.mp.support.Condition;
 import org.springblade.core.mp.support.Query;
 import org.springblade.core.oss.model.BladeFile;
+import org.springblade.core.redis.cache.BladeRedis;
 import org.springblade.core.secure.BladeUser;
 import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.secure.utils.SecureUtil;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.constant.BladeConstant;
 import org.springblade.core.tool.utils.*;
+import org.springblade.evisa.redissionUtil.DistributedRedisLock;
 import org.springblade.manager.bean.TableInfo;
 import org.springblade.manager.dto.AddBussFileSortDTO;
 import org.springblade.manager.entity.*;
@@ -77,9 +79,12 @@ import org.springframework.mock.web.MockMultipartFile;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
 import org.springframework.web.multipart.MultipartFile;
 
 import javax.imageio.ImageIO;
+import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.validation.Valid;
 import java.awt.*;
@@ -92,10 +97,13 @@ import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.StandardCopyOption;
+import java.sql.SQLException;
 import java.text.SimpleDateFormat;
 import java.util.List;
 import java.util.*;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -989,6 +997,598 @@ public class ExcelTabController extends BladeController {
         return doc.select("table").first() + "";
     }
 
+    // 上传解析 html
+    public void expailHtmlInfo(String thmlUrl, Long excelId, String tabType) throws Exception {
+
+        // 读取
+        File file1 = ResourceUtil.getFile(thmlUrl);
+        String htmlString = IoUtil.readToString(new FileInputStream(file1));
+
+        /*
+           解析
+           1 解析样式
+           2 计算坐标
+           3 计算区域位置
+         */
+        // 样式集合
+        Document doc = Jsoup.parse(htmlString);
+        // 解析 style
+        Map<String, String> styleMap = getHtmlStyle(doc);
+        //解析
+        Element table = doc.select("table").first();
+
+        Elements trs = table.select("tr");
+        Element tableinfo = trs.get(0).parent().parent().attr("style", "border-collapse: collapse;");
+
+        // 获取图片信息
+        Elements imgs = doc.select("img");
+
+
+        // 获取总行列数
+        int maxCol = doc.select("Col").size();
+        String[] rowData = new String[trs.size() + 5]; //本来加一的 害怕出现特殊情况 故意 加 5
+
+        // 行的状态
+        boolean index_state = false;
+        // 区域划分表示
+        int xy_type = 1;
+
+        // 解析 excel元素集合
+        List<ExctabCell> colTitle = new ArrayList<>();
+
+//      标题集合信息
+        List<Map<String, String>> zikey = new ArrayList<>();
+        for (int i = 0; i <= trs.size() - 1; i++) {
+            Element tr = trs.get(i);
+            Elements tds = tr.select("td");
+
+            String xyInof = getTrInfo(tds, styleMap, index_state, xy_type, maxCol, i, zikey);
+
+            xy_type = Integer.parseInt(xyInof.split(",")[0]);
+            tr.attr("xy_type", xyInof);
+            index_state = Boolean.parseBoolean(xyInof.split(",")[1]);
+            boolean isMaxCol = Integer.parseInt(xyInof.split(",")[2]) == maxCol;
+
+            boolean istrue = Boolean.parseBoolean(xyInof.split(",")[3]);
+
+
+            // 计算单元格坐标
+            int x = 0;
+
+            for (int j = 0; j < tds.size(); j++) {
+                {
+                    Element data = tds.get(j);
+                    Boolean isText = false;
+                    //判断高度
+                    String style = data.attr("style");
+                    if (StringUtils.isNotBlank(style)) {
+                        int index = style.lastIndexOf(":");
+                        String substring = style.substring(index + 1);
+                        String height = substring.substring(0, substring.length() - 3);
+                        int i1 = 0;
+                        try {
+                            i1 = Integer.parseInt(height);
+                        } catch (NumberFormatException e) {
+                            substring = style.substring(style.lastIndexOf(":", index - 1) + 1);
+                            height = substring.substring(0, substring.indexOf("px;"));
+                            i1 = Integer.parseInt(height);
+                        }
+                        if (i1 > 90) {
+                            isText = true;
+                        }
+                    }
+                    String trHtml = data.html();
+                    int colspan = data.attr("COLSPAN").equals("") ? 0 : Integer.parseInt(data.attr("COLSPAN"));
+                    int rowspan = data.attr("ROWSPAN").equals("") ? 0 : Integer.parseInt(data.attr("ROWSPAN"));
+                    String keyId = data.attr("class");
+                    if (StringUtils.isNotEmpty(keyId)) {
+                        String classInfo = styleMap.get(keyId);
+                        data.removeAttr("class");
+                    }
+
+                    Map<String, String> textObject = new HashMap<>();
+                    // 计算
+                    int x1 = 0;
+                    int x2 = 0;
+                    int y1 = 0;
+                    int y2 = 0;
+
+                    String textInfo = data.text().trim().replaceAll(" ", "");
+
+                    y1 = i + 1;
+                    //x 移位 算法
+                    String getRowInfo = rowData[y1];
+
+                    if (getRowInfo != null) {
+                        String[] dataInfo2 = getRowInfo.split(",");
+
+                        // 排序
+                        int lastMax = 0;
+                        List<String> datax = Arrays.stream(dataInfo2).sorted((a, b) -> Integer.parseInt(a.split(":")[1]) - Integer.parseInt(b.split(":")[1])).collect(Collectors.toList());
+                        List<String> lastdata = new ArrayList<>();
+                        //组合
+                        for (int h = 0; h < datax.size(); h++) {
+                            int mx1 = Integer.parseInt(datax.get(h).split(":")[0]);
+                            int mx2 = Integer.parseInt(datax.get(h).split(":")[1]);
+                            if (lastdata.size() == 0) {
+                                lastdata.add(datax.get(0));
+                            } else {
+                                if (lastMax + 1 == mx1) {
+                                    int minVal = Integer.parseInt(lastdata.get(lastdata.size() - 1).split(":")[0]);
+                                    lastdata.remove(lastdata.size() - 1);
+                                    lastdata.add(minVal + ":" + mx2);
+                                } else {
+                                    lastdata.add(datax.get(h));
+                                }
+                            }
+                            lastMax = mx2;
+                        }
+                        dataInfo2 = lastdata.stream().toArray(String[]::new);
+
+                        // 先逻辑处理 连续时,归一
+                        if ((dataInfo2[0].split(":")[0]).equals("1") && j == 0) {
+                            x = Integer.parseInt(dataInfo2[0].split(":")[1]);
+                        } else {
+                            for (int m = 0; m < dataInfo2.length; m++) {
+                                int mx1 = Integer.parseInt(dataInfo2[m].split(":")[0]);
+                                int mx2 = Integer.parseInt(dataInfo2[m].split(":")[1]);
+                                if ((mx1 - x) == 1 && mx1 > x) {
+                                    x = mx2;
+                                }
+                            }
+                        }
+                    }
+
+                    // X 坐标
+
+
+                    if (tds.size() == 1) {
+                        if (colspan == 0) {
+                            x1 = x + 1;
+                            x2 = x + 1;
+                        } else {
+                            if (x == 0) {
+                                x1 = 1;
+                                x2 = colspan;
+                            } else {
+                                x1 = x + 1;
+                                x2 = x + colspan;
+                            }
+                        }
+                    } else {
+                        if (colspan == 0) {
+                            x1 = x + 1;
+                            x2 = x + 1;
+                            x = x2;
+                        } else {
+                            x1 = x + 1;
+                            x2 = x + colspan;
+                            x = x2;
+                        }
+                    }
+
+
+                    //x y 坐标
+                    if (rowspan == 0) {
+                        y2 = i + 1;
+                    } else {
+                        y2 = i + rowspan;
+                        for (int k = 0; k < rowspan - 1; k++) {
+                            String dataInfo = rowData[k + 2 + i];
+                            if (dataInfo == null) {
+                                dataInfo = x1 + ":" + x2;
+                            } else {
+                                dataInfo = dataInfo + "," + x1 + ":" + x2;
+                                String[] arr = dataInfo.split(",");
+                                //排序
+                                for (int r = 0; r < arr.length - 1; r++) {
+                                    for (int q = arr.length - 2; q >= r; q--) {
+                                        Integer jval = Integer.parseInt(arr[q + 1].split(":")[0]);
+                                        Integer jval1 = Integer.parseInt(arr[q].split(":")[0]);
+                                        if (jval < jval1) {
+                                            String temp = arr[q + 1];
+                                            arr[q + 1] = arr[q];
+                                            arr[q] = temp;
+                                        }
+                                    }
+                                }
+
+                                //组合
+                                String newDataInfo = "";
+                                for (int r = 0; r < arr.length; r++) {
+                                    if (r == 0) {
+                                        newDataInfo = arr[0];
+                                    } else {
+                                        int StrMax = Integer.parseInt(newDataInfo.substring(newDataInfo.lastIndexOf(":") + 1, newDataInfo.length()));
+                                        Integer nowMin = Integer.parseInt(arr[r].split(":")[0]);
+                                        Integer nowMax = Integer.parseInt(arr[r].split(":")[1]);
+                                        if ((StrMax + 1) == nowMin) {
+                                            String lastStr = "";
+                                            if (newDataInfo.indexOf(",") >= 0) {
+                                                lastStr = newDataInfo.substring(newDataInfo.lastIndexOf(",") + 1, newDataInfo.length());
+                                                newDataInfo = newDataInfo.substring(0, newDataInfo.lastIndexOf(","));
+                                            } else {
+                                                lastStr = newDataInfo;
+                                                newDataInfo = "";
+                                            }
+                                            int lastmin = Integer.parseInt(lastStr.split(":")[0]);
+                                            if (StringUtils.isNotEmpty(newDataInfo)) {
+                                                newDataInfo = newDataInfo + "," + lastmin + ":" + nowMax;
+                                            } else {
+                                                newDataInfo = lastmin + ":" + nowMax;
+                                            }
+                                        } else {
+                                            newDataInfo = newDataInfo + "," + nowMin + ":" + nowMax;
+                                        }
+                                    }
+                                }
+                                dataInfo = newDataInfo;
+                            }
+                            rowData[k + 2 + i] = dataInfo;
+                        }
+                    }
+
+                    data.text(textInfo.replaceAll(" ", ""));
+                    if (textInfo.indexOf("□") < 0 && !textInfo.isEmpty() && !(textInfo.equals("/") && textInfo.length() < 2) && !(textInfo.indexOf("年") >= 0 && textInfo.indexOf("月") >= 0 && textInfo.indexOf("日") >= 0) && !textInfo.equals("—") && !textInfo.equals("-")) {  // 标题区域
+                        Map<String, String> dataInfo = new HashMap<String, String>();
+                        dataInfo.put("name", textInfo);
+                        dataInfo.put("x1", x1 + "");
+                        dataInfo.put("x2", x2 + "");
+                        dataInfo.put("y1", y1 + "");
+                        dataInfo.put("y2", y2 + "");
+                        dataInfo.put("xytype", xy_type + "");
+                        if (textInfo.indexOf("/") < 0 || (textInfo.indexOf("/") >= 0 && textInfo.length() > 1)) { // 带/为分割数据
+                            zikey.add(dataInfo);
+                        }
+                    } else { //空行
+                        List<Map<String, String>> left = new ArrayList<>();
+                        List<Map<String, String>> top = new ArrayList<>();
+                        for (int k = 0; k < zikey.size(); k++) {
+                            String name = zikey.get(k).get("name");
+                            int xx1 = Integer.parseInt(zikey.get(k).get("x1"));
+                            int xx2 = Integer.parseInt(zikey.get(k).get("x2"));
+                            int yy1 = Integer.parseInt(zikey.get(k).get("y1"));
+                            int yy2 = Integer.parseInt(zikey.get(k).get("y2"));
+                            int xytype2 = Integer.parseInt(zikey.get(k).get("xytype"));
+
+                            // 左匹配
+                            if (yy1 <= y1 && yy2 >= y2 && xx2 < x1 && xytype2 == xy_type) {
+                                left.add(zikey.get(k));
+                            }
+
+                            //向 上 匹配
+                            if (index_state) {
+                                if (xx1 <= x1 && xx2 >= x2 && yy2 < y1 && xytype2 == xy_type) {
+                                    top.add(zikey.get(k));
+                                }
+                            }
+                        }
+
+                        String inputText = "";
+                        // 特征值赛选 规则
+                        for (int k = 0; k < left.size(); k++) { // 左计算
+                            String name = left.get(k).get("name");
+                            int xx1 = Integer.parseInt(left.get(k).get("x1"));
+                            int xx2 = Integer.parseInt(left.get(k).get("x2"));
+                            int yy1 = Integer.parseInt(left.get(k).get("y1"));
+                            int yy2 = Integer.parseInt(left.get(k).get("y2"));
+
+                            if (!StringUtil.isNumeric(name) && name.length() <= 20) { // 数字不匹配
+                                if (index_state) { // 正向规则匹配
+                                    if (istrue) { // 是否空格等于值
+                                        if (x1 - xx2 <= 1 && y1 == yy2) {
+                                            inputText = name;
+                                        } else {
+                                            inputText += name + "_";
+                                        }
+                                    } else {
+                                        inputText += name + "_";
+                                    }
+                                } else {
+                                    if (x1 - xx2 <= 1 && y1 == yy2) {
+                                        inputText = name;
+                                    }
+                                }
+                            }
+                        }
+
+                        // 特征值赛选 规则
+                        if (top != null && top.size() >= 1) {
+                            for (int k = 0; k < top.size(); k++) { // 向上计算
+                                String name = top.get(k).get("name");
+                                int xx1 = Integer.parseInt(top.get(k).get("x1"));
+                                int xx2 = Integer.parseInt(top.get(k).get("x2"));
+                                int yy1 = Integer.parseInt(top.get(k).get("y1"));
+                                int yy2 = Integer.parseInt(top.get(k).get("y2"));
+                                if (!StringUtil.isNumeric(name) && name.length() <= 20) {
+                                    inputText += name + "_";
+                                }
+                            }
+                        }
+
+                        if (inputText != null && inputText != "" && inputText.indexOf("_") >= 0) {
+                            inputText = inputText.substring(0, inputText.lastIndexOf("_"));
+                        }
+
+                        // 质检表特殊处理匹配
+
+                        String parm = i + "," + j + "," + x1 + "," + x2 + "," + y1 + "," + y2 + ",$event";
+                        // 设置文本信息
+                        ExctabCell exctabCell = new ExctabCell();
+                        if ((textInfo.indexOf("年") >= 0 && textInfo.indexOf("月") >= 0 && textInfo.indexOf("日") >= 0) || inputText.indexOf("日期") >= 0) {
+                            if (inputText.indexOf("日期") >= 0) {
+                                data.empty().append("<el-date-picker type='date' @keyDowns='dateKeydown()' format='YYYY年MM月DD日' value-format='YYYY年MM月DD日' @contextmenu.prevent.native='contextmenuClick(" + parm + ")'  @mouseup.right='RightClick(" + parm + ")' trIndex=" + i + " tdIndex=" + j + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%;' placeholder='" + inputText + "'> </el-date-picker>");
+                            } else if (textInfo.indexOf("年") >= 0 && textInfo.indexOf("月") >= 0 && textInfo.indexOf("日") >= 0) {
+                                if (inputText.indexOf("专业监理工程师") >= 0) {
+                                    inputText = "专业监理工程师_年月日";
+                                } else if (inputText.indexOf("质检工程师") >= 0) {
+                                    inputText = "质检工程师_年月日";
+                                } else {
+                                    inputText = "年月日";
+                                }
+                            }
+                            data.empty().append("<el-date-picker @keyDowns='dateKeydown()'  type='date' format='YYYY年MM月DD日' value-format='YYYY年MM月DD日' @contextmenu.prevent.native='contextmenuClick(" + parm + ")'  @mouseup.right='RightClick(" + parm + ")' trIndex=" + i + " tdIndex=" + j + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%;' placeholder='年月日'> </el-date-picker>");
+                            exctabCell.setTextInfo(inputText);
+                            exctabCell.setExctabId(excelId);
+                            exctabCell.setIsDeleted(0);
+                            exctabCell.setXys(i + "_" + j);
+                            colTitle.add(exctabCell);
+                            data.attr("title", inputText);
+
+                        } else if (textInfo.indexOf("□") >= 0) { //多选框
+                            exctabCell.setTextInfo(inputText);
+                            exctabCell.setExctabId(excelId);
+                            exctabCell.setIsDeleted(0);
+                            exctabCell.setXys(i + "_" + j);
+                            colTitle.add(exctabCell);
+                            data.attr("title", inputText);
+                            // 添加多选框
+
+                            String[] cheText = textInfo.split("□");
+                            JSONArray objs = new JSONArray();
+                            if (cheText != null && cheText.length >= 1) {
+                                int key = 1;
+                                for (String keyval : cheText) {
+                                    JSONObject jsonObject = new JSONObject();
+                                    if (StringUtils.isNotEmpty(keyval)) {
+                                        jsonObject.put("key", key);
+                                        jsonObject.put("name", keyval);
+                                        objs.add(jsonObject);
+                                        keyId += 1;
+                                    }
+                                }
+                            } else {
+                                JSONObject jsonObject = new JSONObject();
+                                jsonObject.put("key", "1");
+                                jsonObject.put("name", "");
+                                objs.add(jsonObject);
+                            }
+
+                            String checkbox = "<hc-form-checkbox-group @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft' @keydown.shift.right='keyupShiftRight' :objs='" + objs + "'  @change='checkboxGroupChange' @contextmenu.prevent.native='contextmenuClick(" + parm + ")'  @mouseup.right='RightClick(" + parm + ")' trIndex=" + i + " tdIndex=" + j + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " placeholder=''> </hc-form-checkbox-group>";
+                            data.empty().append(checkbox);
+
+                        } else {
+
+                            if (index_state) { // 区域内
+                                if (rowspan >= 1 || isText) {
+                                    data.empty().append("<el-input type='textarea' @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft'  @keydown.shift.right='keyupShiftRight'  @contextmenu.prevent.native='contextmenuClick(" + parm + ")'  @mouseup.right='RightClick(" + parm + ")' trIndex=" + i + " tdIndex=" + j + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%;'   :rows=" + rowspan * 2 + " placeholder=''> </el-input>");
+                                } else {
+                                    data.empty().append("<el-input type='text' @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft'  @keydown.shift.right='keyupShiftRight'  @contextmenu.prevent.native='contextmenuClick(" + parm + ")'  @mouseup.right='RightClick(" + parm + ")' trIndex=" + i + " tdIndex=" + j + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%;' placeholder=''> </el-input>");
+                                }
+                            } else if (tabType.equals("100") && i < 2) { //计量特殊添加
+                                data.empty().append("<el-input type='text' @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft'  @keydown.shift.right='keyupShiftRight'  @contextmenu.prevent.native='contextmenuClick(" + parm + ")'  @mouseup.right='RightClick(" + parm + ")' trIndex=" + i + " tdIndex=" + j + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%;' placeholder=''> </el-input>");
+                            } else { // 区域外
+                                if (j == 0) {
+                                    if (colspan == maxCol && i >= 1) {
+                                        if (rowspan >= 1 || isText) {
+                                            data.empty().append("<el-input @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft' @keydown.shift.right='keyupShiftRight' type='textarea'  @contextmenu.prevent.native='contextmenuClick(" + parm + ")'  @mouseup.right='RightClick(" + parm + ")' trIndex=" + i + " tdIndex=" + j + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%;'   :rows=" + rowspan * 2 + " placeholder=''> </el-input>");
+                                        } else {
+                                            data.empty().append("<el-input @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft' @keydown.shift.right='keyupShiftRight' type='text' @contextmenu.prevent.native='contextmenuClick(" + parm + ")'  @mouseup.right='RightClick(" + parm + ")' trIndex=" + i + " tdIndex=" + j + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%;' placeholder=''> </el-input>");
+                                        }
+                                    }
+                                } else {
+                                    Element bforData = tds.get(j - 1);
+                                    if (!bforData.text().isEmpty() || bforData.html().indexOf("hc-form-checkbox-group") >= 0) {
+                                        if (rowspan >= 1 || isText) {
+                                            data.empty().append("<el-input @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft' @keydown.shift.right='keyupShiftRight' type='textarea' @contextmenu.prevent.native='contextmenuClick(" + parm + ")'  @mouseup.right='RightClick(" + parm + ")' trIndex=" + i + " tdIndex=" + j + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%;'   :rows=" + rowspan * 2 + " placeholder=''> </el-input>");
+                                        } else {
+                                            data.empty().append("<el-input @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft'  @keydown.shift.right='keyupShiftRight' type='text' @contextmenu.prevent.native='contextmenuClick(" + parm + ")'  @mouseup.right='RightClick(" + parm + ")' trIndex=" + i + " tdIndex=" + j + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%;' placeholder=''> </el-input>");
+                                        }
+                                    }
+                                }
+                            }
+
+                            if (!inputText.equals("")) {
+                                exctabCell.setExctabId(excelId);
+                                exctabCell.setTextInfo(inputText);
+                                if (inputText.contains("日期") || inputText.contains("年") || inputText.contains("月") || inputText.contains("日")) {
+                                    //日期
+                                    exctabCell.setTextElementType(4);
+                                } else if (inputText.indexOf("签字") >= 0) {
+                                    exctabCell.setTextElementType(6);
+                                } else {
+                                    //字符串
+                                    exctabCell.setTextElementType(1);
+                                }
+
+                                exctabCell.setIsDeleted(0);
+                                exctabCell.setXys(i + "_" + j);
+                                colTitle.add(exctabCell);
+                            }
+                            data.attr("title", inputText);
+                        }
+                    }
+                }
+            }
+        }
+        //System.out.println(zikey);
+        // 去掉重复的数
+        Map<String, String> groupMap2 = colTitle.stream()
+                .collect(Collectors.groupingBy(ExctabCell::getTextInfo, Collectors.mapping(ExctabCell::getXys, Collectors.joining(","))));
+
+        exctabCellService.DeletExcelByTableId(excelId + "");
+
+        List<ExctabCell> colTitle2 = new ArrayList<>();
+        for (String title : groupMap2.keySet()) {
+            ExctabCell exctabCell = new ExctabCell();
+            exctabCell.setExctabId(excelId);
+            exctabCell.setIsDeleted(0);
+            exctabCell.setTextInfo(title);
+            exctabCell.setCreateTime(new Date());
+
+            if (title.contains("日期") || title.contains("年") || title.contains("月") || title.contains("日")) {
+                //日期
+                exctabCell.setTextElementType(4);
+            } else {
+                //字符串
+                exctabCell.setTextElementType(1);
+            }
+
+            exctabCell.setXys(groupMap2.get(title));
+            colTitle2.add(exctabCell);
+        }
+        exctabCellService.saveBatch(colTitle2);
+
+
+        //对excel 的图片进行操作
+        ExcelTab exceltab = excelTabService.getById(excelId);
+        if (exceltab != null) {
+            // 获取excle 的数据
+            String fileUrl = exceltab.getFileUrl();
+            InputStream ossInputStream = CommonUtil.getOSSInputStream(fileUrl);
+            Workbook wb = new Workbook();
+            wb.loadFromMHtml(ossInputStream);
+            Worksheet sheet = wb.getWorksheets().get(0);
+            PicturesCollection pictures = sheet.getPictures();
+            if (pictures != null && pictures.size() >= 1) {
+                for (int i = 0; i < pictures.size(); i++) {
+                    ExcelPicture pic = pictures.get(i);
+                    int x = pic.getLeftColumn();
+                    int y = pic.getBottomRow();
+                    Elements select = doc.select("el-input[x1=" + x + "][y1=" + y + "]");
+                    System.out.println("xx=--" + x);
+                    System.out.println("yy=--" + y);
+                    if (select != null && select.size() >= 1) {
+                        Element element = select.get(0);
+                        Element elementP = element.parent();
+                        element.remove();
+                        Element imgele = imgs.get(i);
+                        imgele.removeAttr("class");
+                        elementP.append(imgele.toString());
+                    }
+                }
+            }
+
+            ossInputStream.close();
+        }
+        // 移除图片
+        imgs.remove();
+        // 保存
+        exceltab.setIsDeleted(8);
+        excelTabService.saveOrUpdate(exceltab);
+        File writefile = new File(thmlUrl);
+        FileUtil.writeToFile(writefile, doc.html(), Boolean.parseBoolean("UTF-8"));
+    }
+
+    //计算区域坐标
+    public static String getTrInfo(Elements tds, Map<String, String> styleMap, boolean index_state, Integer xy_type, int maxCol, int y, List<Map<String, String>> zikey) {
+
+        int x_width = 0;
+        int y_width = 0;
+        int text_width = 0;
+        int width = 0;
+
+        int null_count = 0;
+        int val_count = 0;
+
+        boolean istrue = true;
+
+        // 上 tr 长度
+
+        List<Map<String, String>> maxList = zikey.stream().filter(map -> Integer.parseInt(map.get("y1")) <= y && y <= Integer.parseInt(map.get("y2"))).collect(Collectors.toList());
+
+        int top1_max = 0;
+        if (maxList != null && maxList.size() >= 1) {
+            top1_max = maxList.stream().mapToInt(m -> Integer.parseInt(m.get("x2"))).max().getAsInt();
+        }
+
+
+        //区域计算
+        for (int j = 0; j < tds.size(); j++) {
+            Element data = tds.get(j);
+            String keyId = data.attr("class");
+            int colspan = data.attr("COLSPAN").equals("") ? 1 : Integer.parseInt(data.attr("COLSPAN"));
+            if (colspan == 0) {
+                colspan = data.attr("colspan").equals("") ? 1 : Integer.parseInt(data.attr("colspan"));
+            }
+            String classInfo = styleMap.get(keyId);
+            String textInfo = data.text().trim().replaceAll(" ", "");
+
+            if (classInfo == null) {
+                classInfo = data.attr("style");
+            } else {
+                data.removeAttr("class");
+                data.attr("style", styleMap.get(keyId).replaceAll("break-word", "inherit"));
+            }
+
+            // 计算线开始
+            if (classInfo.indexOf("border-left-style") >= 0 && classInfo.indexOf("border-top-style") >= 0 && classInfo.indexOf("border-right-style") >= 0) {
+                x_width += colspan;
+            }
+
+            // 计算结束
+            if (classInfo.indexOf("border-left-style") < 0 && (classInfo.indexOf("border-top-style") < 0 || classInfo.indexOf("border-top-style") >= 0) && classInfo.indexOf("border-bottom-style") < 0 && classInfo.indexOf("border-right-style") < 0) {
+                y_width += colspan;
+            }
+
+            String name = data.text();
+            if (!name.isEmpty()) {
+                text_width += colspan;
+            }
+            width += colspan;
+
+            if (!textInfo.isEmpty() && !(textInfo.equals("/") && textInfo.length() <= 2) && !(textInfo.indexOf("年") >= 0 && textInfo.indexOf("月") >= 0 && textInfo.indexOf("日") >= 0) && !textInfo.equals("—") && !textInfo.equals("-")) {  // 标题区域
+                val_count++;
+            } else {
+                null_count++;
+            }
+        }
+
+        // 在区域内
+        //  System.out.println(index_state+"——"+y+"__"+x_width);
+
+        if (index_state) {
+            //是否需要改变
+            if (maxCol == y_width) { // 是否结束区域值
+                index_state = false;
+                xy_type += 1;
+            }
+            if (maxCol == text_width && top1_max != text_width) { // 是否区域开始时
+                xy_type += 1;
+            }
+        } else { // 区域外
+            if (maxCol == x_width) {
+                index_state = true;
+                xy_type += 1;
+            }
+        }
+
+        // 空是否等于值的个数
+        istrue = null_count == val_count && width == maxCol;
+        return xy_type + "," + index_state + "," + width + "," + istrue;
+    }
+
+    // 获取解析样式
+    public static Map<String, String> getHtmlStyle(Document doc) {
+        Map<String, String> styleMap = new HashMap<>();
+        Element style = doc.select("style").first();
+        Matcher cssMatcher = Pattern.compile("(\\w+)\\s*[{]([^}]+)[}]").matcher(style.html());
+        while (cssMatcher.find()) {
+            styleMap.put(cssMatcher.group(1), cssMatcher.group(2));
+        }
+        return styleMap;
+    }
+
     /**
      * 清表生成html
      */
@@ -2066,8 +2666,31 @@ public class ExcelTabController extends BladeController {
                     }
                     // 组装电签设置
                     Elements dqids = table.getElementsByAttribute("dqid");
+                    // 电签组装2
+                    String dqSql = "select e_key,GROUP_CONCAT(DISTINCT concat('*✹',id)) ids from u_sign_key_role_info where tab_en_name='" + tableNode.getInitTableName() + "' GROUP BY e_key";
+                    List<Map<String, Object>> mapList = jdbcTemplate.queryForList(dqSql);
+                    if(mapList!=null && mapList.size()>0){
+                        for(Map<String, Object> map : mapList) {
+                            Elements elementsBy = table.getElementsByAttributeValueStarting("keyname", map.get("e_key") + "_");
+                            if(elementsBy!=null && elementsBy.size()>0){
+                                for(Element element : elementsBy){
+                                    String dqIds = (String) map.get("ids");
+                                    dqIds = dqIds.replace(",","");
+                                    dqIds = dqIds.substring(1);
+                                    element.attr("sign_type", dqIds);
+                                    dqids.add(element);
+                                }
+                            }
+
+                        }
+                    }
                     for (Element element : dqids) {
-                        String dqid = element.attr("dqid");
+                        String dqid="";
+                        if(element.hasAttr("sign_type")){
+                            dqid = element.attr("sign_type");
+                        }else{
+                            dqid = element.attr("dqid");
+                        }
                         Elements x11 = element.getElementsByAttribute("x1");
                         if (x11 != null && x11.size() >= 1) {
                             Element element1 = x11.get(x11.size() - 1);
@@ -2077,6 +2700,10 @@ public class ExcelTabController extends BladeController {
                             CellRange cellRange = sheet.getCellRange(y1, x1);
                             if (cellRange != null) {
                                 // 创建字体
+                                String text = cellRange.getText();
+                                if (StringUtil.hasText(text)) {
+                                    dqid = text + "*" + dqid;
+                                }
                                 cellRange.setText(dqid);
                                 cellRange.getCellStyle().getExcelFont().setSize(1);
                                 cellRange.getCellStyle().getExcelFont().setColor(Color.WHITE);

+ 25 - 6
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/TextdictInfoController.java

@@ -35,14 +35,19 @@ import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.mp.support.Condition;
 import org.springblade.core.mp.support.Query;
 import org.springblade.core.redis.cache.BladeRedis;
+import org.springblade.core.secure.BladeUser;
+import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.secure.utils.SecureUtil;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.*;
+import org.springblade.manager.entity.DqOperationLog;
 import org.springblade.manager.entity.TextdictInfo;
 import org.springblade.manager.entity.WbsTreeContract;
 import org.springblade.manager.entity.WbsTreePrivate;
 import org.springblade.manager.mapper.WbsTreePrivateMapper;
+import org.springblade.manager.service.IDqOperationLogService;
 import org.springblade.manager.service.ITextdictInfoService;
+import org.springblade.manager.service.impl.DqOperationLogServiceImpl;
 import org.springblade.manager.service.impl.WbsTreeContractServiceImpl;
 import org.springblade.manager.utils.ExcelInfoUtils;
 import org.springblade.manager.utils.FileUtils;
@@ -58,10 +63,7 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.stream.Collectors;
 
 /**
@@ -81,6 +83,7 @@ public class TextdictInfoController extends BladeController {
     private final WbsTreeContractServiceImpl wbsTreeContractService;
     private final BladeRedis bladeRedis;
     private final JdbcTemplate jdbcTemplate;
+    private final IDqOperationLogService dqOperationLogService;
 
     /**
      * 详情
@@ -237,9 +240,14 @@ public class TextdictInfoController extends BladeController {
             File writeFile = new File(wbsTreePrivate.getHtmlUrl());
             FileUtil.writeToFile(writeFile, doc.html(), Boolean.parseBoolean("UTF-8"));
         }
-
         //批量删除
         delIds.add(ids);
+        if (textdictInfo.getType() == 6 || textdictInfo.getType() == 2) {
+            JSONObject param = new JSONObject();
+            param.put("ids", ids);
+            param.put("tabId", tabId);
+            dqOperationLogService.save(new DqOperationLog(wbsTreePrivate, AuthUtil.getUser(), String.join( ",", delIds), 2,param.toJSONString(), JSON.toJSONString(query), ""));
+        }
         textdictInfoService.getBaseMapper().deleteBatchIds(delIds);
 
         return R.success("删除成功");
@@ -461,6 +469,8 @@ public class TextdictInfoController extends BladeController {
         String ids = StringUtils.join(pKeyIds, ",");
 
         //删除历史数据
+        String querySql = "select * from m_textdict_info where (tab_id in(SELECT p_key_id from m_wbs_tree_private where project_id='"+wbsTreePrivate.getProjectId()+"' and excel_id='"+wbsTreePrivate.getExcelId()+"' and type=2 and is_deleted=0) or (excel_id="+wbsTreePrivate.getExcelId()+" AND project_id='"+wbsTreePrivate.getProjectId()+"')) and project_id="+wbsTreePrivate.getProjectId()+" and type in(2,6) ";
+        List<TextdictInfo> oldTextdictInfos = jdbcTemplate.query(querySql, new BeanPropertyRowMapper<>(TextdictInfo.class));
         String delSql = "delete from m_textdict_info where (tab_id in(SELECT p_key_id from m_wbs_tree_private where project_id='"+wbsTreePrivate.getProjectId()+"' and excel_id='"+wbsTreePrivate.getExcelId()+"' and type=2 and is_deleted=0) or (excel_id="+wbsTreePrivate.getExcelId()+" AND project_id='"+wbsTreePrivate.getProjectId()+"')) and project_id="+wbsTreePrivate.getProjectId()+" and type in(2,6) ";
         jdbcTemplate.execute(delSql);
 
@@ -468,6 +478,8 @@ public class TextdictInfoController extends BladeController {
         Map<String,String> keyMap = new HashMap<>();
 
         // ------- 查询数据库是否存在 该该电签信息 ---------
+        StringBuilder dqIds = new StringBuilder();
+        List<TextdictInfo> newTextDictInfos = new ArrayList<>();
         for (int i = 0; i < jsonArray.size(); i++) {
             JSONObject jsonObject = jsonArray.getJSONObject(i);
             TextdictInfo textdictInfo = new TextdictInfo();
@@ -514,6 +526,8 @@ public class TextdictInfoController extends BladeController {
             }else{
                 textdictInfoService.save(textdictInfo);
             }
+            newTextDictInfos.add(textdictInfo);
+            dqIds.append(textdictInfo.getId()).append( ",");
             String dqId = "";
             if(keyMap.containsKey(keky)){
                 dqId = keyMap.get(keky)+"||"+textdictInfo.getId();
@@ -557,7 +571,12 @@ public class TextdictInfoController extends BladeController {
             String updateSqlC = "update m_wbs_tree_contract set html_url = '" + replace + "' where p_key_id in (" + cPkeyIdsStr + ") and project_id="+wbsTreePrivate.getProjectId()+"";
             jdbcTemplate.execute(updateSqlC);
         }
-
+        BladeUser user = AuthUtil.getUser();
+        DqOperationLog log = new DqOperationLog(wbsTreePrivate, user, "", 1, dataInfo.toJSONString(), JSON.toJSONString(oldTextdictInfos), JSON.toJSONString(newTextDictInfos));
+        if (dqIds.length() > 1) {
+            log.setBusinessId(dqIds.deleteCharAt(dqIds.length() - 1).toString());
+        }
+        dqOperationLogService.save(log);
         bladeRedis.set("save-eVis-lock:" + SecureUtil.getUserId(), "1");
         bladeRedis.expire("save-eVis-lock:" + SecureUtil.getUserId(), 3);
 

+ 8 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/DqOperationLogMapper.java

@@ -0,0 +1,8 @@
+package org.springblade.manager.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.springblade.manager.entity.DqOperationLog;
+import org.springblade.manager.entity.FormulaBase;
+
+public interface DqOperationLogMapper extends BaseMapper<DqOperationLog> {
+}

+ 25 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/DqOperationLogMapper.xml

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.springblade.manager.mapper.DqOperationLogMapper">
+
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="resultMap" type="org.springblade.manager.entity.DqOperationLog">
+        <result column="id" property="id"/>
+        <result column="create_time" property="createTime"/>
+        <result column="create_user" property="createUser"/>
+        <result column="create_dept" property="createDept"/>
+        <result column="update_user" property="updateUser"/>
+        <result column="update_time" property="updateTime"/>
+        <result column="status" property="status"/>
+        <result column="is_deleted" property="isDeleted"/>
+        <result column="project_id" property="projectId"/>
+        <result column="node_id" property="nodeId"/>
+        <result column="operation_type" property="operationType"/>
+        <result column="operation_content" property="operationContent"/>
+        <result column="business_id" property="businessId"/>
+        <result column="old_content" property="oldContent"/>
+        <result column="new_content" property="newContent"/>
+    </resultMap>
+
+</mapper>

+ 2 - 2
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/TextdictInfoMapper.xml

@@ -73,8 +73,8 @@
     </select>
     <select id="selectTextDictInfoByIdAndColKeyAndColName" resultMap="textdictInfoVoResultMap">
         select * from m_textdict_info where is_deleted = 0
-        <foreach collection="list" item="item" separator="," open=" and (id,col_key,col_name) in ( " close=")">
-            (#{item.id},#{item.colKey},#{item.colName})
+        <foreach collection="list" item="item" separator="," open=" and (id,col_key) in ( " close=")">
+            (#{item.id},#{item.colKey})
         </foreach>
     </select>
     <update id="updateHtmlUrl">

+ 12 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/IDqOperationLogService.java

@@ -0,0 +1,12 @@
+package org.springblade.manager.service;
+
+import org.springblade.core.mp.base.BaseService;
+import org.springblade.manager.entity.*;
+
+
+/**
+ * @author yangyj
+ */
+public interface IDqOperationLogService extends BaseService<DqOperationLog> {
+
+}

+ 13 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/DqOperationLogServiceImpl.java

@@ -0,0 +1,13 @@
+package org.springblade.manager.service.impl;
+
+import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springblade.manager.entity.DqOperationLog;
+import org.springblade.manager.mapper.DqOperationLogMapper;
+import org.springblade.manager.service.IDqOperationLogService;
+import org.springframework.stereotype.Service;
+
+
+@Service
+public class DqOperationLogServiceImpl extends BaseServiceImpl<DqOperationLogMapper, DqOperationLog> implements IDqOperationLogService {
+
+}

+ 144 - 87
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java

@@ -741,6 +741,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
 
             //参数
             LinkedHashMap<String, String> dataMap2 = tableInfo.getDataMap();
+            updateFieldLength(tabName, dataMap2);
             for (String key : dataMap2.keySet()) {
                 keySql.append(", ").append(key);
                 valSql.append(", '").append(dataMap2.get(key)).append("'");
@@ -1112,7 +1113,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                         for (TableInfo tableInfo : tableInfoList) {
                             //获取字段信息
                             LinkedHashMap<String, String> dataMap2 = tableInfo.getDataMap();
-
+                            updateFieldLength(table.getTabEnName(),dataMap2);
                             //拼接SQL
                             StringBuilder sql = new StringBuilder("INSERT INTO " + table.getTabEnName()),
                                     keySql = new StringBuilder("id, group_id"),
@@ -1240,9 +1241,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                     String delSql = "delete from " + tabName + " where p_key_id=" + tableInfo.getPkeyId();
                     String sqlInfo = "";
                     LinkedHashMap<String, String> dataMap2 = tableInfo.getDataMap();
-                    if (!updateFieldLength(tabName, dataMap2)) {
-                        throw new ServiceException("字段长度超出限制, 系统无法进行自增,请前往后台管理系统手动设置");
-                    }
+                    updateFieldLength(tabName, dataMap2);
                     /*检查发现有p_key_id缺失的情况,导致表单数据丢失,所以强制覆盖*/
                     dataMap2.put("p_key_id", tableInfo.getPkeyId());
                     //统计保存的字段
@@ -1353,17 +1352,14 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
        // return R.success(fileName1);
     }
 
-    public boolean updateFieldLength(String tableName, Map<String, String> fieldNameAndLengthMap) {
+    public void updateFieldLength(String tableName, Map<String, String> fieldNameAndLengthMap) {
         if (fieldNameAndLengthMap == null || fieldNameAndLengthMap.isEmpty()) {
-            return true;
+            return;
         }
-        fieldNameAndLengthMap.remove("id");
-        fieldNameAndLengthMap.remove("p_key_id");
-        fieldNameAndLengthMap.remove("group_id");
-        if (fieldNameAndLengthMap.isEmpty()) {
-            return true;
+        String fields = fieldNameAndLengthMap.keySet().stream().filter(key -> !key.equals("id") && !key.equals("p_key_id") && !key.equals("group_id")).map(key -> "'" + key + "'").collect(Collectors.joining(","));
+        if (fields.isEmpty()) {
+            return;
         }
-        String fields = fieldNameAndLengthMap.keySet().stream().map(key -> "'" + key + "'").collect(Collectors.joining(","));
         List<Map<String, Object>> fieldMap = jdbcTemplate.queryForList("select distinct COLUMN_NAME as fieldName, CHARACTER_MAXIMUM_LENGTH as fieldLength from information_schema.COLUMNS where  TABLE_NAME = '" + tableName +
                 "' and COLUMN_NAME in (" + fields + ")");
         Map<String, Integer> map = fieldMap.stream().collect(toMap(k -> k.get("fieldName") + "", v -> {
@@ -1404,10 +1400,9 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
             } catch (Exception e) {
                 transactionManager1.rollback(transactionStatus);
                 log.error("更新字段长度失败, error: " + e.getMessage());
-                return false;
+                throw new ServiceException("字段长度超出限制, 系统无法进行自增,请前往后台管理系统手动设置");
             }
         }
-        return true;
     }
 
     public String reason(String log) {
@@ -3750,37 +3745,65 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                         }
                     }
                 }
+            }
+        }
+        // 组装电签设置
+        Elements dqids = table.getElementsByAttribute("dqid");
+        // 电签组装2
+        String dqSql = "select e_key,GROUP_CONCAT(DISTINCT concat('*✹',id)) ids from u_sign_key_role_info where tab_en_name='" + wbsTreePrivate.getInitTableName() + "' GROUP BY e_key";
 
-                // 组装电签设置
-                Elements dqids = table.getElementsByAttribute("dqid");
-                for (Element element : dqids) {
-                    String dqid = element.attr("dqid");
-                    Elements x11 = element.getElementsByAttribute("x1");
-                    if (x11 != null && x11.size() >= 1) {
-                        Element element1 = x11.get(x11.size() - 1);
-                        int x1 = Func.toInt(element1.attr("x1"));
-                        int y1 = Func.toInt(element1.attr("y1"));
+        List<Map<String, Object>> mapList = jdbcTemplate.queryForList(dqSql);
 
-                        Row row = sheet.getRow(y1 - 1);
-                        if (row != null) {
-                            Cell cell = row.getCell(x1 - 1);
-                            if (cell != null || ObjectUtils.isNotEmpty(cell)) {
-                                short fontIndex = cell.getCellStyle().getFontIndex();
-                                Font oldfontAt = workbook.getFontAt(fontIndex);
-                                Font redFont = workbook.createFont();
-                                redFont.setColor(IndexedColors.WHITE.getIndex()); //设置字体颜色
-                                redFont.setFontHeightInPoints(Short.valueOf("1"));//设置字体大小
-                                redFont.setFontName(oldfontAt.getFontName());//设置字体
-                                String CellValue = cell.getStringCellValue().trim();
+        if(mapList!=null && mapList.size()>0){
+            for(Map<String, Object> map : mapList) {
+                Elements elementsBy = table.getElementsByAttributeValueStarting("keyname", map.get("e_key") + "_");
+                if(elementsBy!=null && elementsBy.size()>0){
+                    for(Element element : elementsBy){
+                        String ids = (String) map.get("ids");
+                        ids = ids.replace(",","");
+                        ids = ids.substring(1);
+                        element.attr("sign_type", ids);
+                        dqids.add(element);
+                    }
+                }
 
-                                CellStyle newStyle = workbook.createCellStyle(); //创建单元格样式
-                                newStyle.cloneStyleFrom(cell.getCellStyle());
-                                newStyle.setFont(redFont);
-                                newStyle.setShrinkToFit(true);
-                                cell.setCellStyle(newStyle);
-                                cell.setCellValue(dqid);
+            }
+        }
+        for (Element element : dqids) {
+            String dqid="";
+            if(element.hasAttr("sign_type")){
+                dqid = element.attr("sign_type");
+            }else{
+                dqid = element.attr("dqid");
+            }
+            Elements x11 = element.getElementsByAttribute("x1");
+            if (x11 != null && x11.size() >= 1) {
+                Element element1 = x11.get(x11.size() - 1);
+                int x1 = Func.toInt(element1.attr("x1"));
+                int y1 = Func.toInt(element1.attr("y1"));
+
+                Row row = sheet.getRow(y1 - 1);
+                if (row != null) {
+                    Cell cell = row.getCell(x1 - 1);
+                    if (cell != null || ObjectUtils.isNotEmpty(cell)) {
+                        short fontIndex = cell.getCellStyle().getFontIndex();
+                        Font oldfontAt = workbook.getFontAt(fontIndex);
+                        Font redFont = workbook.createFont();
+                        redFont.setColor(IndexedColors.WHITE.getIndex()); //设置字体颜色
+                        redFont.setFontHeightInPoints(Short.valueOf("1"));//设置字体大小
+                        redFont.setFontName(oldfontAt.getFontName());//设置字体
+                        CellStyle newStyle = workbook.createCellStyle(); //创建单元格样式
+                        newStyle.cloneStyleFrom(cell.getCellStyle());
+                        newStyle.setFont(redFont);
+                        newStyle.setShrinkToFit(true);
+                        cell.setCellStyle(newStyle);
+                        if (cell.getCellTypeEnum().equals(CellType.STRING)) {
+                            String value = cell.getStringCellValue();
+                            if (StringUtil.hasText(value) && !value.equals("/")) {
+                                dqid = value + "*" + dqid;
                             }
                         }
+                        cell.setCellValue(dqid);
                     }
                 }
             }
@@ -3970,6 +3993,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                 //新增SQL
                 String sqlInfo = "";
                 LinkedHashMap<String, String> dataMap2 = tableInfo.getDataMap();
+                updateFieldLength(wbsTreePrivate.getInitTableName() ,dataMap2);
                 if(!dataMap2.containsKey("p_key_id")){
                     if(tableInfo.getPkeyId()!=null&&!tableInfo.getPkeyId().equals("")){
                         dataMap2.put("p_key_id",tableInfo.getPkeyId());
@@ -4808,56 +4832,89 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                         }
                     }
                 }
+            }
+        }
+        // 组装电签设置
+        QueryWrapper<TextdictInfo> queryWrapper = new QueryWrapper<>();
+        queryWrapper.select("col_key", "id");
+        queryWrapper.in("type", 2, 6);
+        queryWrapper.eq("tab_id", wbsTreePrivate.getPKeyId());
+        List<TextdictInfo> textdictInfos = textdictInfoService.getBaseMapper().selectList(queryWrapper);
+        String dqSql = "select e_key,GROUP_CONCAT(DISTINCT concat('*✹',id)) ids from u_sign_key_role_info where tab_en_name='" + wbsTreePrivate.getInitTableName() + "' GROUP BY e_key";
+        List<Map<String, Object>> mapList = jdbcTemplate.queryForList(dqSql);
+        if(!mapList.isEmpty()){
+            for(Map<String, Object> map : mapList) {
+                Elements elementsBy = table.getElementsByAttributeValueStarting("keyname", map.get("e_key") + "__");
+                if(elementsBy!=null && !elementsBy.isEmpty()){
+                    String ids = map.get("ids").toString();
+                    ids = ids.replace(",","");
+                    String[] split = ids.split("\\*✹");
+                    for(Element element : elementsBy){
+                        for (String s : split) {
+                            if (s.isEmpty()) {
+                                continue;
+                            }
+                            try {
+                                TextdictInfo info = new TextdictInfo();
+                                info.setColKey(element.attr("keyname"));
+                                info.setId(Long.parseLong(s));
+                                info.setType(-1);
+                                textdictInfos.add(info);
+                            } catch (Exception e) {
+                                e.printStackTrace();
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        if (textdictInfos != null && !textdictInfos.isEmpty()) {
+            for (TextdictInfo e : textdictInfos) {
+                String key = e.getColKey();
+                String[] keys = key.split("__");
+                String[] trtd = keys[1].split("_");
+                if (Integer.parseInt(trtd[0]) < trs.size()) {
+                    Element ytzData = trs.get(Integer.parseInt(trtd[0]));
+                    if (ytzData != null) {
+                        Elements tdsx = ytzData.select("td");
+                        if (Integer.parseInt(trtd[1]) < tdsx.size()) {
+                            Element data = ytzData.select("td").get(Integer.parseInt(trtd[1]));
+                            if (data.html().contains("el-tooltip")) {
+                                data = data.children().get(0);
+                            }
 
-                // 组装电签设置
-                QueryWrapper<TextdictInfo> queryWrapper = new QueryWrapper<>();
-                queryWrapper.select("col_key", "id");
-                queryWrapper.in("type", 2, 6);
-                queryWrapper.eq("tab_id", wbsTreePrivate.getPKeyId());
-
-                List<TextdictInfo> textdictInfos = textdictInfoService.getBaseMapper().selectList(queryWrapper);
-                if (textdictInfos != null && !textdictInfos.isEmpty()) {
-                    for (TextdictInfo e : textdictInfos) {
-                        String key = e.getColKey();
-                        String[] keys = key.split("__");
-                        String[] trtd = keys[1].split("_");
-                        if (Integer.parseInt(trtd[0]) < trs.size()) {
-                            Element ytzData = trs.get(Integer.parseInt(trtd[0]));
-                            if (ytzData != null) {
-                                Elements tdsx = ytzData.select("td");
-                                if (Integer.parseInt(trtd[1]) < tdsx.size()) {
-                                    Element data = ytzData.select("td").get(Integer.parseInt(trtd[1]));
-                                    if (data.html().contains("el-tooltip")) {
-                                        data = data.children().get(0);
-                                    }
-
-                                    int x1 = Integer.parseInt(data.children().get(0).attr("x1"));
-                                    if (x1 == 0) {
-                                        x1 = 1;
+                            int x1 = Integer.parseInt(data.children().get(0).attr("x1"));
+                            if (x1 == 0) {
+                                x1 = 1;
+                            }
+                            int y1 = Integer.parseInt(data.children().get(0).attr("y1"));
+
+                            Row row = sheet.getRow(y1 - 1);
+                            if (row != null) {
+                                Cell cell = sheet.getRow(y1 - 1).getCell(x1 - 1);
+                                if (cell != null) {
+                                    short fontIndex = cell.getCellStyle().getFontIndex();
+                                    Font oldfontAt = workbook.getFontAt(fontIndex);
+
+                                    Font redFont = workbook.createFont();
+                                    redFont.setColor(IndexedColors.WHITE.getIndex()); //设置字体颜色
+                                    redFont.setFontHeightInPoints(Short.valueOf("1"));//设置字体大小
+                                    redFont.setFontName(oldfontAt.getFontName());//设置字体
+
+                                    CellStyle newStyle = workbook.createCellStyle(); //创建单元格样式
+                                    newStyle.cloneStyleFrom(cell.getCellStyle());
+                                    newStyle.setFont(redFont);
+                                    cell.setCellStyle(newStyle);
+                                    String id = e.getId() + "";
+                                    if (e.getType() != null && e.getType() == -1) {
+                                        id = "✹" + id;
                                     }
-                                    int y1 = Integer.parseInt(data.children().get(0).attr("y1"));
-
-                                    Row row = sheet.getRow(y1 - 1);
-                                    if (row != null) {
-                                        Cell cell = sheet.getRow(y1 - 1).getCell(x1 - 1);
-                                        if (cell != null) {
-                                            short fontIndex = cell.getCellStyle().getFontIndex();
-                                            Font oldfontAt = workbook.getFontAt(fontIndex);
-
-                                            Font redFont = workbook.createFont();
-                                            redFont.setColor(IndexedColors.WHITE.getIndex()); //设置字体颜色
-                                            redFont.setFontHeightInPoints(Short.valueOf("1"));//设置字体大小
-                                            redFont.setFontName(oldfontAt.getFontName());//设置字体
-
-                                            CellStyle newStyle = workbook.createCellStyle(); //创建单元格样式
-                                            newStyle.cloneStyleFrom(cell.getCellStyle());
-                                            newStyle.setFont(redFont);
-                                            cell.setCellStyle(newStyle);
-                                            cell.setCellValue(e.getId() + "");
-                                        } else {
-                                            ObjectUtils.isNotEmpty(cell);
-                                        }
+                                    if (cell.getCellTypeEnum() == CellType.STRING && StringUtil.hasText(cell.getStringCellValue())) {
+                                        id = cell.getStringCellValue() + "*" + id;
                                     }
+                                    cell.setCellValue(id);
+                                } else {
+                                    ObjectUtils.isNotEmpty(cell);
                                 }
                             }
                         }

+ 121 - 31
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java

@@ -7,7 +7,6 @@ import cn.hutool.core.util.HashUtil;
 import cn.hutool.log.StaticLog;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
-import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
@@ -22,17 +21,14 @@ import lombok.RequiredArgsConstructor;
 import org.apache.poi.ss.usermodel.*;
 import org.apache.poi.ss.util.CellReference;
 import org.apache.poi.util.IOUtils;
-import org.apache.poi.xssf.usermodel.XSSFRichTextString;
 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;
 import org.springblade.common.constant.CommonConstant;
-import org.springblade.common.constant.MeasurementStorage;
 import org.springblade.common.utils.BaseUtils;
 import org.springblade.common.utils.CommonUtil;
 import org.springblade.common.utils.SnowFlakeUtil;
-import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.mp.base.BaseEntity;
 import org.springblade.core.mp.base.BaseServiceImpl;
 import org.springblade.core.mp.support.Condition;
@@ -92,8 +88,6 @@ import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 import java.util.stream.Stream;
 
-import static org.springblade.manager.utils.TableCoordinates.*;
-
 /**
  * @author yangyj
  * @Date 2022/6/9 14:29
@@ -2501,7 +2495,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
         String sql = "Select * from s_contract_meter_period where contract_id=" + contractId + " and is_deleted=0" + " order by start_date";
         List<ContractMeterPeriod> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(ContractMeterPeriod.class));
         //获取所有excel报表源数据
-        String sqlForExcel = "SELECT p.p_key_id,e.name,e.id,p.html_url,e.file_url FROM m_wbs_tree_private as p LEFT JOIN m_excel_tab as e on p.excel_id=e.id where p.wbs_type=3 AND p.is_deleted=0 AND p.type=2" + " and p.project_id=" + projectId;
+        String sqlForExcel = "SELECT p.p_key_id,e.name,e.id,p.html_url,e.file_url,p.init_table_name as tabName FROM m_wbs_tree_private as p LEFT JOIN m_excel_tab as e on p.excel_id=e.id where p.wbs_type=3 AND p.is_deleted=0 AND p.type=2" + " and p.project_id=" + projectId;
         List<ExcelTabVo1> excelTabs = jdbcTemplate.query(sqlForExcel, new BeanPropertyRowMapper<>(ExcelTabVo1.class));
         ArrayList<ReportResult> reportResults = new ArrayList<>();
         //中期支付报表封面
@@ -2547,25 +2541,25 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
         String htmlUrl6 = excel6.get().getHtmlUrl();
         Long pKeyId6 = excel6.get().getPKeyId();
         // 获取中期支付报表封面的pdfurl
-        ReportResult CoverOfMidtermPaymentReportPDF = getCoverOfMidtermPaymentReportPDF(url, contractId, periodId, htmlUrl, projectName, list, pKeyId);
+        ReportResult CoverOfMidtermPaymentReportPDF = getCoverOfMidtermPaymentReportPDF(url, contractId, periodId, htmlUrl, projectName, list, pKeyId, excel.get().getTabName());
 
         //获取中间支付审核表的pdfurl
-        ReportResult intermediatePaymentPDF = getIntermediatePaymentPDF(url1, contractId, periodId, list, redisId, htmlUrl1, blReserveFundsRatioNew, projectName, changeMoneyNew, pKeyId1);
+        ReportResult intermediatePaymentPDF = getIntermediatePaymentPDF(url1, contractId, periodId, list, redisId, htmlUrl1, blReserveFundsRatioNew, projectName, changeMoneyNew, pKeyId1, excel1.get().getTabName());
 
         //获取补助款申请支付审核表pdfUrl
-        ReportResult subsidyApplicationPaymentReviewPDF = getSubsidyApplicationPaymentReviewPDF(url2, contractId, periodId, list, htmlUrl2, blReserveFundsRatioNew, projectName, projectId, reportId, pKeyId2);
+        ReportResult subsidyApplicationPaymentReviewPDF = getSubsidyApplicationPaymentReviewPDF(url2, contractId, periodId, list, htmlUrl2, blReserveFundsRatioNew, projectName, projectId, reportId, pKeyId2,excel2.get().getTabName());
 
         //获取中间计量支付证书pdfUrl
-        ReportResult intermediateMeasurementPaymentCertificatePDF = getIntermediateMeasurementPaymentCertificatePDF(url3, contractId, periodId, list, htmlUrl3, blReserveFundsRatioNew, projectName, pKeyId3);
+        ReportResult intermediateMeasurementPaymentCertificatePDF = getIntermediateMeasurementPaymentCertificatePDF(url3, contractId, periodId, list, htmlUrl3, blReserveFundsRatioNew, projectName, pKeyId3,excel3.get().getTabName());
 
         //获取清单支付报表PDF
-        ReportResult inventoryPayReportPDF = getInventoryPayReportPDF(url6, contractId, periodId, projectId, list, redisId, htmlUrl6, pKeyId6);
+        ReportResult inventoryPayReportPDF = getInventoryPayReportPDF(url6, contractId, periodId, projectId, list, redisId, htmlUrl6, pKeyId6, excel6.get().getTabName());
 
         //获取工程支付月报pdfUrl
-        ReportResult monthlyReportPDF = getMonthlyReportPDF(url5, reportId, contractId, periodId, projectId, list, redisId, htmlUrl5, pKeyId5);
+        ReportResult monthlyReportPDF = getMonthlyReportPDF(url5, reportId, contractId, periodId, projectId, list, redisId, htmlUrl5, pKeyId5, excel5.get().getTabName());
 
         //获取中间支付申请表pdfUrl
-        ReportResult intermediateApplyPDF = getIntermediateApplyPDF(url4, periodId, projectId, htmlUrl4, projectName, contractId, pKeyId4);
+        ReportResult intermediateApplyPDF = getIntermediateApplyPDF(url4, periodId, projectId, htmlUrl4, projectName, contractId, pKeyId4, excel4.get().getTabName());
 
         reportResults.add(CoverOfMidtermPaymentReportPDF);
         reportResults.add(intermediatePaymentPDF);
@@ -2583,7 +2577,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
     /**
      * 中期支付报表封面
      */
-    private ReportResult getCoverOfMidtermPaymentReportPDF(String url, Long contractId, Long periodId, String htmlUrl, String projectName, List<ContractMeterPeriod> list, Long pkeyId) {
+    private ReportResult getCoverOfMidtermPaymentReportPDF(String url, Long contractId, Long periodId, String htmlUrl, String projectName, List<ContractMeterPeriod> list, Long pkeyId, String tabName) {
 
         //获取本期计量期
         String sqlForMeterPeriodById = "SELECT id,period_number,start_date,end_date FROM s_contract_meter_period WHERE id=" + periodId + " and is_deleted = 0 ";
@@ -2634,7 +2628,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                 Cell c10 = getCellByAddress(sheet, "C10");
                 c10.setCellValue(contractInfo.getSupervisionUnitName());
             }
-            dianqian(htmlUrl, sheet, workbook);
+            dianqian(htmlUrl, sheet, workbook, tabName);
             if (!periodId.equals(1867838908899852290L)) {
                 dianqianTime(htmlUrl, sheet, workbook, pkeyId, periodId, contractId);
             }
@@ -2670,7 +2664,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
     }
 
     /*设置电签ID*/
-    public void dianqian(String htmlUrl, Sheet sheet, Workbook workbook) {
+    public void dianqian(String htmlUrl, Sheet sheet, Workbook workbook, String tabName) {
         try {
             InputStream inputStreamByUrl = FileUtils.getInputStreamByUrl(htmlUrl);
             String htmlString = IoUtil.readToString(inputStreamByUrl);
@@ -2678,8 +2672,30 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
             Element table = doc.select("table").first();
             // 组装电签设置
             Elements dqids = table.getElementsByAttribute("dqid");
+            // 电签组装2
+            String dqSql = "select e_key,GROUP_CONCAT(DISTINCT concat('*✹',id)) ids from u_sign_key_role_info where tab_en_name='" + tabName + "' GROUP BY e_key";
+            List<Map<String, Object>> mapList = jdbcTemplate.queryForList(dqSql);
+            if(mapList!=null && mapList.size()>0){
+                for(Map<String, Object> map : mapList) {
+                    Elements elementsBy = table.getElementsByAttributeValueStarting("keyname", map.get("e_key") + "_");
+                    if(elementsBy!=null && elementsBy.size()>0){
+                        for(Element element : elementsBy){
+                            String dqIds = (String) map.get("ids");
+                            dqIds = dqIds.replace(",","");
+                            dqIds = dqIds.substring(1);
+                            element.attr("sign_type", dqIds);
+                            dqids.add(element);
+                        }
+                    }
+                }
+            }
             for (Element element : dqids) {
-                String dqid = element.attr("dqid");
+                String dqid="";
+                if(element.hasAttr("sign_type")){
+                    dqid = element.attr("sign_type");
+                }else{
+                    dqid = element.attr("dqid");
+                }
 
                 int x1 = 0;
                 int y1 = 0;
@@ -2773,7 +2789,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
     /**
      * 中间计量支付证书获取PDFurl
      */
-    private ReportResult getIntermediateMeasurementPaymentCertificatePDF(String url3, Long contractId, Long periodId, List<ContractMeterPeriod> list, String htmlUrl, BigDecimal blReserveFundsRatioNew, String projectName, Long pkeyId) {
+    private ReportResult getIntermediateMeasurementPaymentCertificatePDF(String url3, Long contractId, Long periodId, List<ContractMeterPeriod> list, String htmlUrl, BigDecimal blReserveFundsRatioNew, String projectName, Long pkeyId, String tabName) {
         //判断当前是否是第一期
         Boolean isOnePeriod = false;
         ContractMeterPeriod contractMeterPeriod = list.get(0);
@@ -2854,7 +2870,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
             Cell c3 = getCellByAddress(sheet, "C3");
             c3.setCellValue(projectName);
 
-            dianqian(htmlUrl, sheet, workbook);
+            dianqian(htmlUrl, sheet, workbook, tabName);
             if (!periodId.equals(1867838908899852290L)) {
                 dianqianTime(htmlUrl, sheet, workbook, pkeyId, periodId, contractId);
             }
@@ -2900,7 +2916,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
     /**
      * 补助款申请支付审核表获取PDFurl
      */
-    private ReportResult getSubsidyApplicationPaymentReviewPDF(String url2, Long contractId, Long periodId, List<ContractMeterPeriod> list, String htmlUrl, BigDecimal blReserveFundsRatioNew, String projectName, Long projectId, Long reportId, Long pkeyId) {
+    private ReportResult getSubsidyApplicationPaymentReviewPDF(String url2, Long contractId, Long periodId, List<ContractMeterPeriod> list, String htmlUrl, BigDecimal blReserveFundsRatioNew, String projectName, Long projectId, Long reportId, Long pkeyId, String tabName) {
         //判断当前是否是只有1期计量
         Boolean isOnePeriod = false;
         ContractMeterPeriod contractMeterPeriod = list.get(0);
@@ -3174,7 +3190,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
             Cell a2 = getCellByAddress(sheet, "A2");
             a2.setCellValue(projectName);
             // 电签
-            dianqian(htmlUrl, sheet, workbook);
+            dianqian(htmlUrl, sheet, workbook, tabName);
             if (!periodId.equals(1867838908899852290L)) {
                 dianqianTime(htmlUrl, sheet, workbook, pkeyId, periodId, contractId);
             }
@@ -3214,7 +3230,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
     /**
      * 中间支付审核表获取PDFurl
      */
-    public ReportResult getIntermediatePaymentPDF(String url, Long contractId, Long periodId, List<ContractMeterPeriod> list, Long redisId, String htmlUrl, BigDecimal blReserveFundsRatioNew, String projectName, BigDecimal changeMoneyNew, Long pkeyId) {
+    public ReportResult getIntermediatePaymentPDF(String url, Long contractId, Long periodId, List<ContractMeterPeriod> list, Long redisId, String htmlUrl, BigDecimal blReserveFundsRatioNew, String projectName, BigDecimal changeMoneyNew, Long pkeyId, String tabName) {
         //判断当前是否是只有1期计量
         Boolean isOnePeriod = false;
         ContractMeterPeriod contractMeterPeriod1 = list.get(0);
@@ -3486,7 +3502,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
             //顶部项目名称
             Cell a1 = getCellByAddress(sheet, "A1");
             a1.setCellValue(projectName);
-            dianqian(htmlUrl, sheet, workbook);
+            dianqian(htmlUrl, sheet, workbook, tabName);
             if (!periodId.equals(1867838908899852290L)) {
                 dianqianTime(htmlUrl, sheet, workbook, pkeyId, periodId, contractId);
             }
@@ -3635,9 +3651,10 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
      * 中间支付申请表获取pdfUrl
      *
      * @param url
+     * @param tabName
      * @return
      */
-    public ReportResult getIntermediateApplyPDF(String url, Long periodId, Long projectId, String htmlUrl, String projectName, Long contractId, Long pkeyId) {
+    public ReportResult getIntermediateApplyPDF(String url, Long periodId, Long projectId, String htmlUrl, String projectName, Long contractId, Long pkeyId, String tabName) {
         InputStream modInput = null;
         FileInputStream excelFileInput = null;
         FileOutputStream outputStream = null;
@@ -3647,7 +3664,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
             modInput = CommonUtil.getOSSInputStream(url);
             workbook = WorkbookFactory.create(modInput);
             Sheet sheet = workbook.getSheetAt(0);
-            dianqian(htmlUrl, sheet, workbook);
+            dianqian(htmlUrl, sheet, workbook, tabName);
             if (!periodId.equals(1867838908899852290L)) {
                 dianqianTime(htmlUrl, sheet, workbook, pkeyId, periodId, contractId);
             }
@@ -3714,9 +3731,10 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
      * 工程支付月报获取pdfUrl
      *
      * @param url
+     * @param tabName
      * @return
      */
-    public ReportResult getMonthlyReportPDF(String url, Long reportId, Long contractId, Long periodId, Long projectId, List<ContractMeterPeriod> list, Long redisId, String htmlUrl, Long pkeyId) throws IllegalAccessException {
+    public ReportResult getMonthlyReportPDF(String url, Long reportId, Long contractId, Long periodId, Long projectId, List<ContractMeterPeriod> list, Long redisId, String htmlUrl, Long pkeyId, String tabName) throws IllegalAccessException {
         //获取本期计量期
         String sqlForMeterPeriodById = "SELECT id,period_number,start_date,end_date FROM s_contract_meter_period WHERE id=" + periodId + " and is_deleted = 0 ";
         ContractMeterPeriod contractMeterPeriodNow = jdbcTemplate.queryForObject(sqlForMeterPeriodById, new BeanPropertyRowMapper<>(ContractMeterPeriod.class));
@@ -4169,7 +4187,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                     m_3.setCellValue(formattedDate);
                 }
             }
-            dianqian(htmlUrl, sheet, workbook);
+            dianqian(htmlUrl, sheet, workbook, tabName);
             if (!periodId.equals(1867838908899852290L)) {
                 dianqianTime(htmlUrl, sheet, workbook, pkeyId, periodId, contractId);
             }
@@ -4205,10 +4223,11 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
      * 清单支付报表获取PDF
      *
      * @param url
+     * @param tabName
      * @return
      */
 
-    public ReportResult getInventoryPayReportPDF(String url, Long contractId, Long periodId, Long projectId, List<ContractMeterPeriod> list, Long redisId, String htmlUrl, Long pkeyId) throws FileNotFoundException, IllegalAccessException {
+    public ReportResult getInventoryPayReportPDF(String url, Long contractId, Long periodId, Long projectId, List<ContractMeterPeriod> list, Long redisId, String htmlUrl, Long pkeyId, String tabName) throws FileNotFoundException, IllegalAccessException {
         MiddleMeterApply middleMeterApply = new MiddleMeterApply();
         middleMeterApply.setContractId(contractId);
         middleMeterApply.setContractPeriodId(periodId);
@@ -4577,7 +4596,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                             l4.setCellStyle(cellStyle);
                             l4.setCellValue(contractInfo.getSupervisionUnitName());
                         }
-                        dianqian(htmlUrl, sheet, workbook);
+                        dianqian(htmlUrl, sheet, workbook, tabName);
                         if (!periodId.equals(1867838908899852290L)) {
                             dianqianTime(htmlUrl, sheet, workbook, pkeyId, periodId, contractId);
                         }
@@ -6179,7 +6198,10 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
             String initTableName = nt.getInitTableName();
             Document document = documentMap.get(nt.getInitTableName());
             coordinateMap.put(initTableName, FormulaUtils.getElementExcelCoords(document));
-            eSignMaps.put(initTableName, FormulaUtils.getESignMap(document));
+            Map<String, String> eSignMap = FormulaUtils.getESignMap(document);
+            eSignMaps.put(initTableName, eSignMap);
+            // 电签组装2
+            getSignMapBySignConfig(initTableName, document, eSignMap);
         });
         executionTime.info("坐标信息获取");
         /*额外单元格坐标配置*/
@@ -6235,6 +6257,74 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
         return tec.getReportResults();
     }
 
+    private void getSignMapBySignConfig(String initTableName, Document document, Map<String, String> eSignMap) {
+        String dqSql = "select e_key,GROUP_CONCAT(DISTINCT concat('*✹',id)) ids from u_sign_key_role_info where tab_en_name='" + initTableName + "' GROUP BY e_key";
+        List<Map<String, Object>> mapList = jdbcTemplate.queryForList(dqSql);
+        if(!mapList.isEmpty()){
+            for(Map<String, Object> map : mapList) {
+                Elements elementsBy = document.getElementsByAttributeValueStarting("keyname", map.get("e_key") + "_");
+                if(elementsBy!=null && !elementsBy.isEmpty()){
+                    for(Element element : elementsBy){
+                        String dqIds = (String) map.get("ids");
+                        dqIds = dqIds.replace(",","");
+                        dqIds = dqIds.substring(1);
+                        int x1 = -1,y1 = -1;
+                        try {
+                            if (element.hasAttr("x1") && element.hasAttr("y1")) {
+                                x1 = Integer.parseInt(element.attr("x1"));
+                                y1 = Integer.parseInt(element.attr("y1"));
+                            } else {
+                                if (element.tagName().equals("td")) {
+                                    Elements x11 = element.getElementsByAttribute("x1");
+                                    if (x11 != null && !x11.isEmpty()) {
+                                        x1 = Integer.parseInt(x11.attr("x1"));
+                                    }
+                                    Elements y11 = element.getElementsByAttribute("y1");
+                                    if (y11 != null && !y11.isEmpty()) {
+                                        y1 = Integer.parseInt(y11.attr("y1"));
+                                    }
+                                } else {
+                                    Elements parents = element.parents();
+                                    if (parents != null && !parents.isEmpty()) {
+                                        for (Element parent1 : parents) {
+                                            if (parent1.hasAttr("x1") && parent1.hasAttr("y1")) {
+                                                x1 = Integer.parseInt(parent1.attr("x1"));
+                                                y1 = Integer.parseInt(parent1.attr("y1"));
+                                                break;
+                                            }
+                                            if (parent1.tagName().equals("td")) {
+                                                break;
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        } catch (Exception e) {
+                            log.error("坐标获取异常", e);
+                        }
+                        if (x1 == -1 || y1 == -1) {
+                            String keyname = element.attr("keyname");
+                            String[] split = keyname.split("__");
+                            if (split.length > 1) {
+                                String value = eSignMap.get(y1 + "_" + x1);
+                                if (StringUtil.hasText(value)) {
+                                    dqIds = value + "*" + dqIds;
+                                }
+                                eSignMap.put(split[1], dqIds);
+                            }
+                        } else {
+                            String value = eSignMap.get(y1 + "_" + x1);
+                            if (StringUtil.hasText(value)) {
+                                dqIds = value + "*" + dqIds;
+                            }
+                            eSignMap.put(y1 + "_" + x1, dqIds);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
     public void saveInterimPayCertificateItems(List<InterimPayCertificateItem> items,Long reportId) {
         if (items != null && items.size() > 0) {
             this.certificateItemClient.saveOrUpdate(items,reportId);

+ 2 - 2
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/SignConfigServiceImpl.java

@@ -146,7 +146,7 @@ public class SignConfigServiceImpl extends BaseServiceImpl<SignConfigMapper, Sig
                 }
             }
             List<String> tableIds = signConfigDTO.getTableIds();
-            if (tableIds != null && !tableIds.isEmpty()) {
+            if (tableIds != null && !tableIds.isEmpty() && (signConfigDTO.getTableType() == null || signConfigDTO.getTableType() != 0)) {
                 List<TableInfo> tableInfos = tableInfoService.list(Wrappers.<TableInfo>lambdaQuery().select(TableInfo::getTabChName, TableInfo::getId, TableInfo::getTabType).in(TableInfo::getId, tableIds));
                 if (tableInfos == null || tableInfos.isEmpty()) {
                     throw new ServiceException("获取元素表信息失败");
@@ -170,7 +170,7 @@ public class SignConfigServiceImpl extends BaseServiceImpl<SignConfigMapper, Sig
             transactionTemplate.execute(transactionStatus -> {
                 if (config.getId() !=  null) {
                     this.updateById(config);
-                    if (!signConfigRelationsByTables.isEmpty()) {
+                    if (!signConfigRelationsByTables.isEmpty() || config.getTableType() == 0) {
                         signConfigRelationService.remove(Wrappers.<SignConfigRelation>lambdaQuery().eq(SignConfigRelation::getConfId, config.getId()).eq(SignConfigRelation::getType, 0));
                     }
                     if (!signConfigRelationsByRoles.isEmpty()) {

+ 54 - 23
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/TextdictInfoServiceImpl.java

@@ -101,12 +101,13 @@ public class TextdictInfoServiceImpl extends ServiceImpl<TextdictInfoMapper, Tex
                     List<TextdictInfo> textdictInfos = new ArrayList<>();
                     if(Func.isNotEmpty(dqid) && dqid.size() > 0){
                         textdict = baseMapper.selectTextdictBYIds(dqid,privateInfo.getProjectId());
+                        // 系统推荐方案一:根据dqId、col_key和col_name查询
                         textdict = getTextdictInfoByDqIdAndKeyName(textdict, dqIdMap, keys, textdictInfos);
                     }else {
-                        textdict = new ArrayList<>();
+                        // 系统推荐方法二:根据excel_id, col_key, col_name查询
+                        textdict = getTextDictInfoBySystem(textdictInfo, keys, textdict, doc, privateInfo, dqid);
                     }
                     if (!keys.isEmpty()) {
-                        textdict = getTextDictInfoBySystem(textdictInfo, keys, textdictInfos, textdict, doc, privateInfo, dqid);
                         TextdictInfoVO temp = null;
                         if (textdict != null && !textdict.isEmpty()) {
                             temp = textdict.get(0);
@@ -120,6 +121,7 @@ public class TextdictInfoServiceImpl extends ServiceImpl<TextdictInfoMapper, Tex
                         }
                         // 查询电签库配置
                         List<TextdictInfoVO> textdictConfigList = iSignConfigService.hasSignConfig(privateInfo.getInitTableName(), keys.keySet(), temp);
+                        saveSignTextDictInfo(textdictInfos, textdictConfigList, keys);
                         if (textdict == null || textdict.isEmpty()) {
                             textdict = textdictConfigList;
                         } else {
@@ -157,31 +159,39 @@ public class TextdictInfoServiceImpl extends ServiceImpl<TextdictInfoMapper, Tex
         return page.setRecords(textdict);
     }
 
-    /**
-     * 系统推荐
-     */
-    @Nullable
-    private List<TextdictInfoVO> getTextDictInfoBySystem(TextdictInfoVO textdictInfo, Map<String, String> keys, List<TextdictInfo> textdictInfos, List<TextdictInfoVO> textdict, Document doc, WbsTreePrivate privateInfo, List<String> dqid) {
-        // 根据excel_id 和col_key 查询
-        List<TextdictInfoVO> textdictList= baseMapper.selectTextdictInfoByExcelIdAndColKey(textdictInfo.getExcelId(), keys.keySet());
-        if (textdictList != null) {
-            Map<String, TextdictInfoVO> map = textdictList.stream().filter(vo -> vo.getColName() != null && vo.getColName().equals(keys.get(vo.getColKey()))).collect(Collectors.toMap(vo -> vo.getColKey() + vo.getSigRoleId(), v -> v, (v1, v2) -> v1));
-            textdictList = new ArrayList<>(map.values());
-            if (!textdictInfos.isEmpty()) {
-                // 保存到数据库,从系统推荐中获取roleId
+    private void saveSignTextDictInfo(List<TextdictInfo> textdictInfos, List<TextdictInfoVO> textdictRecommendedList, Map<String, String> keys) {
+        if (!textdictInfos.isEmpty()) {
+            // 保存到数据库,从系统推荐中获取roleId
+            if (textdictRecommendedList != null && !textdictRecommendedList.isEmpty()) {
+                Map<String, TextdictInfoVO> map = textdictRecommendedList.stream().filter(vo -> vo.getColName() != null && vo.getColName().equals(keys.get(vo.getColKey()))).collect(Collectors.toMap(vo -> vo.getColKey() + vo.getSigRoleId(), v -> v, (v1, v2) -> v1));
+                Collection<TextdictInfoVO> values = map.values();
                 Map<String, TextdictInfo> collect = textdictInfos.stream().collect(Collectors.toMap(info -> info.getColKey() + info.getColName(), v -> v, (v1, v2) -> v1));
-                for (TextdictInfoVO vo : textdictList) {
+                for (TextdictInfoVO vo : values) {
                     TextdictInfo info = collect.get(vo.getColKey() + vo.getColName());
                     if (info != null) {
                         vo.setId(info.getId());
                         vo.setProjectId("0");
                         BeanUtil.copyProperties(vo, info);
+                        vo.setIsSystem(2);
                     }
                 }
                 List<TextdictInfo> list = textdictInfos.stream().filter(info -> StringUtil.hasText(info.getSigRoleId())).collect(Collectors.toList());
                 this.saveBatch( list);
             }
         }
+    }
+
+    /**
+     * 系统推荐
+     */
+    @Nullable
+    private List<TextdictInfoVO> getTextDictInfoBySystem(TextdictInfoVO textdictInfo, Map<String, String> keys,  List<TextdictInfoVO> textdict, Document doc, WbsTreePrivate privateInfo, List<String> dqid) {
+        // 根据excel_id 和col_key 查询
+        List<TextdictInfoVO> textdictList= baseMapper.selectTextdictInfoByExcelIdAndColKey(textdictInfo.getExcelId(), keys.keySet());
+        if (textdictList != null) {
+            Map<String, TextdictInfoVO> map = textdictList.stream().filter(vo -> vo.getColName() != null && vo.getColName().equals(keys.get(vo.getColKey()))).collect(Collectors.toMap(vo -> vo.getColKey() + vo.getSigRoleId(), v -> v, (v1, v2) -> v1));
+            textdictList = new ArrayList<>(map.values());
+        }
         if (textdict.isEmpty()) {
             textdict = textdictList;
             if (textdict != null) {
@@ -212,9 +222,10 @@ public class TextdictInfoServiceImpl extends ServiceImpl<TextdictInfoMapper, Tex
         if (textdict == null) {
             textdict = new ArrayList<>();
         }
-        Map<String, TextdictInfoVO> map = textdict.stream().collect(Collectors.toMap(item -> item.getId() + "", v -> v, (v1, v2) -> v2));
+        Map<String, TextdictInfoVO> idsMap = textdict.stream().collect(Collectors.toMap(item -> item.getId() + "", v -> v, (v1, v2) -> v2));
+        Map<String, TextdictInfoVO> colKeyMap = textdict.stream().collect(Collectors.toMap(item -> item.getId() + "", v -> v, (v1, v2) -> v2));
         dqIdMap.forEach((k, v) -> {
-            if (map.containsKey(k)) {
+            if (idsMap.containsKey(k) || colKeyMap.containsKey(v)) {
                 return;
             }
             Long id = null;
@@ -230,16 +241,36 @@ public class TextdictInfoServiceImpl extends ServiceImpl<TextdictInfoMapper, Tex
             TextdictInfo info = new TextdictInfo();
             info.setId(id);
             info.setColKey(v);
-            info.setColName(colName);
             textdictInfos.add(info);
         });
         if (!textdictInfos.isEmpty()) {
             List<TextdictInfoVO> list = baseMapper.selectTextDictInfoByIdAndColKeyAndColName(textdictInfos);
-            Map<String, TextdictInfoVO> voMap = list.stream().collect(Collectors.toMap(item -> item.getId() + item.getColKey() + item.getColName(), item -> item, (v1, v2) -> v1));
-            Collection<TextdictInfoVO> values = voMap.values();
-            values.forEach(item -> item.setIsSystem(2));
-            textdict.addAll(values);
-            textdictInfos.removeIf(item -> voMap.containsKey(item.getId() + item.getColKey() + item.getColName()));
+            Map<String, List<TextdictInfoVO>> voMap = list.stream().collect(Collectors.groupingBy(item -> item.getId() + item.getColKey()));
+            List<TextdictInfoVO> tempList = new ArrayList<>();
+            voMap.forEach((key, values) -> {
+                TextdictInfoVO temp = null;
+                if (values.size() == 1) {
+                    temp = values.get(0);
+                } else {
+                    for (TextdictInfoVO value : values) {
+                        String colName = keys.get(value.getColKey());
+                        if (colName == null || colName.equals(value.getColName())) {
+                            temp = value;
+                            break;
+                        }
+                    }
+                    if (temp == null) {
+                        // 出现次数最多
+                        Map<String, List<TextdictInfoVO>> collect = values.stream().collect(Collectors.groupingBy(TextdictInfoVO::getColName));
+                        temp = collect.entrySet().stream().max(Comparator.comparingInt(entry -> entry.getValue().size())).get().getValue().get(0);
+                    }
+                }
+                temp.setIsSystem(2);
+                tempList.add(temp);
+                colKeyMap.put(temp.getColKey(), temp);
+            });
+            textdict.addAll(tempList);
+            textdictInfos.removeIf(item -> voMap.containsKey(item.getId() + item.getColKey()) || colKeyMap.containsKey(item.getColKey()));
         }
         return textdict;
     }