فهرست منبع

初始化项目

haobing 2 سال پیش
والد
کامیت
010e7c3b46
91فایلهای تغییر یافته به همراه8463 افزوده شده و 0 حذف شده
  1. 207 0
      pom.xml
  2. 13 0
      src/main/java/cn/aiyangniu/api/AppStart.java
  3. 23 0
      src/main/java/cn/aiyangniu/api/common/config/CorsConfig.java
  4. 27 0
      src/main/java/cn/aiyangniu/api/common/config/CustomizationBean.java
  5. 41 0
      src/main/java/cn/aiyangniu/api/common/config/PageConfig.java
  6. 40 0
      src/main/java/cn/aiyangniu/api/common/config/RedisConfig.java
  7. 46 0
      src/main/java/cn/aiyangniu/api/common/config/RedisSerialize.java
  8. 102 0
      src/main/java/cn/aiyangniu/api/common/config/SwaggerConfig.java
  9. 39 0
      src/main/java/cn/aiyangniu/api/common/entity/system/AuthEntity.java
  10. 26 0
      src/main/java/cn/aiyangniu/api/common/entity/system/SysAreaEntity.java
  11. 16 0
      src/main/java/cn/aiyangniu/api/common/entity/system/SysAreaVo.java
  12. 38 0
      src/main/java/cn/aiyangniu/api/common/entity/system/SysBtnEntity.java
  13. 19 0
      src/main/java/cn/aiyangniu/api/common/entity/system/SysBtnVo.java
  14. 49 0
      src/main/java/cn/aiyangniu/api/common/entity/system/SysModEntity.java
  15. 16 0
      src/main/java/cn/aiyangniu/api/common/entity/system/SysModVo.java
  16. 30 0
      src/main/java/cn/aiyangniu/api/common/entity/system/SysMsgDetail.java
  17. 31 0
      src/main/java/cn/aiyangniu/api/common/entity/system/SysMsgEntity.java
  18. 23 0
      src/main/java/cn/aiyangniu/api/common/entity/system/SysMsgVo.java
  19. 37 0
      src/main/java/cn/aiyangniu/api/common/entity/system/SysOptEntity.java
  20. 19 0
      src/main/java/cn/aiyangniu/api/common/entity/system/SysOptVo.java
  21. 27 0
      src/main/java/cn/aiyangniu/api/common/entity/system/SysRelEntity.java
  22. 31 0
      src/main/java/cn/aiyangniu/api/common/entity/system/SysRoleEntity.java
  23. 20 0
      src/main/java/cn/aiyangniu/api/common/entity/system/SysRoleVo.java
  24. 53 0
      src/main/java/cn/aiyangniu/api/common/entity/system/SysTypeEntity.java
  25. 20 0
      src/main/java/cn/aiyangniu/api/common/entity/system/SysTypeVo.java
  26. 26 0
      src/main/java/cn/aiyangniu/api/common/entity/system/SysUserDto.java
  27. 48 0
      src/main/java/cn/aiyangniu/api/common/entity/system/SysUserEntity.java
  28. 26 0
      src/main/java/cn/aiyangniu/api/common/entity/system/SysUserVo.java
  29. 108 0
      src/main/java/cn/aiyangniu/api/common/util/AuthUtil.java
  30. 172 0
      src/main/java/cn/aiyangniu/api/common/util/CharacterFiltUtil.java
  31. 31 0
      src/main/java/cn/aiyangniu/api/common/util/ClientIpUtil.java
  32. 60 0
      src/main/java/cn/aiyangniu/api/common/util/ClientMacUtil.java
  33. 265 0
      src/main/java/cn/aiyangniu/api/common/util/DateUtil.java
  34. 74 0
      src/main/java/cn/aiyangniu/api/common/util/DecryptUtil.java
  35. 96 0
      src/main/java/cn/aiyangniu/api/common/util/EncryptUtil.java
  36. 111 0
      src/main/java/cn/aiyangniu/api/common/util/HttpRequest.java
  37. 180 0
      src/main/java/cn/aiyangniu/api/common/util/ImgUtil.java
  38. 75 0
      src/main/java/cn/aiyangniu/api/common/util/Md5Util.java
  39. 15 0
      src/main/java/cn/aiyangniu/api/common/util/MyX509TrustManager.java
  40. 55 0
      src/main/java/cn/aiyangniu/api/common/util/PinyinUtil.java
  41. 45 0
      src/main/java/cn/aiyangniu/api/common/util/RandomUtil.java
  42. 86 0
      src/main/java/cn/aiyangniu/api/common/util/RedisUtil.java
  43. 58 0
      src/main/java/cn/aiyangniu/api/common/util/UUIDUtil.java
  44. 89 0
      src/main/java/cn/aiyangniu/api/controller/other/CheckcodeController.java
  45. 85 0
      src/main/java/cn/aiyangniu/api/controller/other/OtherController.java
  46. 287 0
      src/main/java/cn/aiyangniu/api/controller/other/UploadController.java
  47. 79 0
      src/main/java/cn/aiyangniu/api/controller/system/SysAreaController.java
  48. 289 0
      src/main/java/cn/aiyangniu/api/controller/system/SysBtnController.java
  49. 366 0
      src/main/java/cn/aiyangniu/api/controller/system/SysModController.java
  50. 262 0
      src/main/java/cn/aiyangniu/api/controller/system/SysMsgController.java
  51. 338 0
      src/main/java/cn/aiyangniu/api/controller/system/SysOptController.java
  52. 292 0
      src/main/java/cn/aiyangniu/api/controller/system/SysRoleController.java
  53. 349 0
      src/main/java/cn/aiyangniu/api/controller/system/SysTypeController.java
  54. 533 0
      src/main/java/cn/aiyangniu/api/controller/system/SysUserController.java
  55. 24 0
      src/main/java/cn/aiyangniu/api/mapper/system/SysAreaMapper.java
  56. 84 0
      src/main/java/cn/aiyangniu/api/mapper/system/SysBtnMapper.java
  57. 71 0
      src/main/java/cn/aiyangniu/api/mapper/system/SysModMapper.java
  58. 68 0
      src/main/java/cn/aiyangniu/api/mapper/system/SysMsgMapper.java
  59. 85 0
      src/main/java/cn/aiyangniu/api/mapper/system/SysOptMapper.java
  60. 68 0
      src/main/java/cn/aiyangniu/api/mapper/system/SysRoleMapper.java
  61. 72 0
      src/main/java/cn/aiyangniu/api/mapper/system/SysTypeMapper.java
  62. 93 0
      src/main/java/cn/aiyangniu/api/mapper/system/SysUserMapper.java
  63. 34 0
      src/main/java/cn/aiyangniu/api/service/impl/system/SysAreaServiceImpl.java
  64. 91 0
      src/main/java/cn/aiyangniu/api/service/impl/system/SysBtnServiceImpl.java
  65. 255 0
      src/main/java/cn/aiyangniu/api/service/impl/system/SysModServiceImpl.java
  66. 84 0
      src/main/java/cn/aiyangniu/api/service/impl/system/SysMsgServiceImpl.java
  67. 110 0
      src/main/java/cn/aiyangniu/api/service/impl/system/SysOptServiceImpl.java
  68. 93 0
      src/main/java/cn/aiyangniu/api/service/impl/system/SysRoleServiceImpl.java
  69. 230 0
      src/main/java/cn/aiyangniu/api/service/impl/system/SysTypeServiceImpl.java
  70. 126 0
      src/main/java/cn/aiyangniu/api/service/impl/system/SysUserServiceImpl.java
  71. 23 0
      src/main/java/cn/aiyangniu/api/service/system/SysAreaService.java
  72. 64 0
      src/main/java/cn/aiyangniu/api/service/system/SysBtnService.java
  73. 79 0
      src/main/java/cn/aiyangniu/api/service/system/SysModService.java
  74. 58 0
      src/main/java/cn/aiyangniu/api/service/system/SysMsgService.java
  75. 74 0
      src/main/java/cn/aiyangniu/api/service/system/SysOptService.java
  76. 65 0
      src/main/java/cn/aiyangniu/api/service/system/SysRoleService.java
  77. 71 0
      src/main/java/cn/aiyangniu/api/service/system/SysTypeService.java
  78. 90 0
      src/main/java/cn/aiyangniu/api/service/system/SysUserService.java
  79. 91 0
      src/main/resources/application-dev.yml
  80. 91 0
      src/main/resources/application-pro.yml
  81. 28 0
      src/main/resources/application.yml
  82. 5 0
      src/main/resources/banner.txt
  83. 104 0
      src/main/resources/logback-spring.xml
  84. 17 0
      src/main/resources/mapper/system/sysAreaMapper.xml
  85. 69 0
      src/main/resources/mapper/system/sysBtnMapper.xml
  86. 61 0
      src/main/resources/mapper/system/sysModMapper.xml
  87. 86 0
      src/main/resources/mapper/system/sysMsgMapper.xml
  88. 76 0
      src/main/resources/mapper/system/sysOptMapper.xml
  89. 59 0
      src/main/resources/mapper/system/sysRoleMapper.xml
  90. 66 0
      src/main/resources/mapper/system/sysTypeMapper.xml
  91. 105 0
      src/main/resources/mapper/system/sysUserMapper.xml

+ 207 - 0
pom.xml

@@ -0,0 +1,207 @@
+<?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>
+
+  <groupId>cn.aiyangniu</groupId>
+  <artifactId>provider-service</artifactId>
+  <version>1.0.0</version>
+
+  <properties>
+    <maven.compiler.source>8</maven.compiler.source>
+    <maven.compiler.target>8</maven.compiler.target>
+  </properties>
+
+  <!-- 继承SpringBoot父项目 -->
+  <parent>
+    <groupId>org.springframework.boot</groupId>
+    <artifactId>spring-boot-starter-parent</artifactId>
+    <version>2.7.5</version>
+  </parent>
+
+  <dependencies>
+    <!-- 导入starter-web项目 -->
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-web</artifactId>
+      <exclusions>
+        <exclusion>
+          <groupId>org.springframework.boot</groupId>
+          <artifactId>spring-boot-starter-tomcat</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-undertow</artifactId>
+    </dependency>
+
+    <!-- 导入单元测试的包 -->
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-test</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <!-- 导入druid包,配置druid配置 -->
+    <dependency>
+      <groupId>com.alibaba</groupId>
+      <artifactId>druid</artifactId>
+      <version>1.2.14</version>
+    </dependency>
+
+    <dependency>
+      <groupId>com.alibaba</groupId>
+      <artifactId>druid-spring-boot-starter</artifactId>
+      <version>1.2.14</version>
+    </dependency>
+
+    <!-- 导入Mybatis Plus包 -->
+    <dependency>
+      <groupId>com.baomidou</groupId>
+      <artifactId>mybatis-plus-boot-starter</artifactId>
+      <version>3.5.2</version>
+    </dependency>
+
+    <!-- 导入MySQL工具包 -->
+    <dependency>
+      <groupId>mysql</groupId>
+      <artifactId>mysql-connector-java</artifactId>
+      <version>8.0.31</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-data-redis</artifactId>
+      <version>2.7.5</version>
+    </dependency>
+
+    <!-- 导入FastJson工具包 -->
+    <dependency>
+      <groupId>com.alibaba</groupId>
+      <artifactId>fastjson</artifactId>
+      <version>2.0.17</version>
+    </dependency>
+
+    <!-- 导入pinyin4j工具包 -->
+    <dependency>
+      <groupId>com.belerweb</groupId>
+      <artifactId>pinyin4j</artifactId>
+      <version>2.5.1</version>
+    </dependency>
+
+    <!-- 导入getter/setter方法自动加载的包 -->
+    <dependency>
+      <groupId>org.projectlombok</groupId>
+      <artifactId>lombok</artifactId>
+      <version>1.18.24</version>
+    </dependency>
+
+    <!-- 导入通用上传commons-fileupload工具包 -->
+    <dependency>
+      <groupId>commons-fileupload</groupId>
+      <artifactId>commons-fileupload</artifactId>
+      <version>1.4</version>
+    </dependency>
+
+    <!-- 导入commons-io工具包 -->
+    <dependency>
+      <groupId>commons-io</groupId>
+      <artifactId>commons-io</artifactId>
+      <version>2.11.0</version>
+    </dependency>
+
+    <!-- 导入commons-lang3工具包 -->
+    <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-lang3</artifactId>
+      <version>3.12.0</version>
+    </dependency>
+
+    <!-- 导入slf4j-api工具包 -->
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+      <version>1.7.30</version>
+    </dependency>
+
+    <!-- 导入logback-core工具包 -->
+    <dependency>
+      <groupId>ch.qos.logback</groupId>
+      <artifactId>logback-core</artifactId>
+      <version>1.2.3</version>
+    </dependency>
+
+    <!-- 导入logback-classic工具包 -->
+    <dependency>
+      <groupId>ch.qos.logback</groupId>
+      <artifactId>logback-classic</artifactId>
+      <version>1.2.3</version>
+    </dependency>
+
+    <!--swagger3-->
+    <dependency>
+      <groupId>io.springfox</groupId>
+      <artifactId>springfox-boot-starter</artifactId>
+      <version>3.0.0</version>
+    </dependency>
+  </dependencies>
+
+  <profiles>
+    <profile>
+      <id>dev</id>
+      <properties>
+        <profile>dev</profile>
+      </properties>
+      <activation>
+        <!-- 默认环境 -->
+        <activeByDefault>true</activeByDefault>
+      </activation>
+    </profile>
+    <profile>
+      <id>pro</id>
+      <properties>
+        <profile>pro</profile>
+      </properties>
+    </profile>
+  </profiles>
+
+  <build>
+    <!-- 产生的构件的文件名,默认值是${artifactId}-${version} -->
+    <finalName>service_api</finalName>
+    <plugins>
+      <!-- 控制jdk版本 -->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>3.10.1</version>
+        <configuration>
+          <source>1.8</source>
+          <target>1.8</target>
+          <encoding>UTF-8</encoding>
+          <compilerArguments>
+            <verbose />
+            <bootclasspath>${java.home}/lib/rt.jar:${java.home}/lib/jce.jar</bootclasspath>
+          </compilerArguments>
+        </configuration>
+      </plugin>
+
+      <!-- 导入生成Jar文件插件,可以将应用打包成一个可执行的Jar包,直接使用java -jar命令执行 -->
+      <plugin>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-maven-plugin</artifactId>
+      </plugin>
+    </plugins>
+    <resources>
+      <resource>
+        <directory>src/main/resources</directory>
+        <includes>
+          <include>**/*.*</include>
+        </includes>
+        <filtering>true</filtering>
+      </resource>
+    </resources>
+  </build>
+
+</project>

+ 13 - 0
src/main/java/cn/aiyangniu/api/AppStart.java

@@ -0,0 +1,13 @@
+package cn.aiyangniu.api;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import springfox.documentation.oas.annotations.EnableOpenApi;
+
+@EnableOpenApi
+@SpringBootApplication
+public class AppStart {
+    public static void main(String[] args) {
+        SpringApplication.run(AppStart.class, args);
+    }
+}

+ 23 - 0
src/main/java/cn/aiyangniu/api/common/config/CorsConfig.java

@@ -0,0 +1,23 @@
+package cn.aiyangniu.api.common.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.CorsRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+/**
+ * 解决跨域请求的配置类
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+@Configuration
+public class CorsConfig implements WebMvcConfigurer {
+
+    @Override
+    public void addCorsMappings(CorsRegistry registry) {
+        registry.addMapping("/**")
+                .allowedOrigins("*")
+                .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
+                .maxAge(3600);
+    }
+}

+ 27 - 0
src/main/java/cn/aiyangniu/api/common/config/CustomizationBean.java

@@ -0,0 +1,27 @@
+package cn.aiyangniu.api.common.config;
+
+import io.undertow.server.DefaultByteBufferPool;
+import io.undertow.websockets.jsr.WebSocketDeploymentInfo;
+import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
+import org.springframework.boot.web.server.WebServerFactoryCustomizer;
+import org.springframework.stereotype.Component;
+
+/**
+ * 功能描述:
+ *
+ * @author liuchaoyong
+ * @version 1.0
+ * @since 2019-05-26 21:41
+ */
+@Component
+public class CustomizationBean implements WebServerFactoryCustomizer<UndertowServletWebServerFactory> {
+
+    @Override
+    public void customize(UndertowServletWebServerFactory factory) {
+        factory.addDeploymentInfoCustomizers(deploymentInfo -> {
+            WebSocketDeploymentInfo webSocketDeploymentInfo = new WebSocketDeploymentInfo();
+            webSocketDeploymentInfo.setBuffers(new DefaultByteBufferPool(false, 1024));
+            deploymentInfo.addServletContextAttribute("io.undertow.websockets.jsr.WebSocketDeploymentInfo", webSocketDeploymentInfo);
+        });
+    }
+}

+ 41 - 0
src/main/java/cn/aiyangniu/api/common/config/PageConfig.java

@@ -0,0 +1,41 @@
+package cn.aiyangniu.api.common.config;
+import com.baomidou.mybatisplus.annotation.DbType;
+import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
+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;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+import java.util.Collections;
+
+/**
+ * mybatis-plus分页插件
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+@EnableTransactionManagement
+@Configuration
+@MapperScan("cn.aiyangniu.api.mapper.*")
+class PageConfig {
+    /**
+     * 分页插件 3.5.X
+     * @author zhengkai.blog.csdn.net
+     */
+    @Bean
+    public PaginationInnerInterceptor paginationInnerInterceptor() {
+        PaginationInnerInterceptor paginationInterceptor = new PaginationInnerInterceptor();
+        // 设置最大单页限制数量,默认 500 条,-1 不受限制
+        paginationInterceptor.setMaxLimit(-1L);
+        paginationInterceptor.setDbType(DbType.MYSQL);
+        // 开启 count 的 join 优化,只针对部分 left join
+        paginationInterceptor.setOptimizeJoin(true);
+        return paginationInterceptor;
+    }
+    @Bean
+    public MybatisPlusInterceptor mybatisPlusInterceptor(){
+        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
+        mybatisPlusInterceptor.setInterceptors(Collections.singletonList(paginationInnerInterceptor()));
+        return mybatisPlusInterceptor;
+    }
+}

+ 40 - 0
src/main/java/cn/aiyangniu/api/common/config/RedisConfig.java

@@ -0,0 +1,40 @@
+package cn.aiyangniu.api.common.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+/**
+ * Redis 配置类
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+@Configuration
+public class RedisConfig {
+
+    /**
+     * Redis 序列化
+     * @author luyang
+     * @since  2020/3/21 20:12
+     * @param redisConnectionFactory redisConnectionFactory
+     * @return org.springframework.data.redis.core.RedisTemplate<java.lang.Object,java.lang.Object>
+     */
+    @Bean
+    public RedisTemplate<Object, Object> redisTemplate (RedisConnectionFactory redisConnectionFactory) {
+
+        RedisTemplate<Object, Object> template = new RedisTemplate<>();
+        RedisSerialize redisSerialize = new RedisSerialize(Object.class);
+        template.setValueSerializer(redisSerialize);
+        template.setHashValueSerializer(redisSerialize);
+        // key 的序列化采用 StringRedisSerializer
+        template.setKeySerializer(new StringRedisSerializer());
+        template.setHashKeySerializer(new StringRedisSerializer());
+        template.setConnectionFactory(redisConnectionFactory);
+        template.setDefaultSerializer(new StringRedisSerializer());
+        template.afterPropertiesSet();
+        return template;
+    }
+}

+ 46 - 0
src/main/java/cn/aiyangniu/api/common/config/RedisSerialize.java

@@ -0,0 +1,46 @@
+package cn.aiyangniu.api.common.config;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.serializer.SerializerFeature;
+import org.springframework.data.redis.serializer.RedisSerializer;
+import org.springframework.data.redis.serializer.SerializationException;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * FastJson 序列化 Redis
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+public class RedisSerialize<T> implements RedisSerializer<T> {
+
+    /**
+     * 默认编码格式
+     */
+    public static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
+
+    private Class<T> clazz;
+
+    public RedisSerialize(Class<T> clazz) {
+        super();
+        this.clazz = clazz;
+    }
+
+    @Override
+    public byte[] serialize(T t) throws SerializationException {
+        if(null == t) {
+            return new byte[0];
+        }
+        return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
+    }
+
+    @Override
+    public T deserialize(byte[] bytes) throws SerializationException {
+        if(null == bytes || bytes.length <= 0) {
+            return null;
+        }
+        String s = new String(bytes, DEFAULT_CHARSET);
+        return (T) JSON.parseObject(s, clazz);
+    }
+}

+ 102 - 0
src/main/java/cn/aiyangniu/api/common/config/SwaggerConfig.java

@@ -0,0 +1,102 @@
+package cn.aiyangniu.api.common.config;
+
+import io.swagger.annotations.ApiOperation;
+import org.jetbrains.annotations.NotNull;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.util.ReflectionUtils;
+import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.oas.annotations.EnableOpenApi;
+import springfox.documentation.service.*;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spi.service.contexts.SecurityContext;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Configuration
+@EnableOpenApi
+public class SwaggerConfig {
+    @Bean
+    public Docket createRestApi() {
+        return new Docket(DocumentationType.OAS_30)
+            .apiInfo(apiInfo())
+            .select()
+            .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
+            .paths(PathSelectors.any())
+            .build()
+            .securitySchemes(securitySchemes())
+            .securityContexts(securityContexts());
+    }
+
+    private List<SecurityContext> securityContexts() {
+        List<SecurityContext> securityContextList = new ArrayList<>();
+        List<SecurityReference> securityReferenceList = new ArrayList<>();
+        securityReferenceList.add(new SecurityReference("Authorization", scopes()));
+        securityContextList.add(SecurityContext
+            .builder()
+            .securityReferences(securityReferenceList)
+            .build()
+        );
+        return securityContextList;
+    }
+
+    private AuthorizationScope[] scopes() {
+        return new AuthorizationScope[]{new AuthorizationScope("global", "accessAnything")};
+    }
+
+    private List<SecurityScheme> securitySchemes() {
+        List<SecurityScheme> apiKeyList = new ArrayList<>();
+        apiKeyList.add(new ApiKey("Authorization", "Authorization", "header"));
+        return apiKeyList;
+    }
+
+    private ApiInfo apiInfo() {
+        return new ApiInfoBuilder()
+            .title("爱养牛供应商管理系统API接口")
+            .description("前后端分离的接口文档")
+            .version("3.0")
+            .build();
+    }
+
+    @Bean
+    public static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() {
+        return new BeanPostProcessor() {
+            @Override
+            public Object postProcessAfterInitialization(@NotNull Object bean, @NotNull String beanName) throws BeansException {
+                if (bean instanceof WebMvcRequestHandlerProvider) {
+                    customizeSpringfoxHandlerMappings(getHandlerMappings(bean));
+                }
+                return bean;
+            }
+
+            private <T extends RequestMappingInfoHandlerMapping> void customizeSpringfoxHandlerMappings(List<T> mappings) {
+                List<T> copy = mappings.stream().filter(mapping -> mapping.getPatternParser() == null).collect(Collectors.toList());
+                mappings.clear();
+                mappings.addAll(copy);
+            }
+
+            @SuppressWarnings("unchecked")
+            private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean) {
+                try {
+                    Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");
+                    assert field != null;
+                    field.setAccessible(true);
+                    return (List<RequestMappingInfoHandlerMapping>) field.get(bean);
+                } catch (IllegalArgumentException | IllegalAccessException e) {
+                    throw new IllegalStateException(e);
+                }
+            }
+        };
+    }
+}
+
+

+ 39 - 0
src/main/java/cn/aiyangniu/api/common/entity/system/AuthEntity.java

@@ -0,0 +1,39 @@
+package cn.aiyangniu.api.common.entity.system;
+
+
+/**
+ * AuthEntity 平台权限实体类
+ *
+ * @author Henry Hall
+ * @since 2020-09-28
+ */
+public class AuthEntity {
+
+    private boolean success; // 结果标识
+    private String userId; // 用户编号
+
+    public boolean isSuccess() {
+        return success;
+    }
+
+    public void setSuccess(boolean success) {
+        this.success = success;
+    }
+
+    public String getUserId() {
+        return userId;
+    }
+
+    public void setUserId(String userId) {
+        this.userId = userId;
+    }
+
+    public AuthEntity(boolean success) {
+        this.success = success;
+    }
+
+    public AuthEntity(boolean success, String userId) {
+        this.success = success;
+        this.userId = userId;
+    }
+}

+ 26 - 0
src/main/java/cn/aiyangniu/api/common/entity/system/SysAreaEntity.java

@@ -0,0 +1,26 @@
+package cn.aiyangniu.api.common.entity.system;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+/**
+ * SysAreaEntity 区域实体对象
+ *
+ * @author Henry Hall
+ * @since 2020-09-28
+ */
+@Data
+@TableName(value = "sys_area")
+public class SysAreaEntity {
+
+    @TableId(value = "area_id")
+    private int areaId; // 区域主键编号
+    private String areaName; // 区域名称
+    private String areaCode; // 区域编码
+    private int parentId; // 所属区域编号
+    private int areaLevel; // 区域级别
+    private int sort; // 区域排序
+    private String pinyin; // 区域名称全拼
+    private String jianpin; // 区域名称简拼
+}

+ 16 - 0
src/main/java/cn/aiyangniu/api/common/entity/system/SysAreaVo.java

@@ -0,0 +1,16 @@
+package cn.aiyangniu.api.common.entity.system;
+
+import lombok.Data;
+
+/**
+ * SysAreaVo 区域VO对象
+ *
+ * @author Henry Hall
+ * @since 2020-09-28
+ */
+@Data
+public class SysAreaVo {
+    private String name; // 区域名称
+    private int parentId; // 所属区域编号
+    private int areaLevel; // 区域级别
+}

+ 38 - 0
src/main/java/cn/aiyangniu/api/common/entity/system/SysBtnEntity.java

@@ -0,0 +1,38 @@
+package cn.aiyangniu.api.common.entity.system;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import java.util.List;
+
+/**
+ * SysBtnEntity 模块按钮实体对象
+ *
+ * @author Henry Hall
+ * @since 2020-09-28
+ */
+@Data
+@TableName(value = "sys_button")
+public class SysBtnEntity {
+
+    @TableId(value = "btn_id")
+    private String btnId; // 按钮主键编号
+    private String btnName; // 按钮名称
+    private String btnCode; // 按钮编码
+    private String modId; // 所属模块编号
+    private int sort; // 排序
+    private int dataStatus; // 状态,1为已审核,2为未审核,3为删除
+    private String createTime; // 创建时间
+    private String updateTime; // 修改时间
+    private String optUser; // 最后操作人员编号
+
+    @TableField(exist = false)
+    private String modName; // 所属模块名称
+    @TableField(exist = false)
+    private String modCode; // 所属模块名称
+    @TableField(exist = false)
+    private String logo; // 所属模块名称
+    @TableField(exist = false)
+    private String reqRandom; // 请求随机码
+}

+ 19 - 0
src/main/java/cn/aiyangniu/api/common/entity/system/SysBtnVo.java

@@ -0,0 +1,19 @@
+package cn.aiyangniu.api.common.entity.system;
+
+import lombok.Data;
+import java.util.List;
+
+/**
+ * SysBtnVo 模块按钮VO对象
+ *
+ * @author Henry Hall
+ * @since 2020-09-28
+ */
+@Data
+public class SysBtnVo {
+
+    private String schName; // 名称\编码关键字
+    private String modId; // 模块编号
+    private String optUser; // 操作人员编号
+    private List<String> btnIds; // 按钮编号串
+}

+ 49 - 0
src/main/java/cn/aiyangniu/api/common/entity/system/SysModEntity.java

@@ -0,0 +1,49 @@
+package cn.aiyangniu.api.common.entity.system;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import java.util.List;
+
+/**
+ * SysModEntity 系统模块实体对象
+ *
+ * @author Henry Hall
+ * @since 2020-09-28
+ */
+@Data
+@TableName(value = "sys_module")
+public class SysModEntity {
+
+    @TableId(value = "mod_id")
+    private String modId; // 模块主键编号
+    private String modName; //模块名称
+    private String modCode; // 模块编码
+    private String parentId; // 父级编号
+    private int sort; // 排序
+    private String logo; // Logo图标地址
+    private String url; // 跳转地址
+    private int dataStatus; // 状态,1为已审核,2为未审核,3为删除
+    private String createTime; // 创建时间
+    private String updateTime; // 修改时间
+    private String optUser; // 最后操作人员编号
+
+    @TableField(exist = false)
+    private String parentName; // 父级名称
+    @TableField(exist = false)
+    private String parentCode; // 父级编码
+    @TableField(exist = false)
+    private List<SysBtnEntity> buttonList; // 模块所包含的按钮实体List
+    @TableField(exist = false)
+    private List<SysModEntity> children; // 子模块数组
+    @TableField(exist = false)
+    private boolean checked = true; // 是否选中标识
+    @TableField(exist = false)
+    private String iconStyle = "iconbottom"; // 展示图标
+    @TableField(exist = false)
+    private int modLevel; // 模块级别
+
+    @TableField(exist = false)
+    private String reqRandom;
+}

+ 16 - 0
src/main/java/cn/aiyangniu/api/common/entity/system/SysModVo.java

@@ -0,0 +1,16 @@
+package cn.aiyangniu.api.common.entity.system;
+
+import lombok.Data;
+import java.util.List;
+
+/**
+ * SysModVo 模块VO对象
+ *
+ * @author Henry Hall
+ * @since 2020-09-28
+ */
+@Data
+public class SysModVo {
+    private String optUser; // 操作人员编号
+    private List<String> modIds; // 子级模块编号串
+}

+ 30 - 0
src/main/java/cn/aiyangniu/api/common/entity/system/SysMsgDetail.java

@@ -0,0 +1,30 @@
+package cn.aiyangniu.api.common.entity.system;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+/**
+ * SysMsgDetail 系统消息实体对象
+ *
+ * @author Henry Hall
+ * @since 2020-09-28
+ */
+@Data
+@TableName(value = "sys_msg_detail")
+public class SysMsgDetail {
+
+    @TableId(value = "detail_id")
+    private String detailId; // 消息明细主键编号
+    private String msgId; // 消息编号
+    private String kind; // 消息明细种类
+    private String userId; // 消息接收人员编号
+    private int dataStatus; // 状态,1为已读,2为未读,3为删除
+    private String createTime; // 创建时间
+    private String updateTime; // 修改时间
+    private String optUser; // 最后操作人员编号
+
+    @TableField(exist = false)
+    private String kindName;
+}

+ 31 - 0
src/main/java/cn/aiyangniu/api/common/entity/system/SysMsgEntity.java

@@ -0,0 +1,31 @@
+package cn.aiyangniu.api.common.entity.system;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+/**
+ * SysMsgEntity 系统消息实体对象
+ *
+ * @author Henry Hall
+ * @since 2020-09-28
+ */
+@Data
+@TableName(value = "sys_message")
+public class SysMsgEntity {
+
+    @TableId(value = "msg_id")
+    private String msgId; // 消息主键编号
+    private String title; // 消息标题
+    private String remarks; // 备注内容
+    private String kind; // 消息种类
+    private String infoId; // 消息对应的信息编号
+    private int dataStatus; // 状态,1为已读,2为未读,3为删除
+    private String createTime; // 创建时间
+    private String updateTime; // 修改时间
+    private String optUser; // 最后操作人员编号
+
+    @TableField(exist = false)
+    private String kindName;
+}

+ 23 - 0
src/main/java/cn/aiyangniu/api/common/entity/system/SysMsgVo.java

@@ -0,0 +1,23 @@
+package cn.aiyangniu.api.common.entity.system;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * SysMsgVo 消息VO对象
+ *
+ * @author Henry Hall
+ * @since 2020-09-28
+ */
+@Data
+public class SysMsgVo {
+    private String userId; // 查询的人员编号
+    private String title; // 消息标题
+    private String kind; // 消息种类编码
+    private String beginDate; // 开始时间
+    private String endDate; // 结束时间
+    private int status; // 状态编码
+    private String optUser; // 操作人员编号
+    private List<String> msgIds; // 消息编号串
+}

+ 37 - 0
src/main/java/cn/aiyangniu/api/common/entity/system/SysOptEntity.java

@@ -0,0 +1,37 @@
+package cn.aiyangniu.api.common.entity.system;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+/**
+ * SysOptEntity 业务参数实体对象
+ *
+ * @author Henry Hall
+ * @since 2020-09-28
+ */
+@Data
+@TableName(value = "sys_option")
+public class SysOptEntity {
+
+    @TableId(value = "opt_id")
+    private String optId; // 参数编号
+    private String optName; // 参数名称
+    private String optCode; // 参数编码
+    private String kind; // 参数种类
+    private int sort; // 参数排序
+    private String pinyin; // 名称全拼
+    private String jianpin; // 名称简拼
+    private int dataStatus; // 状态,1为已审核,2为未审核,3为删除
+    private String createTime; // 创建时间
+    private String updateTime; // 修改时间
+    private String optUser; // 最后操作人员编号
+
+    @TableField(exist = false)
+    private String kindName; //种类名称
+    @TableField(exist = false)
+    private String kindCode; //种类名称
+    @TableField(exist = false)
+    private String reqRandom; // 请求随机码
+}

+ 19 - 0
src/main/java/cn/aiyangniu/api/common/entity/system/SysOptVo.java

@@ -0,0 +1,19 @@
+package cn.aiyangniu.api.common.entity.system;
+
+import lombok.Data;
+import java.util.List;
+
+/**
+ * SysOptVo 参数选项VO对象
+ *
+ * @author Henry Hall
+ * @since 2020-09-28
+ */
+@Data
+public class SysOptVo {
+
+    private String name; // 名称\编码关键字
+    private String kind; // 种类
+    private String optUser; // 操作人员编号
+    private List<String> optIds; // 编号串
+}

+ 27 - 0
src/main/java/cn/aiyangniu/api/common/entity/system/SysRelEntity.java

@@ -0,0 +1,27 @@
+package cn.aiyangniu.api.common.entity.system;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+/**
+ * SysRelEntity 通用关联实体类
+ *
+ * @author Henry Hall
+ * @since 2020-09-28
+ */
+@Data
+@TableName(value = "sys_relation")
+public class SysRelEntity {
+
+    @TableId("rel_id")
+    private String relId; // 关联编号
+    private String srcId; // 源编号
+    private String dstId; // 目的编号
+    private int kind; // 种类
+    private int sort; // 排序
+    private int dataStatus; // 状态,1为已审核,2为未审核,3为删除
+    private String createTime; // 创建时间
+    private String updateTime; // 修改时间
+    private String optUser; // 最后操作人员编号
+}

