suyun 5 dias atrás
commit
380006d7a4
100 arquivos alterados com 7354 adições e 0 exclusões
  1. 29 0
      .gitignore
  2. 114 0
      pom.xml
  3. 13 0
      src/main/java/com/nh/farm/cloud/SaleCloudApplication.java
  4. 58 0
      src/main/java/com/nh/farm/cloud/basic/entity/BaseEntity.java
  5. 59 0
      src/main/java/com/nh/farm/cloud/basic/entity/BaseEntityUseMp.java
  6. 93 0
      src/main/java/com/nh/farm/cloud/basic/entity/LoginUser.java
  7. 73 0
      src/main/java/com/nh/farm/cloud/basic/entity/PageQuery.java
  8. 29 0
      src/main/java/com/nh/farm/cloud/basic/entity/SysUserRoleEntity.java
  9. 52 0
      src/main/java/com/nh/farm/cloud/basic/entity/UserEntity.java
  10. 86 0
      src/main/java/com/nh/farm/cloud/business/controller/SaleCommendController.java
  11. 106 0
      src/main/java/com/nh/farm/cloud/business/controller/SaleComplainController.java
  12. 116 0
      src/main/java/com/nh/farm/cloud/business/controller/SaleFeedbackController.java
  13. 136 0
      src/main/java/com/nh/farm/cloud/business/controller/SaleSatisfactionController.java
  14. 42 0
      src/main/java/com/nh/farm/cloud/business/domain/dto/SaleCommendInfoDto.java
  15. 42 0
      src/main/java/com/nh/farm/cloud/business/domain/dto/SaleComplainInfoDto.java
  16. 50 0
      src/main/java/com/nh/farm/cloud/business/domain/dto/SaleFeedbackDetailDto.java
  17. 56 0
      src/main/java/com/nh/farm/cloud/business/domain/dto/SaleFeedbackInfoDto.java
  18. 63 0
      src/main/java/com/nh/farm/cloud/business/domain/dto/SalePageQuery.java
  19. 111 0
      src/main/java/com/nh/farm/cloud/business/domain/dto/SaleSatisfactionBasicDto.java
  20. 45 0
      src/main/java/com/nh/farm/cloud/business/domain/dto/SaleSatisfactionDetailDto.java
  21. 52 0
      src/main/java/com/nh/farm/cloud/business/domain/dto/SaleSatisfactionInfoDto.java
  22. 108 0
      src/main/java/com/nh/farm/cloud/business/domain/po/SaleCommendInfoPo.java
  23. 137 0
      src/main/java/com/nh/farm/cloud/business/domain/po/SaleComplainInfoPo.java
  24. 60 0
      src/main/java/com/nh/farm/cloud/business/domain/po/SaleFeedbackDetailPo.java
  25. 107 0
      src/main/java/com/nh/farm/cloud/business/domain/po/SaleFeedbackInfoPo.java
  26. 122 0
      src/main/java/com/nh/farm/cloud/business/domain/po/SaleSatisfactionBasicPo.java
  27. 53 0
      src/main/java/com/nh/farm/cloud/business/domain/po/SaleSatisfactionDetailPo.java
  28. 125 0
      src/main/java/com/nh/farm/cloud/business/domain/po/SaleSatisfactionInfoPo.java
  29. 19 0
      src/main/java/com/nh/farm/cloud/business/mapper/OtherDataMapper.java
  30. 24 0
      src/main/java/com/nh/farm/cloud/business/mapper/SaleCommendInfoMapper.java
  31. 24 0
      src/main/java/com/nh/farm/cloud/business/mapper/SaleComplainInfoMapper.java
  32. 16 0
      src/main/java/com/nh/farm/cloud/business/mapper/SaleFeedbackDetailMapper.java
  33. 25 0
      src/main/java/com/nh/farm/cloud/business/mapper/SaleFeedbackInfoMapper.java
  34. 14 0
      src/main/java/com/nh/farm/cloud/business/mapper/SaleSatisfactionBasicMapper.java
  35. 24 0
      src/main/java/com/nh/farm/cloud/business/mapper/SaleSatisfactionDetailMapper.java
  36. 18 0
      src/main/java/com/nh/farm/cloud/business/mapper/SaleSatisfactionInfoMapper.java
  37. 13 0
      src/main/java/com/nh/farm/cloud/business/service/OtherDataService.java
  38. 27 0
      src/main/java/com/nh/farm/cloud/business/service/SaleCommendInfoService.java
  39. 27 0
      src/main/java/com/nh/farm/cloud/business/service/SaleComplainInfoService.java
  40. 18 0
      src/main/java/com/nh/farm/cloud/business/service/SaleFeedbackDetailService.java
  41. 32 0
      src/main/java/com/nh/farm/cloud/business/service/SaleFeedbackInfoService.java
  42. 24 0
      src/main/java/com/nh/farm/cloud/business/service/SaleSatisfactionBasicService.java
  43. 20 0
      src/main/java/com/nh/farm/cloud/business/service/SaleSatisfactionDetailService.java
  44. 19 0
      src/main/java/com/nh/farm/cloud/business/service/SaleSatisfactionInfoService.java
  45. 26 0
      src/main/java/com/nh/farm/cloud/business/service/impl/OtherDataServiceImpl.java
  46. 34 0
      src/main/java/com/nh/farm/cloud/business/service/impl/SaleCommendInfoServiceImpl.java
  47. 34 0
      src/main/java/com/nh/farm/cloud/business/service/impl/SaleComplainInfoServiceImpl.java
  48. 35 0
      src/main/java/com/nh/farm/cloud/business/service/impl/SaleFeedbackDetailServiceImpl.java
  49. 41 0
      src/main/java/com/nh/farm/cloud/business/service/impl/SaleFeedbackInfoServiceImpl.java
  50. 55 0
      src/main/java/com/nh/farm/cloud/business/service/impl/SaleSatisfactionBasicServiceImpl.java
  51. 53 0
      src/main/java/com/nh/farm/cloud/business/service/impl/SaleSatisfactionDetailServiceImpl.java
  52. 26 0
      src/main/java/com/nh/farm/cloud/business/service/impl/SaleSatisfactionInfoServiceImpl.java
  53. 357 0
      src/main/java/com/nh/farm/cloud/config/JacksonObjectMapper.java
  54. 65 0
      src/main/java/com/nh/farm/cloud/config/MyMetaObjectHandler.java
  55. 25 0
      src/main/java/com/nh/farm/cloud/config/MybatisPlusConfig.java
  56. 19 0
      src/main/java/com/nh/farm/cloud/config/ObjectWrapperFactoryConverter.java
  57. 6 0
      src/main/java/com/nh/farm/cloud/config/ShopConfig.java
  58. 29 0
      src/main/java/com/nh/farm/cloud/config/UploadConfig.java
  59. 60 0
      src/main/java/com/nh/farm/cloud/config/WebConfig.java
  60. 233 0
      src/main/java/com/nh/farm/cloud/util/AesUtil.java
  61. 139 0
      src/main/java/com/nh/farm/cloud/util/BigDecimalUtil.java
  62. 38 0
      src/main/java/com/nh/farm/cloud/util/CheckChineseUtil.java
  63. 95 0
      src/main/java/com/nh/farm/cloud/util/Constants.java
  64. 73 0
      src/main/java/com/nh/farm/cloud/util/CookieUtil.java
  65. 14 0
      src/main/java/com/nh/farm/cloud/util/CustomHandler.java
  66. 100 0
      src/main/java/com/nh/farm/cloud/util/CustomWriteHandler.java
  67. 67 0
      src/main/java/com/nh/farm/cloud/util/DateUtils.java
  68. 156 0
      src/main/java/com/nh/farm/cloud/util/DesensitizedUtils.java
  69. 125 0
      src/main/java/com/nh/farm/cloud/util/ExcelTemplate.java
  70. 38 0
      src/main/java/com/nh/farm/cloud/util/GetNowDate.java
  71. 88 0
      src/main/java/com/nh/farm/cloud/util/HttpUrlConn.java
  72. 81 0
      src/main/java/com/nh/farm/cloud/util/LowerUtils.java
  73. 129 0
      src/main/java/com/nh/farm/cloud/util/LowerUtils2.java
  74. 49 0
      src/main/java/com/nh/farm/cloud/util/PageResult.java
  75. 186 0
      src/main/java/com/nh/farm/cloud/util/ServletUtils.java
  76. 405 0
      src/main/java/com/nh/farm/cloud/util/StringUtils.java
  77. 174 0
      src/main/java/com/nh/farm/cloud/util/TreeTools.java
  78. 20 0
      src/main/java/com/nh/farm/cloud/util/enums/BusinessStatus.java
  79. 98 0
      src/main/java/com/nh/farm/cloud/util/enums/BusinessType.java
  80. 65 0
      src/main/java/com/nh/farm/cloud/util/enums/OperatorType.java
  81. 47 0
      src/main/java/com/nh/farm/cloud/util/enums/SensitiveTypeEnum.java
  82. 109 0
      src/main/java/com/nh/farm/cloud/util/enums/SysTemType.java
  83. 25 0
      src/main/java/com/nh/farm/cloud/util/excelUtil/BigDecimalNumberNewConverter.java
  84. 57 0
      src/main/java/com/nh/farm/cloud/util/excelUtil/ExcelDemoUtils.java
  85. 52 0
      src/main/java/com/nh/farm/cloud/util/getNumUtil.java
  86. 46 0
      src/main/java/com/nh/farm/cloud/util/ip/AddressUtils.java
  87. 222 0
      src/main/java/com/nh/farm/cloud/util/ip/IpUtils.java
  88. 11 0
      src/main/java/com/nh/farm/cloud/util/push/PushConfig.java
  89. 23 0
      src/main/java/com/nh/farm/cloud/util/redis/CacheConstants.java
  90. 246 0
      src/main/java/com/nh/farm/cloud/util/redis/RedisCacheUtil.java
  91. 191 0
      src/main/java/com/nh/farm/cloud/util/redis/TokenUtil.java
  92. 35 0
      src/main/java/com/nh/farm/cloud/util/returnop/JsonUtil.java
  93. 134 0
      src/main/java/com/nh/farm/cloud/util/returnop/ReFlectUtil.java
  94. 17 0
      src/main/java/com/nh/farm/cloud/util/returnop/anno/NotSet.java
  95. 108 0
      src/main/java/com/nh/farm/cloud/util/token/AseController.java
  96. 16 0
      src/main/java/com/nh/farm/cloud/util/token/TokenCheck.java
  97. 79 0
      src/main/java/com/nh/farm/cloud/util/tree/AuthTreeTools.java
  98. 169 0
      src/main/java/com/nh/farm/cloud/util/tree/TreeTools.java
  99. 48 0
      src/main/java/com/nh/farm/cloud/util/tree/TreeUtil.java
  100. 0 0
      src/main/resources/application-prod.yml

+ 29 - 0
.gitignore

@@ -0,0 +1,29 @@
+HELP.md
+/target/
+!.mvn/wrapper/maven-wrapper.jar
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+/build/
+
+### VS Code ###
+.vscode/

+ 114 - 0
pom.xml

@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.6.7</version>
+    </parent>
+
+    <groupId>com.nh.farm.cloud</groupId>
+    <artifactId>nh-mcro-sale</artifactId>
+    <version>1.0.0</version>
+    <packaging>jar</packaging>
+
+    <!--设置jdk版本变量-->
+    <properties>
+        <java.version>11</java.version>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.nh.fk</groupId>
+            <artifactId>nh-common</artifactId>
+            <version>2.0.0</version>
+        </dependency>
+
+        <!-- Web undertow -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+
+        <!-- DB 相关 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-jdbc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.oracle.ojdbc</groupId>
+            <artifactId>ojdbc8</artifactId>
+            <version>19.3.0.0</version>
+        </dependency>
+        <dependency>
+            <groupId>cn.easyproject</groupId>
+            <artifactId>orai18n</artifactId>
+            <version>12.1.0.2.0</version>
+        </dependency>
+        <!-- mybatisPlus集成 -->
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+            <version>3.4.3.4</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+        <!-- jjwt -->
+        <dependency>
+            <groupId>io.jsonwebtoken</groupId>
+            <artifactId>jjwt</artifactId>
+            <version>0.9.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <version>1.18.22</version>
+        </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.5.7</version>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.56</version>
+            <scope>compile</scope>
+        </dependency>
+        <!-- excel实用导入 -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>easyexcel</artifactId>
+            <version>3.1.1</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-fileupload</groupId>
+            <artifactId>commons-fileupload</artifactId>
+            <version>1.4</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>2.8.0</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>2.6.0</version>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 13 - 0
src/main/java/com/nh/farm/cloud/SaleCloudApplication.java

@@ -0,0 +1,13 @@
+package com.nh.farm.cloud;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class SaleCloudApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(SaleCloudApplication.class, args);
+    }
+
+}

+ 58 - 0
src/main/java/com/nh/farm/cloud/basic/entity/BaseEntity.java

@@ -0,0 +1,58 @@
+package com.nh.farm.cloud.basic.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import lombok.ToString;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import javax.persistence.Column;
+import javax.persistence.EntityListeners;
+import javax.persistence.MappedSuperclass;
+import javax.persistence.Transient;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+@Data
+@ToString
+@EntityListeners(AuditingEntityListener.class)
+@MappedSuperclass
+public class BaseEntity implements Serializable {
+	private static final long serialVersionUID = 4549208998135217511L;
+
+    /** 数据来源,0正常录入 1导入数据  2跑批数据  3 迁移数据  默认为0**/
+    @Column(name = "data_flag")
+    @TableField(fill = FieldFill.INSERT)
+    private String dataFlag;
+
+    /** 删除状态, 0删除  1 未删除  默认为1 **/
+    @Column(name = "deleted")
+    @TableField(fill = FieldFill.INSERT)
+    private String deleted;
+    /** 创建时间 */
+    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
+    @TableField(value = "CREATED_TIME",fill = FieldFill.INSERT)
+    @Column(name = "CREATED_TIME")
+    private LocalDateTime createTime;
+
+    /** 更新时间 */
+    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
+    @TableField(value = "UPDATE_TIME",fill = FieldFill.INSERT_UPDATE)
+    private LocalDateTime updateTime;
+
+    @Transient
+    @TableField(fill = FieldFill.INSERT_UPDATE, update="%s+1")
+    private Integer version;
+
+    @TableField(value = "CREATED_BY",fill = FieldFill.INSERT)
+    @Column(name = "CREATED_BY")
+    private String createBy;
+
+    /** 更新者的id */
+    @Column(name = "UPDATE_BY")
+    @TableField(value = "UPDATE_BY",fill = FieldFill.INSERT_UPDATE)
+    private String updateBy;
+
+
+}

+ 59 - 0
src/main/java/com/nh/farm/cloud/basic/entity/BaseEntityUseMp.java

@@ -0,0 +1,59 @@
+package com.nh.farm.cloud.basic.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import lombok.ToString;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import javax.persistence.EntityListeners;
+import javax.persistence.MappedSuperclass;
+import javax.persistence.Transient;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+@Data
+@ToString
+@EntityListeners(AuditingEntityListener.class)
+@MappedSuperclass
+public class BaseEntityUseMp implements Serializable {
+
+    /** 数据来源,0正常录入 1导入数据  2跑批数据  3 迁移数据  默认为0**/
+    @TableField(fill = FieldFill.INSERT, value = "DATA_FLAG")
+    private String dataFlag;
+
+    /** 删除状态, 0删除  1 未删除  默认为1 **/
+    @TableField(fill = FieldFill.INSERT, value = "DELETED")
+    private String deleted;
+
+    @Transient
+    @TableField(fill = FieldFill.INSERT_UPDATE, update="%s+1", value = "VERSION")
+    private Integer version;
+
+    /** 创建时间 */
+    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
+    @TableField(fill = FieldFill.INSERT, value = "CREATED_TIME")
+    private LocalDateTime createTime;
+
+    /** 更新时间 */
+    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
+    @TableField(value = "UPDATE_TIME",fill = FieldFill.INSERT_UPDATE)
+    private LocalDateTime updateTime;
+
+    @TableField(fill = FieldFill.INSERT, value = "CREATED_BY")
+    private String createBy;
+
+    /** 更新者的id */
+    @TableField(value = "UPDATE_BY",fill = FieldFill.INSERT_UPDATE)
+    private String updateBy;
+
+    @TableField(fill = FieldFill.INSERT, value = "CREATED_BY_NAME")
+    private String createByName;
+
+    /** 更新者的id */
+    @TableField(fill = FieldFill.INSERT_UPDATE, value = "UPDATE_BY_NAME")
+    private String updateByName;
+
+
+}

+ 93 - 0
src/main/java/com/nh/farm/cloud/basic/entity/LoginUser.java

@@ -0,0 +1,93 @@
+package com.nh.farm.cloud.basic.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * 用户信息
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class LoginUser implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 用户唯一标识
+     */
+    private String token;
+
+    /**
+     * 用户名id
+     */
+    private String kid;
+
+    /**
+     * 用户名
+     */
+    private String username;
+
+    /**
+     * 用户级别
+     */
+    private Integer bankLevel;
+
+    /**
+     * 登录时间
+     */
+    private Long loginTime;
+
+    /**
+     * 过期时间
+     */
+    private Long expireTime;
+
+    /**
+     * 登录IP地址
+     */
+    private String ipaddr;
+
+    /**
+     * 登录地点
+     */
+    private String loginLocation;
+
+    /**
+     * 浏览器类型
+     */
+    private String browser;
+
+    /**
+     * 操作系统
+     */
+    private String os;
+    /**
+     * 使用端 APP PC
+     */
+    private String useSide;
+    /**
+     * 权限列表
+     */
+    private Set<String> permissions;
+
+    /**
+     * 用户信息
+     */
+    private UserEntity sysUser;
+
+
+    private List<SysUserRoleEntity> roleKids;
+
+
+    public LoginUser(UserEntity user,Integer bankLevel, Set<String> permissions,List<SysUserRoleEntity> roleKids) {
+        this.sysUser = user;
+        this.bankLevel = bankLevel;
+        this.permissions = permissions;
+        this.roleKids = roleKids;
+    }
+}

+ 73 - 0
src/main/java/com/nh/farm/cloud/basic/entity/PageQuery.java

@@ -0,0 +1,73 @@
+package com.nh.farm.cloud.basic.entity;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.nh.fk.common.base.dto.BaseQuery;
+import com.nh.fk.common.base.ne.NeSort;
+import com.nh.fk.common.util.ChkUtil;
+import lombok.Data;
+import org.springframework.data.domain.Sort;
+
+@Data
+public class PageQuery implements BaseQuery {
+    private Integer limit = 2;
+    private Integer page = 1;
+    private String sort;
+
+    public Sort getSorted() {
+        if (ChkUtil.isNotNull(this.sort)) {
+            JSONArray sortArray = JSONArray.parseArray(this.sort);
+            if (sortArray != null && sortArray.size() > 0) {
+                JSONObject sorter = sortArray.getJSONObject(0);
+                String porterty = sorter.getString("property");
+                String directionStr = sorter.getString("direction");
+                Sort.Direction direction = Sort.Direction.fromString(directionStr);
+                return Sort.by(direction, new String[]{porterty});
+            }
+        }
+
+        return null;
+    }
+
+    public NeSort getSort() {
+        if (ChkUtil.isNotNull(this.sort)) {
+            JSONArray sortArray = JSONArray.parseArray(this.sort);
+            if (sortArray != null && sortArray.size() > 0) {
+                JSONObject sorter = sortArray.getJSONObject(0);
+                String porterty = sorter.getString("property");
+                String direction = sorter.getString("direction");
+                NeSort neSort = new NeSort(porterty, direction);
+                return neSort;
+            }
+        }
+
+        return null;
+    }
+
+    public PageQuery() {
+    }
+
+    public Integer getLimit() {
+        return limit;
+    }
+
+    public void setLimit(Integer limit) {
+        if(null == limit){
+            limit = 2;
+        }
+        this.limit = limit;
+    }
+
+    public Integer getPage() {
+        if(null == page){
+            page = 1;
+        }
+        return page;
+    }
+
+    public void setPage(Integer page) {
+        this.page = page;
+    }
+
+
+}

+ 29 - 0
src/main/java/com/nh/farm/cloud/basic/entity/SysUserRoleEntity.java

@@ -0,0 +1,29 @@
+package com.nh.farm.cloud.basic.entity;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 用户角色机构表
+ */
+@Data
+public class SysUserRoleEntity implements Serializable {
+
+    private String userKid;
+    private String pcRoleKid;
+    private String appRoleKid;
+    private String bankCode;
+
+    private String menuKid;
+
+
+
+    private String[]  pcRole;
+
+    private String[] appRole;
+
+    private String bankName;
+
+
+}

+ 52 - 0
src/main/java/com/nh/farm/cloud/basic/entity/UserEntity.java

@@ -0,0 +1,52 @@
+package com.nh.farm.cloud.basic.entity;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+
+/**
+ * @author jueLun
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class UserEntity  extends BaseEntity implements Serializable {
+
+    private static final long serialVersionUID = -8760839825144798347L;
+    private String kid;
+    /**用户名**/
+    private String username;
+    /**用户昵称**/
+    private String nickName;
+    /**机构号**/
+    private String bankCode;
+    /**密码**/
+    private String password;
+    /**是否是管理员 1是 0否 **/
+    private Boolean isAdmin;
+    /**手机号 **/
+    private String phone;
+    /**启用禁用 **/
+    private Boolean isEnable;
+    /**最后修改密码的时间**/
+    @JsonDeserialize(using = LocalDateTimeDeserializer.class)
+    @JsonSerialize(using = LocalDateTimeSerializer.class)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime updatePwdDate;
+    /**头像地址**/
+    private String avatar;
+    /**备注**/
+    private String remark;
+
+    /**机构名称**/
+    private String bankName;
+
+
+}

+ 86 - 0
src/main/java/com/nh/farm/cloud/business/controller/SaleCommendController.java

@@ -0,0 +1,86 @@
+package com.nh.farm.cloud.business.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.nh.farm.cloud.basic.entity.UserEntity;
+import com.nh.farm.cloud.business.domain.dto.SaleCommendInfoDto;
+import com.nh.farm.cloud.business.domain.dto.SalePageQuery;
+import com.nh.farm.cloud.business.domain.po.SaleCommendInfoPo;
+import com.nh.farm.cloud.business.service.OtherDataService;
+import com.nh.farm.cloud.business.service.SaleCommendInfoService;
+import com.nh.farm.cloud.util.redis.TokenUtil;
+import com.nh.fk.common.util.wrapper.WrapMapper;
+import com.nh.fk.common.util.wrapper.Wrapper;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.*;
+
+import java.time.LocalDateTime;
+import java.util.Map;
+
+/**
+ * @description: 表扬信
+ * @author: suyun
+ */
+@RestController
+@RequestMapping("commend")
+public class SaleCommendController {
+
+    @Autowired
+    private TokenUtil tokenUtil;
+
+    @Autowired
+    private OtherDataService otherDataService;
+
+    @Autowired
+    private SaleCommendInfoService saleCommendInfoService;
+
+    /**
+     * 汇总
+     */
+    @GetMapping("/collectInfo")
+    public Wrapper<Map<String, Object>> collectInfo(SalePageQuery pageQuery) {
+        Map<String, Object> map =  saleCommendInfoService.collectInfo(pageQuery);
+        return WrapMapper.ok(map);
+    }
+
+    /**
+     * 分页
+     */
+    @GetMapping("/selectInfo")
+    public Wrapper<IPage<SaleCommendInfoPo>> selectInfo(SalePageQuery pageQuery) {
+        IPage page = saleCommendInfoService.queryPage(pageQuery);
+        return WrapMapper.ok(page);
+    }
+
+    /**
+     * 新增
+     */
+    @Transactional
+    @PostMapping("/saveInfo")
+    public Wrapper<String> saveInfo(@RequestBody SaleCommendInfoDto commend){
+        SaleCommendInfoPo saleCommendInfoPo = new SaleCommendInfoPo();
+        BeanUtils.copyProperties(commend, saleCommendInfoPo);
+        UserEntity user = tokenUtil.getUser();
+        String phone = user.getPhone();
+        String nickName = user.getNickName();
+
+        Map<String, Object> projectInfo = otherDataService.selectProjectInfo(commend.getBankCode());
+        if (projectInfo != null) {
+            saleCommendInfoPo.setProjectId(projectInfo.get("projectId") == null ? null : projectInfo.get("projectId").toString());
+            saleCommendInfoPo.setProjectName(projectInfo.get("projectName") == null ? null : projectInfo.get("projectName").toString());
+            saleCommendInfoPo.setSaleManagerId(projectInfo.get("saleManagerId") == null ? null : projectInfo.get("saleManagerId").toString());
+            saleCommendInfoPo.setSaleManagerName(projectInfo.get("saleManagerName") == null ? null : projectInfo.get("saleManagerName").toString());
+        }
+
+        saleCommendInfoPo.setCreatedBy(nickName);
+        saleCommendInfoPo.setPhone(phone);
+        saleCommendInfoPo.setSubmitter(nickName);
+        saleCommendInfoPo.setSubmitTime(LocalDateTime.now());
+
+        saleCommendInfoService.saveOrUpdate(saleCommendInfoPo);
+
+        return WrapMapper.ok("添加成功");
+    }
+
+}

+ 106 - 0
src/main/java/com/nh/farm/cloud/business/controller/SaleComplainController.java

