Bläddra i källkod

Merge branch 'master' of http://47.110.251.215:3000/java_org/bladex

liuyc 3 år sedan
förälder
incheckning
cff542cb4c
65 ändrade filer med 6051 tillägg och 316 borttagningar
  1. 34 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/FirstInformationDTO.java
  2. 34 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/UserOpinionGoodDTO.java
  3. 101 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/FirstInformation.java
  4. 55 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/UserOpinionGood.java
  5. 70 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/FirstInformationVO.java
  6. 34 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/UserOpinionGoodVO.java
  7. 3 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/UserOpinionVO.java
  8. 1 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/FormulaBean.java
  9. 34 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/LinkdataInfoDTO.java
  10. 34 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/TextdictInfoDTO.java
  11. 27 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/WbsParamBean.java
  12. 1 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/Formula.java
  13. 85 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/LinkdataInfo.java
  14. 76 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/TextdictInfo.java
  15. 24 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/WbsParam.java
  16. 34 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/LinkdataInfoVO.java
  17. 51 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/TextdictDataInfoVO.java
  18. 34 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/TextdictInfoVO.java
  19. 6 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WbsNodeTableVO.java
  20. 3 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WbsTreeContractTreeVOS.java
  21. 19 0
      blade-service/blade-business/src/main/java/org/springblade/business/controller/ContractLogController.java
  22. 47 0
      blade-service/blade-business/src/main/java/org/springblade/business/controller/FirstInformationController.java
  23. 16 0
      blade-service/blade-business/src/main/java/org/springblade/business/controller/UserOpinionController.java
  24. 36 0
      blade-service/blade-business/src/main/java/org/springblade/business/controller/UserOpinionGoodController.java
  25. 2 5
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/ContractLogMapper.java
  26. 4 4
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/ContractLogMapper.xml
  27. 41 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/FirstInformationMapper.java
  28. 86 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/FirstInformationMapper.xml
  29. 2 2
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/InformationQueryMapper.xml
  30. 33 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/UserOpinionGoodMapper.java
  31. 18 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/UserOpinionGoodMapper.xml
  32. 5 5
      blade-service/blade-business/src/main/java/org/springblade/business/service/IContractLogService.java
  33. 56 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/IFirstInformationService.java
  34. 32 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/IUserOpinionGoodService.java
  35. 0 16
      blade-service/blade-business/src/main/java/org/springblade/business/service/IUserOpinionService.java
  36. 0 5
      blade-service/blade-business/src/main/java/org/springblade/business/service/WeatherInfoService.java
  37. 12 5
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/ContractLogServiceImpl.java
  38. 101 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/FirstInformationServiceImpl.java
  39. 36 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/UserOpinionGoodServiceImpl.java
  40. 21 4
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/UserOpinionServiceImpl.java
  41. 2 0
      blade-service/blade-business/src/main/java/org/springblade/business/utils/FunctionMain.java
  42. 3631 0
      blade-service/blade-manager/src/main/java/com/mixsmart/utils/CustomFunction.java
  43. 208 254
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java
  44. 15 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/FormulaController.java
  45. 136 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/LinkdataInfoController.java
  46. 140 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/TextdictInfoController.java
  47. 128 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsParamController.java
  48. 35 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/WbsTreeContractClientImpl.java
  49. 1 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/FormulaMapper.xml
  50. 45 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/LinkdataInfoMapper.java
  51. 25 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/LinkdataInfoMapper.xml
  52. 42 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/TextdictInfoMapper.java
  53. 20 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/TextdictInfoMapper.xml
  54. 7 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsParamMapper.java
  55. 21 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsParamMapper.xml
  56. 2 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreeContractMapper.xml
  57. 1 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreePrivateMapper.xml
  58. 44 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/ILinkdataInfoService.java
  59. 44 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/ITextdictInfoService.java
  60. 13 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IWbsParamService.java
  61. 48 14
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java
  62. 48 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/LinkdataInfoServiceImpl.java
  63. 44 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/TextdictInfoServiceImpl.java
  64. 18 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsParamServiceImpl.java
  65. 25 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/wrapper/WbsParamWrapper.java

+ 34 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/FirstInformationDTO.java

@@ -0,0 +1,34 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.business.dto;
+
+import org.springblade.business.entity.FirstInformation;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 首件信息记录表数据传输对象实体类
+ *
+ * @author BladeX
+ * @since 2022-06-20
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class FirstInformationDTO extends FirstInformation {
+	private static final long serialVersionUID = 1L;
+
+}

+ 34 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/UserOpinionGoodDTO.java

@@ -0,0 +1,34 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.business.dto;
+
+import org.springblade.business.entity.UserOpinionGood;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 点赞记录表数据传输对象实体类
+ *
+ * @author BladeX
+ * @since 2022-06-21
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class UserOpinionGoodDTO extends UserOpinionGood {
+	private static final long serialVersionUID = 1L;
+
+}

+ 101 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/FirstInformation.java

@@ -0,0 +1,101 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.business.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 java.util.Date;
+
+/**
+ * 首件信息记录表实体类
+ *
+ * @author BladeX
+ * @since 2022-06-20
+ */
+@Data
+@TableName("u_first_information")
+@EqualsAndHashCode(callSuper = true)
+public class FirstInformation extends BaseEntity {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 节点ID
+     */
+    @ApiModelProperty("节点ID")
+    private Long wbsNodeId;
+
+    /**
+     * 文件名称
+     */
+    @ApiModelProperty("文件名称")
+    private String fileName;
+
+    /**
+     * 填报时间
+     */
+    @ApiModelProperty("填报时间")
+    private String reportTime;
+
+    /**
+     * 数据ID,通过这个字段去寻找相关联的数据
+     */
+    private Long dataId;
+
+    /**
+     * 流程批次
+     */
+    @ApiModelProperty("流程批次")
+    private Integer reportNumber;
+
+    /**
+     * 创建人姓名
+     */
+    @ApiModelProperty("创建人姓名")
+    private String createUserName;
+
+    /**
+     * 流程ID
+     */
+    @ApiModelProperty("流程ID")
+    private String taskId;
+
+    /**
+     * 1施工2质检
+     */
+    @ApiModelProperty("1施工2质检")
+    private Integer classify;
+
+    public FirstInformation(String fileName, Long wbsNodeId, Integer reportNumber, Integer status, Long userId, String userName, Long deptId){
+        this.fileName = fileName;
+        this.wbsNodeId = wbsNodeId;
+        this.reportNumber = reportNumber;
+        this.setStatus(status);
+        this.setCreateUser(userId);
+        this.createUserName = userName;
+        this.setDataId(deptId);
+        this.setCreateTime(new Date());
+    }
+
+    public FirstInformation(){}
+
+}

+ 55 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/UserOpinionGood.java

@@ -0,0 +1,55 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.business.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import org.springblade.core.mp.base.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 点赞记录表实体类
+ *
+ * @author BladeX
+ * @since 2022-06-21
+ */
+@Data
+@TableName("u_user_opinion_good")
+@EqualsAndHashCode(callSuper = true)
+public class UserOpinionGood extends BaseEntity {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * u_user_opinion id
+     */
+    private Long userOpinionId;
+
+    public UserOpinionGood(Long userOpinionId, Long userId, Long deptId){
+        this.userOpinionId = userOpinionId;
+        this.setCreateUser(userId);
+        this.setCreateDept(deptId);
+        this.setCreateTime(new Date());
+    }
+
+    public UserOpinionGood(){}
+
+}

+ 70 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/FirstInformationVO.java

@@ -0,0 +1,70 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.business.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import org.springblade.business.entity.FirstInformation;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.List;
+
+/**
+ * 首件信息记录表视图实体类
+ *
+ * @author BladeX
+ * @since 2022-06-20
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class FirstInformationVO extends FirstInformation {
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 输入框通用查询
+	 */
+	@ApiModelProperty("输入框通用查询")
+	private String queryValue;
+
+	/**
+	 * 时间查询
+	 */
+	@ApiModelProperty("时间查询,间隔用~")
+	private String betweenTime;
+
+	private String startTime;
+
+	private String endTime;
+
+	/**
+	 * 当前页
+	 */
+	@ApiModelProperty("当前页")
+	private Integer current;
+
+	/**
+	 * 当前页显示条数
+	 */
+	@ApiModelProperty("当前页显示条数")
+	private Integer size;
+
+	@ApiModelProperty("节点查询")
+	private String wbsNodeIds;
+
+	private List<String> wbsNodeArray;
+
+}

+ 34 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/UserOpinionGoodVO.java

@@ -0,0 +1,34 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.business.vo;
+
+import org.springblade.business.entity.UserOpinionGood;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 点赞记录表视图实体类
+ *
+ * @author BladeX
+ * @since 2022-06-21
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class UserOpinionGoodVO extends UserOpinionGood {
+	private static final long serialVersionUID = 1L;
+
+}

+ 3 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/UserOpinionVO.java

@@ -68,4 +68,7 @@ public class UserOpinionVO extends UserOpinion {
 	@ApiModelProperty(value = "用户头像")
 	private String avatar;
 
+	@ApiModelProperty(value = "当前用户是否对当前工单点赞")
+	private Boolean currentUserGood;
+
 }

+ 1 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/FormulaBean.java

@@ -16,4 +16,5 @@ public class FormulaBean {
     private String remark;
     private Long wbsId;
     private Long elementId;
+    private String map;
 }

+ 34 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/LinkdataInfoDTO.java

@@ -0,0 +1,34 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.manager.dto;
+
+import org.springblade.manager.entity.LinkdataInfo;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 清表解析字段信息数据传输对象实体类
+ *
+ * @author BladeX
+ * @since 2022-06-17
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class LinkdataInfoDTO extends LinkdataInfo {
+	private static final long serialVersionUID = 1L;
+
+}

+ 34 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/TextdictInfoDTO.java

@@ -0,0 +1,34 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.manager.dto;
+
+import org.springblade.manager.entity.TextdictInfo;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 参数信息表数据传输对象实体类
+ *
+ * @author BladeX
+ * @since 2022-06-17
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class TextdictInfoDTO extends TextdictInfo {
+	private static final long serialVersionUID = 1L;
+
+}

+ 27 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/WbsParamBean.java

@@ -0,0 +1,27 @@
+package org.springblade.manager.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @author yangyj
+ * @Date 2022/6/17 17:09
+ * @description TODO
+ */
+@Data
+public class WbsParamBean {
+    @ApiModelProperty(value = "名称",required =true)
+    private  String name;
+    @ApiModelProperty(value = "流水号,修改必传")
+    private  Long id;
+    @ApiModelProperty(value = "参数码")
+    private  String k;
+    @ApiModelProperty(value = "参数内容,普通参数才需要")
+    private  String v;
+    @ApiModelProperty(value = "节点id,普通参数才需要")
+    private Long wbsId;
+    @ApiModelProperty(value = "描述说明")
+    private  String remark;
+    @ApiModelProperty(value = "类型:0参数名称字典,1普通参数")
+    private  Integer type;
+}

+ 1 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/Formula.java

@@ -27,4 +27,5 @@ public class Formula extends BaseEntity {
    private Long wbsId;
    @Size(max = 20)
    private Long elementId;
+   private String map;
 }

+ 85 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/LinkdataInfo.java

@@ -0,0 +1,85 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.manager.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.springblade.core.mp.base.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 清表解析字段信息实体类
+ *
+ * @author BladeX
+ * @since 2022-06-17
+ */
+@Data
+@TableName("m_linkdata_info")
+@ApiModel(value = "Dict对象", description = "Dict对象")
+public class LinkdataInfo implements  Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	@ApiModelProperty("主键id")
+	@TableId(
+			value = "id",
+			type = IdType.ASSIGN_ID
+	)
+	private Long id;
+	@JsonSerialize(
+			using = ToStringSerializer.class
+	)
+
+	/**
+	* 私有项目的tabId
+	*/
+		private Long tabId;
+	/**
+	* 元素中文描述
+	*/
+		private String colName;
+	/**
+	* 元素英文name
+	*/
+		private String colKey;
+	/**
+	* 数据类型type
+	*/
+		private Long dataType;
+	/**
+	* html展示类型
+	*/
+		private Long htmlType;
+	/**
+	* tr坐标
+	*/
+		private Integer trIndex;
+	/**
+	* td坐标
+	*/
+		private Integer tdIndex;
+
+
+}

+ 76 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/TextdictInfo.java

@@ -0,0 +1,76 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.manager.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.springblade.core.mp.base.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 参数信息表实体类
+ *
+ * @author BladeX
+ * @since 2022-06-17
+ */
+	@Data
+	@TableName("m_textdict_info")
+	@ApiModel(value = "Dict对象", description = "Dict对象")
+	public class TextdictInfo implements  Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	@ApiModelProperty("主键id")
+	@TableId(
+			value = "id",
+			type = IdType.ASSIGN_ID
+	)
+	private Long id;
+	@JsonSerialize(
+			using = ToStringSerializer.class
+	)
+	/**
+	* 字典名称
+	*/
+		private String dictValue;
+	/**
+	* 排序
+	*/
+		private Integer sort;
+	/**
+	* 字段Id
+	*/
+		private Long comId;
+	/**
+	* 是否默认值
+	*/
+		private Integer isDefult;
+
+	/**
+	 * 是否默认值
+	 */
+	private Integer isDeleted;
+
+}

+ 24 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/WbsParam.java

@@ -0,0 +1,24 @@
+package org.springblade.manager.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.core.mp.base.BaseEntity;
+
+/**
+ * @author yangyj
+ * @Date 2022/6/17 16:48
+ * @description TODO
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@TableName("m_wbs_param")
+public class WbsParam  extends BaseEntity {
+    private static final long serialVersionUID = 1L;
+    private  String name;
+    private  String k;
+    private  String v;
+    private  String remark;
+    private  Integer type;
+    private  Long wbsId;
+}

+ 34 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/LinkdataInfoVO.java

@@ -0,0 +1,34 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.manager.vo;
+
+import org.springblade.manager.entity.LinkdataInfo;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 清表解析字段信息视图实体类
+ *
+ * @author BladeX
+ * @since 2022-06-17
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class LinkdataInfoVO extends LinkdataInfo {
+	private static final long serialVersionUID = 1L;
+
+}

+ 51 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/TextdictDataInfoVO.java

@@ -0,0 +1,51 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.manager.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.manager.entity.TextdictInfo;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 参数信息表视图实体类
+ *
+ * @author BladeX
+ * @since 2022-06-17
+ */
+@Data
+public class TextdictDataInfoVO implements Serializable  {
+	private static final long serialVersionUID = 1L;
+
+
+	@ApiModelProperty(value = "节点Id")
+	private Long nodeId;
+
+	@ApiModelProperty(value = "字段Id")
+	private Long colId;
+
+	@ApiModelProperty(value = "文本类型Id")
+	private String textId;
+
+
+	@ApiModelProperty(value = "字段Id")
+	private List<TextdictInfo> textInfo;
+
+}

+ 34 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/TextdictInfoVO.java

@@ -0,0 +1,34 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.manager.vo;
+
+import org.springblade.manager.entity.TextdictInfo;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 参数信息表视图实体类
+ *
+ * @author BladeX
+ * @since 2022-06-17
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class TextdictInfoVO extends TextdictInfo {
+	private static final long serialVersionUID = 1L;
+
+}

+ 6 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WbsNodeTableVO.java