+ 31 - 0
src/main/java/cn/aiyangniu/api/common/entity/system/SysRoleEntity.java

@@ -0,0 +1,31 @@
+package cn.aiyangniu.api.common.entity.system;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+/**
+ * SysRoleEntity 系统角色权限实体对象
+ *
+ * @author Henry Hall
+ * @since 2020-09-28
+ */
+@Data
+@TableName(value = "sys_role")
+public class SysRoleEntity {
+
+    @TableId(value = "role_id")
+    private String roleId; // 角色主键编号
+    private String roleName; // 角色名称
+    private int display; // 是否显示标识,1显示,2不显示
+    private String modCodes; // 权限模块编码串
+    private String btnCodes; // 权限按钮编码串
+    private int dataStatus; // 状态,1为已审核,2为未审核,3为删除
+    private String createTime; // 创建时间
+    private String updateTime; // 修改时间
+    private String optUser; // 最后操作人员编号
+
+    @TableField(exist = false)
+    private String reqRandom; // 请求随机码
+}

+ 20 - 0
src/main/java/cn/aiyangniu/api/common/entity/system/SysRoleVo.java

@@ -0,0 +1,20 @@
+package cn.aiyangniu.api.common.entity.system;
+
+import lombok.Data;
+import java.util.List;
+
+/**
+ * SysRoleVo 角色VO对象
+ *
+ * @author Henry Hall
+ * @since 2020-09-28
+ */
+@Data
+public class SysRoleVo {
+
+    private String schName; // 角色名称
+    private int display; // 是否显示
+    private int auth; // 是否有查看权限
+    private String optUser; // 操作人员编号
+    private List<String> roleIds; // 角色编号串
+}

+ 53 - 0
src/main/java/cn/aiyangniu/api/common/entity/system/SysTypeEntity.java

@@ -0,0 +1,53 @@
+package cn.aiyangniu.api.common.entity.system;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import java.util.List;
+
+/**
+ * SysTypeEntity 系统分类实体对象
+ *
+ * @author Henry Hall
+ * @since 2020-09-28
+ */
+@Data
+@TableName(value = "sys_type")
+public class SysTypeEntity {
+
+    @TableId(value = "type_id")
+    private String typeId; // 分类主键编号
+    private String parentId; // 父级编号
+    private String typeName; // 分类名称
+    private String typeCode; // 分类编码
+    private String pinyin; // 名称全拼
+    private String jianpin; // 名称简拼
+    private String kind; // 分类种类
+    private int sort; // 分类排序
+    private String typeImg; // 分类图片
+    private int dataStatus; // 状态,1为已审核,2为未审核,3为删除
+    private String createTime; // 创建时间
+    private String updateTime; // 修改时间
+    private String optUser; // 最后操作人员编号
+
+    @TableField(exist = false)
+    private String parentName; // 父级名称
+    @TableField(exist = false)
+    private String parentCode; // 父级编码
+    @TableField(exist = false)
+    private String kindName; // 种类名称
+    @TableField(exist = false)
+    private String kindCode; // 种类编码
+    @TableField(exist = false)
+    private List<SysTypeEntity> children; // 子级对象集合
+    @TableField(exist = false)
+    private List<String> parents; // 模块父级编号数组
+    @TableField(exist = false)
+    private boolean isChecked = false; // 是否选中标识
+    @TableField(exist = false)
+    private int typeLevel; // 分类层级
+
+    @TableField(exist = false)
+    private String reqRandom; // 请求随机码
+}

+ 20 - 0
src/main/java/cn/aiyangniu/api/common/entity/system/SysTypeVo.java

@@ -0,0 +1,20 @@
+package cn.aiyangniu.api.common.entity.system;
+
+import lombok.Data;
+import java.util.List;
+
+/**
+ * SysTypeVo 分类VO对象
+ *
+ * @author Henry Hall
+ * @since 2020-09-28
+ */
+@Data
+public class SysTypeVo {
+
+    private String name; // 名称\编码\全拼\简拼关键字
+    private String parentId; // 父级编号
+    private String kind; // 种类
+    private String optUser; // 操作人员编号
+    private List<String> typeIds; // 编号串
+}

+ 26 - 0
src/main/java/cn/aiyangniu/api/common/entity/system/SysUserDto.java

@@ -0,0 +1,26 @@
+package cn.aiyangniu.api.common.entity.system;
+
+import lombok.Data;
+
+/**
+ * SysUsrDto 用户信息DTO对象
+ *
+ * @author Henry Hall
+ * @since 2020-09-28
+ */
+@Data
+public class SysUserDto {
+    private String userId; // 用户编号
+    private String usname; // 登录账号
+    private String nickName; // 用户昵称
+    private String mobile; // 手机号码
+    private String typeCode; // 组织编码
+    private String typeName; // 组织名称
+    private String optCode; // 职务编码
+    private String optName; // 职务名称
+    private int dataStatus; // 用户状态
+    private String roleId; // 角色编号
+    private String roleName; // 角色名称
+    private String modCodes; // 模块编码串
+    private String btnCodes;  // 按钮编码串
+}

+ 48 - 0
src/main/java/cn/aiyangniu/api/common/entity/system/SysUserEntity.java

@@ -0,0 +1,48 @@
+package cn.aiyangniu.api.common.entity.system;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import java.util.List;
+
+/**
+ * SysUserEntity 系统用户实体对象
+ *
+ * @author Henry Hall
+ * @since 2020-09-28
+ */
+@Data
+@TableName(value = "sys_user")
+public class SysUserEntity {
+
+    @TableId(value = "usr_id")
+    private String userId; // 用户主键编号
+    private String usname; // 登录账号
+    private String passwd; // 登录密码
+    private String nickName; // 用户昵称
+    private String mobile; // 手机号码
+    private String roleId; // 角色编号
+    private String orgId; // 所属组织编号
+    private String dutyId; // 职务编号
+    private int kind; // 用户种类
+    private int dataStatus; // 状态,1为已审核,2为未审核,3为删除
+    private String createTime; // 创建时间
+    private String updateTime; // 修改时间
+    private String optUser; // 最后操作人员编号
+
+    @TableField(exist = false)
+    private String xAuthKey; // 用户会话标识
+    @TableField(exist = false)
+    private String orgName;
+    @TableField(exist = false)
+    private String orgCode;
+    @TableField(exist = false)
+    private String dutyName;
+    @TableField(exist = false)
+    private String dutyCode;
+    @TableField(exist = false)
+    private String roleName;
+    @TableField(exist = false)
+    private String reqRandom;
+}

+ 26 - 0
src/main/java/cn/aiyangniu/api/common/entity/system/SysUserVo.java

@@ -0,0 +1,26 @@
+package cn.aiyangniu.api.common.entity.system;
+
+import lombok.Data;
+import java.util.List;
+
+/**
+ * SysUsrVo 用户信息VO对象
+ *
+ * @author Henry Hall
+ * @since 2020-09-28
+ */
+@Data
+public class SysUserVo {
+
+    private String userId; // 用户编号
+    private String usname; // 登录账号
+    private String passwd; // 登录密码
+    private String name; // 名称\登录账号\手机号码关键字
+    private String roleId; // 角色编号
+    private String orgId; // 组织编号
+    private String dutyId; // 职务编号
+    private int dataStatus; // 状态标识
+    private int kind; // 种类标识
+    private String optUser; // 操作人员编号
+    private List<String> userIds; // 角色编号串
+}

+ 108 - 0
src/main/java/cn/aiyangniu/api/common/util/AuthUtil.java

@@ -0,0 +1,108 @@
+package cn.aiyangniu.api.common.util;
+
+import cn.aiyangniu.api.common.entity.system.AuthEntity;
+import cn.aiyangniu.api.common.entity.system.SysUserDto;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import org.springframework.stereotype.Component;
+import javax.annotation.Resource;
+
+/**
+ * 权限工具类
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+@Component
+public class AuthUtil {
+
+    @Resource
+    private RedisUtil redisUtil;
+
+    /**
+     * setUserSession 将User对象存储到Redis数据库中
+     *
+     * @param userDto 用户对象
+     * @param xAuthKey   Token
+     */
+    public void setUserSession(SysUserDto userDto, String xAuthKey) {
+        String str = JSON.toJSONString(userDto);
+        redisUtil.add("userId" + xAuthKey, str, 36000);
+    }
+
+    /**
+     * delUserSession 删除Redis数据库中的User对象
+     *
+     * @param xAuthKey Token
+     */
+    public void delUserSession(String xAuthKey) {
+        if(redisUtil.exists("userId" + xAuthKey)) {
+            String userEntStr = redisUtil.get("userId" + xAuthKey).toString();
+            JSONObject jo = JSONObject.parseObject(userEntStr);
+            String userId = jo.getString("userId");
+            if(redisUtil.exists("sysRandom" + userId)) {
+                redisUtil.delete("sysRandom" + userId);
+            }
+            redisUtil.delete("userId" + xAuthKey);
+        }
+    }
+
+    /**
+     * hasLogin 判断用户是否登录
+     *
+     * @param xAuthKey Token
+     * @return 返回是否登录标识
+     */
+    public boolean hasLogin(String xAuthKey) {
+        if(redisUtil.exists("userId" + xAuthKey)) {
+            if(redisUtil.getExpire("userId" + xAuthKey) < 0) {
+                redisUtil.delete("userId" + xAuthKey);
+            } else {
+                redisUtil.update("userId" + xAuthKey, 36000);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * getUserSession 获取用户的session数据
+     *
+     * @param xAuthKey Token
+     * @return 返回用户的session数据
+     */
+    public JSONObject getUserSession(String xAuthKey) {
+        if(redisUtil.exists("userId" + xAuthKey)) {
+            if(redisUtil.getExpire("userId" + xAuthKey) < 0) {
+                redisUtil.delete("userId" + xAuthKey);
+            } else {
+                String userEntStr = redisUtil.get("userId" + xAuthKey);
+                redisUtil.update("userId" + xAuthKey, 36000);
+                return JSONObject.parseObject(userEntStr);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * getUserId 从Redis数据库中获取User对象
+     *
+     * @param xAuthKey xAuthKey
+     * @return 返回权限对象
+     */
+    public AuthEntity getUserId(String xAuthKey) {
+        if(redisUtil.exists("userId" + xAuthKey)) {
+            if(redisUtil.getExpire("userId" + xAuthKey) < 0) {
+                redisUtil.delete("userId" + xAuthKey);
+            } else {
+                String userEntStr = redisUtil.get("userId" + xAuthKey).toString();
+                redisUtil.update("userId" + xAuthKey, 36000);
+                JSONObject jo = JSONObject.parseObject(userEntStr);
+                if(jo != null) {
+                    return new AuthEntity(true, jo.getString("userId"));
+                }
+            }
+        }
+        return new AuthEntity(false);
+    }
+}

+ 172 - 0
src/main/java/cn/aiyangniu/api/common/util/CharacterFiltUtil.java

@@ -0,0 +1,172 @@
+package cn.aiyangniu.api.common.util;
+
+/**
+ * CharacterFiltUtil 用于过滤请求参数的字符,以及判断字段串是否为整数或实例
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+public class CharacterFiltUtil {
+
+    /**
+     * inputFilter_文本框、传参过滤方法
+     *
+     * @param srcStr     源字符串
+     * @param whiteSpace 是否去掉空格标识, true为去掉空格, false为保留空格
+     * @return 过滤后的字符串
+     */
+    public static String inputFilter(String srcStr, boolean whiteSpace) {
+        if(srcStr != null && !"".equals(srcStr)) {
+            srcStr = srcStr.trim();
+            srcStr = (srcStr.indexOf(" ") != -1 && whiteSpace ? srcStr.replace(" ", "") : srcStr);
+            srcStr = (srcStr.indexOf("%") != -1 ? srcStr.replace("%", "\uff05") : srcStr);
+            srcStr = (srcStr.indexOf("'") != -1 ? srcStr.replace("'", "\u2018") : srcStr);
+            srcStr = (srcStr.indexOf("\"") != -1 ? srcStr.replace("\"", "\u201c") : srcStr);
+            srcStr = (srcStr.indexOf("<") != -1 ? srcStr.replace("<", "&lt;") : srcStr);
+            srcStr = (srcStr.indexOf(">") != -1 ? srcStr.replace(">", "&gt;") : srcStr);
+            srcStr = (srcStr.indexOf("--") != -1 ? srcStr.replace("--", "\uff0d\uff0d") : srcStr);
+            srcStr = (srcStr.indexOf("(") != -1 ? srcStr.replace("(", "") : srcStr);
+            srcStr = (srcStr.indexOf(")") != -1 ? srcStr.replace(")", "") : srcStr);
+            srcStr = (srcStr.indexOf("\n") != -1 ? srcStr.replace("\n", "<br />") : srcStr);
+            srcStr = (srcStr.indexOf("\r") != -1 ? srcStr.replace("\r", "<br />") : srcStr);
+        } else {
+            srcStr = "";
+        }
+        return srcStr;
+    }
+
+    /**
+     * searchFilter_搜索框过滤方法
+     *
+     * @param srcStr     源字符串
+     * @param whiteSpace 是否去掉空格标识, true为去掉空格, false为保留空格
+     * @return 过滤后的字符串
+     */
+    public static String searchFilter(String srcStr, boolean whiteSpace) {
+        if(srcStr != null && !"".equals(srcStr)) {
+            srcStr = srcStr.trim();
+            srcStr = (srcStr.indexOf(" ") != -1 && whiteSpace ? srcStr.replace(" ", "") : srcStr);
+            srcStr = (srcStr.indexOf("%") != -1 ? srcStr.replace("%", "\uff05") : srcStr);
+            srcStr = (srcStr.indexOf("'") != -1 ? srcStr.replace("'", "\u2018") : srcStr);
+            srcStr = (srcStr.indexOf("\"") != -1 ? srcStr.replace("\"", "\u201c") : srcStr);
+            srcStr = (srcStr.indexOf("--") != -1 ? srcStr.replace("--", "\uff0d\uff0d") : srcStr);
+            srcStr = (srcStr.indexOf("(") != -1 ? srcStr.replace("(", "") : srcStr);
+            srcStr = (srcStr.indexOf(")") != -1 ? srcStr.replace(")", "") : srcStr);
+        } else {
+            srcStr = "";
+        }
+        return srcStr;
+    }
+
+    /**
+     * textFilter_文本域过滤方法
+     *
+     * @param srcStr 源字符串
+     * @return 过滤后的字符串
+     */
+    public static String textFilter(String srcStr) {
+        if(srcStr != null && !"".equals(srcStr)) {
+            srcStr = srcStr.trim();
+            srcStr.replace(" ", "\u3000");
+            srcStr = (srcStr.indexOf("%") != -1 ? srcStr.replace("%", "\uff05") : srcStr);
+            srcStr = (srcStr.indexOf("'") != -1 ? srcStr.replace("'", "\u2018") : srcStr);
+            srcStr = (srcStr.indexOf("\"") != -1 ? srcStr.replace("\"", "\u201c") : srcStr);
+            srcStr = (srcStr.indexOf("<") != -1 ? srcStr.replace("<", "&lt;") : srcStr);
+            srcStr = (srcStr.indexOf(">") != -1 ? srcStr.replace(">", "&gt;") : srcStr);
+            srcStr = (srcStr.indexOf("--") != -1 ? srcStr.replace("--", "\uff0d\uff0d") : srcStr);
+            srcStr = (srcStr.indexOf("(") != -1 ? srcStr.replace("(", "") : srcStr);
+            srcStr = (srcStr.indexOf(")") != -1 ? srcStr.replace(")", "") : srcStr);
+            srcStr = (srcStr.indexOf("\n") != -1 ? srcStr.replace("\n", "<br />") : srcStr);
+            srcStr = (srcStr.indexOf("\r") != -1 ? srcStr.replace("\r", "<br />") : srcStr);
+        } else {
+            srcStr = "";
+        }
+        return srcStr;
+    }
+
+    /**
+     * editorFilter_过滤文本编辑器的内容
+     *
+     * @param srcStr 文本编辑器的字符串
+     * @return 过滤后的字符串
+     */
+    public static String editorFilter(String srcStr) {
+        if(srcStr != null && !"".equals(srcStr)) {
+            srcStr = (srcStr.indexOf("FRAME") != -1 ? srcStr.replace("FRAME", "") : srcStr);
+            srcStr = (srcStr.indexOf("frame") != -1 ? srcStr.replace("frame", "") : srcStr);
+            srcStr = (srcStr.indexOf("Frame") != -1 ? srcStr.replace("Frame", "") : srcStr);
+        } else {
+            srcStr = "";
+        }
+        return srcStr;
+    }
+
+    /**
+     * urlFilter_过滤网址非法字符
+     *
+     * @param srcStr 网址的字符串
+     * @return 过滤后的字符串
+     */
+    public static String urlFilter(String srcStr) {
+        if(srcStr != null && !"".equals(srcStr)) {
+            srcStr = (srcStr.indexOf(" ") != -1 ? srcStr.replace(" ", "") : srcStr);
+            srcStr = (srcStr.indexOf("'") != -1 ? srcStr.replace("'", "") : srcStr);
+            srcStr = (srcStr.indexOf("\"") != -1 ? srcStr.replace("\"", "") : srcStr);
+            srcStr = (srcStr.indexOf(";") != -1 ? srcStr.replace(";", "") : srcStr);
+            srcStr = (srcStr.indexOf("--") != -1 ? srcStr.replace("--", "") : srcStr);
+            srcStr = (srcStr.indexOf("(") != -1 ? srcStr.replace("(", "") : srcStr);
+            srcStr = (srcStr.indexOf(")") != -1 ? srcStr.replace(")", "") : srcStr);
+        } else {
+            srcStr = "";
+        }
+        return srcStr;
+    }
+
+    /**
+     * 用于校验数字是否为整数
+     *
+     * @param str 被校验是否为整数的数字
+     * @return 返回校验结果,true为是,false为不是
+     */
+    public static boolean isInt(String str) {
+        str = str.replace(" ", "");
+        boolean r = false;
+        if(!"".equals(str)) {
+            int b;
+            for(int i = 0, c = str.length(); i < c; i++) {
+                b = str.charAt(i);
+                if(b < 48 || b > 57) {
+                    r = false;
+                    break;
+                } else {
+                    r = true;
+                }
+            }
+        }
+        return r;
+    }
+
+    /**
+     * 用于校验输入的字符串是否为实数
+     *
+     * @param str 被校验是否为实数的字符串
+     * @return 返回校验结果,true为是,false为不是
+     */
+    public static boolean isDub(String str) {
+        str = str.replace(" ", "");
+        boolean r = false;
+        if(!"".equals(str)) {
+            int a;
+            for(int i = 0, c = str.length(); i < c; i++) {
+                a = str.charAt(i);
+                if((a < 48 || a > 57) && a != 45 && a != 46) {
+                    r = false;
+                    break;
+                } else {
+                    r = true;
+                }
+            }
+        }
+        return r;
+    }
+}

+ 31 - 0
src/main/java/cn/aiyangniu/api/common/util/ClientIpUtil.java

@@ -0,0 +1,31 @@
+package cn.aiyangniu.api.common.util;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * ClientIP 获取客户端IP地址
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+public class ClientIpUtil {
+
+    /**
+     * getIPAddr 获取IP地址
+     *
+     * @return 返回IP地址,如:192.168.1.2
+     */
+    public static String getIPAddr(HttpServletRequest req) {
+        String ip = req.getHeader("x-forwarded-for");
+        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = req.getHeader("Proxy-Client-IP");
+        }
+        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = req.getHeader("WL-Proxy-Client-IP");
+        }
+        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = req.getRemoteAddr();
+        }
+        return ip;
+    }
+}

+ 60 - 0
src/main/java/cn/aiyangniu/api/common/util/ClientMacUtil.java

@@ -0,0 +1,60 @@
+package cn.aiyangniu.api.common.util;
+import java.net.*;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * ClientIpUtil 获取客户端IP地址
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+public class ClientMacUtil {
+
+    /**
+     * getMacList 获取客户端设备的所有网络设备的MAC地址列表
+     * 
+     * @return MAC地址列表
+     */
+    public static List<String> getMacList() {
+        StringBuilder sb = new StringBuilder();
+        ArrayList<String> tmpMacList = new ArrayList<>();
+        try {
+            Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces();
+            while (en.hasMoreElements()) {
+                NetworkInterface iface = en.nextElement();
+                List<InterfaceAddress> addrs = iface.getInterfaceAddresses();
+                for (InterfaceAddress addr : addrs) {
+                    InetAddress ip = addr.getAddress();
+                    NetworkInterface network;
+                    network = NetworkInterface.getByInetAddress(ip);
+                    if (network == null) {
+                        continue;
+                    }
+                    byte[] mac = network.getHardwareAddress();
+                    if (mac == null) {
+                        continue;
+                    }
+                    sb.delete(0, sb.length());
+                    for (int i = 0; i < mac.length; i++) {
+                        sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : ""));
+                    }
+                    tmpMacList.add(sb.toString());
+                }
+            }
+        } catch (SocketException e) {
+            e.printStackTrace();
+        }
+        if (tmpMacList.size() <= 0) {
+            return tmpMacList;
+        }
+        List<String> unique = tmpMacList.stream().distinct().collect(Collectors.toList());
+        return unique;
+    }
+    public static void main(String[] args) {
+        List<String> macs = getMacList();
+        System.out.println("本机的mac网卡的地址有:" + macs);
+    }
+}

+ 265 - 0
src/main/java/cn/aiyangniu/api/common/util/DateUtil.java

@@ -0,0 +1,265 @@
+package cn.aiyangniu.api.common.util;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+
+/**
+ * 描述:此类用于取得当前日期相对应的月初,月末,季初,季末,年初,年末,返回值均为String字符串
+ * 1、得到当前日期         today()
+ * 2、得到当前月份月初      thisMonth()
+ * 3、得到当前月份月底      thisMonthEnd()
+ * 4、得到当前季度季初      thisSeason()
+ * 5、得到当前季度季末      thisSeasonEnd()
+ * 6、得到当前年份年初      thisYear()
+ * 7、得到当前年份年底      thisYearEnd()
+ * 8、判断输入年份是否为闰年 leapYear
+ * 注意事项:  日期格式为:xxxx-yy-zz (eg: 2007-12-05)
+ *
+ * @author Henry Hall
+ */
+public class DateUtil {
+    private static final Logger logger = LoggerFactory.getLogger(DateUtil.class);
+
+    private int x;                  // 日期属性:年
+    private int y;                  // 日期属性:月
+    private int z;                  // 日期属性:日
+    private Calendar localTime;     // 当前日期
+
+    public DateUtil() {
+        localTime = Calendar.getInstance();
+    }
+
+    /**
+     * 功能:得到当前日期 格式为:xxxx-yy-zz (eg: 2007-12-05)
+     */
+    public String today() {
+        String strY, strZ;
+        x = localTime.get(Calendar.YEAR);
+        y = localTime.get(Calendar.MONTH) + 1;
+        z = localTime.get(Calendar.DATE);
+        strY = y >= 10 ? String.valueOf(y) : ("0" + y);
+        strZ = z >= 10 ? String.valueOf(z) : ("0" + z);
+        return x + "-" + strY + "-" + strZ;
+    }
+
+    /**
+     * 功能:得到当前月的第一天 格式为:xxxx-yy-zz (eg: 2007-12-01)
+     */
+    public String thisMonth() {
+        String strY;
+        x = localTime.get(Calendar.YEAR);
+        y = localTime.get(Calendar.MONTH) + 1;
+        strY = y >= 10 ? String.valueOf(y) : ("0" + y);
+        return x + "-" + strY + "-01";
+    }
+
+    /**
+     * 功能:得到当前月的最后一天 格式为:xxxx-yy-zz (eg: 2007-12-31)
+     */
+    public String thisMonthEnd() {
+        String strY, strZ = null;
+        boolean leap;
+        x = localTime.get(Calendar.YEAR);
+        y = localTime.get(Calendar.MONTH) + 1;
+        if(y == 1 || y == 3 || y == 5 || y == 7 || y == 8 || y == 10 || y == 12) {
+            strZ = "31";
+        }
+        if(y == 4 || y == 6 || y == 9 || y == 11) {
+            strZ = "30";
+        }
+        if(y == 2) {
+            leap = leapYear(x);
+            if(leap) {
+                strZ = "29";
+            } else {
+                strZ = "28";
+            }
+        }
+        strY = y >= 10 ? String.valueOf(y) : ("0" + y);
+        return x + "-" + strY + "-" + strZ;
+    }
+
+    /**
+     * 功能:得到当前季度季初 格式为:xxxx-yy-zz (eg: 2007-10-01)
+     */
+    public String thisSeason() {
+        String dateString = "";
+        x = localTime.get(Calendar.YEAR);
+        y = localTime.get(Calendar.MONTH) + 1;
+        if(y <= 3) {
+            dateString = x + "-" + "01" + "-" + "01";
+        }
+        if(y >= 4 && y <= 6) {
+            dateString = x + "-" + "04" + "-" + "01";
+        }
+        if(y >= 7 && y <= 9) {
+            dateString = x + "-" + "07" + "-" + "01";
+        }
+        if(y >= 10 && y <= 12) {
+            dateString = x + "-" + "10" + "-" + "01";
+        }
+        return dateString;
+    }
+
+    /**
+     * 功能:得到当前季度季末 格式为:xxxx-yy-zz (eg: 2007-12-31)
+     */
+    public String thisSeasonEnd() {
+        String dateString = "";
+        x = localTime.get(Calendar.YEAR);
+        y = localTime.get(Calendar.MONTH) + 1;
+        if(y <= 3) {
+            dateString = x + "-" + "03" + "-" + "31";
+        }
+        if(y >= 4 && y <= 6) {
+            dateString = x + "-" + "06" + "-" + "30";
+        }
+        if(y >= 7 && y <= 9) {
+            dateString = x + "-" + "09" + "-" + "30";
+        }
+        if(y >= 10 && y <= 12) {
+            dateString = x + "-" + "12" + "-" + "31";
+        }
+        return dateString;
+    }
+
+    /**
+     * 功能:得到当前年份年初 格式为:xxxx-yy-zz (eg: 2007-01-01)
+     */
+    public String thisYear() {
+        x = localTime.get(Calendar.YEAR);
+        return x + "-01" + "-01";
+    }
+
+    /**
+     * 功能:得到当前年份年底 格式为:xxxx-yy-zz (eg: 2007-12-31)
+     */
+    public String thisYearEnd() {
+        x = localTime.get(Calendar.YEAR);
+        return x + "-12" + "-31";
+    }
+
+    /**
+     * 功能:判断输入年份是否为闰年
+     *
+     * @param year 年份
+     */
+    public boolean leapYear(int year) {
+        boolean leap;
+        if(year % 4 == 0) {
+            if(year % 100 == 0) {
+                leap = year % 400 == 0;
+            } else {
+                leap = true;
+            }
+        } else leap = false;
+        return leap;
+    }
+    /**
+     * 获得日期开始时间 格式为:xxxx-yy-zz hh24:mi:ss (eg: 2007-06-22 00:00:00)
+     *
+     * @param d 日期
+     * @return 日期
+     */
+    public static Date getStartDate(Date d) {
+        Calendar c = Calendar.getInstance();
+        if (d != null) {
+            c.setTime(d);
+        }
+
+        c.set(Calendar.HOUR_OF_DAY, 00);
+        c.set(Calendar.MINUTE, 00);
+        c.set(Calendar.SECOND, 00);
+        c.set(Calendar.MILLISECOND, 00);
+        return c.getTime();
+    }
+
+    /**
+     * 获得日期结束时间 格式为:xxxx-yy-zz hh24:mi:ss (eg: 2007-06-22 23:59:59)
+     *
+     * @param d 日期
+     * @return 日期
+     */
+    public static Date getEndDate(Date d) {
+        Calendar c = Calendar.getInstance();
+        if (d != null) {
+            c.setTime(d);
+        }
+
+        c.set(Calendar.HOUR_OF_DAY, 23);
+        c.set(Calendar.MINUTE, 59);
+        c.set(Calendar.SECOND, 59);
+        return c.getTime();
+    }
+
+    /**
+     * 格式化标准日期和时间
+     *
+     * @param date 日期
+     * @return 日期
+     */
+    public static String formatStandardTime(Date date, String pattern) {
+        if (date == null) {
+            return "";
+        }
+        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
+        return sdf.format(date);
+    }
+
+    /**
+     * 比较日期大小(fistDate > secondDate返回true)
+     * @param firstDate
+     * @param secondDate
+     * @return
+     */
+    public static boolean compareDate(Date firstDate, Date secondDate) {
+        Calendar cal1 = Calendar.getInstance();
+        Calendar cal2 = Calendar.getInstance();
+        try {
+            cal1.setTime(new SimpleDateFormat("yyyy-MM-dd").parse(formatStandardTime(firstDate, "yyyy-MM-dd")));
+            cal2.setTime(new SimpleDateFormat("yyyy-MM-dd").parse(formatStandardTime(secondDate, "yyyy-MM-dd")));
+        } catch (ParseException e) {
+            logger.error(e.getMessage());
+        }
+        return cal1.getTime().compareTo(cal2.getTime()) >= 0;
+    }
+
+    public static boolean sameDate(Date d1, Date d2) {
+        SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
+        //fmt.setTimeZone(new TimeZone()); // 如果需要设置时间区域,可以在这里设置
+        return fmt.format(d1).equals(fmt.format(d2));
+
+    }
+
+    public static Date getFirstDayOfWeek() {
+        Date date = new Date();
+        Calendar cal = Calendar.getInstance();
+        try {
+            cal.setTime(date);
+            cal.set(Calendar.DAY_OF_WEEK, 2);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return cal.getTime();
+    }
+
+    public static Date getFirstDayOfMonth() {
+        Calendar cale = Calendar.getInstance();
+        cale.add(Calendar.MONTH, 0);
+        cale.set(Calendar.DAY_OF_MONTH, 1);
+        return cale.getTime();
+    }
+
+    public static Date getFirstDayOfYear(){
+        Calendar calendar = Calendar.getInstance();
+        calendar.add(Calendar.YEAR,0);
+        calendar.set(Calendar.DAY_OF_YEAR,1);
+        return calendar.getTime();
+    }
+}

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 74 - 0
src/main/java/cn/aiyangniu/api/common/util/DecryptUtil.java


+ 96 - 0
src/main/java/cn/aiyangniu/api/common/util/EncryptUtil.java

@@ -0,0 +1,96 @@
+package cn.aiyangniu.api.common.util;
+
+import java.security.Key;
+import java.security.Security;
+import javax.crypto.Cipher;
+
+/**
+ * EncryptUtil 加密处理类
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+public class EncryptUtil {
+
+    private Cipher ec;
+
+    private static String ba2h(byte[] ba) {
+        int il = ba.length;
+        StringBuilder sb = new StringBuilder(il * 2);
+        for(int b : ba) {
+            int it = b;
+            while(it < 0) {
+                it = it + 256;
+            }
+            if(it < 16) {
+                sb.append("0");
+            }
+            sb.append(Integer.toString(it, 16));
+        }
+        return sb.toString();
+    }
+
+    public static byte[] h2ba(String strIn) {
+        byte[] ba = strIn.getBytes();
+        int il = ba.length;
+        byte[] bao = new byte[il / 2];
+        for(int i = 0; i < il; i = i + 2) {
+            String st = new String(ba, i, 2);
+            bao[i / 2] = (byte) Integer.parseInt(st, 16);
+        }
+        return bao;
+    }
+
+    private EncryptUtil(String k) throws Exception {
+        Security.addProvider(new com.sun.crypto.provider.SunJCE());
+        Key kt = getKey(k.getBytes());
+        ec = Cipher.getInstance("DES");
+        ec.init(Cipher.ENCRYPT_MODE, kt);
+    }
+
+    private byte[] encrypt(byte[] ba) throws Exception {
+        return ec.doFinal(ba);
+    }
+
+    private String encrypt(String strIn) throws Exception {
+        return ba2h(encrypt(strIn.getBytes()));
+    }
+
+    private Key getKey(byte[] bat) {
+        byte[] ba = new byte[8];
+        int it = bat.length, i, c = ba.length;
+        for(i = 0; i < it && i < c; i++) {
+            ba[i] = bat[i];
+        }
+        return new javax.crypto.spec.SecretKeySpec(ba, "DES");
+    }
+
+    public String[] encode(String data) {
+        String[] ret = new String[2];
+        long date = System.currentTimeMillis();
+        ret[0] = String.valueOf(date);
+        try {
+            EncryptUtil des = new EncryptUtil(ret[0]);
+            ret[2] = des.encrypt(data);
+        } catch(Exception e) {
+            e.printStackTrace();
+        }
+        return ret;
+    }
+
+    public static void main(String[] args) {
+        try {
+            long startTime = System.currentTimeMillis();
+            String txt = "a=0.3578669977&bh=ab06fd52-c4ae-4632-844b-57a3e5b8bf23&a=0.3578669977&bh=ab06fd52-c4ae-4632-844b-57a3e5b8bf23&a=0.3578669977&bh=ab06fd52-c4ae-4632-844b-57a3e5b8bf23&a=0.3578669977&bh=ab06fd52-c4ae-4632-844b-57a3e5b8bf23&a=0.3578669977&bh=ab06fd52-c4ae-4632-844b-57a3e5b8bf23&zl=2";
+            String now = String.valueOf(startTime);
+            EncryptUtil des = new EncryptUtil("Ub%^@jkl@$$");
+            System.out.println("当前时间戳为:" + now);
+            System.out.println("明文信息为:" + txt);
+            System.out.println("密文信息为:" + des.encrypt(txt));
+            long endTime = System.currentTimeMillis();
+            System.out.println("程序运行时间: " + (endTime - startTime) + "ms");
+        } catch(Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 111 - 0
src/main/java/cn/aiyangniu/api/common/util/HttpRequest.java

@@ -0,0 +1,111 @@
+package cn.aiyangniu.api.common.util;
+
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+
+public class HttpRequest {
+
+    /**
+     * JAVA的http请求通用方法
+     *
+     * @param requestUrl    请求的地址
+     * @param requestMethod 请求的方式,如GET、POST等
+     * @param parms         请求的参数
+     * @return 返回请求的结果
+     */
+    public static String httpRequest(String requestUrl, String requestMethod, String parms) {
+        StringBuffer buffer = null;
+        // System.out.println(parms);
+        try {
+            URL url = new URL(requestUrl);
+            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+            //设置通用的请求头属性
+            conn.setRequestProperty("accept", "*/*");
+            conn.setRequestProperty("connection", "Keep-Alive");
+            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
+            conn.setDoOutput(true);
+            conn.setDoInput(true);
+            conn.setRequestMethod(requestMethod);
+            conn.connect();
+            //往服务器端写内容 也就是发起http请求需要带的参数
+            if(null != parms) {
+                OutputStream os = conn.getOutputStream();
+                os.write(parms.getBytes(StandardCharsets.UTF_8));
+                os.close();
+            }
+            //读取服务器端返回的内容
+            InputStream is = conn.getInputStream();
+            InputStreamReader isr = new InputStreamReader(is, StandardCharsets.UTF_8);
+            BufferedReader br = new BufferedReader(isr);
+            buffer = new StringBuffer();
+            String line;
+            while((line = br.readLine()) != null) {
+                buffer.append(line);
+            }
+            is.close();
+            isr.close();
+        } catch(Exception e) {
+            e.printStackTrace();
+        }
+        assert buffer != null;
+        return buffer.toString();
+    }
+
+    /**
+     * JAVA的https请求通用方法
+     *
+     * @param requestUrl    请求的地址
+     * @param requestMethod 请求的方式,如GET、POST等
+     * @param outputStr     输出字符串
+     * @return 返回请求的结果
+     */
+    public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) {
+        StringBuffer buffer = null;
+        try {
+            //创建SSLContext
+            SSLContext sslContext = SSLContext.getInstance("SSL");
+            TrustManager[] tm = {new MyX509TrustManager()};
+            //初始化
+            sslContext.init(null, tm, new java.security.SecureRandom());
+            //获取SSLSocketFactory对象
+            SSLSocketFactory ssf = sslContext.getSocketFactory();
+            URL url = new URL(requestUrl);
+            HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
+            conn.setDoOutput(true);
+            conn.setDoInput(true);
+            conn.setUseCaches(false);
+            conn.setRequestMethod(requestMethod);
+            //设置当前实例使用的SSLSoctetFactory
+            conn.setSSLSocketFactory(ssf);
+            conn.connect();
+            //往服务器端写内容
+            if(null != outputStr) {
+                OutputStream os = conn.getOutputStream();
+                os.write(outputStr.getBytes(StandardCharsets.UTF_8));
+                os.close();
+            }
+            //读取服务器端返回的内容
+            InputStream is = conn.getInputStream();
+            InputStreamReader isr = new InputStreamReader(is, StandardCharsets.UTF_8);
+            BufferedReader br = new BufferedReader(isr);
+            buffer = new StringBuffer();
+            String line;
+            while((line = br.readLine()) != null) {
+                buffer.append(line);
+            }
+        } catch(Exception e) {
+            e.printStackTrace();
+        }
+        assert buffer != null;
+        return buffer.toString();
+    }
+}