@@ -0,0 +1,106 @@
+package com.nh.farm.cloud.business.controller;
+
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.nh.farm.cloud.basic.entity.UserEntity;
+import com.nh.farm.cloud.business.domain.dto.SaleComplainInfoDto;
+import com.nh.farm.cloud.business.domain.dto.SalePageQuery;
+import com.nh.farm.cloud.business.domain.po.SaleComplainInfoPo;
+import com.nh.farm.cloud.business.service.OtherDataService;
+import com.nh.farm.cloud.business.service.SaleComplainInfoService;
+import com.nh.farm.cloud.util.redis.TokenUtil;
+import com.nh.fk.common.util.wrapper.WrapMapper;
+import com.nh.fk.common.util.wrapper.Wrapper;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.*;
+
+import java.time.LocalDateTime;
+import java.util.Map;
+
+/**
+ * @description: 投诉建议
+ * @author: suyun
+ */
+@RestController
+@RequestMapping("complain")
+public class SaleComplainController {
+
+    @Autowired
+    private TokenUtil tokenUtil;
+
+    @Autowired
+    private OtherDataService otherDataService;
+
+    @Autowired
+    private SaleComplainInfoService saleComplainInfoService;
+
+    /**
+     * 汇总
+     */
+    @GetMapping("/collectInfo")
+    public Wrapper<Map<String, Object>> collectInfo(SalePageQuery pageQuery) {
+        Map<String, Object> map = saleComplainInfoService.collectInfo(pageQuery);
+        return WrapMapper.ok(map);
+    }
+
+    /**
+     * 分页
+     */
+    @GetMapping("/selectInfo")
+    public Wrapper<IPage<SaleComplainInfoPo>> selectInfo(SalePageQuery pageQuery) {
+        IPage page = saleComplainInfoService.queryPage(pageQuery);
+        return WrapMapper.ok(page);
+    }
+
+    /**
+     * 新增
+     */
+    @Transactional
+    @PostMapping("/saveInfo")
+    public Wrapper<String> saveInfo(@RequestBody SaleComplainInfoDto complain){
+        SaleComplainInfoPo saleComplainInfoPo = new SaleComplainInfoPo();
+        BeanUtils.copyProperties(complain, saleComplainInfoPo);
+        UserEntity user = tokenUtil.getUser();
+        String phone = user.getPhone();
+        String nickName = user.getNickName();
+
+        Map<String, Object> projectInfo = otherDataService.selectProjectInfo(complain.getBankCode());
+        if (projectInfo != null) {
+            saleComplainInfoPo.setProjectId(projectInfo.get("projectId") == null ? null : projectInfo.get("projectId").toString());
+            saleComplainInfoPo.setProjectName(projectInfo.get("projectName") == null ? null : projectInfo.get("projectName").toString());
+            saleComplainInfoPo.setSaleManagerId(projectInfo.get("saleManagerId") == null ? null : projectInfo.get("saleManagerId").toString());
+            saleComplainInfoPo.setSaleManagerName(projectInfo.get("saleManagerName") == null ? null : projectInfo.get("saleManagerName").toString());
+        }
+
+        saleComplainInfoPo.setCreatedBy(nickName);
+        saleComplainInfoPo.setPhone(phone);
+        saleComplainInfoPo.setSubmitter(nickName);
+        saleComplainInfoPo.setSubmitTime(LocalDateTime.now());
+
+        saleComplainInfoService.saveOrUpdate(saleComplainInfoPo);
+
+        return WrapMapper.ok("添加成功");
+    }
+
+    /**
+     * 状态变更
+     */
+    @PutMapping("/statusChange/{kid}")
+    public Wrapper<String> statusChange(@PathVariable("kid") String kid){
+        SaleComplainInfoPo complain = saleComplainInfoService.getById(kid);
+        complain.setStatus(2);
+
+        UpdateWrapper<SaleComplainInfoPo> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.lambda().eq(SaleComplainInfoPo::getKid, kid);
+        boolean result = saleComplainInfoService.update(complain, updateWrapper);
+
+        if (!result) {
+            return WrapMapper.error("撤回失败");
+        }
+
+        return WrapMapper.ok("撤回成功");
+    }
+
+}

+ 116 - 0
src/main/java/com/nh/farm/cloud/business/controller/SaleFeedbackController.java

@@ -0,0 +1,116 @@
+package com.nh.farm.cloud.business.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.nh.farm.cloud.basic.entity.UserEntity;
+import com.nh.farm.cloud.business.domain.dto.SaleFeedbackInfoDto;
+import com.nh.farm.cloud.business.domain.dto.SalePageQuery;
+import com.nh.farm.cloud.business.domain.po.SaleFeedbackDetailPo;
+import com.nh.farm.cloud.business.domain.po.SaleFeedbackInfoPo;
+import com.nh.farm.cloud.business.service.SaleFeedbackDetailService;
+import com.nh.farm.cloud.business.service.SaleFeedbackInfoService;
+import com.nh.farm.cloud.util.redis.TokenUtil;
+import com.nh.fk.common.util.wrapper.WrapMapper;
+import com.nh.fk.common.util.wrapper.Wrapper;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.*;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @description: 问题反馈
+ * @author: suyun
+ */
+@RestController
+@RequestMapping("feedback")
+public class SaleFeedbackController {
+
+    @Autowired
+    private TokenUtil tokenUtil;
+    
+    @Autowired
+    private SaleFeedbackInfoService saleFeedbackInfoService;
+
+    @Autowired
+    private SaleFeedbackDetailService saleFeedbackDetailService;
+
+    /**
+     * 汇总
+     */
+    @GetMapping("/collectInfo")
+    public Wrapper<Map<String, Object>> collectInfo(SalePageQuery pageQuery) {
+        Map<String, Object> map = saleFeedbackInfoService.collectInfo(pageQuery);
+        return WrapMapper.ok(map);
+    }
+
+    /**
+     * 按系统汇总
+     */
+    @GetMapping("/collectBySystem")
+    public Wrapper<List<Map<String, Object>>> collectBySystem(SalePageQuery pageQuery) {
+        List<Map<String, Object>> list = saleFeedbackInfoService.collectBySystem(pageQuery);
+        return WrapMapper.ok(list);
+    }
+
+    /**
+     * 分页
+     */
+    @GetMapping("/selectInfo")
+    public Wrapper<IPage<SaleFeedbackInfoPo>> selectInfo(SalePageQuery pageQuery) {
+        IPage page = saleFeedbackInfoService.queryPage(pageQuery);
+        return WrapMapper.ok(page);
+    }
+
+    /**
+     * 明细
+     */
+    @GetMapping("/getDetail")
+    public Wrapper<List<SaleFeedbackDetailPo>> getDetail(SalePageQuery pageQuery) {
+        List<SaleFeedbackDetailPo> list = saleFeedbackDetailService.getDetail(pageQuery);
+        return WrapMapper.ok(list);
+    }
+
+    /**
+     * 新增
+     */
+    @Transactional
+    @PostMapping("/saveInfo")
+    public Wrapper<JSONObject> saveInfo(@RequestBody SaleFeedbackInfoDto feedback){
+        SaleFeedbackInfoPo saleFeedbackInfoPo = new SaleFeedbackInfoPo();
+        BeanUtils.copyProperties(feedback, saleFeedbackInfoPo);
+        UserEntity user = tokenUtil.getUser();
+        String phone = user.getPhone();
+        String nickName = user.getNickName();
+        Integer status = feedback.getStatus();
+
+        saleFeedbackInfoPo.setCreatedBy(nickName);
+
+        JSONObject jsonObject = null;
+
+        if (status == 1) {
+            saleFeedbackInfoPo.setPhone(phone);
+            saleFeedbackInfoPo.setSubmitter(nickName);
+            saleFeedbackInfoPo.setSubmitTime(LocalDateTime.now());
+        }
+
+        saleFeedbackInfoService.saveOrUpdate(saleFeedbackInfoPo);
+
+        return WrapMapper.ok(jsonObject);
+    }
+
+    /**
+     * 删除
+     */
+    @DeleteMapping("/deleteInfo/{kid}")
+    public Wrapper<String> deleteInfo(@PathVariable("kid") String kid){
+        boolean b = saleFeedbackInfoService.removeById(kid);
+        if(b) return WrapMapper.ok("删除成功");
+
+        return WrapMapper.error("删除失败");
+    }
+
+}

+ 136 - 0
src/main/java/com/nh/farm/cloud/business/controller/SaleSatisfactionController.java

@@ -0,0 +1,136 @@
+package com.nh.farm.cloud.business.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.nh.farm.cloud.basic.entity.UserEntity;
+import com.nh.farm.cloud.business.domain.dto.SalePageQuery;
+import com.nh.farm.cloud.business.domain.dto.SaleSatisfactionBasicDto;
+import com.nh.farm.cloud.business.domain.po.SaleFeedbackInfoPo;
+import com.nh.farm.cloud.business.domain.po.SaleSatisfactionBasicPo;
+import com.nh.farm.cloud.business.domain.po.SaleSatisfactionDetailPo;
+import com.nh.farm.cloud.business.domain.po.SaleSatisfactionInfoPo;
+import com.nh.farm.cloud.business.service.OtherDataService;
+import com.nh.farm.cloud.business.service.SaleSatisfactionBasicService;
+import com.nh.farm.cloud.business.service.SaleSatisfactionDetailService;
+import com.nh.farm.cloud.business.service.SaleSatisfactionInfoService;
+import com.nh.farm.cloud.util.redis.TokenUtil;
+import com.nh.fk.common.util.wrapper.WrapMapper;
+import com.nh.fk.common.util.wrapper.Wrapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.*;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @description: 满意度调查
+ * @author: suyun
+ */
+@RestController
+@RequestMapping("satisfaction")
+public class SaleSatisfactionController {
+
+    @Autowired
+    private TokenUtil tokenUtil;
+
+    @Autowired
+    private OtherDataService otherDataService;
+
+    @Autowired
+    private SaleSatisfactionBasicService saleSatisfactionBasicService;
+
+    @Autowired
+    private SaleSatisfactionInfoService saleSatisfactionInfoService;
+
+    @Autowired
+    private SaleSatisfactionDetailService saleSatisfactionDetailService;
+
+    /**
+     * 获取 满意度调查配置 列表
+     */
+    @GetMapping("/selectBasicList")
+    public Wrapper<List<SaleSatisfactionBasicPo>> selectBasicList() {
+        List<SaleSatisfactionBasicPo> list = saleSatisfactionBasicService.selectBasicList();
+        return WrapMapper.ok(list);
+    }
+
+    /**
+     * 获取最新的 满意度调查配置
+     */
+    @GetMapping("/getLatestBasic")
+    public Wrapper<SaleSatisfactionBasicPo> queryStatistics() {
+        SaleSatisfactionBasicPo basic = saleSatisfactionBasicService.getLatestBasic();
+        return WrapMapper.ok(basic);
+    }
+
+    /**
+     * 满意度调查填写-分页
+     */
+    @GetMapping("/selectInfo")
+    public Wrapper<IPage<SaleFeedbackInfoPo>> selectInfo(SalePageQuery pageQuery) {
+        IPage page = saleSatisfactionInfoService.queryPage(pageQuery);
+        return WrapMapper.ok(page);
+    }
+
+    /**
+     * 满意度调查填写-明细
+     */
+    @GetMapping("/getInfoDetail")
+    public Wrapper<SaleSatisfactionBasicPo> getDetail(SalePageQuery pageQuery) {
+        SaleSatisfactionBasicPo basic = saleSatisfactionDetailService.getInfoDetail(pageQuery);
+        return WrapMapper.ok(basic);
+    }
+
+    /**
+     * 满意度调查填写-新增
+     */
+    @Transactional
+    @PostMapping("/saveInfo")
+    public Wrapper<String> saveInfo(@RequestBody SaleSatisfactionBasicDto satisfaction){
+        SaleSatisfactionInfoPo satisfactionInfoPo = new SaleSatisfactionInfoPo();
+        UserEntity user = tokenUtil.getUser();
+        String phone = user.getPhone();
+        String nickName = user.getNickName();
+
+        Map<String, Object> projectInfo = otherDataService.selectProjectInfo(satisfaction.getBankCode());
+        if (projectInfo != null) {
+            satisfactionInfoPo.setProjectId(projectInfo.get("projectId") == null ? null : projectInfo.get("projectId").toString());
+            satisfactionInfoPo.setProjectName(projectInfo.get("projectName") == null ? null : projectInfo.get("projectName").toString());
+            satisfactionInfoPo.setSaleManagerId(projectInfo.get("saleManagerId") == null ? null : projectInfo.get("saleManagerId").toString());
+            satisfactionInfoPo.setSaleManagerName(projectInfo.get("saleManagerName") == null ? null : projectInfo.get("saleManagerName").toString());
+        }
+
+        satisfactionInfoPo.setBankCode(satisfaction.getBankCode());
+        satisfactionInfoPo.setBankName(satisfaction.getBankName());
+        satisfactionInfoPo.setSatisfactionBasicId(satisfaction.getKid());
+        satisfactionInfoPo.setSatisfactionBasicName(satisfaction.getName());
+        satisfactionInfoPo.setScore(satisfaction.getScore());
+        satisfactionInfoPo.setResult(satisfaction.getResult());
+        satisfactionInfoPo.setRemark(satisfaction.getRemark());
+
+        satisfactionInfoPo.setCreatedBy(nickName);
+        satisfactionInfoPo.setPhone(phone);
+        satisfactionInfoPo.setSubmitter(nickName);
+        satisfactionInfoPo.setSubmitTime(LocalDateTime.now());
+
+        // 第一层级:满意度调查名称
+        saleSatisfactionInfoService.save(satisfactionInfoPo);
+
+        // 第二层级:调查内容
+        satisfaction.getDetail().forEach(entryTop -> {
+            // 第三层级:考评指标
+            entryTop.getDetail().forEach(entryPro -> {
+                SaleSatisfactionDetailPo satisfactionDetailPo = new SaleSatisfactionDetailPo();
+                satisfactionDetailPo.setSatisfactionInfoId(satisfactionInfoPo.getKid());
+                satisfactionDetailPo.setIndexId(entryPro.getKid());
+                satisfactionDetailPo.setIndexName(entryPro.getName());
+                satisfactionDetailPo.setScore(entryPro.getScore());
+                saleSatisfactionDetailService.save(satisfactionDetailPo);
+            });
+        });
+
+        return WrapMapper.ok("操作成功");
+    }
+
+}

+ 42 - 0
src/main/java/com/nh/farm/cloud/business/domain/dto/SaleCommendInfoDto.java

@@ -0,0 +1,42 @@
+package com.nh.farm.cloud.business.domain.dto;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * @description: 表扬信
+ * @author: suyun
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class SaleCommendInfoDto implements Serializable {
+
+    /**
+     * 机构号
+     */
+    private String bankCode;
+
+    /**
+     * 组织机构名称
+     */
+    private String bankName;
+
+    /**
+     * 表扬信内容
+     */
+    private String content;
+
+    /**
+     * 附件
+     */
+    private String files;
+
+}

+ 42 - 0
src/main/java/com/nh/farm/cloud/business/domain/dto/SaleComplainInfoDto.java

@@ -0,0 +1,42 @@
+package com.nh.farm.cloud.business.domain.dto;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * @description: 投诉建议
+ * @author: suyun
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class SaleComplainInfoDto implements Serializable {
+
+    /**
+     * 机构号
+     */
+    private String bankCode;
+
+    /**
+     * 组织机构名称
+     */
+    private String bankName;
+
+    /**
+     * 投诉内容
+     */
+    private String content;
+
+    /**
+     * 附件
+     */
+    private String files;
+
+}

+ 50 - 0
src/main/java/com/nh/farm/cloud/business/domain/dto/SaleFeedbackDetailDto.java

@@ -0,0 +1,50 @@
+package com.nh.farm.cloud.business.domain.dto;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * @description: 问题反馈明细
+ * @author: suyun
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class SaleFeedbackDetailDto implements Serializable {
+
+    private String kid;
+
+    /**
+     * 禅道BUG的ID
+     */
+    private String bugId;
+
+    /**
+     * 状态:1处理中,2质检中,3试运行,4已处理
+     */
+    private String status;
+
+    /**
+     * 进度
+     */
+    private String schedule;
+
+    /**
+     * 操作时间
+     */
+    private Date operateDate;
+
+    /**
+     * 操作描述
+     */
+    private String operateDesc;
+
+}

+ 56 - 0
src/main/java/com/nh/farm/cloud/business/domain/dto/SaleFeedbackInfoDto.java

@@ -0,0 +1,56 @@
+package com.nh.farm.cloud.business.domain.dto;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.poi.ss.formula.functions.T;
+
+import java.io.Serializable;
+
+/**
+ * @description: 问题反馈基础信息
+ * @author: suyun
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class SaleFeedbackInfoDto extends Page<T> implements Serializable {
+
+    private String kid;
+
+    /**
+     * 机构号
+     */
+    private String bankCode;
+
+    /**
+     * 组织机构名称
+     */
+    private String bankName;
+
+    /**
+     * 系统名称
+     */
+    private String systemName;
+
+    /**
+     * 问题描述
+     */
+    private String problemDescription;
+
+    /**
+     * 附件
+     */
+    private String files;
+
+    /**
+     * 状态:0未提交,1处理中,2质检中,3试运行,4已处理
+     */
+    private Integer status;
+
+}

+ 63 - 0
src/main/java/com/nh/farm/cloud/business/domain/dto/SalePageQuery.java

@@ -0,0 +1,63 @@
+package com.nh.farm.cloud.business.domain.dto;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.Data;
+
+/**
+ * @description: 通用查询条件
+ * @author: suyun
+ */
+@Data
+public class SalePageQuery<T> extends Page<T> {
+
+    private String kid;
+
+    /**
+     * 机构号
+     */
+    private String bankCode;
+
+    /**
+     * 开始日期
+     */
+    private String beginDate;
+
+    /**
+     * 结束日期
+     */
+    private String endDate;
+
+    /**
+     * 状态
+     */
+    private String status;
+
+    /**
+     * 系统名称
+     */
+    private String systemName;
+
+    /**
+     * 禅道BUG的ID
+     */
+    private String bugId;
+
+    /**
+     * 满意度调查配置ID(ERP配置)
+     */
+    private String satisfactionBasicId;
+
+    private Integer page = 1;
+    private Integer limit = 20;
+
+    public void setPage(Integer page) {
+        this.page = page;
+        this.current = page;
+    }
+
+    public void setLimit(Integer limit) {
+        this.limit = limit;
+        this.size = limit;
+    }
+
+}

+ 111 - 0
src/main/java/com/nh/farm/cloud/business/domain/dto/SaleSatisfactionBasicDto.java

@@ -0,0 +1,111 @@
+package com.nh.farm.cloud.business.domain.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * @description: 满意度调查配置
+ * @author: suyun
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class SaleSatisfactionBasicDto implements Serializable {
+
+    private String kid;
+
+    /**
+     * 机构号
+     */
+    private String bankCode;
+
+    /**
+     * 组织机构名称
+     */
+    private String bankName;
+
+    /**
+     * 上层节点ID
+     */
+    private String topId;
+
+    /**
+     * 满意度调查名称/调查内容/考评指标
+     */
+    private String name;
+
+    /**
+     * 层级:0-满意度调查名称;1-调查内容;2-考评指标
+     */
+    private Integer satisfactionLevel;
+
+    /**
+     * 满意区间
+     */
+    private Integer upperVal1;
+
+    /**
+     * 满意区间
+     */
+    private Integer upperVal2;
+
+    /**
+     * 一般区间
+     */
+    private Integer middleVal1;
+
+    /**
+     * 一般区间
+     */
+    private Integer middleVal2;
+
+    /**
+     * 不满意区间
+     */
+    private Integer lowerVal1;
+
+    /**
+     * 不满意区间
+     */
+    private Integer lowerVal2;
+
+    /**
+     * 总值
+     */
+    private Integer totalVal;
+
+    /**
+     * 结果
+     */
+    private String result;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    /**
+     * 排序
+     */
+    private Integer sort;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createdTime = LocalDateTime.now();
+
+    /**
+     * 得分
+     */
+    private Integer score;
+
+    List<SaleSatisfactionBasicDto> detail;
+
+}

+ 45 - 0
src/main/java/com/nh/farm/cloud/business/domain/dto/SaleSatisfactionDetailDto.java

@@ -0,0 +1,45 @@
+package com.nh.farm.cloud.business.domain.dto;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * @description: 满意度调查填写-明细
+ * @author: suyun
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class SaleSatisfactionDetailDto implements Serializable {
+
+    private String kid;
+
+    /**
+     * 满意度调查信息表ID
+     */
+    private String satisfactionInfoId;
+
+    /**
+     * 指标编号
+     */
+    private String indexId;
+
+    /**
+     * 指标名称
+     */
+    private String indexName;
+
+    /**
+     * 得分
+     */
+    private String score;
+
+
+}

+ 52 - 0
src/main/java/com/nh/farm/cloud/business/domain/dto/SaleSatisfactionInfoDto.java

@@ -0,0 +1,52 @@
+package com.nh.farm.cloud.business.domain.dto;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @description: 满意度调查填写-基本信息
+ * @author: suyun
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class SaleSatisfactionInfoDto implements Serializable {
+
+    private String kid;
+
+    /**
+     * 机构号
+     */
+    private String bankCode;
+
+    /**
+     * 组织机构名称
+     */
+    private String bankName;
+
+    /**
+     * 满意度调查配置ID
+     */
+    private String satisfactionBasicId;
+
+    /**
+     * 满意度调查配置名称
+     */
+    private String satisfactionBasicName;
+
+    /**
+     * 调查结果
+     */
+    private String result;
+
+    private List<SaleSatisfactionDetailDto> detail;
+
+}

+ 108 - 0
src/main/java/com/nh/farm/cloud/business/domain/po/SaleCommendInfoPo.java

@@ -0,0 +1,108 @@
+package com.nh.farm.cloud.business.domain.po;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * @description: 表扬信
+ * @author: suyun
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@TableName(value = "SALE_COMMEND_INFO")
+public class SaleCommendInfoPo implements Serializable {
+
+    @TableId(value = "KID", type = IdType.ASSIGN_UUID)
+    private String kid;
+
+    /**
+     * 机构号
+     */
+    @TableField(value = "BANK_CODE")
+    private String bankCode;
+
+    /**
+     * 组织机构名称
+     */
+    @TableField(value = "BANK_NAME")
+    private String bankName;
+
+    /**
+     * 项目ID
+     */
+    @TableField(value = "PROJECT_ID")
+    private String projectId;
+
+    /**
+     * 项目名称
+     */
+    @TableField(value = "PROJECT_NAME")
+    private String projectName;
+
+    /**
+     * 销售经理
+     */
+    @TableField(value = "SALE_MANAGER_ID")
+    private String saleManagerId;
+
+    /**
+     * 销售经理
+     */
+    @TableField(value = "SALE_MANAGER_NAME")
+    private String saleManagerName;
+
+    /**
+     * 表扬信内容
+     */
+    @TableField(value = "CONTENT")
+    private String content;
+
+    /**
+     * 附件
+     */
+    @TableField(value = "FILES")
+    private String files;
+
+    /**
+     * 联系电话
+     */
+    @TableField(value = "PHONE")
+    private String phone;
+
+    /**
+     * 提交人
+     */
+    @TableField(value = "SUBMITTER")
+    private String submitter;
+
+    /**
+     * 提交时间
+     */
+    @TableField(value = "SUBMIT_TIME")
+    private LocalDateTime submitTime;
+
+    /**
+     * 创建人
+     */
+    @TableField(value = "CREATED_BY")
+    private String createdBy;
+
+    /**
+     * 创建时间
+     */
+    @TableField(value = "CREATED_TIME")
+    private LocalDateTime createdTime = LocalDateTime.now();
+
+
+}

+ 137 - 0
src/main/java/com/nh/farm/cloud/business/domain/po/SaleComplainInfoPo.java

@@ -0,0 +1,137 @@
+package com.nh.farm.cloud.business.domain.po;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * @description: 投诉建议
+ * @author: suyun
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@TableName(value = "SALE_COMPLAIN_INFO")
+public class SaleComplainInfoPo implements Serializable {
+
+    @TableId(value = "KID", type = IdType.ASSIGN_UUID)
+    private String kid;
+
+    /**
+     * 机构号
+     */
+    @TableField(value = "BANK_CODE")
+    private String bankCode;
+
+    /**
+     * 组织机构名称
+     */
+    @TableField(value = "BANK_NAME")
+    private String bankName;
+
+    /**
+     * 项目ID
+     */
+    @TableField(value = "PROJECT_ID")
+    private String projectId;
+
+    /**
+     * 项目名称
+     */
+    @TableField(value = "PROJECT_NAME")
+    private String projectName;
+
+    /**
+     * 销售经理
+     */
+    @TableField(value = "SALE_MANAGER_ID")
+    private String saleManagerId;
+
+    /**
+     * 销售经理
+     */
+    @TableField(value = "SALE_MANAGER_NAME")
+    private String saleManagerName;
+
+    /**
+     * 投诉内容
+     */
+    @TableField(value = "CONTENT")
+    private String content;
+
+    /**
+     * 状态:未处理、已处理、已撤销
+     */
+    @TableField(value = "STATUS")
+    private Integer status = 0;
+
+    /**
+     * 处理结果
+     */
+    @TableField(value = "RESULT")
+    private String result;
+
+    /**
+     * 处理人
+     */
+    @TableField(value = "HANDLE_USER_ID")
+    private String handleUserId;
+
+    /**
+     * 处理人
+     */
+    @TableField(value = "HANDLE_USER_NAME")
+    private String handleUserName;
+
+    /**
+     * 处理时间
+     */
+    @TableField(value = "HANDLE_TIME")
+    private LocalDateTime handleTime;
+
+    /**
+     * 附件
+     */
+    @TableField(value = "FILES")
+    private String files;
+
+    /**
+     * 联系电话
+     */
+    @TableField(value = "PHONE")
+    private String phone;
+
+    /**
+     * 提交人
+     */
+    @TableField(value = "SUBMITTER")
+    private String submitter;
+
+    /**
+     * 提交时间
+     */
+    @TableField(value = "SUBMIT_TIME")
+    private LocalDateTime submitTime;
+
+    /**
+     * 创建人
+     */
+    @TableField(value = "CREATED_BY")
+    private String createdBy;
+
+    /**
+     * 创建时间
+     */
+    @TableField(value = "CREATED_TIME")
+    private LocalDateTime createdTime = LocalDateTime.now();
+
+}

+ 60 - 0
src/main/java/com/nh/farm/cloud/business/domain/po/SaleFeedbackDetailPo.java

@@ -0,0 +1,60 @@
+package com.nh.farm.cloud.business.domain.po;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * @description: 问题反馈明细
+ * @author: suyun
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@TableName(value = "SALE_FEEDBACK_DETAIL")
+public class SaleFeedbackDetailPo implements Serializable {
+
+    @TableId(value = "KID", type = IdType.INPUT)
+    private Integer kid;
+
+    /**
+     * 禅道BUG的ID
+     */
+    @TableField(value = "BUG_ID")
+    private String bugId;
+
+    /**
+     * 状态:1处理中,2质检中,3试运行,4已处理
+     */
+    @TableField(value = "STATUS")
+    private Integer status;
+
+    /**
+     * 进度
+     */
+    @TableField(value = "SCHEDULE")
+    private Integer schedule;
+
+    /**
+     * 操作时间
+     */
+    @TableField(value = "OPERATE_DATE")
+    private Date operateDate;
+
+    /**
+     * 操作描述
+     */
+    @TableField(value = "OPERATE_DESC")
+    private String operateDesc;
+
+
+}

+ 107 - 0
src/main/java/com/nh/farm/cloud/business/domain/po/SaleFeedbackInfoPo.java

@@ -0,0 +1,107 @@
+package com.nh.farm.cloud.business.domain.po;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * @description: 问题反馈基础信息
+ * @author: suyun
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@TableName(value = "SALE_FEEDBACK_INFO")
+public class SaleFeedbackInfoPo implements Serializable {
+
+    @TableId(value = "KID", type = IdType.ASSIGN_UUID)
+    private String kid;
+
+    /**
+     * 禅道BUG的ID
+     */
+    @TableField(value = "BUG_ID")
+    private String bugId;
+
+    /**
+     * 机构号
+     */
+    @TableField(value = "BANK_CODE")
+    private String bankCode;
+
+    /**
+     * 组织机构名称
+     */
+    @TableField(value = "BANK_NAME")
+    private String bankName;
+
+    /**
+     * 系统名称
+     */
+    @TableField(value = "SYSTEM_NAME")
+    private String systemName;
+
+    /**
+     * 问题描述
+     */
+    @TableField(value = "PROBLEM_DESCRIPTION")
+    private String problemDescription;
+
+    /**
+     * 进度
+     */
+    @TableField(value = "SCHEDULE")
+    private Integer schedule;
+
+    /**
+     * 附件
+     */
+    @TableField(value = "FILES")
+    private String files;
+
+    /**
+     * 状态:0未提交,1处理中,2质检中,3试运行,4已处理
+     */
+    @TableField(value = "STATUS")
+    private Integer status;
+
+    /**
+     * 联系电话
+     */
+    @TableField(value = "PHONE")
+    private String phone;
+
+    /**
+     * 提交人
+     */
+    @TableField(value = "SUBMITTER")
+    private String submitter;
+
+    /**
+     * 提交时间
+     */
+    @TableField(value = "SUBMIT_TIME")
+    private LocalDateTime submitTime;
+
+    /**
+     * 创建人
+     */
+    @TableField(value = "CREATED_BY")
+    private String createdBy;
+
+    /**
+     * 创建时间
+     */
+    @TableField(value = "CREATED_TIME")
+    private LocalDateTime createdTime = LocalDateTime.now();
+
+}

