Forráskód Böngészése

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

lvy 5 napja
szülő
commit
4edd2a008c
24 módosított fájl, 540 hozzáadás és 54 törlés
  1. 1 1
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/dto/AddScanFileDto.java
  2. 2 0
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/entity/ScanFile.java
  3. 2 0
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/vo/ScanFolderVO.java
  4. 2 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/MaterialProgressVO.java
  5. 2 2
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ScanFileController.java
  6. 1 1
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ScanFileMapper.java
  7. 4 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ScanFolderMapper.java
  8. 3 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ScanFolderMapper.xml
  9. 3 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchivesAutoServiceImpl.java
  10. 56 30
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ScanFileServiceImpl.java
  11. 24 4
      blade-service/blade-business/src/main/java/org/springblade/business/controller/MaterialProgressController.java
  12. 1 1
      blade-service/blade-manager/src/main/java/com/jfireel/expression/node/impl/EqualNode.java
  13. 1 1
      blade-service/blade-manager/src/main/java/com/jfireel/expression/node/impl/GtEqNode.java
  14. 1 1
      blade-service/blade-manager/src/main/java/com/jfireel/expression/node/impl/GtNode.java
  15. 1 1
      blade-service/blade-manager/src/main/java/com/jfireel/expression/node/impl/LtEqNode.java
  16. 1 1
      blade-service/blade-manager/src/main/java/com/jfireel/expression/node/impl/LtNode.java
  17. 1 1
      blade-service/blade-manager/src/main/java/com/jfireel/expression/node/impl/NotEqualNode.java
  18. 60 0
      blade-service/blade-manager/src/main/java/com/jfireel/expression/util/ValueUtil.java
  19. 200 1
      blade-service/blade-manager/src/main/java/com/mixsmart/utils/CustomFunction.java
  20. 25 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/bean/SpringContextHolder.java
  21. 8 3
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java
  22. 131 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java
  23. 7 4
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/NodeBaseInfoServiceImpl.java
  24. 3 1
      blade-service/blade-user/src/main/java/org/springblade/system/user/service/impl/UserServiceImpl.java

+ 1 - 1
blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/dto/AddScanFileDto.java