+ 180 - 0
src/main/java/cn/aiyangniu/api/common/util/ImgUtil.java

@@ -0,0 +1,180 @@
+package cn.aiyangniu.api.common.util;
+
+import java.awt.AlphaComposite;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.RenderingHints;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import javax.imageio.ImageIO;
+import javax.swing.ImageIcon;
+import com.sun.image.codec.jpeg.JPEGCodec;
+import com.sun.image.codec.jpeg.JPEGImageEncoder;
+import java.util.Base64;
+import java.util.Base64.Decoder;
+
+/**
+ * 图片处理类
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+public class ImgUtil {
+
+    /**
+     * comImg 等比例高清压缩图片
+     *
+     * @param srcPath 原图片路径
+     * @param comW    压缩宽度, 如果为0,则按300像素宽
+     * @param comH    压缩高度, 如果为0,则按300像素高
+     */
+    public static void comImg(String srcPath, double comW, double comH) {
+        String destPath = srcPath.replace("srcImgs", "dstImgs"), foldPath = destPath.substring(0, destPath.lastIndexOf("/") + 1);
+        comW = (comW == 0 ? 200 : comW);
+        comH = (comH == 0 ? 150 : comH);
+        OutputStream fos;
+        try {
+            File srcFile = new File(srcPath), foldFile = new File(foldPath);
+            if(!foldFile.exists()) {
+                foldFile.mkdirs();
+            }
+            BufferedImage scrBI = ImageIO.read(srcFile);
+            int srcW = scrBI.getWidth(), srcH = scrBI.getHeight(), destW, destH;
+            fos = new FileOutputStream(destPath);
+            if(comW < srcW || comH < srcH) {
+                double ratio, ratioW, ratioH;
+                ratioW = comW / srcW;
+                ratioH = comH / srcH;
+                ratio = Math.min(ratioW, ratioH);
+                destW = (int) (srcW * ratio);
+                destH = (int) (srcH * ratio);
+                BufferedImage bi = new BufferedImage(destW, destH, 1);
+                bi.getGraphics().drawImage(scrBI, 0, 0, destW, destH, null);
+                JPEGImageEncoder jpegIe = JPEGCodec.createJPEGEncoder(fos);
+                jpegIe.encode(bi);
+            } else {
+                InputStream fis = new FileInputStream(srcFile);
+                byte[] buffer = new byte[1024];
+                int len;
+                while((len = fis.read(buffer)) > 0) {
+                    fos.write(buffer, 0, len);
+                }
+                fis.close();
+            }
+            fos.close();
+        } catch(IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * cutImg 裁剪图片
+     *
+     * @param srcPath 原图片路径
+     * @param cutX    裁剪的X坐标
+     * @param cutY    裁剪的Y坐标
+     * @param cutW    压缩宽度, 如果为0,则按300像素宽
+     * @param cutH    压缩高度, 如果为0,则按300像素高
+     */
+    public static void cutImg(String srcPath, int cutX, int cutY, int cutW, int cutH) {
+        String dstPath = srcPath.replace("srcImg", "dstImg");
+        String foldPath = dstPath.substring(0, dstPath.lastIndexOf("/") + 1);
+        OutputStream fos;
+        try {
+            File foldFile = new File(foldPath);
+            if(!foldFile.exists()) {
+                foldFile.mkdirs();
+            }
+            fos = new FileOutputStream(dstPath);
+            BufferedImage srcBI = ImageIO.read(new File(srcPath));
+            BufferedImage midBI = srcBI.getSubimage(cutX, cutY, cutW, cutH);
+            BufferedImage dstBI = new BufferedImage(300, 300, 1);
+            dstBI.getGraphics().drawImage(midBI, 0, 0, 300, 300, null);
+            JPEGImageEncoder jpegIe = JPEGCodec.createJPEGEncoder(fos);
+            jpegIe.encode(dstBI);
+            fos.close();
+        } catch(IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * wmImg 图片加水印
+     *
+     * @param srcPath 原图片地址
+     * @param wmPath  水印图片地址
+     */
+    public static void wmImg(String srcPath, String wmPath) {
+        float alphaVal = 0.6f;
+        FileOutputStream fos = null;
+        Image wmImg, srcImg;
+        ImageIcon srcImgIco;
+        BufferedImage bi;
+        Graphics2D gd;
+        try {
+            srcImgIco = new ImageIcon(wmPath);
+            srcImg = srcImgIco.getImage();
+            wmImg = ImageIO.read(new File(srcPath));
+            bi = new BufferedImage(wmImg.getWidth(null), wmImg.getHeight(null), BufferedImage.TYPE_INT_RGB);
+            gd = bi.createGraphics();
+            gd.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+            // 水印图片水平、垂直居中显示
+            // gd.drawImage(srcImg, wmImg.getWidth(null) / 2 - srcImg.getWidth(null) / 2, wmImg.getHeight(null) / 2 - srcImg.getHeight(null) / 2, null);
+            // 水印图片在右下角显示
+            gd.drawImage(wmImg.getScaledInstance(wmImg.getWidth(null), wmImg.getHeight(null), Image.SCALE_SMOOTH), 0, 0, null);
+            gd.rotate(Math.toRadians(0), (double) bi.getWidth() / 2, (double) bi.getHeight() / 2);
+            gd.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alphaVal));
+            gd.drawImage(srcImg, wmImg.getWidth(null) - srcImg.getWidth(null), wmImg.getHeight(null) - srcImg.getHeight(null), null);
+            gd.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
+            gd.dispose();
+            fos = new FileOutputStream(srcPath);
+            ImageIO.write(bi, srcPath.substring(srcPath.lastIndexOf(".") + 1), fos);
+            fos.close();
+        } catch(IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * base64Upload 64位转码上传图片
+     *
+     * @param base64 64位加密
+     */
+    public void base64Upload(String base64) {
+        String[] basa = base64.split("base64,");
+        // 通过base64来转化图片
+        Decoder decoder = Base64.getDecoder();
+        // Base64解码
+        byte[] imageByte;
+        // 生成文件名
+        // String files = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()) +
+        // (new Random().nextInt(9000) % (9000 - 1000 + 1) + 1000) + ".png";
+        // 生成文件路径
+        String path = "";
+        try {
+            imageByte = decoder.decode(basa[1]);
+            for(int i = 0; i < imageByte.length; ++i) {
+                if(imageByte[i] < 0) {// 调整异常数据
+                    imageByte[i] += 256;
+                }
+            }
+            // 生成文件
+            File imageFile = new File(path);
+            imageFile.createNewFile();
+            if(!imageFile.exists()) {
+                imageFile.createNewFile();
+            }
+            OutputStream imageStream = new FileOutputStream(imageFile);
+            imageStream.write(imageByte);
+            imageStream.flush();
+            imageStream.close();
+        } catch(Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 75 - 0
src/main/java/cn/aiyangniu/api/common/util/Md5Util.java

@@ -0,0 +1,75 @@
+package cn.aiyangniu.api.common.util;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * MD5加密处理类
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+public class Md5Util {
+
+    /**
+     * strMd5 字符串加密
+     *
+     * @param a 字符串
+     */
+    public static String strMd5(String a) {
+        String b = "";
+        try {
+            MessageDigest c = MessageDigest.getInstance(System.getProperty("MD5.algorithm", "MD5"));
+            byte[] d = c.digest(a.getBytes());
+            d = c.digest(d);
+            d = c.digest(d);
+            b = cG(d);
+        } catch(NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        }
+        return b;
+    }
+
+    /**
+     * intMd5 数字加密
+     *
+     * @param a 数字串
+     */
+    public static String intMd5(int a) {
+        String b = "", c = String.valueOf(a);
+        try {
+            MessageDigest d = MessageDigest.getInstance(System.getProperty("MD5.algorithm", "MD5"));
+            byte[] e = d.digest(c.getBytes());
+            e = d.digest(e);
+            e = d.digest(e);
+            b = cG(e);
+        } catch(NoSuchAlgorithmException f) {
+            f.printStackTrace();
+        }
+        return b;
+    }
+
+    /**
+     * cG 加密处理
+     *
+     * @param a 字符
+     */
+    private static String cG(byte[] a) {
+        char[] b = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
+        StringBuilder c = new StringBuilder();
+        int d;
+        for(int e = 0; e < 16; e++) {
+            d = a[e];
+            if(d < 0) {
+                d += 174;
+            }
+            c.append(b[(d >>> 4)]);
+            c.append(b[(d % 16)]);
+        }
+        return c.toString();
+    }
+
+    public static void main(String[] args) {
+        System.out.println(Md5Util.strMd5("123456"));
+    }
+}

+ 15 - 0
src/main/java/cn/aiyangniu/api/common/util/MyX509TrustManager.java

@@ -0,0 +1,15 @@
+package cn.aiyangniu.api.common.util;
+
+import java.security.cert.X509Certificate;
+import javax.net.ssl.X509TrustManager;
+
+public class MyX509TrustManager implements X509TrustManager {
+
+    public void checkClientTrusted(X509Certificate[] chain, String authType) {}
+
+    public void checkServerTrusted(X509Certificate[] chain, String authType) {}
+
+    public X509Certificate[] getAcceptedIssuers() {
+        return null;
+    }
+}

+ 55 - 0
src/main/java/cn/aiyangniu/api/common/util/PinyinUtil.java

@@ -0,0 +1,55 @@
+package cn.aiyangniu.api.common.util;
+
+import net.sourceforge.pinyin4j.PinyinHelper;
+import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
+import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
+import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
+import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
+import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
+
+/**
+ * 拼音业务类
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+public class PinyinUtil {
+
+    public static String pinYin(String s) {
+        char[] t1 = s.toCharArray();
+        String[] t2;
+        HanyuPinyinOutputFormat t3 = new HanyuPinyinOutputFormat();
+        t3.setCaseType(HanyuPinyinCaseType.LOWERCASE);
+        t3.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
+        t3.setVCharType(HanyuPinyinVCharType.WITH_V);
+        StringBuilder t4 = new StringBuilder();
+        try {
+            for(char c : t1) {
+                if(Character.toString(c).matches("[\\u4E00-\\u9FA5]+")) {
+                    t2 = PinyinHelper.toHanyuPinyinStringArray(c, t3);
+                    t4.append(t2[0]);
+                } else {
+                    t4.append(Character.toString(c));
+                }
+            }
+        } catch(BadHanyuPinyinOutputFormatCombination e1) {
+            e1.printStackTrace();
+        }
+        return t4.toString();
+    }
+
+    public static String jianPin(String s) {
+        StringBuilder w = new StringBuilder();
+        String[] a;
+        for(int j = 0, k = s.length(); j < k; j++) {
+            char c = s.charAt(j);
+            a = PinyinHelper.toHanyuPinyinStringArray(c);
+            if(a != null) {
+                w.append(a[0].charAt(0));
+            } else {
+                w.append(c);
+            }
+        }
+        return w.toString();
+    }
+}

+ 45 - 0
src/main/java/cn/aiyangniu/api/common/util/RandomUtil.java

@@ -0,0 +1,45 @@
+package cn.aiyangniu.api.common.util;
+
+import org.springframework.stereotype.Component;
+import javax.annotation.Resource;
+
+@Component
+public class RandomUtil {
+
+    @Resource
+    private RedisUtil redisUtil;
+
+    /**
+     * getSysRandom 获取随机数返回给前端,同时存储到缓冲数据库中
+     */
+    public String getSysRandom(String userId) {
+        String sysRandom = String.valueOf(Math.random());
+        if(redisUtil.exists("sysRandom" + userId)) {
+            sysRandom = redisUtil.get("sysRandom" + userId);
+            long expire = redisUtil.getExpire("sysRandom" + userId);
+            if(expire <= 0) {
+                sysRandom = String.valueOf(Math.random());
+                redisUtil.add("sysRandom" + userId, sysRandom, 3600);
+            }
+        } else {
+            redisUtil.add("sysRandom" + userId, sysRandom, 3600);
+        }
+        return sysRandom;
+    }
+
+    /**
+     * verifySysRandom 校验随机数
+     */
+    public static boolean verifySysRandom(String reqRandom, String sysRandom) {
+        // System.out.println("reqRandom="+ reqRandom +", sysRandom="+ sysRandom);
+        return sysRandom == null || "".equals(sysRandom) || reqRandom == null || "".equals(reqRandom) || !sysRandom.equals(reqRandom);
+    }
+
+    /**
+     * setSysRandom 生成随机数,并存入缓冲数据库中
+     */
+    public void setSysRandom(String userId) {
+        String sysRandom = String.valueOf(Math.random());
+        redisUtil.add("sysRandom" + userId, sysRandom, 1800);
+    }
+}

+ 86 - 0
src/main/java/cn/aiyangniu/api/common/util/RedisUtil.java

@@ -0,0 +1,86 @@
+package cn.aiyangniu.api.common.util;
+
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+import javax.annotation.Resource;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Redis 工具服务类
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+@Component
+public class RedisUtil {
+
+    @Resource
+    private RedisTemplate<String, Object> redisTemplate;
+
+    /**
+     * 保存数据
+     *
+     * @param key   键
+     * @param value 值
+     * @param time  时间(秒) 返回0代表为永久有效
+     */
+    public void add(String key, Object value, long time) {
+        redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
+    }
+
+    /**
+     * 删除Key
+     *
+     * @param key 可以传一个值 或多个
+     */
+    public void delete(String... key) {
+        if(key!=null && key.length>0) {
+            redisTemplate.delete(key[0]);
+        }
+    }
+
+    /**
+     * 获取Key对应的值
+     *
+     * @param key 键
+     * @return 值
+     */
+    public <T> T get(String key) {
+        return (T) redisTemplate.opsForValue().get(key);
+    }
+
+    /**
+     * 获取过期时间
+     *
+     * @param key 键 不能为null
+     * @return 时间(秒) 返回0代表为永久有效
+     */
+    public long getExpire(String key) {
+        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
+    }
+
+    /**
+     * 修改失效时间
+     *
+     * @param key  键
+     * @param time 时间(秒),返回0代表为永久有效
+     */
+    public void update(String key, long time) {
+        try {
+            redisTemplate.expire(key, time, TimeUnit.SECONDS);
+        } catch(Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 判断key是否存在
+     *
+     * @param key 键
+     * @return true 存在 false不存在
+     */
+    public boolean exists(String key) {
+        return redisTemplate.hasKey(key);
+    }
+}

+ 58 - 0
src/main/java/cn/aiyangniu/api/common/util/UUIDUtil.java

@@ -0,0 +1,58 @@
+package cn.aiyangniu.api.common.util;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.UUID;
+
+/**
+ * UUIDUtil 用于生成UUID串
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+public class UUIDUtil {
+
+    /**
+     * create36UUID 生成36位的UUID串
+     *
+     * @return 36位的UUID串
+     */
+    public static String create36UUID() {
+        return UUID.randomUUID().toString();
+    }
+
+    /**
+     * create32UUID 生成32位的UUID串
+     *
+     * @return 32位的UUID串
+     */
+    public static String create32UUID() {
+        return UUID.randomUUID().toString().replace("-", "");
+    }
+
+    /**
+     * createOrderNo 生成29位订单号
+     * ADO2020021110342660015882
+     *
+     * @param ordType 订单类型
+     * @return 订单号
+     */
+    public static String createOrderNo(String ordType) {
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
+        String dtStr, numStr;
+        double ranNum = Math.random() * 899999999 + 100000000;
+        dtStr = sdf.format(new Date());
+        numStr = String.format("%.0f", ranNum);
+        ordType += dtStr + numStr;
+        return ordType;
+    }
+
+    /**
+     * 生成6位的随机数
+     *
+     * @return 随机数
+     */
+    public static String createRandomNo() {
+        return (Math.random() * 9 + 1) * 100000 + "";
+    }
+}

+ 89 - 0
src/main/java/cn/aiyangniu/api/controller/other/CheckcodeController.java

@@ -0,0 +1,89 @@
+package cn.aiyangniu.api.controller.other;
+
+import cn.aiyangniu.api.common.util.ClientIpUtil;
+import cn.aiyangniu.api.common.util.RedisUtil;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.imageio.ImageIO;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.awt.*;
+import java.awt.geom.Line2D;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.util.Random;
+
+/**
+ * 图形验证码业务接口类
+ *
+ * @author Henry Hall
+ * @since 2020-08-22
+ */
+@RestController
+@RequestMapping("/checkcode")
+public class CheckcodeController {
+
+    @Resource
+    private RedisUtil redisUtil;
+
+    /**
+     * getSysTime 获取当前服务器系统时间
+     */
+    @RequestMapping(value="/admin", method= RequestMethod.GET)
+    public void getSysTime(HttpServletRequest req, HttpServletResponse res) {
+        res.setHeader("Pragma", "No-cache");
+        res.setHeader("Cache-Control", "No-cache");
+        res.setDateHeader("Expires", 0);
+        res.setContentType("image/jpeg");
+        StringBuilder a = new StringBuilder();
+        String s = "afghjkmnpqrstvxy23456789";
+        String t;
+        int w = 160, h = 42, i, p, q;
+        BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
+        Graphics gs = image.getGraphics();
+        Random rd = new Random();
+        Font f = new Font("Ace Crikey", Font.BOLD, 36);
+        Color c = new Color(237, 237, 237);
+        gs.setColor(c);
+        gs.fillRect(0, 0, w, h);
+        gs.setFont(f);
+        c = new Color(11, 110, 186);
+        gs.setColor(c);
+        BasicStroke bs;
+        Line2D line;
+        bs = new BasicStroke(2f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL);
+        p = 10+rd.nextInt(25);
+        q = 10+rd.nextInt(25);
+        line = new Line2D.Double(0, p, 160, q);
+        Graphics2D g2d = (Graphics2D) gs;
+        g2d.setStroke(bs);
+        g2d.draw(line);
+        for(i = 0; i < 5; i++) {
+            p = rd.nextInt(24);
+            t = s.substring(p, p+1);
+            a.append(t);
+            gs.setColor(c);
+            gs.drawString(t, 30*i+6, 36);
+        }
+        String ip = ClientIpUtil.getIPAddr(req);
+        redisUtil.add("sysCode"+ip, a.toString(), 3600);
+
+        if(redisUtil.exists("sysCode"+ip)) {
+            long expire = redisUtil.getExpire("sysCode"+ip);
+            if(expire <= 0) {
+                redisUtil.add("sysCode"+ip, a.toString(), 3600);
+            }
+        } else {
+            redisUtil.add("sysCode"+ip, a.toString(), 3600);
+        }
+        gs.dispose();
+        try {
+            ImageIO.write(image, "JPEG", res.getOutputStream());
+        } catch(IOException e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 85 - 0
src/main/java/cn/aiyangniu/api/controller/other/OtherController.java

@@ -0,0 +1,85 @@
+package cn.aiyangniu.api.controller.other;
+
+import cn.aiyangniu.api.common.util.AuthUtil;
+import cn.aiyangniu.api.common.util.RedisUtil;
+import com.alibaba.fastjson.JSONObject;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 一些常用的业务接口类
+ *
+ * @author Henry Hall
+ * @since 2019-10-22
+ */
+@RestController
+@RequestMapping("/others")
+public class OtherController {
+
+    @Resource
+    private AuthUtil authUtil;
+
+    @Resource
+    private RedisUtil redisUtil;
+
+    /**
+     * getSysTime 获取当前服务器系统时间
+     */
+    @RequestMapping(value="/getSysTime", method= RequestMethod.GET)
+    public Map<String, Object> getSysTime(HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        SimpleDateFormat sdt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"), sd = new SimpleDateFormat("yyyy-MM-dd");// 设置日期格式
+        String type = req.getParameter("type"), dt = ("1".equals(type) ? sdt.format(new Date()) : sd.format(new Date()));
+        result.put("retCode", "1001");
+        result.put("retMsg", "获取成功!");
+        result.put("time", dt);
+        return result;
+    }
+
+    /**
+     * getSysRandom 获取随机数返回给前端,同时存储到缓冲数据库中
+     */
+    @RequestMapping(value="/getSysRandom", method= RequestMethod.GET)
+    public Map<String, Object> getSysRandom(HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String sysRandom, token, retCode, retMsg, userId;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1004";
+            retMsg = "对不起,您没有登录,请重新登录!";
+        } else {
+            JSONObject jo = authUtil.getUserSession(token);
+            if(jo != null) {
+                userId = jo.getString("userId");
+                if(redisUtil.exists("sysRandom" + userId)) {
+                    sysRandom = redisUtil.get("sysRandom" + userId);
+                    long expire = redisUtil.getExpire("sysRandom" + userId);
+                    if(expire <= 0) {
+                        sysRandom = String.valueOf(Math.random());
+                        redisUtil.add("sysRandom" + userId, sysRandom, 3600);
+                    }
+                }else {
+                    sysRandom = String.valueOf(Math.random());
+                    redisUtil.add("sysRandom" + userId, sysRandom, 3600);
+                }
+                result.put("sysRandom", sysRandom);
+                retCode = "1001";
+                retMsg = "获取成功!";
+            } else {
+                retCode = "1006";
+                retMsg = "获取失败!";
+            }
+        }
+        result.put("retCode", retCode);
+        result.put("retMsg", retMsg);
+        return result;
+    }
+}

+ 287 - 0
src/main/java/cn/aiyangniu/api/controller/other/UploadController.java

@@ -0,0 +1,287 @@
+package cn.aiyangniu.api.controller.other;
+
+import cn.aiyangniu.api.common.util.AuthUtil;
+import cn.aiyangniu.api.common.util.CharacterFiltUtil;
+import org.apache.commons.io.FileUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.io.File;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * 文件上传业务接口类
+ *
+ * @author Henry Hall
+ * @since 2019-10-22
+ */
+@RestController
+@RequestMapping("/upload")
+public class UploadController {
+
+    @Value("${file-path}")
+    private String filePath;
+
+    @Value("${root-path}")
+    private String rootPath;
+
+    @Resource
+    private AuthUtil authUtil;
+
+    /**
+     * singleUpload 单文件上传
+     */
+    @RequestMapping(value="/single", method=RequestMethod.POST)
+    public Map<String, Object> singleUpload(@RequestParam("upFile") MultipartFile upFile, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        Map<String, String> fileMap = new HashMap<>();
+        String retCode="", retMsg="", token, savePath, visitPath, oldFileName, newFileName, extName, allowType;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请先登录后操作!";
+        } else {
+            boolean auth = authUtil.hasLogin(token);
+            if(!auth) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                if(upFile == null) {
+                    retCode = "1000";
+                    retMsg = "对不起,您缺少必要的请求参数,请重试!";
+                } else {
+                    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
+                    String datetime = sdf.format(new Date());
+                    //文件存放的目录
+                    File folder;
+                    try {
+                        oldFileName = upFile.getOriginalFilename();
+                        assert oldFileName != null;
+                        extName = oldFileName.substring(oldFileName.lastIndexOf(".")).toLowerCase();
+                        allowType = ".jpg.jpeg.gif.png.bmp.flv.swf.mp3.mp4.wav.wma.wmv.mid.avi.mpg.asf.rm.rmvb.doc.docx.xls.xlsx.ppt.pptx.txt.pdf.rar.zip.gz.bz2";
+                        if(!allowType.contains(extName)) {
+                            retCode = "1004";
+                            retMsg = "对不起,您选择上传的文件不允许上传";
+                        } else {
+                            if(".jpg.jpeg.gif.png.bmp".contains(extName)) {
+                                savePath = filePath + "images\\" + datetime + "\\";
+                                visitPath = rootPath + "images/" + datetime + "/";
+                            } else if(".doc.docx.xls.xlsx.ppt.pptx.txt.pdf".contains(extName)) {
+                                savePath = filePath + "documents\\" + datetime + "\\";
+                                visitPath = rootPath + "documents/" + datetime + "/";
+                            } else if(".flv.swf.mp3.mp4.wav.wma.wmv.mid.avi.mpg.asf.rm.rmvb".contains(extName)) {
+                                savePath = filePath + "videos\\" + datetime + "\\";
+                                visitPath = rootPath + "videos/" + datetime + "/";
+                            } else {
+                                savePath = filePath + "files\\" + datetime + "\\";
+                                visitPath = rootPath + "files/" + datetime + "/";
+                            }
+                            newFileName = reName(extName);
+                            visitPath = visitPath + newFileName;
+                            savePath = savePath.replace("\\", "/");
+                            folder = new File(savePath);
+                            if(!folder.exists()) {
+                                folder.mkdirs();
+                            }
+                            File targetFile = new File(savePath + newFileName);
+                            upFile.transferTo(targetFile);
+                            fileMap.put("uid", String.valueOf(System.currentTimeMillis()));
+                            fileMap.put("status", "success");
+                            fileMap.put("name", oldFileName);
+                            fileMap.put("url", visitPath);
+                            result.put("upFile", fileMap);
+                            retCode = "1001";
+                            retMsg = "上传成功";
+                        }
+                    } catch(IOException e) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+        }
+        result.put("retCode", retCode);
+        result.put("retMsg", retMsg);
+        return result;
+    }
+
+    /**
+     * multipleUpload 获取当前服务器系统时间
+     */
+    @RequestMapping(value="/multiple", method=RequestMethod.POST)
+    public Map<String, Object> multipleUpload(@RequestParam("upFiles") MultipartFile[] files, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode="", retMsg="", token, savePath, visitPath, oldFileName, newFileName, extName;
+        List<Map<String, String>> fileList = new ArrayList<>();
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请先登录后操作!";
+        } else {
+            boolean auth = authUtil.hasLogin(token);
+            if(!auth) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                if(files == null) {
+                    retCode = "1000";
+                    retMsg = "对不起,您缺少必要的请求参数,请重试!";
+                } else {
+                    Map<String, String> fileMap;
+                    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
+                    String datetime = sdf.format(new Date());
+                    //文件存放的目录
+                    File folder;
+                    boolean r = false;
+                    try {
+                        for(MultipartFile file: files) {
+                            oldFileName = file.getOriginalFilename();
+                            assert oldFileName != null;
+                            //文件新名字
+                            newFileName = reName(oldFileName);
+                            //文件后缀
+                            extName = oldFileName.substring(oldFileName.lastIndexOf("."));
+                            if(!(".jpg.jpeg.gif.png.bmp.flv.swf.mp3.mp4.wav.wma.wmv.mid.avi.mpg.asf.rm.rmvb.doc.docx.xls.xlsx.ppt.pptx.txt.pdf.rar.zip.gz.bz2").contains(extName)) {
+                                retCode = "1002";
+                                retMsg = "对不起,您选择上传的素材文件类型不允许上传,请重试!";
+                                r = false;
+                                break;
+                            } else if(oldFileName.length() > 100) {
+                                retCode = "1003";
+                                retMsg = "对不起,您选择上传的素材文件名称超出100个字符,请重试!";
+                                r = false;
+                                break;
+                            } else {
+                                rootPath = "";
+                                if(".jpg.jpeg.gif.png.bmp".contains(extName)) {
+                                    savePath = filePath + "images\\" + datetime + "\\";
+                                    visitPath = rootPath + "images/" + datetime + "/";
+                                } else if(".doc.docx.xls.xlsx.ppt.pptx.txt.pdf".contains(extName)) {
+                                    savePath = filePath + "documents\\" + datetime + "\\";
+                                    visitPath = rootPath + "documents/" + datetime + "/";
+                                } else if(".flv.swf.mp3.mp4.wav.wma.wmv.mid.avi.mpg.asf.rm.rmvb".contains(extName)) {
+                                    savePath = filePath + "videos\\" + datetime + "\\";
+                                    visitPath = rootPath + "videos/" + datetime + "/";
+                                } else {
+                                    savePath = filePath + "files\\" + datetime + "\\";
+                                    visitPath = rootPath + "files/" + datetime + "/";
+                                }
+                                visitPath = visitPath + newFileName;
+                                savePath = savePath.replace("\\", "/");
+                                folder = new File(savePath);
+                                if(!folder.exists()) {
+                                    folder.mkdirs();
+                                }
+                                File targetFile = new File(savePath + newFileName);
+                                targetFile.setExecutable(true, true);
+                                file.transferTo(targetFile);
+                                fileMap = new HashMap<>();
+                                fileMap.put("uid", String.valueOf(System.currentTimeMillis()));
+                                fileMap.put("status", "success");
+                                fileMap.put("name", oldFileName);
+                                fileMap.put("url", visitPath);
+                                fileList.add(fileMap);
+                                r = true;
+                            }
+                        }
+                        if(r) {
+                            retCode = "1001";
+                            retMsg = "上传成功";
+                            result.put("fileList", fileList);
+                        }
+                    } catch(IOException e) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+        }
+        result.put("retCode", retCode);
+        result.put("retMsg", retMsg);
+        return result;
+    }
+
+    /**
+     * reName 重命名上传文件
+     *
+     * @param extName 文件的后缀名
+     * @return 重命名后的文件名
+     */
+    private String reName(String extName) {
+        SimpleDateFormat simDtFmt = new SimpleDateFormat("yyyyMMddHHmmss");
+        String dateStr = simDtFmt.format(new Date()), randNbr = Math.round(Math.random() * 900) + 100 + "";
+        return dateStr + randNbr + extName;
+    }
+
+    /**
+     * delteByPath 通过路径删除文件
+     */
+    @RequestMapping(value="/delete", method=RequestMethod.POST)
+    private Map<String, Object> delteByPath(HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token, path;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您请求的参数不正确,请重试!";
+        } else {
+            boolean auth = authUtil.hasLogin(token);
+            if(!auth) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                path = req.getParameter("path");
+                path = CharacterFiltUtil.inputFilter(path, true);
+                if("".equals(path)) {
+                    retCode = "1000";
+                    retMsg = "对不起,您输入的信息有为空的必填项,请检查!";
+                } else {
+                    path = filePath + path.replace(rootPath, "");
+                    File cFile = new File(path);
+                    if(cFile.exists()) {
+                        cFile.delete();
+                    }
+                    retCode = "1001";
+                    retMsg = "恭喜您,文件删除成功!";
+                }
+            }
+        }
+        result.put("retCode", retCode);
+        result.put("retMsg", retMsg);
+        return result;
+    }
+
+    /**
+     * download 下载文件
+     * @return 返回可供下载的文件
+     */
+    @RequestMapping(value="/download", method=RequestMethod.POST)
+    public ResponseEntity<byte[]> download(HttpServletRequest req) {
+        String path = req.getParameter("path");
+        path = CharacterFiltUtil.inputFilter(path, true);
+        if(!"".equals(path)) {
+            File downFile = new File(path);
+            if(downFile.exists()) {
+                HttpHeaders headers = new HttpHeaders();
+                headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
+                ResponseEntity<byte[]> entity;
+                try {
+                    entity = new ResponseEntity<>(FileUtils.readFileToByteArray(downFile), headers, HttpStatus.OK);
+                    return entity;
+                } catch(IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return null;
+    }
+}

+ 79 - 0
src/main/java/cn/aiyangniu/api/controller/system/SysAreaController.java

@@ -0,0 +1,79 @@
+package cn.aiyangniu.api.controller.system;
+
+import cn.aiyangniu.api.common.entity.system.SysAreaEntity;
+import cn.aiyangniu.api.common.entity.system.SysAreaVo;
+import cn.aiyangniu.api.service.system.SysAreaService;
+import cn.aiyangniu.api.common.util.CharacterFiltUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * SysAreaController 区域业务接口类
+ *
+ * @author Henry Hall
+ * @since 2022-11-04
+ */
+@Api(tags="地区选择接口")
+@RestController
+@RequestMapping("/sysArea")
+public class SysAreaController {
+
+    @Resource
+    private SysAreaService areaService;
+
+    /**
+     * selAreas 列表显示区域
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "获取地区列表")
+    @RequestMapping(value="/select", method= RequestMethod.GET)
+    @ApiImplicitParams({
+        @ApiImplicitParam(name = "name", value = "名称", paramType = "query", dataType="string", dataTypeClass = String.class),
+        @ApiImplicitParam(name = "parentId", value = "父级编号", paramType = "query", dataType="int", dataTypeClass = Integer.class),
+        @ApiImplicitParam(name = "level", value = "级别", paramType = "query", dataType="int", dataTypeClass = Integer.class)
+    })
+    public Map<String, Object> selAreas(String name, Integer level, Integer parentId, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            name = CharacterFiltUtil.inputFilter(name, true);
+            if(level==null || parentId==null || level==0 || parentId==0) {
+                retCode = "100110090101";
+                retMsg = "对不起,您请求的参数为空,请重试";
+            } else {
+                SysAreaVo areaVo = new SysAreaVo();
+                areaVo.setName(name);
+                areaVo.setAreaLevel(level);
+                areaVo.setParentId(parentId);
+                List<SysAreaEntity> areaEntities = areaService.selAreas(areaVo);
+                if(areaEntities != null && areaEntities.size() > 0) {
+                    result.put("data", areaEntities);
+                    retCode = "1001";
+                    retMsg = "查询成功。";
+                } else {
+                    retCode = "100110090105";
+                    retMsg = "暂无内容";
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+}

+ 289 - 0
src/main/java/cn/aiyangniu/api/controller/system/SysBtnController.java

@@ -0,0 +1,289 @@
+package cn.aiyangniu.api.controller.system;
+
+import cn.aiyangniu.api.common.entity.system.AuthEntity;
+import cn.aiyangniu.api.common.entity.system.SysBtnEntity;
+import cn.aiyangniu.api.common.entity.system.SysBtnVo;
+import cn.aiyangniu.api.service.system.SysBtnService;
+import cn.aiyangniu.api.common.util.AuthUtil;
+import cn.aiyangniu.api.common.util.CharacterFiltUtil;
+import cn.aiyangniu.api.common.util.RandomUtil;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.*;
+
+/**
+ * 按钮业务接口类
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+@Slf4j
+@RestController
+@Api(tags="操作按钮接口")
+@RequestMapping("/sysButton")
+public class SysBtnController {
+
+    @Resource
+    private SysBtnService btnService;
+
+    @Resource
+    private RandomUtil randomUtil;
+
+    @Resource
+    private AuthUtil authUtil;
+
+    /**
+     * saveBtn 新增/修改按钮
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "新增/修改按钮信息")
+    @RequestMapping(value="/save", method= RequestMethod.POST)
+    @ApiImplicitParam(name = "btnEntity", value = "模块信息实体对象", paramType = "body", dataType="SysBtnEntity", dataTypeClass = SysBtnEntity.class, required = true)
+    public Map<String, Object> saveBtn(@RequestBody SysBtnEntity btnEntity, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, sysRandom, token, reqRandom, userId, btnId, btnName, btnCode, modId;
+        int iSort, r;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            AuthEntity auth = authUtil.getUserId(token);
+            if(auth == null || !auth.isSuccess()) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                userId = auth.getUserId();
+                sysRandom = randomUtil.getSysRandom(userId);
+                btnId = btnEntity.getBtnId();
+                btnName = btnEntity.getBtnName();
+                btnCode = btnEntity.getBtnCode();
+                modId = btnEntity.getModId();
+                reqRandom = req.getParameter("reqRandom");
+                btnId = CharacterFiltUtil.inputFilter(btnId, true);
+                btnName = CharacterFiltUtil.inputFilter(btnName, true);
+                btnCode = CharacterFiltUtil.inputFilter(btnCode, true);
+                modId = CharacterFiltUtil.inputFilter(modId, true);
+                reqRandom = CharacterFiltUtil.inputFilter(reqRandom, true);
+                if("".equals(btnName) || "".equals(btnCode) || "0".equals(modId) || "".equals(reqRandom)) {
+                    retCode = "100110030101";
+                    retMsg = "对不起,您输入的信息有为空的必填项,请检查!";
+                } else if(btnName.length() > 30 || btnCode.length() > 10) {
+                    retCode = "100110030102";
+                    retMsg = "对不起,您输入的信息有超出字数限制的项,请检查!";
+                } else if(RandomUtil.verifySysRandom(reqRandom, sysRandom)) {
+                    retCode = "100110030103";
+                    retMsg = "对不起,您已经提交过了,请不要重复提交!";
+                } else {
+                    randomUtil.setSysRandom(userId);
+                    btnEntity.setBtnName(btnName);
+                    btnEntity.setBtnCode(btnCode);
+                    btnEntity.setModId(modId);
+                    btnEntity.setOptUser(userId);
+                    if("".equals(btnId)) {
+                        r = btnService.addBtn(btnEntity);
+                    } else {
+                        btnEntity.setBtnId(btnId);
+                        r = btnService.edtBtn(btnEntity);
+                    }
+                    if(r != 0) {
+                        retCode = "1001";
+                        retMsg = "恭喜您,按钮保存成功!";
+                    } else {
+                        retCode = "100110030104";
+                        retMsg = "对不起,系统错误,请联系系统管理员!";
+                    }
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+
+    /**
+     * delBtns 删除按钮
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "删除按钮信息")
+    @RequestMapping(value="/delete", method= RequestMethod.POST)
+    @ApiImplicitParam(name = "btnVo", value = "模块信息实体对象", paramType = "body", dataType="SysBtnVo", dataTypeClass = SysBtnVo.class, required = true)
+    public Map<String, Object> delBtns(@RequestBody SysBtnVo btnVo, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            AuthEntity auth = authUtil.getUserId(token);
+            if(auth == null || !auth.isSuccess()) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                if(btnVo.getBtnIds()==null || btnVo.getBtnIds().size()==0) {
+                    retCode = "100110030201";
+                    retMsg = "对不起,您提交的信息有为空的必填项,请检查!";
+                } else {
+                    btnVo.setOptUser(auth.getUserId());
+                    int r = btnService.delBtns(btnVo);
+                    if(r != 0) {
+                        retCode = "1001";
+                        retMsg = "恭喜您,按钮删除成功!";
+                    } else {
+                        retCode = "100110030204";
+                        retMsg = "对不起,系统错误,请联系系统管理员!";
+                    }
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+
+    /**
+     * getBtn 获取单一按钮
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "获取按钮详情信息")
+    @RequestMapping(value="/getById", method= RequestMethod.GET)
+    @ApiImplicitParam(name = "btnId", value = "按钮编号", paramType = "query", dataType="String", dataTypeClass = String.class, required = true)
+    public Map<String, Object> getBtn(String btnId, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token;
+        SysBtnEntity btnEntity;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            boolean auth = authUtil.hasLogin(token);
+            if(!auth) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                btnId = CharacterFiltUtil.inputFilter(btnId, true);
+                if("".equals(btnId) || btnId.length() != 36) {
+                    retCode = "100110030301";
+                    retMsg = "对不起,您请求的参数非法,请重试!";
+                } else {
+                    btnEntity = btnService.getBtn(btnId);
+                    if(btnEntity != null) {
+                        result.put("data", btnEntity);
+                        retCode = "1001";
+                        retMsg = "查询成功。";
+                    } else {
+                        retCode = "100110030305";
+                        retMsg = "暂无内容";
+                    }
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+
+    /**
+     * listBtns 列表显示按钮
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "获取按钮分页列表")
+    @RequestMapping(value="/page", method= RequestMethod.GET)
+    @ApiImplicitParams({
+        @ApiImplicitParam(name = "schName", value = "关键字", paramType = "query", dataType="string", dataTypeClass = String.class),
+        @ApiImplicitParam(name = "modId", value = "模块编号", paramType = "query", dataType="string", dataTypeClass = String.class),
+        @ApiImplicitParam(name = "offset", value = "开始数据", paramType = "query", dataType="int", dataTypeClass = Integer.class, required = true),
+        @ApiImplicitParam(name = "limit", value = "每页数量", paramType = "query", dataType="int", dataTypeClass = Integer.class, required = true)
+    })
+    public Map<String, Object> listBtns(String schName, String modId, Integer offset, Integer limit, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            boolean auth = authUtil.hasLogin(token);
+            if(!auth) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                schName = CharacterFiltUtil.inputFilter(schName, true);
+                modId = CharacterFiltUtil.inputFilter(modId, true);
+                SysBtnVo btnVo = new SysBtnVo();
+                btnVo.setSchName(schName);
+                btnVo.setModId(modId);
+                int pageNo = offset / limit + 1;
+                IPage<SysBtnEntity> iPage = btnService.listBtns(btnVo, pageNo, limit);
+                if(iPage != null && iPage.getRecords() != null && iPage.getRecords().size() > 0) {
+                    result.put("data", iPage.getRecords());
+                    result.put("total", iPage.getTotal());
+                    retCode = "1001";
+                    retMsg = "查询成功。";
+                } else {
+                    retCode = "100110030405";
+                    retMsg = "暂无内容";
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+
+    /**
+     * sortBtns 统计某按钮下的子按钮数量,用于自动排序
+     */
+    @ApiOperation(value = "获取按钮详情信息")
+    @ApiImplicitParam(name = "modId", value = "模块编号", paramType = "query", dataType="String", dataTypeClass = String.class)
+    @RequestMapping(value="/sort", method= RequestMethod.GET)
+    private Map<String, Object> sortBtns(String modId, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            boolean auth = authUtil.hasLogin(token);
+            if(!auth) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                modId = CharacterFiltUtil.inputFilter(modId, true);
+                if("".equals(modId) || modId.length() != 36) {
+                    retCode = "100110030501";
+                    retMsg = "对不起,您请求的参数不正确,请重试!";
+                } else {
+                    int btnNum = btnService.sortBtns(modId);
+                    result.put("data", btnNum);
+                    retCode = "1001";
+                    retMsg = "查询成功。";
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+}

+ 366 - 0
src/main/java/cn/aiyangniu/api/controller/system/SysModController.java

@@ -0,0 +1,366 @@
+package cn.aiyangniu.api.controller.system;
+
+import cn.aiyangniu.api.common.entity.system.AuthEntity;
+import cn.aiyangniu.api.common.entity.system.SysModEntity;
+import cn.aiyangniu.api.common.entity.system.SysModVo;
+import cn.aiyangniu.api.service.system.SysModService;
+import cn.aiyangniu.api.common.util.AuthUtil;
+import cn.aiyangniu.api.common.util.CharacterFiltUtil;
+import cn.aiyangniu.api.common.util.RandomUtil;
+import com.alibaba.fastjson.JSONObject;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.*;
+
+/**
+ * 模块业务接口类
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+@Slf4j
+@RestController
+@Api(tags="系统模块接口")
+@RequestMapping("/sysModule")
+public class SysModController {
+
+    @Resource
+    private SysModService modService;
+
+    @Resource
+    private RandomUtil randomUtil;
+
+    @Resource
+    private AuthUtil authUtil;
+
+    /**
+     * saveMod 新增/修改模块
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "新增/修改模块信息")
+    @RequestMapping(value="/save", method= RequestMethod.POST)
+    @ApiImplicitParam(name = "modEntity", value = "模块信息实体对象", paramType = "body", dataType="SysModEntity", dataTypeClass = SysModEntity.class, required = true)
+    public Map<String, Object> saveMod(@RequestBody SysModEntity modEntity, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, sysRandom, token, reqRandom, userId, modId, modName, code, parentId, logo, url;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            AuthEntity auth = authUtil.getUserId(token);
+            if(auth == null || !auth.isSuccess()) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                userId = auth.getUserId();
+                sysRandom = randomUtil.getSysRandom(userId);
+                modId = modEntity.getModId();
+                modName = modEntity.getModName();
+                code = modEntity.getModCode();
+                parentId = modEntity.getParentId();
+                logo = modEntity.getLogo();
+                url = modEntity.getUrl();
+                reqRandom = modEntity.getReqRandom();
+                modId = CharacterFiltUtil.inputFilter(modId, true);
+                modName = CharacterFiltUtil.inputFilter(modName, true);
+                code = CharacterFiltUtil.inputFilter(code, true);
+                parentId = CharacterFiltUtil.inputFilter(parentId, true);
+                logo = CharacterFiltUtil.inputFilter(logo, true);
+                url = CharacterFiltUtil.inputFilter(url, true);
+                reqRandom = CharacterFiltUtil.inputFilter(reqRandom, true);
+                if("".equals(modName) || "".equals(code) || "0".equals(parentId) || "".equals(reqRandom)) {
+                    retCode = "100110020101";
+                    retMsg = "对不起,您输入的信息有为空的必填项,请检查!";
+                } else if(modName.length() > 30 || code.length() > 10 || logo.length() > 30 || url.length() > 60 || parentId.length() != 36) {
+                    retCode = "100110020102";
+                    retMsg = "对不起,您输入的信息有超出字数限制的项,请检查!";
+                } else if(RandomUtil.verifySysRandom(reqRandom, sysRandom)) {
+                    retCode = "100110020103";
+                    retMsg = "对不起,您已经提交过了,请不要重复提交!";
+                } else {
+                    randomUtil.setSysRandom(userId);
+                    modEntity.setModName(modName);
+                    modEntity.setModCode(code);
+                    modEntity.setParentId(parentId);
+                    modEntity.setUrl(url);
+                    modEntity.setLogo(logo);
+                    modEntity.setOptUser(userId);
+                    int r;
+                    if("".equals(modId)) {
+                        r = modService.addMod(modEntity);
+                    } else {
+                        modEntity.setModId(modId);
+                        r = modService.edtMod(modEntity);
+                    }
+                    if(r != 0) {
+                        retCode = "1001";
+                        retMsg = "恭喜您,模块保存成功!";
+                    } else {
+                        retCode = "100110020104";
+                        retMsg = "对不起,系统错误,请联系系统管理员!";
+                    }
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+
+    /**
+     * deleteMod 删除模块
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "删除模块信息")
+    @RequestMapping(value="/delete", method= RequestMethod.POST)
+    @ApiImplicitParam(name = "vo", value = "删除模块的请求对象", paramType = "body", dataType="SysModVo", dataTypeClass = SysModVo.class, required = true)
+    public Map<String, Object> deleteMod(@RequestBody SysModVo vo, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            AuthEntity auth = authUtil.getUserId(token);
+            if(auth == null || !auth.isSuccess()) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                List<String> ids = vo.getModIds();
+                if(ids==null || ids.size()==0) {
+                    retCode = "100110020201";
+                    retMsg = "对不起,您提交的信息有为空的必填项,请检查!";
+                } else {
+                    int r = modService.delMods(auth.getUserId(), ids);
+                    if(r != 0) {
+                        retCode = "1001";
+                        retMsg = "恭喜您,模块删除成功!";
+                    } else {
+                        retCode = "100110020204";
+                        retMsg = "对不起,系统错误,请联系系统管理员!";
+                    }
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+
+    /**
+     * getMod 获取单一模块
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "获取模块详情")
+    @RequestMapping(value="/getById", method= RequestMethod.GET)
+    @ApiImplicitParam(name = "modId", value = "模块编号", paramType = "query", dataType="string", dataTypeClass = String.class, required = true)
+    public Map<String, Object> getMod(String modId, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token;
+        SysModEntity modEntity;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            boolean auth = authUtil.hasLogin(token);
+            if(!auth) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                modId = CharacterFiltUtil.inputFilter(modId, true);
+                if("".equals(modId) || modId.length() != 36) {
+                    retCode = "100110020301";
+                    retMsg = "对不起,您请求的参数非法,请重试!";
+                } else {
+                    modEntity = modService.getMod(modId);
+                    if(modEntity != null) {
+                        result.put("data", modEntity);
+                        retCode = "1001";
+                        retMsg = "查询成功。";
+                    } else {
+                        retCode = "100110020305";
+                        retMsg = "暂无内容";
+                    }
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+
+    /**
+     * list 列表显示模块
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "获取模块树状列表")
+    @RequestMapping(value="/list", method= RequestMethod.GET)
+    @ApiImplicitParam(name = "parentId", value = "父级模块编号", paramType = "query", dataType="string", dataTypeClass = String.class)
+    public Map<String, Object> listMods(String parentId, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            boolean auth = authUtil.hasLogin(token);
+            if(!auth) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                parentId = parentId==null || "".equals(parentId) ? "00000000-0000-0000-0000-000000000000" : parentId; // 一级模块的父级编号
+                List<SysModEntity> modEntities = modService.listMods(parentId);
+                if(modEntities != null && modEntities.size() > 0) {
+                    result.put("data", modEntities);
+                    retCode = "1001";
+                    retMsg = "查询成功。";
+                } else {
+                    retCode = "100110020405";
+                    retMsg = "暂无内容";
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+
+    /**
+     * select 选择显示模块
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "获取模块下拉列表")
+    @RequestMapping(value="/select", method= RequestMethod.GET)
+    @ApiImplicitParams({
+        @ApiImplicitParam(name = "kind", value = "种类,1为全部,2为当前用户所拥有的", paramType = "query", dataType="string", dataTypeClass = String.class),
+        @ApiImplicitParam(name = "schName", value = "关键字", paramType = "query", dataType="string", dataTypeClass = String.class)
+    })
+    public Map<String, Object> selMods(String kind, String schName, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token, parentId;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            JSONObject userSession = authUtil.getUserSession(token);
+            if(userSession == null) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                kind = CharacterFiltUtil.inputFilter(kind, true);
+                schName = CharacterFiltUtil.inputFilter(schName, true);
+                String userMods = userSession.get("modCodes").toString();
+                parentId = "00000000-0000-0000-0000-000000000000"; // 一级模块的父级编号
+                List<SysModEntity> modEntities = modService.selMods(kind, parentId, schName, userMods);
+                if(modEntities != null && modEntities.size() > 0) {
+                    result.put("data", modEntities);
+                    retCode = "1001";
+                    retMsg = "查询成功。";
+                } else {
+                    retCode = "100110020505";
+                    retMsg = "暂无内容";
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+
+    /**
+     * sortMods 统计某模块下的子模块数量,用于自动排序
+     */
+    @ApiOperation(value = "获取模块数量")
+    @RequestMapping(value="/sort", method= RequestMethod.GET)
+    @ApiImplicitParam(name = "parentId", value = "父级模块编号", paramType = "query", dataType="string", dataTypeClass = String.class)
+    private Map<String, Object> sortMods(String parentId, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            boolean auth = authUtil.hasLogin(token);
+            if(!auth) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                parentId = CharacterFiltUtil.inputFilter(parentId, true);
+                if("".equals(parentId) || parentId.length() != 36) {
+                    retCode = "100110020601";
+                    retMsg = "对不起,您请求的参数不正确,请重试!";
+                } else {
+                    int modNum = modService.sortMods(parentId);
+                    result.put("data", modNum);
+                    retCode = "1001";
+                    retMsg = "查询成功。";
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+
+    /**
+     * getModBtns 获取模块及按钮信息
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "获取模块及数量")
+    @RequestMapping(value="/getModBtns", method= RequestMethod.GET)
+    public Map<String, Object> getModBtns(HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            boolean auth = authUtil.hasLogin(token);
+            if(!auth) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                List<SysModEntity> modEntities = modService.getModBtns();
+                if(modEntities != null && modEntities.size() > 0) {
+                    result.put("data", modEntities);
+                    retCode = "1001";
+                    retMsg = "查询成功。";
+                } else {
+                    retCode = "100110020905";
+                    retMsg = "暂无内容";
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+}

+ 262 - 0
src/main/java/cn/aiyangniu/api/controller/system/SysMsgController.java

@@ -0,0 +1,262 @@
+package cn.aiyangniu.api.controller.system;
+
+import cn.aiyangniu.api.common.entity.system.AuthEntity;
+import cn.aiyangniu.api.common.entity.system.SysMsgEntity;
+import cn.aiyangniu.api.common.entity.system.SysMsgVo;
+import cn.aiyangniu.api.service.system.SysMsgService;
+import cn.aiyangniu.api.common.util.AuthUtil;
+import cn.aiyangniu.api.common.util.CharacterFiltUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.*;
+
+/**
+ * SysMsgController 消息业务接口类
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+@Slf4j
+@RestController
+@Api(tags="消息通知接口")
+@RequestMapping("/sysMessage")
+public class SysMsgController {
+
+    @Resource
+    private SysMsgService msgService;
+
+    @Resource
+    private AuthUtil authUtil;
+
+    /**
+     * delMsgs 删除消息
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "删除消息信息")
+    @RequestMapping(value="/delete", method= RequestMethod.POST)
+    @ApiImplicitParam(name = "msgVo", value = "消息实体对象", paramType = "body", dataType="SysMsgVo", dataTypeClass = SysMsgVo.class, required = true)
+    public Map<String, Object> delMsgs(@RequestBody SysMsgVo msgVo, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            AuthEntity auth = authUtil.getUserId(token);
+            if(auth == null || !auth.isSuccess()) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                List<String> ids = msgVo.getMsgIds();
+                int states = msgVo.getStatus();
+                if(ids==null || ids.size()==0 || states<=0) {
+                    retCode = "100110080101";
+                    retMsg = "对不起,您提交的信息有为空的必填项,请检查!";
+                } else {
+                    msgVo.setOptUser(auth.getUserId());
+                    msgVo.setMsgIds(ids);
+                    msgVo.setStatus(states);
+                    int r = msgService.proMsgs(msgVo);
+                    if(r != 0) {
+                        retCode = "1001";
+                        switch(states) {
+                            case 1:
+                                retMsg = "恭喜您,消息已读成功!";
+                                break;
+                            case 3:
+                                retMsg = "恭喜您,消息删除成功!";
+                                break;
+                            default:
+                                retMsg = "恭喜您,消息处理成功!";
+                                break;
+                        }
+
+                    } else {
+                        retCode = "100110080104";
+                        retMsg = "对不起,系统错误,请联系系统管理员!";
+                    }
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+
+    /**
+     * listMsgs 列表显示消息
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "获取消息分页列表")
+    @RequestMapping(value="/page", method= RequestMethod.GET)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "schName", value = "关键字", paramType = "query", dataType="string", dataTypeClass = String.class),
+            @ApiImplicitParam(name = "kind", value = "种类", paramType = "query", dataType="string", dataTypeClass = String.class),
+            @ApiImplicitParam(name = "states", value = "数据状态", paramType = "query", dataType="int", dataTypeClass = Integer.class),
+            @ApiImplicitParam(name = "beginDate", value = "开始时间", paramType = "query", dataType="string", dataTypeClass = String.class),
+            @ApiImplicitParam(name = "endDate", value = "结束时间", paramType = "query", dataType="string", dataTypeClass = String.class),
+            @ApiImplicitParam(name = "offset", value = "开始数据", paramType = "query", dataType="int", dataTypeClass = Integer.class, required = true),
+            @ApiImplicitParam(name = "limit", value = "每页数量", paramType = "query", dataType="int", dataTypeClass = Integer.class, required = true)
+    })
+    public Map<String, Object> listMsgs(String schName, String kind, Integer states, String begingDate, String endDate, Integer offset, Integer limit, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            boolean auth = authUtil.hasLogin(token);
+            if(!auth) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                schName = CharacterFiltUtil.inputFilter(schName, true);
+                kind = CharacterFiltUtil.inputFilter(kind, true);
+                begingDate = CharacterFiltUtil.inputFilter(begingDate, true);
+                endDate = CharacterFiltUtil.inputFilter(endDate, true);
+                SysMsgVo msgVo = new SysMsgVo();
+                msgVo.setTitle(schName);
+                msgVo.setKind(kind);
+                msgVo.setStatus(states);
+                msgVo.setBeginDate(begingDate);
+                msgVo.setEndDate(endDate);
+                int pageNo = offset / limit + 1;
+                IPage<SysMsgEntity> iPage = msgService.listMsgs(msgVo, pageNo, limit);
+                if(iPage != null && iPage.getRecords() != null && iPage.getRecords().size() > 0) {
+                    result.put("data", iPage.getRecords());
+                    result.put("total", iPage.getTotal());
+                    retCode = "1001";
+                    retMsg = "查询成功。";
+                } else {
+                    retCode = "100110080205";
+                    retMsg = "暂无内容";
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+
+    /**
+     * myMsgs 我的消息列表
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "获取我的消息分页列表")
+    @RequestMapping(value="/myMsg", method= RequestMethod.GET)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "schName", value = "关键字", paramType = "query", dataType="string", dataTypeClass = String.class),
+            @ApiImplicitParam(name = "kind", value = "种类", paramType = "query", dataType="string", dataTypeClass = String.class),
+            @ApiImplicitParam(name = "states", value = "数据状态", paramType = "query", dataType="int", dataTypeClass = Integer.class),
+            @ApiImplicitParam(name = "beginDate", value = "开始时间", paramType = "query", dataType="string", dataTypeClass = String.class),
+            @ApiImplicitParam(name = "endDate", value = "结束时间", paramType = "query", dataType="string", dataTypeClass = String.class),
+            @ApiImplicitParam(name = "offset", value = "开始数据", paramType = "query", dataType="int", dataTypeClass = Integer.class, required = true),
+            @ApiImplicitParam(name = "limit", value = "每页数量", paramType = "query", dataType="int", dataTypeClass = Integer.class, required = true)
+    })
+    public Map<String, Object> myMsgs(String schName, String kind, Integer states, String begingDate, String endDate, Integer offset, Integer limit, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token, userId;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            JSONObject userSession = authUtil.getUserSession(token);
+            if(userSession == null) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                userId = userSession.getString("userId");
+                schName = CharacterFiltUtil.inputFilter(schName, true);
+                kind = CharacterFiltUtil.inputFilter(kind, true);
+                begingDate = CharacterFiltUtil.inputFilter(begingDate, true);
+                endDate = CharacterFiltUtil.inputFilter(endDate, true);
+                SysMsgVo msgVo = new SysMsgVo();
+                msgVo.setUserId(userId);
+                msgVo.setTitle(schName);
+                msgVo.setKind(kind);
+                msgVo.setStatus(states);
+                msgVo.setBeginDate(begingDate);
+                msgVo.setEndDate(endDate);
+                int pageNo = offset / limit + 1;
+                IPage<SysMsgEntity> iPage = msgService.myMsgs(msgVo, pageNo, limit);
+                if(iPage != null && iPage.getRecords() != null && iPage.getRecords().size() > 0) {
+                    result.put("data", iPage.getRecords());
+                    result.put("total", iPage.getTotal());
+                    retCode = "1001";
+                    retMsg = "查询成功。";
+                } else {
+                    retCode = "100110080305";
+                    retMsg = "暂无内容";
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+
+    /**
+     * getMsg 获取单一消息
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "获取消息详情信息")
+    @RequestMapping(value="/getById", method= RequestMethod.GET)
+    @ApiImplicitParam(name = "msgId", value = "消息编号", paramType = "query", dataType="string", dataTypeClass = String.class, required = true)
+    public Map<String, Object> getMsg(String msgId, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token;
+        SysMsgEntity msgEntity;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            boolean auth = authUtil.hasLogin(token);
+            if(!auth) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                msgId = CharacterFiltUtil.inputFilter(msgId, true);
+                if("".equals(msgId) || msgId.length() != 36) {
+                    retCode = "100110080401";
+                    retMsg = "对不起,您请求的参数非法,请重试!";
+                } else {
+                    msgEntity = msgService.getMsg(msgId);
+                    if(msgEntity != null) {
+                        result.put("data", msgEntity);
+                        retCode = "1001";
+                        retMsg = "查询成功。";
+                    } else {
+                        retCode = "100110080405";
+                        retMsg = "暂无内容";
+                    }
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+}

+ 338 - 0
src/main/java/cn/aiyangniu/api/controller/system/SysOptController.java

@@ -0,0 +1,338 @@
+package cn.aiyangniu.api.controller.system;
+
+import cn.aiyangniu.api.common.entity.system.AuthEntity;
+import cn.aiyangniu.api.common.entity.system.SysOptEntity;
+import cn.aiyangniu.api.common.entity.system.SysOptVo;
+import cn.aiyangniu.api.service.system.SysOptService;
+import cn.aiyangniu.api.common.util.AuthUtil;
+import cn.aiyangniu.api.common.util.CharacterFiltUtil;
+import cn.aiyangniu.api.common.util.PinyinUtil;
+import cn.aiyangniu.api.common.util.RandomUtil;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.*;
+
+/**
+ * SysOptController 选项业务接口类
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+@Slf4j
+@RestController
+@Api(tags="数据字典接口")
+@RequestMapping("/sysOption")
+public class SysOptController {
+
+    @Resource
+    private SysOptService optService;
+
+    @Resource
+    private RandomUtil randomUtil;
+
+    @Resource
+    private AuthUtil authUtil;
+
+    /**
+     * saveOpt 新增/修改选项
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "新增/修改数据字典")
+    @RequestMapping(value="/save", method= RequestMethod.POST)
+    @ApiImplicitParam(name = "optEntity", value = "数据字典实体对象", paramType = "body", dataType="SysOptEntity", dataTypeClass = SysOptEntity.class, required = true)
+    public Map<String, Object> saveOpt(@RequestBody SysOptEntity optEntity, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, sysRandom, token, reqRandom, userId, optId, optName, optCode, kind, sort, pinyin, jianpin;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            AuthEntity auth = authUtil.getUserId(token);
+            if(auth == null || !auth.isSuccess()) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                userId = auth.getUserId();
+                sysRandom = randomUtil.getSysRandom(userId);
+                optId = optEntity.getOptId();
+                optName = optEntity.getOptName();
+                optCode = optEntity.getOptCode();
+                kind = optEntity.getKind();
+                reqRandom = optEntity.getReqRandom();
+                optId = CharacterFiltUtil.inputFilter(optId, true);
+                optName = CharacterFiltUtil.inputFilter(optName, true);
+                optCode = CharacterFiltUtil.inputFilter(optCode, true);
+                kind = CharacterFiltUtil.inputFilter(kind, true);
+                reqRandom = CharacterFiltUtil.inputFilter(reqRandom, true);
+                if("".equals(optName) || "".equals(optCode) || "".equals(reqRandom)) {
+                    retCode = "100110060101";
+                    retMsg = "对不起,您输入的信息有为空的必填项,请检查!";
+                } else if(optName.length() > 30 || optCode.length() > 10) {
+                    retCode = "100110060102";
+                    retMsg = "对不起,您输入的信息有超出字数限制的项,请检查!";
+                } else if(RandomUtil.verifySysRandom(reqRandom, sysRandom)) {
+                    retCode = "100110060103";
+                    retMsg = "对不起,您已经提交过了,请不要重复提交!";
+                } else {
+                    randomUtil.setSysRandom(userId);
+                    optEntity.setOptName(optName);
+                    optEntity.setOptCode(optCode);
+                    optEntity.setKind(kind);
+                    pinyin = PinyinUtil.pinYin(optName);
+                    jianpin = PinyinUtil.jianPin(optName);
+                    optEntity.setPinyin(pinyin);
+                    optEntity.setJianpin(jianpin);
+                    optEntity.setOptUser(userId);
+                    int r;
+                    if("".equals(optId)) {
+                        r = optService.addOpt(optEntity);
+                    } else {
+                        optEntity.setOptId(optId);
+                        r = optService.edtOpt(optEntity);
+                    }
+                    if(r != 0) {
+                        retCode = "1001";
+                        retMsg = "恭喜您,选项保存成功!";
+                    } else {
+                        retCode = "100110060104";
+                        retMsg = "对不起,系统错误,请联系系统管理员!";
+                    }
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+
+    /**
+     * deleteOpt 删除选项
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "删除数据信息")
+    @RequestMapping(value="/delete", method= RequestMethod.POST)
+    @ApiImplicitParam(name = "optVo", value = "数据字典实体对象", paramType = "body", dataType="SysOptVo", dataTypeClass = SysOptVo.class, required = true)
+    public Map<String, Object> deleteOpt(@RequestBody SysOptVo optVo, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            AuthEntity auth = authUtil.getUserId(token);
+            if(auth == null || !auth.isSuccess()) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                List<String> ids = optVo.getOptIds();
+                if(ids==null || ids.size()>0) {
+                    retCode = "100110060201";
+                    retMsg = "对不起,您提交的信息有为空的必填项,请检查!";
+                } else {
+                    optVo.setOptUser(auth.getUserId());
+                    int r = optService.delOpts(optVo);
+                    if(r != 0) {
+                        retCode = "1001";
+                        retMsg = "恭喜您,选项删除成功!";
+                    } else {
+                        retCode = "100110060204";
+                        retMsg = "对不起,系统错误,请联系系统管理员!";
+                    }
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+
+    /**
+     * getOpt 获取单一选项
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "获取数据字典详情信息")
+    @RequestMapping(value="/getById", method= RequestMethod.GET)
+    @ApiImplicitParam(name = "optId", value = "主键编号", paramType = "query", dataType="string", dataTypeClass = String.class, required = true)
+    public Map<String, Object> getOpt(String optId, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token;
+        SysOptEntity optEntity;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            boolean auth = authUtil.hasLogin(token);
+            if(!auth) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                optId = CharacterFiltUtil.inputFilter(optId, true);
+                if("".equals(optId) || optId.length() != 36) {
+                    retCode = "100110060301";
+                    retMsg = "对不起,您请求的参数非法,请重试!";
+                } else {
+                    optEntity = optService.getOpt(optId);
+                    if(optEntity != null) {
+                        result.put("data", optEntity);
+                        retCode = "1001";
+                        retMsg = "查询成功。";
+                    } else {
+                        retCode = "100110060305";
+                        retMsg = "暂无内容";
+                    }
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+
+    /**
+     * listOpts 列表显示选项
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "获取角色分页列表")
+    @RequestMapping(value="/page", method= RequestMethod.GET)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "schName", value = "关键字", paramType = "query", dataType="string", dataTypeClass = String.class),
+            @ApiImplicitParam(name = "kind", value = "种类", paramType = "query", dataType="string", dataTypeClass = String.class),
+            @ApiImplicitParam(name = "offset", value = "开始数据", paramType = "query", dataType="int", dataTypeClass = Integer.class, required = true),
+            @ApiImplicitParam(name = "limit", value = "每页数量", paramType = "query", dataType="int", dataTypeClass = Integer.class, required = true)
+    })
+    public Map<String, Object> listOpts(String schName, String kind, Integer offset, Integer limit, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            boolean auth = authUtil.hasLogin(token);
+            if(!auth) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                schName = CharacterFiltUtil.inputFilter(schName, true);
+                kind = CharacterFiltUtil.inputFilter(kind, true);
+                SysOptVo optVo = new SysOptVo();
+                optVo.setName(schName);
+                optVo.setKind(kind);
+                int pageNo = offset / limit + 1;
+                IPage<SysOptEntity> iPage = optService.listOpts(optVo, pageNo, limit);
+                if(iPage != null && iPage.getRecords() != null && iPage.getRecords().size() > 0) {
+                    result.put("data", iPage.getRecords());
+                    result.put("total", iPage.getTotal());
+                    retCode = "1001";
+                    retMsg = "查询成功。";
+                } else {
+                    retCode = "100110060405";
+                    retMsg = "暂无内容";
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+
+    /**
+     * selOpts 选择显示角色
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "获取角色下拉列表")
+    @RequestMapping(value="/select", method= RequestMethod.GET)
+    @ApiImplicitParams({
+        @ApiImplicitParam(name = "schName", value = "关键字", paramType = "query", dataType="string", dataTypeClass = String.class),
+        @ApiImplicitParam(name = "kind", value = "种类", paramType = "query", dataType="string", dataTypeClass = String.class),
+    })
+    public Map<String, Object> selOpts(String schName, String kind, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            boolean auth = authUtil.hasLogin(token);
+            if(!auth) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                schName = CharacterFiltUtil.inputFilter(schName, true);
+                kind = CharacterFiltUtil.inputFilter(kind, true);
+                List<SysOptEntity> optEntities = optService.selOpts(schName, kind);
+                if(optEntities != null && optEntities.size() > 0) {
+                    result.put("data", optEntities);
+                    retCode = "1001";
+                    retMsg = "查询成功。";
+                } else {
+                    retCode = "100110060605";
+                    retMsg = "暂无内容";
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+
+    /**
+     * sortOpts 统计某选项下的子选项数量,用于自动排序
+     */
+    @ApiOperation(value = "获取数据字典的数量,用于排序")
+    @RequestMapping(value="/sort", method= RequestMethod.GET)
+    @ApiImplicitParam(name = "kind", value = "种类", paramType = "query", dataType="string", dataTypeClass = String.class)
+    private Map<String, Object> sortOpts(String kind, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            boolean auth = authUtil.hasLogin(token);
+            if(!auth) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                kind = CharacterFiltUtil.inputFilter(kind, true);
+                if("".equals(kind)) {
+                    retCode = "100110060501";
+                    retMsg = "对不起,您请求的参数不正确,请重试!";
+                } else {
+                    int optNum = optService.sortOpts(kind);
+                    result.put("data", optNum);
+                    retCode = "1001";
+                    retMsg = "查询成功。";
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+}

+ 292 - 0
src/main/java/cn/aiyangniu/api/controller/system/SysRoleController.java

@@ -0,0 +1,292 @@
+package cn.aiyangniu.api.controller.system;
+
+import cn.aiyangniu.api.common.entity.system.*;
+import cn.aiyangniu.api.service.system.SysRoleService;
+import cn.aiyangniu.api.common.util.AuthUtil;
+import cn.aiyangniu.api.common.util.CharacterFiltUtil;
+import cn.aiyangniu.api.common.util.RandomUtil;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.*;
+
+/**
+ * 角色业务接口类
+ *
+ * @author Henry Hall
+ * @since 2020-09-28
+ */
+@Slf4j
+@RestController
+@Api(tags="用户角色接口")
+@RequestMapping("/sysRole")
+public class SysRoleController {
+
+    @Resource
+    private SysRoleService roleService;
+
+    @Resource
+    private RandomUtil randomUtil;
+
+    @Resource
+    private AuthUtil authUtil;
+
+    /**
+     * saveRole 新增/修改角色
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "新增/修改角色信息")
+    @RequestMapping(value="/save", method= RequestMethod.POST)
+    @ApiImplicitParam(name = "roleEntity", value = "角色实体对象", paramType = "body", dataType="SysRoleEntity", dataTypeClass = SysRoleEntity.class, required = true)
+    public Map<String, Object> saveRole(@RequestBody SysRoleEntity roleEntity, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, sysRandom, token, reqRandom, userId, roleId, roleName, modCodes, btnCodes;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "10002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            AuthEntity auth = authUtil.getUserId(token);
+            if(auth == null || !auth.isSuccess()) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                userId = auth.getUserId();
+                sysRandom = randomUtil.getSysRandom(userId);
+                roleId = roleEntity.getRoleId();
+                roleName = roleEntity.getRoleName();
+                modCodes = roleEntity.getModCodes();
+                btnCodes = roleEntity.getBtnCodes();
+                reqRandom = roleEntity.getReqRandom();
+                roleId = CharacterFiltUtil.inputFilter(roleId, true);
+                roleName = CharacterFiltUtil.inputFilter(roleName, true);
+                modCodes = CharacterFiltUtil.inputFilter(modCodes, true);
+                btnCodes = CharacterFiltUtil.inputFilter(btnCodes, true);
+                reqRandom = CharacterFiltUtil.inputFilter(reqRandom, true);
+                if("".equals(roleName) || "".equals(modCodes) || "".equals(reqRandom)) {
+                    retCode = "100110040101";
+                    retMsg = "对不起,您输入的信息有为空的必填项,请检查!";
+                } else if(roleName.length() > 30) {
+                    retCode = "100110040102";
+                    retMsg = "对不起,您输入的信息有超出字数限制的项,请检查!";
+                } else if(RandomUtil.verifySysRandom(reqRandom, sysRandom)) {
+                    retCode = "100110040103";
+                    retMsg = "对不起,您已经提交过了,请不要重复提交!";
+                } else {
+                    randomUtil.setSysRandom(userId);
+                    roleEntity.setRoleName(roleName);
+                    roleEntity.setModCodes(modCodes);
+                    roleEntity.setBtnCodes(btnCodes);
+                    roleEntity.setOptUser(userId);
+                    int r;
+                    if("".equals(roleId)) {
+                        r = roleService.addRole(roleEntity);
+                    } else {
+                        roleEntity.setRoleId(roleId);
+                        r = roleService.edtRole(roleEntity);
+                    }
+                    if(r != 0) {
+                        retCode = "1001";
+                        retMsg = "恭喜您,角色保存成功!";
+                    } else {
+                        retCode = "100110040104";
+                        retMsg = "对不起,系统错误,请联系系统管理员!";
+                    }
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+
+    /**
+     * deleteRole 删除角色
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "删除角色信息")
+    @RequestMapping(value="/delete", method= RequestMethod.POST)
+    @ApiImplicitParam(name = "vo", value = "删除模块的请求对象", paramType = "body", dataType="SysRoleVo", dataTypeClass = SysRoleVo.class, required = true)
+    public Map<String, Object> deleteRole(@RequestBody SysRoleVo roleVo, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            AuthEntity auth = authUtil.getUserId(token);
+            if(auth == null || !auth.isSuccess()) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                List<String> ids = roleVo.getRoleIds();
+                if(ids==null || ids.size()==0) {
+                    retCode = "100110040201";
+                    retMsg = "对不起,您提交的信息有为空的必填项,请检查!";
+                } else {
+                    roleVo.setOptUser(auth.getUserId());
+                    int r = roleService.delRoles(roleVo);
+                    if(r != 0) {
+                        retCode = "1001";
+                        retMsg = "恭喜您,角色删除成功!";
+                    } else {
+                        retCode = "100110040204";
+                        retMsg = "对不起,系统错误,请联系系统管理员!";
+                    }
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+
+    /**
+     * getRole 获取单一角色
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "获取角色详情信息")
+    @RequestMapping(value="/getById", method= RequestMethod.GET)
+    @ApiImplicitParam(name = "roleId", value = "角色编号", paramType = "query", dataType="string", dataTypeClass = String.class, required = true)
+    public Map<String, Object> getRole(String roleId, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token;
+        SysRoleEntity roleEntity;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            boolean auth = authUtil.hasLogin(token);
+            if(!auth) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                roleId = CharacterFiltUtil.inputFilter(roleId, true);
+                if("".equals(roleId) || roleId.length() != 36) {
+                    retCode = "100110040301";
+                    retMsg = "对不起,您请求的参数非法,请重试!";
+                } else {
+                    roleEntity = roleService.getRole(roleId);
+                    if(roleEntity != null) {
+                        result.put("data", roleEntity);
+                        retCode = "1001";
+                        retMsg = "查询成功。";
+                    } else {
+                        retCode = "100110040305";
+                        retMsg = "暂无内容";
+                    }
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+
+    /**
+     * listRoles 列表显示角色
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "获取角色分页列表")
+    @RequestMapping(value="/page", method= RequestMethod.GET)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "schName", value = "关键字", paramType = "query", dataType="string", dataTypeClass = String.class),
+            @ApiImplicitParam(name = "display", value = "是否显示", paramType = "query", dataType="int", dataTypeClass = Integer.class),
+            @ApiImplicitParam(name = "offset", value = "开始数据", paramType = "query", dataType="int", dataTypeClass = Integer.class, required = true),
+            @ApiImplicitParam(name = "limit", value = "每页数量", paramType = "query", dataType="int", dataTypeClass = Integer.class, required = true)
+    })
+    public Map<String, Object> listRoles(String schName, Integer display, Integer offset, Integer limit, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token;
+        int iAuth, pageNo;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            AuthEntity auth = authUtil.getUserId(token);
+            if(!auth.isSuccess()) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                schName = CharacterFiltUtil.inputFilter(schName, true);
+                iAuth = (auth.getUserId().contains("gljsv") ? 1 : 2);
+                SysRoleVo roleVo = new SysRoleVo();
+                roleVo.setSchName(schName);
+                roleVo.setAuth(iAuth);
+                roleVo.setDisplay(display);
+                pageNo = offset / limit + 1;
+                IPage<SysRoleEntity> iPage = roleService.listRoles(roleVo, pageNo, limit);
+                if(iPage != null && iPage.getRecords() != null && iPage.getRecords().size() > 0) {
+                    result.put("data", iPage.getRecords());
+                    result.put("total", iPage.getTotal());
+                    retCode = "1001";
+                    retMsg = "查询成功。";
+                } else {
+                    retCode = "100110040405";
+                    retMsg = "暂无内容";
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+
+    /**
+     * selRoles 选择显示角色
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "获取角色下拉列表")
+    @RequestMapping(value="/select", method= RequestMethod.GET)
+    public Map<String, Object> selRoles(HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            AuthEntity auth = authUtil.getUserId(token);
+            if(!auth.isSuccess()) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                int kind = (!auth.getUserId().contains("gljsv") ? 1 : 2);
+                List<SysRoleEntity> roleEntities = roleService.selRoles(kind);
+                if(roleEntities != null && roleEntities.size() > 0) {
+                    result.put("data", roleEntities);
+                    retCode = "1001";
+                    retMsg = "查询成功。";
+                } else {
+                    retCode = "100110040505";
+                    retMsg = "暂无内容";
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+}

+ 349 - 0
src/main/java/cn/aiyangniu/api/controller/system/SysTypeController.java

@@ -0,0 +1,349 @@
+package cn.aiyangniu.api.controller.system;
+
+import cn.aiyangniu.api.common.entity.system.AuthEntity;
+import cn.aiyangniu.api.common.entity.system.SysTypeEntity;
+import cn.aiyangniu.api.common.entity.system.SysTypeVo;
+import cn.aiyangniu.api.service.system.SysTypeService;
+import cn.aiyangniu.api.common.util.AuthUtil;
+import cn.aiyangniu.api.common.util.CharacterFiltUtil;
+import cn.aiyangniu.api.common.util.PinyinUtil;
+import cn.aiyangniu.api.common.util.RandomUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.*;
+
+/**
+ * 分类业务接口类
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+@Slf4j
+@RestController
+@Api(tags="通用分类接口")
+@RequestMapping("/sysType")
+public class SysTypeController {
+
+    @Resource
+    private SysTypeService typeService;
+
+    @Resource
+    private RandomUtil randomUtil;
+
+    @Resource
+    private AuthUtil authUtil;
+
+    /**
+     * saveType 新增/修改分类
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "新增/修改分类信息")
+    @RequestMapping(value="/save", method= RequestMethod.POST)
+    @ApiImplicitParam(name = "typeEntity", value = "分类实体对象", paramType = "body", dataType="SysTypeEntity", dataTypeClass = SysTypeEntity.class, required = true)
+    public Map<String, Object> saveType(@RequestBody SysTypeEntity typeEntity,  HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, sysRandom, token, reqRandom, userId, typeId, typeName, typeCode, kind, parentId, typeImg, pinyin, jianpin;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            AuthEntity auth = authUtil.getUserId(token);
+            if(auth == null || !auth.isSuccess()) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                userId = auth.getUserId();
+                sysRandom = randomUtil.getSysRandom(userId);
+                typeId = typeEntity.getTypeId();
+                typeName = typeEntity.getTypeName();
+                typeCode = typeEntity.getTypeCode();
+                kind = typeEntity.getKind();
+                parentId = typeEntity.getParentId();
+                typeImg = typeEntity.getTypeImg();
+                reqRandom = typeEntity.getReqRandom();
+                typeId = CharacterFiltUtil.inputFilter(typeId, true);
+                typeName = CharacterFiltUtil.inputFilter(typeName, true);
+                typeCode = CharacterFiltUtil.inputFilter(typeCode, true);
+                kind = CharacterFiltUtil.inputFilter(kind, true);
+                parentId = CharacterFiltUtil.inputFilter(parentId, true);
+                typeImg = CharacterFiltUtil.inputFilter(typeImg, true);
+                reqRandom = CharacterFiltUtil.inputFilter(reqRandom, true);
+                if("".equals(typeName) || "".equals(typeCode) || "".equals(parentId) || "".equals(kind) || "".equals(reqRandom)) {
+                    retCode = "100110070101";
+                    retMsg = "对不起,您输入的信息有为空的必填项,请检查!";
+                } else if(typeName.length() > 30 || typeCode.length() > 10 || parentId.length() != 36) {
+                    retCode = "100110070102";
+                    retMsg = "对不起,您输入的信息有超出字数限制的项,请检查!";
+                } else if(RandomUtil.verifySysRandom(reqRandom, sysRandom)) {
+                    retCode = "100110070103";
+                    retMsg = "对不起,您已经提交过了,请不要重复提交!";
+                } else {
+                    randomUtil.setSysRandom(userId);
+                    typeEntity.setTypeName(typeName);
+                    typeEntity.setTypeCode(typeCode);
+                    typeEntity.setKind(kind);
+                    typeEntity.setParentId(parentId);
+                    typeEntity.setTypeImg(typeImg);
+                    pinyin = PinyinUtil.pinYin(typeName);
+                    jianpin = PinyinUtil.jianPin(typeName);
+                    typeEntity.setPinyin(pinyin);
+                    typeEntity.setJianpin(jianpin);
+                    typeEntity.setOptUser(userId);
+                    int r;
+                    if("".equals(typeId)) {
+                        r = typeService.addType(typeEntity);
+                    } else {
+                        typeEntity.setTypeId(typeId);
+                        r = typeService.edtType(typeEntity);
+                    }
+                    if(r != 0) {
+                        retCode = "1001";
+                        retMsg = "恭喜您,分类保存成功!";
+                    } else {
+                        retCode = "100110070104";
+                        retMsg = "对不起,系统错误,请联系系统管理员!";
+                    }
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+
+    /**
+     * deleteType 删除分类
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "删除角色信息")
+    @RequestMapping(value="/delete", method= RequestMethod.POST)
+    @ApiImplicitParam(name = "typeVo", value = "角色实体对象", paramType = "body", dataType="SysTypeVo", dataTypeClass = SysTypeVo.class, required = true)
+    public Map<String, Object> deleteType(@RequestBody SysTypeVo typeVo, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token, kind;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            AuthEntity auth = authUtil.getUserId(token);
+            if(auth == null || !auth.isSuccess()) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                List<String> ids = typeVo.getTypeIds();
+                kind = req.getParameter("kind");
+                kind = CharacterFiltUtil.inputFilter(kind, true);
+                if(ids==null ||ids.size()==0 || "".equals(kind)) {
+                    retCode = "100110070201";
+                    retMsg = "对不起,您提交的信息有为空的必填项,请检查!";
+                } else {
+                    typeVo.setOptUser(auth.getUserId());
+                    typeVo.setKind(kind);
+                    typeVo.setName("");
+                    int r = typeService.delTypes(typeVo);
+                    if(r != 0) {
+                        retCode = "1001";
+                        retMsg = "恭喜您,分类删除成功!";
+                    } else {
+                        retCode = "100110070204";
+                        retMsg = "对不起,系统错误,请联系系统管理员!";
+                    }
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+
+    /**
+     * getType 获取单一分类
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "获取分类详情信息")
+    @RequestMapping(value="/getById", method= RequestMethod.GET)
+    @ApiImplicitParam(name = "typeId", value = "分类编号", paramType = "query", dataType="string", dataTypeClass = String.class, required = true)
+    public Map<String, Object> getType(String typeId, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token;
+        SysTypeEntity typeEntity;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            boolean auth = authUtil.hasLogin(token);
+            if(!auth) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                typeId = CharacterFiltUtil.inputFilter(typeId, true);
+                if("".equals(typeId) || typeId.length() != 36) {
+                    retCode = "100110070301";
+                    retMsg = "对不起,您请求的参数非法,请重试!";
+                } else {
+                    typeEntity = typeService.getType(typeId);
+                    if(typeEntity != null) {
+                        result.put("data", typeEntity);
+                        retCode = "1001";
+                        retMsg = "查询成功。";
+                    } else {
+                        retCode = "100110070305";
+                        retMsg = "暂无内容";
+                    }
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+
+    /**
+     * listTypes 列表显示分类
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "获取分类树状列表")
+    @RequestMapping(value="/list", method= RequestMethod.GET)
+    @ApiImplicitParams({
+        @ApiImplicitParam(name = "kind", value = "种类", paramType = "query", dataType="string", dataTypeClass = String.class),
+        @ApiImplicitParam(name = "parentId", value = "父级编号", paramType = "query", dataType="int", dataTypeClass = Integer.class)
+    })
+    public Map<String, Object> listTypes(String kind, String parentId, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            boolean auth = authUtil.hasLogin(token);
+            if(!auth) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                kind = CharacterFiltUtil.inputFilter(kind, true);
+                parentId = CharacterFiltUtil.inputFilter(parentId, true);
+                parentId = parentId==null || "".equals(parentId) ? "00000000-0000-0000-0000-000000000000" : parentId;
+                List<SysTypeEntity> typeEntities = typeService.listTypes(kind, parentId);
+                if(typeEntities != null && typeEntities.size() > 0) {
+                    result.put("data", typeEntities);
+                    retCode = "1001";
+                    retMsg = "查询成功。";
+                } else {
+                    retCode = "100110070405";
+                    retMsg = "暂无内容";
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+
+    /**
+     * selTypes 下拉选择分类列表
+     */
+    @ApiOperation(value = "获取分类下拉列表")
+    @RequestMapping(value="/select", method= RequestMethod.GET)
+    @ApiImplicitParams({
+        @ApiImplicitParam(name = "schName", value = "关键字", paramType = "query", dataType="string", dataTypeClass = String.class),
+        @ApiImplicitParam(name = "kind", value = "组织编号", paramType = "query", dataType="string", dataTypeClass = String.class),
+        @ApiImplicitParam(name = "parentId", value = "职务编号", paramType = "query", dataType="string", dataTypeClass = String.class)
+    })
+    private Map<String, Object> selTypes(String schName, String kind, String parentId, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            boolean auth = authUtil.hasLogin(token);
+            if(!auth) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                kind = CharacterFiltUtil.inputFilter(kind, true);
+                schName = CharacterFiltUtil.inputFilter(schName, true);
+                parentId = CharacterFiltUtil.inputFilter(parentId, true);
+                if("".equals(parentId) || parentId.length() != 36 || "".equals(kind) || kind.length() != 36) {
+                    retCode = "100110070501";
+                    retMsg = "对不起,您请求的参数不正确,请重试!";
+                } else {
+                    SysTypeVo typeVo = new SysTypeVo();
+                    typeVo.setKind(kind);
+                    typeVo.setName(schName);
+                    typeVo.setParentId(parentId);
+                    List<SysTypeEntity> typeEntities = typeService.selTypes(typeVo);
+                    if(typeEntities!=null && typeEntities.size()>0) {
+                        result.put("entities", typeEntities);
+                        retCode = "1001";
+                        retMsg = "查询成功。";
+                    } else {
+                        retCode = "100110070505";
+                        retMsg = "暂无内容";
+                    }
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+
+    /**
+     * sortTypes 统计某分类下的子分类数量,用于自动排序
+     */
+    @ApiOperation(value = "获取分类下拉列表")
+    @RequestMapping(value="/sort", method= RequestMethod.GET)
+    @ApiImplicitParam(name = "parentId", value = "职务编号", paramType = "query", dataType="string", dataTypeClass = String.class)
+    private Map<String, Object> sortTypes(String parentId, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            boolean auth = authUtil.hasLogin(token);
+            if(!auth) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                parentId = CharacterFiltUtil.inputFilter(parentId, true);
+                if("".equals(parentId) || parentId.length() != 36) {
+                    retCode = "100110070601";
+                    retMsg = "对不起,您请求的参数不正确,请重试!";
+                } else {
+                    int typeNum = typeService.sortTypes(parentId);
+                    result.put("typeNum", typeNum);
+                    retCode = "1001";
+                    retMsg = "查询成功。";
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+}

+ 533 - 0
src/main/java/cn/aiyangniu/api/controller/system/SysUserController.java

@@ -0,0 +1,533 @@
+package cn.aiyangniu.api.controller.system;
+
+import cn.aiyangniu.api.common.entity.system.*;
+import cn.aiyangniu.api.common.util.*;
+import cn.aiyangniu.api.service.system.SysUserService;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.*;
+
+/**
+ * 用户业务接口类
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+@Slf4j
+@RestController
+@Api(tags="系统管理员接口")
+@RequestMapping("/sysUser")
+public class SysUserController {
+
+    @Resource
+    private SysUserService usrService;
+
+    @Resource
+    private RandomUtil randomUtil;
+
+    @Resource
+    private AuthUtil authUtil;
+
+    @Resource
+    private RedisUtil redisUtil;
+
+    /**
+     * saveUsr 新增/修改用户
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "新增/修改角色信息")
+    @RequestMapping(value="/save", method= RequestMethod.POST)
+    @ApiImplicitParam(name = "usrEntity", value = "用户实体对象", paramType = "body", dataType="SysUserEntity", dataTypeClass = SysUserEntity.class, required = true)
+    public Map<String, Object> saveUser(@RequestBody SysUserEntity usrEntity, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, sysRandom, token, reqRandom, userId, nickName, mobile, usname, passwd, orgId, dutyId, roleId;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            AuthEntity auth = authUtil.getUserId(token);
+            if(auth == null || !auth.isSuccess()) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                sysRandom = randomUtil.getSysRandom(auth.getUserId());
+                userId = usrEntity.getUserId();
+                nickName = usrEntity.getNickName();
+                mobile = usrEntity.getMobile();
+                usname = usrEntity.getUsname();
+                passwd = usrEntity.getPasswd();
+                orgId = usrEntity.getOrgId();
+                dutyId = usrEntity.getDutyId();
+                roleId = usrEntity.getRoleId();
+                reqRandom = usrEntity.getReqRandom();
+                userId = CharacterFiltUtil.inputFilter(userId, true);
+                nickName = CharacterFiltUtil.inputFilter(nickName, true);
+                mobile = CharacterFiltUtil.inputFilter(mobile, true);
+                usname = CharacterFiltUtil.inputFilter(usname, true);
+                passwd = CharacterFiltUtil.inputFilter(passwd, true);
+                orgId = CharacterFiltUtil.inputFilter(orgId, true);
+                dutyId = CharacterFiltUtil.inputFilter(dutyId, true);
+                roleId = CharacterFiltUtil.inputFilter(roleId, true);
+                reqRandom = CharacterFiltUtil.inputFilter(reqRandom, true);
+                SysUserVo usrVo = new SysUserVo();
+                usrVo.setUserId(userId);
+                usrVo.setUsname(usname);
+                boolean exists = usrService.extUser(usrVo)>0;
+                if("".equals(nickName) || "".equals(mobile) || "".equals(usname) || ("".equals(userId) && "".equals(passwd)) || "".equals(orgId) || "".equals(dutyId) || "".equals(roleId) || "".equals(reqRandom)) {
+                    retCode = "100110050101";
+                    retMsg = "对不起,您输入的信息有为空的必填项,请检查!";
+                } else if(nickName.length() > 30 || mobile.length() != 11 || usname.length() > 30 || passwd.length() > 30 || orgId.length() != 36 || dutyId.length() != 36 || roleId.length() != 36) {
+                    retCode = "100110050102";
+                    retMsg = "对不起,您输入的信息有超出字数限制的项,请检查!";
+                } else if(RandomUtil.verifySysRandom(reqRandom, sysRandom)) {
+                    retCode = "100110050103";
+                    retMsg = "对不起,您已经提交过了,请不要重复提交!";
+                } else if(exists) {
+                    retCode = "100110050106";
+                    retMsg = "对不起,您输入的登录账号已经存在,请更换!";
+                } else {
+                    randomUtil.setSysRandom(auth.getUserId());
+                    if(!"".equals(passwd) && !"********".equals(passwd)) {
+                        passwd = Md5Util.strMd5(passwd);
+                    }
+                    usrEntity.setNickName(nickName);
+                    usrEntity.setMobile(mobile);
+                    usrEntity.setUsname(usname);
+                    usrEntity.setPasswd(passwd);
+                    usrEntity.setOrgId(orgId);
+                    usrEntity.setDutyId(dutyId);
+                    usrEntity.setRoleId(roleId);
+                    usrEntity.setOptUser(auth.getUserId());
+                    int r;
+                    if("".equals(userId)) {
+                        usrEntity.setUserId(UUIDUtil.create36UUID());
+                        r = usrService.addUser(usrEntity);
+                    } else {
+                        usrEntity.setUserId(userId);
+                        r = usrService.edtUser(usrEntity);
+                    }
+                    if(r != 0) {
+                        retCode = "1001";
+                        retMsg = "恭喜您,用户保存成功!";
+                    } else {
+                        retCode = "100110050104";
+                        retMsg = "对不起,系统错误,请联系系统管理员!";
+                    }
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+
+    /**
+     * proUsrs 删除用户
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "删除角色信息")
+    @RequestMapping(value="/process", method= RequestMethod.POST)
+    @ApiImplicitParam(name = "roleEntity", value = "角色实体对象", paramType = "body", dataType="SysRoleEntity", dataTypeClass = SysRoleEntity.class, required = true)
+    public Map<String, Object> proUsers(HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token, ids, dataStatus;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            AuthEntity auth = authUtil.getUserId(token);
+            if(auth == null || !auth.isSuccess()) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                ids = req.getParameter("ids");
+                dataStatus = req.getParameter("dataStatus");
+                ids = CharacterFiltUtil.inputFilter(ids, true);
+                dataStatus = CharacterFiltUtil.inputFilter(dataStatus, true);
+                int iStatus = CharacterFiltUtil.isInt(dataStatus) ? Integer.parseInt(dataStatus) : 0;
+                if("".equals(ids) || iStatus == 0) {
+                    retCode = "100110050201";
+                    retMsg = "对不起,您提交的信息有为空的必填项,请检查!";
+                } else {
+                    List<String> userIds = Arrays.asList(ids.split(","));
+                    SysUserVo usrVo = new SysUserVo();
+                    usrVo.setDataStatus(iStatus);
+                    usrVo.setOptUser(auth.getUserId());
+                    usrVo.setUserIds(userIds);
+                    int r = usrService.proUsers(usrVo);
+                    if(r != 0) {
+                        retCode = "1001";
+                        switch(iStatus) {
+                            case 1:
+                                retMsg = "恭喜您,用户审核成功!";
+                                break;
+                            case 2:
+                                retMsg = "恭喜您,用户取消审核成功!";
+                                break;
+                            case 3:
+                                retMsg = "恭喜您,用户删除成功!";
+                                break;
+                            default:
+                                retMsg = "恭喜您,用户处理成功!";
+                                break;
+                        }
+                    } else {
+                        retCode = "100110050204";
+                        retMsg = "对不起,系统错误,请联系系统管理员!";
+                    }
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+
+    /**
+     * getUser 获取单一用户
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "获取用户详情信息")
+    @RequestMapping(value="/getById", method= RequestMethod.GET)
+    @ApiImplicitParam(name = "userId", value = "用户编号", paramType = "query", dataType="string", dataTypeClass = String.class, required = true)
+    public Map<String, Object> getUser(String userId, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token;
+        SysUserEntity usrEntity;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            boolean auth = authUtil.hasLogin(token);
+            if(!auth) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                userId = CharacterFiltUtil.inputFilter(userId, true);
+                if("".equals(userId) || userId.length() != 36) {
+                    retCode = "100110050301";
+                    retMsg = "对不起,您请求的参数非法,请重试!";
+                } else {
+                    usrEntity = usrService.getUser(userId);
+                    if(usrEntity != null) {
+                        result.put("data", usrEntity);
+                        retCode = "1001";
+                        retMsg = "查询成功。";
+                    } else {
+                        retCode = "100110050305";
+                        retMsg = "暂无内容";
+                    }
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+
+    /**
+     * listUsrs 列表显示用户
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "获取用户分页列表")
+    @RequestMapping(value="/page", method= RequestMethod.GET)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "schName", value = "关键字", paramType = "query", dataType="string", dataTypeClass = String.class),
+            @ApiImplicitParam(name = "orgId", value = "组织编号", paramType = "query", dataType="int", dataTypeClass = Integer.class),
+            @ApiImplicitParam(name = "dutyId", value = "职务编号", paramType = "query", dataType="int", dataTypeClass = Integer.class),
+            @ApiImplicitParam(name = "roleId", value = "角色编号", paramType = "query", dataType="int", dataTypeClass = Integer.class),
+            @ApiImplicitParam(name = "states", value = "用户状态", paramType = "query", dataType="int", dataTypeClass = Integer.class),
+            @ApiImplicitParam(name = "offset", value = "开始数据", paramType = "query", dataType="int", dataTypeClass = Integer.class, required = true),
+            @ApiImplicitParam(name = "limit", value = "每页数量", paramType = "query", dataType="int", dataTypeClass = Integer.class, required = true)
+    })
+    public Map<String, Object> listUsers(String schName, String orgId, String dutyId, String roleId, Integer states, Integer offset, Integer limit, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token;
+        int kind, pageNo;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            AuthEntity auth = authUtil.getUserId(token);
+            if(auth == null || !auth.isSuccess()) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                schName = CharacterFiltUtil.inputFilter(schName, true);
+                orgId = CharacterFiltUtil.inputFilter(orgId, true);
+                dutyId = CharacterFiltUtil.inputFilter(dutyId, true);
+                roleId = CharacterFiltUtil.inputFilter(roleId, true);
+                kind = (auth.getUserId().contains("glyhv") ? 1 : 2);
+                SysUserVo usrVo = new SysUserVo();
+                usrVo.setName(schName);
+                usrVo.setOrgId(orgId);
+                usrVo.setDutyId(dutyId);
+                usrVo.setRoleId(roleId);
+                usrVo.setDataStatus(states);
+                usrVo.setKind(kind);
+                pageNo = offset / limit + 1;
+                IPage<SysUserDto> iPage = usrService.listUsers(usrVo, pageNo, limit);
+                if(iPage != null && iPage.getRecords() != null && iPage.getRecords().size() > 0) {
+                    result.put("data", iPage.getRecords());
+                    result.put("total", iPage.getTotal());
+                    retCode = "1001";
+                    retMsg = "查询成功。";
+                } else {
+                    retCode = "100110050405";
+                    retMsg = "暂无内容";
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+
+    /**
+     * selUsrs 下拉选择用户列表
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "获取用户下拉列表")
+    @RequestMapping(value="/select", method= RequestMethod.GET)
+    @ApiImplicitParam(name = "schName", value = "关键字", paramType = "query", dataType="string", dataTypeClass = String.class)
+    public Map<String, Object> selUsers(String schName, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            AuthEntity auth = authUtil.getUserId(token);
+            if(auth == null || !auth.isSuccess()) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                schName = CharacterFiltUtil.inputFilter(schName, true);
+                int kind = (auth.getUserId().contains("glyhv") ? 1 : 2);
+                SysUserVo usrVo = new SysUserVo();
+                usrVo.setName(schName);
+                usrVo.setKind(kind);
+                List<SysUserDto> usrDtoList = usrService.selUsers(usrVo);
+                if(usrDtoList != null && usrDtoList.size() > 0) {
+                    result.put("data", usrDtoList);
+                    retCode = "1001";
+                    retMsg = "查询成功。";
+                } else {
+                    retCode = "100110050505";
+                    retMsg = "暂无内容";
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+
+    /**
+     * loginUsr 用户登录
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "获取用户下拉列表")
+    @RequestMapping(value="/login", method= RequestMethod.POST)
+    @ApiImplicitParam(name = "usrVo", value = "用户登录的对象", paramType = "query", dataType="SysUserVo", dataTypeClass = SysUserVo.class)
+    public Map<String, Object> loginUser(@RequestBody SysUserVo usrVo,  HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, username, password, ipAddr, key;
+        int times = 0;
+        ipAddr = ClientIpUtil.getIPAddr(req);
+        key = "ip_" + ipAddr;
+        if(redisUtil.exists(key)) {
+            times = redisUtil.get(key);
+            times++;
+        }
+        redisUtil.add(key, times, 1800);
+        result.put("show", (times>10 ? 1 : 2));
+        username = usrVo.getUsname();
+        password = usrVo.getPasswd();
+        username = CharacterFiltUtil.inputFilter(username, true);
+        password = CharacterFiltUtil.inputFilter(password, true);
+        password = Md5Util.strMd5(password);
+        usrVo.setPasswd(password);
+        if("".equals(username) || "".equals(password)) {
+            retCode = "100110050601";
+            retMsg = "对不起,您输入的信息有为空的必填项,请检查!";
+        } else {
+            SysUserDto usrDto = usrService.loginUser(usrVo);
+            if(usrDto == null) {
+                retCode = "100110050607";
+                retMsg = "对不起,您的用户名或密码不正确,请重试!";
+            } else {
+                int flag = usrDto.getDataStatus();
+                if(flag == 2) {
+                    retCode = "100110050608";
+                    retMsg = "对不起,您的账号未被审核,请联系系统管理员!";
+                } else {
+                    String xAuthKey = UUIDUtil.create32UUID();
+                    authUtil.setUserSession(usrDto, xAuthKey);
+                    result.put("data", xAuthKey);
+                    redisUtil.delete(key);
+                    retCode = "1001";
+                    retMsg = "恭喜您,登录成功!";
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+
+    /**
+     * userSession 获取用户Session
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "获取用户Session")
+    @RequestMapping(value="/session", method= RequestMethod.GET)
+    public Map<String, Object> userSession(HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            JSONObject session = authUtil.getUserSession(token);
+            if(session == null) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                result.put("data", session);
+                retCode = "1001";
+                retMsg = "查询成功。";
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+
+    /**
+     * exitUser 退出登录
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "退出登录")
+    @RequestMapping(value="/exit", method= RequestMethod.POST)
+    public Map<String, Object> exitUser(HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            authUtil.delUserSession(token);
+            retCode = "1001";
+            retMsg = "退出成功。";
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+
+    /**
+     * edtUsr 修改个人资料
+     *
+     * @param req 请求对象
+     * @return 返回结果Json串
+     */
+    @ApiOperation(value = "修改个人资料")
+    @RequestMapping(value="/edit", method= RequestMethod.POST)
+    @ApiImplicitParam(name = "usrEntity", value = "用户登录的对象", paramType = "query", dataType="SysUserEntity", dataTypeClass = SysUserEntity.class)
+    public Map<String, Object> edtUser(@RequestBody SysUserEntity usrEntity, HttpServletRequest req) {
+        Map<String, Object> result = new HashMap<>();
+        String retCode, retMsg, token, userId, nickName, mobile, usname, passwd;
+        token = req.getHeader("Authorization");
+        if(token == null || "null".equals(token)) {
+            retCode = "1002";
+            retMsg = "对不起,您的操作非法,请登录!";
+        } else {
+            boolean auth = authUtil.hasLogin(token);
+            if(!auth) {
+                retCode = "1002";
+                retMsg = "对不起,您没有登录或会话超时,请重新登录!";
+            } else {
+                userId = usrEntity.getUserId();
+                nickName = usrEntity.getNickName();
+                usname = usrEntity.getUsname();
+                passwd = usrEntity.getPasswd();
+                mobile = usrEntity.getMobile();
+                userId = CharacterFiltUtil.inputFilter(userId, true);
+                nickName = CharacterFiltUtil.inputFilter(nickName, true);
+                usname = CharacterFiltUtil.inputFilter(usname, true);
+                passwd = CharacterFiltUtil.inputFilter(passwd, true);
+                mobile = CharacterFiltUtil.inputFilter(mobile, true);
+                SysUserVo usrVo = new SysUserVo();
+                usrVo.setUserId(userId);
+                usrVo.setUsname(usname);
+                boolean exists = usrService.extUser(usrVo)>0;
+                if("".equals(userId) || "".equals(nickName) || "".equals(mobile) || "".equals(usname)) {
+                    retCode = "100110050901";
+                    retMsg = "对不起,您输入的信息有为空的必填项,请检查!";
+                } else if(userId.length() != 36 || nickName.length() > 30 || usname.length() > 30 || passwd.length() > 30 || mobile.length() != 11) {
+                    retCode = "100110050902";
+                    retMsg = "对不起,您输入的信息有超出字数限制的项,请检查!";
+                } else if(exists) {
+                    retCode = "100110050906";
+                    retMsg = "对不起,您输入的登录账号已经存在,请更换!";
+                } else {
+                    if(!"".equals(passwd) && !"********".equals(passwd)) {
+                        passwd = Md5Util.strMd5(passwd);
+                    }
+                    usrEntity.setUserId(userId);
+                    usrEntity.setNickName(nickName);
+                    usrEntity.setMobile(mobile);
+                    usrEntity.setUsname(usname);
+                    usrEntity.setPasswd(passwd);
+                    usrEntity.setOptUser(userId);
+                    int r = usrService.updUser(usrEntity);
+                    if(r != 0) {
+                        retCode = "1001";
+                        retMsg = "恭喜您,个人资料修改成功,请重新登录以便生效!";
+                    } else {
+                        retCode = "100110050904";
+                        retMsg = "对不起,系统错误,请联系系统管理员!";
+                    }
+                }
+            }
+        }
+        result.put("code", retCode);
+        result.put("msg", retMsg);
+        return result;
+    }
+}

+ 24 - 0
src/main/java/cn/aiyangniu/api/mapper/system/SysAreaMapper.java

@@ -0,0 +1,24 @@
+package cn.aiyangniu.api.mapper.system;
+
+import cn.aiyangniu.api.common.entity.system.SysAreaEntity;
+import cn.aiyangniu.api.common.entity.system.SysAreaVo;
+import org.apache.ibatis.annotations.Mapper;
+import java.util.List;
+
+/**
+ * SysAreaMapper 区域数据接口类
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+@Mapper
+public interface SysAreaMapper {
+
+    /**
+     * selAreas 下拉选择展示区域
+     *
+     * @param areaVo 父级区域编号
+     * @return 返回结果
+     */
+    List<SysAreaEntity> selAreas(SysAreaVo areaVo);
+}

+ 84 - 0
src/main/java/cn/aiyangniu/api/mapper/system/SysBtnMapper.java

@@ -0,0 +1,84 @@
+package cn.aiyangniu.api.mapper.system;
+
+import cn.aiyangniu.api.common.entity.system.SysBtnEntity;
+import cn.aiyangniu.api.common.entity.system.SysBtnVo;
+import cn.aiyangniu.api.common.entity.system.SysModVo;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import java.util.List;
+
+/**
+ * 按钮数据接口类
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+@Mapper
+public interface SysBtnMapper {
+
+    /**
+     * addBtn 新增按钮
+     *
+     * @param btnEntity 按钮实体对象
+     * @return 返回新增结果
+     */
+    int addBtn(SysBtnEntity btnEntity);
+
+    /**
+     * delBtns 删除按钮
+     *
+     * @param sysBtnVo 按钮Vo对象
+     * @return 返回删除结果
+     */
+    int delBtns(SysBtnVo sysBtnVo);
+
+    /**
+     * delBtnsByModId删除按钮
+     *
+     * @param sysModVo 按钮Vo对象
+     * @return 返回删除结果
+     */
+    int delBtnsByModId(SysModVo sysModVo);
+
+    /**
+     * getBtn 获取单一按钮编号详情
+     *
+     * @param btnId 按钮编号
+     * @return 返回详情结果
+     */
+    SysBtnEntity getBtn(String btnId);
+
+    /**
+     * edtBtn 修改按钮
+     *
+     * @param btnEntity 按钮实体对象
+     * @return 返回修改结果
+     */
+    int edtBtn(SysBtnEntity btnEntity);
+
+    /**
+     * listBtns 列表展示按钮
+     *
+     * @param page 分页对象对象
+     * @param sysBtnVo 按钮Vo对象
+     * @return 返回新增结果
+     */
+    IPage<SysBtnEntity> listBtns(@Param("page") Page<SysBtnEntity> page, @Param("vo") SysBtnVo sysBtnVo);
+
+    /**
+     * sortBtns 统计子级按钮数量,用于排序
+     *
+     * @param modId 模块编号
+     * @return 返回新增结果
+     */
+    int sortBtns(String modId);
+
+    /**
+     * selBtns 下拉选择展示按钮
+     *
+     * @return 返回新增结果
+     */
+    List<SysBtnEntity> selBtns();
+}

+ 71 - 0
src/main/java/cn/aiyangniu/api/mapper/system/SysModMapper.java

@@ -0,0 +1,71 @@
+package cn.aiyangniu.api.mapper.system;
+
+import cn.aiyangniu.api.common.entity.system.SysModEntity;
+import cn.aiyangniu.api.common.entity.system.SysModVo;
+import org.apache.ibatis.annotations.Mapper;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * SysModMapper 系统模块数据接口类
+ *
+ * @author Henry Hall
+ * @since 2020-09-28
+ */
+@Mapper
+public interface SysModMapper {
+
+    /**
+     * addMod 新增模块
+     *
+     * @param modEntity 模块实体对象
+     * @return 返回新增结果
+     */
+    int addMod(SysModEntity modEntity);
+
+    /**
+     * delMods 删除模块
+     *
+     * @param sysModVo 模块Vo对象
+     * @return 返回删除结果
+     */
+    int delMods(SysModVo sysModVo);
+
+    /**
+     * getMod 获取单一模块编号详情
+     *
+     * @param modId 模块编号
+     * @return 返回详情结果
+     */
+    SysModEntity getMod(String modId);
+
+    /**
+     * edtMod 修改模块
+     *
+     * @param modEntity 模块实体对象
+     * @return 返回修改结果
+     */
+    int edtMod(SysModEntity modEntity);
+
+    /**
+     * listMods 列表展示模块
+     *
+     * @return 返回新增结果
+     */
+    List<SysModEntity> listMods();
+
+    /**
+     * selMods 下拉选择模块
+     *
+     * @return 返回新增结果
+     */
+    List<SysModEntity> selMods(String schName);
+
+    /**
+     * sortMods 统计子级模块数量,用于排序
+     *
+     * @param parentId 父级编号
+     * @return 返回新增结果
+     */
+    int sortMods(String parentId);
+}

+ 68 - 0
src/main/java/cn/aiyangniu/api/mapper/system/SysMsgMapper.java

@@ -0,0 +1,68 @@
+package cn.aiyangniu.api.mapper.system;
+
+import cn.aiyangniu.api.common.entity.system.SysMsgEntity;
+import cn.aiyangniu.api.common.entity.system.SysMsgVo;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * SysMsgMapper 系统消息数据接口类
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+@Mapper
+public interface SysMsgMapper {
+
+    /**
+     * addMsg 新增消息
+     *
+     * @param msgEntity 消息实体对象
+     * @return 返回新增结果
+     */
+    int addMsg(SysMsgEntity msgEntity);
+
+    /**
+     * addMsg 新增消息
+     *
+     * @param msgEntity 消息实体对象
+     * @return 返回新增结果
+     */
+    int addMsgDetail(SysMsgEntity msgEntity);
+
+    /**
+     * proMsgs 已读、删除消息
+     *
+     * @param sysMsgVo 消息Vo对象
+     * @return 返回删除结果
+     */
+    int proMsgs(SysMsgVo sysMsgVo);
+
+    /**
+     * listMsgs 列表展示消息
+     *
+     * @param page 分页对象对象
+     * @param sysMsgVo 消息Vo对象
+     * @return 返回新增结果
+     */
+    IPage<SysMsgEntity> listMsgs(@Param("page") Page<SysMsgEntity> page, @Param("vo") SysMsgVo sysMsgVo);
+
+    /**
+     * 我的消息列表
+     *
+     * @param page 分页对象对象
+     * @param sysMsgVo 消息Vo对象
+     * @return 返回新增结果
+     */
+    IPage<SysMsgEntity> myMsgs(@Param("page") Page<SysMsgEntity> page, @Param("vo") SysMsgVo sysMsgVo);
+
+    /**
+     * getMsg 获取单一消息编号详情
+     *
+     * @param msgId 消息编号
+     * @return 返回详情结果
+     */
+    SysMsgEntity getMsg(String msgId);
+}

+ 85 - 0
src/main/java/cn/aiyangniu/api/mapper/system/SysOptMapper.java

@@ -0,0 +1,85 @@
+package cn.aiyangniu.api.mapper.system;
+
+import cn.aiyangniu.api.common.entity.system.SysOptEntity;
+import cn.aiyangniu.api.common.entity.system.SysOptVo;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * SysOptMapper 选项数据接口类
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+@Mapper
+public interface SysOptMapper {
+
+    /**
+     * addOpt 新增选项
+     *
+     * @param optEntity 选项实体对象
+     * @return 返回新增结果
+     */
+    int addOpt(SysOptEntity optEntity);
+
+    /**
+     * delOpts 删除选项
+     *
+     * @param sysOptVo 选项Vo对象
+     * @return 返回删除结果
+     */
+    int delOpts(SysOptVo sysOptVo);
+
+    /**
+     * delOpts 删除选项
+     *
+     * @param sysOptVo 选项Vo对象
+     * @return 返回删除结果
+     */
+    int delChildOpts(SysOptVo sysOptVo);
+
+    /**
+     * getOpt 获取单一选项编号详情
+     *
+     * @param optId 选项编号
+     * @return 返回详情结果
+     */
+    SysOptEntity getOpt(String optId);
+
+    /**
+     * edtOpt 修改选项
+     *
+     * @param optEntity 选项实体对象
+     * @return 返回修改结果
+     */
+    int edtOpt(SysOptEntity optEntity);
+
+    /**
+     * listOpts 列表展示选项
+     *
+     * @param page 分页对象对象
+     * @param sysOptVo 选项Vo对象
+     * @return 返回结果
+     */
+    IPage<SysOptEntity> listOpts(@Param("page") Page<SysOptEntity> page, @Param("vo") SysOptVo sysOptVo);
+
+    /**
+     * sortOpts 统计子级选项数量,用于排序
+     *
+     * @param kind 选项种类
+     * @return 返回结果
+     */
+    int sortOpts(String kind);
+
+    /**
+     * selOpts 下拉选择展示选项
+     *
+     * @param reqMap 请求的名称及种类参数
+     * @return 返回结果
+     */
+    List<SysOptEntity> selOpts(Map<String, String> reqMap);
+}

+ 68 - 0
src/main/java/cn/aiyangniu/api/mapper/system/SysRoleMapper.java

@@ -0,0 +1,68 @@
+package cn.aiyangniu.api.mapper.system;
+
+import cn.aiyangniu.api.common.entity.system.SysRoleEntity;
+import cn.aiyangniu.api.common.entity.system.SysRoleVo;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import java.util.List;
+
+/**
+ * 角色数据接口类
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+@Mapper
+public interface SysRoleMapper {
+
+    /**
+     * addRole 新增角色
+     *
+     * @param roleEntity 角色实体对象
+     * @return 返回新增结果
+     */
+    int addRole(SysRoleEntity roleEntity);
+
+    /**
+     * delRoles 删除角色
+     *
+     * @param sysRoleVo 角色Vo对象
+     * @return 返回删除结果
+     */
+    int delRoles(SysRoleVo sysRoleVo);
+
+    /**
+     * getRole 获取单一角色编号详情
+     *
+     * @param roleId 角色编号
+     * @return 返回详情结果
+     */
+    SysRoleEntity getRole(String roleId);
+
+    /**
+     * edtRole 修改角色
+     *
+     * @param roleEntity 角色实体对象
+     * @return 返回修改结果
+     */
+    int edtRole(SysRoleEntity roleEntity);
+
+    /**
+     * listRoles 列表展示角色
+     *
+     * @param page 分页对象对象
+     * @param sysRoleVo 角色Vo对象
+     * @return 返回新增结果
+     */
+    IPage<SysRoleEntity> listRoles(@Param("page") Page<SysRoleEntity> page, @Param("vo") SysRoleVo sysRoleVo);
+
+    /**
+     * selRoles 下拉选择展示角色
+     *
+     * @param auth 是否有查看全部角色的权限
+     * @return 返回新增结果
+     */
+    List<SysRoleEntity> selRoles(int auth);
+}

+ 72 - 0
src/main/java/cn/aiyangniu/api/mapper/system/SysTypeMapper.java

@@ -0,0 +1,72 @@
+package cn.aiyangniu.api.mapper.system;
+
+import cn.aiyangniu.api.common.entity.system.SysTypeEntity;
+import cn.aiyangniu.api.common.entity.system.SysTypeVo;
+import org.apache.ibatis.annotations.Mapper;
+import java.util.List;
+
+/**
+ * SysTypeMapper 分类数据接口类
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+@Mapper
+public interface SysTypeMapper {
+
+    /**
+     * addType 新增分类
+     *
+     * @param typeEntity 分类实体对象
+     * @return 返回新增结果
+     */
+    int addType(SysTypeEntity typeEntity);
+
+    /**
+     * delTypes 删除分类
+     *
+     * @param sysTypeVo 分类Vo对象
+     * @return 返回删除结果
+     */
+    int delTypes(SysTypeVo sysTypeVo);
+
+    /**
+     * getType 获取单一分类编号详情
+     *
+     * @param typeId 分类编号
+     * @return 返回详情结果
+     */
+    SysTypeEntity getType(String typeId);
+
+    /**
+     * edtType 修改分类
+     *
+     * @param typeEntity 分类实体对象
+     * @return 返回修改结果
+     */
+    int edtType(SysTypeEntity typeEntity);
+
+    /**
+     * listTypes 列表展示分类
+     *
+     * @param kind 分类种类编号
+     * @return 返回新增结果
+     */
+    List<SysTypeEntity> listTypes(String kind);
+
+    /**
+     * sortTypes 统计子级分类数量,用于排序
+     *
+     * @param parentId 请求参数
+     * @return 返回新增结果
+     */
+    int sortTypes(String parentId);
+
+    /**
+     * selTypes 下拉选择展示分类
+     *
+     * @param sysTypeVo 分类Vo对象
+     * @return 返回新增结果
+     */
+    List<SysTypeEntity> selTypes(SysTypeVo sysTypeVo);
+}

+ 93 - 0
src/main/java/cn/aiyangniu/api/mapper/system/SysUserMapper.java

@@ -0,0 +1,93 @@
+package cn.aiyangniu.api.mapper.system;
+
+import cn.aiyangniu.api.common.entity.system.SysUserDto;
+import cn.aiyangniu.api.common.entity.system.SysUserEntity;
+import cn.aiyangniu.api.common.entity.system.SysUserVo;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import java.util.List;
+
+/**
+ * 用户数据接口类
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+@Mapper
+public interface SysUserMapper {
+
+    /**
+     * addUser 新增用户
+     *
+     * @param userEntity 用户实体对象
+     * @return 返回新增结果
+     */
+    int addUser(SysUserEntity userEntity);
+
+    /**
+     * proUsers 删除用户
+     *
+     * @param sysUserVo 用户Vo对象
+     * @return 返回删除结果
+     */
+    int proUsers(SysUserVo sysUserVo);
+
+    /**
+     * getUser 获取单一用户编号详情
+     *
+     * @param userId 用户编号
+     * @return 返回详情结果
+     */
+    SysUserEntity getUser(String userId);
+
+    /**
+     * edtUser 修改用户
+     *
+     * @param userEntity 用户实体对象
+     * @return 返回修改结果
+     */
+    int edtUser(SysUserEntity userEntity);
+
+    /**
+     * listUsers 列表展示用户
+     *
+     * @param page 分页对象对象
+     * @param sysUserVo 用户Vo对象
+     * @return 返回新增结果
+     */
+    IPage<SysUserDto> listUsers(@Param("page") Page<SysUserDto> page, @Param("vo") SysUserVo sysUserVo);
+
+    /**
+     * selUsers 下拉选择展示用户
+     *
+     * @param sysUserVo 用户Vo对象
+     * @return 返回新增结果
+     */
+    List<SysUserDto> selUsers(SysUserVo sysUserVo);
+
+    /**
+     * extUser 根据账号查询重复的用户
+     *
+     * @param sysUserVo 用户Vo对象
+     * @return 返回新增结果
+     */
+    int extUser(SysUserVo sysUserVo);
+
+    /**
+     * loginUser 列表展示用户
+     *
+     * @param sysUserVo 用户Vo对象
+     * @return 返回新增结果
+     */
+    SysUserDto loginUser(SysUserVo sysUserVo);
+
+    /**
+     * updUser 修改个人资料
+     *
+     * @param userEntity 用户实体对象
+     * @return 返回修改结果
+     */
+    int updUser(SysUserEntity userEntity);
+}

+ 34 - 0
src/main/java/cn/aiyangniu/api/service/impl/system/SysAreaServiceImpl.java

@@ -0,0 +1,34 @@
+package cn.aiyangniu.api.service.impl.system;
+
+import cn.aiyangniu.api.service.system.SysAreaService;
+import cn.aiyangniu.api.common.entity.system.SysAreaEntity;
+import cn.aiyangniu.api.common.entity.system.SysAreaVo;
+import cn.aiyangniu.api.mapper.system.SysAreaMapper;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * SysAreaServiceImpl 区域服务实现类
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+@Service
+public class SysAreaServiceImpl implements SysAreaService {
+
+    @Resource
+    private SysAreaMapper areaMapper;
+
+    /**
+     * selAreas 下拉选择展示区域
+     *
+     * @param areaVo 父级区域编号
+     * @return 返回结果
+     */
+    @Override
+    public List<SysAreaEntity> selAreas(SysAreaVo areaVo) {
+        return areaMapper.selAreas(areaVo);
+    }
+}

+ 91 - 0
src/main/java/cn/aiyangniu/api/service/impl/system/SysBtnServiceImpl.java

@@ -0,0 +1,91 @@
+package cn.aiyangniu.api.service.impl.system;
+
+import cn.aiyangniu.api.service.system.SysBtnService;
+import cn.aiyangniu.api.common.entity.system.SysBtnEntity;
+import cn.aiyangniu.api.common.entity.system.SysBtnVo;
+import cn.aiyangniu.api.mapper.system.SysBtnMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+
+/**
+ * 按钮服务实现类
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+@Service
+public class SysBtnServiceImpl implements SysBtnService {
+
+    @Resource
+    private SysBtnMapper btnMapper;
+
+    /**
+     * addBtn 添加按钮
+     *
+     * @param btnEntity 按钮实体对象
+     * @return 返回保存结果
+     */
+    @Override
+    public int addBtn(SysBtnEntity btnEntity) {
+        return btnMapper.addBtn(btnEntity);
+    }
+
+    /**
+     * delBtns 删除按钮
+     *
+     * @param sysBtnVo 按钮Vo对象
+     * @return 返回删除结果
+     */
+    @Override
+    public int delBtns(SysBtnVo sysBtnVo) {
+        return btnMapper.delBtns(sysBtnVo);
+    }
+
+    /**
+     * getBtn 获取单一按钮
+     *
+     * @param btnId 按钮编号
+     * @return 返回按钮对象
+     */
+    @Override
+    public SysBtnEntity getBtn(String btnId) {
+        return btnMapper.getBtn(btnId);
+    }
+
+    /**
+     * edtBtn 修改按钮
+     *
+     * @param btnEntity 按钮实体对象
+     * @return 返回修改结果
+     */
+    @Override
+    public int edtBtn(SysBtnEntity btnEntity) {
+        return btnMapper.edtBtn(btnEntity);
+    }
+
+    /**
+     * listBtns 列表显示按钮
+     *
+     * @param sysBtnVo 按钮Vo对象
+     * @return 返回按钮列表
+     */
+    @Override
+    public IPage<SysBtnEntity> listBtns(SysBtnVo sysBtnVo, int pageNo, int pageSize) {
+        Page<SysBtnEntity> page = new Page<>(pageNo, pageSize);
+        return btnMapper.listBtns(page, sysBtnVo);
+    }
+
+    /**
+     * sortBtns 统计子级按钮数量,用于排序
+     *
+     * @param modId 模块编号
+     * @return 返回新增结果
+     */
+    @Override
+    public int sortBtns(String modId) {
+        return btnMapper.sortBtns(modId);
+    }
+}

+ 255 - 0
src/main/java/cn/aiyangniu/api/service/impl/system/SysModServiceImpl.java

@@ -0,0 +1,255 @@
+package cn.aiyangniu.api.service.impl.system;
+
+import cn.aiyangniu.api.service.system.SysModService;
+import cn.aiyangniu.api.common.entity.system.SysBtnEntity;
+import cn.aiyangniu.api.common.entity.system.SysModEntity;
+import cn.aiyangniu.api.common.entity.system.SysModVo;
+import cn.aiyangniu.api.mapper.system.SysBtnMapper;
+import cn.aiyangniu.api.mapper.system.SysModMapper;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.util.*;
+
+/**
+ * 系统模块服务实现类
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+@Service
+public class SysModServiceImpl implements SysModService {
+
+    @Resource
+    private SysModMapper modMapper;
+
+    @Resource
+    private SysBtnMapper btnMapper;
+
+    /**
+     * addMod 添加模块
+     *
+     * @param modEntity 模块实体对象
+     * @return 返回保存结果
+     */
+    @Override
+    public int addMod(SysModEntity modEntity) {
+        return modMapper.addMod(modEntity);
+    }
+
+    /**
+     * delMods 删除模块
+     *
+     * @param userId 操作人员编号
+     * @param modIds 模块编号数组
+     * @return 返回删除结果
+     */
+    @Transactional
+    @Override
+    public int delMods(String userId, List<String> modIds) {
+        List<String> idList = new ArrayList<>();
+        List<SysModEntity> modEntities = modMapper.selMods("");
+        for(String s : modIds) {
+            getModIds(modEntities, s, idList);
+        }
+        SysModVo sysModVo = new SysModVo();
+        sysModVo.setOptUser(userId);
+        sysModVo.setModIds(idList);
+        btnMapper.delBtnsByModId(sysModVo);
+        return modMapper.delMods(sysModVo);
+    }
+
+    /**
+     * getMod 获取单一模块
+     *
+     * @param modId 模块编号
+     * @return 返回模块对象
+     */
+    @Override
+    public SysModEntity getMod(String modId) {
+        return modMapper.getMod(modId);
+    }
+
+    /**
+     * edtMod 修改模块
+     *
+     * @param modEntity 模块实体对象
+     * @return 返回修改结果
+     */
+    @Override
+    public int edtMod(SysModEntity modEntity) {
+        return modMapper.edtMod(modEntity);
+    }
+
+    /**
+     * listMods 列表显示模块
+     *
+     * @param parentId 父级编号
+     * @return 返回模块列表
+     */
+    @Override
+    public List<SysModEntity> listMods(String parentId) {
+        List<SysModEntity> modEntityList = modMapper.listMods();
+        // 用于重新排序展示
+        if(modEntityList!=null && modEntityList.size()>0) {
+            modEntityList = buildTrees(modEntityList, parentId);
+        }
+        return modEntityList;
+    }
+
+    /**
+     * selMods 列表显示模块
+     *
+     * @param kind 查询种类,1为查询全部,2为查询当前用户所拥有的
+     * @param userMods 当前用户所拥有的模块
+     * @return 返回模块列表
+     */
+    @Override
+    public List<SysModEntity> selMods(String kind, String parentId, String schName, String userMods) {
+        List<SysModEntity> modEntityList = modMapper.selMods(schName);
+        if(modEntityList!=null && modEntityList.size()>0) {
+            if("2".equals(kind)) {
+                modEntityList.removeIf(modEntity -> !userMods.contains(modEntity.getModCode()));
+            }
+            modEntityList = buildTrees(modEntityList, parentId);
+        }
+        return modEntityList;
+    }
+
+    /**
+     * sortMods 统计子级模块数量,用于排序
+     *
+     * @param parentId 父级编号
+     * @return 返回新增结果
+     */
+    @Override
+    public int sortMods(String parentId) {
+        return modMapper.sortMods(parentId);
+    }
+
+    /**
+     * getModBtns 获取模块及按钮信息
+     *
+     * @return 返回模块列表
+     */
+    @Override
+    public List<SysModEntity> getModBtns() {
+        List<SysModEntity> newList = null;
+        List<SysModEntity> moduleEntities = modMapper.selMods("");
+        List<SysBtnEntity> buttonEntities = btnMapper.selBtns();
+        if(moduleEntities != null && moduleEntities.size() > 0) {
+            List<SysBtnEntity> btnEntities;
+            for(SysModEntity sysModEntity : moduleEntities) {
+                btnEntities = new ArrayList<>();
+                for(SysBtnEntity sysBtnEntity : buttonEntities) {
+                    if(sysModEntity.getModId().equals(sysBtnEntity.getModId())) {
+                        btnEntities.add(sysBtnEntity);
+                    }
+                }
+                sysModEntity.setButtonList(btnEntities);
+            }
+            String parentId = "00000000-0000-0000-0000-000000000000";
+            newList = new ArrayList<>();
+            int modLevel = 0;
+            for(SysModEntity curEnt: moduleEntities) {
+                if(parentId.equals(curEnt.getParentId())) {
+                    curEnt.setModLevel(modLevel);
+                    newList.add(curEnt);
+                    getChildMod(moduleEntities, curEnt.getModId(), newList, modLevel);
+                }
+            }
+        }
+        return newList;
+    }
+
+    /**
+     * 获取树型的节点下所有子节点编号
+     *
+     * @param ents 模块的List
+     * @param cid  当前模块编号
+     */
+    private void getModIds(List<SysModEntity> ents, String cid, List<String> idList) {
+        if(ents != null && ents.size() > 0 && !"".equals(cid)) {
+            idList.add(cid);
+            List<SysModEntity> list = getModules(ents, cid);
+            if(list.size() > 0) {
+                for(SysModEntity cEntity : list) {
+                    getModIds(ents, cEntity.getModId(), idList);
+                }
+            }
+        }
+    }
+
+    /**
+     * 获取树型的节点下所有子节点对象List
+     *
+     * @param ents 模块的List
+     * @param cid  当前模块编号
+     */
+    private List<SysModEntity> getModules(List<SysModEntity> ents, String cid) {
+        List<SysModEntity> list = new ArrayList<>();
+        if(ents != null && ents.size() > 0) {
+            for(SysModEntity cEntity : ents) {
+                if(cid.equals(cEntity.getParentId())) {
+                    list.add(cEntity);
+                }
+            }
+        }
+        return list;
+    }
+
+    /**
+     * 从已有List中找出与父级编号一致的,放到新的List中, 用于递归排序
+     *
+     * @param lists 已有List数组
+     * @param parentId 父级编号
+     * @param newList 新的List数组
+     * @param modLevel 模块级别
+     */
+    private static void getChildMod(List<SysModEntity> lists, String parentId, List<SysModEntity> newList, int modLevel) {
+        if(lists != null && lists.size() > 0) {
+            modLevel++;
+            for(SysModEntity entity : lists) {
+                if(entity.getParentId().equals(parentId)) {
+                    entity.setModLevel(modLevel);
+                    newList.add(entity);
+                    getChildMod(lists, entity.getModId(), newList, modLevel);
+                }
+            }
+        }
+    }
+
+    /**
+     * 递归筛选组织前端所需要的数据格式
+     *
+     * @param lists    组织对象数组List
+     * @param parentId 父级编号
+     * @return 返回要求的数据格式
+     */
+    private List<SysModEntity> buildTrees(List<SysModEntity> lists, String parentId) {
+        List<SysModEntity> entities = new ArrayList<>();
+        if(lists != null && lists.size() > 0) {
+            for(SysModEntity cEntity : lists) {
+                if(cEntity.getParentId().equals(parentId)) {
+                    entities.add(findChildren(cEntity, lists));
+                }
+            }
+        }
+        return entities;
+    }
+
+    private static SysModEntity findChildren(SysModEntity typeEntity, List<SysModEntity> lists) {
+        if(lists != null && lists.size() > 0) {
+            for(SysModEntity entity : lists) {
+                if(entity.getParentId().equals(typeEntity.getModId())) {
+                    if(typeEntity.getChildren() == null) {
+                        typeEntity.setChildren(new ArrayList<>());
+                    }
+                    typeEntity.getChildren().add(findChildren(entity, lists));
+                }
+            }
+        }
+        return typeEntity;
+    }
+}

+ 84 - 0
src/main/java/cn/aiyangniu/api/service/impl/system/SysMsgServiceImpl.java

@@ -0,0 +1,84 @@
+package cn.aiyangniu.api.service.impl.system;
+
+import cn.aiyangniu.api.service.system.SysMsgService;
+import cn.aiyangniu.api.common.entity.system.SysMsgEntity;
+import cn.aiyangniu.api.common.entity.system.SysMsgVo;
+import cn.aiyangniu.api.mapper.system.SysMsgMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+
+/**
+ * SysMsgServiceImpl 消息服务实现类
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+@Service
+public class SysMsgServiceImpl implements SysMsgService {
+
+    @Resource
+    private SysMsgMapper msgMapper;
+
+    /**
+     * addMsg 添加消息
+     *
+     * @param msgEntity 消息实体对象
+     * @return 返回保存结果
+     */
+    @Override
+    @Transactional
+    public int addMsg(SysMsgEntity msgEntity) {
+        msgMapper.addMsgDetail(msgEntity);
+        return msgMapper.addMsg(msgEntity);
+    }
+
+    /**
+     * delMsgs 已读、删除消息
+     *
+     * @param sysMsgVo 消息Vo对象
+     * @return 返回删除结果
+     */
+    @Override
+    public int proMsgs(SysMsgVo sysMsgVo) {
+        return msgMapper.proMsgs(sysMsgVo);
+    }
+
+    /**
+     * listMsgs 列表显示消息
+     *
+     * @param sysMsgVo 消息Vo对象
+     * @return 返回消息列表
+     */
+    @Override
+    public IPage<SysMsgEntity> listMsgs(SysMsgVo sysMsgVo, int pageNo, int pageSize) {
+        Page<SysMsgEntity> page = new Page<>(pageNo, pageSize);
+        return msgMapper.listMsgs(page, sysMsgVo);
+    }
+
+    /**
+     * myMsgs 我的消息列表
+     *
+     * @param sysMsgVo 消息Vo对象
+     * @return 返回消息列表
+     */
+    @Override
+    public IPage<SysMsgEntity> myMsgs(SysMsgVo sysMsgVo, int pageNo, int pageSize) {
+        Page<SysMsgEntity> page = new Page<>(pageNo, pageSize);
+        return msgMapper.myMsgs(page, sysMsgVo);
+    }
+
+    /**
+     * getMsg 获取单一消息
+     *
+     * @param msgId 消息编号
+     * @return 返回消息对象
+     */
+    @Override
+    public SysMsgEntity getMsg(String msgId) {
+        return msgMapper.getMsg(msgId);
+    }
+}

+ 110 - 0
src/main/java/cn/aiyangniu/api/service/impl/system/SysOptServiceImpl.java

@@ -0,0 +1,110 @@
+package cn.aiyangniu.api.service.impl.system;
+
+import cn.aiyangniu.api.service.system.SysOptService;
+import cn.aiyangniu.api.common.entity.system.SysOptEntity;
+import cn.aiyangniu.api.common.entity.system.SysOptVo;
+import cn.aiyangniu.api.mapper.system.SysOptMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * SysOptServiceImpl 选项服务实现类
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+@Service
+public class SysOptServiceImpl implements SysOptService {
+
+    @Resource
+    private SysOptMapper optMapper;
+
+    /**
+     * addOpt 添加选项
+     *
+     * @param optEntity 选项实体对象
+     * @return 返回保存结果
+     */
+    @Override
+    public int addOpt(SysOptEntity optEntity) {
+        return optMapper.addOpt(optEntity);
+    }
+
+    /**
+     * delOpts 删除选项
+     *
+     * @param sysOptVo 选项Vo对象
+     * @return 返回删除结果
+     */
+    @Override
+    public int delOpts(SysOptVo sysOptVo) {
+        optMapper.delChildOpts(sysOptVo);
+        return optMapper.delOpts(sysOptVo);
+    }
+
+    /**
+     * getOpt 获取单一选项
+     *
+     * @param optId 选项编号
+     * @return 返回选项对象
+     */
+    @Override
+    public SysOptEntity getOpt(String optId) {
+        return optMapper.getOpt(optId);
+    }
+
+    /**
+     * edtOpt 修改选项
+     *
+     * @param optEntity 选项实体对象
+     * @return 返回修改结果
+     */
+    @Override
+    public int edtOpt(SysOptEntity optEntity) {
+        return optMapper.edtOpt(optEntity);
+    }
+
+    /**
+     * listOpts 列表显示选项
+     *
+     * @param sysOptVo 选项Vo对象
+     * @return 返回选项列表
+     */
+    @Override
+    public IPage<SysOptEntity> listOpts(SysOptVo sysOptVo, int pageNo, int pageSize) {
+        Page<SysOptEntity> page = new Page<>(pageNo, pageSize);
+        return optMapper.listOpts(page, sysOptVo);
+    }
+
+    /**
+     * sortOpts 统计子级选项数量,用于排序
+     *
+     * @param kind 选项种类
+     * @return 返回新增结果
+     */
+    @Override
+    public int sortOpts(String kind) {
+        return optMapper.sortOpts(kind);
+    }
+
+    /**
+     * selOpts 下拉选择展示选项
+     *
+     * @param name 选项名称或编码的关键字
+     * @param kind 选项种类
+     * @return 返回新增结果
+     */
+    @Override
+    public List<SysOptEntity> selOpts(String name, String kind) {
+        Map<String, String> reqMap = new HashMap<>();
+        reqMap.put("name", name);
+        reqMap.put("kind", kind);
+        return optMapper.selOpts(reqMap);
+    }
+}

+ 93 - 0
src/main/java/cn/aiyangniu/api/service/impl/system/SysRoleServiceImpl.java

@@ -0,0 +1,93 @@
+package cn.aiyangniu.api.service.impl.system;
+
+import cn.aiyangniu.api.service.system.SysRoleService;
+import cn.aiyangniu.api.common.entity.system.SysRoleEntity;
+import cn.aiyangniu.api.common.entity.system.SysRoleVo;
+import cn.aiyangniu.api.mapper.system.SysRoleMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 角色服务实现类
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+@Service
+public class SysRoleServiceImpl implements SysRoleService {
+
+    @Resource
+    private SysRoleMapper roleMapper;
+
+    /**
+     * addRole 添加角色
+     *
+     * @param roleEntity 角色实体对象
+     * @return 返回保存结果
+     */
+    @Override
+    public int addRole(SysRoleEntity roleEntity) {
+        return roleMapper.addRole(roleEntity);
+    }
+
+    /**
+     * delRoles 删除角色
+     *
+     * @param sysRoleVo 角色Vo对象
+     * @return 返回删除结果
+     */
+    @Override
+    public int delRoles(SysRoleVo sysRoleVo) {
+        return roleMapper.delRoles(sysRoleVo);
+    }
+
+    /**
+     * getRole 获取单一角色
+     *
+     * @param roleId 角色编号
+     * @return 返回角色对象
+     */
+    @Override
+    public SysRoleEntity getRole(String roleId) {
+        return roleMapper.getRole(roleId);
+    }
+
+    /**
+     * edtRole 修改角色
+     *
+     * @param roleEntity 角色实体对象
+     * @return 返回修改结果
+     */
+    @Override
+    public int edtRole(SysRoleEntity roleEntity) {
+        return roleMapper.edtRole(roleEntity);
+    }
+
+    /**
+     * listRoles 列表显示角色
+     *
+     * @param sysRoleVo 角色Vo对象
+     * @return 返回角色列表
+     */
+    @Override
+    public IPage<SysRoleEntity> listRoles(SysRoleVo sysRoleVo, int pageNo, int pageSize) {
+        Page<SysRoleEntity> page = new Page<>(pageNo, pageSize);
+        return roleMapper.listRoles(page, sysRoleVo);
+    }
+
+    /**
+     * selRoles 下拉选择展示角色
+     *
+     * @param auth 是否有查看全部角色的权限
+     * @return 返回新增结果
+     */
+    @Override
+    public List<SysRoleEntity> selRoles(int auth) {
+        return roleMapper.selRoles(auth);
+    }
+
+}

+ 230 - 0
src/main/java/cn/aiyangniu/api/service/impl/system/SysTypeServiceImpl.java

@@ -0,0 +1,230 @@
+package cn.aiyangniu.api.service.impl.system;
+
+import cn.aiyangniu.api.service.system.SysTypeService;
+import cn.aiyangniu.api.common.entity.system.SysTypeEntity;
+import cn.aiyangniu.api.common.entity.system.SysTypeVo;
+import cn.aiyangniu.api.mapper.system.SysTypeMapper;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.*;
+
+/**
+ * SysTypeServiceImpl 分类服务实现类
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+@Service
+public class SysTypeServiceImpl implements SysTypeService {
+
+    @Resource
+    private SysTypeMapper typeMapper;
+
+    /**
+     * addType 添加分类
+     *
+     * @param typeEntity 分类实体对象
+     * @return 返回保存结果
+     */
+    @Override
+    public int addType(SysTypeEntity typeEntity) {
+        return typeMapper.addType(typeEntity);
+    }
+
+    /**
+     * delTypes 删除分类
+     *
+     * @param sysTypeVo 分类Vo对象
+     * @return 返回删除结果
+     */
+    @Override
+    public int delTypes(SysTypeVo sysTypeVo) {
+        List<String> idList = new ArrayList<>();
+        List<SysTypeEntity> typeEntities = typeMapper.selTypes(sysTypeVo);
+        for(String s : sysTypeVo.getTypeIds()) {
+            getTypeIds(typeEntities, s, idList);
+        }
+        sysTypeVo.setTypeIds(idList);
+        return typeMapper.delTypes(sysTypeVo);
+    }
+
+    /**
+     * getType 获取单一分类
+     *
+     * @param typeId 分类编号
+     * @return 返回分类对象
+     */
+    @Override
+    public SysTypeEntity getType(String typeId) {
+        return typeMapper.getType(typeId);
+    }
+
+    /**
+     * edtType 修改分类
+     *
+     * @param typeEntity 分类实体对象
+     * @return 返回修改结果
+     */
+    @Override
+    public int edtType(SysTypeEntity typeEntity) {
+        return typeMapper.edtType(typeEntity);
+    }
+
+    /**
+     * listTypes 列表显示分类
+     *
+     * @param kind 分类种类编号
+     * @return 返回分类列表
+     */
+    @Override
+    public List<SysTypeEntity> listTypes(String kind, String parentId) {
+        List<SysTypeEntity> newList = null;
+        List<SysTypeEntity> typeEntityList = typeMapper.listTypes(kind);
+        // 用于重新排序展示
+        if(typeEntityList!=null && typeEntityList.size()>0) {
+            newList = new ArrayList<>();
+            int modLevel = 0;
+            for(SysTypeEntity curEnt: typeEntityList) {
+                if(parentId.equals(curEnt.getParentId())) {
+                    curEnt.setTypeLevel(modLevel);
+                    newList.add(curEnt);
+                    getChild(typeEntityList, curEnt.getTypeId(), newList, modLevel);
+                }
+            }
+        }
+        return newList;
+    }
+
+    /**
+     * sortTypes 统计子级分类数量,用于排序
+     *
+     * @param parentId 请求参数
+     * @return 返回新增结果
+     */
+    @Override
+    public int sortTypes(String parentId) {
+        return typeMapper.sortTypes(parentId);
+    }
+
+    /**
+     * selTypes 下拉选择展示分类
+     *
+     * @param sysTypeVo 分类Vo对象
+     * @return 返回新增结果
+     */
+    @Override
+    public List<SysTypeEntity> selTypes(SysTypeVo sysTypeVo) {
+        List<SysTypeEntity> typeEntityList = typeMapper.selTypes(sysTypeVo);
+        if(typeEntityList!=null && typeEntityList.size()>0) {
+            typeEntityList = buildTrees(typeEntityList, sysTypeVo.getParentId());
+        }
+        return typeEntityList;
+    }
+
+    /**
+     * getTypeIds 获取树型的节点下所有子节点编号
+     *
+     * @param ents 模块的List
+     * @param cid  当前模块编号
+     */
+    private void getTypeIds(List<SysTypeEntity> ents, String cid, List<String> idList) {
+        if(ents != null && ents.size() > 0 && !"".equals(cid)) {
+            idList.add(cid);
+            List<SysTypeEntity> list = getTypes(ents, cid);
+            if(list.size() > 0) {
+                for(SysTypeEntity cEntity : list) {
+                    getTypeIds(ents, cEntity.getTypeId(), idList);
+                }
+            }
+        }
+    }
+
+    /**
+     * getTypes 获取树型的节点下所有子节点对象List
+     *
+     * @param ents 模块的List
+     * @param cid  当前模块编号
+     */
+    private List<SysTypeEntity> getTypes(List<SysTypeEntity> ents, String cid) {
+        List<SysTypeEntity> list = new ArrayList<>();
+        if(ents != null && ents.size() > 0) {
+            for(SysTypeEntity cEntity : ents) {
+                if(cid.equals(cEntity.getParentId())) {
+                    list.add(cEntity);
+                }
+            }
+        }
+        return list;
+    }
+
+    /**
+     * buildTrees 递归筛选组织前端所需要的数据格式
+     *
+     * @param lists    组织对象数组List
+     * @param parentId 父级编号
+     * @return 返回要求的数据格式
+     */
+    private List<SysTypeEntity> buildTrees(List<SysTypeEntity> lists, String parentId) {
+        List<SysTypeEntity> entities = new ArrayList<>();
+        if(lists != null && lists.size() > 0) {
+            for(SysTypeEntity cEntity : lists) {
+                if(cEntity.getParentId().equals(parentId)) {
+                    entities.add(findChildren(cEntity, lists));
+                }
+            }
+        }
+        return entities;
+    }
+
+    private static SysTypeEntity findChildren(SysTypeEntity typeEntity, List<SysTypeEntity> lists) {
+        if(lists != null && lists.size() > 0) {
+            for(SysTypeEntity entity : lists) {
+                if(entity.getParentId().equals(typeEntity.getTypeId())) {
+                    if(typeEntity.getChildren() == null) {
+                        typeEntity.setChildren(new ArrayList<>());
+                    }
+                    typeEntity.getChildren().add(findChildren(entity, lists));
+                }
+            }
+        }
+        return typeEntity;
+    }
+
+    /**
+     * 从已有List中找出与父级编号一致的,放到新的List中, 用于递归排序
+     *
+     * @param lists 已有List数组
+     * @param parentId 父级编号
+     * @param newList 新的List数组
+     * @param level 模块级别
+     */
+    private static void getChild(List<SysTypeEntity> lists, String parentId, List<SysTypeEntity> newList, int level) {
+        if(lists != null && lists.size() > 0) {
+            level++;
+            for(SysTypeEntity entity : lists) {
+                if(entity.getParentId().equals(parentId)) {
+                    entity.setTypeLevel(level);
+                    newList.add(entity);
+                    getChild(lists, entity.getTypeId(), newList, level);
+                }
+            }
+        }
+    }
+
+    /**
+     * getParentTypes 向上递归查询所有父节点(每一层的父节点只有一个)
+     * @param id 当前节点编号
+     * @param entityList 实体对象集合
+     * @return 返回递归结果
+     */
+    private List<SysTypeEntity> getParentTypes(String id, List<SysTypeEntity> entityList) {
+        // 向上递归查询所有父节点
+        SysTypeEntity typeEntity = typeMapper.getType(id);
+        if(typeEntity != null) {
+            entityList.add(typeEntity);
+            getParentTypes(typeEntity.getTypeId(), entityList);
+        }
+        return entityList;
+    }
+}

+ 126 - 0
src/main/java/cn/aiyangniu/api/service/impl/system/SysUserServiceImpl.java

@@ -0,0 +1,126 @@
+package cn.aiyangniu.api.service.impl.system;
+
+import cn.aiyangniu.api.service.system.SysUserService;
+import cn.aiyangniu.api.common.entity.system.SysUserDto;
+import cn.aiyangniu.api.common.entity.system.SysUserEntity;
+import cn.aiyangniu.api.common.entity.system.SysUserVo;
+import cn.aiyangniu.api.mapper.system.SysUserMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 用户服务实现类
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+@Service
+public class SysUserServiceImpl implements SysUserService {
+
+    @Resource
+    private SysUserMapper userMapper;
+
+    /**
+     * 添加用户
+     *
+     * @param userEntity 用户实体对象
+     * @return 返回保存结果
+     */
+    @Override
+    public int addUser(SysUserEntity userEntity) {
+        return userMapper.addUser(userEntity);
+    }
+
+    /**
+     * 删除用户
+     *
+     * @param sysUserVo 用户Vo对象
+     * @return 返回删除结果
+     */
+    @Override
+    public int proUsers(SysUserVo sysUserVo) {
+        return userMapper.proUsers(sysUserVo);
+    }
+
+    /**
+     * 获取单一用户
+     *
+     * @param userId 用户编号
+     * @return 返回用户对象
+     */
+    @Override
+    public SysUserEntity getUser(String userId) {
+        return userMapper.getUser(userId);
+    }
+
+    /**
+     * 修改用户
+     *
+     * @param userEntity 用户实体对象
+     * @return 返回修改结果
+     */
+    @Override
+    public int edtUser(SysUserEntity userEntity) {
+        return userMapper.edtUser(userEntity);
+    }
+
+    /**
+     * 列表显示用户
+     *
+     * @param sysUserVo 用户Vo对象
+     * @return 返回用户列表
+     */
+    @Override
+    public IPage<SysUserDto> listUsers(SysUserVo sysUserVo, int pageNo, int pageSize) {
+        Page<SysUserDto> page = new Page<>(pageNo, pageSize);
+        return userMapper.listUsers(page, sysUserVo);
+    }
+
+    /**
+     * 下拉选择用户列表
+     *
+     * @param sysUserVo 用户Vo对象
+     * @return 返回用户列表
+     */
+    @Override
+    public List<SysUserDto> selUsers(SysUserVo sysUserVo) {
+        return userMapper.selUsers(sysUserVo);
+    }
+
+    /**
+     * 判断登录账号是否重复
+     *
+     * @param sysUserVo 用户Vo对象
+     * @return 返回用户列表
+     */
+    @Override
+    public int extUser(SysUserVo sysUserVo) {
+        return userMapper.extUser(sysUserVo);
+    }
+
+    /**
+     * 用户登录
+     *
+     * @param sysUserVo 用户Vo对象
+     * @return 返回用户列表
+     */
+    @Override
+    public SysUserDto loginUser(SysUserVo sysUserVo) {
+        return userMapper.loginUser(sysUserVo);
+    }
+
+    /**
+     * 修改个人资料
+     *
+     * @param userEntity 用户实体对象
+     * @return 返回用户列表
+     */
+    @Override
+    public int updUser(SysUserEntity userEntity) {
+        return userMapper.updUser(userEntity);
+    }
+}

+ 23 - 0
src/main/java/cn/aiyangniu/api/service/system/SysAreaService.java

@@ -0,0 +1,23 @@
+package cn.aiyangniu.api.service.system;
+
+import cn.aiyangniu.api.common.entity.system.SysAreaEntity;
+import cn.aiyangniu.api.common.entity.system.SysAreaVo;
+
+import java.util.List;
+
+/**
+ * SysAreaService 区域服务接口类
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+public interface SysAreaService {
+
+    /**
+     * selAreas 下拉选择展示区域
+     *
+     * @param areaVo 父级区域编号
+     * @return 返回结果
+     */
+    List<SysAreaEntity> selAreas(SysAreaVo areaVo);
+}

+ 64 - 0
src/main/java/cn/aiyangniu/api/service/system/SysBtnService.java

@@ -0,0 +1,64 @@
+package cn.aiyangniu.api.service.system;
+
+import cn.aiyangniu.api.common.entity.system.SysBtnEntity;
+import cn.aiyangniu.api.common.entity.system.SysBtnVo;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+/**
+ * 按钮服务接口类
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+public interface SysBtnService {
+
+    /**
+     * 新增按钮
+     *
+     * @param btnEntity 按钮实体对象
+     * @return 返回新增结果
+     */
+    int addBtn(SysBtnEntity btnEntity);
+
+    /**
+     * 删除按钮
+     *
+     * @param sysBtnVo 按钮Vo对象
+     * @return 返回删除结果
+     */
+    int delBtns(SysBtnVo sysBtnVo);
+
+    /**
+     * 获取单一按钮编号详情
+     *
+     * @param btnId 按钮编号
+     * @return 返回详情结果
+     */
+    SysBtnEntity getBtn(String btnId);
+
+    /**
+     * 修改按钮
+     *
+     * @param btnEntity 按钮实体对象
+     * @return 返回修改结果
+     */
+    int edtBtn(SysBtnEntity btnEntity);
+
+    /**
+     * 列表展示按钮
+     *
+     * @param sysBtnVo 按钮Vo对象
+     * @param pageNo 页数
+     * @param PageSize 每页显示数量
+     * @return 返回新增结果
+     */
+    IPage<SysBtnEntity> listBtns(SysBtnVo sysBtnVo, int pageNo, int PageSize);
+
+    /**
+     * 统计子级按钮数量,用于排序
+     *
+     * @param modId 模块编号
+     * @return 返回新增结果
+     */
+    int sortBtns(String modId);
+}

+ 79 - 0
src/main/java/cn/aiyangniu/api/service/system/SysModService.java

@@ -0,0 +1,79 @@
+package cn.aiyangniu.api.service.system;
+
+import cn.aiyangniu.api.common.entity.system.SysModEntity;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 系统模块服务接口类
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+public interface SysModService {
+
+    /**
+     * addMod 新增模块
+     *
+     * @param modEntity 模块实体对象
+     * @return 返回新增结果
+     */
+    int addMod(SysModEntity modEntity);
+
+    /**
+     * delMods 删除模块
+     *
+     * @param userId 操作人员编号
+     * @param modIds 模块编号串
+     * @return 返回删除结果
+     */
+    int delMods(String userId, List<String> modIds);
+
+    /**
+     * getMod 获取单一模块编号详情
+     *
+     * @param modId 模块编号
+     * @return 返回详情结果
+     */
+    SysModEntity getMod(String modId);
+
+    /**
+     * edtMod 修改模块
+     *
+     * @param modEntity 模块实体对象
+     * @return 返回修改结果
+     */
+    int edtMod(SysModEntity modEntity);
+
+    /**
+     * listMods 列表展示模块
+     *
+     * @param parentId 父级编号
+     * @return 返回结果
+     */
+    List<SysModEntity> listMods(String parentId);
+
+    /**
+     * selMods 下拉选择模块
+     *
+     * @param kind 查询种类,1为查询全部,2为查询当前用户所拥有的
+     * @param userMods 当前用户所拥有的模块
+     * @return 返回结果
+     */
+    List<SysModEntity> selMods(String kind, String parentId, String schName, String userMods);
+
+    /**
+     * sortMods 统计子级模块数量,用于排序
+     *
+     * @param parentId 父级编号
+     * @return 返回结果
+     */
+    int sortMods(String parentId);
+
+    /**
+     * getModBtns 获取模块及拥有的按钮数据
+     *
+     * @return 返回新增结果
+     */
+    List<SysModEntity> getModBtns();
+}

+ 58 - 0
src/main/java/cn/aiyangniu/api/service/system/SysMsgService.java

@@ -0,0 +1,58 @@
+package cn.aiyangniu.api.service.system;
+
+import cn.aiyangniu.api.common.entity.system.SysMsgEntity;
+import cn.aiyangniu.api.common.entity.system.SysMsgVo;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+/**
+ * SysMsgService 消息服务接口类
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+public interface SysMsgService {
+
+    /**
+     * 新增消息
+     *
+     * @param msgEntity 消息实体对象
+     * @return 返回新增结果
+     */
+    int addMsg(SysMsgEntity msgEntity);
+
+    /**
+     * 已读、删除消息
+     *
+     * @param sysMsgVo 消息Vo对象
+     * @return 返回删除结果
+     */
+    int proMsgs(SysMsgVo sysMsgVo);
+
+    /**
+     * 我的消息列表
+     *
+     * @param sysMsgVo 消息Vo对象
+     * @param pageNo 页数
+     * @param PageSize 每页显示数量
+     * @return 返回新增结果
+     */
+    IPage<SysMsgEntity> myMsgs(SysMsgVo sysMsgVo, int pageNo, int PageSize);
+
+    /**
+     * 列表展示消息
+     *
+     * @param sysMsgVo 消息Vo对象
+     * @param pageNo 页数
+     * @param PageSize 每页显示数量
+     * @return 返回新增结果
+     */
+    IPage<SysMsgEntity> listMsgs(SysMsgVo sysMsgVo, int pageNo, int PageSize);
+
+    /**
+     * 获取单一消息编号详情
+     *
+     * @param msgId 消息编号
+     * @return 返回详情结果
+     */
+    SysMsgEntity getMsg(String msgId);
+}

+ 74 - 0
src/main/java/cn/aiyangniu/api/service/system/SysOptService.java

@@ -0,0 +1,74 @@
+package cn.aiyangniu.api.service.system;
+
+import cn.aiyangniu.api.common.entity.system.SysOptEntity;
+import cn.aiyangniu.api.common.entity.system.SysOptVo;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import java.util.List;
+
+/**
+ * SysOptService 选项服务接口类
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+public interface SysOptService {
+
+    /**
+     * addOpt 新增选项
+     *
+     * @param optEntity 选项实体对象
+     * @return 返回新增结果
+     */
+    int addOpt(SysOptEntity optEntity);
+
+    /**
+     * delOpts 删除选项
+     *
+     * @param sysOptVo 选项Vo对象
+     * @return 返回删除结果
+     */
+    int delOpts(SysOptVo sysOptVo);
+
+    /**
+     * getOpt 获取单一选项编号详情
+     *
+     * @param optId 选项编号
+     * @return 返回详情结果
+     */
+    SysOptEntity getOpt(String optId);
+
+    /**
+     * edtOpt 修改选项
+     *
+     * @param optEntity 选项实体对象
+     * @return 返回修改结果
+     */
+    int edtOpt(SysOptEntity optEntity);
+
+    /**
+     * listOpts 列表展示选项
+     *
+     * @param sysOptVo 选项Vo对象
+     * @param pageNo 页数
+     * @param PageSize 每页显示数量
+     * @return 返回新增结果
+     */
+    IPage<SysOptEntity> listOpts(SysOptVo sysOptVo, int pageNo, int PageSize);
+
+    /**
+     * sortOpts 统计子级选项数量,用于排序
+     *
+     * @param kind 选项种类
+     * @return 返回新增结果
+     */
+    int sortOpts(String kind);
+
+    /**
+     * selOpts 下拉选择展示选项
+     *
+     * @param name 选项名称或编码的关键字
+     * @param kind 选项种类
+     * @return 返回新增结果
+     */
+    List<SysOptEntity> selOpts(String name, String kind);
+}

+ 65 - 0
src/main/java/cn/aiyangniu/api/service/system/SysRoleService.java

@@ -0,0 +1,65 @@
+package cn.aiyangniu.api.service.system;
+
+import cn.aiyangniu.api.common.entity.system.SysRoleEntity;
+import cn.aiyangniu.api.common.entity.system.SysRoleVo;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import java.util.List;
+
+/**
+ * 角色服务接口类
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+public interface SysRoleService {
+
+    /**
+     * addRole 新增角色
+     *
+     * @param roleEntity 角色实体对象
+     * @return 返回新增结果
+     */
+    int addRole(SysRoleEntity roleEntity);
+
+    /**
+     * delRoles 删除角色
+     *
+     * @param sysRoleVo 角色Vo对象
+     * @return 返回删除结果
+     */
+    int delRoles(SysRoleVo sysRoleVo);
+
+    /**
+     * getRole 获取单一角色编号详情
+     *
+     * @param roleId 角色编号
+     * @return 返回详情结果
+     */
+    SysRoleEntity getRole(String roleId);
+
+    /**
+     * edtRole 修改角色
+     *
+     * @param roleEntity 角色实体对象
+     * @return 返回修改结果
+     */
+    int edtRole(SysRoleEntity roleEntity);
+
+    /**
+     * listRoles 列表展示角色
+     *
+     * @param sysRoleVo 角色Vo对象
+     * @param pageNo 页数
+     * @param PageSize 每页显示数量
+     * @return 返回新增结果
+     */
+    IPage<SysRoleEntity> listRoles(SysRoleVo sysRoleVo, int pageNo, int PageSize);
+
+    /**
+     * selRoles 下拉选择展示角色
+     *
+     * @param auth 是否有查看全部角色的权限
+     * @return 返回新增结果
+     */
+    List<SysRoleEntity> selRoles(int auth);
+}

+ 71 - 0
src/main/java/cn/aiyangniu/api/service/system/SysTypeService.java

@@ -0,0 +1,71 @@
+package cn.aiyangniu.api.service.system;
+
+import cn.aiyangniu.api.common.entity.system.SysTypeEntity;
+import cn.aiyangniu.api.common.entity.system.SysTypeVo;
+import java.util.List;
+
+/**
+ * SysTypeService 分类服务接口类
+ *
+ * @author Henry Hall
+ * @since 2020-09-28
+ */
+public interface SysTypeService {
+
+    /**
+     * addType 新增分类
+     *
+     * @param typeEntity 分类实体对象
+     * @return 返回新增结果
+     */
+    int addType(SysTypeEntity typeEntity);
+
+    /**
+     * delTypes 删除分类
+     *
+     * @param sysTypeVo 分类Vo对象
+     * @return 返回删除结果
+     */
+    int delTypes(SysTypeVo sysTypeVo);
+
+    /**
+     * getType 获取单一分类编号详情
+     *
+     * @param typeId 分类编号
+     * @return 返回详情结果
+     */
+    SysTypeEntity getType(String typeId);
+
+    /**
+     * edtType 修改分类
+     *
+     * @param typeEntity 分类实体对象
+     * @return 返回修改结果
+     */
+    int edtType(SysTypeEntity typeEntity);
+
+    /**
+     * listTypes 列表展示分类
+     *
+     * @param kind 分类种类编号
+     * @param parentId 父级分类编号
+     * @return 返回新增结果
+     */
+    List<SysTypeEntity> listTypes(String kind, String parentId);
+
+    /**
+     * sortTypes 统计子级分类数量,用于排序
+     *
+     * @param parentId 请求参数
+     * @return 返回新增结果
+     */
+    int sortTypes(String parentId);
+
+    /**
+     * selTypes 下拉选择展示分类
+     *
+     * @param sysTypeVo 分类Vo对象
+     * @return 返回新增结果
+     */
+    List<SysTypeEntity> selTypes(SysTypeVo sysTypeVo);
+}

+ 90 - 0
src/main/java/cn/aiyangniu/api/service/system/SysUserService.java

@@ -0,0 +1,90 @@
+package cn.aiyangniu.api.service.system;
+
+import cn.aiyangniu.api.common.entity.system.SysUserDto;
+import cn.aiyangniu.api.common.entity.system.SysUserEntity;
+import cn.aiyangniu.api.common.entity.system.SysUserVo;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import java.util.List;
+
+/**
+ * 用户服务接口类
+ *
+ * @author Henry Hall
+ * @since 2020-08-08
+ */
+public interface SysUserService {
+
+    /**
+     * addUser 新增用户
+     *
+     * @param usrEntity 用户实体对象
+     * @return 返回新增结果
+     */
+    int addUser(SysUserEntity usrEntity);
+
+    /**
+     * proUsers 删除用户
+     *
+     * @param sysUserVo 用户Vo对象
+     * @return 返回删除结果
+     */
+    int proUsers(SysUserVo sysUserVo);
+
+    /**
+     * getUser 获取单一用户编号详情
+     *
+     * @param userId 用户编号
+     * @return 返回详情结果
+     */
+    SysUserEntity getUser(String userId);
+
+    /**
+     * edtUser 修改用户
+     *
+     * @param usrEntity 用户实体对象
+     * @return 返回修改结果
+     */
+    int edtUser(SysUserEntity usrEntity);
+
+    /**
+     * listUsers 列表展示用户
+     *
+     * @param sysUserVo 用户Vo对象
+     * @param pageNo 页数
+     * @param PageSize 每页显示数量
+     * @return 返回新增结果
+     */
+    IPage<SysUserDto> listUsers(SysUserVo sysUserVo, int pageNo, int PageSize);
+
+    /**
+     * selUsers 下拉选择展示用户
+     *
+     * @param sysUserVo 用户Vo对象
+     * @return 返回新增结果
+     */
+    List<SysUserDto> selUsers(SysUserVo sysUserVo);
+
+    /**
+     * extUser 根据账号查询重复的用户
+     *
+     * @param sysUserVo 用户Vo对象
+     * @return 返回新增结果
+     */
+    int extUser(SysUserVo sysUserVo);
+
+    /**
+     * loginUser 列表展示用户
+     *
+     * @param sysUserVo 用户Vo对象
+     * @return 返回新增结果
+     */
+    SysUserDto loginUser(SysUserVo sysUserVo);
+
+    /**
+     * updUser 修改个人资料
+     *
+     * @param usrEntity 用户实体对象
+     * @return 返回修改结果
+     */
+    int updUser(SysUserEntity usrEntity);
+}

+ 91 - 0
src/main/resources/application-dev.yml

@@ -0,0 +1,91 @@
+#Pei Zhi Gong Cheng Duan Kou.
+server:
+  port: 8010
+  #Pei Zhi Gong Cheng Gen Lu Jing.
+  servlet:
+    context-path: /
+    #Jie Jue FastJson Zhong Wen Luan Ma De Wen ti
+    encoding:
+      force: true
+
+file-path: E:\data\apps\provider-service\file
+root-path: http://127.0.0.1/common/upfiles/
+
+#Jing Tai Zi Yuan Fang Wen Lu Jing
+spring:
+  #Druid Jdbc Config
+  datasource:
+    name: druidDataSource
+    type: com.alibaba.druid.pool.DruidDataSource
+    driver-class-name: com.mysql.cj.jdbc.Driver
+    url: jdbc:mysql://127.0.0.1:3306/ayn_db_provider?useUnicode=true&serverTimezone=PRC&characterEncoding=UTF-8
+    username: root
+    password: 123456
+
+    druid:
+      filters: stat
+      #最大连接池数量
+      max-active: 200
+      #初始化时建立物理连接的个数
+      initial-size: 10
+      #获取连接时最大等待时间,单位毫秒
+      max-wait: 60000
+      #最小连接池数量
+      min-idle: 10
+      time-between-eviction-runs-millis: 60000
+      min-evictable-idle-time-millis: 300000
+      validation-query: select 1
+      #validation-query: select 1 from dual
+      test-while-idle: false
+      test-on-borrow: false
+      test-on-return: false
+      #是否缓存preparedStatement
+      pool-prepared-statements: true
+      #要启用PSCache,必须配置大于0
+      max-open-prepared-statements: 200
+      break-after-acquire-failure: true
+      time-between-connect-error-millis: 300000
+      # 下面3个enabled改为true即开启druid monitor
+      filter:
+        config:
+          enabled: false
+      # 配置 DruidStatFilter
+      web-stat-filter:
+        enabled: false
+        url-pattern: /*
+        exclusions: .js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*
+      # 配置 DruidStatViewServlet
+      stat-view-servlet:
+        enabled: true
+        url-pattern: /druid/*
+        # IP 白名单,没有配置或者为空,则允许所有访问
+        allow:
+        # IP 黑名单,若白名单也存在,则优先使用
+        deny:
+        # 禁用 HTML 中 Reset All 按钮
+        reset-enable: false
+        # 登录用户名/密码
+        login-username: druid
+        login-password: druid
+
+  # redis
+  redis:
+    host: 119.3.220.7
+    port: 6379
+    password: 3T%UPCd2pRyP
+    database: 1
+    timeout: 10000
+    jedis:
+      pool:
+        max-active: 1000
+        max-wait: -1
+        max-idle: 10
+        min-idle: 5
+
+#Show SQL Log
+logging:
+  level:
+    cn:
+      aiyangniu:
+        api:
+          mapper: debug

+ 91 - 0
src/main/resources/application-pro.yml

@@ -0,0 +1,91 @@
+#Pei Zhi Gong Cheng Duan Kou.
+server:
+  port: 8010
+  #Pei Zhi Gong Cheng Gen Lu Jing.
+  servlet:
+    context-path: /
+    #Jie Jue FastJson Zhong Wen Luan Ma De Wen ti
+    encoding:
+      force: true
+
+file-path: /datas/web/common/upfiles/
+root-path: http://127.0.0.1/common/upfiles/
+
+#Jing Tai Zi Yuan Fang Wen Lu Jing
+spring:
+  #Druid Jdbc Config
+  datasource:
+    name: druidDataSource
+    type: com.alibaba.druid.pool.DruidDataSource
+    driver-class-name: com.mysql.cj.jdbc.Driver
+    url: jdbc:mysql://127.0.0.1:3306/ubt_db_api?useUnicode=true&serverTimezone=PRC&characterEncoding=UTF-8
+    username: root
+    password: 01235689@Hh
+
+    druid:
+      filters: stat
+      #最大连接池数量
+      max-active: 200
+      #初始化时建立物理连接的个数
+      initial-size: 10
+      #获取连接时最大等待时间,单位毫秒
+      max-wait: 60000
+      #最小连接池数量
+      min-idle: 10
+      time-between-eviction-runs-millis: 60000
+      min-evictable-idle-time-millis: 300000
+      validation-query: select 1
+      #validation-query: select 1 from dual
+      test-while-idle: false
+      test-on-borrow: false
+      test-on-return: false
+      #是否缓存preparedStatement
+      pool-prepared-statements: true
+      #要启用PSCache,必须配置大于0
+      max-open-prepared-statements: 200
+      break-after-acquire-failure: true
+      time-between-connect-error-millis: 300000
+      # 下面3个enabled改为true即开启druid monitor
+      filter:
+        config:
+          enabled: false
+      # 配置 DruidStatFilter
+      web-stat-filter:
+        enabled: false
+        url-pattern: /*
+        exclusions: .js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*
+      # 配置 DruidStatViewServlet
+      stat-view-servlet:
+        enabled: true
+        url-pattern: /druid/*
+        # IP 白名单,没有配置或者为空,则允许所有访问
+        allow:
+        # IP 黑名单,若白名单也存在,则优先使用
+        deny:
+        # 禁用 HTML 中 Reset All 按钮
+        reset-enable: false
+        # 登录用户名/密码
+        login-username: druid
+        login-password: druid
+
+  # redis
+  redis:
+    host: 119.3.220.7
+    port: 6379
+    password: 3T%UPCd2pRyP
+    database: 1
+    timeout: 10000
+    jedis:
+      pool:
+        max-active: 1000
+        max-wait: -1
+        max-idle: 10
+        min-idle: 5
+
+#Show SQL Log
+logging:
+  level:
+    cn:
+      aiyangniu:
+        api:
+          mapper: debug

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

@@ -0,0 +1,28 @@
+#Jing Tai Zi Yuan Fang Wen Lu Jing
+spring:
+  profiles:
+    active: @profile@
+  servlet:
+    #上传文件的路径
+    multipart:
+      enabled: true
+      max-file-size: 1024MB
+      max-request-size: 1024MB
+  mvc:
+    pathmatch:
+      matching-strategy: ant_path_matcher
+    async:
+      request-timeout=: 300000
+  # jackson时间格式化
+  jackson:
+    time-zone: GMT+8
+    date-format: yyyy-MM-dd HH:mm:ss
+
+#Mybatis Config
+mybatis-plus:
+  mapper-locations: classpath:mapper/**/*Mapper.xml
+  type-aliases-package: cn.aiyangniu.api.common.entity
+  configuration:
+    map-underscore-to-camel-case: true
+  global-config:
+    banner: false

+ 5 - 0
src/main/resources/banner.txt

@@ -0,0 +1,5 @@
+====================================================================================================================
+
+                                  欢迎使用 供应商信息管理平台 - Powered By AYN
+
+====================================================================================================================

+ 104 - 0
src/main/resources/logback-spring.xml

@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+    <include resource="org/springframework/boot/logging/logback/defaults.xml" />
+    <include resource="org/springframework/boot/logging/logback/console-appender.xml" />
+    <property name="LOG_FILE" value="E:\\data\\apps\\provider-service\\logs\\%d{yyyyMM}\\" />
+    <!--<property name="LOG_FILE" value="/data/apps/provider-service/logs/" />-->
+
+    <!-- 保留DEBUG Level的日志 -->
+    <appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <!-- %i用来标记分割日志的序号 -->
+            <fileNamePattern>${LOG_FILE}%d{yyyy-MM-dd}_DEBUG_%i.log</fileNamePattern>
+            <!-- 单个日志文件最大10MB, 保存30天的历史日志, 所有日志文件最大500MB -->
+            <maxFileSize>10MB</maxFileSize>
+            <maxHistory>30</maxHistory>
+            <totalSizeCap>500MB</totalSizeCap>
+        </rollingPolicy>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>DEBUG</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <!-- 保留INFO Level的日志 -->
+    <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <!-- %i用来标记分割日志的序号 -->
+            <fileNamePattern>${LOG_FILE}%d{yyyy-MM-dd}_INFO_%i.log</fileNamePattern>
+            <!-- 单个日志文件最大10MB, 保存30天的历史日志, 所有日志文件最大50MB -->
+            <maxFileSize>10MB</maxFileSize>
+            <maxHistory>30</maxHistory>
+            <totalSizeCap>500MB</totalSizeCap>
+        </rollingPolicy>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>INFO</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <!-- 保留 WARN Level的日志 -->
+    <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <!-- %i用来标记分割日志的序号 -->
+            <fileNamePattern>${LOG_FILE}%d{yyyy-MM-dd}_WARN_%i.log</fileNamePattern>
+            <!-- 单个日志文件最大10MB, 保存30天的历史日志, 所有日志文件最大50MB -->
+            <maxFileSize>10MB</maxFileSize>
+            <maxHistory>30</maxHistory>
+            <totalSizeCap>500MB</totalSizeCap>
+        </rollingPolicy>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>WARN</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <!-- 保留ERROR Level的日志 -->
+    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <!-- %i用来标记分割日志的序号 -->
+            <fileNamePattern>${LOG_FILE}%d{yyyy-MM-dd}_ERROR_%i.log</fileNamePattern>
+            <!-- 单个日志文件最大10MB, 保存30天的历史日志, 所有日志文件最大50MB -->
+            <maxFileSize>10MB</maxFileSize>
+            <maxHistory>30</maxHistory>
+            <totalSizeCap>500MB</totalSizeCap>
+        </rollingPolicy>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>ERROR</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <!-- 控制台显示的日志级别 -->
+    <root level="INFO">
+        <appender-ref ref="CONSOLE" />
+        <appender-ref ref="DEBUG_FILE" />
+        <appender-ref ref="INFO_FILE" />
+        <appender-ref ref="WARN_FILE" />
+        <appender-ref ref="ERROR_FILE" />
+    </root>
+
+    <!-- 不同环境中打印不同级别的日志,多个环境用逗号隔开 -->
+    <springProfile name="test,dev">
+        <logger name="cn.aiyangniu.api" level="DEBUG"/>
+    </springProfile>
+    <springProfile name="prod">
+        <logger name="cn.aiyangniu.api" level="WARN"/>
+    </springProfile>
+</configuration>

+ 17 - 0
src/main/resources/mapper/system/sysAreaMapper.xml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="cn.aiyangniu.api.mapper.system.SysAreaMapper">
+
+  <!-- 列表展示按钮 -->
+  <select id="selAreas" parameterType="cn.aiyangniu.api.common.entity.system.SysAreaVo" resultType="cn.aiyangniu.api.common.entity.system.SysAreaEntity">
+    SELECT area_id, area_name
+      FROM sys_area
+     WHERE area_level=#{areaLevel}
+       AND parent_id=#{parentId}
+    <if test="name!=''">
+       AND (area_name LIKE CONCAT('%', #{name}, '%') OR area_code LIKE CONCAT('%', #{name}, '%') OR pinyin LIKE CONCAT('%', #{name}, '%') OR jianpin LIKE CONCAT('%', #{name}, '%'))
+    </if>
+     ORDER BY area_id
+  </select>
+</mapper>

+ 69 - 0
src/main/resources/mapper/system/sysBtnMapper.xml

@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="cn.aiyangniu.api.mapper.system.SysBtnMapper">
+
+  <!-- 添加按钮 -->
+  <insert id="addBtn" parameterType="cn.aiyangniu.api.common.entity.system.SysBtnEntity">
+    INSERT INTO sys_button (btn_id, btn_name, btn_code, mod_id, sort, opt_user)
+    VALUES (UUID(), #{btnName}, #{btnCode}, #{modId}, #{sort}, #{optUser})
+  </insert>
+
+  <!-- 删除按钮 -->
+  <update id="delBtns" parameterType="cn.aiyangniu.api.common.entity.system.SysBtnVo">
+    UPDATE sys_button SET data_status=3, update_time=NOW(), opt_user=#{optUser} WHERE btn_id IN
+    <foreach collection="btnIds" item="btnId" open="(" separator="," close=")">
+      #{btnId}
+    </foreach>
+  </update>
+
+  <!-- 根据模块编号删除按钮 -->
+  <update id="delBtnsByModId" parameterType="cn.aiyangniu.api.common.entity.system.SysModVo">
+    UPDATE sys_button SET data_status=3, update_time=NOW(), opt_user=#{optUser} WHERE mod_id IN
+    <foreach collection="modIds" item="modId" open="(" separator="," close=")">
+      #{modId}
+    </foreach>
+  </update>
+
+  <!-- 获取单一按钮 -->
+  <select id="getBtn" parameterType="string" resultType="cn.aiyangniu.api.common.entity.system.SysBtnEntity">
+    SELECT a.btn_id, a.btn_name, a.btn_code, a.mod_id, b.mod_name, b.mod_code, a.sort
+      FROM sys_button a
+      LEFT JOIN sys_module b on b.data_status=1 AND a.mod_id=b.mod_id
+     WHERE a.btn_id=#{btnId}
+  </select>
+
+  <!-- 修改按钮 -->
+  <update id="edtBtn" parameterType="cn.aiyangniu.api.common.entity.system.SysBtnEntity">
+    UPDATE sys_button SET btn_name=#{btnName}, btn_code=#{btnCode}, mod_id=#{modId}, sort=#{sort}, update_time=NOW(), opt_user=#{optUser}
+     WHERE btn_id=#{btnId}
+  </update>
+
+  <!-- 列表展示按钮 -->
+  <select id="listBtns" resultType="cn.aiyangniu.api.common.entity.system.SysBtnEntity">
+    SELECT a.btn_id, a.btn_name, a.btn_code, b.mod_name modName, a.sort
+      FROM sys_button a
+      LEFT JOIN sys_module b ON b.data_status=1 AND a.mod_id=b.mod_id
+     WHERE a.data_status=1
+    <if test="vo.schName!=''">
+       AND (a.btn_name LIKE CONCAT('%', #{vo.schName}, '%') OR a.btn_code LIKE CONCAT('%', #{vo.schName}, '%'))
+    </if>
+    <if test="vo.modId!=''">
+       AND a.mod_id=#{vo.modId}
+    </if>
+     ORDER BY b.sort, a.sort
+  </select>
+
+  <!-- 统计子级按钮数量,用于排序 -->
+  <select id="sortBtns" parameterType="string" resultType="int">
+    SELECT COUNT(1)+1 AS r FROM sys_button WHERE data_status=1 AND mod_id=#{modId}
+  </select>
+
+  <!-- 下拉选择展示按钮 -->
+  <select id="selBtns" resultType="cn.aiyangniu.api.common.entity.system.SysBtnEntity">
+    SELECT btn_id, btn_name, btn_code, mod_id
+      FROM sys_button
+     WHERE data_status=1
+     ORDER BY sort
+  </select>
+</mapper>

+ 61 - 0
src/main/resources/mapper/system/sysModMapper.xml

@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="cn.aiyangniu.api.mapper.system.SysModMapper">
+
+  <!-- 添加模块 -->
+  <insert id="addMod" parameterType="cn.aiyangniu.api.common.entity.system.SysModEntity">
+    INSERT INTO sys_module (mod_id, mod_name, mod_code, parent_id, sort, logo, url, opt_user)
+    VALUES (UUID(), #{modName}, #{modCode}, #{parentId}, #{sort},  #{logo}, #{url}, #{optUser})
+  </insert>
+
+  <!-- 删除模块 -->
+  <update id="delMods" parameterType="cn.aiyangniu.api.common.entity.system.SysModVo">
+    UPDATE sys_module SET data_status=3, update_time=NOW(), opt_user=#{optUser} WHERE mod_id IN
+    <foreach collection="modIds" item="modId" open="(" separator="," close=")">
+      #{modId}
+    </foreach>
+  </update>
+
+  <!-- 获取单一模块 -->
+  <select id="getMod" parameterType="string" resultType="cn.aiyangniu.api.common.entity.system.SysModEntity">
+    SELECT a.mod_id, a.mod_name, a.mod_code, a.parent_id, (CASE WHEN a.parent_id='00000000-0000-0000-0000-000000000000' THEN '一级模块' ELSE b.mod_name END) parentName, (CASE WHEN a.parent_id='00000000-0000-0000-0000-000000000000' THEN '10000000' ELSE b.mod_code END) parentCode, a.sort, a.logo, a.url
+      FROM sys_module a
+      LEFT JOIN sys_module b ON b.data_status=1 AND a.parent_id=b.mod_id
+     WHERE a.mod_id=#{modId}
+     LIMIT 1
+  </select>
+
+  <!-- 修改模块 -->
+  <update id="edtMod" parameterType="cn.aiyangniu.api.common.entity.system.SysModEntity">
+    UPDATE sys_module SET mod_name=#{modName}, mod_code=#{modCode}, parent_id=#{parentId}, sort=#{sort}, logo=#{logo}, url=#{url}, update_time=NOW(), opt_user=#{optUser}
+     WHERE mod_id=#{modId}
+  </update>
+
+  <!-- 列表展示模块 -->
+  <select id="listMods" parameterType="string" resultType="cn.aiyangniu.api.common.entity.system.SysModEntity">
+    SELECT a.mod_id, a.mod_name, a.mod_code, a.parent_id, a.sort, a.logo, a.url
+      FROM sys_module a
+     WHERE a.data_status=1
+     ORDER BY a.sort
+  </select>
+
+  <!-- 下拉选择模块 -->
+  <select id="selMods" parameterType="map" resultType="cn.aiyangniu.api.common.entity.system.SysModEntity">
+    SELECT mod_id, mod_name, mod_code, parent_id, logo, url
+    FROM sys_module
+     WHERE data_status=1
+    <if test="name!=''">
+       AND (mod_name LIKE CONCAT('%', #{schName}, '%') OR mod_code LIKE CONCAT('%', #{schName}, '%'))
+    </if>
+     ORDER BY sort
+  </select>
+
+  <!-- 统计子级模块数量,用于排序 -->
+  <select id="sortMods" parameterType="string" resultType="int">
+    SELECT COUNT(1)+1 AS r
+      FROM sys_module
+     WHERE data_status=1
+       AND parent_id=#{parentId}
+  </select>
+</mapper>

+ 86 - 0
src/main/resources/mapper/system/sysMsgMapper.xml

@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="cn.aiyangniu.api.mapper.system.SysMsgMapper">
+
+  <!-- 添加消息 -->
+  <insert id="addMsg" parameterType="cn.aiyangniu.api.common.entity.system.SysMsgEntity">
+    INSERT INTO sys_message (msg_id, title, remarks, kind, info_id, data_status, create_time, opt_user)
+    VALUES (UUID(), #{title}, #{remarks}, #{kind}, #{infoId}, 2, NOW(), #{optUser})
+  </insert>
+  <insert id="addMsgDetail" parameterType="cn.aiyangniu.api.common.entity.system.SysMsgEntity">
+    INSERT INTO sys_msg_detail (detail_id, msg_id, kind, user_id, data_status, create_time, opt_user) VALUES
+    <foreach collection="msgEntity.detailList" item="msgDetail" separator=",">
+      (UUID(), #{msgId}, #{msgDetail.kind}, #{msgDetail.userId}, 2, NOW(), #{msgDetail.optUser})
+    </foreach>
+  </insert>
+
+  <!-- 已读、删除消息 -->
+  <update id="proMsgs" parameterType="cn.aiyangniu.api.common.entity.system.SysMsgVo">
+    UPDATE sys_message SET data_status=#{status}, update_time=NOW(), opt_user=#{optUser} WHERE msg_id IN
+    <foreach collection="msgIds" item="msgId" open="(" separator="," close=")">
+      #{msgId}
+    </foreach>
+  </update>
+
+  <!-- 列表展示消息 -->
+  <select id="listMsgs" resultType="cn.aiyangniu.api.common.entity.system.SysMsgEntity">
+    SELECT a.msg_id, a.title, a.remarks, a.kind, b.opt_name kindName, a.info_id, a.data_status, a.create_time
+      FROM sys_message a
+      LEFT JOIN sys_option b ON b.data_status=1 AND a.kind=b.opt_id
+     WHERE a.data_status!=3
+    <if test="vo.title!=''">
+       AND a.title LIKE CONCAT('%', #{vo.title}, '%')
+    </if>
+    <if test="vo.kind!=''">
+       AND a.kind=#{vo.kind}
+    </if>
+    <if test="vo.status!=''">
+      AND a.data_status=#{vo.status}
+    </if>
+    <if test="vo.beginDate!=''">
+      AND a.create_time>=STR_TO_DATE(#{vo.beginDate}, '%Y-%m-%d')
+    </if>
+    <if test="vo.endDate!=''">
+      <![CDATA[
+       AND a.create_time<=STR_TO_DATE(#{vo.endDate}, '%Y-%m-%d')
+      ]]>
+    </if>
+     ORDER BY a.create_time DESC
+  </select>
+
+  <!-- 我的消息列表 -->
+  <select id="myMsgs" resultType="cn.aiyangniu.api.common.entity.system.SysMsgEntity">
+    SELECT a.msg_id, a.title, a.remarks, a.kind, c.opt_name kindName, a.info_id, a.data_status, a.create_time
+      FROM sys_message a
+      LEFT JOIN sys_msg_detail b ON b.data_status!=3 AND a.msg_id=b.msg_id
+      LEFT JOIN sys_option c ON c.data_status=1 AND a.kind=c.opt_id
+     WHERE a.data_status!=3 AND b.user_id=#{userId}
+    <if test="vo.title!=''">
+       AND a.title LIKE CONCAT('%', #{vo.title}, '%')
+    </if>
+    <if test="vo.kind!=''">
+       AND a.kind=#{vo.kind}
+    </if>
+    <if test="vo.status!=''">
+       AND b.data_status=#{vo.status}
+    </if>
+    <if test="vo.beginDate!=''">
+       AND b.create_time>=STR_TO_DATE(#{vo.beginDate}, '%Y-%m-%d')
+    </if>
+    <if test="vo.endDate!=''">
+      <![CDATA[
+       AND b.create_time<=STR_TO_DATE(#{vo.endDate}, '%Y-%m-%d')
+      ]]>
+    </if>
+     ORDER BY b.create_time DESC
+  </select>
+
+  <!-- 获取单一消息 -->
+  <select id="getMsg" parameterType="string" resultType="cn.aiyangniu.api.common.entity.system.SysMsgEntity">
+    SELECT a.msg_id, a.title, a.remarks, a.kind, b.opt_name kindName, a.info_id, a.data_status, a.create_time
+      FROM sys_message a
+      LEFT JOIN sys_option b ON b.data_status=1 AND a.kind=b.opt_id
+     WHERE a.msg_id=#{msgId}
+  </select>
+</mapper>

+ 76 - 0
src/main/resources/mapper/system/sysOptMapper.xml

@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="cn.aiyangniu.api.mapper.system.SysOptMapper">
+
+  <!-- 添加选项 -->
+  <insert id="addOpt" parameterType="cn.aiyangniu.api.common.entity.system.SysOptEntity">
+    INSERT INTO sys_option (opt_id, opt_name, opt_code, kind, sort, pinyin, jianpin, opt_user)
+    VALUES (UUID(), #{optName}, #{optCode}, #{kind}, #{sort}, #{pinyin}, #{jianpin}, #{optUser})
+  </insert>
+
+  <!-- 删除选项 -->
+  <update id="delOpts" parameterType="cn.aiyangniu.api.common.entity.system.SysOptVo">
+    UPDATE sys_option SET data_status=3, update_time=NOW(), opt_user=#{optUser} WHERE opt_id IN
+    <foreach collection="optIds" item="optId" open="(" separator="," close=")">
+      #{optId}
+    </foreach>
+  </update>
+
+  <!-- 删除子选项 -->
+  <update id="delChildOpts" parameterType="cn.aiyangniu.api.common.entity.system.SysOptVo">
+    UPDATE sys_option SET data_status=3, update_time=NOW(), opt_user=#{optUser} WHERE kind IN
+    <foreach collection="optIds" item="optId" open="(" separator="," close=")">
+      #{optId}
+    </foreach>
+  </update>
+
+  <!-- 获取单一选项 -->
+  <select id="getOpt" parameterType="string" resultType="cn.aiyangniu.api.common.entity.system.SysOptEntity">
+    SELECT a.opt_id, a.opt_name, a.opt_code, a.kind, b.opt_name kindName, b.opt_code kindCode, a.sort
+      FROM sys_option a
+      LEFT JOIN sys_option b ON b.data_status=1 AND a.kind=b.opt_id
+     WHERE a.opt_id=#{optId}
+  </select>
+
+  <!-- 修改选项 -->
+  <update id="edtOpt" parameterType="cn.aiyangniu.api.common.entity.system.SysOptEntity">
+    UPDATE sys_option SET opt_name=#{optName}, opt_code=#{optCode}, kind=#{kind}, sort=#{sort}, pinyin=#{pinyin}, jianpin=#{jianpin}, update_time=NOW(), opt_user=#{optUser}
+     WHERE opt_id=#{optId}
+  </update>
+
+  <!-- 列表展示选项 -->
+  <select id="listOpts" parameterType="cn.aiyangniu.api.common.entity.system.SysOptVo" resultType="cn.aiyangniu.api.common.entity.system.SysOptEntity">
+    SELECT a.opt_id, a.opt_name, a.opt_code, a.kind, a.sort, b.opt_name kindName
+      FROM sys_option a
+      LEFT JOIN sys_option b ON b.data_status=1 AND a.kind=b.opt_id
+     WHERE a.data_status=1
+       AND a.opt_id!='00000000-0000-0000-0000-000000000000'
+    <if test="vo.name!=''">
+       AND (a.opt_name LIKE CONCAT('%', #{vo.name}, '%') OR a.opt_code LIKE CONCAT('%', #{vo.name}, '%') OR a.pinyin LIKE CONCAT('%', #{vo.name}, '%') OR a.jianpin LIKE CONCAT('%', #{vo.name}, '%'))
+    </if>
+    <if test="vo.kind!=''">
+       AND a.kind=#{vo.kind}
+    </if>
+     ORDER BY b.sort, a.sort
+  </select>
+
+  <!-- 统计同种类参数项的数量,用于排序 -->
+  <select id="sortOpts" parameterType="string" resultType="int">
+    SELECT COUNT(1)+1 AS r FROM sys_option WHERE data_status=1 AND kind=#{kind}
+  </select>
+
+  <!-- 下拉选择展示选项 -->
+  <select id="selOpts" parameterType="map" resultType="cn.aiyangniu.api.common.entity.system.SysOptEntity">
+    SELECT opt_id, opt_code, opt_name, sort
+      FROM sys_option
+     WHERE data_status=1
+    <if test="name!=''">
+       AND (opt_name LIKE CONCAT('%', #{name}, '%') OR opt_code LIKE CONCAT('%', #{name}, '%') OR pinyin LIKE CONCAT('%', #{name}, '%') OR jianpin LIKE CONCAT('%', #{name}, '%'))
+    </if>
+    <if test="kind!=''">
+       AND kind=#{kind}
+    </if>
+     ORDER BY sort
+  </select>
+</mapper>

+ 59 - 0
src/main/resources/mapper/system/sysRoleMapper.xml

@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="cn.aiyangniu.api.mapper.system.SysRoleMapper">
+
+  <!-- 添加角色 -->
+  <insert id="addRole" parameterType="cn.aiyangniu.api.common.entity.system.SysRoleEntity">
+    INSERT INTO sys_role (role_id, role_name, display, mod_codes, btn_codes, opt_user)
+    VALUES (UUID(), #{roleName}, #{display}, #{modCodes}, #{btnCodes}, #{optUser})
+  </insert>
+
+  <!-- 删除角色 -->
+  <update id="delRoles" parameterType="cn.aiyangniu.api.common.entity.system.SysRoleVo">
+    UPDATE sys_role SET data_status=3, update_time=NOW(), opt_user=#{optUser} WHERE role_id IN
+    <foreach collection="roleIds" item="roleId" open="(" separator="," close=")">
+      #{roleId}
+    </foreach>
+  </update>
+
+  <!-- 获取单一角色 -->
+  <select id="getRole" parameterType="string" resultType="cn.aiyangniu.api.common.entity.system.SysRoleEntity">
+    SELECT role_id, role_name, display, mod_codes, btn_codes FROM sys_role WHERE role_id=#{roleId}
+  </select>
+
+  <!-- 修改角色 -->
+  <update id="edtRole" parameterType="cn.aiyangniu.api.common.entity.system.SysRoleEntity">
+    UPDATE sys_role SET role_name=#{roleName}, display=#{display}, mod_codes=#{modCodes}, btn_codes=#{btnCodes}, update_time=NOW(), opt_user=#{optUser}
+     WHERE role_id=#{roleId}
+  </update>
+
+  <!-- 列表展示角色 -->
+  <select id="listRoles" parameterType="cn.aiyangniu.api.common.entity.system.SysRoleVo" resultType="cn.aiyangniu.api.common.entity.system.SysRoleEntity">
+    SELECT role_id, role_name, display
+      FROM sys_role
+     WHERE data_status=1
+    <!-- 代表普通角色,没有查看所有角色的权限 -->
+    <if test="vo.auth==2">
+       AND display=1
+    </if>
+    <if test="vo.name!=''">
+       AND role_name LIKE CONCAT('%', #{vo.name}, '%')
+    </if>
+    <if test="vo.display!=0">
+       AND display=#{vo.display}
+    </if>
+     ORDER BY create_time DESC
+  </select>
+
+  <!-- 下拉选择展示角色 -->
+  <select id="selRoles" parameterType="int" resultType="cn.aiyangniu.api.common.entity.system.SysRoleEntity">
+    SELECT role_id, role_name
+      FROM sys_role
+     WHERE data_status=1
+    <if test="auth==2">
+       AND display=1
+    </if>
+     ORDER BY create_time DESC
+  </select>
+</mapper>

+ 66 - 0
src/main/resources/mapper/system/sysTypeMapper.xml

@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="cn.aiyangniu.api.mapper.system.SysTypeMapper">
+
+  <!-- 添加选项 -->
+  <insert id="addType" parameterType="cn.aiyangniu.api.common.entity.system.SysTypeEntity">
+    INSERT INTO sys_type (type_id, parent_id, type_name, type_code, pinyin, jianpin, kind, sort, type_img, opt_user)
+    VALUES (UUID(), #{parentId}, #{typeName}, #{typeCode}, #{pinyin}, #{jianpin}, #{kind}, #{sort}, #{typeImg}, #{optUser})
+  </insert>
+
+  <!-- 删除选项 -->
+  <update id="delTypes" parameterType="cn.aiyangniu.api.common.entity.system.SysTypeVo">
+    UPDATE sys_type SET data_status=3, update_time=NOW(), opt_user=#{optUser} WHERE type_id IN
+    <foreach collection="typeIds" item="typeId" open="(" separator="," close=")">
+      #{typeId}
+    </foreach>
+  </update>
+
+  <!-- 获取单一选项 -->
+  <select id="getType" parameterType="string" resultType="cn.aiyangniu.api.common.entity.system.SysTypeEntity">
+    SELECT a.type_id, a.type_name, a.type_code, a.kind, b.opt_name kindName, b.opt_code kindCode, a.parent_id, (CASE WHEN a.parent_id='00000000-0000-0000-0000-000000000000' THEN '一级模块' ELSE c.type_name END) parentName, (CASE WHEN a.parent_id='00000000-0000-0000-0000-000000000000' THEN '10000000' ELSE c.type_code END) parentCode, a.sort, a.type_img
+      FROM sys_type a
+      LEFT JOIN sys_option b ON b.data_status=1 AND a.kind=b.opt_id
+      LEFT JOIN sys_type c ON c.data_status=1 AND a.parent_id=c.type_id
+     WHERE a.type_id=#{typeId}
+  </select>
+
+  <!-- 修改选项 -->
+  <update id="edtType" parameterType="cn.aiyangniu.api.common.entity.system.SysTypeEntity">
+    UPDATE sys_type SET parent_id=#{parentId}, type_name=#{typeName}, type_code=#{typeCode}, pinyin=#{pinyin}, jianpin=#{jianpin}, kind=#{kind}, sort=#{sort}, type_img=#{typeImg}, update_time=NOW(), opt_user=#{optUser}
+    WHERE type_id=#{typeId}
+  </update>
+
+  <!-- 列表展示选项 -->
+  <select id="listTypes" parameterType="string" resultType="cn.aiyangniu.api.common.entity.system.SysTypeEntity">
+    SELECT type_id, type_name, type_code, parent_id, sort
+      FROM sys_type
+     WHERE data_status=1 AND kind=#{kind}
+     ORDER BY sort
+  </select>
+
+  <!-- 统计子级选项数量,用于排序 -->
+  <select id="sortTypes" parameterType="cn.aiyangniu.api.common.entity.system.SysTypeVo" resultType="int">
+    SELECT COUNT(1)+1 AS r
+      FROM sys_type
+     WHERE data_status=1
+    <if test="parentId!=''">
+       AND parent_id=#{parentId}
+    </if>
+  </select>
+
+  <!-- 下拉选择选项 -->
+  <select id="selTypes" parameterType="cn.aiyangniu.api.common.entity.system.SysTypeVo" resultType="cn.aiyangniu.api.common.entity.system.SysTypeEntity">
+    SELECT type_id, type_name, type_code, parent_id
+      FROM sys_type
+     WHERE data_status=1
+    <if test="kind!=''">
+       AND kind=#{kind}
+    </if>
+    <if test="name!=''">
+       AND (type_name LIKE CONCAT('%', #{name}, '%') OR type_code LIKE CONCAT('%', #{name}, '%') OR pinyin LIKE CONCAT('%', #{name}, '%') OR jianpin LIKE CONCAT('%', #{name}, '%'))
+    </if>
+     ORDER BY sort
+  </select>
+</mapper>

+ 105 - 0
src/main/resources/mapper/system/sysUserMapper.xml

@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="cn.aiyangniu.api.mapper.system.SysUserMapper">
+
+  <!-- 添加用户 -->
+  <insert id="addUser" parameterType="cn.aiyangniu.api.common.entity.system.SysUserEntity">
+    INSERT INTO sys_user (user_id, usname, passwd, nick_name, mobile, role_id, org_id, duty_id, opt_user)
+    VALUES (UUID(), #{usname}, #{passwd}, #{nickName}, #{mobile}, #{roleId}, #{orgId}, #{dutyId}, #{optUser})
+  </insert>
+
+  <!-- 删除用户 -->
+  <update id="proUsers" parameterType="cn.aiyangniu.api.common.entity.system.SysUserVo">
+    UPDATE sys_user SET data_status=#{dataStatus}, update_time=NOW(), opt_user=#{optUser} WHERE user_id IN
+    <foreach collection="userIds" item="userId" open="(" separator="," close=")">
+      #{userId}
+    </foreach>
+  </update>
+
+  <!-- 获取单一用户 -->
+  <select id="getUser" parameterType="string" resultType="cn.aiyangniu.api.common.entity.system.SysUserEntity">
+    SELECT a.user_id, a.nick_name, a.mobile, a.usname, a.org_id orgId, b.type_name orgName, b.type_code orgCode, a.duty_id, c.opt_name dutyName, c.opt_code dutyCode, a.role_id, d.role_name
+      FROM sys_user a
+      LEFT JOIN sys_type b ON b.data_status=1 AND a.org_id=b.type_id
+      LEFT JOIN sys_option c ON c.data_status=1 AND a.duty_id=c.opt_id
+      LEFT JOIN sys_role d ON d.data_status=1 AND a.role_id=d.role_id
+     WHERE a.user_id=#{userId}
+  </select>
+
+  <!-- 修改用户 -->
+  <update id="edtUser" parameterType="cn.aiyangniu.api.common.entity.system.SysUserEntity">
+    UPDATE sys_user SET usname=#{usname}, <if test="passwd!='' and passwd!='********'">passwd=#{passwd}, </if>nick_name=#{nickName}, mobile=#{mobile}, role_id=#{roleId}, org_id=#{orgId}, duty_id=#{dutyId}, update_time=NOW(), opt_user=#{optUser}
+     WHERE user_id=#{userId}
+  </update>
+
+  <!-- 列表展示用户 -->
+  <select id="listUsers" resultType="cn.aiyangniu.api.common.entity.system.SysUserDto">
+    SELECT a.user_id, a.usname, a.nick_name, a.mobile, b.role_name, c.type_code, c.type_name, d.opt_code, d.opt_name, a.data_status
+      FROM sys_user a
+      LEFT JOIN sys_role b ON b.data_status=1 AND a.role_id=b.role_id
+      LEFT JOIN sys_type c ON c.data_status=1 AND a.org_id=c.type_id
+      LEFT JOIN sys_option d ON d.data_status=1 AND a.duty_id=d.opt_id
+     WHERE a.data_status!=3
+    <if test="vo.name!=''">
+       AND (a.usname LIKE CONCAT('%', #{vo.name}, '%') OR a.nick_name LIKE CONCAT('%', #{vo.name}, '%') OR a.mobile LIKE CONCAT('%', #{vo.name}, '%'))
+    </if>
+    <if test="vo.roleId!=''">
+      AND a.role_id=#{vo.roleId}
+    </if>
+    <if test="vo.orgId!=''">
+       AND a.org_id=#{vo.orgId}
+    </if>
+    <if test="vo.dutyId!=''">
+       AND a.duty_id=#{vo.dutyId}
+    </if>
+    <if test="vo.dataStatus!=0">
+       AND a.data_status=#{vo.dataStatus}
+    </if>
+    <if test="vo.kind==2">
+      AND a.kind=1
+    </if>
+     ORDER BY a.data_status, a.create_time DESC
+  </select>
+
+  <!-- 下拉选择展示用户 -->
+  <select id="selUsers" parameterType="cn.aiyangniu.api.common.entity.system.SysUserVo" resultType="cn.aiyangniu.api.common.entity.system.SysUserDto">
+    SELECT a.user_id, a.usname, a.nick_name, a.mobile, b.type_code, b.type_name, c.opt_code, c.opt_name
+      FROM sys_user a
+      LEFT JOIN sys_type b ON b.data_status=1 AND b.kind=1 AND a.org_id=b.type_id
+      LEFT JOIN sys_option c ON c.data_status=1 AND c.kind=1 AND a.duty_id=c.opt_id
+     WHERE a.data_status=1
+    <if test="name!=''">
+      AND (a.usname LIKE CONCAT('%', #{name}, '%') OR a.nick_name LIKE CONCAT('%', #{name}, '%') OR a.mobile LIKE CONCAT('%', #{name}, '%'))
+    </if>
+    <if test="kind==2">
+      AND a.kind=1
+    </if>
+     ORDER BY a.create_time DESC
+  </select>
+
+  <!-- 根据账号查询重复的用户 -->
+  <select id="extUser" parameterType="cn.aiyangniu.api.common.entity.system.SysUserVo" resultType="int">
+    SELECT COUNT(1) AS r
+      FROM sys_user
+     WHERE data_status=1
+       AND usname=#{usname}
+    <if test="userId!=''">
+      AND user_id!=#{userId}
+    </if>
+  </select>
+
+  <!-- 用户登录 -->
+  <select id="loginUser" parameterType="cn.aiyangniu.api.common.entity.system.SysUserVo" resultType="cn.aiyangniu.api.common.entity.system.SysUserDto">
+    SELECT a.user_id, a.usname, a.nick_name, a.mobile, a.data_status, a.role_id, b.mod_codes, b.btn_codes
+      FROM sys_user a
+      LEFT JOIN sys_role b ON b.data_status=1 AND a.role_id=b.role_id
+     WHERE a.usname=#{usname} AND a.passwd=#{passwd}
+  </select>
+
+  <!-- 修改用户个人资料 -->
+  <update id="updUser" parameterType="cn.aiyangniu.api.common.entity.system.SysUserEntity">
+    UPDATE sys_user SET usname=#{usname}, <if test="passwd!='' and passwd!='********'">passwd=#{passwd}, </if>nick_name=#{nickName}, mobile=#{mobile}, update_time=NOW(), opt_user=#{optUser}
+    WHERE user_id=#{userId}
+  </update>
+</mapper>