+ 122 - 0
src/main/java/com/nh/farm/cloud/business/domain/po/SaleSatisfactionBasicPo.java

@@ -0,0 +1,122 @@
+package com.nh.farm.cloud.business.domain.po;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * @description: 满意度调查配置
+ * @author: suyun
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@TableName(value = "VW_ERP_SATISFACTION_BASIC")
+public class SaleSatisfactionBasicPo implements Serializable {
+
+    @TableId
+    private String kid;
+
+    /**
+     * 上层节点ID
+     */
+    @TableField(value = "TOP_ID")
+    private String topId;
+
+    /**
+     * 满意度调查名称/调查内容/考评指标
+     */
+    @TableField(value = "NAME")
+    private String name;
+
+    /**
+     * 层级:0-满意度调查名称;1-调查内容;2-考评指标
+     */
+    @TableField(value = "SATISFACTION_LEVEL")
+    private Integer satisfactionLevel;
+
+    /**
+     * 满意区间
+     */
+    @TableField(value = "UPPER_VAL1")
+    private Integer upperVal1;
+
+    /**
+     * 满意区间
+     */
+    @TableField(value = "UPPER_VAL2")
+    private Integer upperVal2;
+
+    /**
+     * 一般区间
+     */
+    @TableField(value = "MIDDLE_VAL1")
+    private Integer middleVal1;
+
+    /**
+     * 一般区间
+     */
+    @TableField(value = "MIDDLE_VAL2")
+    private Integer middleVal2;
+
+    /**
+     * 不满意区间
+     */
+    @TableField(value = "LOWER_VAL1")
+    private Integer lowerVal1;
+
+    /**
+     * 不满意区间
+     */
+    @TableField(value = "LOWER_VAL2")
+    private Integer lowerVal2;
+
+    /**
+     * 总值
+     */
+    @TableField(value = "TOTAL_VAL")
+    private Integer totalVal;
+
+    /**
+     * 备注
+     */
+    @TableField(value = "REMARK")
+    private String remark;
+
+    /**
+     * 排序
+     */
+    @TableField(value = "SORT")
+    private Integer sort;
+
+    /**
+     * 创建时间
+     */
+    @TableField(value = "CREATED_TIME")
+    private LocalDateTime createdTime = LocalDateTime.now();
+
+    /**
+     * 得分
+     */
+    @TableField(exist = false)
+    private Integer score;
+
+    /**
+     * 结果
+     */
+    @TableField(exist = false)
+    private String result;
+
+    @TableField(exist = false)
+    List<SaleSatisfactionBasicPo> detail;
+
+}

+ 53 - 0
src/main/java/com/nh/farm/cloud/business/domain/po/SaleSatisfactionDetailPo.java

@@ -0,0 +1,53 @@
+package com.nh.farm.cloud.business.domain.po;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * @description: 满意度调查填写-明细
+ * @author: suyun
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@TableName(value = "SALE_SATISFACTION_DETAIL")
+public class SaleSatisfactionDetailPo implements Serializable {
+
+    @TableId(value = "KID", type = IdType.ASSIGN_UUID)
+    private String kid;
+
+    /**
+     * 满意度调查信息表ID
+     */
+    @TableField(value = "SATISFACTION_INFO_ID")
+    private String satisfactionInfoId;
+
+    /**
+     * 指标编号
+     */
+    @TableField(value = "INDEX_ID")
+    private String indexId;
+
+    /**
+     * 指标名称
+     */
+    @TableField(value = "INDEX_NAME")
+    private String indexName;
+
+    /**
+     * 得分
+     */
+    @TableField(value = "SCORE")
+    private Integer score;
+
+
+}

+ 125 - 0
src/main/java/com/nh/farm/cloud/business/domain/po/SaleSatisfactionInfoPo.java

@@ -0,0 +1,125 @@
+package com.nh.farm.cloud.business.domain.po;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * @description: 满意度调查填写-基本信息
+ * @author: suyun
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@TableName(value = "SALE_SATISFACTION_INFO")
+public class SaleSatisfactionInfoPo implements Serializable {
+
+    @TableId(value = "KID", type = IdType.ASSIGN_UUID)
+    private String kid;
+
+    /**
+     * 机构号
+     */
+    @TableField(value = "BANK_CODE")
+    private String bankCode;
+
+    /**
+     * 组织机构名称
+     */
+    @TableField(value = "BANK_NAME")
+    private String bankName;
+
+    /**
+     * 项目ID
+     */
+    @TableField(value = "PROJECT_ID")
+    private String projectId;
+
+    /**
+     * 项目名称
+     */
+    @TableField(value = "PROJECT_NAME")
+    private String projectName;
+
+    /**
+     * 销售经理
+     */
+    @TableField(value = "SALE_MANAGER_ID")
+    private String saleManagerId;
+
+    /**
+     * 销售经理
+     */
+    @TableField(value = "SALE_MANAGER_NAME")
+    private String saleManagerName;
+
+    /**
+     * 满意度调查配置ID
+     */
+    @TableField(value = "SATISFACTION_BASIC_ID")
+    private String satisfactionBasicId;
+
+    /**
+     * 满意度调查配置名称
+     */
+    @TableField(value = "SATISFACTION_BASIC_NAME")
+    private String satisfactionBasicName;
+
+    /**
+     * 总值
+     */
+    @TableField(value = "score")
+    private Integer score;
+
+    /**
+     * 结果
+     */
+    @TableField(value = "RESULT")
+    private String result;
+
+    /**
+     * 备注
+     */
+    @TableField(value = "REMARK")
+    private String remark;
+
+    /**
+     * 联系电话
+     */
+    @TableField(value = "PHONE")
+    private String phone;
+
+    /**
+     * 提交人
+     */
+    @TableField(value = "SUBMITTER")
+    private String submitter;
+
+    /**
+     * 提交时间
+     */
+    @TableField(value = "SUBMIT_TIME")
+    private LocalDateTime submitTime;
+
+    /**
+     * 创建人
+     */
+    @TableField(value = "CREATED_BY")
+    private String createdBy;
+
+    /**
+     * 创建时间
+     */
+    @TableField(value = "CREATED_TIME")
+    private LocalDateTime createdTime = LocalDateTime.now();
+
+}

+ 19 - 0
src/main/java/com/nh/farm/cloud/business/mapper/OtherDataMapper.java

@@ -0,0 +1,19 @@
+package com.nh.farm.cloud.business.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.nh.farm.cloud.business.domain.po.SaleCommendInfoPo;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.Map;
+
+/**
+ * @author: suyun
+ */
+@Mapper
+public interface OtherDataMapper extends BaseMapper<SaleCommendInfoPo> {
+
+    @Select("SELECT * FROM erp_project_info@ERP WHERE bank_code = substr(#{bankCode}, 1, 9)")
+    Map<String, Object> selectProjectInfo(String bankCode);
+
+}

+ 24 - 0
src/main/java/com/nh/farm/cloud/business/mapper/SaleCommendInfoMapper.java

@@ -0,0 +1,24 @@
+package com.nh.farm.cloud.business.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.nh.farm.cloud.business.domain.dto.SalePageQuery;
+import org.apache.ibatis.annotations.Mapper;
+
+import com.nh.farm.cloud.business.domain.po.SaleCommendInfoPo;
+
+import java.util.Map;
+
+/**
+ * @description: 表扬信
+ * @author: suyun
+ */
+@Mapper
+public interface SaleCommendInfoMapper extends BaseMapper<SaleCommendInfoPo> {
+
+    Map<String, Object> collectInfo(SalePageQuery pageQuery);
+
+    IPage<Map<String,Object>> queryPage(SalePageQuery pageQuery);
+
+}

+ 24 - 0
src/main/java/com/nh/farm/cloud/business/mapper/SaleComplainInfoMapper.java

@@ -0,0 +1,24 @@
+package com.nh.farm.cloud.business.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.nh.farm.cloud.business.domain.dto.SalePageQuery;
+import org.apache.ibatis.annotations.Mapper;
+
+import com.nh.farm.cloud.business.domain.po.SaleComplainInfoPo;
+
+import java.util.Map;
+
+/**
+ * @description: 投诉建议
+ * @author: suyun
+ */
+@Mapper
+public interface SaleComplainInfoMapper extends BaseMapper<SaleComplainInfoPo> {
+
+    Map<String, Object> collectInfo(SalePageQuery pageQuery);
+
+    IPage<Map<String,Object>> queryPage(SalePageQuery pageQuery);
+
+}

+ 16 - 0
src/main/java/com/nh/farm/cloud/business/mapper/SaleFeedbackDetailMapper.java

@@ -0,0 +1,16 @@
+package com.nh.farm.cloud.business.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+import org.apache.ibatis.annotations.Mapper;
+
+import com.nh.farm.cloud.business.domain.po.SaleFeedbackDetailPo;
+
+/**
+ * @description: 问题反馈明细
+ * @author: suyun
+ */
+@Mapper
+public interface SaleFeedbackDetailMapper extends BaseMapper<SaleFeedbackDetailPo> {
+
+}

+ 25 - 0
src/main/java/com/nh/farm/cloud/business/mapper/SaleFeedbackInfoMapper.java

@@ -0,0 +1,25 @@
+package com.nh.farm.cloud.business.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.nh.farm.cloud.business.domain.dto.SalePageQuery;
+import com.nh.farm.cloud.business.domain.po.SaleFeedbackInfoPo;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @description: 问题反馈基础信息
+ * @author: suyun
+ */
+@Mapper
+public interface SaleFeedbackInfoMapper extends BaseMapper<SaleFeedbackInfoPo> {
+
+    Map<String, Object> collectInfo(SalePageQuery pageQuery);
+
+    List<Map<String, Object>> collectBySystem(SalePageQuery pageQuery);
+
+    IPage<Map<String, Object>> queryPage(SalePageQuery pageQuery);
+
+}

+ 14 - 0
src/main/java/com/nh/farm/cloud/business/mapper/SaleSatisfactionBasicMapper.java

@@ -0,0 +1,14 @@
+package com.nh.farm.cloud.business.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.nh.farm.cloud.business.domain.po.SaleSatisfactionBasicPo;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * @description: 满意度调查配置
+ * @author: suyun
+ */
+@Mapper
+public interface SaleSatisfactionBasicMapper extends BaseMapper<SaleSatisfactionBasicPo> {
+
+}

+ 24 - 0
src/main/java/com/nh/farm/cloud/business/mapper/SaleSatisfactionDetailMapper.java

@@ -0,0 +1,24 @@
+package com.nh.farm.cloud.business.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+import com.nh.farm.cloud.business.domain.po.SaleSatisfactionBasicPo;
+import org.apache.ibatis.annotations.Mapper;
+
+import com.nh.farm.cloud.business.domain.po.SaleSatisfactionDetailPo;
+
+import java.util.List;
+
+/**
+ * @description: 满意度调查填写-明细
+ * @author: suyun
+ */
+@Mapper
+public interface SaleSatisfactionDetailMapper extends BaseMapper<SaleSatisfactionDetailPo> {
+
+    /**
+     * 满意度调查-考评指标-打分明细
+     */
+    List<SaleSatisfactionBasicPo> getDetail(String satisfactionInfoId, String topId);
+
+}

+ 18 - 0
src/main/java/com/nh/farm/cloud/business/mapper/SaleSatisfactionInfoMapper.java

@@ -0,0 +1,18 @@
+package com.nh.farm.cloud.business.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.nh.farm.cloud.business.domain.dto.SalePageQuery;
+import com.nh.farm.cloud.business.domain.po.SaleSatisfactionInfoPo;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * @description: 满意度调查填写-基本信息
+ * @author: suyun
+ */
+@Mapper
+public interface SaleSatisfactionInfoMapper extends BaseMapper<SaleSatisfactionInfoPo> {
+
+    IPage queryPage(SalePageQuery pageQuery);
+
+}

+ 13 - 0
src/main/java/com/nh/farm/cloud/business/service/OtherDataService.java

@@ -0,0 +1,13 @@
+package com.nh.farm.cloud.business.service;
+
+import java.util.Map;
+
+/**
+ * @author: suyun
+ */
+
+public interface OtherDataService {
+
+    Map<String, Object> selectProjectInfo(String bankCode);
+
+}

+ 27 - 0
src/main/java/com/nh/farm/cloud/business/service/SaleCommendInfoService.java

@@ -0,0 +1,27 @@
+package com.nh.farm.cloud.business.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import com.nh.farm.cloud.business.domain.dto.SalePageQuery;
+import com.nh.farm.cloud.business.domain.po.SaleCommendInfoPo;
+
+import java.util.Map;
+
+/**
+ * @description: 表扬信
+ * @author: suyun
+ */
+public interface SaleCommendInfoService extends IService<SaleCommendInfoPo> {
+
+    /**
+     * 汇总
+     */
+    Map<String, Object> collectInfo(SalePageQuery pageQuery);
+
+    /**
+     * 分页
+     */
+    IPage queryPage(SalePageQuery pageQuery);
+
+}

+ 27 - 0
src/main/java/com/nh/farm/cloud/business/service/SaleComplainInfoService.java

@@ -0,0 +1,27 @@
+package com.nh.farm.cloud.business.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import com.nh.farm.cloud.business.domain.dto.SalePageQuery;
+import com.nh.farm.cloud.business.domain.po.SaleComplainInfoPo;
+
+import java.util.Map;
+
+/**
+ * @description: 投诉建议
+ * @author: suyun
+ */
+public interface SaleComplainInfoService extends IService<SaleComplainInfoPo> {
+
+    /**
+     * 汇总
+     */
+    Map<String, Object> collectInfo(SalePageQuery pageQuery);
+
+    /**
+     * 分页
+     */
+    IPage queryPage(SalePageQuery pageQuery);
+
+}

+ 18 - 0
src/main/java/com/nh/farm/cloud/business/service/SaleFeedbackDetailService.java

@@ -0,0 +1,18 @@
+package com.nh.farm.cloud.business.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import com.nh.farm.cloud.business.domain.dto.SalePageQuery;
+import com.nh.farm.cloud.business.domain.po.SaleFeedbackDetailPo;
+
+import java.util.List;
+
+/**
+ * @description: 问题反馈明细
+ * @author: suyun
+ */
+public interface SaleFeedbackDetailService extends IService<SaleFeedbackDetailPo> {
+
+    List<SaleFeedbackDetailPo> getDetail(SalePageQuery pageQuery);
+
+}

+ 32 - 0
src/main/java/com/nh/farm/cloud/business/service/SaleFeedbackInfoService.java

@@ -0,0 +1,32 @@
+package com.nh.farm.cloud.business.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.nh.farm.cloud.business.domain.dto.SalePageQuery;
+import com.nh.farm.cloud.business.domain.po.SaleFeedbackInfoPo;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @description: 问题反馈基础信息
+ * @author: suyun
+ */
+public interface SaleFeedbackInfoService extends IService<SaleFeedbackInfoPo> {
+
+    /**
+     * 汇总
+     */
+    Map<String, Object> collectInfo(SalePageQuery pageQuery);
+
+    /**
+     * 按系统汇总
+     */
+    List<Map<String, Object>> collectBySystem(SalePageQuery pageQuery);
+
+    /**
+     * 分页
+     */
+    IPage queryPage(SalePageQuery pageQuery);
+
+}

+ 24 - 0
src/main/java/com/nh/farm/cloud/business/service/SaleSatisfactionBasicService.java

@@ -0,0 +1,24 @@
+package com.nh.farm.cloud.business.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.nh.farm.cloud.business.domain.po.SaleSatisfactionBasicPo;
+
+import java.util.List;
+
+/**
+ * @description: 满意度调查配置
+ * @author: suyun
+ */
+public interface SaleSatisfactionBasicService extends IService<SaleSatisfactionBasicPo> {
+
+    /**
+     * 获取 满意度调查配置 列表
+     */
+    List<SaleSatisfactionBasicPo> selectBasicList();
+
+    /**
+     * 获取最新的 满意度调查配置
+     */
+    SaleSatisfactionBasicPo getLatestBasic();
+
+}

+ 20 - 0
src/main/java/com/nh/farm/cloud/business/service/SaleSatisfactionDetailService.java

@@ -0,0 +1,20 @@
+package com.nh.farm.cloud.business.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import com.nh.farm.cloud.business.domain.dto.SalePageQuery;
+import com.nh.farm.cloud.business.domain.po.SaleSatisfactionBasicPo;
+import com.nh.farm.cloud.business.domain.po.SaleSatisfactionDetailPo;
+
+/**
+ * @description: 满意度调查填写-明细
+ * @author: suyun
+ */
+public interface SaleSatisfactionDetailService extends IService<SaleSatisfactionDetailPo> {
+
+    /**
+     * 满意度调查填写-明细
+     */
+    SaleSatisfactionBasicPo getInfoDetail(SalePageQuery pageQuery);
+
+}

+ 19 - 0
src/main/java/com/nh/farm/cloud/business/service/SaleSatisfactionInfoService.java

@@ -0,0 +1,19 @@
+package com.nh.farm.cloud.business.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.nh.farm.cloud.business.domain.dto.SalePageQuery;
+import com.nh.farm.cloud.business.domain.po.SaleSatisfactionInfoPo;
+
+/**
+ * @description: 满意度调查填写-基本信息
+ * @author: suyun
+ */
+public interface SaleSatisfactionInfoService extends IService<SaleSatisfactionInfoPo> {
+
+    /**
+     * 分页
+     */
+    IPage queryPage(SalePageQuery pageQuery);
+
+}

+ 26 - 0
src/main/java/com/nh/farm/cloud/business/service/impl/OtherDataServiceImpl.java

@@ -0,0 +1,26 @@
+package com.nh.farm.cloud.business.service.impl;
+
+import com.nh.farm.cloud.business.mapper.OtherDataMapper;
+import com.nh.farm.cloud.business.service.OtherDataService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+
+/**
+ * @author: suyun
+ */
+@Slf4j
+@Service
+public class OtherDataServiceImpl implements OtherDataService {
+
+    @Autowired
+    private OtherDataMapper otherDataMapper;
+
+    @Override
+    public Map<String, Object> selectProjectInfo(String bankCode) {
+        return otherDataMapper.selectProjectInfo(bankCode);
+    }
+
+}

+ 34 - 0
src/main/java/com/nh/farm/cloud/business/service/impl/SaleCommendInfoServiceImpl.java

@@ -0,0 +1,34 @@
+package com.nh.farm.cloud.business.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.nh.farm.cloud.business.domain.dto.SalePageQuery;
+import com.nh.farm.cloud.business.domain.po.SaleCommendInfoPo;
+import com.nh.farm.cloud.business.mapper.SaleCommendInfoMapper;
+import com.nh.farm.cloud.business.service.SaleCommendInfoService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+
+/**
+ * @description: 表扬信
+ * @author: suyun
+ */
+@Slf4j
+@Service
+public class SaleCommendInfoServiceImpl extends ServiceImpl<SaleCommendInfoMapper, SaleCommendInfoPo> implements SaleCommendInfoService {
+
+    @Override
+    public Map<String, Object> collectInfo(SalePageQuery pageQuery) {
+        Map<String, Object> map = this.baseMapper.collectInfo(pageQuery);
+        return map;
+    }
+
+    @Override
+    public IPage queryPage(SalePageQuery pageQuery) {
+        IPage page = this.baseMapper.queryPage(pageQuery);
+        return page;
+    }
+
+}

+ 34 - 0
src/main/java/com/nh/farm/cloud/business/service/impl/SaleComplainInfoServiceImpl.java

@@ -0,0 +1,34 @@
+package com.nh.farm.cloud.business.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.nh.farm.cloud.business.domain.dto.SalePageQuery;
+import com.nh.farm.cloud.business.domain.po.SaleComplainInfoPo;
+import com.nh.farm.cloud.business.mapper.SaleComplainInfoMapper;
+import com.nh.farm.cloud.business.service.SaleComplainInfoService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+
+/**
+ * @description: 投诉建议
+ * @author: suyun
+ */
+@Slf4j
+@Service
+public class SaleComplainInfoServiceImpl extends ServiceImpl<SaleComplainInfoMapper, SaleComplainInfoPo> implements SaleComplainInfoService {
+
+    @Override
+    public Map<String, Object> collectInfo(SalePageQuery pageQuery) {
+        Map<String, Object> map = this.baseMapper.collectInfo(pageQuery);
+        return map;
+    }
+
+    @Override
+    public IPage queryPage(SalePageQuery pageQuery) {
+        IPage page = this.baseMapper.queryPage(pageQuery);
+        return page;
+    }
+
+}

+ 35 - 0
src/main/java/com/nh/farm/cloud/business/service/impl/SaleFeedbackDetailServiceImpl.java

@@ -0,0 +1,35 @@
+package com.nh.farm.cloud.business.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.nh.farm.cloud.business.domain.dto.SalePageQuery;
+import com.nh.farm.cloud.business.domain.po.SaleFeedbackDetailPo;
+import com.nh.farm.cloud.business.mapper.SaleFeedbackDetailMapper;
+import com.nh.farm.cloud.business.service.SaleFeedbackDetailService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @description: 问题反馈明细
+ * @author: suyun
+ */
+@Slf4j
+@Service
+public class SaleFeedbackDetailServiceImpl extends ServiceImpl<SaleFeedbackDetailMapper, SaleFeedbackDetailPo> implements SaleFeedbackDetailService {
+
+    @Override
+    public List<SaleFeedbackDetailPo> getDetail(SalePageQuery pageQuery) {
+        String bugId = pageQuery.getBugId();
+
+        QueryWrapper<SaleFeedbackDetailPo> wrapper = new QueryWrapper<>();
+        wrapper.lambda().eq(SaleFeedbackDetailPo::getBugId, bugId);
+        wrapper.lambda().in(SaleFeedbackDetailPo::getStatus, 1, 2, 3, 4);
+        wrapper.lambda().orderByAsc(SaleFeedbackDetailPo::getStatus);
+
+        List<SaleFeedbackDetailPo> list = this.baseMapper.selectList(wrapper);
+        return list;
+    }
+
+}

+ 41 - 0
src/main/java/com/nh/farm/cloud/business/service/impl/SaleFeedbackInfoServiceImpl.java

@@ -0,0 +1,41 @@
+package com.nh.farm.cloud.business.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.nh.farm.cloud.business.domain.dto.SalePageQuery;
+import com.nh.farm.cloud.business.domain.po.SaleFeedbackInfoPo;
+import com.nh.farm.cloud.business.mapper.SaleFeedbackInfoMapper;
+import com.nh.farm.cloud.business.service.SaleFeedbackInfoService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @description: 问题反馈基础信息
+ * @author: suyun
+ */
+@Slf4j
+@Service
+public class SaleFeedbackInfoServiceImpl extends ServiceImpl<SaleFeedbackInfoMapper, SaleFeedbackInfoPo> implements SaleFeedbackInfoService {
+
+    @Override
+    public Map<String, Object> collectInfo(SalePageQuery pageQuery) {
+        Map<String, Object> map = this.baseMapper.collectInfo(pageQuery);
+        return map;
+    }
+
+    @Override
+    public List<Map<String, Object>> collectBySystem(SalePageQuery pageQuery) {
+        List<Map<String, Object>> list = this.baseMapper.collectBySystem(pageQuery);
+        return list;
+    }
+
+    @Override
+    public IPage queryPage(SalePageQuery pageQuery) {
+        IPage page = this.baseMapper.queryPage(pageQuery);
+        return page;
+    }
+
+}

+ 55 - 0
src/main/java/com/nh/farm/cloud/business/service/impl/SaleSatisfactionBasicServiceImpl.java

@@ -0,0 +1,55 @@
+package com.nh.farm.cloud.business.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.nh.farm.cloud.business.domain.po.SaleSatisfactionBasicPo;
+import com.nh.farm.cloud.business.mapper.SaleSatisfactionBasicMapper;
+import com.nh.farm.cloud.business.service.SaleSatisfactionBasicService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @description: 满意度调查配置
+ * @author: suyun
+ */
+@Slf4j
+@Service
+public class SaleSatisfactionBasicServiceImpl extends ServiceImpl<SaleSatisfactionBasicMapper, SaleSatisfactionBasicPo> implements SaleSatisfactionBasicService {
+
+    @Override
+    public List<SaleSatisfactionBasicPo> selectBasicList() {
+        QueryWrapper<SaleSatisfactionBasicPo> wrapper = new QueryWrapper<>();
+        wrapper.lambda().eq(SaleSatisfactionBasicPo::getSatisfactionLevel, 0);
+        wrapper.lambda().orderByDesc(SaleSatisfactionBasicPo::getCreatedTime);
+        List<SaleSatisfactionBasicPo> list = this.baseMapper.selectList(wrapper);
+        return list;
+    }
+
+    @Override
+    public SaleSatisfactionBasicPo getLatestBasic() {
+        QueryWrapper<SaleSatisfactionBasicPo> wrapper = new QueryWrapper<>();
+        wrapper.lambda().eq(SaleSatisfactionBasicPo::getSatisfactionLevel, 0);
+        wrapper.lambda().orderByDesc(SaleSatisfactionBasicPo::getCreatedTime);
+        List<SaleSatisfactionBasicPo> basicList  = this.baseMapper.selectList(wrapper);
+
+        if (basicList.isEmpty()) {
+            return null;
+        } else {
+            // 第一层级:满意度调查名称
+            SaleSatisfactionBasicPo basic = basicList.get(0);
+            // 第二层级:调查内容
+            List<SaleSatisfactionBasicPo> topList = this.baseMapper.selectList(new LambdaQueryWrapper<SaleSatisfactionBasicPo>().eq(SaleSatisfactionBasicPo::getTopId, basic.getKid()));
+            topList.forEach(top -> {
+                // 第三层级:考评指标
+                List<SaleSatisfactionBasicPo> proList = this.baseMapper.selectList(new LambdaQueryWrapper<SaleSatisfactionBasicPo>().eq(SaleSatisfactionBasicPo::getTopId, top.getKid()));
+                top.setDetail(proList);
+            });
+            basic.setDetail(topList);
+            return basic;
+        }
+    }
+
+}

+ 53 - 0
src/main/java/com/nh/farm/cloud/business/service/impl/SaleSatisfactionDetailServiceImpl.java