@@ -7,7 +7,7 @@ public class AddScanFileDto {
     private Long projectId;
     private Long contractId;
     private String fileName;
-    private Long forderId;
+    private Long folderId;
     private Integer fileSize;
     private String ossUrl;
     private String responsible;

+ 2 - 0
blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/entity/ScanFile.java

@@ -33,6 +33,8 @@ public class ScanFile {
     private String fileNum;
     @ApiModelProperty(value = "文件题名")
     private String fileName;
+    @ApiModelProperty(value = "文件名")
+    private String fileNameSuffix;
     @ApiModelProperty(value = "文件页数")
     private String fileSize;
     @ApiModelProperty(value = "文件日期")

+ 2 - 0
blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/vo/ScanFolderVO.java

@@ -15,4 +15,6 @@ public class ScanFolderVO extends ScanFolder {
     private Boolean hasChildren;
     @ApiModelProperty(value = "子级节点")
     private List<ScanFolderVO> childs;
+    @ApiModelProperty(value = "是否可以删除")
+    private Boolean isRemove;
 }

+ 2 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/MaterialProgressVO.java

@@ -176,6 +176,8 @@ public class MaterialProgressVO {
         private Integer awaitAmount;
         @ApiModelProperty("已审批数量")
         private Integer approvalAmount;
+        @ApiModelProperty("是否隐藏 0显示1隐藏")
+        private Integer isHide;
 
         public ProcessMaterialStatus(String title, Integer submitAmount, Integer awaitAmount, Integer approvalAmount) {
             this.title = title;

+ 2 - 2
blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ScanFileController.java

@@ -143,13 +143,13 @@ public class ScanFileController {
     }
     @PostMapping("/addScanFile")
     @ApiOperation("新增节点扫描文件")
-    public R addScanFile(List<AddScanFileDto>list){
+    public R addScanFile(@RequestBody List<AddScanFileDto>list){
         return R.status(scanFileService.addScanFile(list));
     }
     @GetMapping("/deleteScanFolder")
     @ApiOperation("删除扫描文件夹")
     @ApiImplicitParam(name = "id", value = "文件夹ID")
-    public R deleteScanFolder(Long id){
+    public R deleteScanFolder(@RequestParam Long id){
         return R.status(scanFileService.deleteScanFolder(id));
     }
     @GetMapping("/getDetil")

+ 1 - 1
blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ScanFileMapper.java

@@ -22,5 +22,5 @@ public interface ScanFileMapper extends BaseMapper<ScanFile> {
 
     IPage<ScanFile> getScanFile(IPage<ScanFile> page, @Param("contractId") Long contractId, @Param("projectId") Long projectId, @Param("folderId") Long folderId,@Param("move")Integer  move);
 
-    void removeScan(@Param("longList") List<Long> longList);
+    void removeScan(@Param("longList") List<Long> longList, @Param("projectId")Long projectId, @Param("contractId")Long contractId);
 }

+ 4 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ScanFolderMapper.java

@@ -4,6 +4,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.apache.ibatis.annotations.Param;
 import org.springblade.archive.entity.ScanFolder;
 
+import java.util.List;
+
 public interface ScanFolderMapper extends BaseMapper<ScanFolder> {
 
     int exists(@Param("projectId") Long projectId, @Param("contractId") Long contractId, @Param("folderName") String folderName);
@@ -12,4 +14,6 @@ public interface ScanFolderMapper extends BaseMapper<ScanFolder> {
 
 
     Long getId(@Param("folderName") String folderName, @Param("contractId") Long contractId, @Param("projectId") Long projectId);
+
+    List<ScanFolder> selectAllChildren(@Param("id") Long id);
 }

+ 3 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ScanFolderMapper.xml

@@ -9,4 +9,7 @@
     <select id="getId" resultType="java.lang.Long">
         select id from scan_folder where project_id = #{projectId} AND contract_id = #{contractId} AND folder_name = #{folderName}
     </select>
+    <select id="selectAllChildren" resultType="org.springblade.archive.entity.ScanFolder">
+        CALL GetScanFolderChildren(#{id})
+    </select>
 </mapper>

+ 3 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchivesAutoServiceImpl.java

@@ -5373,6 +5373,7 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 		//String url="D:\\AutoPdf\\";
 		//List<Long> idsList=Func.toLongList(ids);
 		List<ArchivesAuto> archivesAutoList = this.list(new LambdaQueryWrapper<ArchivesAuto>().in(ArchivesAuto::getId, idsList));
+		this.update(Wrappers.<ArchivesAuto>lambdaUpdate().set(ArchivesAuto::getColourStatus, 2).in(ArchivesAuto::getId, idsList));
 		for (ArchivesAuto auto : archivesAutoList) {
 			String sql=" select * from u_archive_file where is_deleted = 0 and archive_id="+auto.getId();
 			List<ArchiveFile> archiveFiles = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(ArchiveFile.class));
@@ -5429,6 +5430,8 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 
 			}finally {
 				FileUtils.removeFile(filePath);
+				String updateSql="update u_archives_auto set colour_status=1 where id="+auto.getId();
+				jdbcTemplate.execute(updateSql);
 			}
 		}
 		this.updateBatchById(archivesAutoList);

+ 56 - 30
blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ScanFileServiceImpl.java

@@ -13,6 +13,7 @@ import org.springblade.archive.entity.ScanFolder;
 import org.springblade.archive.mapper.ScanFileMapper;
 import org.springblade.archive.mapper.ScanFolderMapper;
 import org.springblade.archive.service.ScanFileService;
+import org.springblade.archive.service.ScanFolderService;
 import org.springblade.archive.utils.FileUtils;
 import org.springblade.archive.vo.ScanFolderVO;
 import org.springblade.business.entity.ArchiveFile;
@@ -63,8 +64,7 @@ public class ScanFileServiceImpl  extends ServiceImpl<ScanFileMapper, ScanFile>
     private final ArchiveTreeContractClient archiveTreeContractClient;
     private final JdbcTemplate jdbcTemplate;
     private final ArchiveFileClient archiveFileClient;
-
-
+    private final ScanFolderService scanFolderService;
 
 
     @Override
@@ -99,6 +99,8 @@ public class ScanFileServiceImpl  extends ServiceImpl<ScanFileMapper, ScanFile>
         List<ScanFolderVO> result = new ArrayList<>();
 
         for (ScanFolderVO vo : voList) {
+            List<ScanFolder> scanFolders = scanFolderMapper.selectAllChildren(vo.getId());
+            vo.setIsRemove(scanFolders.isEmpty());
             Long parentId = vo.getParentId();
             if (parentId == null || parentId == 0) {
                 // 没有父节点的作为根节点
@@ -112,7 +114,6 @@ public class ScanFileServiceImpl  extends ServiceImpl<ScanFileMapper, ScanFile>
                 }
             }
         }
-
         return result;
 
     }
@@ -128,10 +129,10 @@ public class ScanFileServiceImpl  extends ServiceImpl<ScanFileMapper, ScanFile>
     public String deleteScanFile(String ids) {
         List<Long> longList = Func.toLongList(ids);
         List<ScanFile> scanFiles = baseMapper.selectList(new LambdaQueryWrapper<>(ScanFile.class).in(ScanFile::getId, longList));
-        List<String> fileNames = scanFiles.stream().filter(o-> !StringUtil.isBlank(o.getFileName())).map(o -> o.getFileName()).collect(Collectors.toList());
-        baseMapper.removeScan(longList);
+        List<String> fileNames = scanFiles.stream().filter(o-> !StringUtil.isBlank(o.getOssUrl())).map(o -> (FileUtils.getAliYunSubUrl(o.getOssUrl()))).collect(Collectors.toList());
+        baseMapper.removeScan(longList,scanFiles.get(0).getProjectId(),scanFiles.get(0).getContractId());
         newIOSSClient.removeFiles(fileNames);
-        return "";
+        return "删除成功";
     }
 
     @Override
@@ -196,24 +197,24 @@ public class ScanFileServiceImpl  extends ServiceImpl<ScanFileMapper, ScanFile>
             scanFolder.setFolderName(forderName);
             scanFolder.setParentId(parentId);
             scanFolder.setIsDeleted(0);
-            String folderPath="";
-            if(parentId!=0){
-                ScanFolder fatherFolder = scanFolderMapper.selectById(parentId);
-                if (fatherFolder!=null){
-                    String fatherPath = fatherFolder.getFolderPath();
-                    folderPath=fatherPath+"/"+forderName;
-                }
-            }else {
-                 folderPath=ROOT_PREFIX+"/"+contractId+"/"+forderName;
-            }
-            File folder = new File(folderPath);
-           if (!folder.exists()) {
-             boolean created = folder.mkdirs();
-             if (!created) {
-                throw new ServiceException("创建文件夹失败");
-             }
-           }
-          scanFolder.setFolderPath(folderPath);
+//            String folderPath="";
+//            if(parentId!=0){
+//                ScanFolder fatherFolder = scanFolderMapper.selectById(parentId);
+//                if (fatherFolder!=null){
+//                    String fatherPath = fatherFolder.getFolderPath();
+//                    folderPath=fatherPath+"/"+forderName;
+//                }
+//            }else {
+//                 folderPath=ROOT_PREFIX+"/"+contractId+"/"+forderName;
+//            }
+//            File folder = new File(folderPath);
+//           if (!folder.exists()) {
+//             boolean created = folder.mkdirs();
+//             if (!created) {
+//                throw new ServiceException("创建文件夹失败");
+//             }
+//           }
+//          scanFolder.setFolderPath(folderPath);
           int insert = scanFolderMapper.insert(scanFolder);
           return insert == 1;
     }
@@ -225,13 +226,19 @@ public class ScanFileServiceImpl  extends ServiceImpl<ScanFileMapper, ScanFile>
         if(digitalNum==null||digitalNum<1){
             digitalNum=0;
         }
-        Integer sort = baseMapper.selectMaxSort(list.get(0).getContractId(), list.get(0).getProjectId(), list.get(0).getForderId());
+        Integer sort = baseMapper.selectMaxSort(list.get(0).getContractId(), list.get(0).getProjectId(), list.get(0).getFolderId());
         if(sort==null||sort<1){
             sort=0;
         }
         for (AddScanFileDto dto : list) {
             ScanFile file = new ScanFile();
             BeanUtils.copyProperties(dto,file);
+            if(dto.getFileName().indexOf(".")>0&&dto.getFileName().indexOf("pdf")>0){
+                file.setFileName(dto.getFileName().substring(0,dto.getFileName().lastIndexOf(".")));
+            }else {
+                file.setFileName(dto.getFileName());
+            }
+            file.setFileNameSuffix(dto.getFileName());
             file.setId(SnowFlakeUtil.getId());
             file.setDigitalNum(++digitalNum);
             file.setSort(++sort);
@@ -244,14 +251,32 @@ public class ScanFileServiceImpl  extends ServiceImpl<ScanFileMapper, ScanFile>
 
     @Override
     public boolean deleteScanFolder(Long id) {
-        List<ScanFile> scanFiles = baseMapper.selectList(new LambdaQueryWrapper<>(ScanFile.class).eq(ScanFile::getFolderId, id));
-        if(scanFiles.size()>0){
-            throw new ServiceException("当前节点存在文件,无法删除");
+        List<ScanFolder> scanFolders = scanFolderMapper.selectAllChildren(id);
+        List<Long> longList = scanFolders.stream().map(ScanFolder::getId).collect(Collectors.toList());
+        List<ScanFile> scanFiles = baseMapper.selectList(new LambdaQueryWrapper<>(ScanFile.class).in(ScanFile::getFolderId, longList));
+        if(!scanFiles.isEmpty()){
+            throw new ServiceException("当前节点或子节点存在文件,无法删除");
+        }
+        for (ScanFolder folder : scanFolders) {
+            scanFolderMapper.deleteById(folder.getId());
+            //this.deleteScanFolderLinux(folder.getId());
         }
-        scanFolderMapper.deleteById(id);
         return true;
     }
 
+    private void deleteScanFolderLinux(Long id) {
+        ScanFolder scanFolder = scanFolderMapper.selectById(id);
+        if (scanFolder != null&&scanFolder.getFolderPath()!=null){
+            File folder = new File(scanFolder.getFolderPath());
+            if (folder.exists()) {
+                boolean deleted = folder.delete();
+                if (!deleted) {
+                    throw new ServiceException("删除文件夹失败");
+                }
+            }
+        }
+    }
+
     /**
      * 入口方法:扫描并入库指定contractId的所有文件夹
      * @param contractId 传入的合同ID(对应D:\PDF下的文件夹名)
@@ -476,7 +501,8 @@ public class ScanFileServiceImpl  extends ServiceImpl<ScanFileMapper, ScanFile>
                     null,//序号
                     null,//数字编号
                     null,//文件编号
-                    fileName,
+                    fileName.substring(0,fileName.lastIndexOf(".")),//文件题名
+                    fileName,//文件名
                     pdfNum,//文件页数
                     null,//文件日期
                     createTime,

+ 24 - 4
blade-service/blade-business/src/main/java/org/springblade/business/controller/MaterialProgressController.java

@@ -300,7 +300,7 @@ public class MaterialProgressController extends BladeController {
                 }
                 if (countList.size() > 0) {
                     //设置参数
-                    this.setTaskParameter(reVO, countList, classifyType);
+                    this.setTaskParameter(reVO, countList, classifyType,contractId);
                     filtetDataByRole(contract, reVO,2);
                     return R.data(reVO);
                 }
@@ -309,7 +309,7 @@ public class MaterialProgressController extends BladeController {
             //找到可填写的
             List<WbsTreeContract> submitNodeList = this.wbsTreeContractClient.queryContractSubmitWbsTreeByContractId(contractId);
             if (submitNodeList != null && submitNodeList.size() > 0) {
-                this.setTaskParameter(reVO, submitNodeList, classifyType);
+                this.setTaskParameter(reVO, submitNodeList, classifyType,contractId);
                 filtetDataByRole(contract, reVO,2);
                 return R.data(reVO);
             }
@@ -407,7 +407,7 @@ public class MaterialProgressController extends BladeController {
         }*/
     }
 
-    private void setTaskParameter(MaterialProgressVO reVO, List<WbsTreeContract> submitNodeList, String classifyType) {
+    private void setTaskParameter(MaterialProgressVO reVO, List<WbsTreeContract> submitNodeList, String classifyType,String contractId) {
         classifyType = StringUtils.isEmpty(classifyType) ? "1" : classifyType;
 
         //汇总四个填报类型的总数
@@ -435,7 +435,6 @@ public class MaterialProgressController extends BladeController {
         if (completion.size() > 0) {
             completionSubmitList = this.informationQueryService.list(Wrappers.<InformationQuery>lambdaQuery().in(InformationQuery::getWbsId, completion).eq(InformationQuery::getClassify, classifyType));
         }
-
         //处理工序资料
         if (processSubmitList != null && processSubmitList.size() > 0) {
             this.setParameter("工序资料", reVO, processSubmitList);
@@ -463,6 +462,27 @@ public class MaterialProgressController extends BladeController {
         } else {
             reVO.setProcessMaterialStatusList("中间交工", 0, 0, 0);
         }
+
+        String sql="select * from m_hide_process where contract_id= "+contractId+" and classify_type= "+classifyType;
+        List<HideProcess> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(HideProcess.class));
+        String hideTypes="";
+        if(!list.isEmpty()){
+            hideTypes= list.stream().map(HideProcess::getHideType).map(String::valueOf).collect(Collectors.joining(","));
+        }
+        for (MaterialProgressVO.ProcessMaterialStatus status : reVO.getProcessMaterialStatusList()) {
+            if("开工报告".equals(status.getTitle())){
+                status.setIsHide(hideTypes.contains("1")?1:0);
+            }
+            if("工序资料".equals(status.getTitle())){
+                status.setIsHide(hideTypes.contains("2")?1:0);
+            }
+            if ("评定资料".equals(status.getTitle())){
+                status.setIsHide(hideTypes.contains("3")?1:0);
+            }
+            if ("中间交工".equals(status.getTitle())){
+                status.setIsHide(hideTypes.contains("4")?1:0);
+            }
+        }
     }
 
     /**

+ 1 - 1
blade-service/blade-manager/src/main/java/com/jfireel/expression/node/impl/EqualNode.java

@@ -28,7 +28,7 @@ public class EqualNode extends OperatorResultNode {
             if (leftValue instanceof Number && rightValue instanceof Number) {
                 return EqUtil.calculate((Number) leftValue, (Number) rightValue);
             } else if (leftValue instanceof List || rightValue instanceof List) {
-                Object[] leftAndRight = ValueUtil.obtain(leftOperand.calculate(variables), rightOperand.calculate(variables));
+                Object[] leftAndRight = ValueUtil.obtain(leftOperand.calculate(variables), rightOperand.calculate(variables), true);
 
                 //如果是数字类型 第一个是float  第二个是整数所以不能使用equals
                 if (leftAndRight[0] instanceof Number && leftAndRight[1] instanceof Number) {

+ 1 - 1
blade-service/blade-manager/src/main/java/com/jfireel/expression/node/impl/GtEqNode.java

@@ -28,7 +28,7 @@ public class GtEqNode extends OperatorResultNode {
             return calculate;
         }
         Object calculate1 = rightOperand.calculate(variables);
-        Object[] leftAndRight = ValueUtil.obtain(calculate, calculate1);
+        Object[] leftAndRight = ValueUtil.obtain(calculate, calculate1, true);
         return leftAndRight == null ? null : !((Boolean) LtUtil.calculate((Number) leftAndRight[0], (Number) leftAndRight[1]));
     }
 }

+ 1 - 1
blade-service/blade-manager/src/main/java/com/jfireel/expression/node/impl/GtNode.java

@@ -26,7 +26,7 @@ public class GtNode extends OperatorResultNode {
             return calculate;
         }
         Object calculate1 = rightOperand.calculate(variables);
-        Object[] leftAndRight = ValueUtil.obtain(calculate, calculate1);
+        Object[] leftAndRight = ValueUtil.obtain(calculate, calculate1, true);
         return leftAndRight == null ? null : GtUtil.calculate((Number) leftAndRight[0], (Number) leftAndRight[1]);
     }
 

+ 1 - 1
blade-service/blade-manager/src/main/java/com/jfireel/expression/node/impl/LtEqNode.java

@@ -26,7 +26,7 @@ public class LtEqNode extends OperatorResultNode {
             return calculate;
         }
         Object calculate1 = rightOperand.calculate(variables);
-        Object[] leftAndRight = ValueUtil.obtain(calculate, calculate1);
+        Object[] leftAndRight = ValueUtil.obtain(calculate, calculate1, true);
         return leftAndRight == null ? null : !((Boolean) GtUtil.calculate((Number) leftAndRight[0], (Number) leftAndRight[1]));
     }
 

+ 1 - 1
blade-service/blade-manager/src/main/java/com/jfireel/expression/node/impl/LtNode.java

@@ -27,7 +27,7 @@ public class LtNode extends OperatorResultNode {
             return calculate;
         }
         Object calculate1 = rightOperand.calculate(variables);
-        Object[] leftAndRight = ValueUtil.obtain(calculate, calculate1);
+        Object[] leftAndRight = ValueUtil.obtain(calculate, calculate1, true);
         return leftAndRight == null ? null : LtUtil.calculate((Number) leftAndRight[0], (Number) leftAndRight[1]);
     }
 

+ 1 - 1
blade-service/blade-manager/src/main/java/com/jfireel/expression/node/impl/NotEqualNode.java

@@ -28,7 +28,7 @@ public class NotEqualNode extends OperatorResultNode {
             if (leftValue instanceof Number && rightValue instanceof Number) {
                 return EqUtil.calculate((Number) leftValue, (Number) rightValue) == false;
             } else if (leftValue instanceof List || rightValue instanceof List) {
-                Object[] leftAndRight = ValueUtil.obtain(leftOperand.calculate(variables), rightOperand.calculate(variables));
+                Object[] leftAndRight = ValueUtil.obtain(leftOperand.calculate(variables), rightOperand.calculate(variables), true);
 
                 //如果是数字类型 第一个是float  第二个是整数所以不能使用equals
                 if (leftAndRight[0] instanceof Number && leftAndRight[1] instanceof Number) {

+ 60 - 0
blade-service/blade-manager/src/main/java/com/jfireel/expression/util/ValueUtil.java

@@ -53,10 +53,70 @@ public class ValueUtil {
         return null;
     }
 
+    /**
+     * 判断条件 处理字母+数字的数据 去掉字母
+     * @param left
+     * @param right
+     * @param letterNumber
+     * @return
+     */
+    public static Object[] obtain(Object left, Object right, boolean letterNumber) {
+        if (StringUtils.isNotEmpty(left, right)) {
+            if (left instanceof List) {
+                List<Object> tmp = CustomFunction.obj2ListNe(left);
+                if (tmp.size() == 0) {
+                    return null;
+                }
+                if(tmp.size() == 1){
+                    if(StringUtils.isNumber(tmp.get(0).toString())){
+                        left = Double.valueOf(tmp.get(0).toString());
+                    }else{
+                        left = tmp.get(0);
+                    }
+
+                }else{
+                    left = sum(tmp);
+                }
+            }
+            if (right instanceof List) {
+                List<Object> tmp = CustomFunction.obj2ListNe(right);
+                if (tmp.size() == 0) {
+                    return null;
+                }
+                if(tmp.size() == 1){
+                    if(StringUtils.isNumber(tmp.get(0).toString())){
+                        right = Double.valueOf(tmp.get(0).toString());
+                    }else{
+                        right = tmp.get(0);
+                    }
+                }else{
+                    right = sum(tmp);
+                }
+
+            }
+            if (StringUtils.isNotEmpty(left) && StringUtils.isNotEmpty(right)) {
+                if (letterNumber) {
+                    left = isLetterNumber(left);
+                    right = isLetterNumber(right);
+                }
+                return new Object[]{left, right};
+            }
+        }
+        return null;
+    }
     public static Object sum(List<Object> list) {
         if (ListUtils.isNotEmpty(list)) {
             return (float) list.stream().filter(StringUtils::isNumber).map(StringUtils::handleNull).mapToDouble(Double::parseDouble).sum();
         }
         return 0;
     }
+
+    public static Object isLetterNumber(Object str){
+        // 检查是否是字母数字组合(必须同时包含字母和数字,且只包含字母数字)
+        if (str != null && str.toString().matches("^(?=.*[a-zA-Z])(?=.*\\d)[a-zA-Z\\d]+$")) {
+            // 提取所有数字
+            return Double.valueOf(str.toString().replaceAll("[^0-9]", ""));
+        }
+        return str;
+    }
 }

+ 200 - 1
blade-service/blade-manager/src/main/java/com/mixsmart/utils/CustomFunction.java

@@ -14,9 +14,11 @@ import org.springblade.common.utils.BaseUtils;
 import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.redis.cache.BladeRedis;
 import org.springblade.core.tool.utils.*;
+import org.springblade.manager.bean.SpringContextHolder;
 import org.springblade.manager.dto.ParamElements;
 import org.springblade.manager.entity.WbsTreeContract;
 import org.springblade.manager.utils.RandomNumberHolder;
+import org.springframework.jdbc.core.JdbcTemplate;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
@@ -24,6 +26,7 @@ import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.time.ZoneOffset;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
@@ -1188,7 +1191,7 @@ public class CustomFunction {
         }else{
             localDateTime= LocalDateTime.now();
         }
-      return localDateTime.atZone(java.time.ZoneOffset.UTC)
+      return localDateTime.atZone(ZoneOffset.UTC)
               .toInstant()
               .toEpochMilli();
     }
@@ -1997,6 +2000,19 @@ public class CustomFunction {
         }
         return result;
     }
+    public static List<Object> obj3List(Object obj) {
+        List<Object> result = new ArrayList<>();
+        if (obj != null) {
+            List<Object> datas = new ArrayList<>();
+            if (obj instanceof List) {
+                datas = (List<Object>) obj;
+            } else {
+                datas.add(obj);
+            }
+            return datas;
+        }
+        return result;
+    }
 
     /**
      * @return java.lang.Object
@@ -2236,6 +2252,10 @@ public class CustomFunction {
         List<Object> list = obj2List(obj);
         return list.parallelStream().filter(StringUtils::isNotEmpty).collect(Collectors.toList());
     }
+    public static List<Object> obj3ListNe(Object obj) {
+        List<Object> list = obj3List(obj);
+        return list.parallelStream().filter(StringUtils::isNotEmpty).collect(Collectors.toList());
+    }
 
     /*obj2ListNe别名*/
     public static List<Object> objToListNe(Object obj) {
@@ -3121,4 +3141,183 @@ public class CustomFunction {
         }
         return result;
     }
+
+    /**
+     * 特征值计算
+     */
+    public static Object eigenvalue(Object data){
+
+        //默认只有10组数据
+        if (data != null ) {
+            List<Object> datas = obj2ListNe(data);
+            datas = datas.size() > 10 ? datas.subList(0, datas.size()/2) : datas;
+            int total = datas.size();
+            //换算系数
+            double conversionFactor;
+            //获取换算系数
+            if(total >= 10 && total <= 15){
+                conversionFactor = 1.695;
+            }else if(total >= 16 && total <= 24){
+                conversionFactor = 1.645;
+            }else if(total>=25){
+                conversionFactor = 1.595;
+            }else{
+                throw new ServiceException("数据组数小于10");
+            }
+            List<String> _datas = datas.stream().map(StringUtils::handleNull).collect(Collectors.toList());
+            //获取平均值
+            double avgVal = _datas.stream().mapToDouble(Double::parseDouble).average().orElse(0D);
+            //获取标准差
+            double sqrt = Math.sqrt(_datas.stream().mapToDouble(Double::parseDouble).map(e -> Math.pow(e - avgVal, 2)).sum() / (total-1));
+            return avgVal - (conversionFactor * sqrt);
+        }
+        return null;
+    }
+
+    /**
+     * 混凝土强度 “换算值”计算
+     * @param data 混凝土强度实测值
+     * @param angle 角度
+     * @param pouringSurface 浇筑面
+     * @param type 测区计算方式 1-单独测区深度,2-测区平均值
+     * @param surveyDepth 测区深度
+     * @param Pumping 是否泵送 1-是,2-否
+     */
+    public static Object concreteStrength(Object data, Object angle, Object pouringSurface, Object type, Object surveyDepth, Object Pumping){
+        List<Object> datas = obj2ListNe(data);
+        List<Object> data1 = obj2ListNe(angle);
+        List<Object> data2 = obj2ListNe(pouringSurface);
+        List<Object> data4 = obj2ListNe(Pumping);
+
+        //数据库查询对象
+        JdbcTemplate jdbcTemplateStatic = SpringContextHolder.getBean(JdbcTemplate.class);
+
+        if (CollectionUtil.isNotEmpty(datas) && CollectionUtil.isNotEmpty(data1) && CollectionUtil.isNotEmpty(data2) && surveyDepth != null && CollectionUtil.isNotEmpty(data4)) {
+            angle = data1.get(0);
+            pouringSurface = data2.get(0);
+            Pumping = data4.get(0);
+
+            List<Double> list = datas.stream().filter(StringUtils::isNumber).map(m -> Double.valueOf(m.toString())).collect(Collectors.toList());
+            list = removeThreeMinAndMaxEfficient(list);
+            //计算平均值
+            double asDouble = list.stream().filter(StringUtils::isNumber).map(StringUtils::handleNull).mapToDouble(Double::parseDouble).average().orElse(0.0);
+            if (StringUtils.isNotEmpty(angle) && StringUtils.isNotEmpty(pouringSurface)) {
+                //角度  根据平均值从数据库中查询对应的映射值
+                List<Map<String, Object>> angleList = jdbcTemplateStatic.queryForList("select data_value from coordinate_angle where r_value = " + asDouble + " and h_value = " + angle);
+                if (CollectionUtil.isNotEmpty(angleList)) {
+                    Map<String, Object> stringObjectMap = angleList.get(0);
+                    asDouble += Double.parseDouble(stringObjectMap.get("data_value").toString());
+                }
+                //角度  根据平均值从数据库中查询对应的映射值
+                List<Map<String, Object>> pouringSurfaceList = jdbcTemplateStatic.queryForList("select data_value from coordinate_pouring_urface where r_value = " + asDouble + " and h_value = '" + pouringSurface + "'");
+                if (CollectionUtil.isNotEmpty(pouringSurfaceList)) {
+                    Map<String, Object> stringObjectMap = pouringSurfaceList.get(0);
+                    asDouble += Double.parseDouble(stringObjectMap.get("data_value").toString());
+                }
+
+                //最终值 R H
+                double r = asDouble;
+                double h = 0;
+
+                //测区深度 第一种只取第一条数据
+                if(type == null || "1".equals(type.toString())){
+                    String surveyDepthStr;
+                    if(surveyDepth instanceof List){
+                        List<Object> surveyDepthList = obj3ListNe(surveyDepth);
+                        surveyDepthStr = surveyDepthList.get(0).toString();
+                    }else{
+                        surveyDepthStr = surveyDepth.toString();
+                    }
+                    //分割字符串
+                    String[] split = surveyDepthStr.split(surveyDepthStr.contains(",") ? "," : "、");
+                    //计算平均值
+                    h = Arrays.stream(split).filter(StringUtils::isNumber).map(StringUtils::handleNull).mapToDouble(Double::parseDouble).average().orElse(0.0);
+                    //进行0.5修正
+                    h = roundHalfEven(new BigDecimal(h).setScale(1, RoundingMode.HALF_UP).doubleValue(),1);
+                }else{
+                    List<Object> surveyDepthList = obj3ListNe(surveyDepth);
+                    List<Double> doubleArrList = new ArrayList<>();
+                    surveyDepthList.forEach(f -> {
+                        String string = f.toString();
+                        //分割字符串
+                        String[] split = string.split(string.contains(",") ? "," : "、");
+                        //计算平均值
+                        double avg = Arrays.stream(split).filter(StringUtils::isNumber).map(StringUtils::handleNull).mapToDouble(Double::parseDouble).average().orElse(0.0);
+                        doubleArrList.add(roundHalfEven(new BigDecimal(avg).setScale(1, RoundingMode.HALF_UP).doubleValue(),1));
+                    });
+                    //结果再计算平均值
+                    h = doubleArrList.stream().mapToDouble(Double::doubleValue).average().orElse(0.0);
+                    //在进行修正
+                    h = roundHalfEven(new BigDecimal(h).setScale(1, RoundingMode.HALF_UP).doubleValue(),1);
+                }
+
+                //是否泵送
+                if ("是".equals(Pumping) || "1".equals(Pumping)) {
+                    //计算公式:f = 0.034488 * (R^1.9400) * 10^(-0.0173 * dm)
+                    double v = 0.034488 * Math.pow(r, 1.9400) * Math.pow(10, -0.0173 * h);
+                    return new BigDecimal(v).setScale(1, RoundingMode.HALF_UP);
+                } else {
+                    //从数据库中获取数据
+                    List<Map<String, Object>> list1 = jdbcTemplateStatic.queryForList("select data_value from coordinate_data where r_value = " + r + " and h_value = " + h);
+                    if (CollectionUtil.isNotEmpty(list1)) {
+                        Map<String, Object> stringObjectMap = list1.get(0);
+                        return new BigDecimal(stringObjectMap.get("data_value").toString()).setScale(1, RoundingMode.HALF_UP);
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    // 更高效的实现方式(一次性操作)
+    public static List<Double> removeThreeMinAndMaxEfficient(List<Double> list) {
+        if (list.size() <= 6) {
+            return new ArrayList<>();
+        }
+
+        // 创建列表的副本
+        List<Double> sortedList = new ArrayList<>(list);
+
+        // 排序列表
+        Collections.sort(sortedList);
+
+        // 直接获取中间部分的元素(跳过前3个和后3个)
+        return sortedList.subList(3, sortedList.size() - 3);
+    }
+
+    /**
+     * 使用银行家舍入法进行0.5修正
+     * @param number 要修正的数字
+     * @param scale 保留的小数位数
+     * @return 修正后的结果
+     */
+    public static double roundHalfEven(double number, int scale) {
+        BigDecimal bd = BigDecimal.valueOf(number);
+
+        // 获取小数部分
+        BigDecimal integerPart = new BigDecimal(bd.toBigInteger().toString());
+        BigDecimal decimalPart = bd.subtract(integerPart);
+
+        // 如果小数部分为0,直接返回
+        if (decimalPart.compareTo(BigDecimal.ZERO) == 0) {
+            return number;
+        }
+
+        // 将小数部分乘以10,获取第一位小数
+        BigDecimal firstDecimal = decimalPart.multiply(BigDecimal.TEN)
+                .setScale(0, RoundingMode.DOWN);
+
+        int firstDigit = firstDecimal.intValue();
+
+        if (firstDigit < 5) {
+            // 小数位数小于5,改成5
+            return integerPart.add(new BigDecimal("0.5")).doubleValue();
+        } else if (firstDigit > 5) {
+            // 小数位数大于5,四舍五入到整数
+            return bd.setScale(0, RoundingMode.HALF_UP).doubleValue();
+        } else {
+            // 等于5,不变
+            return number;
+        }
+    }
 }

+ 25 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/bean/SpringContextHolder.java

@@ -0,0 +1,25 @@
+package org.springblade.manager.bean;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+@Component
+public class SpringContextHolder implements ApplicationContextAware {
+
+    private static ApplicationContext applicationContext;
+
+    @Override
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+        SpringContextHolder.applicationContext = applicationContext;
+    }
+
+    public static <T> T getBean(Class<T> clazz) {
+        return applicationContext.getBean(clazz);
+    }
+
+    public static Object getBean(String name) {
+        return applicationContext.getBean(name);
+    }
+}

+ 8 - 3
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java

@@ -145,6 +145,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
     // excel 解析结构
     private final IExctabCellService exctabCellService;
 
+    private final IParameterElementService parameterElementService;
 
     @Autowired
     StringRedisTemplate RedisTemplate;
@@ -1129,9 +1130,13 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
     public void setAutomatic(Long pkeyId, String nodeId, Document doc) {
         //自动获取数据查询
         try {
-            Map<String, Object> nodeBaseInfo = nodeBaseInfoService.getAllNodeBaseInfoByPkeyId(pkeyId, Long.valueOf(nodeId));
-            nodeBaseInfo.keySet().forEach(key -> {
-                Elements select = doc.select("table").first().select("[keyname=" + key + "]");
+            WbsTreeContract wbsTreeContract = wbsTreeContractService.getBaseMapper().selectOne(new QueryWrapper<WbsTreeContract>().eq("p_key_id", pkeyId));
+            List<ParameterElement> nodeBaseInfo = parameterElementService.list(Wrappers.<ParameterElement>lambdaQuery().eq(ParameterElement::getProjectId, wbsTreeContract.getProjectId())
+                    .eq(ParameterElement::getContractId, wbsTreeContract.getContractId()).eq(ParameterElement::getType, 3)
+                    .eq(ParameterElement::getNodeId, wbsTreeContract.getCopyPkId()));
+
+            nodeBaseInfo.forEach(key -> {
+                Elements select = doc.select("table").first().select("[keyname=" + key.getElementName() + "]");
                 select.stream().filter(Objects::nonNull).forEach(element -> element.attr("clearAutomatic", "1"));
             });
         } catch (Exception e) {

+ 131 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java

@@ -6158,6 +6158,109 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                     }
                 }
             }
+            //合格点数公式
+            if(f.contains(".passingPoints")){
+                //Fc.passingPoints(参数1,参数2,=,参数3,返回类型(1数量,2内容),判定规则同行/同列)
+                Matcher m = RegexUtils.matcher(FC_REG + "(passingPoints)\\(([^)]+)\\)", f);
+                while (m.find()) {
+                    String el = m.group();
+                    String[] args = m.group(2).split(",");
+                    if(args.length == 6){
+                        //前进方向一侧
+                        List<FormData> fronts = getFormDataByCode(args[0], tec);
+                        //相反方向一侧
+                        List<FormData> afters = getFormDataByCode(args[1], tec);
+                        //统计规则,x 同列,y,同行
+                        String arg = args[5];
+                        List<Object> data = new ArrayList<>();
+                        Map<Integer, List<ElementData>> collect1;
+                        Map<Integer, List<ElementData>> collect2;
+                        if(CollectionUtil.isNotEmpty(fronts)){
+                            List<ElementData> values = fronts.get(0).getValues();
+                            //同行还是同列
+                            if("x".equals(arg)){
+                                collect1 = values.stream().collect(Collectors.groupingBy(ElementData::getX));
+                            }else{
+                                collect1 = values.stream().collect(Collectors.groupingBy(ElementData::getY));
+                            }
+
+                        } else {
+                            collect1 = null;
+                        }
+                        if(CollectionUtil.isNotEmpty(afters)){
+                            List<ElementData> values = afters.get(0).getValues();
+                            if("x".equals(arg)){
+                                collect2 = values.stream().collect(Collectors.groupingBy(ElementData::getX));
+                            }else{
+                                collect2 = values.stream().collect(Collectors.groupingBy(ElementData::getY));
+                            }
+                        } else {
+                            collect2 = null;
+                        }
+                        //默认统计数量
+                        boolean type;
+                        //统计数量
+                        if("2".equals(args[4])){
+                            type = false;
+                        } else {
+                            type = true;
+                        }
+                        fd.getValues().forEach(v -> {
+                            long count = 0;
+                            List<Object> list = new ArrayList<>();
+
+                            //两个数据源都为空
+                            boolean isOneFalse = true;
+                            boolean isTwoFalse = true;
+                            if (collect1 != null) {
+                                //根据坐标获取数据
+                                List<ElementData> elementData = collect1.get("x".equals(arg) ? v.getX() : v.getY());
+                                if(CollectionUtil.isNotEmpty(elementData)){
+
+                                    List<ElementData> collect = elementData.stream().filter(e -> StringUtils.isNotEmpty(e.getValue())).collect(Collectors.toList());
+                                    //如果全部参数不为空,统计值
+                                    if(CollectionUtil.isNotEmpty(collect)){
+                                        if(type){
+                                            count += collect.stream().filter(e -> evaluateCondition(e.getValue().toString(), args[2], args[3])).count();
+                                        }else{
+                                            list.addAll(collect.stream().map(ElementData::getValue).filter(value -> evaluateCondition(value.toString(), args[2], args[3])).collect(Collectors.toList()));
+                                        }
+
+                                        isOneFalse = false;
+                                    }
+                                }
+                            }
+                            if (collect2 != null) {
+                                List<ElementData> elementData = collect2.get("x".equals(arg) ? v.getX() : v.getY());
+                                if(CollectionUtil.isNotEmpty(elementData)){
+                                    List<ElementData> collect = elementData.stream().filter(e -> StringUtils.isNotEmpty(e.getValue())).collect(Collectors.toList());
+                                    if(CollectionUtil.isNotEmpty(collect)){
+                                        if(type){
+                                            count += collect.stream().filter(e -> evaluateCondition(e.getValue().toString(), args[2], args[3])).count();
+                                        }else{
+                                            list.addAll(collect.stream().map(ElementData::getValue).filter(value -> evaluateCondition(value.toString(), args[2], args[3])).collect(Collectors.toList()));
+                                        }
+                                        isTwoFalse = false;
+                                    }
+
+                                }
+                            }
+                            //如果两个组数据都是空的 那么值也设置为空
+                            if(isOneFalse && isTwoFalse){
+                                data.add("");
+                            }else{
+                                if(type){
+                                    data.add(count);
+                                }else{
+                                    data.add(StringUtil.join(list, "、"));
+                                }
+                            }
+                        });
+                        f = f.replace(el, putDataWithKey(data, tec));
+                    }
+
+                }
+            }
             formula.setFormula(f);
             if (f.contains("quantity")) {
                 quantity(formula, fd, f, tec);
@@ -8029,5 +8132,32 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
         }
         return wbsTreeContract;
     }
-    
+
+    public boolean evaluateCondition(String value1, String operator, String value2) {
+        try {
+            // 尝试将字符串转换为数字(支持整数和浮点数)
+            double num1 = Double.parseDouble(value1);
+            double num2 = Double.parseDouble(value2);
+
+            switch (operator) {
+                case "=":
+                case "==":
+                    return num1 == num2;
+                case ">":
+                    return num1 > num2;
+                case "<":
+                    return num1 < num2;
+                case ">=":
+                    return num1 >= num2;
+                case "<=":
+                    return num1 <= num2;
+                case "!=":
+                    return num1 != num2;
+                default:
+                    throw new IllegalArgumentException("无效的运算符: " + operator);
+            }
+        } catch (NumberFormatException e) {
+            throw new IllegalArgumentException("数值格式错误: " + value1 + " 或 " + value2);
+        }
+    }
 }

+ 7 - 4
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/NodeBaseInfoServiceImpl.java

@@ -491,9 +491,12 @@ public class NodeBaseInfoServiceImpl extends BaseServiceImpl<NodeBaseInfoMapper,
         ParameterElement element = parameterElementService.getOne(Wrappers.<ParameterElement>lambdaQuery().eq(ParameterElement::getProjectId, wbsTreeContract.getProjectId())
                 .eq(ParameterElement::getContractId, wbsTreeContract.getContractId()).eq(ParameterElement::getType, 3)
                 .eq(ParameterElement::getElementName, paramName).eq(ParameterElement::getNodeId, wbsTreeContract.getCopyPkId()));
-        //软删除
-        return parameterElementService.update(Wrappers.<ParameterElement>update().lambda()
-                .set(ParameterElement::getIsDeleted, 1)
-                .eq(ParameterElement::getId, element.getId()));
+        if(element != null){
+            //软删除
+            return parameterElementService.update(Wrappers.<ParameterElement>update().lambda()
+                    .set(ParameterElement::getIsDeleted, 1)
+                    .eq(ParameterElement::getId, element.getId()));
+        }
+        return true;
     }
 }

+ 3 - 1
blade-service/blade-user/src/main/java/org/springblade/system/user/service/impl/UserServiceImpl.java

@@ -531,6 +531,8 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
                 if(StringUtil.isEmpty(user.getPhone())){
                     throw new ServiceException("手机号不能为空,请填写正确的手机号后,再导入");
                 }
+            }
+            if(StringUtil.isEmpty(user.getAccount())){
                 user.setAccount(user.getPhone());
             }
             // 设置用户平台
@@ -571,7 +573,7 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
             // 覆盖数据
             if (isCovered) {
                 // 查询用户是否存在
-                User oldUser = UserCache.getUser(AuthUtil.getTenantId(), userExcel.getAccount());
+                User oldUser = UserCache.getUser(AuthUtil.getTenantId(), user.getAccount());
                 //User oldUser = baseMapper.selectOne(Wrappers.<User>query().lambda().eq(User::getAccount, userExcel.getAccount()).eq(User::getIsDeleted, BladeConstant.DB_NOT_DELETED));
                 if (oldUser != null && oldUser.getId() != null) {
                     user.setId(oldUser.getId());