@@ -62,6 +62,12 @@ public class WbsNodeTableVO implements Serializable {
     @ApiModelProperty(value = "是否关联清表 '1'否 '2'是")
     private Integer isLinkTable;
 
+    /**
+     * excelId
+     */
+    @ApiModelProperty(value = "清表Id")
+    private Long excelId;
+
     /**
      * 初始化实体表名
      */

+ 3 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WbsTreeContractTreeVOS.java

@@ -52,4 +52,7 @@ public class WbsTreeContractTreeVOS {
     @ApiModelProperty("是否被标记为首件")
     private Boolean isFirst;
 
+    @ApiModelProperty("图标")
+    private String iconValue;
+
 }

+ 19 - 0
blade-service/blade-business/src/main/java/org/springblade/business/controller/ContractLogController.java

@@ -25,6 +25,7 @@ import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
 import org.springblade.business.entity.ContractLog;
 import org.springblade.business.vo.ContractLogVO;
+import org.springblade.business.vo.FileUserVO;
 import org.springblade.core.mp.support.Query;
 import org.springblade.core.tool.api.R;
 import org.springblade.manager.feign.WbsTreeContractClient;
@@ -50,6 +51,24 @@ public class ContractLogController extends BladeController {
 
 	private final WbsTreeContractClient wbsTreeContractClient;
 
+	/**
+	 * 获取当前日志类型的填报人
+	 * @return 结果
+	 */
+	@GetMapping("/queryFillUser")
+	@ApiOperationSupport(order = 3)
+	@ApiOperation(value = "获取当前日志类型的填报人")
+	@ApiImplicitParams({
+			@ApiImplicitParam(name = "wbsNodeId", value = "分类列表的primaryKeyId", required = true),
+			@ApiImplicitParam(name = "contractId", value = "合同段ID", required = true)
+	})
+	public R<List<FileUserVO>> queryFillUser(@RequestParam Long primaryKeyId, @RequestParam Long contractId){
+		ContractLogVO logVo = new ContractLogVO();
+		logVo.setWbsNodeId(primaryKeyId);
+		logVo.setContractId(contractId);
+		return R.data(this.contractLogService.queryFillUser(logVo));
+	}
+
 	/**
 	 * 施工日志分页
 	 * @param logVo 查询条件

+ 47 - 0
blade-service/blade-business/src/main/java/org/springblade/business/controller/FirstInformationController.java

@@ -0,0 +1,47 @@
+package org.springblade.business.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import lombok.AllArgsConstructor;
+
+import org.springblade.core.mp.support.Condition;
+import org.springblade.core.mp.support.Query;
+import org.springblade.core.tool.api.R;
+import org.springframework.web.bind.annotation.*;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.springblade.business.vo.FirstInformationVO;
+import org.springblade.business.service.IFirstInformationService;
+import org.springblade.core.boot.ctrl.BladeController;
+
+/**
+ * 首件信息记录表 控制器
+ *
+ * @author BladeX
+ * @since 2022-06-20
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("/firstInformation")
+@Api(value = "首件信息记录表", tags = "首件信息记录表接口")
+public class FirstInformationController extends BladeController {
+
+	private final IFirstInformationService firstInformationService;
+
+	/**
+	 * 自定义分页 首件信息记录表
+	 */
+	@GetMapping("/page")
+	@ApiOperationSupport(order = 1)
+	@ApiOperation(value = "分页")
+	public R<IPage<FirstInformationVO>> page(FirstInformationVO vo) {
+		//创建分页信息
+		Query query = new Query();
+		query.setCurrent(vo.getCurrent());
+		query.setSize(vo.getSize());
+
+		return R.data(firstInformationService.selectFirstInformationPage(Condition.getPage(query), vo));
+	}
+
+	
+}

+ 16 - 0
blade-service/blade-business/src/main/java/org/springblade/business/controller/UserOpinionController.java

@@ -13,8 +13,10 @@ import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.time.DateUtils;
 import org.springblade.business.entity.UserOpinionFile;
 import org.springblade.business.entity.UserOpinionFlow;
+import org.springblade.business.entity.UserOpinionGood;
 import org.springblade.business.service.IUserOpinionFileService;
 import org.springblade.business.service.IUserOpinionFlowService;
+import org.springblade.business.service.IUserOpinionGoodService;
 import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.mp.support.Condition;
 import org.springblade.core.mp.support.Query;
@@ -64,6 +66,8 @@ public class UserOpinionController extends BladeController {
 
 	private final IUserClient userClient;
 
+	private final IUserOpinionGoodService userOpinionGoodService;
+
 	/**
 	 * 取消点赞
 	 * @param userOpinionId 工单ID
@@ -76,6 +80,11 @@ public class UserOpinionController extends BladeController {
 	public R<Boolean> cancelGood(@RequestParam String userOpinionId){
 		if(StringUtils.isNotEmpty(userOpinionId)){
 			UserOpinion opinion = this.userOpinionService.getById(userOpinionId);
+
+			//删除当前用户对当前工单的点赞信息
+			BladeUser user = AuthUtil.getUser();
+			this.userOpinionGoodService.update(Wrappers.<UserOpinionGood>lambdaUpdate().set(UserOpinionGood::getIsDeleted, 1).eq(UserOpinionGood::getCreateUser, user.getUserId()).eq(UserOpinionGood::getUserOpinionId, userOpinionId));
+
 			//获取原本的点赞数
 			Integer oldGood = opinion.getGoodNumber();
 			return R.data(this.userOpinionService.update(Wrappers.<UserOpinion>lambdaUpdate().set(UserOpinion::getGoodNumber, (oldGood - 1)).eq(UserOpinion::getId, userOpinionId)));
@@ -171,6 +180,13 @@ public class UserOpinionController extends BladeController {
 			//获取原本的点赞数
 			Integer oldGood = opinion.getGoodNumber();
 			opinion.setGoodNumber(oldGood == null || oldGood < 0 ? good : oldGood + good);
+
+			//获取当前用户信息
+			BladeUser user = AuthUtil.getUser();
+			Long deptId = user.getDeptId().contains(",") ? Long.parseLong(user.getDeptId().split(",")[0]) : Long.parseLong(user.getDeptId());
+			//保存点赞信息
+			this.userOpinionGoodService.save(new UserOpinionGood(opinion.getId(), user.getUserId(), deptId));
+
 			return R.data(this.userOpinionService.updateById(opinion));
 		}
 		return R.data(-1, false, "数据操作失败");

+ 36 - 0
blade-service/blade-business/src/main/java/org/springblade/business/controller/UserOpinionGoodController.java

@@ -0,0 +1,36 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.business.controller;
+
+import io.swagger.annotations.Api;
+import lombok.AllArgsConstructor;
+import org.springframework.web.bind.annotation.*;
+import org.springblade.core.boot.ctrl.BladeController;
+
+/**
+ * 点赞记录表 控制器
+ *
+ * @author BladeX
+ * @since 2022-06-21
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("/userOpinionGood")
+@Api(value = "点赞记录表", tags = "点赞记录表接口")
+public class UserOpinionGoodController extends BladeController {
+	
+}

+ 2 - 5
blade-service/blade-business/src/main/java/org/springblade/business/mapper/ContractLogMapper.java

@@ -31,13 +31,10 @@ import java.util.List;
  */
 public interface ContractLogMapper extends BaseMapper<ContractLog> {
 
+	List<ContractLog> queryFillUser(@Param("vo") ContractLogVO vo);
+
 	List<ContractLog> constructionLogPage(@Param("current") Integer current, @Param("size") Integer size, @Param("vo") ContractLogVO vo);
 
 	Integer selectPageCount(@Param("vo") ContractLogVO vo);
 
-	/**
-	 * 自定义分页
-	 */
-	List<ContractLogVO> selectContractLogPage(IPage page, ContractLogVO contractLog);
-
 }

+ 4 - 4
blade-service/blade-business/src/main/java/org/springblade/business/mapper/ContractLogMapper.xml

@@ -24,6 +24,10 @@
         <result column="create_user_name" property="createUserName"/>
     </resultMap>
 
+    <select id="queryFillUser" resultMap="contractLogResultMap">
+      select create_user, create_user_name from u_contract_log where is_deleted = 0 and wbs_node_id = #{vo.wbsNodeId}
+    </select>
+
     <select id="constructionLogPage" resultMap="contractLogResultMap">
         select
           id,
@@ -80,8 +84,4 @@
         </if>
     </select>
 
-    <select id="selectContractLogPage" resultMap="contractLogResultMap">
-        select * from u_contract_log where is_deleted = 0
-    </select>
-
 </mapper>

+ 41 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/FirstInformationMapper.java

@@ -0,0 +1,41 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.business.mapper;
+
+import org.apache.ibatis.annotations.Param;
+import org.springblade.business.entity.FirstInformation;
+import org.springblade.business.vo.FirstInformationVO;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import java.util.List;
+
+/**
+ * 首件信息记录表 Mapper 接口
+ *
+ * @author BladeX
+ * @since 2022-06-20
+ */
+public interface FirstInformationMapper extends BaseMapper<FirstInformation> {
+
+	Integer countFirstInformation(@Param("vo")FirstInformationVO vo);
+
+	/**
+	 * 自定义分页
+	 */
+	List<FirstInformationVO> selectFirstInformationPage(@Param("current")Long current, @Param("size")Long size, @Param("vo")FirstInformationVO vo);
+
+}

+ 86 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/FirstInformationMapper.xml

@@ -0,0 +1,86 @@
+<?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.business.mapper.FirstInformationMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="firstInformationResultMap" type="org.springblade.business.entity.FirstInformation">
+        <result column="id" property="id"/>
+        <result column="create_user" property="createUser"/>
+        <result column="create_user_name" property="createUserName"/>
+        <result column="create_dept" property="createDept"/>
+        <result column="create_time" property="createTime"/>
+        <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="wbs_node_id" property="wbsNodeId"/>
+        <result column="file_name" property="fileName"/>
+        <result column="data_id" property="dataId"/>
+        <result column="report_number" property="reportNumber"/>
+        <result column="report_time" property="reportTime"/>
+        <result column="task_id" property="taskId"/>
+        <result column="classify" property="classify"/>
+    </resultMap>
+
+    <select id="countFirstInformation" resultType="java.lang.Integer">
+        select count(id) from u_first_information
+        where
+          is_deleted = 0
+        <if test="vo.betweenTime != null and vo.betweenTime != ''">
+            and report_time between #{vo.startTime} and #{vo.endTime}
+        </if>
+        <if test="vo.status != null">
+            and status = #{vo.status}
+        </if>
+        <if test="vo.reportNumber != null">
+            and report_number = #{vo.reportNumber}
+        </if>
+        <if test="vo.queryValue != null and vo.queryValue != ''">
+            and file_name like concat('%',#{vo.queryValue},'%')
+        </if>
+        <if test="vo.wbsNodeArray != null and vo.wbsNodeArray.size > 0">
+            and wbs_node_id in
+            <foreach collection="vo.wbsNodeArray" item="wbsNodeIds" open="(" separator="," close=")">
+                #{wbsNodeIds}
+            </foreach>
+        </if>
+    </select>
+
+    <select id="selectFirstInformationPage" resultMap="firstInformationResultMap">
+        select
+          id,
+          file_name,
+          create_user_name,
+          report_number,
+          report_time,
+          wbs_node_id,
+          status,
+          data_id,
+          task_id,
+          classify
+        from u_first_information
+        where
+          is_deleted = 0
+        <if test="vo.betweenTime != null and vo.betweenTime != ''">
+            and report_time between #{vo.startTime} and #{vo.endTime}
+        </if>
+        <if test="vo.status != null">
+            and status = #{vo.status}
+        </if>
+        <if test="vo.reportNumber != null">
+            and report_number = #{vo.reportNumber}
+        </if>
+        <if test="vo.queryValue != null and vo.queryValue != ''">
+            and file_name like concat('%',#{vo.queryValue},'%')
+        </if>
+        <if test="vo.wbsNodeArray != null and vo.wbsNodeArray.size > 0">
+            and wbs_node_id in
+            <foreach collection="vo.wbsNodeArray" item="wbsNodeIds" open="(" separator="," close=")">
+                #{wbsNodeIds}
+            </foreach>
+        </if>
+        order by wbs_node_id, report_time DESC
+        limit ${current}, ${size}
+    </select>
+
+</mapper>

+ 2 - 2
blade-service/blade-business/src/main/java/org/springblade/business/mapper/InformationQueryMapper.xml

@@ -72,7 +72,7 @@
             query.create_time,
             query.task_status,
             query.report_number,
-            query.file_user_name
+            query.file_user_id_and_name
         from
         (
             select
@@ -82,7 +82,7 @@
                 create_time,
                 task_status,
                 report_number,
-                file_user_name,
+                file_user_id_and_name,
                 date_format(create_time,'%Y-%m-%d') as createTimes
             from u_information_query
             where

+ 33 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/UserOpinionGoodMapper.java

@@ -0,0 +1,33 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.business.mapper;
+
+import org.springblade.business.entity.UserOpinionGood;
+import org.springblade.business.vo.UserOpinionGoodVO;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import java.util.List;
+
+/**
+ * 点赞记录表 Mapper 接口
+ *
+ * @author BladeX
+ * @since 2022-06-21
+ */
+public interface UserOpinionGoodMapper extends BaseMapper<UserOpinionGood> {
+
+}

+ 18 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/UserOpinionGoodMapper.xml

@@ -0,0 +1,18 @@
+<?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.business.mapper.UserOpinionGoodMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="userOpinionGoodResultMap" type="org.springblade.business.entity.UserOpinionGood">
+        <result column="id" property="id"/>
+        <result column="create_user" property="createUser"/>
+        <result column="create_dept" property="createDept"/>
+        <result column="create_time" property="createTime"/>
+        <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="user_opinion_id" property="userOpinionId"/>
+    </resultMap>
+
+</mapper>

+ 5 - 5
blade-service/blade-business/src/main/java/org/springblade/business/service/IContractLogService.java

@@ -18,9 +18,12 @@ package org.springblade.business.service;
 
 import org.springblade.business.entity.ContractLog;
 import org.springblade.business.vo.ContractLogVO;
+import org.springblade.business.vo.FileUserVO;
 import org.springblade.core.mp.base.BaseService;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 
+import java.util.List;
+
 /**
  * 日志通用表 服务类
  *
@@ -29,6 +32,8 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
  */
 public interface IContractLogService extends BaseService<ContractLog> {
 
+	List<FileUserVO> queryFillUser(ContractLogVO logVO);
+
 	/**
 	 * 施工日志分页
 	 * @param logVO 查询条件
@@ -36,9 +41,4 @@ public interface IContractLogService extends BaseService<ContractLog> {
 	 */
 	IPage<ContractLogVO> constructionLogPage(ContractLogVO logVO);
 
-	/**
-	 * 自定义分页
-	 */
-	IPage<ContractLogVO> selectContractLogPage(IPage<ContractLogVO> page, ContractLogVO contractLog);
-
 }

+ 56 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/IFirstInformationService.java

@@ -0,0 +1,56 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.business.service;
+
+import org.springblade.business.entity.FirstInformation;
+import org.springblade.business.vo.FirstInformationVO;
+import org.springblade.core.mp.base.BaseService;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+/**
+ * 首件信息记录表 服务类
+ *
+ * @author BladeX
+ * @since 2022-06-20
+ */
+public interface IFirstInformationService extends BaseService<FirstInformation> {
+
+	/**
+	 * 修改首件记录表信息
+	 * @param id 主键
+	 * @param fileName 文件名称
+	 * @param reportNumber 上报批次
+	 * @param status 流程状态
+	 * @return 修改结果
+	 */
+	Boolean updateFirstInformation(Long id, String fileName, Integer reportNumber, Integer status);
+
+	/**
+	 * 保存首件记录表信息
+	 * @param wbsNodeId 当前资料所在节点ID
+	 * @param fileName 文件名称
+	 * @param dataId 数据ID
+	 * @return 保存后数据的ID
+	 */
+	Long saveFirstInformation(Long wbsNodeId, String fileName, Long dataId);
+
+	/**
+	 * 自定义分页
+	 */
+	IPage<FirstInformationVO> selectFirstInformationPage(IPage<FirstInformationVO> page, FirstInformationVO vo);
+
+}

+ 32 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/IUserOpinionGoodService.java

@@ -0,0 +1,32 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.business.service;
+
+import org.springblade.business.entity.UserOpinionGood;
+import org.springblade.business.vo.UserOpinionGoodVO;
+import org.springblade.core.mp.base.BaseService;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+/**
+ * 点赞记录表 服务类
+ *
+ * @author BladeX
+ * @since 2022-06-21
+ */
+public interface IUserOpinionGoodService extends BaseService<UserOpinionGood> {
+
+}

+ 0 - 16
blade-service/blade-business/src/main/java/org/springblade/business/service/IUserOpinionService.java

@@ -1,19 +1,3 @@
-/*
- *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice,
- *  this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright
- *  notice, this list of conditions and the following disclaimer in the
- *  documentation and/or other materials provided with the distribution.
- *  Neither the name of the dreamlu.net developer nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- *  Author: Chill 庄骞 (smallchill@163.com)
- */
 package org.springblade.business.service;
 
 import org.springblade.business.entity.UserOpinion;

+ 0 - 5
blade-service/blade-business/src/main/java/org/springblade/business/service/WeatherInfoService.java

@@ -13,9 +13,4 @@ public interface WeatherInfoService extends IService<WeatherInfo> {
      */
     List<Map<String, List<Map<String,Object>>>> queryWeatherAllByYear(String year, String contractId);
 
-    /**
-     * 自动同步当天天气
-     */
-    void syncWeatherInfo();
-
 }

+ 12 - 5
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/ContractLogServiceImpl.java

@@ -23,12 +23,14 @@ import org.springblade.business.entity.ContractLog;
 import org.springblade.business.vo.ContractLogVO;
 import org.springblade.business.mapper.ContractLogMapper;
 import org.springblade.business.service.IContractLogService;
+import org.springblade.business.vo.FileUserVO;
 import org.springblade.core.mp.base.BaseServiceImpl;
 import org.springblade.core.mp.support.Condition;
 import org.springblade.core.mp.support.Query;
 import org.springframework.stereotype.Service;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -40,6 +42,16 @@ import java.util.List;
 @Service
 public class ContractLogServiceImpl extends BaseServiceImpl<ContractLogMapper, ContractLog> implements IContractLogService {
 
+	@Override
+	public List<FileUserVO> queryFillUser(ContractLogVO logVO) {
+		List<FileUserVO> result = new ArrayList<>();
+		List<ContractLog> logResult = this.baseMapper.queryFillUser(logVO);
+		if(logResult != null && logResult.size() != 0){
+			logResult.forEach(log -> result.add(new FileUserVO(log.getCreateUser().toString(), log.getCreateUserName())));
+		}
+		return result;
+	}
+
 	@Override
 	public IPage<ContractLogVO> constructionLogPage(ContractLogVO logVO) {
 		Integer current = (logVO.getCurrent() - 1) * logVO.getSize();
@@ -64,9 +76,4 @@ public class ContractLogServiceImpl extends BaseServiceImpl<ContractLogMapper, C
 		return iPage.setRecords(voResult);
 	}
 
-	@Override
-	public IPage<ContractLogVO> selectContractLogPage(IPage<ContractLogVO> page, ContractLogVO contractLog) {
-		return page.setRecords(this.baseMapper.selectContractLogPage(page, contractLog));
-	}
-
 }

+ 101 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/FirstInformationServiceImpl.java

@@ -0,0 +1,101 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.business.service.impl;
+
+import cn.hutool.core.date.DateUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import org.apache.commons.lang.StringUtils;
+import org.springblade.business.entity.FirstInformation;
+import org.springblade.business.vo.FirstInformationVO;
+import org.springblade.business.mapper.FirstInformationMapper;
+import org.springblade.business.service.IFirstInformationService;
+import org.springblade.common.utils.SnowFlakeUtil;
+import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springblade.core.secure.BladeUser;
+import org.springblade.core.secure.utils.AuthUtil;
+import org.springframework.stereotype.Service;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 首件信息记录表 服务实现类
+ *
+ * @author BladeX
+ * @since 2022-06-20
+ */
+@Service
+public class FirstInformationServiceImpl extends BaseServiceImpl<FirstInformationMapper, FirstInformation> implements IFirstInformationService {
+
+	@Override
+	public Boolean updateFirstInformation(Long id, String fileName, Integer reportNumber, Integer status) {
+		if(StringUtils.isEmpty(fileName) && reportNumber == null && status == null){
+			return null;
+		} else {
+			FirstInformation update = new FirstInformation();
+			update.setId(id);
+			if(StringUtils.isNotEmpty(fileName)){
+				update.setFileName(fileName);
+			}
+			if(reportNumber != null){
+				update.setReportNumber(reportNumber);
+			}
+			if(status != null){
+				update.setStatus(status);
+			}
+			return this.updateById(update);
+		}
+	}
+
+	@Override
+	public Long saveFirstInformation(Long wbsNodeId, String fileName, Long dataId) {
+		BladeUser bladeUser = AuthUtil.getUser();
+		FirstInformation newData = new FirstInformation(fileName, wbsNodeId, null, 0, bladeUser.getUserId(), bladeUser.getUserName(), bladeUser.getDeptId().contains(",") ? Long.parseLong(bladeUser.getDeptId().split(",")[0]) : Long.parseLong(bladeUser.getDeptId()));
+		newData.setId(SnowFlakeUtil.getId());
+		//将主键返回,保存失败返回null
+		return this.save(newData) ? newData.getId() : null;
+	}
+
+	@Override
+	public IPage<FirstInformationVO> selectFirstInformationPage(IPage<FirstInformationVO> page, FirstInformationVO vo) {
+		//处理分页相关
+		Long current = (page.getCurrent() - 1L) * page.getSize();
+		if(StringUtils.isNotEmpty(vo.getWbsNodeIds()) && !",".equals(vo.getWbsNodeIds())){
+			List<String> wbsNodeArray = JSONArray.parseArray(JSONObject.toJSONString(vo.getWbsNodeIds().split(",")), String.class);
+			wbsNodeArray.removeIf(StringUtils::isEmpty);
+			vo.setWbsNodeArray(wbsNodeArray);
+		}
+		if(StringUtils.isNotEmpty(vo.getBetweenTime())){
+			if(vo.getBetweenTime().contains("~")){
+				String[] between = vo.getBetweenTime().split("~");
+				vo.setStartTime(between[0].trim());
+				vo.setEndTime(between[1].trim());
+			} else {
+				vo.setStartTime(vo.getBetweenTime().trim());
+				vo.setEndTime(DateUtil.format(new Date(), "yyyy-MM-dd"));
+			}
+		}
+		//获取列表总数
+		int countValue = this.baseMapper.countFirstInformation(vo);
+		//设置总数
+		page.setTotal(countValue);
+		return page.setRecords(this.baseMapper.selectFirstInformationPage(current, page.getSize(), vo));
+	}
+
+}

+ 36 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/UserOpinionGoodServiceImpl.java

@@ -0,0 +1,36 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.business.service.impl;
+
+import org.springblade.business.entity.UserOpinionGood;
+import org.springblade.business.vo.UserOpinionGoodVO;
+import org.springblade.business.mapper.UserOpinionGoodMapper;
+import org.springblade.business.service.IUserOpinionGoodService;
+import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springframework.stereotype.Service;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+/**
+ * 点赞记录表 服务实现类
+ *
+ * @author BladeX
+ * @since 2022-06-21
+ */
+@Service
+public class UserOpinionGoodServiceImpl extends BaseServiceImpl<UserOpinionGoodMapper, UserOpinionGood> implements IUserOpinionGoodService {
+
+}

+ 21 - 4
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/UserOpinionServiceImpl.java

@@ -3,19 +3,18 @@ package org.springblade.business.service.impl;
 import cn.hutool.core.date.DateUtil;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.AllArgsConstructor;
 import org.apache.commons.lang.StringUtils;
 import org.apache.http.client.utils.DateUtils;
 import org.springblade.business.entity.UserOpinion;
 import org.springblade.business.entity.UserOpinionFile;
-import org.springblade.business.service.IUserOpinionCommentsService;
-import org.springblade.business.service.IUserOpinionFileService;
-import org.springblade.business.service.IUserOpinionFlowService;
+import org.springblade.business.entity.UserOpinionGood;
+import org.springblade.business.service.*;
 import org.springblade.business.vo.BusinessUserOpinionVO;
 import org.springblade.business.vo.UserOpinionFlowVO;
 import org.springblade.business.vo.UserOpinionVO;
 import org.springblade.business.mapper.UserOpinionMapper;
-import org.springblade.business.service.IUserOpinionService;
 import org.springblade.common.utils.CommonUtil;
 import org.springblade.core.mp.base.BaseServiceImpl;
 import org.springblade.core.mp.support.Condition;
@@ -48,6 +47,8 @@ public class UserOpinionServiceImpl extends BaseServiceImpl<UserOpinionMapper, U
 
 	private final IUserClient userClient;
 
+	private final IUserOpinionGoodService userOpinionGoodService;
+
 	@Override
 	public IPage<BusinessUserOpinionVO> queryBusinessUserOpinionListAll(Query query) {
 		return this.queryBusinessUserOpinionList(null, query);
@@ -202,6 +203,10 @@ public class UserOpinionServiceImpl extends BaseServiceImpl<UserOpinionMapper, U
 		if(currentUserResult != null && currentUserResult.size() != 0){
 			//有数据,查询相关信息
 			List<UserOpinionVO> resultVo = JSONArray.parseArray(JSONObject.toJSONString(currentUserResult), UserOpinionVO.class);
+
+			//获取当前用户的点赞记录
+			List<UserOpinionGood> userGood = this.userOpinionGoodService.list(Wrappers.<UserOpinionGood>lambdaQuery().eq(UserOpinionGood::getCreateUser, users.getUserId()).eq(UserOpinionGood::getIsDeleted, 0));
+
 			resultVo.forEach(vo -> {
 				//查询相关附件
 				List<UserOpinionFile> files = this.userOpinionFileService.selectUserOpinionFileByUserOpinionKey(vo.getId());
@@ -227,6 +232,18 @@ public class UserOpinionServiceImpl extends BaseServiceImpl<UserOpinionMapper, U
 				}catch (Exception e){
 					e.printStackTrace();
 				}
+
+				//判断是否点赞
+				Iterator<UserOpinionGood> iterator = userGood.iterator();
+				while (iterator.hasNext()){
+					UserOpinionGood next = iterator.next();
+					if(next.getUserOpinionId().equals(vo.getId())){
+						vo.setCurrentUserGood(true);
+						iterator.remove();
+						break;
+					}
+				}
+
 			});
 			return page.setRecords(resultVo);
 		}

+ 2 - 0
blade-service/blade-business/src/main/java/org/springblade/business/utils/FunctionMain.java

@@ -171,6 +171,7 @@ public class FunctionMain {
           System.out.println(sql);
     }
 
+/*
     public static void main(String[] args)  {
 //        createTable(Formula.class,"公式配置");
 //        System.out.println(builder(Formula.class));
@@ -187,6 +188,7 @@ public class FunctionMain {
          dap.setRemark("导线点");
         System.out.println(JSON.toJSONString(dap));
     }
+*/
 
 
 }

+ 3631 - 0
blade-service/blade-manager/src/main/java/com/mixsmart/utils/CustomFunction.java

@@ -0,0 +1,3631 @@
+package com.mixsmart.utils;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.jfireel.expression.Expression;
+import com.mixsmart.security.SecurityUtils;
+import org.apache.commons.collections4.MapUtils;
+import org.apache.http.Consts;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.message.BasicNameValuePair;
+import org.springblade.core.tool.utils.CollectionUtil;
+import org.springblade.core.tool.utils.Func;
+
+import java.io.*;
+import java.math.BigDecimal;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+import static java.math.BigDecimal.ROUND_CEILING;
+import static java.math.BigDecimal.ROUND_HALF_UP;
+
+
+public class CustomFunction {
+
+	//定义存储天气数据
+	public static final  Map<String,Object> weatherMap=new HashMap<>();
+	
+	/**
+	 * 类调用地址前缀
+	 */
+	public static final String CLASS_CALL = "T(com.mixsmart.utils.CustomFunction).";
+	public static final String CONCAT = "@";
+	/**
+	 * 获取区间内随机值
+	 * @param min
+	 * @param max
+	 * @param scale 返回值保留的小时位数 (传参为浮点型时使用)
+	 * @return
+	 * @author:rock
+	 * @time:2020年2月20日 下午4:14:00
+	 */
+	public static Object getRangeRandom(Object min, Object max, Object scale) {
+		int sc = objectChangeInt(scale);
+		if(min != null && max != null) {
+			String i = min.toString();
+			String x = max.toString();
+			if(StringUtils.isNumber(i) && StringUtils.isNumber(x)) {
+				Random random = new Random();
+				if(sc == 0) {
+					//整数处理
+					int mi = Integer.parseInt(i);
+					int ma = Integer.parseInt(x);
+					return random.nextInt(ma - mi + 1) + mi;
+				} else if(sc > 0) {
+					//处理浮点数
+					double mi = Double.parseDouble(i);
+					double ma = Double.parseDouble(x);
+					double result = mi + (ma - mi) * random.nextDouble();
+					BigDecimal b = new BigDecimal(result);
+					return b.setScale(sc, ROUND_HALF_UP);
+				}
+			}
+		}
+		return null;
+	}
+	
+	/**
+	 * 取绝对值
+	 * @param value
+	 * @param scaleObj
+	 * @return
+	 * @author:rock
+	 * @time:2020年2月20日 下午5:03:39
+	 */
+	public static Object abs(Object value, Object scaleObj) {
+		if(StringUtils.isNumber(value)) {
+			int scale = objectChangeInt(scaleObj);
+			String valueStr = value.toString();
+			if(scale <= 0) {
+				//整型处理
+				int v = 0;
+				if(valueStr.contains(".")) {
+					v = Integer.parseInt(valueStr.substring(0, valueStr.indexOf(".")));
+				} else {
+					v = Integer.parseInt(valueStr);
+				}
+				return Math.abs(v);
+			} else if(scale > 0) {
+				double d = Math.abs(Double.parseDouble(valueStr));
+				BigDecimal big = new BigDecimal(d);
+				return big.setScale(scale, ROUND_HALF_UP);
+			}
+		}
+		return null;
+	}
+	
+	/**
+	 * 根据指定范围value获取随机数数组
+	 * @param hz 频率
+	 * @param startValue 初始值
+	 * @param rangeValue 范围值
+	 * @param scaleObj 返回列表的数值小数点位数,为0时是整数
+	 * @return
+	 * @author:rock
+	 * @time:2020年4月11日 下午4:53:34
+	 */
+	public static List<Object> getRangeRandomList(Object hz, Object startValue, Object rangeValue, Object scaleObj) {
+		//返回结果列表
+		List<Object> result = new ArrayList<>();
+
+		if(StringUtils.isEmpty(rangeValue) ) {
+			return result;
+		}
+		//返回列表大小
+		int size = objectChangeInt(hz);
+		//小数位数
+		int scale = objectChangeInt(scaleObj);
+
+
+//		if(StringUtils.isEmpty(startValue)){
+//			return result;
+//		}
+
+		//
+		boolean isExistFlag1 = false;
+		boolean isExistFlag2 = false;
+		BigDecimal design = new BigDecimal(0);
+		if(StringUtils.isNumber(startValue)) {
+			design = new BigDecimal(startValue.toString());
+			randomList(result, startValue, rangeValue, design, size, scale);
+		} else if(StringUtils.isNotEmpty(startValue)) {
+			String sv = startValue.toString();
+			int flagIndex = sv.indexOf("1:");
+			if(flagIndex != -1) {
+				isExistFlag1 = true;
+				design = new BigDecimal(sv.substring(flagIndex+2, sv.length()));
+				randomList(result, startValue, rangeValue, design, size, scale);
+			} else if((flagIndex = sv.indexOf("1:")) != -1) {
+				isExistFlag1 = true;
+				design = new BigDecimal(sv.substring(flagIndex+2, sv.length()));
+				randomList(result, startValue, rangeValue, design, size, scale);
+			} else if((flagIndex = sv.indexOf("/")) != -1) {
+				String[] designs = sv.split("/");
+				for (int i = 0; i < designs.length; i++) {
+					String rs = designs[i].trim();
+					if(StringUtils.isNumber(rs)) {
+						List<Object> tmpResult = new ArrayList<>();
+						randomList(tmpResult, startValue, rangeValue, new BigDecimal(rs), size, scale);
+						//分组内混乱
+						Collections.shuffle(tmpResult);
+						result.addAll(tmpResult);
+					}
+				}
+			} else if((flagIndex = sv.indexOf("*")) != -1) {
+				String[] designs = sv.split("\\*");
+				for (int i = 0; i < designs.length; i++) {
+					String rs = designs[i].trim();
+					if(StringUtils.isNumber(rs)) {
+						List<Object> tmpResult = new ArrayList<>();
+
+						randomList(tmpResult, startValue, rangeValue, new BigDecimal(rs), size, scale);
+
+						//分组内混乱
+						Collections.shuffle(tmpResult);
+						if (i == 0) {
+							result.addAll(tmpResult);
+						}else {
+							for (int j=0;j < result.size();j++) {
+								Object tmp = result.get(j) + "×" +  tmpResult.get(j);
+								result.set(j,tmp);
+							}
+						}
+
+					}
+				}
+			}
+			else if((flagIndex = sv.indexOf("×")) != -1 ) {
+				if(rangeValue.toString().contains("×")) {
+					String[] ranges = rangeValue.toString().split("×");
+					String[] designs = sv.split("×");
+					if (ranges.length == designs.length) {
+						for (int i = 0; i < designs.length; i++) {
+							String rs = designs[i].trim();
+							if (StringUtils.isNumber(rs)) {
+								isExistFlag2 = true;
+								randomList(result, startValue, ranges[i], new BigDecimal(rs), size, scale);
+							}
+						}
+					}
+				}else{
+					String[] designs = sv.split("×");
+					for (int i = 0; i < designs.length; i++) {
+						String rs = designs[i].trim();
+						if (StringUtils.isNumber(rs)) {
+							isExistFlag2 = true;
+							randomList(result, startValue, rangeValue, new BigDecimal(rs), size, scale);
+						}
+					}
+				}
+			}
+		} else {
+			//if(rangeValue.toString().contains("<")) {
+				randomList(result, startValue, rangeValue, design, size, scale);
+			//}
+		}
+		
+		if(!result.isEmpty()) {
+			if(isExistFlag1) {
+				List<Object> list = new ArrayList<>();
+				for (Object o : result) {
+					list.add("1:" + o);
+				}
+				result = list;
+			}
+			if(isExistFlag2 && result.size() == 2*size) {
+				List<Object> list = new ArrayList<>();
+				for (int i = 0; i < size; i++) {
+					list.add(result.get(i) + "×" + result.get(i+size));
+				}
+				result = list;
+			}
+		}
+		return result;
+	}
+
+     /*FUNC.groupByStake(桩号,宽幅,数据,模式)*/
+	public  static Object  groupByStake(Object stake,Object line,Object data ,Object mode){
+		if(stake instanceof List){
+			List<Object> _stake =(List<Object>) removeByReg(stake,"ZD\\d*");
+			List<Object> datas = (List<Object>) data;
+			List<Object> result = new ArrayList<>();
+            int max =(int) Math.ceil((double)datas.size()/Double.parseDouble(line.toString()));
+            for(int i=0;i<max&&i<_stake.size();i++){
+            	String s = handleNull(_stake.get(i));
+            	if(StringUtils.isEquals(1,mode)){
+					if(Pattern.matches(".+V$",s)){
+						int ln=StringUtils.handleObj2Integer(line);
+						result.addAll((List<Object>)subList(datas,i*ln+1,(i+1)*ln));
+					}
+				}else{
+					if(!Pattern.matches(".+V$",s)){
+						int ln=StringUtils.handleObj2Integer(line);
+						result.addAll((List<Object>)subList(datas,i*ln+1,(i+1)*ln));
+					}
+				}
+
+			}
+            return result;
+		}
+		return null;
+	}
+
+	/**
+	 * 
+	 * @param result
+	 * @param
+	 * @param
+	 * @param size
+	 * @param scale
+	 * @author:rock
+	 * @time:2020年5月20日 下午2:05:19
+	 */
+	public static void randomList(List<Object> result, Object startValue, Object rangeValue, BigDecimal design, int size, int scale){
+		BigDecimal min = new BigDecimal(0);
+		BigDecimal max = new BigDecimal(0);
+		String[] values = null;
+		String range = rangeValue.toString();
+		if(range.contains(",")) {
+			values = range.split(",");
+			boolean b = false;
+			boolean c = false;
+			if(StringUtils.isNotEmpty(startValue)){
+				int i = 0;
+				for (String value:values){
+
+					if(value.equals(startValue.toString()))
+					{
+						if (i==0) {
+							b = true;
+						}else {
+							c = true;
+						}
+						break;
+					}
+					i++;
+//					if(value.equals(startValue.toString())){
+//						b = true;
+//						break;
+//					}else {
+//						b = false;
+//						c = true;
+//					}
+				}
+			}
+			if(range.contains("%")) {
+				BigDecimal value = new BigDecimal(0);
+				int index = values[0].indexOf("%");
+				if(index != -1) {
+					value = new BigDecimal(values[0].substring(0, index)).divide(new BigDecimal(100));
+					min = design.add(design.multiply(value));
+				} else {
+					value = new BigDecimal(values[0]);
+					min = design.add(design.multiply(value));
+				}
+				index = values[1].indexOf("%");
+				if(index != -1) {
+					value = new BigDecimal(values[1].substring(0, index)).divide(new BigDecimal(100));
+					max = design.add(design.multiply(value));
+				} else {
+					value = new BigDecimal(values[1]);
+					max = design.add(value);
+				}
+			} else if (b){
+				min = new BigDecimal(values[0]);
+				max = new BigDecimal(values[1]);
+			}else if (c){
+				min = design.add(new BigDecimal(values[0]));
+				max = new BigDecimal(values[1]);
+			}else{
+				min = design.add(new BigDecimal(values[0]));
+				max = design.add(new BigDecimal(values[1]));
+			}
+		} else if(range.contains("<")){
+			range = range.replace("<", "");
+			if(StringUtils.isNumber(range)) {
+				if(StringUtils.isNumber(startValue)) {
+					min = design;
+					max = design.add(new BigDecimal(range));
+				} else {
+					max = new BigDecimal(range);
+				}
+			}
+		} else if(range.contains("≤")){
+			range = range.replace("≤", "");
+			if(StringUtils.isNumber(range)) {
+				if(StringUtils.isNumber(startValue)) {
+					min = design;
+					if(scale == 0) {
+						max = design.add(new BigDecimal(range)).add(new BigDecimal(1));
+					} else if(scale > 0){
+						int temp = scale;
+						BigDecimal b = new BigDecimal(1);
+						while (temp > 0) {
+							b = b.divide(new BigDecimal(10), scale, ROUND_HALF_UP);
+							temp--;
+						}
+						max = design.add(new BigDecimal(range)).add(b);
+					}
+				} else {
+					if(scale == 0) {
+						max = new BigDecimal(range).add(new BigDecimal(1));
+					} else if(scale > 0){
+						int temp = scale;
+						BigDecimal b = new BigDecimal(1);
+						while (temp > 0) {
+							b = b.divide(new BigDecimal(10), scale, ROUND_HALF_UP);
+							temp--;
+						}
+						max = new BigDecimal(range).add(b);
+					}
+				}
+			}
+		}
+		else if(range.contains("(")){
+			range = range.replace("(", "");
+			if(StringUtils.isNumber(range)) {
+				min = design;
+				max = design.add(new BigDecimal(range));
+				if (scale > 0) {
+					double sup = 1d/(10*scale);
+					BigDecimal supDec = new BigDecimal(sup);
+
+					if(max.subtract(supDec).compareTo(min.add(supDec)) > 0) {
+						double mi = min.doubleValue() + sup;
+						min = new BigDecimal(mi);
+					}
+				}
+			}
+		}else if(range.contains("%")){
+             min=new BigDecimal(0);
+             range=range.replaceAll("%","");
+             max=design.multiply(new BigDecimal(range)).divide(new BigDecimal(100),scale,ROUND_HALF_UP);
+		}
+		else {
+			if(StringUtils.isNumber(range)) {
+
+				min = design;
+				max = design.add(new BigDecimal(range));
+			}
+		}
+		//范围值大小判断
+		if(min.compareTo(max) > 0) {
+			BigDecimal temp = min;
+			min = max;
+			max = temp;
+		}
+		if(max != null && min != null) {
+			Random random = new Random();
+			if(scale == 0) {
+				//整数处理
+				if(max.compareTo(min.add(new BigDecimal(1))) > 0) {
+
+					if(min.toString().contains(".") || max.toString().contains(".")){
+						//包含小数点时当作小数处理(09-22,2250号单)
+						double mi = min.doubleValue();
+						double ma = max.doubleValue();
+						BigDecimal b = new BigDecimal(0);
+						for (int i = 0; i < size; i++) {
+							b = new BigDecimal(mi + (ma - mi) * random.nextDouble());
+							result.add(b.setScale(scale, ROUND_HALF_UP));
+						}
+
+					} else {
+						//最小值+1是保证生成的随机数不包含临界值
+						int mi = min.intValue() + 1;
+						int ma = max.intValue();
+						int medianvalue = ma - mi;
+						if(medianvalue == 1){
+							ma = ma + 1;
+						}
+						medianvalue = ma - mi;
+						if(medianvalue != 0) {
+							for (int i = 0; i < size; i++) {
+								result.add(random.nextInt(ma - mi) + mi);
+							}
+						}
+					}
+				}else if (max.compareTo(min)==0) {
+					//偏差值为0的处理
+					for (int i = 0; i < size; i++) {
+						result.add(max);
+					}
+				}else if (max.compareTo(min.add(new BigDecimal(1))) == 0    //偏差值就是1,无设计值随机
+						&& max.compareTo(new BigDecimal(1)) == 0) {
+					//偏差值为0的处理
+					for (int i = 0; i < size; i++) {
+						result.add(max);
+					}
+				}
+			} else if(scale > 0){
+				//浮动数处理
+				//double sup = 1d/(10*scale);
+				//BigDecimal supDec = new BigDecimal(sup);
+				//if(max.subtract(supDec).compareTo(min.add(supDec)) > 0) {
+					//临界值问题处理
+					//double mi = min.doubleValue() + sup;
+					//double ma = max.doubleValue() - sup;
+				if(max.compareTo(min) > 0) {
+					double mi = min.doubleValue();
+					double ma = max.doubleValue();
+					BigDecimal b = new BigDecimal(0);
+					for (int i = 0; i < size; i++) {
+						b = new BigDecimal(mi + (ma - mi) * random.nextDouble());
+						result.add(b.setScale(scale, ROUND_HALF_UP));
+					}
+				}else if (max.compareTo(min)==0) {
+					//偏差值为0的处理
+					for (int i = 0; i < size; i++) {
+						result.add(max.setScale(scale, ROUND_HALF_UP));
+					}
+				}
+			}
+		}
+	}
+	
+	/**
+	 * 获取单个随机值
+	 * @param startValue 初始值
+	 * @param rangeValue 偏差范围
+	 * @param scaleObj 保留小数位数
+	 * @return
+	 * @author:rock
+	 * @time:2020年5月18日 下午2:02:57
+	 */
+	public static Object getRangeRandomValue(Object startValue, Object rangeValue, Object scaleObj) {
+		List<Object> list = getRangeRandomList(1, startValue, rangeValue, scaleObj);
+		if(list != null && !list.isEmpty()) {
+			return list.get(0);
+		}
+		return null;
+	}
+	
+	/**
+	 * Object转换int,默认返回0
+	 * @param value
+	 * @return
+	 * @author:rock
+	 * @time:2020年5月15日 下午6:50:06
+	 */
+	public static int objectChangeInt(Object value) {
+		if(StringUtils.isNumber(value)) {
+			String s = value.toString();
+			if(s.contains(".")) {
+				return Integer.parseInt(s.substring(0, s.indexOf(".")));
+			} else {
+				return Integer.parseInt(s);
+			}
+		}
+		return 0;
+	}
+	
+	/**
+	 * 根据桩号类型生成桩号
+	 * @param
+	 * @return
+	 * @author:rock
+	 * @time:2020年4月30日 下午6:09:26
+	 */
+	public static String createStationOld(Object stationType) {
+		if(StringUtils.isEmpty(stationType)) {
+			return null;
+		}
+		String value = "K";
+		String st = String.valueOf(stationType);
+		if(st.contains(value)) {
+			return st;
+		}
+		int len = st.length();
+		if(st.contains(".")) {
+			len = st.indexOf(".");
+		}
+		if(len > 3) {
+			value = value + st.substring(0, len - 3) + "+" + st.substring(len - 3);
+		} else if(len == 3) {
+			value = value + "0+" + st;
+		} else if(len < 3){
+			if(len == 1) {
+				value = value + "0+00" + st;
+			} else if(len == 2){
+				value = value + "0+0" + st;
+			}
+		}
+		return value;
+	}
+
+	/**
+	 * @Description  根据桩号类型生成桩号
+	 * @Param [stationType]
+	 * @return java.lang.String
+	 * @Author yangyj
+	 * @Date 2021.01.20 17:43
+	 **/
+	public static String createStation(Object stationType) {
+		if(StringUtils.isNotEmpty(stationType)) {
+
+		    Matcher m =  matcher("[~|-]",handleNull(stationType));
+		    if(m.find()){
+		    	StringBuilder sb = new StringBuilder();
+		    	String  splitchar = m.group(0);
+                String[] arr = stationType.toString().split(splitchar);
+                for(String str:arr){
+                	sb.append(singleStation(str)+splitchar);
+				}
+                if(sb.length()>0){
+                	return sb.deleteCharAt(sb.length()-1).toString();
+				}
+			}else {
+		    	return  singleStation(stationType);
+			}
+		}
+	    return "";
+	}
+
+	public static Matcher matcher(String regex, String value) {
+		Pattern pattern = Pattern.compile(regex);
+		return pattern.matcher(value);
+	}
+
+	/**
+	 * @Description 记录表5输入桩号代码解析,2G1#1+100>>2G1K0+100
+	 * @Param [stake]
+	 * @return java.lang.String[] result[0]:返回桩号前缀;result[1]:实际显示前缀;result[2]:里程数
+	 * @Author yangyj
+	 * @Date 2021.04.09 11:49
+	 **/
+	public static String[] decodeStake(Object stake){
+		String[] result = new String[]{"","",""};
+		if(StringUtils.isNotEmpty(stake)){
+			String stakeStr = StringUtils.repaceBlank(stake.toString().toUpperCase());
+			Matcher m ;
+			if(stake.toString().contains("+")){
+				m = matcher("(([A-Z0-9]*)(#\\d*)?)\\+([\\d||\\.]*)", stakeStr);
+				if(m.find()){
+					String partNoD = m.group(1);
+					String partNoV = m.group(2);
+					String kilometer = m.group(4);
+					result[0]=partNoD;
+					result[1]=partNoV;
+					result[2]=kilometer;
+				}
+			}else{
+				m =matcher("([A-Z]*)([\\d||\\.]*)", stakeStr);
+				if(m.find()){
+					String partNo = m.group(1);
+					String kilometer = m.group(2);
+					result[0]=partNo;
+					result[1]=partNo;
+					result[2]=kilometer;
+				}
+			}
+
+		}
+		return result;
+	}
+	public static String[] standardStake(Object stake){
+		String[] result = new String[]{"",""};
+		if(StringUtils.isNotEmpty(stake)){
+			String stakeStr = StringUtils.repaceBlank(stake.toString().toUpperCase());
+			Matcher m  = matcher("([A-Z0-9]{0,3})K(\\d{1,3})\\+([\\d||\\.]*)", stakeStr);
+			Matcher m2  = matcher("([A-Z]{0,3})([\\d||\\.]+)", stakeStr);
+			if(m.find()){
+				String partNo = m.group(1);
+				double km = Double.parseDouble(m.group(2));
+				double meter = Double.parseDouble(m.group(3));
+				result[0]=partNo;
+				int scale=getScale(meter);
+				result[1]=StringUtils.number2String(km*1000+meter,scale);
+			}else if(m2.find()){
+				result[0]=m2.group(1);
+				result[1]=m2.group(2);
+			}
+
+		}
+		return result;
+	}
+	/**
+	 * @Description 获取最大小数位
+	 * @Param [number]
+	 * @return int
+	 * @Author yangyj
+	 * @Date 2021.12.23 15:08
+	 **/
+	public  static Integer getScale(Object ...number){
+		int max=0;
+		for(Object n:number){
+			if(StringUtils.isNotEmpty(n)){
+				String[] sa = n.toString().split(",");
+				for(String s:sa){
+					Matcher m = matcher("(\\d)+.(\\d)+",s);
+					if(m.find()){
+						max=Math.max(new StringBuilder(m.group()).reverse().toString().indexOf("."),max);
+					}
+				}
+			}
+		}
+		return max;
+	}
+	public static String singleStation(Object station) {
+		if(StringUtils.isNotEmpty(station)) {
+			Object zhdata =station;
+			String zhdatastr = zhdata.toString().toUpperCase();
+			if(zhdatastr.contains("+")&&zhdatastr.contains("K")){
+				return zhdatastr;
+			}
+			String[] stake = decodeStake(zhdatastr);
+			String partNo =stake[1];
+			String kilometer = stake[2];
+			if(StringUtils.isNotEmpty(kilometer)){
+				partNo= handleNull(partNo);
+				int ks = (int) Math.floor(Double.parseDouble(kilometer)/1000);
+				double ke =new BigDecimal(kilometer).subtract(new BigDecimal(String.valueOf(ks*1000))).doubleValue();
+				String temp = ""+ke;
+				if((int)Double.parseDouble(temp)==Double.parseDouble(temp)){
+					temp = String.valueOf((int)Double.parseDouble(temp));
+				}
+				String sf="000";
+				if(temp.length()<3){
+					temp = sf.substring(0,3-temp.length())+temp;
+				}
+				if((temp.contains(".")&&temp.indexOf(".")<=2)){
+					temp = sf.substring(0,3-temp.indexOf("."))+temp;
+				}
+				return  partNo+"K"+ks+"+"+temp;
+			}
+		}
+		return "";
+	}
+	
+
+	public static Object calculate(Object a, Object b, Object scaleObj, Integer type) {
+		boolean nullFlag = false;
+		if(type == null) {
+			return null;
+		}
+		if (StringUtils.isEmpty(a)&&StringUtils.isEmpty(b)){
+			return null;
+		}
+		if(StringUtils.isEmpty(a) && type == 7){
+			nullFlag = true;
+			a=0;
+		}
+		if(StringUtils.isEmpty(b) && type == 7){
+			nullFlag = true;
+			b=0;
+		}
+		if(StringUtils.isNotEmpty(a) && StringUtils.isNotEmpty(b)) {
+			try {
+				int scale = objectChangeInt(scaleObj);
+				String aStr = a.toString();
+				String bStr = b.toString();
+				double ad = Double.parseDouble(aStr);
+				double bd=0;
+				if (type == 6) {
+					//判断设计值是否包含"/"
+					if (bStr.contains("/")){
+						bd = bStr.split("/").length;
+						return  (int) (ad*bd);
+					}else{
+						return  (int) ad;
+					}
+				}
+				bd = Double.parseDouble(bStr);
+				double result = 0;
+				if(type == 1) {
+					result = ad+bd;
+				} else if(type == 2) {
+					result = ad-bd;
+				} else if(type == 3) {
+					result = ad*bd;
+				} else if(type == 4) {
+					result = ad/bd;
+				} else if(type == 5) {
+					result = ad%bd;
+				} else if(type == 7&&ad*bd!=0&&!nullFlag){
+					return  (int) Math.ceil(ad*bd);
+				}else {
+					return null;
+				}
+				BigDecimal big = new BigDecimal(result);
+				return big.setScale(scale, ROUND_HALF_UP);
+			} catch (NumberFormatException e) {
+				e.printStackTrace();
+			}
+		}
+		return null;
+	}
+
+
+
+	/**
+	 * 求列表内数据的平均值
+	 * @param scaleObj 平均值保留小数位数,0时为整数
+	 * @param list
+	 * @return
+	 * @author:rock
+	 * @time:2020年5月8日 下午4:20:10
+	 */
+	public static Object avg(Integer scaleObj, List<Object> list) {
+		Object result = null;
+		if(ListUtils.isNotEmpty(list)){
+			int size = list.size();
+			if(list != null && size > 0) {
+				int scale = objectChangeInt(scaleObj);
+				double sum = 0;
+				for (Object data : list) {
+					if(StringUtils.isNumber(data)) {
+						sum += Double.parseDouble(data.toString());
+					} else {
+						//非数字类型则忽略,且总数大小要减一
+						size--;
+					}
+				}
+				if(scale == 0) {
+					//整数处理
+					result = (int)(sum / size);
+				} else if(scale > 0) {
+					result = new BigDecimal(sum).divide(new BigDecimal(size), scale, ROUND_HALF_UP);
+				}
+			}
+		}
+		return result;
+	}
+	
+
+	
+	/**
+	 * 列表求和
+	 * @param scaleObj
+	 * @param list
+	 * @return
+	 * @author:rock
+	 * @time:2020年5月18日 下午2:26:26
+	 */
+	public static Object sum(Object scaleObj, List<Object> list) {
+		Object result = null;
+		if(list != null && list.size() > 0) {
+			int scale = objectChangeInt(scaleObj);
+			double sum = 0;
+			for (Object data : list) {
+				if(StringUtils.isNumber(data)) {
+					sum += Double.parseDouble(data.toString());
+				}
+			}
+			if(scale == 0) {
+				//整数
+				result = (int)sum;
+			} else if(scale > 0) {
+				//浮点数
+				BigDecimal big = new BigDecimal(sum);
+				result = big.setScale(scale, ROUND_HALF_UP);
+			}
+		}
+		return result;
+	}
+	
+	/**
+	 * 桩长实际值=桩长设计值+范围值(0~0.1m)的随机数
+	 * @param designValue
+	 * @param range
+	 * @param scale
+	 * @return
+	 * @author:rock
+	 * @time:2020年5月19日 下午3:57:26
+	 */
+	public static Object pileLengthValue(Object designValue, Object range, Object scale) {
+		if(StringUtils.isNumber(designValue) && StringUtils.isNotEmpty(range)) {
+			int sc = objectChangeInt(scale);
+			Object randomValue = getRangeRandomValue(0, range, sc);
+			if(StringUtils.isNumber(randomValue)) {
+				BigDecimal big = new BigDecimal(designValue.toString()).add(new BigDecimal(randomValue.toString()));
+				designValue = big.setScale(sc, ROUND_HALF_UP);
+			}
+		}
+		return designValue;
+	}
+	
+	/**
+	 * 判断value是否存在range范围内
+	 * @param value
+	 * @param rangeValue 格式 “1,10” ;即最小值和最大值加用逗号隔开 
+	 * @return
+	 * @author:rock
+	 * @time:2020年5月28日 下午4:40:53
+	 */
+	public static boolean existInRange(Object value, Object rangeValue) {
+		if(StringUtils.isNumber(value) && rangeValue != null) {
+			BigDecimal min = new BigDecimal(0);
+			BigDecimal max = new BigDecimal(0);
+			String[] values = null;
+			String range = rangeValue.toString();
+			if(range.contains(",")) {
+				values = range.split(",");
+				if(StringUtils.isNumber(values[0]) && StringUtils.isNumber(values[1])) {
+					min = new BigDecimal(values[0]);
+					max = new BigDecimal(values[1]);
+				}
+			} else if(range.contains("<")){
+				range = range.replace("<", "");
+				if(StringUtils.isNumber(range)) {
+					max = new BigDecimal(range);
+				}
+			} else if(range.contains("≤")){
+				range = range.replace("≤", "");
+				if(StringUtils.isNumber(range)) {
+					max = new BigDecimal(range);
+				}
+			} else {
+				if(StringUtils.isNumber(range)) {
+					max = new BigDecimal(range);
+				}
+			}
+			//范围值大小判断
+			if(min.compareTo(max) > 0) {
+				BigDecimal temp = min;
+				min = max;
+				max = temp;
+			}
+			BigDecimal v = new BigDecimal(value.toString());
+			if(v.compareTo(min) > 0 && v.compareTo(max) < 0) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * 判断value是否存在range范围内
+	 * @param value
+	 * @param rangeValue 格式 “1,10” ;即最小值和最大值加用逗号隔开
+	 * @return
+	 * @author:rock
+	 * @time:2020年5月28日 下午4:40:53
+	 */
+	public static boolean existInRangeAbs(Object value, Object rangeValue) {
+		if(StringUtils.isNumber(value) && rangeValue != null) {
+			BigDecimal min = new BigDecimal(0);
+			BigDecimal max = new BigDecimal(0);
+			String[] values = null;
+			String range = rangeValue.toString();
+			if(range.contains(",")) {
+				values = range.split(",");
+				if(StringUtils.isNumber(values[0]) && StringUtils.isNumber(values[1])) {
+					min = new BigDecimal(values[0]);
+					max = new BigDecimal(values[1]);
+				}
+			} else if(range.contains("<")){
+				range = range.replace("<", "");
+				if(StringUtils.isNumber(range)) {
+					max = new BigDecimal(range);
+				}
+			} else if(range.contains("≤")){
+				range = range.replace("≤", "");
+				if(StringUtils.isNumber(range)) {
+					max = new BigDecimal(range);
+				}
+			} else {
+				if(StringUtils.isNumber(range)) {
+					max = new BigDecimal(range);
+				}
+			}
+			//范围值大小判断
+			if(min.compareTo(max) > 0) {
+				BigDecimal temp = min;
+				min = max;
+				max = temp;
+			}
+			BigDecimal v = new BigDecimal(value.toString());
+			v =v.abs();
+
+			if(v.compareTo(min) > 0 && v.compareTo(max) < 0) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 *  @author: willSir
+	 *  @Date:  2020/8/14 - 11:40
+	 *  @Description:
+	 *  检验时间获取的如果是施工时间,施工时间时间段为一天内,就只显示施工开始时间,如果时间段不是同一天,就获取施工结束时间。
+	 *  需要修改:TABLE['t_pf_RecordTable015']['shigongkaishiriqi']+'~'+TABLE['t_pf_RecordTable015']['shigongjieshuriqi']
+	 *  为:FUNC.existOneDay(TABLE['t_pf_RecordTable015']['shigongkaishiriqi'],TABLE['t_pf_RecordTable015']['shigongjieshuriqi'])
+	 */
+	public static Object existOneDay(Object value1, Object value2){
+		if(null==value1 && null==value2){
+			return null;
+		}else if(StringUtils.isNotEmpty(value2)){
+			return  value2.toString();
+		}else if(StringUtils.isNotEmpty(value1)){
+			return  value1.toString();
+		}else {
+			return value2.toString();
+		}
+
+	}
+	/**
+	 *  @author: willSir
+	 *  @Date:  2020/8/17 - 9:54
+	 *  @Description:  一个自定义的预防公式报错的方法
+	 *  FUNC.correctFormula(“公式错误”)
+	 */
+	public static Object correctFormula(String str){
+ 		if(StringUtils.isNotEmpty(str)) {
+			return str;
+		}
+ 		return "";
+	}
+
+
+	/** * 对年月日进行组合成日期格式
+	 * @param year 年 month 月 day 日
+	 * @return String 日期格式的字符串
+	 * @author:renhao
+	 * @time:2020年8月18日
+	 **/
+	public  static  String dataProcessing(int year,int month,int day){
+		if(month>=10){
+			if(day>=10){
+				return year+"."+month+"."+day;
+			}else {
+				return year+"."+month+".0"+day;
+			}
+		}else {
+			if(day>=10){
+				return year+".0"+month+"."+day;
+			}else {
+				return year+".0"+month+".0"+day;
+			}
+		}
+	}
+	/**
+	 * @Description  输出勾选复选框
+	 * @Param [o1, o2]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2021.06.29 10:35
+	 **/
+	public  static Object checkbox(Object o1,Object o2){
+		if(StringUtils.isNotEmpty(o1)&&StringUtils.isNotEmpty(o2)){
+			if(o1.equals(o2)){
+				return "\u2611";
+			}
+		}
+		return "";
+	}
+	/**
+	 * @Description 返回n个空格,用于输出字符串格式化
+	 * @Param [n]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2021.06.29 11:41
+	 **/
+	public  static Object space(Object n){
+		if(StringUtils.isNumber(n)){
+			return  String.join("", Collections.nCopies(Integer.parseInt(n.toString()), "\u0020"));
+		}
+		return "";
+	}
+
+
+
+
+
+
+	public  static Object storageTime(Object years){
+       if(StringUtils.isNotEmpty(years)){
+       	 if(StringUtils.isEquals("9999",years)){
+       	 	return "永久";
+		 }else{
+            return years+"年";
+		 }
+	   }
+       return "";
+	}
+
+
+
+
+	public  static Object extractName(Object name){
+		if(StringUtils.isNotEmpty(name)){
+			String fileName = handleNull(name);
+			int index = fileName.lastIndexOf(".pdf");
+			if(index==-1){
+				return  fileName;
+			}else{
+			    return fileName.substring(0,fileName.lastIndexOf("."));
+			}
+		}
+		return "";
+	}
+
+
+
+	/**
+	 * @Description 字符串中是包含中文
+	 * @Param [chars]
+	 * @return boolean
+	 * @Author yangyj
+	 * @Date 2021.09.17 14:31
+	 **/
+   public  static boolean containsZH(Object chars){
+		Matcher m =matcher("[\u4e00-\u9fa5]",handleNull(chars));
+		 return m.find();
+   }
+
+	/**
+	 * @Description 字符串中是包含数字
+	 * @Param [chars]
+	 * @return boolean
+	 * @Author yangyj
+	 * @Date 2021.09.17 14:31
+	 **/
+	public  static boolean containsD(Object chars){
+		Matcher m =matcher("\\d",handleNull(chars));
+		return m.find();
+	}
+
+
+	/**
+	 * @Description 封装超链接
+	 * @Param [uri]
+	 * @return java.lang.String
+	 * @Author yangyj
+	 * @Date 2021.10.14 16:15
+	 **/
+   public static String uri(Object uri){
+   	 if(StringUtils.isNotEmpty(uri)){
+   	 	return "URI<"+handleNull(uri)+">";
+	 }
+   	  return "";
+   }
+
+
+
+
+
+
+
+
+
+	/**
+	 * @Description  获取相隔多少天后的日期
+	 * @Param [date, n:相隔天数,正数代表未来,负数代表历史]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2021.10.27 10:21
+	 **/
+	public static Object dateAfter(Object date ,Object n){
+		if(StringUtils.isNotEmpty(date)&&StringUtils.isNumber(n)){
+			Calendar cal = Calendar.getInstance();
+			Date d= parseDate(date.toString());
+			if(d!=null){
+				cal.setTime(d);
+				cal.add(Calendar.DATE,StringUtils.handObj2Integer(n));
+				if(date.toString().contains("-")){
+					return dateToStr(cal.getTime(),"yyyy-MM-dd");
+				}	if(date.toString().contains("年")){
+					return dateToStr(cal.getTime(),"yyyy年MM月dd日");
+				}else{
+					return dateToStr(cal.getTime(),"yyyy.MM.dd");
+				}
+			}
+		}
+		return "";
+	}
+
+	public static String dateToStr(Date date, String formatter) {
+		String value = null;
+		if(null != date) {
+			if(StringUtils.isEmpty(formatter)) {
+				formatter = "yyyy-MM-dd HH:mm:ss";
+			}
+			SimpleDateFormat dateFormat = new SimpleDateFormat(formatter);
+			value = dateFormat.format(date);
+			dateFormat = null;
+		}
+		return value;
+	}
+
+
+
+	private static Object crack(String password){
+//		return  SecurityUtils.desDecode(password, SSOUtils.getSecretKey());
+		return  SecurityUtils.desDecode(password, "qazwertyuioptgb");
+	}
+	/**
+	 * @Description 计算t1~t2,t3~t4 两个时间段的合计时间,unit 输入数值的单位
+	 * @Param [t1, t2, t3, t4, unit]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2021.07.02 15:47
+	 **/
+	public static Object totalTime(Object t1,Object t2,Object t3,Object t4,Object unit){
+		if(StringUtils.isNotEmpty(t1)&&StringUtils.isNotEmpty(t2)&&StringUtils.isNotEmpty(t3)&&StringUtils.isNotEmpty(t4)&&StringUtils.isNotEmpty(unit)){
+			return 	conversionUnit((Long.parseLong(minutesPassedRecent(t1,t2).toString())+Long.parseLong(minutesPassedRecent(t3,t4).toString())),unit);
+		}
+		return  "";
+	}
+	/**
+	 * @Description 字符串日期转指定格式日期
+	 * @Param [date, format:输出格式]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2021.07.02 15:55
+	 **/
+	public  static  Object dateFormatter(Object date,Object format){
+		if(StringUtils.isNotEmpty(date)&&StringUtils.isNotEmpty(format)){
+			Matcher m =	matcher("(\\d{4})\\D(\\d{2})\\D(\\d{2})日?\\s*(\\d{0,2})(\\D\\d{1,2})?",date.toString());
+            if(m.find()){
+                  String yyyy = handleNull(m.group(1));
+				  String MM = handleNull(m.group(2));
+				  String dd = handleNull(m.group(3));
+				  String HH = handleNull(m.group(4));
+			      String mm = handleNull(m.group(5));
+				  String d = handleNull(format);
+                  if(StringUtils.isNotEmpty(yyyy)){
+                  	d=d.replace("yyyy",yyyy);
+				  }
+				  if(StringUtils.isNotEmpty(MM)){
+					d=d.replace("MM",MM);
+			 	  }
+				  if(StringUtils.isNotEmpty(dd)){
+					d=d.replace("dd",dd);
+				  }
+			      if(StringUtils.isNotEmpty(HH)){
+			    		d=d.replace("HH",HH);
+			      }
+			    	if(StringUtils.isNotEmpty(mm)){
+			    		mm=mm.replaceAll("\\D","");
+			    		d=d.replace("mm",mm);
+			    	}
+			    	return  d;
+			}
+		}
+		return "";
+	}
+	/**
+	 * @Description 字符串日期转指定格式日期
+	 * @Param [date, format1:输入格式, format2:输出格式]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2021.07.02 15:57
+	 **/
+//	public  static  Object dateFormatter(Object date,Object format1,Object format2){
+//		if(StringUtils.isNotEmpty(date)&&StringUtils.isNotEmpty(format1)&&StringUtils.isNotEmpty(format2)){
+//			return 	dateToStr(parseDate(date.toString(),format1.toString()),format2.toString()) ;
+//		}
+//		return "";
+//	}
+
+
+	/**
+	 * @Description 求偏差值
+	 * @Param [list, design]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2021.09.18 10:43
+	 **/
+	public  static  Object deviation(Object list,Object design){
+		if(StringUtils.isNotEmpty(list)&&StringUtils.isNumber(design)){
+			List<Object> result = new ArrayList<>();
+			List<Object> tmp;
+			if(list instanceof List){
+				tmp = (List<Object>) list;
+			}else{
+				tmp=Arrays.asList(list.toString().split("[,|-|~|,]"));
+			}
+			int dev =StringUtils.handObj2Integer(design);
+			for(Object e:tmp){
+				if(containsZH(e)){
+					/*不允许包含中文*/
+					return "";
+				}
+				result.add(StringUtils.handObj2Integer(e)-dev);
+			}
+			if(ListUtils.isNotEmpty(result)){
+				return result;
+			}
+		}
+		return "";
+	}
+
+
+
+	/**
+	 * @Description 把日期格式化成 'xxxx年xx月xx日 星期x' 字符串
+	 * @Param [date]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2021.06.21 14:27
+	 **/
+    public  static  Object toDateAndWeek(Object date){
+		if(StringUtils.isNotEmpty(date)){
+			Date d = parseDate(handleNull(date));
+			String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
+			Calendar calendar=Calendar.getInstance();
+			assert d != null;
+			calendar.setTime(d);
+			String week = weekDays[calendar.get(Calendar.DAY_OF_WEEK)-1];
+			return  dateToStr(d,"yyyy年MM月dd日")+" "+week;
+		}
+		return  null;
+	}
+
+	public static  Object conversionUnit(Object data,Object unit){
+    	if(StringUtils.isNumber(data)&&StringUtils.isNotEmpty(unit)){
+    		//统一转化成毫秒在处理
+			long ms=0;
+			long l=Long.parseLong(data.toString());
+			final long s=1000L;
+			final long m=s*60;
+			final long H=m*60;
+			final long D=H*24;
+			final long M=D*30;
+			final long Y=D*365;
+			if(StringUtils.isEquals("Y",unit.toString())){
+				ms=l*Y;
+			}else if(StringUtils.isEquals("M",unit.toString())){
+				ms=l*M;
+			}else if(StringUtils.isEquals("D",unit.toString())){
+				ms=l*D;
+			}else if(StringUtils.isEquals("H",unit.toString())){
+				ms=l*H;
+			}else if(StringUtils.isEquals("m",unit.toString())){
+				ms=l*m;
+			}
+            StringBuilder sb = new StringBuilder();
+			if(ms/Y!=0){
+				sb.append(ms/Y).append("年");
+				ms=ms%Y;
+			}
+			if(ms/M!=0){
+				sb.append(ms/M).append("月");
+				ms=ms%M;
+			}
+			if(ms/D!=0){
+				sb.append(ms/D).append("日");
+				ms=ms%D;
+			}
+			if(ms/H!=0){
+				sb.append(ms/H).append("时");
+				ms=ms%H;
+			}
+			if(ms/m!=0){
+				sb.append(ms/m).append("分");
+				ms=ms%m;
+			}
+			if(sb.length()>0){
+				return sb.toString();
+			}
+		}
+		return  "";
+	}
+
+	public static  Object fileSize(Object data){
+    	return fileSize(data,null);
+	}
+	public static  Object fileSize(Object data,Object unit){
+		if(StringUtils.isNumber(data)){
+			if(StringUtils.isEmpty(unit)){
+				unit="K";
+			}
+			//统一转化成KB在处理
+			long ms=0;
+			long l=Long.parseLong(data.toString());
+			final long KB=1L;
+			final long MB=1024*KB;
+			final long GB=1024*MB;
+			final long TB=1024*GB;
+			if(StringUtils.isEquals("K",unit.toString().toUpperCase())){
+				ms=l*KB;
+			}else if(StringUtils.isEquals("M",unit.toString().toUpperCase())){
+				ms=l*MB;
+			}else if(StringUtils.isEquals("G",unit.toString().toUpperCase())){
+				ms=l*GB;
+			}else if(StringUtils.isEquals("T",unit.toString().toUpperCase())){
+				ms=l*TB;
+			}
+			if(ms/TB!=0){
+		        return  new BigDecimal(ms).divide(new BigDecimal(TB),2,ROUND_HALF_UP)+"TB";
+			}
+			if(ms/GB!=0){
+				return  new BigDecimal(ms).divide(new BigDecimal(GB),1,ROUND_HALF_UP)+"GB";
+			}
+			if(ms/MB!=0){
+				return  new BigDecimal(ms).divide(new BigDecimal(MB),0,ROUND_HALF_UP)+"MB";
+			}
+			return ms+"KB";
+		}
+		return  "";
+	}
+
+	public static  Object hoursPassed(Object t1,Object t2){
+    	return timePassed(t1,t2,"H",0,"yyyy-MM-dd HH");
+	}
+	public static  Object minutesPassed(Object t1,Object t2){
+		return timePassed(t1,t2,"m",0,"yyyy-MM-dd HH:mm");
+	}
+	/**
+	 * @Description 输入时间格式:mm:ss(例如01:33)
+	 * @Param [t1, t2]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2021.07.02 17:45
+	 **/
+	public static  Object minutesPassedRecent(Object t1,Object t2){
+		String year = Calendar.getInstance().get(Calendar.YEAR)+".";
+		int month= Calendar.getInstance().get(Calendar.MONTH)+1;
+		String mstr="";
+		if(month<10){
+			mstr="0"+month+".";
+		}else{
+			mstr=month+".";
+		}
+		int day =   Calendar.getInstance().get(Calendar.DATE)+1;
+		String dstr="";
+		if(day<10){
+			dstr ="0"+day+" ";
+		}else {
+			dstr =day+" ";
+		}
+		t1=year+mstr+dstr+t1;
+		t2=year+mstr+dstr+t2;
+		return timePassed(t1,t2,"m",0,"yyyy-MM-dd HH:mm");
+	}
+	public static  Object hoursPassedRecent(Object t1,Object t2){
+    	 String year = Calendar.getInstance().get(Calendar.YEAR)+"年";
+         t1=year+t1;t1=t1.toString().replace("日"," ").replace("时"," ");
+         t2=year+t2;t2=t2.toString().replace("日"," ").replace("时"," ");
+		return timePassed(t1,t2,"H",0,"yyyy-MM-dd HH");
+	}
+	public static Date parseDate(String dateStr) {
+		if(StringUtils.isEmpty(dateStr)) {
+			return null;
+		}
+		if(!dateStr.contains("-")){
+			dateStr=StringUtils.repaceBlank(dateStr);
+			Matcher m =	matcher("\\d{4}(.)\\d{2}(.)\\d{2}(.?)",dateStr);
+			if(m.find()){
+				Set<String> set = new HashSet<>();
+				set.add(m.group(1));
+				set.add(m.group(2));
+				if(StringUtils.isNotEmpty(m.group(3))){
+					set.add(m.group(3));
+				}
+				if(!set.isEmpty()){
+					for(String str:set){
+						dateStr=dateStr.replace(str,"-");
+					}
+				}
+			}
+		}
+		Date datetime = null;
+		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+		try {
+			datetime = dateFormat.parse(dateStr);
+		} catch (ParseException e) {
+			e.printStackTrace();
+		}
+		return datetime;
+	}
+	public static Date parseDate(String dateStr,String format) {
+		if(StringUtils.isEmpty(dateStr)||StringUtils.isEmpty(format)) {
+			return null;
+		}
+		if(!dateStr.contains("-")){
+			Matcher m =	matcher("\\d{4}(.)\\d{2}(.)\\d{2}(日?)",dateStr);
+			if(m.find()){
+				Set<String> set = new HashSet<>();
+				set.add(m.group(1));
+				set.add(m.group(2));
+				if(StringUtils.isNotEmpty(m.group(3))){
+					dateStr=dateStr.replace(m.group(3),"");
+				}
+				if(!set.isEmpty()){
+					for(String str:set){
+						dateStr=dateStr.replace(str,"-");
+					}
+				}
+			}
+		}
+		Date datetime = null;
+		SimpleDateFormat dateFormat = new SimpleDateFormat(format);
+		try {
+			datetime = dateFormat.parse(dateStr);
+		} catch (ParseException e) {
+			e.printStackTrace();
+		}
+		return datetime;
+	}
+	public static String handleNull(Object obj) {
+		if (null == obj) {
+			return "";
+		} else {
+			return obj.toString().trim();
+		}
+	}
+
+	/**
+	 * @Description 返回时间间隔差
+	 * @Param [t1:开始时间, t2:结束时间, mode:返回值单位:Y年 M月 D日 H时 m分,scale:保留小数位, format:输入日期格式]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2021.07.01 09:57
+	 **/
+	public static  Object timePassed(Object t1,Object t2,Object mode,Object scale,Object format){
+    	if(StringUtils.isNotEmpty(t1)&&StringUtils.isNotEmpty(t2)&&StringUtils.isNotEmpty(mode)&&StringUtils.isNotEmpty(scale)&&StringUtils.isNotEmpty(format)){
+//    		mode=mode.toString().toUpperCase();
+			Date d1 = parseDate(handleNull(t1),handleNull(format));
+			Date d2 = parseDate(handleNull(t2),handleNull(format));
+			assert d2 != null;
+			assert d1 != null;
+			if(d1.after(d2)&&StringUtils.isEquals("H",mode)){
+				/*假如是计算相差单位是小时,当开始时间大于结束时间,需要考虑跨年的情况*/
+                   Calendar c =Calendar.getInstance();
+                   c.setTime(d1);
+				   c.add(Calendar.YEAR, -1);
+				   d1=c.getTime();
+			}
+			long range = d2.getTime()-d1.getTime();
+			long r=0;
+			if(StringUtils.isEquals("Y",mode.toString())){
+                r=range/(1000L *3600*24*365);
+			}else if(StringUtils.isEquals("M",mode.toString())){
+				r=range/(1000L *3600*24*30);
+			}else if(StringUtils.isEquals("D",mode.toString())){
+				r=range/(1000L *3600*24);
+			}else if(StringUtils.isEquals("H",mode.toString())){
+				r=range/(1000L *3600);
+			}else if(StringUtils.isEquals("m",mode.toString())){
+				r=range/(1000L *60);
+			}
+			BigDecimal b = new BigDecimal(r);
+			if(!StringUtils.isNumber(scale)){
+                 scale=0;
+			}
+			return b.setScale(Integer.parseInt(scale.toString()),ROUND_HALF_UP);
+		}
+    	return "";
+	}
+
+
+
+
+
+	public static Object k2d(Object k){
+		Matcher mt = matcher("[A-Z]*(\\d*)\\+([\\d|\\.]*)",k.toString());
+		if(mt.find()){
+		   return  Double.parseDouble(mt.group(1))*1000+Double.parseDouble(mt.group(2));
+		}
+		return -1;
+	}
+
+	/**
+	 * @Description   开方
+	 * @Param [a:被开方数, scale:结果的小数位]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2020.12.10 15:10
+	 **/
+	public static Object sqrt(Object a,Object scale) {
+		if(StringUtils.isNumber(a)&&StringUtils.isNumber(scale)){
+			Double d = Math.sqrt(Double.parseDouble(a.toString()));
+			BigDecimal r = new BigDecimal(d);
+			return  r.setScale((int)Double.parseDouble(scale.toString()), ROUND_HALF_UP);
+		}
+		return 0;
+	}
+	/**
+	 * @Description   开方
+	 * @Param [a:被开方数 结果取整]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2020.12.10 15:10
+	 **/
+	public static Object sqrt(Object a) {
+		if(StringUtils.isNumber(a)){
+			return sqrt(a,0);
+		}
+		return 0;
+	}
+
+	/**
+	 * @Description   两者最大值
+	 * @Param [a:被开方数, scale:结果的小数位]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2020.12.10 15:10
+	 **/
+	public static Object max(Object a,Object b,Object scale) {
+		if(StringUtils.isNumber(a)&&StringUtils.isNumber(b)&&StringUtils.isNumber(scale)){
+			Double d = Math.max(Double.parseDouble(a.toString()),Double.parseDouble(b.toString()));
+			BigDecimal r = new BigDecimal(d);
+			return  r.setScale((int)Double.parseDouble(scale.toString()), ROUND_HALF_UP);
+		}
+		return 0;
+	}
+
+	/**
+	 * @Description   两者最大值
+	 * @Param [a:被开方数, scale:结果取整]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2020.12.10 15:10
+	 **/
+	public static Object max(Object a,Object b) {
+		a=parse(a);
+		b=parse(b);
+		if(StringUtils.isNumber(a)&&StringUtils.isNumber(b)){
+			return  max(a,b,0);
+		}
+		return 0;
+	}
+
+    /**
+     * @Description   两者最小值
+     * @Param [a:被开方数, scale:结果的小数位]
+     * @return java.lang.Object
+     * @Author yangyj
+     * @Date 2020.12.10 15:10
+     **/
+    public static Object min(Object a,Object b,Object scale) {
+        if(StringUtils.isNumber(a)&&StringUtils.isNumber(b)&&StringUtils.isNumber(scale)){
+            double d = Math.min(Double.parseDouble(a.toString()),Double.parseDouble(b.toString()));
+            BigDecimal r = new BigDecimal(d);
+            return  r.setScale((int)Double.parseDouble(scale.toString()), ROUND_HALF_UP);
+        }
+        return 0;
+    }
+
+    /**
+     * @Description   两者最小值
+     * @Param [a:被开方数, scale:结果取整]
+     * @return java.lang.Object
+     * @Author yangyj
+     * @Date 2020.12.10 15:10
+     **/
+    public static Object min(Object a,Object b) {
+    	a=parse(a);
+    	b=parse(b);
+        if(StringUtils.isNumber(a)&&StringUtils.isNumber(b)){
+            return  min(a,b,0);
+        }
+        return 0;
+    }
+
+	/**
+	 * @Description   平方
+	 * @Param [a:开方数, scale:结果的小数位]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2020.12.10 15:10
+	 **/
+	public static Object pow(Object a,Object b,Object scale) {
+		if(StringUtils.isNumber(a)&&StringUtils.isNumber(b)&&StringUtils.isNumber(scale)){
+			double d = Math.pow(Double.parseDouble(a.toString()),Double.parseDouble(b.toString()));
+			BigDecimal r = new BigDecimal(d);
+			return  r.setScale((int)Double.parseDouble(scale.toString()), ROUND_HALF_UP);
+		}
+		return 0;
+	}
+
+	/**
+	 * @Description   平方
+	 * @Param [a:底數, scale:结果取整]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2020.12.10 15:10
+	 **/
+	public static Object pow(Object a,Object b) {
+		if(StringUtils.isNumber(a)&&StringUtils.isNumber(b)){
+			return  pow(a,b,0);
+		}
+		return 0;
+	}
+	/**
+	 * @Description   EL表达式解析
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2020.12.10 15:10
+	 **/
+	public static Object parse(Object a) {
+		if(StringUtils.isNotEmpty(a)&&!StringUtils.isNumber(a)){
+			return  Expression.parse(a.toString()).calculate().toString();
+		}
+		return a;
+	}
+
+
+
+
+	/**
+	 * 获取动态行最后一行指定值
+	 */
+	public static Object  lastMapValByKey(Object table,Object key){
+        ArrayList<HashMap<String, Object>> list = objToArray(table);
+        if(ListUtils.isNotEmpty(list)){
+			for(int i=list.size()-1;i>=0;i--){
+				if(list.get(i).get(key) != null){
+					return list.get(i).get(key);
+				}
+			}
+		}
+       return "";
+	}
+	/**
+	 * 获取动态行第一行指定值
+	 */
+	public static Object  firstMapValByKey(Object table,Object key){
+		ArrayList<HashMap<String, Object>> list = objToArray(table);
+		if(ListUtils.isNotEmpty(list)){
+			for(int i=0;i<list.size();i++){
+				if(list.get(i).get(key) != null){
+					return list.get(i).get(key);
+				}
+			}
+		}
+		return "";
+	}
+	/**
+	 * 获取累计最后一个值
+	 */
+	public static Object  lastMapVal(Object scaleObj,Object table,Object key){
+		Object result = null;
+		ArrayList<HashMap<String, Object>> list = objToArray(table);
+		if(list != null && list.size() > 0) {
+			int scale = objectChangeInt(scaleObj);
+			double sum = 0;
+			for (Map<String,Object> data : list) {
+				if(StringUtils.isNumber(data.get(key))) {
+					sum += Double.parseDouble(data.get(key).toString());
+				}
+			}
+			if(scale == 0) {
+				//整数
+				result = (int)sum;
+			} else if(scale > 0) {
+				//浮点数
+				BigDecimal big = new BigDecimal(sum);
+				result = big.setScale(scale, ROUND_HALF_UP);
+			}
+		}
+		return result;
+	}
+	/**@yangyj
+	 * 构造随机正负数
+	 */
+	public static Object  minusOrPlus(){
+		Random rm = new Random();
+        if(rm.nextBoolean()){
+			return "-1";
+		}else{
+           	return "1";
+		}
+
+	}
+
+	/**
+	 * yangyj
+	 * 混合两个序列内容
+	 * @param la
+	 * @param lb
+	 * @return
+	 */
+ 	public static  List<Object>  mixedMList(List<Object> la ,List<Object> lb){
+		 List<Object> res = new ArrayList<>();
+		 res.addAll(la);
+		 res.addAll(lb);
+		Collections.shuffle(res);
+		return res;
+	}
+
+
+
+	/**@yangyj
+	 *根据取值范围获取随机数值,例子:FUNC.getRandomListPro('X','X+10',TABLE['t_pf_UniversalTable124_2']['hanfengchicunguiding'],TABLE['t_pf_UniversalTable124_2']['hanfengchicunpinlv'],0)
+	 * @param designv
+	 * @param hz
+	 * @return
+	 */
+	public static List<Object> getRandomListPro(Object min,Object max,Object designv,Object hz,Object scale){
+         if(max!=null&&hz!=null&&min!=null&&scale!=null){
+         	 if(StringUtils.isEmpty(designv)){
+         	 	designv="0";
+			 }
+         	 min=min.toString().replace("X",designv.toString());
+			 max=max.toString().replace("X",designv.toString());
+			 if(min.toString().startsWith("-")){
+			 	min="'"+min+"'";
+			 }
+			 if(max.toString().startsWith("+")){
+				 max="'"+max+"'";
+			 }
+			 if(!StringUtils.isNumber(min)){
+				 min=Expression.parse(min.toString()).calculate().toString();
+			 }
+			 if(!StringUtils.isNumber(max)){
+				 max=Expression.parse(max.toString()).calculate().toString();
+			 }
+			 return getRangeRandomList(hz, 0, min+","+max, scale);
+		 }
+		return null;
+	}
+
+	/**
+	 * @Description 生成用户指定范围实测值
+	 * @Param [n 数量, design 设计值, scope 偏差范围, rate 合格率0~1, scale保留小数位]
+	 * @return java.util.List<java.lang.Object>
+	 * @Author yangyj
+	 * @Date 2021.08.27 14:47
+	 **/
+	public static List<Object> cmv(Object n, Object design, Object scope, Object rate, Object scale){
+		if(StringUtils.isNotEmpty(n)&&StringUtils.isNotEmpty(design)&&StringUtils.isNotEmpty(scope)&&StringUtils.isNotEmpty(rate)&&StringUtils.isNotEmpty(scale)){
+			return rangeList(n,design,scope,1,scale,rate);
+		}
+		return null;
+	}
+
+	/**
+	 * @Description 生成用户指定范围实测值(重庆需求)
+	 * @Param [n 数量, design 设计值, scope 偏差范围, rate 合格率0~1, scale保留小数位]
+	 * @return java.util.List<java.lang.Object>
+	 * @Author huangjn
+	 * @Date 2021.08.27 14:47
+	 **/
+	public static List<Object> cmvcq(Object n, Object design, Object scope, Object rate, Object scale){
+		if(StringUtils.isNotEmpty(n) && StringUtils.isNotEmpty(design) &&
+				StringUtils.isNotEmpty(scope) && StringUtils.isNotEmpty(rate) && StringUtils.isNotEmpty(scale)){
+			String[] arr = handleNull(scope).split("[,|,]");
+			double minD = Math.abs(Double.parseDouble(arr[0]));
+			double maxD = Math.abs(Double.parseDouble(arr[1]));
+			int size = Integer.parseInt(n.toString());
+			double rateD = Double.parseDouble(rate.toString());
+			double m = Math.ceil(size * rateD);
+			List<Object> qualified = getRandomListPro("(X)-0.001-"+minD,"(X)+0.001+"+maxD,design,m,scale);
+			if(m < size){
+				Random r = new Random();
+				int le = r.nextInt((int) (size - m));
+				int gt = (int) (size - m - le);
+				//重庆需求,大于设计值的才算不合格,那么需要在生成指定个数且在合格范围内的合格值后,生成一定个数的不合格值且这些不合格值一定是大于设计值
+				List<Object> unQualified = getRandomListPro("(X)+1+" + maxD,"(X)+2.1+" + maxD, design, le + gt, scale);
+
+				return mixedMList(qualified,unQualified);
+			}else{
+				return qualified;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * @Description 检测是否存在客户手填的内容 ,不存在则批量生成实测值
+	 * @Param [param, customData]
+	 * @return java.util.List<java.lang.Object>
+	 * @Author yangyj
+	 * @Date 2021.12.22 10:52 update
+	 **/
+	public static List<Object> batchCmv(String param,Object customData){
+		boolean fi=true;
+		if(customData!=null){
+			ArrayList<HashMap<String,Object>> tmp = objToArray(customData);
+			if(ListUtils.isNotEmpty(tmp)){
+		      if(tmp.get(0).entrySet().stream().anyMatch(e->StringUtils.isNotEquals("id",e.getKey())&&StringUtils.isNotEmpty(e.getValue()))){
+		      	fi=false;
+			  }
+			}
+		}
+		if(StringUtils.isNotEmpty(param)&&fi){
+			param=param.replaceAll("\\s","").replaceAll("(","(").replaceAll(")",")");
+			//每组格式:项目名称(项目)合格率(0.9)数量(20)设计值(100)偏差范围(-10,10)保留小数位(0);
+			List<Object> result = new ArrayList<>();
+			String[] ss = param.split("[;|;]");
+			int i=1;
+			/*前一个项目名称*/
+			String pre=ss[0].split("\\)合格率\\(")[0];
+			for(String xm:ss){
+				Map<String,String> map = new HashMap();
+				String[] args = xm.split("\\)");
+				for(String a:args){
+					if(StringUtils.isNotEmpty(a)){
+						String[] kv=a.split("\\(");
+						map.put(kv[0],kv[1]);
+					}
+				}
+				List<Object> datas = cmv(map.get("数量"),map.get("设计值"),map.get("偏差范围"),map.get("合格率"),map.get("保留小数位"));
+				if(ListUtils.isNotEmpty(datas)){
+					List<Object> tmp = new ArrayList<>();
+					int n= datas.size();
+					int index=0;
+					String _pre=xm.split("\\)合格率\\(")[0];
+					if(StringUtils.isNotEquals(pre,_pre)){
+						i++;
+						pre=_pre;
+					}
+					while (n>=15){
+						tmp.add(i);
+						tmp.add(map.get("项目名称"));
+						tmp.add(map.get("项目名称"));
+						tmp.addAll(datas.subList(index,index+15));
+						index=index+15;
+						n=n-15;
+						tmp.add(map.get("设计值"));
+					}
+					if(n>0){
+						int fill=15-n;
+						tmp.add(i);
+						tmp.add(map.get("项目名称"));
+						tmp.add(map.get("项目名称"));
+						tmp.addAll(datas.subList(index,datas.size()));
+					    for(int j=0;j<fill;j++){
+							tmp.add(map.get(""));
+						}
+						tmp.add(map.get("设计值"));
+					}
+					result.addAll(tmp);
+				}
+			}
+			if(result.size()>0){
+				return  result;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * @Description 累加器
+	 * @Param [scale:保留小数位, args:累加对象,支持动态数量]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2021.05.18 10:40
+	 **/
+	public static  Object _sumObj(Object scale,Object...args){
+		 double result = 0d;
+		 boolean flag = false;
+         for(Object obj:args){
+         	if(StringUtils.isNotEmpty(obj)&&StringUtils.isNumber(obj)){
+				result+=Double.parseDouble(obj.toString());
+				flag=true;
+			}
+		 }
+         if(flag){
+			 BigDecimal r = new BigDecimal(result);
+			 return  r.setScale((int)Double.parseDouble(scale.toString()), ROUND_HALF_UP);
+		 }
+		return "";
+	}
+	/**
+	 * @Description 累加公式,最大支持20个数累加,第一个参数是保留小数位
+	 * @Param [scale,...obj]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2021.06.17 13:51
+	 **/
+	public static  Object sumObj(Object scale,Object o1,Object o2){
+		return _sumObj(scale,o1,o2);
+	}
+	public static  Object sumObj(Object scale,Object o1,Object o2,Object o3){
+
+		return _sumObj(scale,o1,o2,o3);
+	}
+	public static  Object sumObj(Object scale,Object o1,Object o2,Object o3,Object o4){
+		return _sumObj(scale,o1,o2,o3,o4);
+	}
+	public static  Object sumObj(Object scale,Object o1,Object o2,Object o3,Object o4,Object o5){
+		return _sumObj(scale,o1,o2,o3,o4,o5);
+	}
+	public static  Object sumObj(Object scale,Object o1,Object o2,Object o3,Object o4,Object o5,Object o6){
+		return _sumObj(scale,o1,o2,o3,o4,o5,o6);
+	}
+	public static  Object sumObj(Object scale,Object o1,Object o2,Object o3,Object o4,Object o5,Object o6,Object o7){
+		return _sumObj(scale,o1,o2,o3,o4,o5,o6,o7);
+	}
+	public static  Object sumObj(Object scale,Object o1,Object o2,Object o3,Object o4,Object o5,Object o6,Object o7,Object o8){
+		return _sumObj(scale,o1,o2,o3,o4,o5,o6,o7,o8);
+	}
+	public static  Object sumObj(Object scale,Object o1,Object o2,Object o3,Object o4,Object o5,Object o6,Object o7,Object o8,Object o9){
+		return _sumObj(scale,o1,o2,o3,o4,o5,o6,o7,o8,o9);
+	}
+	public static  Object sumObj(Object scale,Object o1,Object o2,Object o3,Object o4,Object o5,Object o6,Object o7,Object o8,Object o9,Object o10){
+		return _sumObj(scale,o1,o2,o3,o4,o5,o6,o7,o8,o9,o10);
+	}
+	public static  Object sumObj(Object scale,Object o1,Object o2,Object o3,Object o4,Object o5,Object o6,Object o7,Object o8,Object o9,Object o10,Object o11){
+		return _sumObj(scale,o1,o2,o3,o4,o5,o6,o7,o8,o9,o10,o11);
+	}
+	public static  Object sumObj(Object scale,Object o1,Object o2,Object o3,Object o4,Object o5,Object o6,Object o7,Object o8,Object o9,Object o10,Object o11,Object o12){
+		return _sumObj(scale,o1,o2,o3,o4,o5,o6,o7,o8,o9,o10,o11,o12);
+	}
+	public static  Object sumObj(Object scale,Object o1,Object o2,Object o3,Object o4,Object o5,Object o6,Object o7,Object o8,Object o9,Object o10,Object o11,Object o12,Object o13){
+		return _sumObj(scale,o1,o2,o3,o4,o5,o6,o7,o8,o9,o10,o11,o12,o13);
+	}
+	public static  Object sumObj(Object scale,Object o1,Object o2,Object o3,Object o4,Object o5,Object o6,Object o7,Object o8,Object o9,Object o10,Object o11,Object o12,Object o13,Object o14){
+		return _sumObj(scale,o1,o2,o3,o4,o5,o6,o7,o8,o9,o10,o11,o12,o13,o14);
+	}
+	public static  Object sumObj(Object scale,Object o1,Object o2,Object o3,Object o4,Object o5,Object o6,Object o7,Object o8,Object o9,Object o10,Object o11,Object o12,Object o13,Object o14,Object o15){
+		return _sumObj(scale,o1,o2,o3,o4,o5,o6,o7,o8,o9,o10,o11,o12,o13,o14,o15);
+	}
+
+
+
+
+	public static Object dataFormatter(Object o,Object type){
+		if(o!=null&&o instanceof List){
+			ArrayList<Object> data = (ArrayList<Object>) o;
+			List<Object> result = new ArrayList<>();
+			for(Object ob:data){
+                 result.add(ob+"%");
+			}
+			return result;
+		}
+       return  null;
+	}
+
+
+
+	/**@yangyj
+	 * getDivisorRandomList
+	 * 生成的随机数是divisor的整数倍
+	 * @param hz
+	 * @param scaleObj
+	 * @return
+	 */
+
+	public static List<Object> getDivisorRL( Object min,Object max, Object designv,Object hz, Object scaleObj,Object divisor) {
+		List<Object> result =new ArrayList<Object>();
+		if(StringUtils.isEmpty(min) || StringUtils.isEmpty(max) || StringUtils.isEmpty(designv) || StringUtils.isEmpty(hz) || StringUtils.isEmpty(scaleObj) || StringUtils.isEmpty(divisor)){
+			return  result;
+		}
+		min=min.toString().replace("X",designv.toString());
+		max=max.toString().replace("X",designv.toString());
+		Double s = Double.parseDouble(Expression.parse(min.toString()).calculate().toString())/Double.parseDouble(divisor.toString());
+		Double e = Double.parseDouble(Expression.parse(max.toString()).calculate().toString())/Double.parseDouble(divisor.toString());
+		List<Object>  list = getRandomListPro(s,e,0,hz,0);
+		for(Object obj:list){
+			result.add(String.format("%."+scaleObj.toString()+"f",Double.parseDouble(obj.toString())*Double.parseDouble(divisor.toString())));
+		}
+		return  result;
+	}
+
+
+	/**
+     * @yangyj 判断取值,例子:FUNC.ifVal('X<=2?2:(X-1)*3',TABLE[tablename][fieldname])
+     * @param ari  运算表达式
+     * @param designv 设计值(未知量X的值)
+     * @return
+     */
+	public static Object ifVal(Object ari,Object designv){
+          if(designv==null){
+          	  return "";
+		  }
+          if(StringUtils.isEmpty(designv.toString())){
+          	return "";
+          }
+		 ari = ari.toString().replaceAll("[\\t\\n\\r]", "");
+		 ari=ari.toString().replace("X",designv.toString());
+         return  Expression.parse(ari.toString()).calculate().toString();
+	}
+	/**
+	 * @Description  空白或者/都判断为空
+	 * @Param [data]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2022.04.01 15:04
+	 **/
+	public static Object isNotEmpty(Object data){
+	      List<Object> list = obj2List(data);
+         return  list.stream().map(StringUtils::handleNull).anyMatch(e->!e.contains("/"));
+	}
+
+	public static Object isPass(Object data){
+		List<Object> list = obj2List(data);
+		return  list.stream().map(StringUtils::handleNull).map(e-> !e.contains("/")&&StringUtils.isNotEmpty(e)?"合格":"").collect(Collectors.toList());
+	}
+
+
+
+
+	/**
+	 * @Description 评定表实测值
+	 * @Param [data, remark]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2022.01.13 15:26
+	 **/
+	public static Object eval(Object data ,Object remark){
+		if(data!=null){
+			if(data instanceof  List){
+				data = removeEmpty(data);
+				List<Object> datas = (List<Object>) data;
+                if(datas.size()<=10&&datas.size()>0){
+				  return join(datas,"、");
+				}
+			}else{
+				if(StringUtils.isNotEmpty(data)){
+					return handleNull(data);
+				}
+			}
+		}
+		return remark;
+	}
+
+	public static Object model100(Object data ,Object remark){
+		if(data!=null){
+			if(data instanceof  List){
+				data = removeEmpty(data);
+				List<Object> datas = (List<Object>) data;
+				if(datas.size()<=10&&datas.size()>0){
+					return join(datas,"、");
+				}else{
+					return remark;
+				}
+			}
+		}
+		return "";
+	}
+
+
+
+
+
+	/**
+	 * @Description 共检点合格点公式
+	 * @Param [data 数据, remark超出10个后的提示, design实际值, dev偏差值]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2022.02.11 10:09
+	 **/
+	public static Object checkpoints(Object data ,Object remark,Object design,Object dev){
+		if(data!=null){
+			    if(data instanceof  String &&((String) data).contains("NumberFormatException")){
+			    	return data;
+				}
+				Object[] R=ck(data,design,dev);
+				if(R[0]!=null&&R[1]!=null&&R[2]!=null){
+					int checkpoints=Integer.parseInt(R[0].toString());
+					int passpoints=Integer.parseInt(R[1].toString());
+					List<Object> result = (List<Object>) R[2];
+					boolean	over=checkpoints>result.size();
+					if(checkpoints<=0){
+						return "/";
+					}else if(ListUtils.isNotEmpty(result)&&result.size()<=10&&!over){
+						result=	result.stream().map(obj->{
+							if(StringUtils.isNumber(obj)){
+								if(obj.toString().contains(".")){
+									BigDecimal big = new BigDecimal(obj.toString());
+									String s = big.toString();
+									return s.replaceAll("(0+|\\.0+)$","");
+								}
+							}
+							return obj;
+						}).collect(Collectors.toList());
+						return join(result,"、");
+					}else{
+						if(StringUtils.isEmpty(remark)){
+							remark ="共检点,合格点";
+						}
+						return remark.toString().replace("共检","共检"+checkpoints).replace("合格","合格"+passpoints);
+					}
+				}
+		}
+		return "/";
+	}
+
+	public static Object[] ck(Object data ,Object design,Object dev){
+		Object[] r=new Object[3];
+		List<Object> result = new ArrayList<>();
+		List<Object> datas = obj2List(removeEmpty(data));
+		if(ListUtils.isNotEmpty(datas)){
+			int checkpoints=0;
+			int passpoints=0;
+			List<Object> designList = obj2List(design);
+			if(ListUtils.isNotEmpty(designList)){
+				design=designList.get(0);
+			}
+			for(Object e:datas){
+				String s = handleNull(e);
+				if(StringUtils.isNotEmpty(s)){
+					if(containsZH(s)){
+						Matcher m =matcher("[\u4e00-\u9fa5]+(\\d+)\\D*合格(\\d+)\\D+",s);
+						if(m.find()){
+							checkpoints+=Integer.parseInt(m.group(1));
+							passpoints+=Integer.parseInt(m.group(2));
+						}
+					}else{
+						result.add(s);
+					}
+				}
+			}
+			result=result.stream().map(StringUtils::handleNull).map(String::trim).filter(e->!StringUtils.isEquals("/",e)).collect(Collectors.toList());
+			if(result.size()>0){
+				List<Object> pl = passList(design,dev,result,1);
+				passpoints+= pl.size();
+				result=obj2List(result);
+				checkpoints+=result.size();
+			}else{
+				System.out.println();
+			}
+			r[0]=checkpoints;
+			r[1]=passpoints;
+			r[2]=result;
+		}
+		return r;
+	}
+
+	public static Object tree(List<String>nodes,String param){
+		if(CollectionUtil.isNotEmpty(nodes)&& Func.isNotBlank(param)){
+			List<String> result = new ArrayList<>();
+			param=param.replaceAll("[cC]","");
+			List<String> list = Arrays.asList(param.split("-"));
+			List<Integer> index =list.stream().map(Integer::parseInt).collect(Collectors.toList());
+			for(Integer i:index){
+				result.add(nodes.get(i));
+			}
+			return String.join(",", result);
+		}
+        return "";
+	}
+
+	public static Object qrate(Object design,Object dev,Object data){
+		return qrate(design,dev,data,0,1);
+	}
+	public static Object qrate(Object design,Object dev,Object data,Object scale){
+		return qrate(design,dev,data,scale,1);
+	}
+	/**
+	 * @Description Qualified rate of measured value 计算合格率
+	 * @Param [design: 设计值, dev:偏差范围或规定值, xN:偏差值单位转设计值单位倍率, data:数据, scale:保留小数位]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2022.01.14 09:56
+	 **/
+	public static Object qrate(Object design,Object dev,Object data,Object scale,Object xN){
+		 if(data!=null&&StringUtils.isNotEmpty(design,dev,xN)){
+              Object[] R=ck(data,design,dev);
+              if(R[0]!=null&&R[1]!=null&&Math.abs(Double.parseDouble(R[0].toString()))>0){
+                	String result=StringUtils.number2String(Double.parseDouble(R[1].toString())*100/Double.parseDouble(R[0].toString()),scale);
+				  if(result.contains(".")){
+					  result =result.replaceAll("(0+|\\.0+)$","");
+				  }
+				  return result;
+			  }
+		 }
+		return "";
+	}
+	public static Object easyRate(Object data){
+		if(null!=data){
+			List<Object> datas = obj2List(data);
+			if(datas.stream().anyMatch(e->containsZH(e))){
+				return 100;
+			}
+		}
+		return "";
+	}
+	/**
+	 * @Description 筛选合格的部分
+	 * @Param [design, dev, data, xN]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2022.02.12 13:59
+	 **/
+	public static List<Object> passList(Object design,Object dev,Object data,Object xN){
+		List<Object> result = new ArrayList<>();
+		List<Object> datas = obj2List(data);
+		datas= (List<Object>) removeEmpty(datas);
+		Double[] range=scopeParse(dev,design,xN);
+		assert range != null;
+		double finalMin = range[0];
+		double finalMax = range[1];
+        List<Object> l1 =   datas.stream().map(StringUtils::handleNull).filter(e->e.contains("*")||e.contains("X")||e.contains("x") ||e.contains("×")||e.contains("/")).collect(Collectors.toList());
+        if(ListUtils.isNotEmpty(l1)){
+        	for(Object obj:l1){
+               String[] arr = obj.toString().split("[×xX*/]");
+               if(Arrays.stream(Arrays.stream(arr).toArray()).allMatch(StringUtils::isNumber)){
+               	    if(Arrays.stream(Arrays.stream(arr).toArray()).map(StringUtils::handleNull).map(Double::parseDouble).noneMatch(e->e>finalMax ||e< finalMin)){
+               	    	result.add(obj);
+					}
+			   }
+			}
+		}
+		List<Object> l2 =   datas.stream().filter(StringUtils::isNumber).map(StringUtils::handleNull).map(Double::parseDouble).filter(e->e<= finalMax &&e>= finalMin).collect(Collectors.toList());
+		if(ListUtils.isNotEmpty(l2)){
+			result.addAll(l2);
+		}
+		return  result;
+	}
+
+
+	public static Double[] scopeParse(Object dev, Object design, Object xN){
+		if(StringUtils.isNotEmpty(dev)){
+ 			Double[] result = new Double[2];
+			double designD=Double.parseDouble(design.toString());
+			double xND=Double.parseDouble(xN.toString());
+			String devStr = dev.toString();
+			double min=0;
+			double max=0;
+			devStr=devStr.replaceAll("\\s+","");
+			if(devStr.contains("≤")||devStr.contains("<=")||devStr.contains("<")){
+				devStr=devStr.replace("≤","").replace("<=","");
+				max=designD+Double.parseDouble(devStr)*xND;
+			}else if(devStr.contains("≥")||devStr.contains(">=")||devStr.contains(">")){
+				devStr=devStr.replace("≥","").replace(">=","");
+				min=designD+Double.parseDouble(devStr)*xND;
+				max=Double.MAX_VALUE;
+			}else if(devStr.contains(",")||devStr.contains(",")){
+				String[] arr = devStr.split("[,,]");
+				min = designD+Double.parseDouble(arr[0])*xND;
+				max = designD+Double.parseDouble(arr[1])*xND;
+			}else if(devStr.contains("%")){
+				devStr=devStr.replace("%","");
+				double devD =Math.abs(Double.parseDouble(devStr)*designD/100);
+				min = designD-devD;
+				max = designD+devD;
+			}else if(devStr.contains("±")){
+				devStr=devStr.replace("±","");
+				double devD =Math.abs(Double.parseDouble(devStr)*xND);
+				min = designD-devD;
+				max = designD+devD;
+			}
+				result[0]=min;
+				result[1]=max;
+				return result;
+		}
+		return null;
+	}
+
+	/*specifiedRangeList*/
+	public static List<Object>  rangeList(Object hz,Object design,Object dev,Object xN,Object scale,Object passRate){
+		 List<Object> result = new ArrayList<>();
+		 if(StringUtils.isNotEmpty(design,dev,hz)){
+			 if(StringUtils.isEmpty(scale)){
+				 scale=0;
+			 }
+             if(StringUtils.isEmpty(passRate)){
+             	passRate=1;
+			 }
+             if(StringUtils.isEmpty(xN)){
+             	xN=1;
+			 }
+			 Double[] range=scopeParse(dev,design,xN);
+             int scaleI= Integer.parseInt(scale.toString());
+             int min=0,max=0;
+			 assert range != null;
+			 if(range.length>0){
+				 min = (int)(range[0]*Math.pow(10,scaleI));
+				 max = (int)(range[1]*Math.pow(10,scaleI));
+			 }
+			 Random rd= new Random();
+			 int hzi=new BigDecimal(hz.toString()).multiply(new BigDecimal(passRate.toString())).setScale(0,ROUND_CEILING).intValue();
+			 for(int i=0;i<hzi;i++){
+			 	BigDecimal tb = new BigDecimal(rd.nextInt(max-min+1)+min).divide(BigDecimal.valueOf(Math.pow(10,scaleI)),scaleI,ROUND_HALF_UP);
+			 	if(scaleI>0){
+					result.add(tb.doubleValue());
+				}else{
+					result.add(tb.intValue());
+				}
+
+			 }
+			 int total=StringUtils.handleObj2Integer(hz);
+			 if(total-hzi>0){
+			 	for(int k=0;k<total-hzi;k++){
+					BigDecimal tb;
+                    if(rd.nextBoolean()){
+						 tb = new BigDecimal(rd.nextInt(((max-min)/2))+max+1).divide(BigDecimal.valueOf(Math.pow(10,scaleI)),scaleI,ROUND_HALF_UP);
+					}else{
+						 tb = new BigDecimal(min-1-rd.nextInt(((max-min)/2))).divide(BigDecimal.valueOf(Math.pow(10,scaleI)),scaleI,ROUND_HALF_UP);
+					}
+					if(scaleI>0){
+						result.add(tb.doubleValue());
+					}else{
+						result.add(tb.intValue());
+					}
+				}
+			 	if(ListUtils.isNotEmpty(result)){
+					Collections.shuffle(result);
+				}
+			 }
+		 }
+		 return  result;
+	}
+
+	/**
+	 * @Description obj 转List
+	 * @Param [obj]
+	 * @return java.util.List<java.lang.Object>
+	 * @Author yangyj
+	 * @Date 2022.01.13 15:40
+	 **/
+	public static List<Object> obj2List(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);
+			}
+			if(ListUtils.isNotEmpty(datas)){
+				for(Object e:datas){
+					if(StringUtils.isNotEmpty(e)&&!CustomFunction.containsZH(e.toString())&&(e.toString().contains("、")||e.toString().contains(",")||e.toString().contains(" ")||e.toString().contains(","))){
+						String s=e.toString().trim();
+						if(s.contains(" ")){
+							s=s.replaceAll("\\s+","、");
+						}
+						Object[] bs = s.split("[、,,]");
+						result.addAll(Arrays.asList(bs));
+					}else{
+						result.add(e);
+					}
+				}
+			}
+		}
+		return  result;
+	}
+	/**
+	 * @Description 对象转字符串,list取第一个对象
+	 * @Param [obj]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2022.02.11 15:14
+	 **/
+	public static Object o2Str(Object obj){
+		String result = "";
+		if(obj!=null){
+			List<Object> datas =obj2List(obj);
+			if(ListUtils.isNotEmpty(datas)){
+				return handleNull(datas.get(0));
+			}
+		}
+		return  result;
+	}
+
+	public static Object getFirstNonNull(Object ob1,Object ob2,Object ob3){
+		return _getFirstNonNull(ob1,ob2,ob3);
+	}
+	public static Object getFirstNonNull(Object ob1,Object ob2){
+		return _getFirstNonNull(ob1,ob2);
+	}
+	/**
+	 * @Description  返回第一个不为空的对象
+	 * @Param
+	 * @Author yangyj
+	 * @Date 2022.01.04 13:57
+	 **/
+	public static Object _getFirstNonNull(Object ...obs){
+		   if(obs!=null){
+		   	 for(Object ob:obs){
+		   	 	if(ob instanceof List){
+		   	 		List<Object> list =obj2List(ob);
+		   	 		if(ListUtils.isNotEmpty(list)&&list.stream().anyMatch(StringUtils::isNotEmpty)){
+						return  ob;
+					}
+				}else if(ob instanceof Map){
+		   	 		if(MapUtils.isNotEmpty((Map)ob)){
+						return ob;
+					}
+				}else{
+		   	 		if(StringUtils.isNotEmpty(ob)&&StringUtils.isNotEquals("/",ob)){
+		   	 			return ob;
+					}
+				}
+			 }
+		   }
+           return null;
+	}
+
+
+	/**
+	 * @Description 三元运算 bool?o1:o2 ,默认返回空字符串
+	 * @Param [bool, o1, o2]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2021.01.29 13:54
+	 **/
+	public static Object ifValObj(Object bool,Object o1 ,Object o2){
+		Boolean fi;
+          if(bool instanceof Boolean){
+			 fi = (Boolean) bool;
+		  }else{
+          	return "";
+		  }
+         return fi?o1:o2;
+	}
+	/*太多写错公式名称的,应该是下面的方法名称比较容易接受*/
+	public static Object isValObj(Object bool,Object o1 ,Object o2){
+		return  ifValObj(bool,o1,o2);
+	}
+	/**
+	 * @Description  判断o1中是否包含字符串o2
+	 * @Param [o1, o2]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2021.01.29 14:04
+	 **/
+	public static Object ifContains(Object o1 ,Object o2){
+		if(StringUtils.isNotEmpty(o1)&&StringUtils.isNotEmpty(o2)){
+			return o1.toString().contains(o2.toString());
+		}
+		return false;
+	}
+	/**
+	 * @Description 判断两个对象是否相等
+	 * @Param [o1, o2]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2021.08.23 16:51
+	 **/
+	public static Object isEq(Object o1 ,Object o2){
+		if(StringUtils.isNotEmpty(o1)||StringUtils.isNotEmpty(o2)){
+		      return  StringUtils.isEquals(o1,o2);
+		}
+		return false;
+	}
+		/**
+         * @yangyj
+         * 单极点区间范围判断
+         * @param value 数据
+         * @param o1    比较对象1
+         * @param o2    比较对象2
+         * @param type  <=&&<
+         * @return
+         */
+	public static  Object isVisible(Object value,Object o1 ,Object o2,Object type){
+		if(o1!=null&&o2!=null){
+			double fi =Double.parseDouble(o1.toString())-Double.parseDouble(o2.toString());
+			if(type.equals("<=")){
+				if(fi<=0){
+					return value;
+				}
+			}else{
+				if(fi<0){
+					return value;
+				}
+			}
+		}
+		//如果不存在判断条件对象的值
+		if((o1==null||o2==null)&&type.equals("<=")){
+            return value;
+        }
+        return "";
+	}
+
+	/**@yangyj
+	 * 双极点区间范围判断
+	 * @param value
+	 * @param o1
+	 * @param o2
+	 * @param o3
+	 * @return
+	 */
+	public static  Object isVisibleD(Object value,Object o1 ,Object o2,Object o3){
+		Object r1=isVisible(value,o1,o2,"<");
+		Object r2=isVisible(value,o2,o3,"<=");
+		if(r1!=""&&r2!=""){
+			return  value;
+		}
+		return "";
+	}
+
+
+		/**@yangyj
+         *获取列表最小值
+         * @return
+         */
+	public static  Object getListMin(Object object){
+		if(object instanceof  ArrayList){
+			ArrayList<Object> arrayList = (ArrayList<Object>) object;
+			if(ListUtils.isNotEmpty(arrayList)){
+				arrayList.sort(((o1, o2) -> {
+					Integer io1= Integer.valueOf(o1.toString());
+					Integer io2 = Integer.valueOf(o2.toString());
+					return io1.compareTo(io2);
+				}));
+				return arrayList.get(0);
+			}
+		}
+		return "";
+	}
+
+
+
+
+	/**
+	 * @Description 计算数据集的合格率
+	 * @Param [list:数据集, design:设计值, dev:偏差范围, scale:保存小数位]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2021.10.26 09:34
+	 **/
+	public static  Object getListTick(Object list,Object design,Object dev,Object scale){
+		if(list!=null&&design!=null&&StringUtils.isNotEmpty(dev)){
+			if(!StringUtils.isNumber(scale)){
+				scale=0;
+			}
+			Matcher m = matcher("(-?\\d+(\\.\\d+)?)[h|H]?[,|,](\\+?\\d+(\\.\\d+)?)[h|H]?",dev.toString().replaceAll("[(|)]",""));
+			if(list instanceof  List&&m.find()){
+				List<Object> arrayList = (ArrayList<Object>) list;
+				double tick=0;
+				double designD= Double.parseDouble(handleNull(design));
+				double h=1;
+				if(dev.toString().toUpperCase(Locale.ROOT).contains("H")){
+					h=designD;
+				}
+				for(Object obj:arrayList){
+                    double dx = Double.parseDouble(handleNull(obj))-designD;
+					if(Double.parseDouble(m.group(1))*h<=dx&&dx<=Double.parseDouble(m.group(3))*h){
+                       tick++;
+					}
+				}
+			    if(tick>0){
+			    	BigDecimal a= new BigDecimal(tick);
+			    	BigDecimal b= new BigDecimal(arrayList.size());
+
+			    	return a.divide(b,8,ROUND_HALF_UP).multiply(new BigDecimal(100)).setScale(StringUtils.handleObj2Integer(scale.toString()),ROUND_HALF_UP);
+				}else{
+			    	return "0";
+				}
+			}
+		}
+		return "";
+	}
+	/**
+	 * @Description   指定表字段 数据
+	 * @Param [table, field]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2022.10.11 11:28
+	 **/
+	public static Object getTaleRow(Object table,Object field){
+		if(table!=null&&field!=null){
+			List<Object>  datas = new ArrayList<Object>();
+			ArrayList<HashMap<String,Object>> list=objToArray(table);
+			if(ListUtils.isNotEmpty(list)){
+				for(HashMap<String, Object> ob:list){
+					datas.add(ob.get(field));
+				}
+			}
+			return datas;
+		}
+      return null;
+	}
+
+
+
+	/**
+	 * @Description 获取最后一个对象
+	 * @Param [list]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2021.08.09 14:37
+	 **/
+	public static  Object getListLast(Object o){
+		if(o instanceof List){
+			List<Object> list = (List<Object>) o;
+			if(ListUtils.isNotEmpty(list)){
+				return list.get(list.size()-1);
+			}
+		}
+		return "";
+	}
+	/**
+	 * @Description 获取最后一个对象
+	 * @Param [list]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2021.08.09 14:37
+	 **/
+	public static  Object getListnum(Object o,Integer type){
+		if(o == null){
+			return "";
+		}
+		if(o instanceof List){
+			List<Object> list = (List<Object>) o;
+			if(ListUtils.isNotEmpty(list) || list.size() > type){
+				return list.get(type);
+			}
+		}else{
+			return o.toString();
+		}
+		return "";
+	}
+	/**
+	 * @Description 根据参数,取包含有对应参数的list
+	 * @Param [list],o是list,str是包含的字符串,type=1包含,2未包含
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2021.08.09 14:37
+	 **/
+	public static  Object getListtype(Object o,Object objstr,Integer type){
+		if(o == null || type == null){
+			return "";
+		}
+		String str = "";
+		if(objstr != null ){
+			str =objstr.toString();
+		}
+		List<Object> result = new ArrayList<>();
+		if(o instanceof List){
+			List<Object> list = (List<Object>) o;
+			if(ListUtils.isNotEmpty(list)){
+				for(Object obj : list){
+					if(obj == null){
+						continue;
+					}
+					if(type == 2){
+						if(!obj.toString().contains(str)){
+							result.add(obj);
+						}
+					}else{
+						if(obj.toString().contains(str)){
+							result.add(obj);
+						}
+					}
+
+				}
+				return result;
+			}
+		}else{
+			if(type == 2 && !o.toString().contains(str)){
+				return o.toString();
+			}else if(type == 1 && o.toString().contains(str)){
+				return o.toString();
+			}
+		}
+		return "";
+	}
+	/**
+	 * @Description 过滤掉List中的空对象
+	 * @Param [o]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2021.07.28 11:16
+	 **/
+	public static  Object removeEmpty(Object o){
+		List<Object> result = new ArrayList<>();
+		if(o instanceof  List){
+			for(Object e:(List<Object>)o){
+				if(StringUtils.isNotEmpty(e)){
+					result.add(e);
+				}
+			}
+		}else{
+			result.add(o);
+		}
+		return result;
+	}
+	/**
+	 * @Description 过滤掉List中的相同的对象
+	 * @Param [o]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2021.07.28 11:16
+	 **/
+	public static  Object removeeqEmpty(Object o){
+		List<Object> result = new ArrayList<>();
+		if(o instanceof  List){
+			for(Object e:(List<Object>)o){
+				if(StringUtils.isNotEmpty(e) && !result.contains(e)){
+					result.add(e);
+				}
+			}
+		}else{
+			result.add(o);
+		}
+		return result;
+	}
+	/**
+	 * @Description 设置保留小数位
+	 * @Param
+	 * @return
+	 * @Author yangyj
+	 * @Date 2021.12.31 17:14
+	 **/
+	public static  Object setScale(Object o,Object scale){
+		if(StringUtils.isNumber(scale)&&o!=null){
+			if(o instanceof  List){
+				List<Object> result = new ArrayList<>();
+				for(Object e:(List<Object>)o){
+					if(StringUtils.isNumber(e)){
+						result.add(StringUtils.number2String(e,scale));
+					}else{
+						result.add("");
+					}
+				}
+				return result;
+			}else{
+				if(StringUtils.isNumber(o)){
+					return StringUtils.number2String(o,scale);
+				}
+			}
+		}
+		return "";
+	}
+
+
+	public static  Object abs(Object o){
+		/**
+		 * @Description  测试
+		 * @Param [o]
+		 * @return java.lang.Object
+		 * @Author yangyj
+		 * @Date 2022.03.21 15:43
+		 **/
+		if(o!=null){
+			if(o instanceof  List){
+				List<Object> result = new ArrayList<>();
+				List<Object> datas = obj2List(o);
+				if(ListUtils.isNotEmpty(datas)){
+					for(Object e:datas){
+						if(StringUtils.isNotEmpty(e)){
+							result.add(e.toString().replaceAll("^-",""));
+						}
+					}
+				}
+				return  result;
+			}else{
+				return o.toString().replaceAll("^-","");
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * @Description 返回正则式匹配内容
+	 * @Param [regex:正则式, value:匹配的字符串, i:group(i), g:是否返回全局搜索,全局搜索返回的是列表]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2021.01.08 16:31
+	 **/
+	public static Object matcherFindGroup(String regex, String value ,int i,boolean g){
+		Matcher m = matcher(regex,value);
+		List<Object> result = new ArrayList<>();
+		while (m.find()){
+			result.add(m.group(i));
+		}
+		if(ListUtils.isNotEmpty(result)){
+			if(g){
+				return result;
+			}else {
+				return result.get(0);
+			}
+		}
+		return null;
+	}
+	/**
+	 * @Description 放大缩小
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2022.01.14 14:17
+	 **/
+	public static  Object xN(Object o,Object xN){
+		String cur="";
+		try{
+			if(StringUtils.isNotEmpty(o)&&StringUtils.isNumber(xN)){
+				double xND=Double.parseDouble(xN.toString());
+				List<Object> outList = new ArrayList<>();
+				if(o instanceof List){
+					List<Object> datas = (List<Object>)o;
+					for(Object e:datas){
+						if(StringUtils.isNotEmpty(e)){
+							String[] as = e.toString().split("[^\\d.]");
+							Object m= matcherFindGroup("[^\\d.]",e.toString(),0,false);
+							StringBuilder d = new StringBuilder();
+							for(int i=0;i<as.length;i++){
+								String s=as[i];
+								cur=s;
+								int scale = (int) Math.max(getScale(s)-Math.log10(xND),0);
+                                d.append(StringUtils.number2String(Double.parseDouble(s) * xND, scale)).append(i!=as.length-1&&m!=null?m:"");
+							}
+							outList.add(d.toString());
+						}
+					}
+					if(ListUtils.isNotEmpty(outList)){
+						return outList;
+					}
+				}else{
+					List<Object> datas = Arrays.asList(o.toString().split("[、, ,]"));
+					Matcher m = matcher("[、, ,]",o.toString());
+					String s="、";
+					if(m.find()){
+						s=handleNull(m.group());
+					}
+					if(ListUtils.isNotEmpty(datas)){
+						for(Object e:datas){
+							if(StringUtils.isNotEmpty(e)){
+								int scale = (int) Math.max(getScale(s)-Math.log10(xND),0);
+								cur=e.toString();
+								outList.add(StringUtils.number2String(Double.parseDouble(e.toString())*xND,scale));
+							}
+						}
+					}
+					if(ListUtils.isNotEmpty(outList)){
+						return StringUtils.join(outList.stream().map(StringUtils::handleNull).collect(Collectors.toList()),s);
+					}
+				}
+			}
+		}catch (NumberFormatException e){
+			e.printStackTrace();
+			String  error = "";
+			if(e.getMessage().contains("multiple points")){
+				error=cur+"包含多个小数点";
+			}else {
+				error=cur;
+			}
+			return "NumberFormatException(数字格式异常,请检查)"+error;
+		}
+		return "";
+	}
+	public static  Object repeat(Object data){
+		List<Object> result = new ArrayList<>();
+		if(data!=null){
+			List<Object> list = obj2List(removeEmpty(data));
+			result=list.stream().distinct().collect(Collectors.toList());
+		}
+		return  result;
+	}
+	/**
+	 * @Description  截取list subList(list,1,5) 返回list的第1到第5个元素
+	 * @Param [o]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2021.07.28 11:16
+	 **/
+	public static  Object subList(Object o,Object  start ,Object end){
+		List<Object> result = new ArrayList<>();
+		if(o instanceof  List){
+			 result = (List<Object>) o;
+			 int s=StringUtils.handleObj2Integer(start);
+			 int e=StringUtils.handleObj2Integer(end);
+			 s= Math.max(s, 1);
+			 if(e<=0){
+			 	e=result.size();
+			 }
+			 return result.subList(s-1,e);
+		}
+		return result;
+	}
+
+	/**
+	 * @Description 获取G8测点偏差
+	 * @Param [cd, pc]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2022.02.25 11:05
+	 **/
+	public static  Object g8dx(Object cd,Object pc){
+		if(cd!=null&&pc!=null){
+			List<Object> result = new ArrayList<>();
+			List<Object> stakes=obj2List(cd);
+			List<Object> dx=obj2List(pc);
+			if(ListUtils.isNotEmpty(stakes)&&dx.size()>=stakes.size()){
+				Object bmd = stakes.get(0);
+				if(StringUtils.isNotEmpty(bmd)){
+					for(int i=0;i<stakes.size();i++){
+						  Object cp = stakes.get(i);
+                          if(StringUtils.isNotEmpty(cp)&&StringUtils.isNotEquals(bmd,cp)){
+							  Matcher m = matcher("(?i)zd\\d+",cp.toString());
+							  if(!m.find()){
+							  	 result.add(dx.get(i));
+							  }
+						  }
+					}
+					return result;
+				}
+			}
+		}
+		return "";
+	}
+	public static  Object g8stakes(Object cd){
+		if(cd!=null){
+			List<Object> result = new ArrayList<>();
+			List<Object> stakes=obj2List(cd);
+			if(ListUtils.isNotEmpty(stakes)){
+				Object bmd = stakes.get(0);
+				if(StringUtils.isNotEmpty(bmd)){
+					for (Object cp : stakes) {
+						if (StringUtils.isNotEmpty(cp) && StringUtils.isNotEquals(bmd, cp)) {
+							Matcher m = matcher("(?i)zd\\d+", cp.toString());
+							if (!m.find()) {
+								result.add(cp);
+							}
+						}
+					}
+					return result;
+				}
+			}
+		}
+		return "";
+	}
+	public static  List<Object> g8c103(Object cd,Object sj, Object sc,Object dx){
+		List<Object> result = new ArrayList<>();
+		if(cd!=null&&sj!=null&&sc!=null&&dx!=null){
+			List<Object> cds=obj2List(cd);
+			List<Object> sjs=obj2List(sj);
+			List<Object> scs=obj2List(sc);
+			List<Object> dxs=obj2List(dx);
+			int min=Math.min(Math.min(sjs.size(),scs.size()),dxs.size());
+			if(ListUtils.isNotEmpty(cds)&&min>=cds.size()){
+				Object bmd = cds.get(0);
+				if(StringUtils.isNotEmpty(bmd)){
+					for(int i=0;i<cds.size();i++){
+						Object cp = cds.get(i);
+						if(StringUtils.isNotEmpty(cp)&&StringUtils.isNotEquals(bmd,cp)){
+							Matcher m = matcher("(?i)zd\\d+",cp.toString());
+							if(!m.find()){
+								if(StringUtils.isNumber(cp)){
+									result.add("");
+									result.add("");
+									result.add("");
+									result.add(dxs.get(i));
+								}else {
+									result.add(sjs.get(i));
+									result.add(scs.get(i));
+									result.add(dxs.get(i));
+									result.add("");
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+        return result;
+	}
+
+	public static  List<Object> g8zzds(Object cd,Object dx,Object fi){
+		List<Object> result = new ArrayList<>();
+		if(cd!=null&&dx!=null){
+			List<Object> cds=obj2List(cd);
+			List<Object> dxs=obj2List(dx);
+			boolean bol= (boolean) fi;
+			int min=dxs.size();
+			if(ListUtils.isNotEmpty(cds)&&min>=cds.size()){
+				Object bmd = cds.get(0);
+				List<String> l1 = new ArrayList<>();
+				List<String> l2 = new ArrayList<>();
+				List<String> l3 = new ArrayList<>();
+				List<String> dyn ;
+				if(bol){
+					dyn=l3;
+				}else{
+					dyn=l2;
+				}
+				if(StringUtils.isNotEmpty(bmd)){
+					for(int i=0;i<cds.size();i++){
+						Object cp = cds.get(i);
+						if(StringUtils.isNotEmpty(cp)&&StringUtils.isNotEquals(bmd,cp)){
+							Matcher m = matcher("(?i)zd\\d+",cp.toString());
+							if(!m.find()){
+								if(StringUtils.isNumber(cp)){
+									dyn.add(handleNull(dxs.get(i)));
+								}else {
+							    	l1.add(handleNull(dxs.get(i)));
+								}
+							}
+						}
+					}
+					result.add(StringUtils.join(l1,","));
+					result.add(StringUtils.join(l2,","));
+					result.add(StringUtils.join(l3,","));
+				}
+			}
+		}
+		return  result;
+	}
+
+	public static List<Object> gcc(Object zh,Object sj,Object sc,Object dx,Object mode){
+		List<Object> result = new ArrayList<>();
+		if(zh!=null&&sj!=null&&sc!=null&&dx!=null){
+			List<Object> cds=obj2List(zh);
+			List<Object> sjs=obj2List(sj);
+			List<Object> scs=obj2List(sc);
+			List<Object> dxs=obj2List(dx);
+			int min=Math.min(Math.min(dxs.size(),sjs.size()),scs.size());
+			if(ListUtils.isNotEmpty(cds)&&min>=cds.size()){
+				Object bmd = cds.get(0);
+				if(StringUtils.isNotEmpty(bmd)){
+					for(int i=0;i<cds.size();i++){
+						Object cp = cds.get(i);
+						if(StringUtils.isNotEmpty(cp)&&StringUtils.isNotEquals(bmd,cp)){
+							Matcher m = matcher("(?i)zd\\d+",cp.toString());
+							if(!m.find()){
+								if(StringUtils.isEquals(mode,0)){
+									if(!Pattern.matches(".+(?i)v$",cp.toString())){
+										result.add(sjs.get(i));
+										result.add(scs.get(i));
+										result.add(dxs.get(i));
+									}
+								}else if(StringUtils.isEquals(mode,1)){
+									if(Pattern.matches(".+(?i)v$",cp.toString())){
+										result.add(sjs.get(i));
+										result.add(scs.get(i));
+										result.add(dxs.get(i));
+									}
+								}
+
+							}
+						}
+					}
+				}
+			}
+		}
+		return  result;
+	}
+
+	/**
+	 * @Description 获取最后一份G8
+	 * @Param [data, out]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2022.04.02 17:46
+	 **/
+	public static  Object g8zd(Object data,Object out){
+		List<Object> result = new ArrayList<>();
+		if(StringUtils.isNotEmpty(out)&&data instanceof List){
+			List<Object> datas =obj2List(data);
+			String bm = handleNull(datas.get(0));
+			List<Object> cds = new ArrayList<>();
+			List<Object> bhs = new ArrayList<>();
+			List<Object> hss = new ArrayList<>();
+			List<Object> qss = new ArrayList<>();
+			List<Object> ygs = new ArrayList<>();
+			List<Object> scs = new ArrayList<>();
+			List<Object> sjs = new ArrayList<>();
+			List<Object> dxs = new ArrayList<>();
+			for(int n=0;n<datas.size();n++){
+                 int m=n%13;
+                 Object d=datas.get(n);
+                 if(m==0){
+                 	cds.add(d);
+				 }else if(m==1){
+					 bhs.add(d);
+				 }else if(m==2){
+					 hss.add(d);
+				 }else if(m==4){
+					 qss.add(d);
+				 }else if(m==6){
+					 ygs.add(d);
+				 }else if(m==8){
+					 scs.add(d);
+				 }else if(m==10){
+					 sjs.add(d);
+				 }else if(m==12){
+					 dxs.add(d);
+				 }
+			}
+			/*同时存在超过一组水准点,则存在多张复制表*/
+			if(cds.stream().filter(e -> StringUtils.isEquals(bm, e)).count() >2){
+				Collections.reverse(cds);
+				int length =0;
+				int count=0;
+				for(int x=0;x<cds.size();x++){
+					if(StringUtils.isEquals(cds.get(x),bm)){
+						/*倒序后,第一次bm点到第二次bm点为一组*/
+						if(count==2){
+							length=x+1;
+							break;
+						}else{
+							count++;
+						}
+
+					}
+				}
+				Collections.reverse(cds);
+				cds = cds.stream().skip(cds.size()-length).collect(Collectors.toList());
+				bhs = bhs.stream().skip(bhs.size()-length).collect(Collectors.toList());
+				hss = hss.stream().skip(hss.size()-length).collect(Collectors.toList());
+				qss = qss.stream().skip(qss.size()-length).collect(Collectors.toList());
+				ygs = ygs.stream().skip(ygs.size()-length).collect(Collectors.toList());
+				scs = scs.stream().skip(scs.size()-length).collect(Collectors.toList());
+				sjs = sjs.stream().skip(sjs.size()-length).collect(Collectors.toList());
+				dxs = dxs.stream().skip(dxs.size()-length).collect(Collectors.toList());
+			}
+			if(cds.size()>0){
+				String BM=handleNull(cds.get(0));
+				for(int i=0;i<bhs.size();i++){
+					Object _bh=bhs.get(i);
+					if(StringUtils.isNotEmpty(_bh)){
+						int k=i;
+						boolean loop=true;
+						do{
+							Object _cd=cds.get(k);
+							if(StringUtils.isNotEmpty(_cd)&&(_cd.toString().contains("ZD")||StringUtils.isEquals(BM,_cd))){
+								loop=false;
+							}else{
+								k--;
+							}
+						}while (k>=0&&loop);
+						String outStr=handleNull(out);
+						if(outStr.contains("桩号")){
+							result.add(handleNull(cds.get(i))+"  "+_bh);
+						}
+						if(outStr.contains("后视")){
+							result.add(hss.get(k));
+						}
+						if(outStr.contains("前视")){
+							result.add(qss.get(k));
+						}
+						if(outStr.contains("仪器高")){
+							result.add(ygs.get(k));
+						}
+						if(outStr.contains("实测高程、设计高程、高程差")){
+							if(_bh.toString().contains("右")){
+								result.addAll(Arrays.asList("","",scs.get(i)));
+								result.addAll(Arrays.asList("","",sjs.get(i)));
+								result.addAll(Arrays.asList("","",dxs.get(i)));
+							}else if(_bh.toString().contains("左")){
+								result.addAll(Arrays.asList(scs.get(i),"",""));
+								result.addAll(Arrays.asList(sjs.get(i),"",""));
+								result.addAll(Arrays.asList(dxs.get(i),"",""));
+							}else{
+								result.addAll(Arrays.asList("",scs.get(i),""));
+								result.addAll(Arrays.asList("",sjs.get(i),""));
+								result.addAll(Arrays.asList("",dxs.get(i),""));
+							}
+						}
+					}
+				}
+			}
+
+		}
+		return result;
+	}
+
+	/**
+	 * @Description  list 去头尾
+	 * @Param [o]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2021.12.31 14:53
+	 **/
+	public static  Object removeHT(Object o){
+		List<Object> result = new ArrayList<>();
+		if(o instanceof  List){
+			result= (List<Object>) o;
+			if(result.size()>2){
+				int end =result.size();
+				for(int i=result.size()-1;i>1;i--){
+					if(StringUtils.isNotEmpty(result.get(i))){
+						end=i;
+						break;
+					}
+				}
+				return subList(result,2,end);
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * @Description  list 去头
+	 * @Param [o]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2021.12.31 14:53
+	 **/
+	public static  Object removeH(Object o){
+		List<Object> result = new ArrayList<>();
+		if(o instanceof  List){
+			result= (List<Object>) o;
+			if(result.size()>2){
+				return subList(result,2,result.size());
+			}
+		}
+		return result;
+	}
+
+
+	public static  Object removeByReg(Object o,Object reg){
+		List<Object> result = new ArrayList<>();
+		if(o instanceof  List && StringUtils.isNotEmpty(reg)){
+			result= (List<Object>) o;
+			return result.stream().map(StringUtils::handleNull).filter(e->!Pattern.matches(reg.toString(),e)).collect(Collectors.toList());
+		}
+		return result;
+	}
+
+	/**
+	 * @Description 获取动态行某列内容
+	 * @Param [data, field]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2022.01.08 10:02
+	 **/
+	public static  Object getColumn(Object data ,Object field){
+	   if(StringUtils.isNotEmpty(field)){
+	   	    List<HashMap<String,Object>> _data =objToArray(data);
+	   	    if(ListUtils.isNotEmpty(_data)){
+	   	    	return  _data.stream().map(e->e.get(field.toString())).collect(Collectors.toList());
+			}
+	   }
+		return data;
+	}
+
+	/**
+	 * @Description 合并多个list
+	 * @Param [listArr]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2021.12.31 15:10
+	 **/
+	public static  Object mergeList(Object l1,Object l2){
+		return _mergeList(l1,l2);
+	}
+	public static  Object mergeList(Object l1,Object l2,Object l3){
+		return _mergeList(l1,l2,l3);
+	}
+	public static  Object mergeList(Object l1,Object l2,Object l3,Object l4){
+		return _mergeList(l1,l2,l3,l4);
+	}
+	public static  Object mergeList(Object l1,Object l2,Object l3,Object l4,Object l5){
+		return _mergeList(l1,l2,l3,l4,l5);
+	}
+	public static  Object mergeList(Object l1,Object l2,Object l3,Object l4,Object l5,Object l6){
+		return _mergeList(l1,l2,l3,l4,l5,l6);
+	}
+	public static  Object mergeList(Object l1,Object l2,Object l3,Object l4,Object l5,Object l6,Object l7){
+		return _mergeList(l1,l2,l3,l4,l5,l6,l7);
+	}
+	public static  Object mergeList(Object l1,Object l2,Object l3,Object l4,Object l5,Object l6,Object l7,Object l8){
+		return _mergeList(l1,l2,l3,l4,l5,l6,l7,l8);
+	}
+	public static  Object _mergeList(Object ...listArr){
+		List<Object> result = new ArrayList<>();
+	    if(listArr!=null&&listArr.length>=2){
+	    	List<List<Object>> tmp =new ArrayList<>();
+	    	int max=0;
+	    	for(Object o:listArr){
+				List<Object> list = Collections.singletonList("");
+	    		if(o instanceof List){
+	    			list = (List<Object>) o;
+					max=Math.max(max,list.size());
+				}
+	    		tmp.add(list);
+			}
+	    	if(ListUtils.isNotEmpty(tmp)){
+	    		for(int i=0;i<max;i++){
+	    			for(List<Object> _l:tmp){
+	    				if(_l.size()>i){
+	    					result.add(_l.get(i));
+						}else{
+	    					result.add("");
+						}
+					}
+				}
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * @Description 删除列表最后一个数据
+	 * @Param [o]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2021.07.28 15:47
+	 **/
+	public static  Object remLast(Object o){
+		if(o instanceof  List){
+		     rem(o,	((List<Object>)o).size()-1);
+		}
+		return  o;
+	}
+	/**
+	 * @Description list 转 string
+	 * @Param [o, separator:分隔符]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2021.07.28 15:50
+	 **/
+	public static  Object _join(Object o,Object separator){
+		StringBuilder r = new StringBuilder();
+		if(o instanceof  List){
+			if(null==separator){
+				separator=space(1);
+			}
+			for(Object e:(List<Object>)o){
+				if(StringUtils.isNotEmpty(e)){
+					r.append(handleNull(e)).append(separator);
+				}
+			}
+		}else if(StringUtils.isNotEmpty(o)){
+			r.append(o).append(",");
+		}
+		if(r.length()>0){
+			r.deleteCharAt(r.length()-1);
+		}
+		return  r;
+	}
+	public static  Object __join(Object ...args){
+		StringBuilder r = new StringBuilder();
+		if(args!=null){
+			if(args.length>=2){
+				String separator=handleNull(args[args.length-1]);
+				for(int i=0;i<args.length-1;i++){
+					r.append(_join(args[i],separator)).append(separator);
+				}
+				if(r.length()>0){
+					r.deleteCharAt(r.length()-1);
+				}
+			}else{
+               return _join(args[0],"、");
+			}
+		}
+		return  r.toString();
+	}
+	public static  Object join(Object o1,Object o2,Object o3,Object separator){
+		return __join(o1,o2,o3,separator);
+	}
+	public static  Object join(Object o1,Object o2,Object separator){
+		return __join(o1,o2,separator);
+	}
+	public static  Object join(Object o1,Object separator){
+		return __join(o1,separator);
+	}
+	public static  Object join(Object o1){
+		return __join(o1);
+	}
+	/**
+	 * @Description String 转List
+	 * @Param [o, separator]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2021.12.03 15:09
+	 **/
+	public static  Object split(Object o,Object separator){
+		 if(StringUtils.isNotEmpty(o,separator)){
+			 System.out.println(separator);
+		 	String[] arr = o.toString().split(separator.toString());
+		    return 	Arrays.stream(arr).collect(Collectors.toList());
+		 }
+         return null;
+	}
+	public static  Object split(Object o){
+		return split(o,"/|,|、|,|;|;|\\\\|(\\s+)");
+	}
+
+	/**
+	 * @Description  删除下标为index的元素
+	 * @Param [o, index]
+	 * @return void
+	 * @Author yangyj
+	 * @Date 2021.07.28 15:52
+	 **/
+	public static  void rem(Object o,Object index){
+		if(o instanceof  List&&StringUtils.isNumber(index)){
+			((List<Object>)o).remove(StringUtils.handleObj2Integer(index).intValue());
+		}
+	}
+
+	/**
+	 * @Description  根据百分比返回子集list内容
+	 * @Param [obj:数据源, percent:0-100]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2020.12.04 09:24
+	 **/
+	public  static Object getListPercent(Object obj,Object percent){
+		if(obj!=null&&percent!=null){
+			if(obj instanceof  List){
+				ArrayList<Object> list = (ArrayList<Object>) obj;
+				Collections.shuffle(list);
+				int n = (int) Math.round((Double.parseDouble(percent.toString())/100)*list.size());
+				if(n<=list.size()){
+					return  list.subList(0,n);
+				}
+				return list;
+			}
+		}
+		return "";
+	}
+
+
+
+	public static Object  doForTableList(Object ot,Object type){
+		if(ot!=null){
+			//记录表46:构造深度平均值
+			if(type.toString().equals("0")){
+				List<Object>  datas = new ArrayList<Object>();
+				if(ot instanceof  HashMap){
+					HashMap mp = (HashMap) ot;
+					if(mp.size()>0){
+						datas.add(mp.get("TdGZSD"));
+					}
+				}else if(ot instanceof  ArrayList){
+					ArrayList<HashMap<String,Object>> list = (ArrayList<HashMap<String, Object>>) ot;
+					if(ListUtils.isNotEmpty(list)){
+						for(HashMap<String, Object> ob:list){
+							datas.add(ob.get("TdGZSD"));
+						}
+					}
+				}
+				return  avg(1,datas);
+			}
+
+		}
+
+		return  null;
+	}
+
+
+
+
+	public static boolean isNumeric(String str){
+		Pattern pattern = Pattern.compile("[0-9.]*");
+		return pattern.matcher(str).matches();
+	}
+
+
+
+	/**
+	 * @Description  把Object 转换成 ArrayList<HashMap<String, Object>>
+	 * @Param [obj]
+	 * @return java.util.ArrayList<java.util.HashMap<java.lang.String,java.lang.Object>>
+	 * @Author yangyj
+	 * @Date 2020.12.11 09:44
+	 **/
+	public static ArrayList<HashMap<String,Object>> objToArray(Object obj){
+		if(obj instanceof  ArrayList){
+			return (ArrayList<HashMap<String, Object>>) obj;
+		}else if(obj instanceof  HashMap){
+			ArrayList<HashMap<String, Object>> array = new ArrayList<HashMap<String, Object>>();
+			HashMap<String, Object> map =	(HashMap<String, Object>) obj  ;
+			if(map.size()>0){
+				array.add(map);
+			}
+			return array;
+		}
+       return null;
+	}
+
+
+
+	/**
+	 *  @author: zhifk
+	 *  @Date:  2020/9/4 - 11:00
+	 *  @Description:
+	 *  value1:公式所在单元格的分类,value2:选择的分类,value3:从记录表获得的共检点合格点
+	 *  根据选择的分类判断是否是该分类的共检点合格点
+	 *  为:FUNC.isfenlei(TABLE['t_pf_RecordTable015']['shigongkaishiriqi'],'板拱',FORMULA[‘公式编号’])
+	 */
+	public static Object isfenlei(Object value1,Object value2,Object value3){
+		if( StringUtils.isEmpty(value1)  || StringUtils.isEmpty(value2) || StringUtils.isEmpty(value3)){
+			return null;
+		}
+		if(value1.toString().contains(value2.toString())){
+			return value3;
+		}
+		return null;
+	}
+
+
+
+	public  static Object dXd(Object design,Object data){
+		return dXd(design,data,1,getScale(design,data));
+	}
+	public  static Object dXd(Object design,Object data,Object xN){
+		int scale=0;
+		if(StringUtils.isNotEmpty(design,data,xN)){
+			 scale=getScale(design,data);
+			 scale= (int) (scale-Math.log10(Double.parseDouble(xN.toString())));
+		}
+		return dXd(design,data,xN,scale);
+	}
+	/**
+	 * @Description 求偏差公式  支持AXA-BXB=DXD或者A-B=D的格式
+	 * @Param [design:设计值, data:实测值, xN:倍率, scale:保留小数位]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2022.01.20 09:45
+	 **/
+	public  static Object dXd(Object design,Object data,Object xN,Object scale){
+		if(StringUtils.isNotEmpty(design,data)){
+			if(StringUtils.isEmpty(xN)){
+				xN=1;
+			}
+			if(StringUtils.isEmpty(scale)){
+				scale=0;
+			}
+			String delimiter=handleNull(matcherFindGroup("[^0-9.]",design.toString(),0,false));
+			if(StringUtils.isEmpty(delimiter)){
+				delimiter=CONCAT;
+			}
+			String[] dArr=handleNull(design).split("["+delimiter+"]");
+			String[] bArr=handleNull(data).split("["+delimiter+"]");
+			Object _dx=null;
+			for(int n=0;n<dArr.length;n++){
+				BigDecimal a = new BigDecimal(dArr[n]);
+				BigDecimal b = new BigDecimal(bArr[n]);
+				String _data=b.subtract(a).multiply(new BigDecimal(xN.toString())).setScale(Integer.parseInt(scale.toString()), ROUND_HALF_UP).toString();
+				if(StringUtils.isNotEmpty(_dx)){
+					_dx=StringUtils.join(_dx,_data,delimiter);
+				}else{
+					_dx=_data;
+				}
+			}
+			return _dx;
+		}
+		return "";
+	}
+
+
+	public  static Object over10(Object C82 ,Object C81 ,Object xmm, Object remark){
+         List<Object> list = obj2List(C82);
+         if(ListUtils.isNotEmpty(list)){
+         	if(list.stream().map(StringUtils::handleNull).anyMatch(e->e.contains(xmm.toString()))){
+				return remark;
+			}
+		 }
+		List<Object> list2 =obj2List(C81);
+		if(ListUtils.isNotEmpty(list2)){
+			return list2.stream().filter(StringUtils::isNotEmpty).map(StringUtils::handleNull).collect(Collectors.joining("、"));
+		}else{
+			return "";
+		}
+	}
+
+	/**
+	 * @Description 字符串连接
+	 * @Param [obs]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2022.02.12 17:21
+	 **/
+	public  static Object _concat(Object ...obs){
+		StringBuilder sb  = new StringBuilder();
+		if(obs!=null){
+			for(Object ob:obs){
+				sb.append(handleNull(ob));
+			}
+		}
+        return sb.toString();
+	}
+	public  static Object concat(Object o1,Object o2,Object o3,Object o4){
+		return _concat(o1,o2,o3,o4);
+	}
+	public  static Object concat(Object o1,Object o2,Object o3){
+		return _concat(o1,o2,o3);
+	}
+	public  static Object concat(Object o1,Object o2){
+		return _concat(o1,o2);
+	}
+	public  static Object concat(Object o1){
+		return _concat(o1);
+	}
+
+
+	/**
+	 * @Description 总体标准差
+	 * @Param [data, scale]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2022.04.14 11:32
+	 **/
+	public  static Object sd(Object data,Object scale){
+		if(data!=null&&StringUtils.isNumber(scale)){
+			data=removeEmpty(data);
+			List<Object> datas=obj2List(data);
+			int total=datas.size();
+			List<String> _datas=datas.stream().map(StringUtils::handleNull).collect(Collectors.toList());
+			double avgVal=_datas.stream().mapToDouble(Double::parseDouble).average().orElse(0D);
+			double result=Math.sqrt(_datas.stream().mapToDouble(Double::parseDouble).map(e->Math.pow(e-avgVal,2)).sum()/total);
+			return  StringUtils.number2String(result,scale);
+		}
+		return "";
+	}
+
+
+
+//	public static void main(String[] args)  {
+//	}
+
+}

+ 208 - 254
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java

@@ -16,8 +16,9 @@
  */
 package org.springblade.manager.controller;
 
-import com.alibaba.fastjson.JSONArray;
-import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.spire.xls.Workbook;
 import com.spire.xls.Worksheet;
 import io.swagger.annotations.*;
@@ -43,26 +44,18 @@ import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.constant.BladeConstant;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.core.tool.utils.StringPool;
-import org.springblade.manager.entity.ExctabCell;
-import org.springblade.manager.entity.WbsTreePrivate;
-import org.springblade.manager.service.IExctabCellService;
-import org.springblade.manager.service.IWbsTreePrivateService;
-import org.springblade.manager.service.IWbsTreeService;
+import org.springblade.manager.entity.*;
+import org.springblade.manager.service.*;
 import org.springblade.manager.vo.*;
 import org.springblade.manager.wrapper.ExcelTabWrapper;
 import org.springblade.resource.feign.IOSSClient;
 import org.springframework.web.bind.annotation.*;
 import com.baomidou.mybatisplus.core.metadata.IPage;
-import org.springblade.manager.entity.ExcelTab;
-import org.springblade.manager.service.IExcelTabService;
 import org.springblade.core.boot.ctrl.BladeController;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.io.*;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -90,6 +83,12 @@ public class ExcelTabController extends BladeController {
 	// 私有项目wbs
 	private final IWbsTreePrivateService wbsTreePrivateService;
 
+	// 清表表格解析信息
+	private final ILinkdataInfoService linkdataInfoService;
+
+	// 元素信息表-
+	private final IWbsFormElementService wbsFormElementService;
+
 	/**
 	 * 详情
 	 */
@@ -247,41 +246,6 @@ public class ExcelTabController extends BladeController {
 		detail.setFileType(3); // 表示为清表信息  1 表示祖节点  2 表示为节点信息 3 表示清表
 		detail.setHtmlUrl(thmlUrl);
 		excelTabService.saveOrUpdate(detail);
-/*
-		//解析数据
-		Thread.sleep(200);
-		String htmlString =  readfile(thmlUrl);
-
-		String htmlString2=  getBody(htmlString);
-
-		Document doc = Jsoup.parse(htmlString2);
-
-		Elements trs = doc.select("tr");
-		List<ExctabCell> cellList = new ArrayList<>();
-
-		for(int i = 0 ;i < trs.size() ;i++){
-			Element tr = trs.get(i);
-			Elements tds = tr.select("td");
-			for( int j = 0 ; j < tds.size();j++ ){
-				ExctabCell cell = new ExctabCell();
-				Element data = tds.get(j);
-				int colspan = Integer.parseInt(data.attr("COLSPAN").equals("")?"0":data.attr("COLSPAN"));
-				int rowspan  = Integer.parseInt(data.attr("ROWSPAN").equals("")?"0":data.attr("ROWSPAN"));
-				String textInfo = data.text();
-				cell.setExctabId(nodeId);
-				cell.setTrIndex(i);
-				cell.setTdIndex(j);
-				cell.setColIndex(colspan);
-				cell.setRowIndex(rowspan);
-				cell.setTextInfo(textInfo);
-				cellList.add(cell);
-				System.out.print("COLSPAN:" +colspan+" ROWSPAN:"+rowspan+" "+textInfo);
-			}
-			System.out.println();
-		}
-
-		// 保存结构
-		exctabCellService.saveOrUpdateBatch(cellList);*/
 		return R.success("上传成功");
 	}
 
@@ -385,23 +349,25 @@ public class ExcelTabController extends BladeController {
 		return buffer.toString();
 	}
 
-	public static String getBody(String val) {
-		String start = "<body>";
-		String end = "</body>";
-		int s = val.indexOf(start) + start.length();
-		int e = val.indexOf(end);
-		return val.substring(s, e);
-	}
 
-	public static String getStyle(String val) {
-		String start = "<<style type=\"text/css\">";
-		String end = "</style>";
-		int s = val.indexOf(start) + start.length();
-		int e = val.indexOf(end);
-		return val.substring(s, e);
+	private static void saveAsFileWriter(String content ,String filePath) {
+		Writer fwriter = null;
+		try {
+			// true表示不覆盖原来的内容,而是加到文件的后面。若要覆盖原来的内容,直接省略这个参数就好
+			fwriter = new BufferedWriter((new OutputStreamWriter(new FileOutputStream(filePath),"UTF-8")));
+			fwriter.write(content);
+		} catch (IOException ex) {
+			ex.printStackTrace();
+		} finally {
+			try {
+				fwriter.flush();
+				fwriter.close();
+			} catch (IOException ex) {
+				ex.printStackTrace();
+			}
+		}
 	}
 
-
 	/**
 	 * 关联清表树
 	 */
@@ -431,19 +397,31 @@ public class ExcelTabController extends BladeController {
 		WbsTreePrivate aPrivate = wbsTreePrivateService.getOne(Condition.getQueryWrapper(wbsTree));
 		aPrivate.setIsLinkTable(1); // 已关联
 		aPrivate.setExcelId(exceTabId);
-		wbsTreePrivateService.saveOrUpdate(aPrivate);
+
+		UpdateWrapper<WbsTreePrivate> updateWrapper = new UpdateWrapper<>();
+		updateWrapper.in("p_key_id",tabId);
+		updateWrapper.set("is_link_table",1);
+		updateWrapper.set("excel_id",exceTabId);
+
+		wbsTreePrivateService.update(updateWrapper);
+		// 获取excel 基本信息
+		ExcelTab excelTab = excelTabService.getById(exceTabId);
 		// 解析
-		return R.success("关联成功");
-	}
 
+		// 获取元素列表
+		WbsFormElement wbsFormElement = new WbsFormElement();
+		QueryWrapper<WbsFormElement> queryWrapper = new QueryWrapper<>();
+		List<WbsFormElement> detail = wbsFormElementService.selectElementListByFid(aPrivate.getId()+"");
+		// 解析html
+		getExcelHtml1(excelTab.getHtmlUrl());
 
+		return R.success("关联成功");
+	}
 
 
+	public void getExcelHtml1(String thmlUrl) {
 
-	/*public static void main(String[] args) {
-		String thmlUrl = "/Users/hongchuangyanfa/Desktop/ToHtml.html";
 		String htmlString =  readfile(thmlUrl);
-		String htmlBody=  getBody(htmlString);
 		Map<String ,String > styleMap = new HashMap<>();
 
 		// 解析 style
@@ -453,11 +431,7 @@ public class ExcelTabController extends BladeController {
 		while (cssMatcher.find()) {
 			styleMap.put(cssMatcher.group(1),cssMatcher.group(2));
 		}
-
 		// 解析 总行和总列
-
-
-
 		// 解析
 		Element table = doc.select("table").first();
 		Elements trs = table.select("tr");
@@ -465,126 +439,189 @@ public class ExcelTabController extends BladeController {
 		// 获取总行列数
 		int maxCol = doc.select("Col").size();
 
-		System.out.println(trs.size());
-		System.out.println( maxCol );
-		List<Map<String,String>> textlist = new ArrayList();
+		List<Map<String,String>> textlist = new ArrayList<>() ;
+
+		String [] rowData = new String[trs.size()+1];
 
-		// 计算 单元格的每个坐标
-*//*		for(int i = 0 ;i < trs.size() ;i++) {
+		int s_index = 0;
+		// 横向计算
+		for(int i = 0 ;i < trs.size() ;i++) {
 			Element tr = trs.get(i);
 			Elements tds = tr.select("td");
-			int tdw =1;
+			int x= 0;
 			for (int j = 0; j < tds.size(); j++) {
 				ExctabCell cell = new ExctabCell();
 				Element data = tds.get(j);
-				String textInfo = data.text();
-				int colspan = data.attr("COLSPAN").equals("") ? 1: Integer.parseInt(data.attr("COLSPAN"))-1;
-				int rowspan = data.attr("ROWSPAN").equals("") ? 1: Integer.parseInt(data.attr("ROWSPAN"))-1;
-
-				//if(!textInfo.equals("/") && !textInfo.isEmpty()){
-					*//**//*Map<String,String> textObject = new HashMap<>();
-					textObject.put("text",textInfo);
-					textObject.put("x1",tdw+"");
-					textObject.put("x2",tdw+colspan+"");
-					textObject.put("y1",i+"");
-					textObject.put("y2",(i+rowspan)+"");*//**//*
-					//textlist.add(textObject);
-				//}
-//				System.out.print(textInfo +":x1:"+tdw +":x2:"+(tdw+colspan) + "  ");
-			}
-			System.out.println();
-		}*//*
+				int colspan = data.attr("COLSPAN").equals("") ? 0 : Integer.parseInt(data.attr("COLSPAN"));
+				int rowspan = data.attr("ROWSPAN").equals("") ? 0 : Integer.parseInt(data.attr("ROWSPAN"));
+				Map<String, String> textObject = new HashMap<>();
+
+
+				// 计算
+				int x1 =0;
+				int x2 =0;
+				int y1 =0;
+				int y2 =0;
+				//x
+				// X 坐标
+				if(colspan==0){
+					x1 = x+1;
+					x2 = x+1;
+					x= x +1;
+				}else{
+					x1 = x+1;
+					x2 = x+colspan;
+					x = x+colspan;
+				}
+
+				String textInfo = data.text().trim();
+				// y 坐标
+				textObject.put("text",textInfo);
+				y1=i+1;
+				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{
+							String [] dataInfo2 = dataInfo.split(",");
+							String dataInfo3 = dataInfo2[dataInfo2.length-1];
+							int mx1 = Integer.parseInt(dataInfo3.split(":")[0]);
+							int mx2 = Integer.parseInt(dataInfo3.split(":")[1]);
+							if(mx2+1==x1){
+								dataInfo = dataInfo+","+mx1+":"+x2;
+							}else{
+								dataInfo = dataInfo+","+x1+":"+x2;
+							}
+						}
+						rowData[k+2+i] = dataInfo;
+					}
+				}
+
+				String getRowInfo = rowData[y1];
+				if(getRowInfo!=null){
+					String [] dataInfo2 = getRowInfo.split(",");
+					if(getRowInfo.indexOf("1")>=0 && j==0){
+						for(int m =0;m<dataInfo2.length ;m++){
+							int mx1 = Integer.parseInt(dataInfo2[m].split(":")[0]);
+							int mx2 = Integer.parseInt(dataInfo2[m].split(":")[1]);
+							x = mx2;
+						}
+						x1 = x+x1;
+						x2 = x+x2;
+						x = x+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(x2+1 == mx1){
+								x = mx2 ;
+							}
+						}
+					}
+				}
 
-		*//*for(Map<String,String> m:textlist){
-			System.out.println(m.get("text")+":"+m.get("x1")+":"+m.get("x2")+":"+m.get("y1")+":"+m.get("y1"));
-		}*//*
 
-		for(int i = 0 ;i < trs.size() ;i++){
-			Element tr = trs.get(i);
-			Elements tds = tr.select("td");
-			int tdw =0;
-			for( int j = 0 ; j < tds.size();j++ ){
-				ExctabCell cell = new ExctabCell();
-				Element data = tds.get(j);
-				boolean isadd = false ;
-				// 更改样式
 				String keyId = data.attr("class");
 				if(!keyId.isEmpty()){
 					data.removeAttr("class");
 					data.attr("style",styleMap.get(keyId));
-				}
-
-				int colspan = data.attr("COLSPAN").equals("") ? 1: Integer.parseInt(data.attr("COLSPAN"))-1;
-				int rowspan = data.attr("ROWSPAN").equals("") ? 1: Integer.parseInt(data.attr("ROWSPAN"))-1;
-
-				// 决定输入啥文本框
-				String textInfo = data.text();
-
-				//data
-
-				System.out.println(textInfo + ":" +data.attr("offsetTop"));
-				*//*if(textlist.size()>=1){
-					for(Map<String,String> m:textlist) {
-						int x1 = Integer.parseInt(m.get("x1"));
-						int x2 = Integer.parseInt(m.get("x2"));
-						int y1 = Integer.parseInt(m.get("y1"));
-						int y2 = Integer.parseInt(m.get("y2"));
-						System.out.println(m.get("text")+":"+m.get("x1")+":"+m.get("x2")+":"+m.get("y1")+":"+m.get("y2"));
-
 
+					// 封版
+					if(styleMap.get(keyId).indexOf("border-top-style")>=0 && styleMap.get(keyId).indexOf("border-bottom-style")>=0){
+						s_index = y1;
 					}
-				}else{
-					Map<String,String> textObject = new HashMap<>();
-					textObject.put("text",textInfo);
-					textObject.put("x1",tdw+"");
-					textObject.put("x2",tdw+colspan+"");
-					textObject.put("y1",(i)+"");
-					textObject.put("y2",(i+rowspan)+"");
-					textlist.add(textObject);
-				}*//*
-
-
-
-
-
+					if(styleMap.get(keyId).indexOf("border-top-style")>=0 && styleMap.get(keyId).indexOf("border-bottom-style")<0){
+						s_index = y1;
+					}
+				}
 
-				*//*if(textInfo.equals("/")|| textInfo.isEmpty()){
+				LinkdataInfo linkdataInfo = new LinkdataInfo();
+				linkdataInfo.setTrIndex(i);
+				linkdataInfo.setTdIndex(j);
+				linkdataInfo.setTabId(Long.parseLong("123456789"));
+				boolean isadd = false;
+				// 组装 html 数据
+				boolean istopVal =false;
+				boolean isleftVal =false;
+				int inputType = 1;  //1 输入框  2 时间
+				if(textInfo.equals("/")|| textInfo.isEmpty() || textInfo.equals("—")){
 					if(i== 0 && j==0 && maxCol==colspan ){ // 第一行为空
 						isadd = false;
 					}else{
 						// 得到 当前位置 获取值
-						for(Map<String,String> m:textlist){
-							int x1 = Integer.parseInt(m.get("x1"));
-							int x2 = Integer.parseInt(m.get("x2"));
-							int y1 = Integer.parseInt(m.get("y1"));
-							int y2 = Integer.parseInt(m.get("y2"));
+						for(int k=textlist.size()-1;k>=0;k--){
+							Map<String,String> m = textlist.get(k);
+							int xx1 = Integer.parseInt(m.get("x1"));
+							int xx2 = Integer.parseInt(m.get("x2"));
+							int yy1 = Integer.parseInt(m.get("y1"));
+							int yy2 = Integer.parseInt(m.get("y2"));
 							String kekval = m.get("text");
 
-							//||(i>= y1 && (i+rowspan)<=y2 && x2 <tdw && !kekval.isEmpty())
-							//(tdw >= x1 && (tdw+colspan)<=x2 && y1<=i && !kekval.isEmpty())
-
-							if((i>= y1 && (i+rowspan)<=y2 && x2 < tdw && !kekval.isEmpty())){ // 向上取值
-								System.out.print(i+":"+j);
-								System.out.println(":"+m.get("text"));
+							if(xx1<=x1 && xx2>=x2 && yy2<y1 && !istopVal && y1>=s_index){ // 向上取值
+								if(!kekval.isEmpty() && !kekval.equals("/") && kekval.indexOf("检验单")<0 && kekval.indexOf("表")<0 && kekval.indexOf("—")<0){
+									if(kekval.indexOf("日期")>=0){
+										inputType=2;
+									}
+									linkdataInfo.setColName(kekval);
+									istopVal = true ;
+									System.out.println(x1 +"-"+x2 +":"+y1+"-"+y2 + "--"+s_index +"val:"+kekval);
+								}
+							}
+							if(yy1<=y1 && yy2>=y2 && xx2<x1 && !isleftVal && y1>=s_index){ // 向左取
+								if(!kekval.isEmpty() && !kekval.equals("/") && kekval.indexOf("检验单")<0 && kekval.indexOf("表")<0&& kekval.indexOf("—")<0){
+									isleftVal = true ;
+									if(kekval.indexOf("日期")>=0){
+										inputType=2;
+									}
+									linkdataInfo.setColName(kekval);
+								//	System.out.println(x1 +"-"+x2 +":"+y1+"-"+y2 + "--"+s_index +"val:"+kekval);
+								}
+							}
+							if(isleftVal || istopVal){
 								isadd = true ;
 							}
+							if (istopVal&&isleftVal){
+								break;
+							}
 						}
 					}
 				}else{
 					isadd = false;
-				}*//*
+				}
+
+				if(textInfo.indexOf("年")>=0 && textInfo.indexOf("月")>=0&& textInfo.indexOf("日")>=0){
+					data.empty().append("<el-date-picker style='width:100%;height:100%'   type='date' format='yyyy 年 MM 月 dd 日' placeholder='请选择时间'> </el-date-picker>");
+				}
 
 				if(isadd){
-					data.empty().append("<el-input type='text'  placeholder='请输入内容'> </el-input>");
+
+					if(inputType==2){
+						data.empty().append("<el-date-picker  type='date' style='width:100%;height:100%' > </el-date-picker>");
+					}else{
+						if(rowspan>=1){
+							data.empty().append("<el-input type='textarea' style='width:100%;height:100%'   :rows="+rowspan*2+" placeholder=''> </el-input>");
+						}else{
+							data.empty().append("<el-input type='text' style='width:100%;height:100%' placeholder=''> </el-input>");
+						}
+					}
+					//linkdataInfoService.save(linkdataInfo);
 				}
-				tdw = tdw + colspan;
+
+				textObject.put("x1",x1+"");
+				textObject.put("x2",x2+"");
+				textObject.put("y1",y1+"");
+				textObject.put("y2",y2+"");
+				textObject.put("rowSpan",rowspan+"");
+				textlist.add(textObject);
 			}
 		}
-
-		//System.out.println(table+"");
+		saveAsFileWriter(doc+"",thmlUrl);
 	}
 
-*/
 
 
 	/**
@@ -593,106 +630,23 @@ public class ExcelTabController extends BladeController {
 	@GetMapping("/get-excel-html")
 	@ApiOperationSupport(order = 15)
 	@ApiOperation(value = "清表生成html", notes = "清表生成html")
-	public R getExcelHtml() {
-		String thmlUrl = "/Users/hongchuangyanfa/Desktop/ToHtml.html";
-		String htmlString =  readfile(thmlUrl);
-		String htmlBody=  getBody(htmlString);
-		Map<String ,String > styleMap = new HashMap<>();
-
-		// 解析 style
-		Document doc = Jsoup.parse(htmlString);
-		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));
+	@ApiImplicitParams(value = {
+			@ApiImplicitParam(name = "excelId", value = "excelId", required = true)
+	})
+	public R getExcelHtml(Long excelId) {
+		ExcelTab excelTab = excelTabService.getById(excelId);
+		if(excelTab ==null ){
+			return R.fail("该数据下无此节点!");
 		}
 
-		// 解析
-		Element table = doc.select("table").first();
-		Elements trs = table.select("tr");
-
-		// 获取总行列数
-		int maxCol = doc.select("Col").size();
-
-		List<Map<String,String>> textlist = new ArrayList();
-		// 计算 单元格的每个坐标
-		int trh = 0;
-		for(int i = 0 ;i < trs.size() ;i++) {
-			Element tr = trs.get(i);
-			Elements tds = tr.select("td");
-			int tdw =0;
-			for (int j = 0; j < tds.size(); j++) {
-				ExctabCell cell = new ExctabCell();
-				Element data = tds.get(j);
-				String textInfo = data.text();
-				if(!textInfo.equals("/") && !textInfo.isEmpty()){
-					int colspan = Integer.parseInt(data.attr("COLSPAN").equals("")?"0":data.attr("COLSPAN"));
-					int rowspan  = Integer.parseInt(data.attr("ROWSPAN").equals("")?"0":data.attr("ROWSPAN"));
-
-					Map<String,String> textObject = new HashMap<>();
-					textObject.put("text",textInfo);
-					textObject.put("x1",tdw+"");
-					tdw = tdw + colspan;
-					textObject.put("x2",tdw+"");
-					textObject.put("y1",trh+"");
-					trh = trh + rowspan;
-					textObject.put("y2",trh+"");
-					textlist.add(textObject);
-				}
-			}
+		if(excelTab.getHtmlUrl()==null){
+			return R.fail("请上传清表!");
 		}
 
-	for(Map<String,String> m:textlist){
-		System.out.println(m.get("text")+":"+m.get("x1")+":"+m.get("x2")+":"+m.get("y1")+":"+m.get("y1"));
-	}
-
-		/*for(int i = 0 ;i < trs.size() ;i++){
-			Element tr = trs.get(i);
-			Elements tds = tr.select("td");
-
-
-			for( int j = 0 ; j < tds.size();j++ ){
-				ExctabCell cell = new ExctabCell();
-				Element data = tds.get(j);
-
-				boolean isadd = false ;
-
-				// 更改样式
-				String keyId = data.attr("class");
-				if(!keyId.isEmpty()){
-					data.removeAttr("class");
-					data.attr("style",styleMap.get(keyId));
-				}
-
-				int colspan = Integer.parseInt(data.attr("COLSPAN").equals("")?"0":data.attr("COLSPAN"));
-				int rowspan  = Integer.parseInt(data.attr("ROWSPAN").equals("")?"0":data.attr("ROWSPAN"));
-				// 决定输入啥文本框
-				String textInfo = data.text();
-				if(textInfo.equals("/")|| textInfo.isEmpty()){
-					String trtopval = "";
-					String tdleftval = "";
-					if(i==0){ // tr 取值
-						trtopval = "";
-					}else{
-
-					}
-
-					if(j==0){ // tr 取值
-						tdleftval = "";
-					}else{
-
-					}
-
-
-				}else{
-					isadd = false;
-				}
-
-				if(isadd){
-					data.empty().append("<el-input type='text'  placeholder=''> </el-input>");
-				}
-			}
-		}*/
+		String htmlString =  readfile(excelTab.getHtmlUrl());
+		// 解析 style
+		Document doc = Jsoup.parse(htmlString);
+		Element table = doc.select("table").first();
 		return R.data(table+"");
 	}
 }

+ 15 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/FormulaController.java

@@ -42,6 +42,9 @@ public class FormulaController {
     @ApiOperationSupport(order = 4)
     @ApiOperation(value = "新增或修改", notes = "传入")
     public R save(@RequestBody Formula f) {
+        if(this.service.count(Wrappers.<Formula>query().lambda().eq(Formula::getElementId,f.getElementId()))>0){
+            return R.status(false);
+        }
         return R.status(service.save(f));
     }
 
@@ -62,6 +65,17 @@ public class FormulaController {
         return R.status(false);
     }
 
+    @PostMapping("/saveOrUpdate")
+    @ApiOperationSupport(order = 5)
+    @ApiOperation(value = "保存或修改公式脚本", notes = "保存或修改公式脚本")
+    public R saveOrUpdate( @RequestBody Formula f) {
+        if(f.getId()==null){
+         return    save(f);
+        }else{
+          return   update(Objects.requireNonNull(BeanUtil.copy(f, FormulaBean.class)));
+        }
+    }
+
     /**
      * 删除
      */
@@ -82,7 +96,7 @@ public class FormulaController {
         if(detail!=null){
            return R.data(BeanUtil.copy(detail,FormulaBean.class));
         }
-        return R.fail("无数据");
+        return R.success("无数据");
     }
 
     @ApiOperationSupport(order = 8)

+ 136 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/LinkdataInfoController.java

@@ -0,0 +1,136 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.manager.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import lombok.AllArgsConstructor;
+import javax.validation.Valid;
+
+import org.springblade.core.mp.support.Condition;
+import org.springblade.core.mp.support.Query;
+import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.Func;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.RequestParam;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.springblade.manager.entity.LinkdataInfo;
+import org.springblade.manager.vo.LinkdataInfoVO;
+import org.springblade.manager.service.ILinkdataInfoService;
+import org.springblade.core.boot.ctrl.BladeController;
+
+/**
+ * 清表解析字段信息 控制器
+ *
+ * @author BladeX
+ * @since 2022-06-17
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("/linkdatainfo")
+@Api(value = "清表解析字段信息", tags = "清表解析字段信息接口")
+public class LinkdataInfoController extends BladeController {
+
+	private final ILinkdataInfoService linkdataInfoService;
+
+	/**
+	 * 详情
+	 */
+/*	@GetMapping("/detail")
+	@ApiOperationSupport(order = 1)
+	@ApiOperation(value = "详情", notes = "传入linkdataInfo")
+	public R<LinkdataInfo> detail(LinkdataInfo linkdataInfo) {
+		LinkdataInfo detail = linkdataInfoService.getOne(Condition.getQueryWrapper(linkdataInfo));
+		return R.data(detail);
+	}
+
+	*//**
+	 * 分页 清表解析字段信息
+	 *//*
+	@GetMapping("/list")
+	@ApiOperationSupport(order = 2)
+	@ApiOperation(value = "分页", notes = "传入linkdataInfo")
+	public R<IPage<LinkdataInfo>> list(LinkdataInfo linkdataInfo, Query query) {
+		IPage<LinkdataInfo> pages = linkdataInfoService.page(Condition.getPage(query), Condition.getQueryWrapper(linkdataInfo));
+		return R.data(pages);
+	}
+
+	*//**
+	 * 自定义分页 清表解析字段信息
+	 *//*
+	@GetMapping("/page")
+	@ApiOperationSupport(order = 3)
+	@ApiOperation(value = "分页", notes = "传入linkdataInfo")
+	public R<IPage<LinkdataInfoVO>> page(LinkdataInfoVO linkdataInfo, Query query) {
+		IPage<LinkdataInfoVO> pages = linkdataInfoService.selectLinkdataInfoPage(Condition.getPage(query), linkdataInfo);
+		return R.data(pages);
+	}
+
+	*//**
+	 * 新增 清表解析字段信息
+	 *//*
+	@PostMapping("/save")
+	@ApiOperationSupport(order = 4)
+	@ApiOperation(value = "新增", notes = "传入linkdataInfo")
+	public R save(@Valid @RequestBody LinkdataInfo linkdataInfo) {
+		return R.status(linkdataInfoService.save(linkdataInfo));
+	}
+
+	*//**
+	 * 修改 清表解析字段信息
+	 *//*
+	@PostMapping("/update")
+	@ApiOperationSupport(order = 5)
+	@ApiOperation(value = "修改", notes = "传入linkdataInfo")
+	public R update(@Valid @RequestBody LinkdataInfo linkdataInfo) {
+		return R.status(linkdataInfoService.updateById(linkdataInfo));
+	}
+
+	*//**
+	 * 新增或修改 清表解析字段信息
+	 *//*
+	@PostMapping("/submit")
+	@ApiOperationSupport(order = 6)
+	@ApiOperation(value = "新增或修改", notes = "传入linkdataInfo")
+	public R submit(@Valid @RequestBody LinkdataInfo linkdataInfo) {
+		return R.status(linkdataInfoService.saveOrUpdate(linkdataInfo));
+	}*/
+
+	
+	/**
+	 * 删除 清表解析字段信息
+	 */
+/*	@PostMapping("/remove")
+	@ApiOperationSupport(order = 7)
+	@ApiOperation(value = "逻辑删除", notes = "传入ids")
+	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
+		return R.status(linkdataInfoService.deleteLogic(Func.toLongList(ids)));
+	}*/
+
+	/**
+	 *  获取字段信息 下拉框
+	 */
+	@GetMapping("/getColByTabId")
+	@ApiOperationSupport(order = 7)
+	@ApiOperation(value = "获取字段信息", notes = "传入ids")
+	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String tabId) {
+		return R.data(linkdataInfoService.getColSelect(tabId));
+	}
+
+}

+ 140 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/TextdictInfoController.java

@@ -0,0 +1,140 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.manager.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import lombok.AllArgsConstructor;
+import javax.validation.Valid;
+
+import org.springblade.core.mp.support.Condition;
+import org.springblade.core.mp.support.Query;
+import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.manager.vo.TextdictDataInfoVO;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.RequestParam;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.springblade.manager.entity.TextdictInfo;
+import org.springblade.manager.vo.TextdictInfoVO;
+import org.springblade.manager.service.ITextdictInfoService;
+import org.springblade.core.boot.ctrl.BladeController;
+
+/**
+ * 参数信息表 控制器
+ *
+ * @author BladeX
+ * @since 2022-06-17
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("/textdictinfo")
+@Api(value = "参数信息表", tags = "参数信息表接口")
+public class TextdictInfoController extends BladeController {
+
+	private final ITextdictInfoService textdictInfoService;
+
+	/**
+	 * 详情
+	 */
+	@GetMapping("/detail")
+	@ApiOperationSupport(order = 1)
+	@ApiOperation(value = "详情", notes = "传入textdictInfo")
+	public R<TextdictInfo> detail(TextdictInfo textdictInfo) {
+		TextdictInfo detail = textdictInfoService.getOne(Condition.getQueryWrapper(textdictInfo));
+		return R.data(detail);
+	}
+
+	/**
+	 * 分页 参数信息表
+	 */
+	@GetMapping("/list")
+	@ApiOperationSupport(order = 2)
+	@ApiOperation(value = "分页", notes = "传入textdictInfo")
+	public R<IPage<TextdictInfo>> list(TextdictInfo textdictInfo, Query query) {
+		IPage<TextdictInfo> pages = textdictInfoService.page(Condition.getPage(query), Condition.getQueryWrapper(textdictInfo));
+		return R.data(pages);
+	}
+
+	/**
+	 * 自定义分页 参数信息表
+	 */
+	@GetMapping("/page")
+	@ApiOperationSupport(order = 3)
+	@ApiOperation(value = "分页", notes = "传入textdictInfo")
+	public R<IPage<TextdictInfoVO>> page(TextdictInfoVO textdictInfo, Query query) {
+		IPage<TextdictInfoVO> pages = textdictInfoService.selectTextdictInfoPage(Condition.getPage(query), textdictInfo);
+		return R.data(pages);
+	}
+
+	/**
+	 * 新增 参数信息表
+	 */
+	@PostMapping("/save")
+	@ApiOperationSupport(order = 4)
+	@ApiOperation(value = "新增", notes = "传入textdictInfo")
+	public R save(@Valid @RequestBody TextdictInfo textdictInfo) {
+		return R.status(textdictInfoService.save(textdictInfo));
+	}
+
+	/**
+	 * 修改 参数信息表
+	 */
+	@PostMapping("/update")
+	@ApiOperationSupport(order = 5)
+	@ApiOperation(value = "修改", notes = "传入textdictInfo")
+	public R update(@Valid @RequestBody TextdictInfo textdictInfo) {
+		return R.status(textdictInfoService.updateById(textdictInfo));
+	}
+
+	/**
+	 * 新增或修改 参数信息表
+	 */
+	@PostMapping("/submit")
+	@ApiOperationSupport(order = 6)
+	@ApiOperation(value = "新增或修改", notes = "传入textdictInfo")
+	public R submit(@Valid @RequestBody TextdictInfo textdictInfo) {
+		return R.status(textdictInfoService.saveOrUpdate(textdictInfo));
+	}
+
+	
+	/**
+	 * 删除 参数信息表
+	 */
+//	@PostMapping("/remove")
+//	@ApiOperationSupport(order = 7)
+//	@ApiOperation(value = "逻辑删除", notes = "传入ids")
+//	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
+//		return R.status(textdictInfoService.deleteLogic(Func.toLongList(ids)));
+//	}
+
+
+	/**
+	 * 保存字段信息
+	 */
+	@PostMapping("/saveTextInfo")
+	@ApiOperationSupport(order = 6)
+	@ApiOperation(value = "新增或修改", notes = "传入textdictInfo")
+	public R saveTextInfo(@Valid @RequestBody TextdictDataInfoVO textdictInfo) {
+		//
+
+		return R.status(textdictInfoService.saveBatch(textdictInfo.getTextInfo()));
+	}
+
+}

+ 128 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsParamController.java

@@ -0,0 +1,128 @@
+package org.springblade.manager.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import lombok.AllArgsConstructor;
+import org.springblade.core.mp.support.Condition;
+import org.springblade.core.mp.support.Query;
+import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.BeanUtil;
+import org.springblade.core.tool.utils.CollectionUtil;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.manager.dto.FormulaBean;
+import org.springblade.manager.dto.WbsParamBean;
+import org.springblade.manager.entity.Formula;
+import org.springblade.manager.entity.WbsParam;
+import org.springblade.manager.service.IWbsParamService;
+import org.springblade.manager.wrapper.FormulaWrapper;
+import org.springblade.manager.wrapper.WbsParamWrapper;
+import org.springframework.beans.BeanUtils;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * @author yangyj
+ * @Date 2022/6/17 17:06
+ * @description TODO
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("/param")
+@Api(value = "节点参数", tags = "节点参数")
+public class WbsParamController {
+    private final IWbsParamService service;
+
+    /**
+     * 保存或修改
+     * @param wp
+     * @return
+     */
+    @PostMapping("/saveOrUpdate")
+    @ApiOperationSupport(order = 1)
+    @ApiOperation(value = "保存或修改参数", notes = "保存或修改参数")
+    public R saveOrUpdate(@RequestBody WbsParamBean wp) {
+        if(wp.getId()==null){
+            WbsParam e= new WbsParam();
+            BeanUtils.copyProperties(wp,e);
+            return R.status(this.service.save(e));
+        }else{
+            WbsParam old = this.service.getById(wp.getId());
+            if(old!=null){
+                BeanUtils.copyProperties(wp,old);
+                return R.status(service.updateById(old));
+            }
+            return R.status(false);
+        }
+    }
+
+    /**
+     * 删除
+     */
+    @PostMapping("/remove")
+    @ApiOperationSupport(order = 2)
+    @ApiOperation(value = "删除", notes = "传入id集合")
+    public R remove(@ApiParam(value="需要删除的Id,多个用逗号逗号分开",required = true)@RequestParam String ids) {
+        return R.status(this.service.deleteLogic(Func.toLongList(ids)));
+    }
+    /**
+     * 查询单条
+     */
+    @ApiOperationSupport(order =3)
+    @ApiOperation(value = "查看详情", notes = "传入id")
+    @GetMapping("/detail")
+    @ApiIgnore
+    public R<WbsParamBean> detail(WbsParam wp) {
+        WbsParam detail = service.getOne(Condition.getQueryWrapper(wp));
+        if(detail!=null){
+            return R.data(BeanUtil.copy(detail,WbsParamBean.class));
+        }
+        return R.success("无数据");
+    }
+
+    @ApiOperationSupport(order = 4)
+    @ApiOperation(value = "节点参数列表(翻页)", notes = "节点参数列表(翻页)")
+    @GetMapping("/page")
+    public IPage<WbsParamBean> list( WbsParamBean param,  Query query) {
+        LambdaQueryWrapper<WbsParam> queryWrapper = Wrappers.<WbsParam>query().lambda();
+        IPage<WbsParam> pages  = this.service.page(Condition.getPage(query),queryWrapper);
+        return WbsParamWrapper.build().pageVO(pages);
+    }
+
+    @ApiOperationSupport(order = 5)
+    @ApiOperation(value = "获取名称字典", notes = "获取名称字典")
+    @GetMapping("/keymap")
+    public R<List<WbsParamBean>> list2() {
+        LambdaQueryWrapper<WbsParam> queryWrapper = Wrappers.<WbsParam>query().lambda().eq(WbsParam::getType,0);
+        List<WbsParamBean> list = new ArrayList<>();
+        List<WbsParam> data =  this.service.list(queryWrapper);
+        if(CollectionUtil.isNotEmpty(data)){
+            list = WbsParamWrapper.build().listVO(this.service.list(queryWrapper));
+        }
+        return R.data(list);
+    }
+
+    @ApiOperationSupport(order = 6)
+    @ApiOperation(value = "节点参数列表", notes = "节点参数列表")
+    @GetMapping("/list")
+    public R<List<WbsParamBean>> list3(@ApiParam(value = "wbs节点id", required = true) Long wbsId) {
+        LambdaQueryWrapper<WbsParam> queryWrapper = Wrappers.<WbsParam>query().lambda().eq(WbsParam::getWbsId,wbsId).eq(WbsParam::getType,1);
+        List<WbsParamBean> list = new ArrayList<>();
+        List<WbsParam> data =  this.service.list(queryWrapper);
+        if(CollectionUtil.isNotEmpty(data)){
+            list = WbsParamWrapper.build().listVO(this.service.list(queryWrapper));
+        }
+        return R.data(list);
+    }
+
+
+
+}

+ 35 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/feign/WbsTreeContractClientImpl.java

@@ -80,6 +80,7 @@ public class WbsTreeContractClientImpl implements WbsTreeContractClient {
             result.forEach(node -> {
                 //转换
                 WbsTreeContractTreeVOS vos = new WbsTreeContractTreeVOS();
+                vos.setDeptCategory(node.getDeptCategory());
                 vos.setPrimaryKeyId(String.valueOf(node.getPKeyId()));
                 vos.setTitle(StringUtils.isNotEmpty(node.getFullName()) ? node.getFullName() : node.getDeptName());
                 //最终返回集合
@@ -99,6 +100,40 @@ public class WbsTreeContractClientImpl implements WbsTreeContractClient {
                 while (iterator.hasNext()){
                     WbsTreeContractTreeVOS next = iterator.next();
                     if(next.getTitle().contains(dictBiz.getDictValue())){
+                        //设置图标
+                        switch (next.getDeptCategory()){
+                            case 7:
+                                //施工日志
+                                next.setIconValue("hcicon-Excavator-3");
+                                break;
+                            case 8:
+                                //监理日志
+                                next.setIconValue("hcicon-jianlizixun");
+                                break;
+                            case 9:
+                                //安全日志
+                                next.setIconValue("hcicon-anquan");
+                                break;
+                            case 10:
+                                //监理巡视日志
+                                next.setIconValue("hcicon-zhengkaiyanjing4");
+                                break;
+                            case 11:
+                                //监理旁站日志
+                                next.setIconValue("hcicon-side");
+                                break;
+                            case 12:
+                                //安全监理日志
+                                next.setIconValue("hcicon-jianlifang");
+                                break;
+                            case 13:
+                                //安全巡视日志
+                                next.setIconValue("hcicon-chakan");
+                                break;
+                            default:
+                                break;
+                        }
+
                         finalResult.add(next);
                         iterator.remove();
                         break;

+ 1 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/FormulaMapper.xml

@@ -17,6 +17,7 @@
         <result column="remark" property="remark"/>
         <result column="wbsId" property="wbs_id"/>
         <result column="elementId" property="element_id"/>
+        <result column="map" property="map"/>
     </resultMap>
 
 </mapper>

+ 45 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/LinkdataInfoMapper.java

@@ -0,0 +1,45 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.manager.mapper;
+
+import org.springblade.manager.entity.LinkdataInfo;
+import org.springblade.manager.vo.LinkdataInfoVO;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import java.util.List;
+
+/**
+ * 清表解析字段信息 Mapper 接口
+ *
+ * @author BladeX
+ * @since 2022-06-17
+ */
+public interface LinkdataInfoMapper extends BaseMapper<LinkdataInfo> {
+
+	/**
+	 * 自定义分页
+	 *
+	 * @param page
+	 * @param linkdataInfo
+	 * @return
+	 */
+	List<LinkdataInfoVO> selectLinkdataInfoPage(IPage page, LinkdataInfoVO linkdataInfo);
+
+
+	List<LinkdataInfo> getColSelect(String tabId);
+
+}

+ 25 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/LinkdataInfoMapper.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.LinkdataInfoMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="linkdataInfoResultMap" type="org.springblade.manager.entity.LinkdataInfo">
+        <result column="id" property="id"/>
+        <result column="tab_id" property="tabId"/>
+        <result column="col_name" property="colName"/>
+        <result column="col_key" property="colKey"/>
+        <result column="data_type" property="dataType"/>
+        <result column="html_type" property="htmlType"/>
+        <result column="tr_index" property="trIndex"/>
+        <result column="td_index" property="tdIndex"/>
+    </resultMap>
+
+
+    <select id="selectLinkdataInfoPage" resultMap="linkdataInfoResultMap">
+        select * from m_linkdata_info where is_deleted = 0
+    </select>
+
+    <select id="getColSelect" resultMap="linkdataInfoResultMap">
+        select * from m_linkdata_info where is_deleted = 0 and tab_id =#{tabId}
+    </select>
+</mapper>

+ 42 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/TextdictInfoMapper.java

@@ -0,0 +1,42 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.manager.mapper;
+
+import org.springblade.manager.entity.TextdictInfo;
+import org.springblade.manager.vo.TextdictInfoVO;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import java.util.List;
+
+/**
+ * 参数信息表 Mapper 接口
+ *
+ * @author BladeX
+ * @since 2022-06-17
+ */
+public interface TextdictInfoMapper extends BaseMapper<TextdictInfo> {
+
+	/**
+	 * 自定义分页
+	 *
+	 * @param page
+	 * @param textdictInfo
+	 * @return
+	 */
+	List<TextdictInfoVO> selectTextdictInfoPage(IPage page, TextdictInfoVO textdictInfo);
+
+}

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

@@ -0,0 +1,20 @@
+<?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.TextdictInfoMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="textdictInfoResultMap" type="org.springblade.manager.entity.TextdictInfo">
+        <result column="id" property="id"/>
+        <result column="is_deleted" property="isDeleted"/>
+        <result column="dict_value" property="dictValue"/>
+        <result column="sort" property="sort"/>
+        <result column="com_id" property="comId"/>
+        <result column="is_defult" property="isDefult"/>
+    </resultMap>
+
+
+    <select id="selectTextdictInfoPage" resultMap="textdictInfoResultMap">
+        select * from m_textdict_info where is_deleted = 0
+    </select>
+
+</mapper>

+ 7 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsParamMapper.java

@@ -0,0 +1,7 @@
+package org.springblade.manager.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.springblade.manager.entity.WbsParam;
+
+public interface WbsParamMapper extends BaseMapper<WbsParam> {
+}

+ 21 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsParamMapper.xml

@@ -0,0 +1,21 @@
+<?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.WbsParamMapper">
+    <resultMap id="ResultMap" type="org.springblade.manager.entity.WbsParam">
+        <result column="id" property="id"/>
+        <result column="createUser" property="create_user"/>
+        <result column="createDept" property="create_dept"/>
+        <result column="createTime" property="create_time"/>
+        <result column="updateUser" property="update_user"/>
+        <result column="updateTime" property="update_time"/>
+        <result column="status" property="status"/>
+        <result column="isDeleted" property="is_deleted"/>
+        <result column="name" property="name"/>
+        <result column="k" property="k"/>
+        <result column="v" property="v"/>
+        <result column="wbsId" property="wbs_id"/>
+        <result column="remark" property="remark"/>
+        <result column="type" property="type"/>
+    </resultMap>
+
+</mapper>

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

@@ -170,7 +170,8 @@
         select
             p_key_id,
             dept_name,
-            full_name
+            full_name,
+            dept_category
         from
           m_wbs_tree_contract
         where

+ 1 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreePrivateMapper.xml

@@ -296,6 +296,7 @@
             wt.table_owner as tableOwner,
             wt.is_link_table,
             wt.init_table_name,
+            wt.excel_id as excelId,
             wt.sort
         FROM
             m_wbs_tree_private AS wt

+ 44 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/ILinkdataInfoService.java

@@ -0,0 +1,44 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.manager.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.springblade.manager.entity.LinkdataInfo;
+import org.springblade.manager.vo.LinkdataInfoVO;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+import java.util.List;
+
+/**
+ * 清表解析字段信息 服务类
+ *
+ * @author BladeX
+ * @since 2022-06-17
+ */
+public interface ILinkdataInfoService extends IService<LinkdataInfo> {
+
+	/**
+	 * 自定义分页
+	 *
+	 * @param page
+	 * @param linkdataInfo
+	 * @return
+	 */
+	IPage<LinkdataInfoVO> selectLinkdataInfoPage(IPage<LinkdataInfoVO> page, LinkdataInfoVO linkdataInfo);
+
+	List<LinkdataInfo> getColSelect(String tabId);
+}

+ 44 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/ITextdictInfoService.java

@@ -0,0 +1,44 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.manager.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.springblade.core.tool.api.R;
+import org.springblade.manager.entity.TextdictInfo;
+import org.springblade.manager.vo.TextdictDataInfoVO;
+import org.springblade.manager.vo.TextdictInfoVO;
+import org.springblade.core.mp.base.BaseService;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+/**
+ * 参数信息表 服务类
+ *
+ * @author BladeX
+ * @since 2022-06-17
+ */
+public interface ITextdictInfoService extends IService<TextdictInfo> {
+
+	/**
+	 * 自定义分页
+	 *
+	 * @param page
+	 * @param textdictInfo
+	 * @return
+	 */
+	IPage<TextdictInfoVO> selectTextdictInfoPage(IPage<TextdictInfoVO> page, TextdictInfoVO textdictInfo);
+
+}

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

@@ -0,0 +1,13 @@
+package org.springblade.manager.service;
+
+import org.springblade.core.mp.base.BaseService;
+import org.springblade.manager.entity.WbsInfo;
+import org.springblade.manager.entity.WbsParam;
+
+/**
+ * @author yangyj
+ * @Date 2022/6/17 17:02
+ * @description TODO
+ */
+public interface IWbsParamService  extends BaseService<WbsParam> {
+}

+ 48 - 14
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java

@@ -31,38 +31,72 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
      **/
     public void execute(Map variables, List<FormData> list,List<Formula> formulas ){
              Map<Boolean,List<FormData>> map = list.stream().collect(Collectors.partitioningBy(e->e!=null&&e.getFormula().getFormula().contains("E[")));
-             /*有依赖的*/
-             List<FormData> rely= map.get(true);
+            List<FormData>total = new ArrayList<>();
              /*没有依赖的*/
              List<FormData> simple=map.get(false);
+             if(CollectionUtil.isNotEmpty(simple)){
+                 total.addAll(simple);
+             }
+            /*有依赖的*/
+             List<FormData> rely= map.get(true);
+             if(CollectionUtil.isNotEmpty(rely)){
+                  sort(rely,((rely.size()+1)/2)*rely.size());
+                  total.addAll(rely);
+             }
+            if(CollectionUtil.isNotEmpty(total)){
+                /*预处理*/
+                for(FormData fd:total){
 
+                }
+            }
     }
 
 
-    public static final String ELE_CODE_REG= "(?<=E\\[)[^]]+(?=\\])";
+
 
     /**
      * 依赖排序
      */
-    public   void sort( List<FormData> list,List<FormData> data,List<FormData> queue,FormData current){
-        if(current!=null){
-            Pattern p = Pattern.compile(ELE_CODE_REG);
-            Matcher m =p.matcher(current.getFormula().getFormula());
+    public static final String ELE_CODE_REG= "(?<=E\\[)[^]]+(?=\\])";
+    public static final  Pattern P = Pattern.compile(ELE_CODE_REG);
+    public  static void sort( List<FormData> list,int n){
+        System.out.println("剩余计算次数:"+n+"次");
+        if(move(list)&&n>0){
+            sort(list,--n);
+        }
+    }
+    public  static Boolean move( List<FormData> list){
+        for(int i=0;i<list.size();i++){
+            FormData f=list.get(i);
+            Matcher m =P.matcher(f.getFormula().getFormula());
             List<String> cp =  new ArrayList<>();
             while (m.find()){
                 cp.add(m.group());
             }
-           Map<Boolean,List<FormData>>  map= list.stream().collect(Collectors.partitioningBy(e->cp.contains(e.getEKey())));
+            Map<Boolean,List<FormData>>  map= list.stream().skip(i+1).collect(Collectors.partitioningBy(e->cp.contains(e.getEKey())));
             List<FormData> match =map.get(true);
             if(CollectionUtil.isNotEmpty(match)){
-                data.addAll(match);
-            }
-            List<FormData> remain =map.get(false);
-            if(CollectionUtil.isNotEmpty(remain)){
-                list.clear();
-                list.addAll(remain);
+                for(FormData r:match){
+                    list.remove(r);
+                }
+                list.addAll(0,match);
+                return true;
             }
         }
+        return false;
+
     }
 
+
+
 }
+
+
+
+
+
+
+
+
+
+

+ 48 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/LinkdataInfoServiceImpl.java

@@ -0,0 +1,48 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.manager.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springblade.manager.entity.LinkdataInfo;
+import org.springblade.manager.mapper.LinkdataInfoMapper;
+import org.springblade.manager.service.ILinkdataInfoService;
+import org.springblade.manager.vo.LinkdataInfoVO;
+import org.springframework.stereotype.Service;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+import java.util.List;
+
+/**
+ * 清表解析字段信息 服务实现类
+ *
+ * @author BladeX
+ * @since 2022-06-17
+ */
+@Service
+public class LinkdataInfoServiceImpl extends ServiceImpl<LinkdataInfoMapper, LinkdataInfo> implements ILinkdataInfoService {
+
+	@Override
+	public IPage<LinkdataInfoVO> selectLinkdataInfoPage(IPage<LinkdataInfoVO> page, LinkdataInfoVO linkdataInfo) {
+		return page.setRecords(baseMapper.selectLinkdataInfoPage(page, linkdataInfo));
+	}
+
+	@Override
+	public List<LinkdataInfo> getColSelect(String tabId) {
+		return baseMapper.getColSelect(tabId);
+	}
+
+}

+ 44 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/TextdictInfoServiceImpl.java

@@ -0,0 +1,44 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.manager.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springblade.core.tool.api.R;
+import org.springblade.manager.entity.TextdictInfo;
+import org.springblade.manager.vo.TextdictDataInfoVO;
+import org.springblade.manager.vo.TextdictInfoVO;
+import org.springblade.manager.mapper.TextdictInfoMapper;
+import org.springblade.manager.service.ITextdictInfoService;
+import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springframework.stereotype.Service;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+/**
+ * 参数信息表 服务实现类
+ *
+ * @author BladeX
+ * @since 2022-06-17
+ */
+@Service
+public class TextdictInfoServiceImpl extends ServiceImpl<TextdictInfoMapper, TextdictInfo> implements ITextdictInfoService {
+
+	@Override
+	public IPage<TextdictInfoVO> selectTextdictInfoPage(IPage<TextdictInfoVO> page, TextdictInfoVO textdictInfo) {
+		return page.setRecords(baseMapper.selectTextdictInfoPage(page, textdictInfo));
+	}
+
+}

+ 18 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsParamServiceImpl.java

@@ -0,0 +1,18 @@
+package org.springblade.manager.service.impl;
+
+import lombok.AllArgsConstructor;
+import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springblade.manager.entity.WbsParam;
+import org.springblade.manager.mapper.WbsParamMapper;
+import org.springblade.manager.service.IWbsParamService;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author yangyj
+ * @Date 2022/6/17 17:00
+ * @description TODO
+ */
+@Service
+@AllArgsConstructor
+public class WbsParamServiceImpl extends BaseServiceImpl<WbsParamMapper, WbsParam> implements IWbsParamService {
+}

+ 25 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/wrapper/WbsParamWrapper.java

@@ -0,0 +1,25 @@
+package org.springblade.manager.wrapper;
+
+
+import org.springblade.core.mp.support.BaseEntityWrapper;
+import org.springblade.core.tool.utils.BeanUtil;
+import org.springblade.manager.dto.WbsParamBean;
+import org.springblade.manager.entity.WbsParam;
+
+import java.util.Objects;
+
+/**
+ * @author yangyj
+
+ * @Date 2022/6/17 17:28
+ * @description TODO
+ */
+public class WbsParamWrapper extends BaseEntityWrapper<WbsParam, WbsParamBean> {
+    public static WbsParamWrapper build() {
+        return new WbsParamWrapper();
+    }
+    @Override
+    public WbsParamBean entityVO(WbsParam entity) {
+        return  Objects.requireNonNull(BeanUtil.copy(entity, WbsParamBean.class));
+    }
+}