@@ -0,0 +1,53 @@
+package com.nh.farm.cloud.business.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.nh.farm.cloud.business.domain.dto.SalePageQuery;
+import com.nh.farm.cloud.business.domain.po.SaleSatisfactionBasicPo;
+import com.nh.farm.cloud.business.domain.po.SaleSatisfactionDetailPo;
+import com.nh.farm.cloud.business.domain.po.SaleSatisfactionInfoPo;
+import com.nh.farm.cloud.business.mapper.SaleSatisfactionBasicMapper;
+import com.nh.farm.cloud.business.mapper.SaleSatisfactionDetailMapper;
+import com.nh.farm.cloud.business.mapper.SaleSatisfactionInfoMapper;
+import com.nh.farm.cloud.business.service.SaleSatisfactionDetailService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @description: 满意度调查填写-明细
+ * @author: suyun
+ */
+@Slf4j
+@Service
+public class SaleSatisfactionDetailServiceImpl extends ServiceImpl<SaleSatisfactionDetailMapper, SaleSatisfactionDetailPo> implements SaleSatisfactionDetailService {
+
+    @Autowired
+    private SaleSatisfactionBasicMapper satisfactionBasicMapper;
+
+    @Autowired
+    private SaleSatisfactionInfoMapper satisfactionInfoMapper;
+
+    @Override
+    public SaleSatisfactionBasicPo getInfoDetail(SalePageQuery pageQuery) {
+        SaleSatisfactionInfoPo satisfactionInfo = satisfactionInfoMapper.selectById(pageQuery.getKid());
+        // 第一层级:满意度调查名称
+        SaleSatisfactionBasicPo basic = satisfactionBasicMapper.selectById(satisfactionInfo.getSatisfactionBasicId());
+        basic.setScore(satisfactionInfo.getScore());
+        basic.setResult(satisfactionInfo.getResult());
+        basic.setRemark(satisfactionInfo.getRemark());
+        // 第二层级:调查内容
+        List<SaleSatisfactionBasicPo> topList = satisfactionBasicMapper.selectList(new LambdaQueryWrapper<SaleSatisfactionBasicPo>().eq(SaleSatisfactionBasicPo::getTopId, basic.getKid()));
+        topList.forEach(top -> {
+            // 第三层级:考评指标
+            List<SaleSatisfactionBasicPo> proList = this.baseMapper.getDetail(pageQuery.getKid(), top.getKid());
+            top.setDetail(proList);
+        });
+        basic.setDetail(topList);
+
+        return basic;
+    }
+
+}

+ 26 - 0
src/main/java/com/nh/farm/cloud/business/service/impl/SaleSatisfactionInfoServiceImpl.java

@@ -0,0 +1,26 @@
+package com.nh.farm.cloud.business.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.nh.farm.cloud.business.domain.dto.SalePageQuery;
+import com.nh.farm.cloud.business.domain.po.SaleSatisfactionInfoPo;
+import com.nh.farm.cloud.business.mapper.SaleSatisfactionInfoMapper;
+import com.nh.farm.cloud.business.service.SaleSatisfactionInfoService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+/**
+ * @description: 满意度调查填写-基本信息
+ * @author: suyun
+ */
+@Slf4j
+@Service
+public class SaleSatisfactionInfoServiceImpl extends ServiceImpl<SaleSatisfactionInfoMapper, SaleSatisfactionInfoPo> implements SaleSatisfactionInfoService {
+
+    @Override
+    public IPage queryPage(SalePageQuery pageQuery) {
+        IPage page = this.baseMapper.queryPage(pageQuery);
+        return page;
+    }
+
+}

+ 357 - 0
src/main/java/com/nh/farm/cloud/config/JacksonObjectMapper.java

@@ -0,0 +1,357 @@
+package com.nh.farm.cloud.config;
+
+/**
+ * @author 张智凯
+ * @version 1.0
+ * @data 2022/10/11 15:08
+ */
+
+import com.fasterxml.jackson.core.JacksonException;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.databind.ser.std.DateSerializer;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
+import org.springframework.stereotype.Component;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.math.BigInteger;
+import java.sql.Clob;
+import java.sql.SQLException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.time.*;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
+import java.time.temporal.ChronoField;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+
+import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;
+
+/**
+ * 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象
+ * 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]
+ * 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]
+ */
+@Component
+public class JacksonObjectMapper extends ObjectMapper {
+
+    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
+    public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
+    public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";
+
+    public static final List<String> formarts = new ArrayList<String>(14);
+    static{
+        formarts.add("yyyy-MM");
+        formarts.add("yyyy-MM-dd");
+        formarts.add("yyyy-MM-dd HH:mm");
+        formarts.add("yyyy-MM-dd HH:mm:ss");
+        formarts.add("yyyy-MM-dd'T'HH:mm:ss");
+        //国际标准时间
+
+        formarts.add("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
+        formarts.add("yyyy-MM-dd'T'HH:mm");
+
+
+        formarts.add("yyyy/MM");
+        formarts.add("yyyy/MM/dd");
+        formarts.add("yyyy/MM/dd HH:mm");
+        formarts.add("yyyy/MM/dd HH:mm:ss");
+        formarts.add("yyyy/MM/dd'T'HH:mm:ss");
+        //国际标准时间
+        formarts.add("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
+        formarts.add("yyyy/MM/dd'T'HH:mm");
+    }
+
+    public JacksonObjectMapper() {
+        super();
+        //收到未知属性时不报异常
+        this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);
+
+        //反序列化时,属性不存在的兼容处理
+        this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
+
+        SimpleModule simpleModule = new SimpleModule()
+                .addDeserializer(LocalDateTime.class, new MyLocalDateTimeDeserializer())
+                .addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
+                .addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)))
+
+                .addSerializer(BigInteger.class, ToStringSerializer.instance)
+                .addSerializer(Long.class, ToStringSerializer.instance)
+                .addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
+                .addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
+                .addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));
+
+        //日期序列化、反序列化
+        simpleModule.addSerializer(Date.class,new DateSerializer(false,new SimpleDateFormat(DEFAULT_DATE_TIME_FORMAT)));
+        simpleModule.addDeserializer(Date.class, new DateDeserializer());
+        simpleModule.addSerializer(Clob.class,new ClobSerializer());
+        //注册功能模块 例如,可以添加自定义序列化器和反序列化器
+        this.registerModule(simpleModule);
+    }
+
+    public class DateDeserializer extends JsonDeserializer<Date> {
+
+
+        @Override
+        public Date deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
+            String source = p.getText().trim();
+            if ("".equals(source)) {
+                return null;
+            }
+            if(source.matches("^\\d{4}-\\d{1,2}$")){
+                return parseDate(source, formarts.get(0));
+            }else if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2}$")){
+                return parseDate(source, formarts.get(1));
+            }else if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}$")){
+                return parseDate(source, formarts.get(2));
+            }else if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}:\\d{1,2}$")){
+                return parseDate(source, formarts.get(3));
+            } else if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2}T{1}\\d{1,2}:\\d{1,2}:\\d{1,2}$")){
+                return parseDate(source, formarts.get(4));
+            } else if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2}T{1}\\d{1,2}:\\d{1,2}:\\d{1,2}.0{3}Z$")){
+                source = source.replace("Z", " UTC");
+                return parseDate(source, formarts.get(5));
+            }else if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2}T{1}\\d{1,2}:\\d{1,2}$")){
+                return parseDate(source, formarts.get(6));
+            }
+            if(source.matches("^\\d{4}/\\d{1,2}$")){
+                return parseDate(source, formarts.get(7));
+            }else if(source.matches("^\\d{4}/\\d{1,2}/\\d{1,2}$")){
+                return parseDate(source, formarts.get(8));
+            }else if(source.matches("^\\d{4}/\\d{1,2}/\\d{1,2} {1}\\d{1,2}:\\d{1,2}$")){
+                return parseDate(source, formarts.get(9));
+            }else if(source.matches("^\\d{4}/\\d{1,2}/\\d{1,2} {1}\\d{1,2}:\\d{1,2}:\\d{1,2}$")){
+                return parseDate(source, formarts.get(10));
+            } else if(source.matches("^\\d{4}/\\d{1,2}/\\d{1,2}T{1}\\d{1,2}:\\d{1,2}:\\d{1,2}$")){
+                return parseDate(source, formarts.get(11));
+            } else if(source.matches("^\\d{4}/\\d{1,2}/\\d{1,2}T{1}\\d{1,2}:\\d{1,2}:\\d{1,2}.0{3}Z$")){
+                source = source.replace("Z", " UTC");
+                return parseDate(source, formarts.get(12));
+            }else if(source.matches("^\\d{4}/\\d{1,2}/\\d{1,2}T{1}\\d{1,2}:\\d{1,2}$")){
+                return parseDate(source, formarts.get(13));
+            }
+            else if(source.matches("^\\d{13}$")){//毫秒
+                return new Date(Long.parseLong(source));
+            }
+            else if(source.matches("^\\d{10}$")){//秒
+                return new Date(Long.parseLong(source) * 1000);
+            }
+            else {
+                throw new IllegalArgumentException("Invalid Date value '" + source + "'");
+            }
+
+        }
+
+        /**
+         * 功能描述:格式化日期
+         * @param dateStr String 字符型日期
+         * @param format String 格式
+         * @return Date 日期
+         */
+        public  Date parseDate(String dateStr, String format) {
+            Date date = null;
+            try {
+                DateFormat dateFormat = new SimpleDateFormat(format);
+                date = dateFormat.parse(dateStr);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            return date;
+        }
+    }
+
+
+
+
+    public class MyLocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
+
+
+        @Override
+        public LocalDateTime deserialize(JsonParser p, DeserializationContext ctcx) throws IOException, JacksonException {
+            String source = p.getText().trim();
+            if ("".equals(source)) {
+                return null;
+            }
+            if(source.matches("^\\d{4}-\\d{1,2}$")){
+                return parseDate(source, formarts.get(0),"yyyy-MM");
+            }else if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2}$")){
+                return parseDate(source, formarts.get(1),"yyyy-MM-dd");
+            }else if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}$")){
+                return parseDate(source, formarts.get(2));
+            }else if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}:\\d{1,2}$")){
+                return parseDate(source, formarts.get(3));
+            } else if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2}T{1}\\d{1,2}:\\d{1,2}:\\d{1,2}$")){
+                return parseDate(source, formarts.get(4));
+            } else if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2}T{1}\\d{1,2}:\\d{1,2}:\\d{1,2}.0{3}Z$")){
+                //   source = source.replace("Z", " UTC");
+                return parseDate(source, formarts.get(5),"UTC");
+            }else if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2}T{1}\\d{1,2}:\\d{1,2}$")){
+                return parseDate(source, formarts.get(6));
+            }
+            if(source.matches("^\\d{4}/\\d{1,2}$")){
+                return parseDate(source, formarts.get(7),"yyyy-MM");
+            }else if(source.matches("^\\d{4}/\\d{1,2}/\\d{1,2}$")){
+                return parseDate(source, formarts.get(8),"yyyy-MM-dd");
+            }else if(source.matches("^\\d{4}/\\d{1,2}/\\d{1,2} {1}\\d{1,2}:\\d{1,2}$")){
+                return parseDate(source, formarts.get(9));
+            }else if(source.matches("^\\d{4}/\\d{1,2}/\\d{1,2} {1}\\d{1,2}:\\d{1,2}:\\d{1,2}$")){
+                return parseDate(source, formarts.get(10));
+            } else if(source.matches("^\\d{4}/\\d{1,2}/\\d{1,2}T{1}\\d{1,2}:\\d{1,2}:\\d{1,2}$")){
+                return parseDate(source, formarts.get(11));
+            } else if(source.matches("^\\d{4}/\\d{1,2}/\\d{1,2}T{1}\\d{1,2}:\\d{1,2}:\\d{1,2}.0{3}Z$")){
+                //  source = source.replace("Z", " UTC");
+                return parseDate(source, formarts.get(12),"UTC");
+            }else if(source.matches("^\\d{4}/\\d{1,2}/\\d{1,2}T{1}\\d{1,2}:\\d{1,2}$")){
+                return parseDate(source, formarts.get(13));
+            }
+            else if(source.matches("^\\d{13}$")){//毫秒
+                return new Date(Long.parseLong(source)).toInstant().atOffset(ZoneOffset.of("+8")).toLocalDateTime();
+            }
+            else if(source.matches("^\\d{10}$")){//秒
+                return new Date(Long.parseLong(source) * 1000).toInstant().atOffset(ZoneOffset.of("+8")).toLocalDateTime();
+            }
+            else {
+                throw new IllegalArgumentException("Invalid LocalDateTime value '" + source + "'");
+            }
+        }
+
+
+        /**
+         * 功能描述:格式化日期
+         * @param dateStr String 字符型日期
+         * @param format String 格式
+         * @return LocalDateTime 日期*/
+
+        public LocalDateTime parseDate(String dateStr, String format,String parser) {
+            LocalDateTime dateTime = null;
+            try {
+                if(parser.equals("yyyy-MM")){
+                    DateTimeFormatter fmt = new DateTimeFormatterBuilder()
+                            .appendPattern(format)
+                            .parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
+                            .toFormatter();
+                    LocalDate localDate = LocalDate.parse(dateStr, fmt);
+                    dateTime = localDate.atStartOfDay();
+                }else if(parser.equals("yyyy-MM-dd")){
+                    LocalDate localDate = LocalDate.parse(dateStr, DateTimeFormatter.ofPattern(format));
+                    dateTime = localDate.atStartOfDay();
+                }else if(parser.equals("UTC")){
+                    DateTimeFormatter df = DateTimeFormatter.ofPattern(format, Locale.ENGLISH);
+                    LocalDateTime ldt = LocalDateTime.parse(dateStr, df);
+                    ZoneId currentZone = ZoneId.of("UTC");
+                    dateTime = ldt.atZone(currentZone).withZoneSameInstant(ZoneOffset.ofHours(8)).toLocalDateTime();
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            return dateTime;
+        }
+
+        /**
+         * 功能描述:格式化日期
+         * @param dateStr String 字符型日期
+         * @param format String 格式
+         * @return LocalDateTime 日期
+         */
+        public LocalDateTime parseDate(String dateStr, String format) {
+            LocalDateTime dateTime = null;
+            try {
+                dateTime = LocalDateTime.parse(dateStr, DateTimeFormatter.ofPattern(format));
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            return dateTime;
+        }
+
+    }
+
+
+    public class ClobSerializer extends JsonSerializer<Clob> {
+
+        @Override
+        public void serialize(Clob clob, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
+                throws IOException {
+            try {
+                StringBuilder sb = new StringBuilder();
+                Reader reader = clob.getCharacterStream();
+                BufferedReader br = new BufferedReader(reader);
+                String line;
+                while ((line = br.readLine()) != null) {
+                    sb.append(line);
+                }
+                br.close();
+                jsonGenerator.writeString(sb.toString());
+            } catch (SQLException e) {
+                // 处理异常情况
+                e.printStackTrace();
+            }
+        }
+    }
+
+    public static void main(String[] args) {
+/*
+        int input = 257;
+        int i = input;
+        int a = 0;
+        Boolean bo = true;
+
+        if(input%64 == 0){
+            System.out.println(input);
+        }else{
+            while (true){
+                a ++;
+                i = i - 1;
+                if(i <= 0){
+                    bo = false;
+                    break;
+                }
+                if(i%64 == 0){
+                    break;
+                }
+            }
+
+            int b = 0;
+            int i1 = input;
+            while (true){
+                b ++;
+                i1 = i1 + 1;
+                if(i1%64 == 0){
+                    break;
+                }
+            }
+
+            if(a < b && bo){
+                System.out.println(i);
+            }else{
+                System.out.println(i1);
+            }
+        }
+*/
+
+
+
+        int num = 257;
+        if(num<64){
+            System.out.println(64);
+        }else {
+            int round = Math.round(num / 64);
+            System.out.println(round * 64);
+        }
+    }
+
+
+}
+

+ 65 - 0
src/main/java/com/nh/farm/cloud/config/MyMetaObjectHandler.java

@@ -0,0 +1,65 @@
+package com.nh.farm.cloud.config;
+
+import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
+import com.nh.farm.cloud.util.ServletUtils;
+import com.nh.farm.cloud.util.redis.TokenUtil;
+import org.apache.ibatis.reflection.MetaObject;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.time.LocalDateTime;
+
+@Component
+public class MyMetaObjectHandler implements MetaObjectHandler {
+
+    @Autowired
+    private TokenUtil tokenUtil;
+
+    @Override
+    public void insertFill(MetaObject metaObject) {
+        if(ServletUtils.getRequestAttributes() != null && tokenUtil.getLoginUser(ServletUtils.getRequest()) != null){
+            this.setFieldValByName("createBy", tokenUtil.getKid(),metaObject);
+            this.setFieldValByName("createByName", tokenUtil.getNickName(),metaObject);
+            this.setFieldValByName("createTime", LocalDateTime.now(),metaObject);
+            this.setFieldValByName("updateBy", tokenUtil.getKid(),metaObject);
+            this.setFieldValByName("updateByName", tokenUtil.getNickName(),metaObject);
+            this.setFieldValByName("updateTime", LocalDateTime.now(),metaObject);
+            this.setFieldValByName("version", 1,metaObject);
+            this.setFieldValByName("deleted", "1",metaObject);
+            this.setFieldValByName("dataFlag", "0",metaObject);
+            this.setFieldValByName("operationUser", tokenUtil.getKid(),metaObject);
+            this.setFieldValByName("operationTime", LocalDateTime.now(),metaObject);
+            this.setFieldValByName("operationUserName", tokenUtil.getNickName(),metaObject);
+        }else{
+            this.setFieldValByName("createBy", " ",metaObject);
+            this.setFieldValByName("createByName", " ",metaObject);
+            this.setFieldValByName("createTime", LocalDateTime.now(),metaObject);
+            this.setFieldValByName("updateBy", " ",metaObject);
+            this.setFieldValByName("updateByName", " ",metaObject);
+            this.setFieldValByName("updateTime", LocalDateTime.now(),metaObject);
+            this.setFieldValByName("version", 1,metaObject);
+            this.setFieldValByName("deleted", "1",metaObject);
+            this.setFieldValByName("dataFlag", "0",metaObject);
+            this.setFieldValByName("operationUser", " ",metaObject);
+            this.setFieldValByName("operationTime", LocalDateTime.now(),metaObject);
+            this.setFieldValByName("operationUserName", " ",metaObject);
+        }
+
+
+    }
+
+    @Override
+    public void updateFill(MetaObject metaObject) {
+        if(ServletUtils.getRequestAttributes() != null && tokenUtil.getLoginUser(ServletUtils.getRequest()) != null){
+            this.setFieldValByName("updateBy", tokenUtil.getKid(), metaObject);
+            this.setFieldValByName("updateByName", tokenUtil.getNickName(), metaObject);
+            this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject);
+        }else{
+            this.setFieldValByName("updateBy", " ", metaObject);
+            this.setFieldValByName("updateByName", " ", metaObject);
+            this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject);
+        }
+
+        this.setFieldValByName("version", this.getFieldValByName("version", metaObject), metaObject);
+    }
+}

+ 25 - 0
src/main/java/com/nh/farm/cloud/config/MybatisPlusConfig.java

@@ -0,0 +1,25 @@
+package com.nh.farm.cloud.config;
+
+import com.baomidou.mybatisplus.annotation.DbType;
+import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@MapperScan("com.nh.farm.cloud.**.mapper")
+public class MybatisPlusConfig {
+    @Bean
+    public MybatisPlusInterceptor mybatisPlusInterceptor() {
+        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
+        PaginationInnerInterceptor interceptor = new PaginationInnerInterceptor();
+        interceptor.setDbType(DbType.ORACLE);
+        interceptor.setOverflow(true);
+        mybatisPlusInterceptor.addInnerInterceptor(interceptor);
+        // 开启乐观锁
+        mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
+        return mybatisPlusInterceptor;
+    }
+}

+ 19 - 0
src/main/java/com/nh/farm/cloud/config/ObjectWrapperFactoryConverter.java

@@ -0,0 +1,19 @@
+package com.nh.farm.cloud.config;
+
+import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;
+import org.springframework.boot.context.properties.ConfigurationPropertiesBinding;
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.stereotype.Component;
+
+@Component
+@ConfigurationPropertiesBinding
+public class ObjectWrapperFactoryConverter implements Converter<String, ObjectWrapperFactory> {
+    @Override
+    public ObjectWrapperFactory convert(String source) {
+        try {
+            return (ObjectWrapperFactory) Class.forName(source).newInstance();
+        } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}

+ 6 - 0
src/main/java/com/nh/farm/cloud/config/ShopConfig.java

@@ -0,0 +1,6 @@
+package com.nh.farm.cloud.config;
+
+public class ShopConfig {
+
+	public static final int OVERTIME_MONTH = 1;// 默认试用期
+}

+ 29 - 0
src/main/java/com/nh/farm/cloud/config/UploadConfig.java

@@ -0,0 +1,29 @@
+package com.nh.farm.cloud.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.multipart.MultipartResolver;
+import org.springframework.web.multipart.commons.CommonsMultipartResolver;
+
+/**
+ * 上传配置
+ *
+ * @author SunYang
+ * @date 2023/05/29
+ */
+@Configuration
+public class UploadConfig {
+    //显示声明CommonsMultipartResolver为mutipartResolver
+    @Bean(name = "multipartResolver")
+    public MultipartResolver multipartResolver() {
+        CommonsMultipartResolver resolver = new CommonsMultipartResolver();
+        resolver.setDefaultEncoding("UTF-8");
+        //resolveLazily属性启用是为了推迟文件解析,以在在UploadAction中捕获文件大小异常
+        resolver.setResolveLazily(true);
+        resolver.setMaxInMemorySize(40960);
+        //上传文件大小 50M 50*1024*1024
+        resolver.setMaxUploadSize(50 * 1024 * 1024);
+        return resolver;
+    }
+
+}

+ 60 - 0
src/main/java/com/nh/farm/cloud/config/WebConfig.java

@@ -0,0 +1,60 @@
+package com.nh.farm.cloud.config;
+
+import org.springframework.boot.web.client.RestTemplateBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+
+/**
+ * Web全局配置
+ * 
+ * @author 冯晓东 398479251@qq.com
+ *
+ */
+@Configuration
+public class WebConfig implements WebMvcConfigurer{
+
+	/**
+	 * 长度需要>8
+	 */
+	public static final String DESKEY = "des4TbAdminId";
+	/**
+	 * 记录 cookie中的session值
+	 */
+	public static final String ADMINSESSION = "ADMINSESSION";
+	/**
+	 * 记录 cookie中的session值
+	 */
+	public static final String SHOPSESSION = "SHOPSESSION";
+	/**
+	 * 记录 cookie中的session值
+	 */
+	public static final String MEMBERSESSION = "MEMBERSESSION";
+	/**
+	 * 记录 cookie中的session值
+	 */
+	public static final String USERSESSION = "USERSESSION";
+	
+	/**
+	 * 记录 cookie中的用户值
+	 */
+	public static final String USERSNAME = "USERSNAME";
+
+	/**
+	 * 记录 cookie中的token
+	 */
+	public static final String TOKENSESSION = "TOKENSESSION";
+	/**
+	 * 记录 用户信息的json
+	 */
+	public static final String ADMININFOSESSION = "ADMININFOSESSION";
+
+	@Bean
+	public RestTemplate restTemplate(RestTemplateBuilder builder) {
+		return builder.build();
+	}
+
+}
+

+ 233 - 0
src/main/java/com/nh/farm/cloud/util/AesUtil.java

@@ -0,0 +1,233 @@
+package com.nh.farm.cloud.util;
+
+import com.nh.fk.common.util.ChkUtil;
+import org.apache.commons.codec.binary.Base64;
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.spec.SecretKeySpec;
+import java.math.BigInteger;
+import java.util.*;
+
+/**
+ * AES的加密和解密
+ *
+ * @author libo
+ */
+public class AesUtil {
+	// 密钥 (需要前端和后端保持一致)
+	private static final String KEY = "01QFS8SD13ab0016";
+	// 算法
+	private static final String ALGORITHMSTR = "AES/ECB/PKCS5Padding";
+
+	/**
+	 * aes解密
+	 *
+	 * @param encrypt 内容
+	 * @return
+	 * @throws Exception
+	 */
+	public static String aesDecrypt(String encrypt) {
+		try {
+			return aesDecrypt(encrypt, KEY);
+		} catch (Exception e) {
+			e.printStackTrace();
+			return "";
+		}
+	}
+
+	/**
+	 * aes加密
+	 *
+	 * @param content
+	 * @return
+	 * @throws Exception
+	 */
+	public static String aesEncrypt(String content) {
+		try {
+			return aesEncrypt(content, KEY);
+		} catch (Exception e) {
+			e.printStackTrace();
+			return "";
+		}
+	}
+
+
+	/**
+	 * aes加密
+	 *
+	 * @param content
+	 * @return
+	 * @throws Exception
+	 */
+	public static String aesEncryptjia(String content,String key) {
+		try {
+			return aesEncrypt(content, key);
+		} catch (Exception e) {
+			e.printStackTrace();
+			return "";
+		}
+	}
+
+	/**
+	 * 将byte[]转为各种进制的字符串
+	 *
+	 * @param bytes byte[]
+	 * @param radix 可以转换进制的范围,从Character.MIN_RADIX到Character.MAX_RADIX,超出范围后变为10进制
+	 * @return 转换后的字符串
+	 */
+	public static String binary(byte[] bytes, int radix) {
+		return new BigInteger(1, bytes).toString(radix);// 这里的1代表正数
+	}
+
+	/**
+	 * base 64 encode
+	 *
+	 * @param bytes 待编码的byte[]
+	 * @return 编码后的base 64 code
+	 */
+	public static String base64Encode(byte[] bytes) {
+		return Base64.encodeBase64String(bytes);
+	}
+
+	/**
+	 * base 64 decode
+	 *
+	 * @param base64Code 待解码的base 64 code
+	 * @return 解码后的byte[]
+	 * @throws Exception
+	 */
+	public static byte[] base64Decode(String base64Code) throws Exception {
+		return ChkUtil.isNull(base64Code) ? null : java.util.Base64.getDecoder().decode(base64Code);
+	}
+
+	/**
+	 * AES加密
+	 *
+	 * @param content    待加密的内容
+	 * @param encryptKey 加密密钥
+	 * @return 加密后的byte[]
+	 * @throws Exception
+	 */
+	public static byte[] aesEncryptToBytes(String content, String encryptKey) throws Exception {
+		KeyGenerator kgen = KeyGenerator.getInstance("AES");
+		kgen.init(128);
+		Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
+		cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(encryptKey.getBytes(), "AES"));
+
+		return cipher.doFinal(content.getBytes("utf-8"));
+	}
+
+
+	/**
+	 * 返回结果全部加密
+	 * 李岩
+	 * */
+	public static List<Map<String,Object>> rtList(List<Map<String,Object>> list){
+		List<Map<String,Object>> rtlist =new ArrayList<Map<String,Object>>();
+		Map<String,Object> map =new HashMap<String,Object>(); //定义map存储加密后的信息
+		for (int a =0; a<list.size();a++){ //遍历传入参数获取所有键值对
+			Map<String,Object> maps =list.get(a);
+			Iterator iter = maps.entrySet().iterator(); //获取迭代器
+			while (iter.hasNext()){//遍历迭代器
+				Map.Entry  next = (Map.Entry) iter.next();
+				String key =(String) next.getKey(); //获取键
+				Object val =(Object) next.getValue(); //获取值
+				if (val == null || val.equals("")) {
+					map.put(key,val);
+				}else {
+					map.put(key, AesUtil.aesEncrypt(val.toString())); //存储加密后的信息
+
+				}
+			}
+			rtlist.add(map);
+		}
+		return rtlist;
+	}
+
+	/**
+	 * AES加密为base 64 code
+	 *
+	 * @param content    待加密的内容
+	 * @param encryptKey 加密密钥
+	 * @return 加密后的base 64 code
+	 * @throws Exception
+	 */
+	public static String aesEncrypt(String content, String encryptKey) throws Exception {
+		return base64Encode(aesEncryptToBytes(content, encryptKey));
+	}
+
+	/**
+	 * AES解密
+	 *
+	 * @param encryptBytes 待解密的byte[]
+	 * @param decryptKey   解密密钥
+	 * @return 解密后的String
+	 * @throws Exception
+	 */
+	public static String aesDecryptByBytes(byte[] encryptBytes, String decryptKey) throws Exception {
+		KeyGenerator kgen = KeyGenerator.getInstance("AES");
+		kgen.init(128);
+
+		Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
+		cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(decryptKey.getBytes(), "AES"));
+		byte[] decryptBytes = cipher.doFinal(encryptBytes);
+		return new String(decryptBytes);
+	}
+
+	/**
+	 * 将base 64 code AES解密
+	 *
+	 * @param encryptStr 待解密的base 64 code
+	 * @param decryptKey 解密密钥
+	 * @return 解密后的string
+	 * @throws Exception
+	 */
+	public static String aesDecrypt(String encryptStr, String decryptKey) throws Exception {
+		return ChkUtil.isNull(encryptStr) ? null : aesDecryptByBytes(base64Decode(encryptStr), decryptKey);
+	}
+
+	/**
+	 * 测试
+	 */
+	public static void main(String[] args) throws Exception {
+		/*String content = "000000";
+		System.out.println("加密前:" + content);
+		System.out.println("加密密钥和解密密钥:" + KEY);*/
+		String encrypt = aesEncrypt("yz123456.", KEY);//6ESyKgpNEQXWv+sc45Xm6g==    dUpUOFRZhg2nX9So2l8NgQ==
+		System.out.println("加密后:" + encrypt);
+		String decrypt = aesDecrypt("naT+uPyMfh1r+86xK1A3SQ==", KEY);
+		System.out.println("解密后:" + decrypt);
+	}
+
+
+	/**
+	 * aes解密
+	 *
+	 * @param encrypt 内容
+	 * @return
+	 * @throws Exception
+	 */
+	public static String aesDecrypt1(String encrypt,String key) {
+		try {
+			return aesDecrypt11(encrypt, key);
+		} catch (Exception e) {
+			e.printStackTrace();
+			return "";
+		}
+	}
+
+
+	/**
+	 * 将base 64 code AES解密
+	 *
+	 * @param encryptStr 待解密的base 64 code
+	 * @param decryptKey 解密密钥
+	 * @return 解密后的string
+	 * @throws Exception
+	 */
+	public static String aesDecrypt11(String encryptStr, String decryptKey) throws Exception {
+		return ChkUtil.isNull(encryptStr) ? null : aesDecryptByBytes(base64Decode(encryptStr), decryptKey);
+	}
+
+}

+ 139 - 0
src/main/java/com/nh/farm/cloud/util/BigDecimalUtil.java

@@ -0,0 +1,139 @@
+package com.nh.farm.cloud.util;
+
+import java.math.BigDecimal;
+
+/**
+ *	计算公式 .
+ *
+ */
+public class BigDecimalUtil {
+	/**
+	 * 对double数据进行取精度.
+	 * @param value  double数据.
+	 * @param scale  精度位数(保留的小数位数).
+	 * @param roundingMode  精度取值方式.
+	 * @return 精度计算后的数据.
+	 */
+	public static double round(double value, int scale,
+			int roundingMode) {
+		BigDecimal bd = BigDecimal.valueOf(value);
+		bd = bd.setScale(scale, roundingMode);
+		double d = bd.doubleValue();
+		bd = null;
+		return d;
+	}
+
+
+	/**
+	 *   提供精确的小数位四舍五入处理 .
+	 *   @param   v   需要四舍五入的数字。
+	 *   @param   scale   小数点后保留几位。
+	 *   @return   四舍五入后的结果。
+	 */
+	public static BigDecimal round(BigDecimal v, 
+			int scale) {
+		if (scale < 0) {
+			throw new IllegalArgumentException("The   scale   must   be   a   positive   integer   or   zero");
+		}
+		BigDecimal b = new BigDecimal(v.toString());
+		BigDecimal one = new BigDecimal("1");
+		return b.divide(one, scale, BigDecimal.ROUND_HALF_UP);
+	}
+
+
+	/**
+	 * double 相加.
+	 * @param d1
+	 * @param d2
+	 * @return
+	 */
+	public static BigDecimal sum(BigDecimal d1,BigDecimal d2){
+		BigDecimal bd1 = new BigDecimal(d1.toString());
+		BigDecimal bd2 = new BigDecimal(d2.toString()); 
+		return bd1.add(bd2);
+	}
+
+
+	/**
+	 * double 相减.
+	 * @param d1
+	 * @param d2
+	 * @return
+	 */
+	public static BigDecimal sub(BigDecimal d1,BigDecimal d2){
+		BigDecimal bd1 = new BigDecimal(d1.toString());
+		BigDecimal bd2 = new BigDecimal(d2.toString());
+		return bd1.subtract(bd2);
+	}
+
+	/**
+	 * double 乘法.
+	 * @param d1
+	 * @param d2
+	 * @return
+	 */
+	public static BigDecimal mul(BigDecimal d1,BigDecimal d2){
+		BigDecimal bd1 = new BigDecimal(d1.toString());
+		BigDecimal bd2 = new BigDecimal(d2.toString());
+		return bd1.multiply(bd2);
+	}
+
+	/**
+	 * double 乘法.
+	 * @param d1
+	 * @param d2
+	 * @return
+	 */
+	public static BigDecimal mul(BigDecimal d1,BigDecimal d2,int scale){
+		return round(mul(d1,d2), scale);
+	}
+
+
+	/**
+	 * double 除法.
+	 * @param d1
+	 * @param d2
+	 * @param scale 四舍五入 小数点位数
+	 * @return
+	 */
+	public static BigDecimal div(BigDecimal d1,BigDecimal d2,int scale){
+		//  当然在此之前,你要判断分母是否为0,
+		//  为0你可以根据实际需求做相应的处理
+
+		BigDecimal bd1 = new BigDecimal(d1.toString());
+		BigDecimal bd2 = new BigDecimal(d2.toString());
+		return bd1.divide
+				(bd2,scale,BigDecimal.ROUND_HALF_UP);
+	}
+
+	/**
+	 * double 除法.
+	 * @param d1
+	 * @param d2
+	 * @param scale 小数点位数(向零方向舍入的舍入模式)
+	 * @return
+	 */
+	public static BigDecimal divDown(BigDecimal d1,BigDecimal d2,int scale){
+		//  当然在此之前,你要判断分母是否为0,
+		//  为0你可以根据实际需求做相应的处理
+
+		BigDecimal bd1 = new BigDecimal(d1.toString());
+		BigDecimal bd2 = new BigDecimal(d2.toString());
+		return bd1.divide
+				(bd2,scale,BigDecimal.ROUND_DOWN);
+	}
+
+
+	/**
+	 * 获取账套.
+	 */
+	public static String getBillTo(String costCenterCode) {
+		if("BSVK".equals(costCenterCode.substring(0, 4))){
+			return "8009";
+		}else if("Bddd".equals(costCenterCode.substring(0, 4))){
+			return "1001";
+		}else{
+			return "1301";
+		}
+	}
+}

+ 38 - 0
src/main/java/com/nh/farm/cloud/util/CheckChineseUtil.java

@@ -0,0 +1,38 @@
+package com.nh.farm.cloud.util;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * 判断字符串类型
+ * 
+ * @author libo
+ */
+public class CheckChineseUtil {
+
+	//判断字符串是否是汉字
+	public static boolean isChinese(String con) {
+		for (int i = 0; i < con.length(); i = i + 1) {
+			if (!Pattern.compile("[\u4e00-\u9fa5]").matcher(String.valueOf(con.charAt(i))).find()) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	//判断是否是中文或英文字母
+	public static boolean conValidate(String con) {
+		if (null != con && !"".equals(con)) {
+			return (isChinese(con) || con.matches("^[A-Za-z]+$")) && con.length() <= 10;
+		}
+		return false;
+	}
+
+	//判断字符串是否是数字
+	public static boolean isNumeric(String str) {
+		Pattern pattern = Pattern.compile("[0-9]*");
+		Matcher isNum = pattern.matcher(str);
+		return isNum.matches();
+	}
+
+}

+ 95 - 0
src/main/java/com/nh/farm/cloud/util/Constants.java

@@ -0,0 +1,95 @@
+package com.nh.farm.cloud.util;
+
+/**
+ * 通用常量信息
+ */
+public class Constants
+{
+    /**
+     * UTF-8 字符集
+     */
+    public static final String UTF8 = "UTF-8";
+
+    /**
+     * GBK 字符集
+     */
+    public static final String GBK = "GBK";
+
+    /**
+     * 成功标记
+     */
+    public static final Integer SUCCESS = 200;
+
+    /**
+     * 失败标记
+     */
+    public static final Integer FAIL = 500;
+
+    /**
+     * 登录成功状态
+     */
+    public static final String LOGIN_SUCCESS_STATUS = "STATE001";
+
+    /**
+     * 登录失败状态
+     */
+    public static final String LOGIN_FAIL_STATUS = "STATE002";
+
+    /**
+     * 启用
+     */
+    public static final String ENABLE_SUCCESS_STATUS = "ENABLE001";
+
+    /**
+     * 禁用
+     */
+    public static final String ENABLE_FAIL_STATUS = "ENABLE002";
+
+    /**
+     * 登录成功
+     */
+    public static final String LOGIN_SUCCESS = "Success";
+
+    /**
+     * 注销
+     */
+    public static final String LOGOUT = "Logout";
+
+    /**
+     * 登录失败
+     */
+    public static final String LOGIN_FAIL = "Error";
+
+
+    /**
+     * 验证码 redis key
+     */
+    public static final String CAPTCHA_CODE_KEY = "captcha_codes:";
+
+
+    /**
+     * 菜单 redis key
+     */
+    public static final String MENU_CODE_KEY = "menu_codes:";
+
+    /**
+     * 验证码有效期(分钟)
+     */
+    public static final long CAPTCHA_EXPIRATION = 2;
+
+
+    /**
+     * token分隔符
+     */
+    public static final String SPLIT_FLAG = "@@";
+
+    /**
+     * 短信验证码
+     */
+    public static final String SMS_CODE_KEY = "sms_codes";
+
+    /**
+     * 通配符
+     */
+    public static final String WILDCARD = "*";
+}

+ 73 - 0
src/main/java/com/nh/farm/cloud/util/CookieUtil.java

@@ -0,0 +1,73 @@
+package com.nh.farm.cloud.util;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Cookie 工具类
+ * 
+ * @author 冯晓东 398479251@qq.com
+ *
+ */
+public class CookieUtil {
+	private CookieUtil() {
+	}
+
+	/**
+	 * set cookie
+	 * 
+	 * @param response
+	 * @param name
+	 * @param value
+	 * @param maxAgeInSeconds
+	 * @param path
+	 * @param domain
+	 * @param isHttpOnly
+	 */
+	public static void setCookie(HttpServletResponse response, String name, String value, int maxAgeInSeconds,
+			String path, String domain, Boolean isHttpOnly) {
+		Cookie cookie = new Cookie(name, value);
+		cookie.setMaxAge(maxAgeInSeconds);
+		if (path == null) {
+			path = "/";
+		}
+		cookie.setPath(path);
+
+		if (domain != null) {
+			cookie.setDomain(domain);
+		}
+		if (isHttpOnly != null) {
+			cookie.setHttpOnly(isHttpOnly);
+		}
+		response.addCookie(cookie);
+	}
+
+	/**
+	 * get cookie
+	 * 
+	 * @param request
+	 * @param name
+	 * @return
+	 */
+	public static Cookie getCookieObject(HttpServletRequest request, String name) {
+		Cookie[] cookies = request.getCookies();
+		if (cookies != null) {
+			for (Cookie cookie : cookies) {
+				if (cookie.getName().equals(name)) {
+					return cookie;
+				}
+			}
+		}
+		return null;
+	}
+
+	public static String getCookie(HttpServletRequest request, String name) {
+		Cookie cookie = getCookieObject(request, name);
+		return cookie != null ? cookie.getValue() : "";
+	}
+
+	public static void setCookie(HttpServletResponse response, String name, String value, int maxAgeInSeconds) {
+		setCookie(response, name, value, maxAgeInSeconds, null, null, null);
+	}
+}

+ 14 - 0
src/main/java/com/nh/farm/cloud/util/CustomHandler.java

@@ -0,0 +1,14 @@
+package com.nh.farm.cloud.util;
+
+import com.alibaba.excel.write.metadata.style.WriteCellStyle;
+import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
+
+public class CustomHandler extends HorizontalCellStyleStrategy {
+
+    private static final String RECORD = "Record";
+
+    public CustomHandler(WriteCellStyle headWriteCellStyle, WriteCellStyle contentWriteCellStyle) {
+        super(headWriteCellStyle, contentWriteCellStyle);
+    }
+
+}

+ 100 - 0
src/main/java/com/nh/farm/cloud/util/CustomWriteHandler.java

@@ -0,0 +1,100 @@
+package com.nh.farm.cloud.util;
+
+import com.alibaba.excel.enums.CellDataTypeEnum;
+import com.alibaba.excel.metadata.Head;
+import com.alibaba.excel.metadata.data.WriteCellData;
+import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
+import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
+import com.alibaba.excel.write.style.column.AbstractColumnWidthStyleStrategy;
+import org.apache.poi.ss.usermodel.Cell;
+import org.springframework.util.CollectionUtils;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class CustomWriteHandler extends AbstractColumnWidthStyleStrategy  {
+
+    // 单元格的最大宽度
+    private static final int MAX_COLUMN_WIDTH = 20;
+    // 缓存(第一个Map的键是sheet的index, 第二个Map的键是列的index, 值是数据长度)
+    private  Map<Integer, Map<Integer, Integer>> CACHE = new HashMap(8);
+
+
+
+    @Override
+    protected void setColumnWidth(CellWriteHandlerContext context) {
+        List<WriteCellData<?>> cellDataList = context.getCellDataList();
+        Cell cell = context.getCell();
+        Head head = context.getHeadData();
+        Integer relativeRowIndex = context.getRelativeRowIndex();
+        Boolean isHead = context.getHead();
+        WriteSheetHolder writeSheetHolder = context.getWriteSheetHolder();
+
+        boolean needSetWidth = isHead || !CollectionUtils.isEmpty(cellDataList);
+        // 当时表头或者单元格数据列表有数据时才进行处理
+        if (needSetWidth) {
+            Map<Integer, Integer> maxColumnWidthMap =
+                    CACHE.get(writeSheetHolder.getSheetNo());
+
+            if (maxColumnWidthMap == null) {
+                maxColumnWidthMap = new HashMap(16);
+                CACHE.put(writeSheetHolder.getSheetNo(), maxColumnWidthMap);
+            }
+            // 获取数据长度
+            Integer columnWidth = this.dataLength(cellDataList, cell, isHead);
+            if (columnWidth >= 0) {
+                if (columnWidth > MAX_COLUMN_WIDTH) {
+                    columnWidth = MAX_COLUMN_WIDTH;
+                }
+                // 确保一个列的列宽以表头为主,如果表头已经设置了列宽,单元格将会跟随表头的列宽
+                Integer maxColumnWidth = maxColumnWidthMap.get(cell.getColumnIndex());
+
+                if (maxColumnWidth == null || columnWidth > maxColumnWidth) {
+                    maxColumnWidthMap.put(cell.getColumnIndex(), columnWidth);
+                    // 如果使用EasyExcel默认表头,那么使用columnWidth * 512
+                    // 如果不使用EasyExcel默认表头,那么使用columnWidth * 256
+                    // 如果是自己定义的字体大小,可以再去测试这个参数常量
+                    writeSheetHolder
+                            .getSheet()
+                            .setColumnWidth(cell.getColumnIndex(), columnWidth * 256);
+                }
+
+            }
+        }
+    }
+
+
+    /**
+     * 获取当前单元格的数据长度
+     * @param cellDataList
+     * @param cell
+     * @param isHead
+     * @return
+     */
+    private Integer dataLength(List<WriteCellData<?>> cellDataList,
+                               Cell cell,
+                               Boolean isHead) {
+        if (isHead) {
+            return cell.getStringCellValue().getBytes().length;
+        } else {
+            WriteCellData cellData = cellDataList.get(0);
+            CellDataTypeEnum type = cellData.getType();
+            if (type == null) {
+                return -1;
+            } else {
+                switch(type) {
+                    case STRING:
+                        return cellData.getStringValue().getBytes().length;
+                    case BOOLEAN:
+                        return cellData.getBooleanValue().toString().getBytes().length;
+                    case NUMBER:
+                        return cellData.getNumberValue().toString().getBytes().length;
+                    default:
+                        return -1;
+                }
+            }
+        }
+    }
+
+}

+ 67 - 0
src/main/java/com/nh/farm/cloud/util/DateUtils.java

@@ -0,0 +1,67 @@
+package com.nh.farm.cloud.util;
+
+import org.apache.commons.lang3.time.DateFormatUtils;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+
+public class DateUtils {
+
+    //取出两个日期之间的所有年月
+    public static List<String> getMonthBetween(String minDate, String maxDate) throws ParseException {
+        ArrayList<String> result = new ArrayList<>();
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");//格式化为年月
+
+        Calendar min = Calendar.getInstance();
+        Calendar max = Calendar.getInstance();
+
+        min.setTime(sdf.parse(minDate));
+        min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);
+
+        max.setTime(sdf.parse(maxDate));
+        max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);
+
+        while (min.before(max)) {
+            result.add(sdf.format(min.getTime()));
+            min.add(Calendar.MONTH, 1);
+        }
+        return result;
+    }
+
+    /**
+     * 获取当前时间指定格式下的字符串.
+     * @param pattern
+     *            转化后时间展示的格式,例如"yyyy-MM-dd","yyyy-MM-dd HH:mm:ss"等
+     * @return String 格式转换之后的时间字符串.
+     * @since 1.0
+     */
+    public static String getDate(String pattern) {
+        return DateFormatUtils.format(new Date(), pattern);
+    }
+
+    /**
+     * 获取任意时间的月 下个月第一天
+     * 描述:<描述函数实现的功能>.
+     * @param repeatDate
+     * @return
+     */
+    public static String getMinMonthDate(String repeatDate, int num) {
+        SimpleDateFormat dft = new SimpleDateFormat("yyyy-MM-dd");
+        Calendar calendar = Calendar.getInstance();
+        try {
+            if (StringUtils.isNotBlank(repeatDate) && !"null".equals(repeatDate)) {
+                calendar.setTime(dft.parse(repeatDate));
+            }
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        calendar.add(Calendar.MONTH, num);
+        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
+        return dft.format(calendar.getTime());
+    }
+
+}

+ 156 - 0
src/main/java/com/nh/farm/cloud/util/DesensitizedUtils.java

@@ -0,0 +1,156 @@
+package com.nh.farm.cloud.util;
+
+import cn.hutool.core.util.StrUtil;
+import com.nh.fk.common.util.encoder.AesEncoder;
+
+/**
+ * 脱敏工具类
+ *
+ * @version v1.0
+ **/
+public class DesensitizedUtils {
+
+    /**
+     * 对字符串进行脱敏操作
+     * @param origin 原始字符串
+     * @param prefixNoMaskLen 左侧需要保留几位明文字段
+     * @param suffixNoMaskLen 右侧需要保留几位明文字段
+     * @param maskStr 用于遮罩的字符串, 如'*'
+     * @return 脱敏后结果
+     */
+    public static String desValue(String origin, int prefixNoMaskLen, int suffixNoMaskLen, String maskStr) {
+        if (origin == null) {
+            return null;
+        }
+
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0, n = origin.length(); i < n; i++) {
+            if (i < prefixNoMaskLen) {
+                sb.append(origin.charAt(i));
+                continue;
+            }
+            if (i > (n - suffixNoMaskLen - 1)) {
+                sb.append(origin.charAt(i));
+                continue;
+            }
+            sb.append(maskStr);
+        }
+        return sb.toString();
+    }
+
+    /**
+     * 【中文姓名】只显示最后一个汉字,其他隐藏为星号,比如:**梦
+     * @param fullName 姓名
+     * @return 结果
+     */
+    public static String chineseName(String fullName) {
+        if (fullName == null) {
+            return null;
+        }
+
+        if(fullName.length()==2){
+            return desValue(fullName, 1, 0, "*");
+        }else{
+            return desValue(fullName, 1, 1, "*");
+        }
+
+    }
+
+    /**
+     * 【身份证号】显示前六位, 四位,其他隐藏。共计18位或者15位,比如:340304*******1234
+     * @param id 身份证号码
+     * @return 结果
+     */
+    public static String idCardNum(String id,boolean isDecode) {
+        if(isDecode){
+            id = AesEncoder.decrypt(id);
+        }
+        return desValue(id, 6, 4, "*");
+    }
+
+
+
+    /**
+     * 【手机号码】前三位,后四位,其他隐藏,比如135****6810
+     * @param num 手机号码
+     * @return 结果
+     */
+    public static String mobilePhone(String num) {
+        return desValue(num, 3, 4, "*");
+    }
+
+    /**
+     * 【地址】只显示到地区,不显示详细地址,比如:北京市海淀区****
+     * @param address 地址
+     * @return 结果
+     */
+    public static String address(String address) {
+        return desValue(address, 6, 0, "*");
+    }
+
+    /**
+     * 【电子邮箱 邮箱前缀仅显示第一个字母,前缀其他隐藏,用星号代替,@及后面的地址显示,比如:d**@126.com
+     * @param email 电子邮箱
+     * @return 结果
+     */
+    public static String email(String email) {
+        if (email == null) {
+            return null;
+        }
+        int index = StrUtil.indexOf(email, '@');
+        if (index <= 1) {
+            return email;
+        }
+        String preEmail = desValue(email.substring(0, index), 1, 0, "*");
+        return preEmail + email.substring(index);
+
+    }
+
+    /**
+     * 【银行卡号】前六位,后四位,其他用星号隐藏每位1个星号,比如:622260**********1234
+     * @param cardNum 银行卡号
+     * @return 结果
+     */
+    public static String bankCard(String cardNum) {
+        return desValue(cardNum, 6, 4, "*");
+    }
+
+    /**
+     * 【密码】密码的全部字符都用*代替,比如:******
+     * @param password 密码
+     * @return 结果
+     */
+    public static String password(String password) {
+        if (password == null) {
+            return null;
+        }
+        return "******";
+    }
+
+    /**
+     * 【密钥】密钥除了最后三位,全部都用*代替,比如:***xdS 脱敏后长度为6,如果明文长度不足三位,则按实际长度显示,剩余位置补*
+     * @param key 密钥
+     * @return 结果
+     */
+    public static String key(String key) {
+        if (key == null) {
+            return null;
+        }
+        int viewLength = 6;
+        StringBuilder tmpKey = new StringBuilder(desValue(key, 0, 3, "*"));
+        if (tmpKey.length() > viewLength) {
+            return tmpKey.substring(tmpKey.length() - viewLength);
+        }
+        else if (tmpKey.length() < viewLength) {
+            int buffLength = viewLength - tmpKey.length();
+            for (int i = 0; i < buffLength; i++) {
+                tmpKey.insert(0, "*");
+            }
+            return tmpKey.toString();
+        }
+        else {
+            return tmpKey.toString();
+        }
+    }
+
+}

+ 125 - 0
src/main/java/com/nh/farm/cloud/util/ExcelTemplate.java

@@ -0,0 +1,125 @@
+package com.nh.farm.cloud.util;
+
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.ExcelWriter;
+import com.alibaba.excel.write.metadata.WriteSheet;
+import com.alibaba.excel.write.metadata.style.WriteCellStyle;
+import com.alibaba.excel.write.metadata.style.WriteFont;
+import oracle.net.ns.NetException;
+import org.apache.poi.ss.usermodel.BorderStyle;
+import org.apache.poi.ss.usermodel.HorizontalAlignment;
+import org.apache.poi.ss.usermodel.Workbook;
+
+import javax.servlet.http.HttpServletResponse;
+import java.net.URLEncoder;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * @Author 文件导出
+ * @Date 2021/9/14 10:13
+ * @Version 1.0
+ */
+public class ExcelTemplate {
+
+    /**
+     * 导出excel  动态生成列 无模板
+     * @param head 列集合
+     * @param dataList  一行的数据
+     * @param response
+     * @param fileName  文件名称
+     * @throws NetException
+     */
+    public static void exportExcelDynamicHead(List<List<String>> head, List<List<Object>> dataList, HttpServletResponse response, String fileName) throws NetException {
+        ExcelWriter excelWriter;
+        try {
+            response.setContentType("application/vnd.ms-excel");
+            response.setCharacterEncoding("utf-8");
+            // 这里URLEncoder.encode可以防止中文乱码 当然和easyExcel没有关系
+            String filename = URLEncoder.encode(fileName, "utf-8");
+            response.setHeader("Content-disposition", "attachment;filename=" + filename + ".xlsx");
+            excelWriter = EasyExcel.write(response.getOutputStream()).build();
+
+
+            // 创建一个写出的单元格样式对象
+            WriteCellStyle headWriteCellStyle = new WriteCellStyle();
+
+
+            // 创建一个写出的单元格样式对象
+            WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
+
+// 边框设置
+            contentWriteCellStyle.setBorderTop(BorderStyle.THIN);			 // 设置单元格上边框为细线
+            contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);		 // 设置单元格下边框为粗线
+            contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);	     // 设置单元格左边框为中线
+            contentWriteCellStyle.setBorderRight(BorderStyle.THIN); // 设置单元格右边框为中虚线
+
+// 创建写出Excel的字体对象
+            WriteFont contentWriteFont = new WriteFont();
+            contentWriteFont.setFontHeightInPoints((short)11);						  //设置字体大小
+            contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER); //设置文字居中
+            contentWriteCellStyle.setWriteFont(contentWriteFont); 	 // 把字体对象设置到单元格样式对象中
+
+
+            String sheetName = "Sheet1";
+            WriteSheet writeSheet = EasyExcel.writerSheet(sheetName)
+                    .head(head)
+                    .registerWriteHandler(new CustomWriteHandler())
+                    .registerWriteHandler(new CustomHandler(headWriteCellStyle,contentWriteCellStyle))
+                    .build();
+
+            excelWriter.write(dataList, writeSheet);
+            excelWriter.finish();
+
+
+        } catch (Exception e) {
+            //System.out.println(e.getMessage());
+        }
+    }
+
+
+
+    public static void ExcelTemplate(String fileName, String filePath, List list, Map<String, Object> map, HttpServletResponse response) throws Exception {
+
+
+        ExcelWriter excelWriter = null;
+       // try {
+            //   String fileName = s + DateUtils.getStringDate();//导出的文件名称
+            response.setContentType("application/vnd.ms-excel");
+            response.setCharacterEncoding("utf-8");
+            // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
+            String filename = URLEncoder.encode(fileName, "utf-8");
+            response.setHeader("Content-disposition", "attachment;filename=" + filename + ".xlsx");
+            //使用response.getOutputStream()下载,并使用项目下的模板填充
+            excelWriter = EasyExcel.write(response.getOutputStream()).withTemplate(filePath).build();
+
+
+            WriteSheet writeSheet = EasyExcel.writerSheet().build();
+
+            if (map != null) {
+                excelWriter.fill(map, writeSheet);//存入map
+            }
+            if (list != null) {
+                excelWriter.fill(list, writeSheet);//存入list
+            }
+            //   设置强制计算公式:不然公式会以字符串的形式显示在excel中
+
+            Workbook workbook = excelWriter.writeContext().writeWorkbookHolder().getWorkbook();
+            workbook.setForceFormulaRecalculation(true);
+            excelWriter.finish();
+
+
+//        } catch (Exception e) {
+//            // 重置response
+//            response.reset();
+//            response.setContentType("application/json");
+//            response.setCharacterEncoding("utf-8");
+//            return;
+//
+     }
+
+
+
+
+}

+ 38 - 0
src/main/java/com/nh/farm/cloud/util/GetNowDate.java

@@ -0,0 +1,38 @@
+package com.nh.farm.cloud.util;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+
+public class GetNowDate {
+    //获取系统当前时间,字符串类型
+    public static String getStrDate(){
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        //设置为东八区
+        sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
+        Date newDate = new Date();
+        String dateStr = sdf.format(newDate);
+        return dateStr;
+    }
+
+    //获取系统当前时间Date类型,需要将字符串类型转成时间
+    public static Date getDaDate(){
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        //设置为东八区
+        sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
+        Date date = new Date();
+        String dateStr = sdf.format(date);
+
+        //将字符串转成时间
+        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        Date newDate=null;
+        try {
+            newDate = df.parse(dateStr);
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        return newDate;
+    }
+}

+ 88 - 0
src/main/java/com/nh/farm/cloud/util/HttpUrlConn.java

@@ -0,0 +1,88 @@
+package com.nh.farm.cloud.util;
+
+
+import com.alibaba.fastjson.JSONObject;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.ConnectException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+/**
+ * 跨系统调用接口接收数据/发送数据
+ *
+ * @author SunY
+ * @date 2023/07/20
+ */
+public class HttpUrlConn {
+    /**
+     * 公共接口方法
+     * @param requestUrl 地址
+     * @param requestMethod 传输方式
+     * @param outputStr 数据 json形式的
+     * @return
+     */
+    public static JSONObject httpRequest2(String requestUrl, String requestMethod, String outputStr) {
+        JSONObject jsonObject = null;
+        StringBuffer buffer = new StringBuffer();
+        HttpURLConnection httpUrlConn = null;
+        try {
+            // 创建SSLContext对象,并使用我们指定的信任管理器初始化
+            URL url = new URL(requestUrl);
+            httpUrlConn = (HttpURLConnection) url.openConnection();
+            httpUrlConn.setDoOutput(true);
+            httpUrlConn.setDoInput(true);
+            httpUrlConn.setUseCaches(false);
+            httpUrlConn.setRequestProperty("Accept", "application/json");
+            httpUrlConn.setRequestProperty("Content-Type", "application/json");
+            // 设置请求方式(GET/POST)
+            httpUrlConn.setRequestMethod(requestMethod);
+            if ("GET".equalsIgnoreCase(requestMethod))
+                httpUrlConn.connect();
+
+            // 当有数据需要提交时
+            if (null != outputStr) {
+                OutputStream outputStream = httpUrlConn.getOutputStream();
+                // 注意编码格式,防止中文乱码
+                outputStream.write(outputStr.getBytes("UTF-8"));
+                outputStream.close();
+            }
+
+            // 将返回的输入流转换成字符串
+            InputStream inputStream = httpUrlConn.getInputStream();
+            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
+            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
+
+            String str = null;
+            while ((str = bufferedReader.readLine()) != null) {
+                buffer.append(str);
+            }
+            bufferedReader.close();
+            inputStreamReader.close();
+            // 释放资源
+            inputStream.close();
+            inputStream = null;
+            httpUrlConn.disconnect();
+            System.out.println(buffer.toString());
+            jsonObject = JSONObject.parseObject(buffer.toString());
+            // jsonObject = JSONObject.fromObject(buffer.toString());
+        } catch (ConnectException ce) {
+            throw new RuntimeException("Weixin server connection timed out.");
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException("https request error:{}" + e.getMessage());
+        } finally {
+            try {
+                httpUrlConn.disconnect();
+            } catch (Exception e) {
+                e.printStackTrace();
+                throw new RuntimeException("http close error:{}" + e.getMessage());
+            }
+        }
+        return jsonObject;
+    }
+
+}

+ 81 - 0
src/main/java/com/nh/farm/cloud/util/LowerUtils.java

@@ -0,0 +1,81 @@
+package com.nh.farm.cloud.util;
+
+import com.nh.fk.common.base.ne.NePage;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class LowerUtils {
+
+	public static List<Map<String, Object>> lower(List<Map<String, Object>> menuslist) {
+		List<Map<String, Object>> returnlist = new ArrayList<Map<String, Object>>();
+		for (int i = 0; i < menuslist.size(); i++) {
+			Map<String, Object> hashMap = new HashMap<String, Object>();
+			Map map = (Map) menuslist.get(i);
+			Object[] objs = null;
+			if (map != null)
+				objs = map.keySet().toArray();
+			if (objs != null) {
+				for (Object obj : objs) {
+					Object val = map.get(obj);
+					if (null == val) {
+						val = "";
+					}
+					hashMap.put(obj.toString().toLowerCase(), val);
+				}
+			}
+			returnlist.add(hashMap);
+		}
+
+		return returnlist;
+	}
+	
+	public static NePage lower(NePage page) {
+		NePage page1 =new NePage();
+		List<Map<String, Object>> menuslist = page.getList();
+		List<Map<String, Object>> returnlist = new ArrayList<Map<String, Object>>();
+		for (int i = 0; i < menuslist.size(); i++) {
+			Map<String, Object> hashMap = new HashMap<String, Object>();
+			Map map = (Map) menuslist.get(i);
+			Object[] objs = null;
+			if (map != null)
+				objs = map.keySet().toArray();
+			if (objs != null) {
+				for (Object obj : objs) {
+					Object val = map.get(obj);
+					if (null == val) {
+						val = "";
+					}
+					hashMap.put(obj.toString().toLowerCase(), val);
+				}
+			}
+			returnlist.add(hashMap);
+		}
+		page1.setList(returnlist);
+		page1.setPageNumber(page.getPageNumber());
+		page1.setPageSize(page.getPageSize());
+		page1.setTotalPage(page.getTotalPage());
+		page1.setTotalRow(page.getTotalRow());
+		return page1;
+	}
+	
+	public static Map<String, Object> lower(Map<String, Object> menuslist) {
+		Map<String, Object> hashMap = new HashMap<String, Object>();
+		Object[] objs = null;
+		if (menuslist != null)
+			objs = menuslist.keySet().toArray();
+		if (objs != null) {
+			for (Object obj : objs) {
+				Object val = menuslist.get(obj);
+				if (null == val) {
+					val = "";
+				}
+				hashMap.put(obj.toString().toLowerCase(), val);
+			}
+		}
+		return hashMap;
+	}
+
+}

+ 129 - 0
src/main/java/com/nh/farm/cloud/util/LowerUtils2.java

@@ -0,0 +1,129 @@
+package com.nh.farm.cloud.util;
+
+import com.nh.fk.common.base.ne.NePage;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class LowerUtils2 {
+
+	private static Pattern linePattern = Pattern.compile("_(\\w)");
+
+	public static List<Map<String, Object>> lower(List<Map<String, Object>> menuslist) {
+		List<Map<String, Object>> returnlist = new ArrayList<>();
+		if(menuslist.size()>0){
+			for (int i = 0; i < menuslist.size(); i++) {
+				Map<String, Object> hashMap = new HashMap<>();
+				Map map = menuslist.get(i);
+				Object[] objs = null;
+				if (map != null)
+					objs = map.keySet().toArray();
+				if (objs != null) {
+					for (Object obj : objs) {
+						Object val = map.get(obj);
+						if (null == val) {
+							val = "";
+						}
+						String colnames = obj.toString().toLowerCase();
+						colnames = lineToHump(colnames);
+						hashMap.put(colnames, val);
+					}
+				}
+				returnlist.add(hashMap);
+			}
+			return returnlist;
+		}else{
+			return menuslist;
+		}
+	}
+	
+	public static NePage lower(NePage page) {
+		NePage page1 =new NePage();
+		List<Map<String, Object>> menuslist = page.getList();
+		List<Map<String, Object>> returnlist = new ArrayList<>();
+		for (int i = 0; i < menuslist.size(); i++) {
+			Map<String, Object> hashMap = new HashMap<>();
+			Map map = menuslist.get(i);
+			Object[] objs = null;
+			if (map != null)
+				objs = map.keySet().toArray();
+			if (objs != null) {
+				for (Object obj : objs) {
+					Object val = map.get(obj);
+					if (null == val) {
+						val = "";
+					}
+					String colnames = obj.toString().toLowerCase();
+					colnames = lineToHump(colnames);
+					hashMap.put(colnames, val);
+				}
+			}
+			returnlist.add(hashMap);
+		}
+		page1.setList(returnlist);
+		page1.setPageNumber(page.getPageNumber());
+		page1.setPageSize(page.getPageSize());
+		page1.setTotalPage(page.getTotalPage());
+		page1.setTotalRow(page.getTotalRow());
+		return page1;
+	}
+	public static Map<String, Object> lower(Map<String, Object> menuslist) {
+			Map<String, Object> hashMap = new HashMap<>();
+			Object[] objs = null;
+			if (menuslist != null)
+				objs = menuslist.keySet().toArray();
+			if (objs != null) {
+				for (Object obj : objs) {
+					Object val = menuslist.get(obj);
+					if (null == val) {
+						val = "";
+					}
+					String colnames = obj.toString().toLowerCase();
+					colnames = lineToHump(colnames);
+					hashMap.put(colnames, val);
+				}
+			}
+
+		return hashMap;
+	}
+	
+	/** 下划线转驼峰 */
+	public static String lineToHump(String str) {
+		str = str.toLowerCase();
+		Matcher matcher = linePattern.matcher(str);
+		StringBuffer sb = new StringBuffer();
+		while (matcher.find()) {
+			matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
+		}
+		matcher.appendTail(sb);
+		return sb.toString();
+	}
+
+	public static void main(String[] args) {
+		//System.out.println(lineToHump("bank_code"));
+	}
+
+	/**
+	 * 驼峰转下划线,最后转为大写
+	 * @param str
+	 * @return
+	 */
+
+	private static final Pattern pattern = Pattern.compile("[A-Z]");
+	public static String humpToLine(String str) {
+		if(StringUtils.isEmpty(str)){
+			return null;
+		}
+		Matcher matcher = pattern.matcher(str);
+		StringBuffer sb = new StringBuffer();
+		while (matcher.find()) {
+			matcher.appendReplacement(sb, "_" + matcher.group(0).toUpperCase());
+		}
+		matcher.appendTail(sb);
+		return sb.toString().toUpperCase();
+	}
+}

+ 49 - 0
src/main/java/com/nh/farm/cloud/util/PageResult.java

@@ -0,0 +1,49 @@
+package com.nh.farm.cloud.util;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 分页工具类
+ */
+@Data
+public class PageResult {
+    /**
+     *页数
+     */
+    private int pageNum;
+    /**
+     * 每页的信息的个数
+     */
+    private int pageSize;
+    /**
+     * 总条数
+     */
+    private Long total;
+    /**
+     * 总页数
+     */
+    private int pages;
+    /**
+     * 结果集
+     */
+    private List<?> content;
+    /**
+     * 返回结果调用的方法
+     */
+    public static PageResult getPageResult(List content, int page, int limit, Long total) {
+        // 创建返回的对象
+        PageResult pageResult = new PageResult();
+        // 将分页后查询到的结果放入对象中
+        pageResult.setContent(content);
+        // 将起始页放入对象中
+        pageResult.setPageNum(page);
+        // 将每页显示的条数放入对象中
+        pageResult.setPageSize(limit);
+        // 将总条数放入对象中
+        pageResult.setTotal(total);
+        // 返回结果
+        return pageResult;
+    }
+}

+ 186 - 0
src/main/java/com/nh/farm/cloud/util/ServletUtils.java

@@ -0,0 +1,186 @@
+package com.nh.farm.cloud.util;
+
+import com.alibaba.fastjson.JSON;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.core.io.buffer.DataBuffer;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.http.server.reactive.ServerHttpResponse;
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+import reactor.core.publisher.Mono;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.util.Enumeration;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * 客户端工具类
+ */
+public class ServletUtils {
+
+    /**
+     * 获取request
+     */
+    public static HttpServletRequest getRequest() {
+        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
+                .getRequest();
+        return request;
+    }
+
+    /**
+     * 获取response
+     */
+    public static HttpServletResponse getReponse() {
+        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
+                .getResponse();
+        return response;
+    }
+
+
+    /**
+     * 获取session
+     */
+    public static HttpSession getSession() {
+        return getRequest().getSession();
+    }
+
+    public static ServletRequestAttributes getRequestAttributes() {
+        try {
+            RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
+            return (ServletRequestAttributes) attributes;
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    public static String getHeader(HttpServletRequest request, String name) {
+        String value = request.getHeader(name);
+        if (StringUtils.isEmpty(value)) {
+            return StringUtils.EMPTY;
+        }
+        return urlDecode(value);
+    }
+
+    public static Map<String, String> getHeaders(HttpServletRequest request) {
+        Map<String, String> map = new LinkedHashMap<>();
+        Enumeration<String> enumeration = request.getHeaderNames();
+        if (enumeration != null) {
+            while (enumeration.hasMoreElements()) {
+                String key = enumeration.nextElement();
+                String value = request.getHeader(key);
+                map.put(key, value);
+            }
+        }
+        return map;
+    }
+
+    /**
+     * 将字符串渲染到客户端
+     *
+     * @param response 渲染对象
+     * @param string   待渲染的字符串
+     */
+    public static void renderString(HttpServletResponse response, String string) {
+        try {
+            response.setStatus(200);
+            response.setContentType("application/json");
+            response.setCharacterEncoding("utf-8");
+            response.getWriter().print(string);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 内容编码
+     *
+     * @param str 内容
+     * @return 编码后的内容
+     */
+    public static String urlEncode(String str) {
+        try {
+            return URLEncoder.encode(str, Constants.UTF8);
+        } catch (UnsupportedEncodingException e) {
+            return StringUtils.EMPTY;
+        }
+    }
+
+    /**
+     * 内容解码
+     *
+     * @param str 内容
+     * @return 解码后的内容
+     */
+    public static String urlDecode(String str) {
+        try {
+            return URLDecoder.decode(str, Constants.UTF8);
+        } catch (UnsupportedEncodingException e) {
+            return StringUtils.EMPTY;
+        }
+    }
+
+    /**
+     * 设置webflux模型响应
+     *
+     * @param response ServerHttpResponse
+     * @param value    响应内容
+     * @return Mono<Void>
+     */
+    public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, Object value) {
+        return webFluxResponseWriter(response, HttpStatus.OK, value, HttpStatus.INTERNAL_SERVER_ERROR.value());
+    }
+
+    /**
+     * 设置webflux模型响应
+     *
+     * @param response ServerHttpResponse
+     * @param code     响应状态码
+     * @param value    响应内容
+     * @return Mono<Void>
+     */
+    public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, Object value, int code) {
+        return webFluxResponseWriter(response, HttpStatus.OK, value, code);
+    }
+
+    /**
+     * 设置webflux模型响应
+     *
+     * @param response ServerHttpResponse
+     * @param status   http状态码
+     * @param code     响应状态码
+     * @param value    响应内容
+     * @return Mono<Void>
+     */
+    public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, HttpStatus status, Object value, int code) {
+        return webFluxResponseWriter(response, MediaType.APPLICATION_JSON_VALUE, status, value, code);
+    }
+
+    /**
+     * 设置webflux模型响应
+     *
+     * @param response    ServerHttpResponse
+     * @param contentType content-type
+     * @param status      http状态码
+     * @param code        响应状态码
+     * @param value       响应内容
+     * @return Mono<Void>
+     */
+    public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, String contentType, HttpStatus status, Object value, int code) {
+        response.setStatusCode(status);
+        response.getHeaders().add(HttpHeaders.CONTENT_TYPE, contentType);
+        ResponseEntity<?> result = ResponseEntity.status(code).body(value.toString());
+        DataBuffer dataBuffer = response.bufferFactory().wrap(JSON.toJSONString(result).getBytes());
+        return response.writeWith(Mono.just(dataBuffer));
+    }
+}

+ 405 - 0
src/main/java/com/nh/farm/cloud/util/StringUtils.java

@@ -0,0 +1,405 @@
+package com.nh.farm.cloud.util;
+
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * 字符串工具类
+ * 
+ * @author jueLun
+ */
+public class StringUtils extends org.apache.commons.lang3.StringUtils
+{
+    /** 空字符串 */
+    private static final String NULLSTR = "";
+
+    /** 下划线 */
+    private static final char SEPARATOR = '_';
+
+    /**
+     * 获取参数不为空值
+     * 
+     * @param value defaultValue 要判断的value
+     * @return value 返回值
+     */
+    public static <T> T nvl(T value, T defaultValue)
+    {
+        return value != null ? value : defaultValue;
+    }
+
+    /**
+     * * 判断一个Collection是否为空, 包含List,Set,Queue
+     * 
+     * @param coll 要判断的Collection
+     * @return true:为空 false:非空
+     */
+    public static boolean isEmpty(Collection<?> coll)
+    {
+        return isNull(coll) || coll.isEmpty();
+    }
+
+    /**
+     * * 判断一个Collection是否非空,包含List,Set,Queue
+     * 
+     * @param coll 要判断的Collection
+     * @return true:非空 false:空
+     */
+    public static boolean isNotEmpty(Collection<?> coll)
+    {
+        return !isEmpty(coll);
+    }
+
+    /**
+     * * 判断一个对象数组是否为空
+     * 
+     * @param objects 要判断的对象数组
+     ** @return true:为空 false:非空
+     */
+    public static boolean isEmpty(Object[] objects)
+    {
+        return isNull(objects) || (objects.length == 0);
+    }
+
+    /**
+     * * 判断一个对象数组是否非空
+     * 
+     * @param objects 要判断的对象数组
+     * @return true:非空 false:空
+     */
+    public static boolean isNotEmpty(Object[] objects)
+    {
+        return !isEmpty(objects);
+    }
+
+    /**
+     * * 判断一个Map是否为空
+     * 
+     * @param map 要判断的Map
+     * @return true:为空 false:非空
+     */
+    public static boolean isEmpty(Map<?, ?> map)
+    {
+        return isNull(map) || map.isEmpty();
+    }
+
+    /**
+     * * 判断一个Map是否为空
+     * 
+     * @param map 要判断的Map
+     * @return true:非空 false:空
+     */
+    public static boolean isNotEmpty(Map<?, ?> map)
+    {
+        return !isEmpty(map);
+    }
+
+    /**
+     * * 判断一个字符串是否为空串
+     * 
+     * @param str String
+     * @return true:为空 false:非空
+     */
+    public static boolean isEmpty(String str)
+    {
+        return isNull(str) || NULLSTR.equals(str.trim());
+    }
+
+    /**
+     * * 判断一个字符串是否为非空串
+     * 
+     * @param str String
+     * @return true:非空串 false:空串
+     */
+    public static boolean isNotEmpty(String str)
+    {
+        return !isEmpty(str);
+    }
+
+    /**
+     * * 判断一个对象是否为空
+     * 
+     * @param object Object
+     * @return true:为空 false:非空
+     */
+    public static boolean isNull(Object object)
+    {
+        return object == null;
+    }
+
+    /**
+     * * 判断一个对象是否非空
+     * 
+     * @param object Object
+     * @return true:非空 false:空
+     */
+    public static boolean isNotNull(Object object)
+    {
+        return !isNull(object);
+    }
+
+    /**
+     * * 判断一个对象是否是数组类型(Java基本型别的数组)
+     * 
+     * @param object 对象
+     * @return true:是数组 false:不是数组
+     */
+    public static boolean isArray(Object object)
+    {
+        return isNotNull(object) && object.getClass().isArray();
+    }
+
+    /**
+     * 去空格
+     */
+    public static String trim(String str)
+    {
+        return (str == null ? "" : str.trim());
+    }
+
+    /**
+     * 截取字符串
+     * 
+     * @param str 字符串
+     * @param start 开始
+     * @return 结果
+     */
+    public static String substring(final String str, int start)
+    {
+        if (str == null)
+        {
+            return NULLSTR;
+        }
+
+        if (start < 0)
+        {
+            start = str.length() + start;
+        }
+
+        if (start < 0)
+        {
+            start = 0;
+        }
+        if (start > str.length())
+        {
+            return NULLSTR;
+        }
+
+        return str.substring(start);
+    }
+
+    /**
+     * 截取字符串
+     * 
+     * @param str 字符串
+     * @param start 开始
+     * @param end 结束
+     * @return 结果
+     */
+    public static String substring(final String str, int start, int end)
+    {
+        if (str == null)
+        {
+            return NULLSTR;
+        }
+
+        if (end < 0)
+        {
+            end = str.length() + end;
+        }
+        if (start < 0)
+        {
+            start = str.length() + start;
+        }
+
+        if (end > str.length())
+        {
+            end = str.length();
+        }
+
+        if (start > end)
+        {
+            return NULLSTR;
+        }
+
+        if (start < 0)
+        {
+            start = 0;
+        }
+        if (end < 0)
+        {
+            end = 0;
+        }
+
+        return str.substring(start, end);
+    }
+
+
+
+    /**
+     * 字符串转set
+     * 
+     * @param str 字符串
+     * @param sep 分隔符
+     * @return set集合
+     */
+    public static Set<String> str2Set(String str, String sep)
+    {
+        return new HashSet<String>(str2List(str, sep, true, false));
+    }
+
+    /**
+     * 字符串转list
+     * 
+     * @param str 字符串
+     * @param sep 分隔符
+     * @param filterBlank 过滤纯空白
+     * @param trim 去掉首尾空白
+     * @return list集合
+     */
+    public static List<String> str2List(String str, String sep, boolean filterBlank, boolean trim)
+    {
+        List<String> list = new ArrayList<String>();
+        if (StringUtils.isEmpty(str))
+        {
+            return list;
+        }
+
+        // 过滤空白字符串
+        if (filterBlank && StringUtils.isBlank(str))
+        {
+            return list;
+        }
+        String[] split = str.split(sep);
+        for (String string : split)
+        {
+            if (filterBlank && StringUtils.isBlank(string))
+            {
+                continue;
+            }
+            if (trim)
+            {
+                string = string.trim();
+            }
+            list.add(string);
+        }
+
+        return list;
+    }
+
+
+
+    /**
+     * 是否包含字符串
+     * 
+     * @param str 验证字符串
+     * @param strs 字符串组
+     * @return 包含返回true
+     */
+    public static boolean inStringIgnoreCase(String str, String... strs)
+    {
+        if (str != null && strs != null)
+        {
+            for (String s : strs)
+            {
+                if (str.equalsIgnoreCase(trim(s)))
+                {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。 例如:HELLO_WORLD->HelloWorld
+     *
+     * @param name 转换前的下划线大写方式命名的字符串
+     * @return 转换后的驼峰式命名的字符串
+     */
+    public static String convertToCamelCase(String name)
+    {
+        StringBuilder result = new StringBuilder();
+        // 快速检查
+        if (name == null || name.isEmpty())
+        {
+            // 没必要转换
+            return "";
+        }
+        else if (!name.contains("_"))
+        {
+            // 不含下划线,仅将首字母大写
+            return name.substring(0, 1).toUpperCase() + name.substring(1);
+        }
+        // 用下划线将原始字符串分割
+        String[] camels = name.split("_");
+        for (String camel : camels)
+        {
+            // 跳过原始字符串中开头、结尾的下换线或双重下划线
+            if (camel.isEmpty())
+            {
+                continue;
+            }
+            // 首字母大写
+            result.append(camel.substring(0, 1).toUpperCase());
+            result.append(camel.substring(1).toLowerCase());
+        }
+        return result.toString();
+    }
+
+    /**
+     * 驼峰式命名法 例如:user_name->userName
+     */
+    public static String toCamelCase(String s)
+    {
+        if (s == null)
+        {
+            return null;
+        }
+        s = s.toLowerCase();
+        StringBuilder sb = new StringBuilder(s.length());
+        boolean upperCase = false;
+        for (int i = 0; i < s.length(); i++)
+        {
+            char c = s.charAt(i);
+
+            if (c == SEPARATOR)
+            {
+                upperCase = true;
+            }
+            else if (upperCase)
+            {
+                sb.append(Character.toUpperCase(c));
+                upperCase = false;
+            }
+            else
+            {
+                sb.append(c);
+            }
+        }
+        return sb.toString();
+    }
+
+
+    /**
+     * 驼峰转下划线,最后转为大写
+     * @param str
+     * @return
+     */
+
+    private static final Pattern pattern = Pattern.compile("[A-Z]");
+    public static String humpToLine(String str) {
+        if(isEmpty(str)){
+            return null;
+        }
+        Matcher matcher = pattern.matcher(str);
+        StringBuffer sb = new StringBuffer();
+        while (matcher.find()) {
+            matcher.appendReplacement(sb, "_" + matcher.group(0).toUpperCase());
+        }
+        matcher.appendTail(sb);
+        return sb.toString().toUpperCase();
+    }
+
+
+}

+ 174 - 0
src/main/java/com/nh/farm/cloud/util/TreeTools.java

@@ -0,0 +1,174 @@
+package com.nh.farm.cloud.util;
+
+import com.nh.fk.common.util.JsonUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class TreeTools {
+
+	public static void main(String[] args) {
+
+	}
+
+	// 预处理树节点
+	public static List<Map<String, Object>> handleTree(List<Map<String, Object>> menuList) {
+		return handleTree(menuList, false);
+	}
+
+	// 预处理树节点
+	public static List<Map<String, Object>> handleTree(List<Map<String, Object>> menuList, boolean isChecked) {
+		for (Map<String, Object> map : menuList) {
+			map.put("id", map.get("area_code"));
+			map.put("iconCls", map.get("url"));
+			map.put("text", map.get("area_name"));
+			// map.put("text", map.remove("name"));
+		map.put("leaf", true);
+			
+			
+		}
+
+		return menuList;
+	}
+
+	// 预处理地区树节点
+	public static List<Map<String, Object>> handleTree_area(List<Map<String, Object>> menuList) {
+		return handleTree_area(menuList, false);
+	}
+
+	// 预处理地区树节点
+	public static List<Map<String, Object>> handleTree_area(List<Map<String, Object>> menuList, boolean isChecked) {
+		for (Map<String, Object> map : menuList) {
+			map.put("id", map.get("area_code"));
+			map.put("iconCls", map.get("url"));
+			map.put("text", map.get("area_name"));
+			map.put("code_area", map.get("area_code"));
+			map.put("leaf", true);
+			map.put("checked", false);
+		}
+
+		return menuList;
+	}
+
+	public static String turnListToTree(List<Map<String, Object>> menuList) {
+		// TODO 转换List为树形结构
+		return turnListToTree(menuList, false);
+	}
+
+	@SuppressWarnings("unchecked")
+	public static String turnListToTree(List<Map<String, Object>> menuList, boolean isChecked) {
+		// TODO 转换List为树形结构
+		menuList = handleTree(menuList, isChecked);
+
+		List<Map<String, Object>> nodeList = new ArrayList<Map<String, Object>>();
+		for (Map<String, Object> node1 : menuList) {
+			String node1_code = (String) node1.get("area_code");
+			String node1_parent_code = node1_code.substring(0, node1_code.length() - 3);
+
+			boolean mark = false;
+			for (Map<String, Object> node2 : menuList) {
+				String node2_code = (String) node2.get("area_code");
+
+				if (node1_parent_code != null && node1_parent_code.equals(node2_code)) {
+					mark = true;
+					if (node2.get("children") == null) {
+						node2.put("children", new ArrayList<Map<String, Object>>());
+					}
+					((List<Map<String, Object>>) node2.get("children")).add(node1);
+					node2.put("leaf", false);
+					if (!isChecked) {
+						node2.put("expanded", false);
+					}
+					break;
+				}
+			}
+			if (!mark) {
+				nodeList.add(node1);
+			}
+		}
+		return JsonUtil.toJson(nodeList);
+	}
+	
+	
+	
+
+	public static String turnListToTree_area(List<Map<String, Object>> menuList) {
+		// TODO 转换List为树形结构
+		return turnListToTree_area(menuList, false);
+	}
+
+	@SuppressWarnings("unchecked")
+	public static String turnListToTree_area(List<Map<String, Object>> menuList, boolean isChecked) {
+		// TODO 转换List为树形结构
+		menuList = handleTree_area(menuList, isChecked);
+
+		List<Map<String, Object>> nodeList = new ArrayList<Map<String, Object>>();
+		for (Map<String, Object> node1 : menuList) {
+			String node1_code = (String) node1.get("area_code");
+			String node1_parent_code = node1_code.substring(0, node1_code.length() - 3);
+
+			boolean mark = false;
+			for (Map<String, Object> node2 : menuList) {
+				String node2_code = (String) node2.get("area_code");
+
+				if (node1_parent_code != null && node1_parent_code.equals(node2_code)) {
+					mark = true;
+					if (node2.get("children") == null) {
+						node2.put("children", new ArrayList<Map<String, Object>>());
+					}
+					((List<Map<String, Object>>) node2.get("children")).add(node1);
+					node2.put("leaf", false);
+					if (!isChecked) {
+						node2.put("expanded", false);
+					}
+					break;
+				}
+			}
+			if (!mark) {
+				nodeList.add(node1);
+			}
+		}
+		return JsonUtil.toJson(nodeList);
+	}
+
+	// 预处理树节点
+	public static List<Map<String, Object>> handleAreaTree(List<Map<String, Object>> menuList, boolean isChecked,
+			int deep) {
+		for (Map<String, Object> map : menuList) {
+			map.put("id", map.remove("area_code"));
+			map.put("iconCls", map.remove("area_id"));
+			map.put("text", map.remove("area_name"));
+			if (deep == 3) {
+				map.put("leaf", true);
+
+			} else {
+				map.put("leaf", false);
+			}
+
+			if (isChecked) {
+				map.put("checked", false);
+			}
+		}
+		return menuList;
+	}
+	
+	public static List<Map<String, Object>> handle_paramNo(List<Map<String, Object>> menuslist,boolean isChecked) {
+		
+		for (Map<String, Object> map : menuslist) {
+			//String a = map.get("status").toString();
+			//if("0".equals(a)) {
+			map.put("id", map.get("area_code"));
+			map.put("iconCls", map.get("url"));
+			map.put("text", map.get("area_name"));
+			map.put("code_area", map.get("area_code"));
+			map.put("leaf", true);
+			 if (isChecked) {
+				    map.put("checked", false);
+				 //  }
+		}
+	}
+		return menuslist;
+	}
+
+}

+ 20 - 0
src/main/java/com/nh/farm/cloud/util/enums/BusinessStatus.java

@@ -0,0 +1,20 @@
+package com.nh.farm.cloud.util.enums;
+
+/**
+ * 操作状态
+ * 
+ * @author ruoyi
+ *
+ */
+public enum BusinessStatus
+{
+    /**
+     * 成功
+     */
+    SUCCESS,
+
+    /**
+     * 失败
+     */
+    FAIL,
+}

+ 98 - 0
src/main/java/com/nh/farm/cloud/util/enums/BusinessType.java

@@ -0,0 +1,98 @@
+package com.nh.farm.cloud.util.enums;
+
+import java.util.Objects;
+
+/**
+ * 业务操作类型
+ * 
+ * @author 农业
+ */
+public enum BusinessType
+{
+    /**
+     * 其它
+     */
+    OTHER("OPER001", "其它"),
+
+    /**
+     * 新增
+     */
+    INSERT("OPER002", "新增"),
+
+    /**
+     * 修改
+     */
+    UPDATE("OPER003", "修改"),
+
+    /**
+     * 删除
+     */
+    DELETE("OPER004", "删除"),
+
+    /**
+     * 授权
+     */
+    GRANT("OPER005", "授权"),
+
+    /**
+     * 导出
+     */
+    EXPORT("OPER006", "导出"),
+
+    /**
+     * 导入
+     */
+    IMPORT("OPER007", "导入"),
+
+    /**
+     * 强退
+     */
+    FORCE("OPER008", "强退"),
+
+    /**
+     * 生成代码
+     */
+    GENCODE("OPER009", "生成代码"),
+;
+    private String code;
+    private String msg;
+
+    /**
+     * Msg string.
+     *
+     * @return the string
+     */
+    public String msg() {
+        return msg;
+    }
+
+    /**
+     * Code int.
+     *
+     * @return the int
+     */
+    public String code() {
+        return code;
+    }
+
+    BusinessType(String code, String msg) {
+        this.code = code;
+        this.msg = msg;
+    }
+
+    /**
+     * Gets enum.
+     *
+     * @param code the code
+     *
+     * @return the enum
+     */
+    public static BusinessType getEnum(String code) {
+        for (BusinessType ele : BusinessType.values()) {
+            if (Objects.equals(ele.code(), code)) {
+                return ele;
+            }
+        }
+        return null;
+    }
+}

+ 65 - 0
src/main/java/com/nh/farm/cloud/util/enums/OperatorType.java

@@ -0,0 +1,65 @@
+package com.nh.farm.cloud.util.enums;
+
+import java.util.Objects;
+
+/**
+ * 操作人类别
+ *
+ * @author 农业
+ */
+public enum OperatorType {
+    /**
+     * 其它
+     */
+    OTHER("FACILITY001", "其它"),
+
+    /**
+     * 后台用户
+     */
+    MANAGE("FACILITY002", "后台用户"),
+
+    /**
+     * 手机端用户
+     */
+    MOBILE("FACILITY003", "手机端用户");
+    private String code;
+    private String msg;
+    /**
+     * Msg string.
+     *
+     * @return the string
+     */
+    public String msg() {
+        return msg;
+    }
+
+    /**
+     * Code int.
+     *
+     * @return the int
+     */
+    public String code() {
+        return code;
+    }
+
+    OperatorType(String code, String msg) {
+        this.code = code;
+        this.msg = msg;
+    }
+
+    /**
+     * Gets enum.
+     *
+     * @param code the code
+     *
+     * @return the enum
+     */
+    public static OperatorType getEnum(String code) {
+        for (OperatorType ele : OperatorType.values()) {
+            if (Objects.equals(ele.code(), code)) {
+                return ele;
+            }
+        }
+        return null;
+    }
+}

+ 47 - 0
src/main/java/com/nh/farm/cloud/util/enums/SensitiveTypeEnum.java

@@ -0,0 +1,47 @@
+package com.nh.farm.cloud.util.enums;
+
+/**
+ * 敏感信息枚举类
+ *
+ * @version v1.0
+ **/
+public enum SensitiveTypeEnum {
+
+    /**
+     * 自定义
+     */
+    CUSTOMER,
+    /**
+     * 用户名, 刘*华, 徐*
+     */
+    CHINESE_NAME,
+    /**
+     * 身份证号, 110110********1234
+     */
+    ID_CARD,
+    /**
+     * 手机号, 176****1234
+     */
+    MOBILE_PHONE,
+    /**
+     * 地址, 北京********
+     */
+    ADDRESS,
+    /**
+     * 电子邮件, s*****o@xx.com
+     */
+    EMAIL,
+    /**
+     * 银行卡, 622202************1234
+     */
+    BANK_CARD,
+    /**
+     * 密码, 永远是 ******, 与长度无关
+     */
+    PASSWORD,
+    /**
+     * 密钥, 【密钥】密钥除了最后三位其他都是***, 与长度无关
+     */
+    KEY
+
+}

+ 109 - 0
src/main/java/com/nh/farm/cloud/util/enums/SysTemType.java

@@ -0,0 +1,109 @@
+package com.nh.farm.cloud.util.enums;
+
+import java.util.Objects;
+
+/**
+ * 业务操作类型
+ * 
+ * @author 农业
+ */
+public enum SysTemType
+{
+    /**
+     * 基础系统
+     */
+    BASIC("SYSTEM001", "基础系统"),
+
+    /**
+     * 数据管理系统
+     */
+    COLLECT("SYSTEM002", "数据管理系统"),
+
+    /**
+     * 信息发布系统
+     */
+    INFO("SYSTEM003", "信息发布系统"),
+
+    /**
+     * 数据治理系统
+     */
+    GOVERNANCE("SYSTEM004", "数据治理系统"),
+
+    /**
+     * 数据监测系统
+     */
+    MONITOR("SYSTEM005", "数据监测系统"),
+
+    /**
+     * 转账审批系统
+     */
+    APPROVAL("SYSTEM006", "转账审批系统"),
+
+    /**
+     * 预警系统
+     */
+    WARN("SYSTEM007", "预警系统"),
+
+    /**
+     * 数据分析系统
+     */
+    ANALYSIS("SYSTEM008", "数据分析系统"),
+
+    /**
+     * 财务系统
+     */
+    FINANCE("SYSTEM009", "财务系统"),
+
+    /**
+     * 其它
+     */
+    OTHER("SYSTEM088", "其它"),
+
+    /**
+     * 不建议使用  目前仅查询菜单时使用
+     */
+    ALL("SYSTEM099", "财务系统"),
+
+;
+    private String code;
+    private String msg;
+
+    /**
+     * Msg string.
+     *
+     * @return the string
+     */
+    public String msg() {
+        return msg;
+    }
+
+    /**
+     * Code int.
+     *
+     * @return the int
+     */
+    public String code() {
+        return code;
+    }
+
+    SysTemType(String code, String msg) {
+        this.code = code;
+        this.msg = msg;
+    }
+
+    /**
+     * Gets enum.
+     *
+     * @param code the code
+     *
+     * @return the enum
+     */
+    public static SysTemType getEnum(String code) {
+        for (SysTemType ele : SysTemType.values()) {
+            if (Objects.equals(ele.code(), code)) {
+                return ele;
+            }
+        }
+        return null;
+    }
+}

+ 25 - 0
src/main/java/com/nh/farm/cloud/util/excelUtil/BigDecimalNumberNewConverter.java

@@ -0,0 +1,25 @@
+package com.nh.farm.cloud.util.excelUtil;
+
+import com.alibaba.excel.converters.Converter;
+import com.alibaba.excel.converters.bigdecimal.BigDecimalNumberConverter;
+import com.alibaba.excel.metadata.GlobalConfiguration;
+import com.alibaba.excel.metadata.data.ReadCellData;
+import com.alibaba.excel.metadata.property.ExcelContentProperty;
+
+import java.math.BigDecimal;
+
+/**
+ * @author LiuYu
+ * @date 2023/3/28 13:33
+ * @description
+ */
+public class BigDecimalNumberNewConverter extends BigDecimalNumberConverter implements Converter<BigDecimal> {
+    @Override
+    public BigDecimal convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
+        BigDecimal numberValue = cellData.getNumberValue();
+        if (numberValue == null) {
+            return BigDecimal.ZERO;
+        }
+        return new BigDecimal(numberValue.doubleValue());
+    }
+}

+ 57 - 0
src/main/java/com/nh/farm/cloud/util/excelUtil/ExcelDemoUtils.java

@@ -0,0 +1,57 @@
+package com.nh.farm.cloud.util.excelUtil;
+
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.function.Consumer;
+
+public class ExcelDemoUtils {
+	
+	/**
+	 * 指定阈值
+	 * @param <T>
+	 * @param consumer
+	 * @param threshold
+	 * @return
+	 */
+	public static <T> AnalysisEventListener<T> getListener(Consumer<List<T>> consumer, int threshold){
+		
+		
+		return new AnalysisEventListener<T>() {
+			private LinkedList<T> linkedList = new LinkedList<T>();
+			//private int count;
+			//int s=threshold-2;
+			@Override
+			public void invoke(T t , AnalysisContext analysisContext) {
+				linkedList.add(t);
+				if(linkedList.size() == threshold) {
+				
+					consumer.accept(linkedList);
+					linkedList.clear();
+					
+				}
+			}
+			
+			@Override
+			public void doAfterAllAnalysed(AnalysisContext analysisContext) {
+				
+				if(linkedList.size()>0) {
+					
+					consumer.accept(linkedList);
+				}
+			}
+		};
+	}
+	
+	/**
+	 * 不指定阈值,阈值默认为10
+	 * @param <T>
+	 * @param consumer
+	 * @return
+	 */
+	public static <T> AnalysisEventListener<T> getListener(Consumer<List<T>> consumer){
+		return getListener(consumer);
+	}
+}

+ 52 - 0
src/main/java/com/nh/farm/cloud/util/getNumUtil.java

@@ -0,0 +1,52 @@
+package com.nh.farm.cloud.util;
+
+import com.nh.fk.common.base.exception.BusinessException;
+
+import java.text.DecimalFormat;
+
+/**
+ * @author hancf
+ * @date 2022/8/27
+ * @apinote
+ */
+public class getNumUtil {
+    /**
+     * 轮次编号生成规则
+     * 1、如果当前时间没有核酸轮次,直接新增 ,默认为:HSJC-yyyyMMdd01
+     * 2、查询到有核酸轮次,查找当前那一天最大的轮次编号,自增1
+     *
+     * @param code 当前最大编码
+     */
+    public static String getNum(String code) {
+        String roundCode = "01";
+        if (code != null && !code.isEmpty()) {
+            int intCode = Integer.parseInt(code) + 1;
+            if (intCode < 99) {
+                roundCode = String.format(String.valueOf(intCode));
+            } else {
+                throw new BusinessException("500, 轮次编号达到最大");
+            }
+        }
+        //编号前面补0
+        DecimalFormat df = new DecimalFormat("00");
+        String newCode = df.format(Integer.parseInt(roundCode));
+        return newCode;
+    }
+
+    public static String getNo(String code) {
+        String roundCode = "0001";
+        if (code != null && !code.isEmpty()) {
+            int intCode = Integer.parseInt(code) + 1;
+            if (intCode < 9999) {
+                roundCode = String.format(String.valueOf(intCode));
+            } else {
+                throw new BusinessException("10000, 轮次编号达到最大");
+            }
+        }
+        //编号前面补0
+        DecimalFormat df = new DecimalFormat("0000");
+        String newCode = df.format(Integer.parseInt(roundCode));
+        return newCode;
+    }
+
+}

+ 46 - 0
src/main/java/com/nh/farm/cloud/util/ip/AddressUtils.java

@@ -0,0 +1,46 @@
+package com.nh.farm.cloud.util.ip;
+
+import com.alibaba.fastjson.JSONObject;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * 获取地址类
+ * 
+ * @author 张德华
+ */
+public class AddressUtils
+{
+
+    // IP地址查询
+    public static final String IP_URL = "http://whois.pconline.com.cn/ipJson.jsp";
+
+    // 未知地址
+    public static final String UNKNOWN = "XX XX";
+
+    public static String getRealAddressByIP(String ip)
+    {
+            try
+            {
+                RestTemplate restTemplate = new RestTemplate();
+                String rspStr = restTemplate.getForObject(IP_URL,String.class, "ip=" + ip + "&json=true", "GBK");
+                if (StringUtils.isEmpty(rspStr))
+                {
+                    return UNKNOWN;
+                }
+                JSONObject obj = JSONObject.parseObject(rspStr);
+                String region = obj.getString("pro");
+                String city = obj.getString("city");
+                return String.format("%s %s", region, city);
+            }
+            catch (Exception ignored)
+            {
+            }
+        return "不知名的IP";
+    }
+
+    public static void main(String[] args) {
+        String realAddressByIP = getRealAddressByIP("171.120.211.108");
+        System.out.println(realAddressByIP);
+    }
+}

+ 222 - 0
src/main/java/com/nh/farm/cloud/util/ip/IpUtils.java

@@ -0,0 +1,222 @@
+package com.nh.farm.cloud.util.ip;
+
+import org.apache.commons.lang3.StringUtils;
+
+import javax.servlet.http.HttpServletRequest;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * 获取IP方法
+ */
+public class IpUtils {
+    /**
+     * 获取客户端IP
+     *
+     * @param request 请求对象
+     * @return IP地址
+     */
+    public static String getIpAddr(HttpServletRequest request) {
+        if (request == null) {
+            return "unknown";
+        }
+        String ip = request.getHeader("x-forwarded-for");
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("Proxy-Client-IP");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("X-Forwarded-For");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("WL-Proxy-Client-IP");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("X-Real-IP");
+        }
+
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getRemoteAddr();
+        }
+
+        return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : getMultistageReverseProxyIp(ip);
+    }
+
+    /**
+     * 检查是否为内部IP地址
+     *
+     * @param ip IP地址
+     * @return 结果
+     */
+    public static boolean internalIp(String ip) {
+        byte[] addr = textToNumericFormatV4(ip);
+        return internalIp(addr) || "127.0.0.1".equals(ip);
+    }
+
+    /**
+     * 检查是否为内部IP地址
+     *
+     * @param addr byte地址
+     * @return 结果
+     */
+    private static boolean internalIp(byte[] addr) {
+        if (addr == null || addr.length < 2) {
+            return true;
+        }
+        final byte b0 = addr[0];
+        final byte b1 = addr[1];
+        // 10.x.x.x/8
+        final byte SECTION_1 = 0x0A;
+        // 172.16.x.x/12
+        final byte SECTION_2 = (byte) 0xAC;
+        final byte SECTION_3 = (byte) 0x10;
+        final byte SECTION_4 = (byte) 0x1F;
+        // 192.168.x.x/16
+        final byte SECTION_5 = (byte) 0xC0;
+        final byte SECTION_6 = (byte) 0xA8;
+        switch (b0) {
+            case SECTION_1:
+                return true;
+            case SECTION_2:
+                if (b1 >= SECTION_3 && b1 <= SECTION_4) {
+                    return true;
+                }
+            case SECTION_5:
+                switch (b1) {
+                    case SECTION_6:
+                        return true;
+                }
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * 将IPv4地址转换成字节
+     *
+     * @param text IPv4地址
+     * @return byte 字节
+     */
+    public static byte[] textToNumericFormatV4(String text) {
+        if (text.length() == 0) {
+            return null;
+        }
+
+        byte[] bytes = new byte[4];
+        String[] elements = text.split("\\.", -1);
+        try {
+            long l;
+            int i;
+            switch (elements.length) {
+                case 1:
+                    l = Long.parseLong(elements[0]);
+                    if ((l < 0L) || (l > 4294967295L)) {
+                        return null;
+                    }
+                    bytes[0] = (byte) (int) (l >> 24 & 0xFF);
+                    bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF);
+                    bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
+                    bytes[3] = (byte) (int) (l & 0xFF);
+                    break;
+                case 2:
+                    l = Integer.parseInt(elements[0]);
+                    if ((l < 0L) || (l > 255L)) {
+                        return null;
+                    }
+                    bytes[0] = (byte) (int) (l & 0xFF);
+                    l = Integer.parseInt(elements[1]);
+                    if ((l < 0L) || (l > 16777215L)) {
+                        return null;
+                    }
+                    bytes[1] = (byte) (int) (l >> 16 & 0xFF);
+                    bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
+                    bytes[3] = (byte) (int) (l & 0xFF);
+                    break;
+                case 3:
+                    for (i = 0; i < 2; ++i) {
+                        l = Integer.parseInt(elements[i]);
+                        if ((l < 0L) || (l > 255L)) {
+                            return null;
+                        }
+                        bytes[i] = (byte) (int) (l & 0xFF);
+                    }
+                    l = Integer.parseInt(elements[2]);
+                    if ((l < 0L) || (l > 65535L)) {
+                        return null;
+                    }
+                    bytes[2] = (byte) (int) (l >> 8 & 0xFF);
+                    bytes[3] = (byte) (int) (l & 0xFF);
+                    break;
+                case 4:
+                    for (i = 0; i < 4; ++i) {
+                        l = Integer.parseInt(elements[i]);
+                        if ((l < 0L) || (l > 255L)) {
+                            return null;
+                        }
+                        bytes[i] = (byte) (int) (l & 0xFF);
+                    }
+                    break;
+                default:
+                    return null;
+            }
+        } catch (NumberFormatException e) {
+            return null;
+        }
+        return bytes;
+    }
+
+    /**
+     * 获取IP地址
+     *
+     * @return 本地IP地址
+     */
+    public static String getHostIp() {
+        try {
+            return InetAddress.getLocalHost().getHostAddress();
+        } catch (UnknownHostException e) {
+        }
+        return "127.0.0.1";
+    }
+
+    /**
+     * 获取主机名
+     *
+     * @return 本地主机名
+     */
+    public static String getHostName() {
+        try {
+            return InetAddress.getLocalHost().getHostName();
+        } catch (UnknownHostException e) {
+        }
+        return "未知";
+    }
+
+    /**
+     * 从多级反向代理中获得第一个非unknown IP地址
+     *
+     * @param ip 获得的IP地址
+     * @return 第一个非unknown IP地址
+     */
+    public static String getMultistageReverseProxyIp(String ip) {
+        // 多级反向代理检测
+        if (ip != null && ip.indexOf(",") > 0) {
+            final String[] ips = ip.trim().split(",");
+            for (String subIp : ips) {
+                if (false == isUnknown(subIp)) {
+                    ip = subIp;
+                    break;
+                }
+            }
+        }
+        return ip;
+    }
+
+    /**
+     * 检测给定字符串是否为未知,多用于检测HTTP请求相关
+     *
+     * @param checkString 被检测的字符串
+     * @return 是否未知
+     */
+    public static boolean isUnknown(String checkString) {
+        return StringUtils.isBlank(checkString) || "unknown".equalsIgnoreCase(checkString);
+    }
+}

+ 11 - 0
src/main/java/com/nh/farm/cloud/util/push/PushConfig.java

@@ -0,0 +1,11 @@
+package com.nh.farm.cloud.util.push;
+
+public class PushConfig {
+
+	public static final String appId = "F72rqsm8Nh5F1UTELt8hA3";
+	public static final String appKey = "B1JYQPvDXCAIkRSs5zfwa9";
+	public static final String masterSecret = "H8tmjRqrxE6Obf0hHcOgD8";
+	public static final String host = "http://sdk.open.api.igexin.com/apiex.htm";
+
+
+}

+ 23 - 0
src/main/java/com/nh/farm/cloud/util/redis/CacheConstants.java

@@ -0,0 +1,23 @@
+package com.nh.farm.cloud.util.redis;
+
+/**
+ * 缓存的key 常量
+ */
+public class CacheConstants
+{
+
+    /**
+     * 缓存有效期,默认720(分钟)
+     */
+    public final static long EXPIRATION = 600;
+
+    /**
+     * 缓存刷新时间,默认120(分钟)
+     */
+    public final static long REFRESH_TIME = 240;
+
+    /**
+     * 权限缓存前缀
+     */
+    public final static String LOGIN_TOKEN_KEY = "login_tokens:";
+}

+ 246 - 0
src/main/java/com/nh/farm/cloud/util/redis/RedisCacheUtil.java

@@ -0,0 +1,246 @@
+package com.nh.farm.cloud.util.redis;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.BoundSetOperations;
+import org.springframework.data.redis.core.HashOperations;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.ValueOperations;
+import org.springframework.data.redis.serializer.RedisSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+import org.springframework.stereotype.Component;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * spring redis 工具类
+ **/
+@SuppressWarnings(value = { "unchecked", "rawtypes" })
+@Component
+public class RedisCacheUtil
+{
+    public RedisTemplate redisTemplate;
+
+    /**
+     * 解决redis存储key乱码问题
+     */
+    @Autowired(required = false)
+    public void setRedisTemplate(RedisTemplate redisTemplate) {
+
+        RedisSerializer stringSerializer = new StringRedisSerializer();
+        redisTemplate.setKeySerializer(stringSerializer);
+       // redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
+        redisTemplate.setHashKeySerializer(stringSerializer);
+      //  redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
+        this.redisTemplate = redisTemplate;
+    }
+    public RedisTemplate getRedisTemplate() {
+        return this.redisTemplate;
+    }
+    /**
+     * 缓存基本的对象,Integer、String、实体类等
+     *
+     * @param key 缓存的键值
+     * @param value 缓存的值
+     */
+    public <T> void setCacheObject(final String key, final T value)
+    {
+        redisTemplate.opsForValue().set(key, value);
+    }
+
+    /**
+     * 缓存基本的对象,Integer、String、实体类等
+     *
+     * @param key 缓存的键值
+     * @param value 缓存的值
+     * @param timeout 时间
+     * @param timeUnit 时间颗粒度
+     */
+    public  <T> void setCacheObject(final String key, final T value, final Long timeout, final TimeUnit timeUnit)
+    {
+        redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
+    }
+
+    /**
+     * 设置有效时间
+     *
+     * @param key Redis键
+     * @param timeout 超时时间
+     * @return true=设置成功;false=设置失败
+     */
+    public boolean expire(final String key, final long timeout)
+    {
+        return expire(key, timeout, TimeUnit.SECONDS);
+    }
+
+    /**
+     * 设置有效时间
+     *
+     * @param key Redis键
+     * @param timeout 超时时间
+     * @param unit 时间单位
+     * @return true=设置成功;false=设置失败
+     */
+    public boolean expire(final String key, final long timeout, final TimeUnit unit)
+    {
+        return Boolean.TRUE.equals(redisTemplate.expire(key, timeout, unit));
+    }
+
+    /**
+     * 获得缓存的基本对象。
+     *
+     * @param key 缓存键值
+     * @return 缓存键值对应的数据
+     */
+    public  <T> T getCacheObject(final String key)
+    {
+        ValueOperations<String, T> operation = redisTemplate.opsForValue();
+        return operation.get(key);
+    }
+
+    /**
+     * 删除单个对象
+     *
+     */
+    public  boolean deleteObject(final String key)
+    {
+        return Boolean.TRUE.equals(redisTemplate.delete(key));
+    }
+
+    /**
+     * 删除集合对象
+     *
+     * @param collection 多个对象
+     */
+    public long deleteObject(final Collection collection)
+    {
+        return redisTemplate.delete(collection);
+    }
+
+    /**
+     * 缓存List数据
+     *
+     * @param key 缓存的键值
+     * @param dataList 待缓存的List数据
+     * @return 缓存的对象
+     */
+    public <T> long setCacheList(final String key, final List<T> dataList)
+    {
+        Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
+        return count == null ? 0 : count;
+    }
+
+    /**
+     * 获得缓存的list对象
+     *
+     * @param key 缓存的键值
+     * @return 缓存键值对应的数据
+     */
+    public <T> List<T> getCacheList(final String key)
+    {
+        return redisTemplate.opsForList().range(key, 0, -1);
+    }
+
+    /**
+     * 缓存Set
+     *
+     * @param key 缓存键值
+     * @param dataSet 缓存的数据
+     * @return 缓存数据的对象
+     */
+    public <T> BoundSetOperations<String, T> setCacheSet(final String key, final Set<T> dataSet)
+    {
+        BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);
+        for (T t : dataSet) {
+            setOperation.add(t);
+        }
+        return setOperation;
+    }
+
+    /**
+     * 获得缓存的set
+     *
+     */
+    public <T> Set<T> getCacheSet(final String key)
+    {
+        return redisTemplate.opsForSet().members(key);
+    }
+
+    /**
+     * 缓存Map
+     *
+     */
+    public <T> void setCacheMap(final String key, final Map<String, T> dataMap)
+    {
+        if (dataMap != null) {
+            redisTemplate.opsForHash().putAll(key, dataMap);
+        }
+    }
+
+    /**
+     * 获得缓存的Map
+     *
+     */
+    public <T> Map<String, T> getCacheMap(final String key)
+    {
+        return redisTemplate.opsForHash().entries(key);
+    }
+
+    /**
+     * 往Hash中存入数据
+     *
+     * @param key Redis键
+     * @param hKey Hash键
+     * @param value 值
+     */
+    public <T> void setCacheMapValue(final String key, final String hKey, final T value)
+    {
+        redisTemplate.opsForHash().put(key, hKey, value);
+    }
+
+    /**
+     * 获取Hash中的数据
+     *
+     * @param key Redis键
+     * @param hKey Hash键
+     * @return Hash中的对象
+     */
+    public <T> T getCacheMapValue(final String key, final String hKey)
+    {
+        HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();
+        return opsForHash.get(key, hKey);
+    }
+
+    /**
+     * 获取多个Hash中的数据
+     *
+     * @param key Redis键
+     * @param hKeys Hash键集合
+     * @return Hash对象集合
+     */
+    public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys)
+    {
+        return redisTemplate.opsForHash().multiGet(key, hKeys);
+    }
+
+
+    /**
+     * 是否存在key
+     *
+     */
+    public Boolean hasKey(String key) {
+        return redisTemplate.hasKey(key);
+    }
+
+    /**
+     * 查找匹配的key
+     *
+     */
+    public Set<String> keys(String pattern) {
+        return redisTemplate.keys(pattern);
+    }
+
+}

+ 191 - 0
src/main/java/com/nh/farm/cloud/util/redis/TokenUtil.java

@@ -0,0 +1,191 @@
+package com.nh.farm.cloud.util.redis;
+
+import com.nh.farm.cloud.basic.entity.LoginUser;
+import com.nh.farm.cloud.basic.entity.UserEntity;
+import com.nh.farm.cloud.util.ServletUtils;
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Jwts;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * token验证处理
+ */
+@Component
+public class TokenUtil {
+    @Autowired
+    private RedisCacheUtil redisCacheUtil;
+
+    protected static final long MILLIS_SECOND = 1000;
+
+    protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;
+
+    private final static long expireTime = CacheConstants.EXPIRATION;
+
+    private final static String ACCESS_TOKEN = CacheConstants.LOGIN_TOKEN_KEY;
+
+    private final static Long MILLIS_MINUTE_TEN = CacheConstants.REFRESH_TIME * MILLIS_MINUTE;
+
+    /**
+     * 获取用户身份信息
+     *
+     * @return 用户信息
+     */
+    public LoginUser getLoginUser(HttpServletRequest request) {
+        // 获取请求携带的令牌
+        String token = getToken(request);
+        if (StringUtils.isNotEmpty(token)) {
+            Claims claims = parseToken(token);
+            // 解析对应的权限以及用户信息
+            String uuid = (String) claims.get(ACCESS_TOKEN);
+            String userKey = getTokenKey(uuid);
+            return redisCacheUtil.getCacheObject(userKey);
+        }
+        return null;
+    }
+
+    /**
+     * 设置用户身份信息
+     */
+    public void setLoginUser(LoginUser loginUser) {
+        if (loginUser != null && StringUtils.isNotEmpty(loginUser.getToken())) {
+            refreshToken(loginUser);
+        }
+    }
+
+
+
+    /**
+     * 验证令牌有效期,相差不足20分钟,自动刷新缓存
+     */
+    public void verifyToken(LoginUser loginUser) {
+        long expireTime = loginUser.getExpireTime();
+        long currentTime = System.currentTimeMillis();
+        if (expireTime - currentTime <= MILLIS_MINUTE_TEN) {
+            refreshToken(loginUser);
+        }
+    }
+
+    /**
+     * 刷新令牌有效期
+     *
+     * @param loginUser 登录信息
+     */
+    public void refreshToken(LoginUser loginUser) {
+        loginUser.setLoginTime(System.currentTimeMillis());
+        loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE);
+        // 根据uuid将loginUser缓存
+        String userKey = getTokenKey(loginUser.getToken());
+        redisCacheUtil.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
+    }
+
+    /**
+     * 从令牌中获取数据声明
+     *
+     * @param token 令牌
+     * @return 数据声明
+     */
+    private Claims parseToken(String token) {
+        return Jwts.parser()
+                .setSigningKey("nhtccmcrocommonbasicsecret")
+                .parseClaimsJws(token)
+                .getBody();
+    }
+
+
+    /**
+     * 从令牌中获取用户名
+     *
+     * @param token 令牌
+     * @return 用户名
+     */
+    public String getUsernameFromToken(String token) {
+        Claims claims = parseToken(token);
+        return claims.getSubject();
+    }
+
+    /**
+     * 获取请求token 加密
+     *
+     * @return token
+     */
+    public String getToken(HttpServletRequest request) {
+        String token = request.getHeader("authorization");
+
+        if (StringUtils.isNotEmpty(token) && token.startsWith("Bearer ")) {
+            token = token.replace("Bearer ", "");
+            return token;
+        }
+        return null;
+    }
+
+    private String getTokenKey(String uuid) {
+        return ACCESS_TOKEN + uuid;
+    }
+
+
+
+    /**
+     * 查询当前登陆人信息
+     *
+     * @return true 是
+     */
+    public UserEntity getUser() {
+
+        return this.getLoginUser(ServletUtils.getRequest()).getSysUser();
+    }
+    /**
+     * 查询当前登陆人是否为管理员
+     *
+     * @return true 是
+     */
+    public Boolean getIsAdmin() {
+
+        return this.getLoginUser(ServletUtils.getRequest()).getSysUser().getIsAdmin();
+    }
+
+    /**
+     * 查询当前登陆人的用户id
+     */
+    public String getUsername() {
+
+        return this.getLoginUser(ServletUtils.getRequest()).getSysUser().getUsername();
+    }
+
+    /**
+     * 查询当前登陆人的名称
+     */
+    public String getNickName() {
+
+        return this.getLoginUser(ServletUtils.getRequest()).getSysUser().getNickName();
+    }
+
+    /**
+     * 查询当前登陆人的名称
+     */
+    public String getBankCode() {
+
+        return this.getLoginUser(ServletUtils.getRequest()).getSysUser().getBankCode();
+    }
+
+    /**
+     * 查询当前登陆人的名称
+     */
+    public String getKid() {
+        String kid = "519848949849";
+        try {
+            kid = this.getLoginUser(ServletUtils.getRequest()).getSysUser().getKid();
+        } catch (Exception e) {
+
+        }
+        return kid;
+    }
+
+    public Integer getBankLevel() {
+        return this.getLoginUser(ServletUtils.getRequest()).getBankLevel();
+    }
+}

+ 35 - 0
src/main/java/com/nh/farm/cloud/util/returnop/JsonUtil.java

@@ -0,0 +1,35 @@
+package com.nh.farm.cloud.util.returnop;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.nh.fk.common.base.exception.BusinessException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author 张智凯
+ * @version 1.0
+ * @data 2023/8/14 14:28
+ */
+@Component
+public class JsonUtil {
+    @Autowired
+    private ObjectMapper objectMapper;
+
+    public String writeValueAsString(Object value){
+        try {
+            return objectMapper.writeValueAsString(value);
+        } catch (JsonProcessingException e) {
+            throw new BusinessException(e);
+        }
+    }
+
+
+    public <T> T readValue(String content, Class<T> valueType){
+        try {
+           return objectMapper.readValue(content, valueType);
+        } catch (JsonProcessingException e) {
+            throw new BusinessException(e);
+        }
+    }
+}

+ 134 - 0
src/main/java/com/nh/farm/cloud/util/returnop/ReFlectUtil.java

@@ -0,0 +1,134 @@
+package com.nh.farm.cloud.util.returnop;
+
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.ObjectUtils;
+
+import java.lang.reflect.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+ 
+/**
+ * @class_name: ReFlectUtil
+ * @description:
+ * @author: wm_yu
+ * @create: 2019/07/19
+ **/
+public class ReFlectUtil {
+ 
+    /**
+     *反射获取List中的数据
+     * @param args
+     */
+    public static void main(String[] args) {
+       /* Teacher teacher = new Teacher();
+       List<Student> list = new ArrayList<Student>();
+        list.add(new Student("张三", "男"));
+        list.add(new Student("李四", "女"));
+        list.add(new Student("王五", "女"));
+       teacher.setList(list);
+        getList(teacher,Student.class);*/
+    }
+ 
+ 
+    /**
+     * 反射获取对象中的list数据
+     * @param object
+     * @param dateClass
+     * @param <T>
+     */
+    public static<T> void getList(Object object,T dateClass){
+       List<T> resultList = new ArrayList<>();
+        if(!ObjectUtils.isEmpty(object)){
+ 
+            Field[] fields = getAllFields(object.getClass());
+            Field[] filterList= filterField(fields);
+            Arrays.stream(filterList).forEach(var -> {
+                //List集合
+                if(List.class.isAssignableFrom(var.getType())){
+                    Type type = var.getGenericType();
+                    if(type instanceof ParameterizedType){
+                        if(!var.isAccessible()){
+                            var.setAccessible(true);
+                        }
+                        //获取到属性值的字节码
+                        try {
+                            Class<?> clzz = var.get(object).getClass();
+                            //反射调用获取到list的size方法来获取到集合的大小
+                            Method sizeMethod = clzz.getDeclaredMethod("size");
+                            if(!sizeMethod.isAccessible()){
+                                sizeMethod.setAccessible(true);
+                            }
+                            //集合长度
+                            int size = (int) sizeMethod.invoke(var.get(object));
+                            //循环遍历获取到数据
+                            for (int i = 0; i < size; i++) {
+                                //反射获取到list的get方法
+                                Method getMethod = clzz.getDeclaredMethod("get", int.class);
+                                //调用get方法获取数据
+                                if(!getMethod.isAccessible()){
+                                    getMethod.setAccessible(true);
+                                }
+                                T var1 = (T) getMethod.invoke(var.get(object), i);
+                                resultList.add(var1);
+                            }
+ 
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                        }
+                    }
+                }
+            });
+ 
+            resultList.stream().forEach(var -> {
+                System.out.println("反射获取到的数据是什么:" + var);
+            });
+        }
+    }
+
+ 
+    /**
+     * 反射获取所有的字段
+     * @param c
+     * @return
+     */
+    public static Field[] getAllFields(Class c){
+        List<Field> fieldList = new ArrayList<>();
+        while (c!= null){
+            fieldList.addAll(new ArrayList<>(Arrays.asList(c.getDeclaredFields())));
+            c= c.getSuperclass();
+        }
+        Field[] fields = new Field[fieldList.size()];
+        fieldList.toArray(fields);
+        return fields;
+    }
+ 
+ 
+ 
+ 
+ 
+    /**
+     * 过滤字段
+     * @param
+     * @return
+     */
+    public static Field[] filterField(Field[] fields){
+        List<Field> tempList = Arrays.stream(fields).filter(field -> null != field
+                && !Modifier.isFinal(field.getModifiers())
+                && !Modifier.isStatic(field.getModifiers())
+                && !Modifier.isAbstract(field.getModifiers())).collect(Collectors.toList());
+ 
+ 
+        int arrLength = CollectionUtils.isEmpty(tempList) ? 1:tempList.size();
+ 
+        Field[] resultArr = new Field[arrLength];
+        if(!CollectionUtils.isEmpty(tempList)){
+            tempList.toArray(resultArr);
+        }
+        return resultArr;
+    }
+ 
+ 
+ 
+}

+ 17 - 0
src/main/java/com/nh/farm/cloud/util/returnop/anno/NotSet.java

@@ -0,0 +1,17 @@
+package com.nh.farm.cloud.util.returnop.anno;
+
+import java.lang.annotation.*;
+
+/**
+ * 对属性不处理 注解
+ * 被标注的类或属性不会被工具类处理
+ * @author 张智凯
+ * @version 1.0
+ * @data 2023/9/22 14:46
+ */
+@Target({ElementType.FIELD,ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface NotSet {
+    String[] value() default {};
+}

+ 108 - 0
src/main/java/com/nh/farm/cloud/util/token/AseController.java

@@ -0,0 +1,108 @@
+package com.nh.farm.cloud.util.token;
+
+import org.apache.commons.codec.binary.Base64;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.crypto.Cipher;
+import java.security.*;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.HashMap;
+import java.util.Map;
+
+
+@RestController
+public class AseController {
+	
+
+	private static Map<Integer, String> keyMap = new HashMap<Integer, String>();  //用于封装随机产生的公钥与私钥
+
+	@GetMapping("/getAse")
+	public String Ase()  throws Exception{
+		//生成公钥和私钥
+		genKeyPair();
+		//加密字符串
+		//String message = "df723820";
+		System.out.println("随机生成的公钥为:" + keyMap.get(0));
+		return keyMap.get(0);
+	}
+	//解密
+	public static String getAsejm(String str)  throws Exception{
+		String messageDe = decrypt(str,keyMap.get(1));
+		System.out.println("还原后的字符串为:" + messageDe);
+		return messageDe;
+	}
+	
+
+	/** 
+	 * 随机生成密钥对 
+	 * @throws NoSuchAlgorithmException 
+	 */  
+	public static void genKeyPair() throws NoSuchAlgorithmException {  
+		// KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象  
+		KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");  
+		// 初始化密钥对生成器,密钥大小为96-1024位  
+		keyPairGen.initialize(2048,new SecureRandom());  
+		// 生成一个密钥对,保存在keyPair中  
+		KeyPair keyPair = keyPairGen.generateKeyPair();  
+		RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();   // 得到私钥  
+		RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();  // 得到公钥  
+		String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));  
+		// 得到私钥字符串  
+		String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded())));  
+		// 将公钥和私钥保存到Map
+		keyMap.put(0,publicKeyString);  //0表示公钥
+		keyMap.put(1,privateKeyString);  //1表示私钥
+	}  
+	/** 
+	 * RSA公钥加密 
+	 *  
+	 * @param str 
+	 *            加密字符串
+	 * @param publicKey 
+	 *            公钥 
+	 * @return 密文 
+	 * @throws Exception 
+	 *             加密过程中的异常信息 
+	 */  
+	public static String encrypt( String str, String publicKey ) throws Exception{
+		//base64编码的公钥
+		byte[] decoded = Base64.decodeBase64(publicKey);
+		RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
+		//RSA加密
+		Cipher cipher = Cipher.getInstance("RSA");
+		cipher.init(Cipher.ENCRYPT_MODE, pubKey);
+		String outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes("UTF-8")));
+		return outStr;
+	}
+
+	/** 
+	 * RSA私钥解密
+	 *  
+	 * @param str 
+	 *            加密字符串
+	 * @param privateKey 
+	 *            私钥 
+	 * @return 铭文
+	 * @throws Exception 
+	 *             解密过程中的异常信息 
+	 */  
+	public static String decrypt(String str, String privateKey) throws Exception{
+		//64位解码加密后的字符串
+		byte[] inputByte = Base64.decodeBase64(str.getBytes("UTF-8"));
+		//base64编码的私钥
+		byte[] decoded = Base64.decodeBase64(privateKey);  
+        RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));  
+		//RSA解密
+		Cipher cipher = Cipher.getInstance("RSA");
+		cipher.init(Cipher.DECRYPT_MODE, priKey);
+		String outStr = new String(cipher.doFinal(inputByte));
+		return outStr;
+	}
+
+
+
+}

+ 16 - 0
src/main/java/com/nh/farm/cloud/util/token/TokenCheck.java

@@ -0,0 +1,16 @@
+package com.nh.farm.cloud.util.token;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 避免重复提交
+ * 
+ * @author 冯晓东
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface TokenCheck {
+
+}

+ 79 - 0
src/main/java/com/nh/farm/cloud/util/tree/AuthTreeTools.java

@@ -0,0 +1,79 @@
+package com.nh.farm.cloud.util.tree;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 
+ * @author 冯晓东 398479251@qq.com
+ *
+ */
+public class AuthTreeTools {
+
+	/**
+	 * 预处理树节点
+	 * 
+	 * @param menuList
+	 * @param isChecked
+	 * @return
+	 */
+	private static JSONArray handleTree(JSONArray menuList, boolean isChecked) {
+		for (int i = 0; i < menuList.size(); i++) {
+			JSONObject map = menuList.getJSONObject(i);
+			map.put("key", map.getString("code"));
+			map.put("value", map.getString("code"));
+			map.put("title", map.getString("name"));
+			if (isChecked) {
+				map.put("checked", false);
+			}
+		}
+		return menuList;
+	}
+
+	
+	public static List<Map<String, Object>> turnListToTree(JSONArray menuList) {
+		// 转换List为树形结构
+		return turnListToTree(menuList, false);
+	}
+
+	@SuppressWarnings("unchecked")
+	public static List<Map<String, Object>> turnListToTree(JSONArray menuList, boolean isChecked) {
+		// 转换List为树形结构
+		menuList = handleTree(menuList, isChecked);
+
+		List<Map<String, Object>> nodeList = new ArrayList<Map<String, Object>>();
+
+		for (int i = 0; i < menuList.size(); i++) {
+			JSONObject node1 = menuList.getJSONObject(i);
+			String node1_code = (String) node1.get("code");
+			String node1_parent_code = node1_code.substring(0, node1_code.length() - 3);
+
+			boolean mark = false;
+			for (int j = 0; j < menuList.size(); j++) {
+				Map<String, Object> node2 = menuList.getJSONObject(j);
+				String node2_code = (String) node2.get("code");
+
+				if (node1_parent_code != null && node1_parent_code.equals(node2_code)) {
+					mark = true;
+					if (node2.get("children") == null) {
+						node2.put("children", new ArrayList<Map<String, Object>>());
+					}
+					((List<Map<String, Object>>) node2.get("children")).add(node1);
+					node2.put("leaf", false);
+					if (!isChecked) {
+						node2.put("expanded", false);
+					}
+					break;
+				}
+			}
+			if (!mark) {
+				nodeList.add(node1);
+			}
+		}
+		return nodeList;
+	}
+}

+ 169 - 0
src/main/java/com/nh/farm/cloud/util/tree/TreeTools.java

@@ -0,0 +1,169 @@
+package com.nh.farm.cloud.util.tree;
+
+import com.nh.fk.common.util.JsonUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class TreeTools {
+
+	public static void main(String[] args) {
+
+	}
+
+	// 预处理树节点
+	public static List<Map<String, Object>> handleTree(List<Map<String, Object>> menuList) {
+		return handleTree(menuList, false);
+	}
+
+	// 预处理树节点
+	public static List<Map<String, Object>> handleTree(List<Map<String, Object>> menuList, boolean isChecked) {
+		for (Map<String, Object> map : menuList) {
+			map.put("id", map.get("subjectCode"));
+			map.put("initialMoney", map.get("initialMoney"));
+			map.put("deptName", map.get("deptName"));
+			map.put("iconCls", map.get("url"));
+			map.put("text", map.get("subjectName"));
+			map.put("leaf", true);
+		}
+		return menuList;
+	}
+
+	// 预处理地区树节点
+	public static List<Map<String, Object>> handleTree_area(List<Map<String, Object>> menuList) {
+		return handleTree_area(menuList, false);
+	}
+
+	// 预处理地区树节点
+	public static List<Map<String, Object>> handleTree_area(List<Map<String, Object>> menuList, boolean isChecked) {
+		for (Map<String, Object> map : menuList) {
+			map.put("id", map.get("subjectCode"));
+			map.put("iconCls", map.get("url"));
+			map.put("text", map.get("subjectName"));
+			map.put("code_area", map.get("subjectCode"));
+			map.put("leaf", true);
+			map.put("checked", false);
+		}
+		return menuList;
+	}
+
+	public static String turnListToTree(List<Map<String, Object>> menuList) {
+		// TODO 转换List为树形结构
+		return turnListToTree(menuList, false);
+	}
+
+	@SuppressWarnings("unchecked")
+	public static String turnListToTree(List<Map<String, Object>> menuList, boolean isChecked) {
+		// TODO 转换List为树形结构
+		menuList = handleTree(menuList, isChecked);
+
+		List<Map<String, Object>> nodeList = new ArrayList<>();
+		for (Map<String, Object> node1 : menuList) {
+			String node1_code = (String) node1.get("subjectCode");
+			String node1_parent_code = node1_code.substring(0, node1_code.length() - 3);
+
+			boolean mark = false;
+			for (Map<String, Object> node2 : menuList) {
+				String node2_code = (String) node2.get("subjectCode");
+
+				if (node1_parent_code.equals(node2_code)) {
+					mark = true;
+					node2.computeIfAbsent("children", k -> new ArrayList<Map<String, Object>>());
+					((List<Map<String, Object>>) node2.get("children")).add(node1);
+					node2.put("leaf", false);
+					if (!isChecked) {
+						node2.put("expanded", false);
+					}
+					break;
+				}
+			}
+			if (!mark) {
+				nodeList.add(node1);
+			}
+		}
+		return JsonUtil.toJson(nodeList);
+	}
+	
+	
+	
+
+	public static String turnListToTree_area(List<Map<String, Object>> menuList) {
+		// TODO 转换List为树形结构
+		return turnListToTree_area(menuList, false);
+	}
+
+	@SuppressWarnings("unchecked")
+	public static String turnListToTree_area(List<Map<String, Object>> menuList, boolean isChecked) {
+		// TODO 转换List为树形结构
+		menuList = handleTree_area(menuList, isChecked);
+
+		List<Map<String, Object>> nodeList = new ArrayList<>();
+		for (Map<String, Object> node1 : menuList) {
+			String node1_code = (String) node1.get("subjectCode");
+			String node1_parent_code = node1_code.substring(0, node1_code.length() - 3);
+
+			boolean mark = false;
+			for (Map<String, Object> node2 : menuList) {
+				String node2_code = (String) node2.get("subjectCode");
+
+				if (node1_parent_code != null && node1_parent_code.equals(node2_code)) {
+					mark = true;
+					if (node2.get("children") == null) {
+						node2.put("children", new ArrayList<Map<String, Object>>());
+					}
+					((List<Map<String, Object>>) node2.get("children")).add(node1);
+					node2.put("leaf", false);
+					if (!isChecked) {
+						node2.put("expanded", false);
+					}
+					break;
+				}
+			}
+			if (!mark) {
+				nodeList.add(node1);
+			}
+		}
+		return JsonUtil.toJson(nodeList);
+	}
+
+	// 预处理树节点
+	public static List<Map<String, Object>> handleAreaTree(List<Map<String, Object>> menuList, boolean isChecked,
+			int deep) {
+		for (Map<String, Object> map : menuList) {
+			map.put("id", map.remove("subjectCode"));
+			map.put("iconCls", map.remove("bankCode"));
+			map.put("text", map.remove("subjectName"));
+			if (deep == 3) {
+				map.put("leaf", true);
+
+			} else {
+				map.put("leaf", false);
+			}
+
+			if (isChecked) {
+				map.put("checked", false);
+			}
+		}
+		return menuList;
+	}
+	
+	public static List<Map<String, Object>> handle_paramNo(List<Map<String, Object>> menuslist,boolean isChecked) {
+		
+		for (Map<String, Object> map : menuslist) {
+			//String a = map.get("status").toString();
+			//if("0".equals(a)) {
+			map.put("id", map.get("subjectCode"));
+			map.put("iconCls", map.get("url"));
+			map.put("text", map.get("subjectName"));
+			map.put("code_area", map.get("subjectCode"));
+			map.put("leaf", true);
+			 if (isChecked) {
+				    map.put("checked", false);
+				 //  }
+		}
+	}
+		return menuslist;
+	}
+
+}

+ 48 - 0
src/main/java/com/nh/farm/cloud/util/tree/TreeUtil.java

@@ -0,0 +1,48 @@
+package com.nh.farm.cloud.util.tree;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+
+public class TreeUtil {
+	public static JSONArray listToTree(JSONArray arr,String CODE,String UPCODE,String child){
+	   JSONArray r = new JSONArray();
+	   JSONObject hash = new JSONObject();
+	   //将数组转为Object的形式,key为数组中的id
+	   for(int i=0;i<arr.size();i++){
+	      JSONObject json = (JSONObject) arr.get(i);
+	      hash.put(json.getString(CODE), json);
+	   }
+	   //遍历结果集
+	   for(int j=0;j<arr.size();j++){
+	      //单条记录
+	      JSONObject aVal = (JSONObject) arr.get(j);
+	      //在hash中取出key为单条记录中pid的值
+	      JSONObject hashVP = (JSONObject) hash.get(aVal.get(UPCODE).toString());
+	      //如果记录的pid存在,则说明它有父节点,将她添加到孩子节点的集合中
+	      if(hashVP!=null){
+	         //检查是否有child属性
+	         if(hashVP.get(child)!=null){
+	            JSONArray ch = (JSONArray) hashVP.get(child);
+	            ch.add(aVal);
+	            hashVP.put(child, ch);
+	         }else{
+	            JSONArray ch = new JSONArray();
+	            ch.add(aVal);
+	            hashVP.put(child, ch);
+	         }
+	      }else{
+	         r.add(aVal);
+	      }
+	   }
+	   return r;
+	}
+	
+	public static void main(String[] args) {
+		
+		
+		JSONObject hash = new JSONObject();
+		System.out.println(hash);
+
+	}
+
+}

+ 0 - 0
src/main/resources/application-prod.yml


Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff