yangdamao 8 ay önce
işleme
8bc44072a7
100 değiştirilmiş dosya ile 5346 ekleme ve 0 silme
  1. 42 0
      .drone.yml
  2. 44 0
      .gitignore
  3. 12 0
      Dockerfile
  4. 1 0
      HELP.md
  5. 276 0
      pom.xml
  6. 33 0
      run-prod.sh
  7. 19 0
      src/main/java/com/zhongzheng/ZhongZhengOfficialApplication.java
  8. 18 0
      src/main/java/com/zhongzheng/ZhongZhengServletInitializer.java
  9. 131 0
      src/main/java/com/zhongzheng/api/OfficialApiController.java
  10. 12 0
      src/main/java/com/zhongzheng/bo/BatchDelBo.java
  11. 28 0
      src/main/java/com/zhongzheng/bo/CommonOfficialBo.java
  12. 43 0
      src/main/java/com/zhongzheng/bo/LoginBody.java
  13. 42 0
      src/main/java/com/zhongzheng/bo/OfficialActivityBo.java
  14. 13 0
      src/main/java/com/zhongzheng/bo/OfficialActivityQuery.java
  15. 36 0
      src/main/java/com/zhongzheng/bo/OfficialArticleBo.java
  16. 29 0
      src/main/java/com/zhongzheng/bo/OfficialArticleQuery.java
  17. 30 0
      src/main/java/com/zhongzheng/bo/OfficialLinkBo.java
  18. 13 0
      src/main/java/com/zhongzheng/bo/OfficialLinkQuery.java
  19. 48 0
      src/main/java/com/zhongzheng/bo/OfficialMenuBo.java
  20. 16 0
      src/main/java/com/zhongzheng/bo/OfficialMenuQuery.java
  21. 13 0
      src/main/java/com/zhongzheng/bo/OfficialOpenBo.java
  22. 30 0
      src/main/java/com/zhongzheng/bo/OfficialProblemBo.java
  23. 13 0
      src/main/java/com/zhongzheng/bo/OfficialProblemQuery.java
  24. 30 0
      src/main/java/com/zhongzheng/bo/OfficialSuggestBo.java
  25. 13 0
      src/main/java/com/zhongzheng/bo/OfficialSuggestQuery.java
  26. 29 0
      src/main/java/com/zhongzheng/bo/OssRequest.java
  27. 45 0
      src/main/java/com/zhongzheng/bo/SysMenuBo.java
  28. 31 0
      src/main/java/com/zhongzheng/bo/SysRoleBo.java
  29. 34 0
      src/main/java/com/zhongzheng/bo/SysUserBo.java
  30. 15 0
      src/main/java/com/zhongzheng/bo/SysUserQuery.java
  31. 19 0
      src/main/java/com/zhongzheng/bo/UserPwdBo.java
  32. 58 0
      src/main/java/com/zhongzheng/config/CaptchaConfig.java
  33. 20 0
      src/main/java/com/zhongzheng/config/OssConfig.java
  34. 68 0
      src/main/java/com/zhongzheng/config/ResourcesConfig.java
  35. 76 0
      src/main/java/com/zhongzheng/config/RuoYiConfig.java
  36. 163 0
      src/main/java/com/zhongzheng/config/SecurityConfig.java
  37. 147 0
      src/main/java/com/zhongzheng/config/SwaggerConfig.java
  38. 137 0
      src/main/java/com/zhongzheng/controller/CaptchaController.java
  39. 83 0
      src/main/java/com/zhongzheng/controller/OfficialActivityController.java
  40. 80 0
      src/main/java/com/zhongzheng/controller/OfficialArticleController.java
  41. 59 0
      src/main/java/com/zhongzheng/controller/OfficialLinkController.java
  42. 80 0
      src/main/java/com/zhongzheng/controller/OfficialMenuController.java
  43. 59 0
      src/main/java/com/zhongzheng/controller/OfficialProblemController.java
  44. 59 0
      src/main/java/com/zhongzheng/controller/OfficialSuggestController.java
  45. 47 0
      src/main/java/com/zhongzheng/controller/OssController.java
  46. 95 0
      src/main/java/com/zhongzheng/controller/SysLoginController.java
  47. 69 0
      src/main/java/com/zhongzheng/controller/SysMenuController.java
  48. 78 0
      src/main/java/com/zhongzheng/controller/SysRoleController.java
  49. 88 0
      src/main/java/com/zhongzheng/controller/SysUserController.java
  50. 68 0
      src/main/java/com/zhongzheng/entity/OfficialActivity.java
  51. 58 0
      src/main/java/com/zhongzheng/entity/OfficialArticle.java
  52. 48 0
      src/main/java/com/zhongzheng/entity/OfficialLink.java
  53. 78 0
      src/main/java/com/zhongzheng/entity/OfficialMenu.java
  54. 48 0
      src/main/java/com/zhongzheng/entity/OfficialProblem.java
  55. 48 0
      src/main/java/com/zhongzheng/entity/OfficialSuggest.java
  56. 84 0
      src/main/java/com/zhongzheng/entity/SysMenu.java
  57. 54 0
      src/main/java/com/zhongzheng/entity/SysRole.java
  58. 35 0
      src/main/java/com/zhongzheng/entity/SysRoleMenu.java
  59. 64 0
      src/main/java/com/zhongzheng/entity/SysUser.java
  60. 35 0
      src/main/java/com/zhongzheng/entity/SysUserRole.java
  61. 43 0
      src/main/java/com/zhongzheng/exception/CustomException.java
  62. 14 0
      src/main/java/com/zhongzheng/mapper/OfficialActivityMapper.java
  63. 14 0
      src/main/java/com/zhongzheng/mapper/OfficialArticleMapper.java
  64. 14 0
      src/main/java/com/zhongzheng/mapper/OfficialLinkMapper.java
  65. 14 0
      src/main/java/com/zhongzheng/mapper/OfficialMenuMapper.java
  66. 14 0
      src/main/java/com/zhongzheng/mapper/OfficialProblemMapper.java
  67. 14 0
      src/main/java/com/zhongzheng/mapper/OfficialSuggestMapper.java
  68. 15 0
      src/main/java/com/zhongzheng/mapper/SysMenuMapper.java
  69. 15 0
      src/main/java/com/zhongzheng/mapper/SysRoleMapper.java
  70. 15 0
      src/main/java/com/zhongzheng/mapper/SysRoleMenuMapper.java
  71. 14 0
      src/main/java/com/zhongzheng/mapper/SysUserMapper.java
  72. 15 0
      src/main/java/com/zhongzheng/mapper/SysUserRoleMapper.java
  73. 27 0
      src/main/java/com/zhongzheng/service/IOfficialActivityService.java
  74. 30 0
      src/main/java/com/zhongzheng/service/IOfficialApiService.java
  75. 27 0
      src/main/java/com/zhongzheng/service/IOfficialArticleService.java
  76. 23 0
      src/main/java/com/zhongzheng/service/IOfficialLinkService.java
  77. 26 0
      src/main/java/com/zhongzheng/service/IOfficialMenuService.java
  78. 23 0
      src/main/java/com/zhongzheng/service/IOfficialProblemService.java
  79. 23 0
      src/main/java/com/zhongzheng/service/IOfficialSuggestService.java
  80. 25 0
      src/main/java/com/zhongzheng/service/ISysMenuService.java
  81. 13 0
      src/main/java/com/zhongzheng/service/ISysRoleMenuService.java
  82. 29 0
      src/main/java/com/zhongzheng/service/ISysRoleService.java
  83. 13 0
      src/main/java/com/zhongzheng/service/ISysUserRoleService.java
  84. 38 0
      src/main/java/com/zhongzheng/service/ISysUserService.java
  85. 12 0
      src/main/java/com/zhongzheng/service/OssService.java
  86. 75 0
      src/main/java/com/zhongzheng/service/impl/OfficialActivityServiceImpl.java
  87. 265 0
      src/main/java/com/zhongzheng/service/impl/OfficialApiServiceImpl.java
  88. 96 0
      src/main/java/com/zhongzheng/service/impl/OfficialArticleServiceImpl.java
  89. 63 0
      src/main/java/com/zhongzheng/service/impl/OfficialLinkServiceImpl.java
  90. 119 0
      src/main/java/com/zhongzheng/service/impl/OfficialMenuServiceImpl.java
  91. 63 0
      src/main/java/com/zhongzheng/service/impl/OfficialProblemServiceImpl.java
  92. 60 0
      src/main/java/com/zhongzheng/service/impl/OfficialSuggestServiceImpl.java
  93. 105 0
      src/main/java/com/zhongzheng/service/impl/OssServiceImpl.java
  94. 71 0
      src/main/java/com/zhongzheng/service/impl/SysLoginService.java
  95. 90 0
      src/main/java/com/zhongzheng/service/impl/SysMenuServiceImpl.java
  96. 18 0
      src/main/java/com/zhongzheng/service/impl/SysRoleMenuServiceImpl.java
  97. 113 0
      src/main/java/com/zhongzheng/service/impl/SysRoleServiceImpl.java
  98. 18 0
      src/main/java/com/zhongzheng/service/impl/SysUserRoleServiceImpl.java
  99. 277 0
      src/main/java/com/zhongzheng/service/impl/SysUserServiceImpl.java
  100. 159 0
      src/main/java/com/zhongzheng/util/AES.java

+ 42 - 0
.drone.yml

@@ -0,0 +1,42 @@
+kind: pipeline # 定义对象类型,还有secret和signature两种类型
+type: docker # 定义流水线类型,还有kubernetes、exec、ssh等类型
+name: zz_backend # 定义流水线名称
+trigger:
+  branch:
+    - master
+
+steps: # 定义流水线执行步骤,这些步骤将顺序执行
+  - name: package # 流水线名称
+    image: maven:3-jdk-8 # 定义创建容器的Docker镜像
+    volumes: # 将容器内目录挂载到宿主机,仓库需要开启Trusted设置
+      - name: maven-cache
+        path: /root/.m2 # 将maven下载依赖的目录挂载出来,防止重复下载
+      - name: maven-build
+        path: /app/build # 将应用打包好的Jar和执行脚本挂载出来
+    commands: # 定义在Docker容器中执行的shell命令
+      - mvn clean package # 应用打包命令
+      - cp /drone/src/zhongzheng-official/target/zhongzheng-official.jar /app/build/zhongzheng-official.jar
+      - cp Dockerfile /app/build/Dockerfile
+      - cp run-prod.sh /app/build/run-prod.sh
+
+  - name: build-start
+    image: appleboy/drone-ssh:latest # SSH工具镜像
+    settings:
+      host: 120.79.166.78 # 远程连接地址
+      username: root # 远程连接账号
+      key:
+        from_secret: ssh_password
+      port: 22 # 远程连接端口
+      command_timeout: 5m # 远程执行命令超时时间
+      script:
+        - cd /mydata/maven/build # 进入宿主机构建目录
+        - chmod +x run-prod.sh # 更改为可执行脚本
+        - ./run-prod.sh # 运行脚本打包应用镜像并运行
+
+volumes: # 定义流水线挂载目录,用于共享数据
+  - name: maven-build
+    host:
+      path: /mydata/maven/build # 从宿主机中挂载的目录
+  - name: maven-cache
+    host:
+      path: /mydata/maven/cache

+ 44 - 0
.gitignore

@@ -0,0 +1,44 @@
+######################################################################
+# Build Tools
+
+.gradle
+/build/
+!gradle/wrapper/gradle-wrapper.jar
+
+target/
+!.mvn/wrapper/maven-wrapper.jar
+
+######################################################################
+# IDE
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+nbproject/private/
+build/*
+nbbuild/
+dist/
+nbdist/
+.nb-gradle/
+
+######################################################################
+# Others
+*.log
+*.xml.versionsBackup
+*.swp
+
+!*/build/*.java
+!*/build/*.html
+!*/build/*.xml

+ 12 - 0
Dockerfile

@@ -0,0 +1,12 @@
+# 该镜像需要依赖的基础镜像
+FROM openjdk:8
+# 将当前目录下的jar包复制到docker容器的/目录下
+ADD zhongzheng-official.jar /app.jar
+# 声明服务运行在8080端口
+EXPOSE 9090
+# 指定docker容器启动时运行jar包
+ENTRYPOINT ["java", "-jar","-Xms2048m", "-Xmx2048m","/app.jar"]
+# 指定维护者的名字
+MAINTAINER zhongZheng
+
+

+ 1 - 0
HELP.md

@@ -0,0 +1 @@
+## 中正官网

+ 276 - 0
pom.xml

@@ -0,0 +1,276 @@
+<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>zhongzheng-official</groupId>
+    <artifactId>zhongzheng_official</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+
+    <name>zhongzheng_official</name>
+    <description>中正官網</description>
+
+    <properties>
+        <java.version>1.8</java.version>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
+        <druid.version>1.2.4</druid.version>
+        <knife4j.version>2.0.8</knife4j.version>
+        <pagehelper.boot.version>1.3.0</pagehelper.boot.version>
+        <fastjson.version>1.2.75</fastjson.version>
+        <oshi.version>5.6.0</oshi.version>
+        <jna.version>5.7.0</jna.version>
+        <poi.version>4.1.2</poi.version>
+        <velocity.version>1.7</velocity.version>
+        <jwt.version>0.9.1</jwt.version>
+        <mybatis-plus.version>3.4.2</mybatis-plus.version>
+        <hutool.version>5.5.8</hutool.version>
+        <feign.version>2.2.6.RELEASE</feign.version>
+        <feign-okhttp.version>11.0</feign-okhttp.version>
+        <spring-boot-admin.version>2.3.1</spring-boot-admin.version>
+    </properties>
+
+    <dependencies>
+        <!-- SpringBoot Web容器 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+            <exclusions>
+                <exclusion>
+                    <artifactId>spring-boot-starter-tomcat</artifactId>
+                    <groupId>org.springframework.boot</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <!-- web 容器使用 undertow 性能更强 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-undertow</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-freemarker</artifactId>
+        </dependency>
+
+
+        <!-- spring security 安全认证 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-security</artifactId>
+        </dependency>
+
+        <!--阿里数据库连接池 -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid-spring-boot-starter</artifactId>
+            <version>${druid.version}</version>
+        </dependency>
+
+        <!-- OSS SDK 相关依赖 -->
+        <dependency>
+            <groupId>com.aliyun.oss</groupId>
+            <artifactId>aliyun-sdk-oss</artifactId>
+            <version>3.15.2</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.aliyun</groupId>
+            <artifactId>dysmsapi20170525</artifactId>
+            <version>2.0.7</version>
+        </dependency>
+
+        <!-- SpringBoot Websocket -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-websocket</artifactId>
+        </dependency>
+
+        <!-- 阿里JSON解析器 -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>${fastjson.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>cn.afterturn</groupId>
+            <artifactId>easypoi-spring-boot-starter</artifactId>
+            <version>4.1.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-ooxml-schemas</artifactId>
+            <version>4.1.0</version>
+        </dependency>
+
+        <!--Token生成与解析-->
+        <dependency>
+            <groupId>io.jsonwebtoken</groupId>
+            <artifactId>jjwt</artifactId>
+            <version>${jwt.version}</version>
+        </dependency>
+
+        <!-- redis 缓存操作 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+
+        <!-- pool 对象池 -->
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-pool2</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+            <version>${mybatis-plus.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-extension</artifactId>
+            <version>${mybatis-plus.version}</version>
+        </dependency>
+        <!-- Mysql驱动包 -->
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+
+
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>${hutool.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.github.xiaoymin</groupId>
+            <artifactId>knife4j-spring-boot-starter</artifactId>
+            <version>2.0.9</version>
+        </dependency>
+
+        <!--常用工具类 -->
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bcprov-jdk18on</artifactId>
+            <version>1.77</version> <!-- 请检查最新版本 -->
+        </dependency>
+
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+            <version>1.16.1</version> <!-- 检查最新版本 -->
+        </dependency>
+
+        <!-- SpringBoot 拦截器 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-aop</artifactId>
+        </dependency>
+
+    </dependencies>
+
+    <dependencyManagement>
+        <dependencies>
+        <!-- SpringBoot的依赖配置-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-dependencies</artifactId>
+            <version>2.2.13.RELEASE</version>
+            <type>pom</type>
+            <scope>import</scope>
+        </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.1</version>
+                <configuration>
+                    <source>${java.version}</source>
+                    <target>${java.version}</target>
+                    <encoding>${project.build.sourceEncoding}</encoding>
+                </configuration>
+            </plugin>
+        </plugins>
+        <resources>
+            <resource>
+                <!--打包该目录下的 application.yml -->
+                <directory>src/main/resources</directory>
+                <!-- 启用过滤 即该资源中的变量将会被过滤器中的值替换 -->
+                <filtering>true</filtering>
+            </resource>
+        </resources>
+    </build>
+
+    <repositories>
+        <repository>
+            <id>public</id>
+            <name>aliyun nexus</name>
+            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
+            <releases>
+                <enabled>true</enabled>
+            </releases>
+        </repository>
+        <repository>
+            <id>com.e-iceblue</id>
+            <url>http://repo.e-iceblue.cn/repository/maven-public/</url>
+        </repository>
+    </repositories>
+
+    <pluginRepositories>
+        <pluginRepository>
+            <id>public</id>
+            <name>aliyun nexus</name>
+            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
+            <releases>
+                <enabled>true</enabled>
+            </releases>
+            <snapshots>
+                <enabled>false</enabled>
+            </snapshots>
+        </pluginRepository>
+    </pluginRepositories>
+
+    <profiles>
+        <profile>
+            <id>dev</id>
+            <properties>
+                <!-- 环境标识,需要与配置文件的名称相对应 -->
+                <profiles.active>dev</profiles.active>
+                <logging.level>debug</logging.level>
+            </properties>
+            <activation>
+                <!-- 默认环境 -->
+                <activeByDefault>true</activeByDefault>
+            </activation>
+        </profile>
+        <profile>
+            <id>prod</id>
+            <properties>
+                <profiles.active>prod</profiles.active>
+                <logging.level>warn</logging.level>
+            </properties>
+        </profile>
+    </profiles>
+
+</project>

+ 33 - 0
run-prod.sh

@@ -0,0 +1,33 @@
+#!/usr/bin/env bash
+# 定义应用组名
+group_name='zhongzheng'
+# 定义应用名称
+app_name='zhongzheng-official'
+# 定义应用版本
+app_version='1.0-SNAPSHOT'
+# 定义应用环境
+profile_active='prod'
+echo '----copy jar----'
+docker stop ${app_name}
+echo '----stop container----'
+docker rm ${app_name}
+echo '----rm container----'
+docker rmi ${group_name}/${app_name}:${app_version}
+echo '----rm image----'
+# 打包编译docker镜像
+docker build -f /mydata/maven/build/Dockerfile -t ${group_name}/${app_name}:${app_version} .
+echo '----build image----'
+docker run -p 9090:9090 --name ${app_name} \
+--restart=always \
+-e 'spring.profiles.active'=${profile_active} \
+-e TZ="Asia/Shanghai" \
+-m 10240m \
+--cpus=3 \
+--log-opt max-size=50m \
+--log-opt max-file=3 \
+-v /etc/localtime:/etc/localtime \
+-v /usr/share/fonts:/usr/share/fonts \
+-v /data/logs/prod_api:/logs \
+-v /mydata/app/${app_name}/logs:/var/logs \
+-d ${group_name}/${app_name}:${app_version}
+echo '----start container----'

+ 19 - 0
src/main/java/com/zhongzheng/ZhongZhengOfficialApplication.java

@@ -0,0 +1,19 @@
+package com.zhongzheng;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
+@EnableScheduling
+public class ZhongZhengOfficialApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(ZhongZhengOfficialApplication.class, args);
+        System.out.println("(♥◠‿◠)ノ゙  中正官网启动成功   ლ(´ڡ`ლ)゙");
+    }
+
+
+
+}

+ 18 - 0
src/main/java/com/zhongzheng/ZhongZhengServletInitializer.java

@@ -0,0 +1,18 @@
+package com.zhongzheng;
+
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+
+/**
+ * web容器中进行部署
+ * 
+ * @author zhongzheng
+ */
+public class ZhongZhengServletInitializer extends SpringBootServletInitializer
+{
+    @Override
+    protected SpringApplicationBuilder configure(SpringApplicationBuilder application)
+    {
+        return application.sources(ZhongZhengOfficialApplication.class);
+    }
+}

+ 131 - 0
src/main/java/com/zhongzheng/api/OfficialApiController.java

@@ -0,0 +1,131 @@
+package com.zhongzheng.api;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zhongzheng.bo.*;
+import com.zhongzheng.service.IOfficialApiService;
+import com.zhongzheng.util.AjaxResult;
+import com.zhongzheng.util.BaseController;
+import com.zhongzheng.util.TableDataInfo;
+import com.zhongzheng.vo.*;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 官网API接口
+ *
+ * @author zhongzheng
+ */
+@Api(value = "官网API接口", tags = {"官网API接口"})
+@RestController
+@RequestMapping("/api/official")
+public class OfficialApiController extends BaseController {
+
+    @Autowired
+    private IOfficialApiService officialApiService;
+
+
+    /**
+     * 官网菜单列表
+     */
+    @ApiOperation("官网菜单列表")
+    @GetMapping("/list")
+    public AjaxResult<List<OfficialMenuVo>> listMenu(OfficialMenuQuery query) {
+        List<OfficialMenuVo> list = officialApiService.listOfficialMenu(query);
+        return AjaxResult.success(list);
+    }
+
+    /**
+     * 官网菜单
+     */
+    @ApiOperation("官网菜单")
+    @GetMapping("/menu/{menuId}")
+    public AjaxResult<OfficialMenuVo> detailMenu(@PathVariable("menuId") Long menuId) {
+        OfficialMenuVo vo = officialApiService.detailMenu(menuId);
+        return AjaxResult.success(vo);
+    }
+
+    /**
+     * 获取文章
+     */
+    @ApiOperation("获取文章")
+    @GetMapping("/article/list")
+    public TableDataInfo<OfficialArticleVo> listArticle(OfficialArticleQuery query) {
+        Page<OfficialArticleVo> list = officialApiService.listArticle(query);
+        return getDataTable(list);
+    }
+
+    /**
+     * 获取文章详情
+     */
+    @ApiOperation("获取文章详情")
+    @GetMapping("/article/{articleId}")
+    public AjaxResult<OfficialArticleVo> detailArticle(@PathVariable("articleId") Long articleId) {
+        OfficialArticleVo vo = officialApiService.detailArticle(articleId);
+        return AjaxResult.success(vo);
+    }
+
+    /**
+     * 获取广告图
+     */
+    @ApiOperation("获取广告图")
+    @GetMapping("/activity/list")
+    public AjaxResult<List<OfficialActivityVo>> listActivity(OfficialActivityQuery query) {
+        List<OfficialActivityVo> list = officialApiService.listActivity(query);
+        return AjaxResult.success(list);
+    }
+
+    /**
+     * 获取友情连接
+     */
+    @ApiOperation("获取友情连接")
+    @GetMapping("/link/list")
+    public AjaxResult<List<OfficialLinkVo>> listLink(OfficialLinkQuery query) {
+        List<OfficialLinkVo> list = officialApiService.listLink(query);
+        return AjaxResult.success(list);
+    }
+
+
+    /**
+     * 获取常见问题
+     */
+    @ApiOperation("获取常见问题")
+    @GetMapping("/problem/list")
+    public AjaxResult<List<OfficialProblemVo>> listProblem(OfficialProblemQuery query) {
+        List<OfficialProblemVo> list = officialApiService.listProblem(query);
+        return AjaxResult.success(list);
+    }
+
+    /**
+     * 新增留言
+     */
+    @ApiOperation("新增留言")
+    @PostMapping("/suggest")
+    public AjaxResult saveSuggest(OfficialSuggestBo bo) {
+        return toAjax(officialApiService.saveSuggest(bo) ? 1 : 0);
+    }
+
+    /**
+     * 云学堂教育类型
+     */
+    @ApiOperation("云学堂教育类型")
+    @GetMapping("/edu/list")
+    public AjaxResult<List<EducationVo>> getEduList(OfficialOpenBo bo) {
+        List<EducationVo> list = officialApiService.getEduList(bo);
+        return AjaxResult.success(list);
+    }
+
+    /**
+     * 云学堂商品列表
+     */
+    @ApiOperation("云学堂商品列表")
+    @GetMapping("/edu/goods/list")
+    public AjaxResult<List<OfficialRecommendVo>> getEduGoodsList(OfficialOpenBo bo) {
+        List<OfficialRecommendVo> list = officialApiService.getEduGoodsList(bo);
+        return AjaxResult.success(list);
+    }
+
+}

+ 12 - 0
src/main/java/com/zhongzheng/bo/BatchDelBo.java

@@ -0,0 +1,12 @@
+package com.zhongzheng.bo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class BatchDelBo implements Serializable {
+
+    private List<Long> ids;
+}

+ 28 - 0
src/main/java/com/zhongzheng/bo/CommonOfficialBo.java

@@ -0,0 +1,28 @@
+package com.zhongzheng.bo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import java.io.Serializable;
+
+/**
+ * @author yangdamao
+ * @date 2024年06月06日 15:23
+ */
+@Data
+public class CommonOfficialBo implements Serializable {
+
+    @ApiModelProperty("当前时间戳")
+    private Long stamp;
+
+    @ApiModelProperty("签名")
+    private String sign;
+
+    @ApiModelProperty("来源")
+    private Integer platform;
+
+    @ApiModelProperty("状态")
+    private Integer status;
+
+}

+ 43 - 0
src/main/java/com/zhongzheng/bo/LoginBody.java

@@ -0,0 +1,43 @@
+package com.zhongzheng.bo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+/**
+ * 用户登录对象
+ *
+ * @author zhongzheng
+ */
+@ApiModel( "登录用户")
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+public class LoginBody
+{
+    /**
+     * 用户名
+     */
+    @ApiModelProperty( "用户名")
+    private String account;
+
+    /**
+     * 用户密码
+     */
+    @ApiModelProperty( "用户密码")
+    private String password;
+
+    /**
+     * 验证码
+     */
+    @ApiModelProperty( "验证码")
+    private String code;
+
+    /**
+     * 唯一标识
+     */
+    @ApiModelProperty( "验证码uuid")
+    private String uuid = "";
+}

+ 42 - 0
src/main/java/com/zhongzheng/bo/OfficialActivityBo.java

@@ -0,0 +1,42 @@
+package com.zhongzheng.bo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class OfficialActivityBo implements Serializable {
+
+    @ApiModelProperty( "广告ID")
+    private Long activityId;
+
+    @ApiModelProperty( "标题")
+    private String title;
+
+    @ApiModelProperty( "图片地址")
+    private String imageUrl;
+
+    @ApiModelProperty( "类型:1 轮播图 2 底部")
+    private Integer type;
+
+    @ApiModelProperty( "跳转地址")
+    private String jumpUrl;
+
+    @ApiModelProperty( "备注")
+    private String remark;
+
+    @ApiModelProperty( "排序字段")
+    private Integer sort;
+
+    @ApiModelProperty( "状态:1可用 0停用")
+    private Integer status;
+
+    @ApiModelProperty( "创建时间")
+    private Long createTime;
+
+    @ApiModelProperty( "更新时间")
+    private Long updateTime;
+
+}
+

+ 13 - 0
src/main/java/com/zhongzheng/bo/OfficialActivityQuery.java

@@ -0,0 +1,13 @@
+package com.zhongzheng.bo;
+
+import com.zhongzheng.util.BaseQuery;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+public class OfficialActivityQuery extends BaseQuery {
+
+    @ApiModelProperty("类型:1 轮播图 2 底部")
+    private Integer type;
+}
+

+ 36 - 0
src/main/java/com/zhongzheng/bo/OfficialArticleBo.java

@@ -0,0 +1,36 @@
+package com.zhongzheng.bo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class OfficialArticleBo implements Serializable {
+
+    @ApiModelProperty( "文章ID")
+    private Long articleId;
+
+    @ApiModelProperty( "关联官网菜单ID")
+    private Long menuId;
+
+    @ApiModelProperty( "标题")
+    private String title;
+
+    @ApiModelProperty( "是否置顶:1是 0否 ")
+    private Integer topStatus;
+
+    @ApiModelProperty( "内容(富文本框)")
+    private String content;
+
+    @ApiModelProperty( "状态:1可用 0停用")
+    private Integer status;
+
+    @ApiModelProperty( "创建时间")
+    private Long createTime;
+
+    @ApiModelProperty( "更新时间")
+    private Long updateTime;
+
+}
+

+ 29 - 0
src/main/java/com/zhongzheng/bo/OfficialArticleQuery.java

@@ -0,0 +1,29 @@
+package com.zhongzheng.bo;
+
+import com.zhongzheng.util.BaseQuery;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+public class OfficialArticleQuery extends BaseQuery {
+
+    @ApiModelProperty("关联官网菜单ID")
+    private Long menuId;
+
+    @ApiModelProperty("关联官网菜单父ID")
+    private Long parentId;
+
+    @ApiModelProperty("文章ID")
+    private Long articleId;
+
+    @ApiModelProperty("是否置顶:1是 0否")
+    private Integer topStatus;
+
+    @ApiModelProperty( "状态:1可用 0停用")
+    private Integer status;
+
+    @ApiModelProperty( "标题")
+    private String title;
+
+}
+

+ 30 - 0
src/main/java/com/zhongzheng/bo/OfficialLinkBo.java

@@ -0,0 +1,30 @@
+package com.zhongzheng.bo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class OfficialLinkBo implements Serializable {
+
+    @ApiModelProperty( "ID")
+    private Long linkId;
+
+    @ApiModelProperty( "標題")
+    private String title;
+
+    @ApiModelProperty( "鏈接")
+    private String url;
+
+    @ApiModelProperty( "状态:1可用 0停用")
+    private Integer status;
+
+    @ApiModelProperty( "创建时间")
+    private Long createTime;
+
+    @ApiModelProperty( "更新时间")
+    private Long updateTime;
+
+}
+

+ 13 - 0
src/main/java/com/zhongzheng/bo/OfficialLinkQuery.java

@@ -0,0 +1,13 @@
+package com.zhongzheng.bo;
+
+import com.zhongzheng.util.BaseQuery;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+public class OfficialLinkQuery extends BaseQuery {
+
+    @ApiModelProperty( "關鍵字")
+    private String keyword;
+}
+

+ 48 - 0
src/main/java/com/zhongzheng/bo/OfficialMenuBo.java

@@ -0,0 +1,48 @@
+package com.zhongzheng.bo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class OfficialMenuBo implements Serializable {
+
+    @ApiModelProperty( "菜单ID")
+    private Long menuId;
+
+    @ApiModelProperty( "父级ID(为0时是一级)")
+    private Long parentId;
+
+    @ApiModelProperty( "菜单名称")
+    private String name;
+
+    @ApiModelProperty( "类型:1属于新闻大分类,可用后台吴加分类,2小类,首面不分类为0,配置不维护 ")
+    private Integer type;
+
+    @ApiModelProperty( "用途 1文章 2列表")
+    private Integer showType;
+
+    @ApiModelProperty( "标识: 1有 0没有")
+    private Integer sign;
+
+    @ApiModelProperty( "外链跳转地址")
+    private String webUrl;
+
+    @ApiModelProperty( "菜单选中值")
+    private String curValue;
+
+    @ApiModelProperty( "排序字段")
+    private Integer sortNumber;
+
+    @ApiModelProperty( "状态:1可用 0停用")
+    private Integer status;
+
+    @ApiModelProperty( "创建时间")
+    private Long createTime;
+
+    @ApiModelProperty( "更新时间")
+    private Long updateTime;
+
+}
+

+ 16 - 0
src/main/java/com/zhongzheng/bo/OfficialMenuQuery.java

@@ -0,0 +1,16 @@
+package com.zhongzheng.bo;
+
+import com.zhongzheng.util.BaseQuery;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+public class OfficialMenuQuery extends BaseQuery {
+
+    @ApiModelProperty("父Id")
+    private Long parentId;
+
+    @ApiModelProperty( "标识: 1有 0没有")
+    private Integer sign;
+}
+

+ 13 - 0
src/main/java/com/zhongzheng/bo/OfficialOpenBo.java

@@ -0,0 +1,13 @@
+package com.zhongzheng.bo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class OfficialOpenBo implements Serializable {
+
+    @ApiModelProperty("机构ID")
+    private String tenantId;
+}

+ 30 - 0
src/main/java/com/zhongzheng/bo/OfficialProblemBo.java

@@ -0,0 +1,30 @@
+package com.zhongzheng.bo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class OfficialProblemBo implements Serializable {
+
+    @ApiModelProperty( "ID")
+    private Long problemId;
+
+    @ApiModelProperty( "問題")
+    private String title;
+
+    @ApiModelProperty( "答案")
+    private String answer;
+
+    @ApiModelProperty( "状态:1可用 0停用")
+    private Integer status;
+
+    @ApiModelProperty( "创建时间")
+    private Long createTime;
+
+    @ApiModelProperty( "更新时间")
+    private Long updateTime;
+
+}
+

+ 13 - 0
src/main/java/com/zhongzheng/bo/OfficialProblemQuery.java

@@ -0,0 +1,13 @@
+package com.zhongzheng.bo;
+
+import com.zhongzheng.util.BaseQuery;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+public class OfficialProblemQuery extends BaseQuery {
+
+    @ApiModelProperty( "關鍵字")
+    private String keyword;
+}
+

+ 30 - 0
src/main/java/com/zhongzheng/bo/OfficialSuggestBo.java

@@ -0,0 +1,30 @@
+package com.zhongzheng.bo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class OfficialSuggestBo implements Serializable {
+
+    @ApiModelProperty( "建议ID")
+    private Long suggestId;
+
+    @ApiModelProperty( "手机号码")
+    private String phone;
+
+    @ApiModelProperty( "内容")
+    private String content;
+
+    @ApiModelProperty( "状态:1可用 0停用")
+    private Integer status;
+
+    @ApiModelProperty( "创建时间")
+    private Long createTime;
+
+    @ApiModelProperty( "更新时间")
+    private Long updateTime;
+
+}
+

+ 13 - 0
src/main/java/com/zhongzheng/bo/OfficialSuggestQuery.java

@@ -0,0 +1,13 @@
+package com.zhongzheng.bo;
+
+import com.zhongzheng.util.BaseQuery;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+public class OfficialSuggestQuery extends BaseQuery {
+
+    @ApiModelProperty( "關鍵字")
+    private String keyword;
+}
+

+ 29 - 0
src/main/java/com/zhongzheng/bo/OssRequest.java

@@ -0,0 +1,29 @@
+package com.zhongzheng.bo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * @author change
+ * @date 2021年06月10日 9:07
+ */
+@Data
+@ApiModel("传图片标识")
+public class OssRequest {
+
+    /** 上传图片标识 */
+    @ApiModelProperty(value = "上传图片标识 4广告图片 ")
+    @NotNull(message = "上传图片标识不能为空")
+    private Integer ImageStatus;
+
+    /** 上传图片 */
+    @ApiModelProperty("MultipartFile上传文件")
+    private MultipartFile file;
+
+    @ApiModelProperty("图片路径")
+    private String path;
+}

+ 45 - 0
src/main/java/com/zhongzheng/bo/SysMenuBo.java

@@ -0,0 +1,45 @@
+package com.zhongzheng.bo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class SysMenuBo implements Serializable {
+
+    @ApiModelProperty( "菜单ID")
+    private Long menuId;
+
+    @ApiModelProperty( "类型:1目录 2菜单 3按钮")
+    private Integer type;
+
+    @ApiModelProperty( "菜单图标")
+    private String icon;
+
+    @ApiModelProperty( "菜单名称")
+    private String name;
+
+    @ApiModelProperty( "路径")
+    private String path;
+
+    @ApiModelProperty( "组件路径")
+    private String component;
+
+    @ApiModelProperty( "权限标识")
+    private String perms;
+
+    @ApiModelProperty( "排序字段")
+    private Integer sort;
+
+    @ApiModelProperty( "状态:1可用 0停用")
+    private Integer status;
+
+    @ApiModelProperty( "菜单状态(1显示 0隐藏)")
+    private Integer visible;
+
+    @ApiModelProperty( "父级ID(为0时是一级)")
+    private Long parentId;
+
+}
+

+ 31 - 0
src/main/java/com/zhongzheng/bo/SysRoleBo.java

@@ -0,0 +1,31 @@
+package com.zhongzheng.bo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class SysRoleBo implements Serializable {
+
+    @ApiModelProperty( "用户ID")
+    private Long roleId;
+
+    @ApiModelProperty( "账号")
+    private String roleName;
+
+    @ApiModelProperty( "真实姓名")
+    private String roleCode;
+
+    @ApiModelProperty( "排序字段")
+    private Integer sort;
+
+    @ApiModelProperty( "状态:1可用 0停用")
+    private Integer status;
+
+    @ApiModelProperty( "菜单ID集合(只保存最底层菜单ID)")
+    private List<Long> menuIds;
+
+}
+

+ 34 - 0
src/main/java/com/zhongzheng/bo/SysUserBo.java

@@ -0,0 +1,34 @@
+package com.zhongzheng.bo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class SysUserBo implements Serializable {
+
+    @ApiModelProperty( "用户ID")
+    private Long userId;
+
+    @ApiModelProperty( "账号")
+    private String account;
+
+    @ApiModelProperty( "真实姓名")
+    private String userName;
+
+    @ApiModelProperty( "邮箱")
+    private String email;
+
+    @ApiModelProperty( "密码")
+    private String password;
+
+    @ApiModelProperty( "状态:1可用 0停用")
+    private Integer status;
+
+    @ApiModelProperty( "角色ID集合")
+    private List<Long> roleIds;
+
+}
+

+ 15 - 0
src/main/java/com/zhongzheng/bo/SysUserQuery.java

@@ -0,0 +1,15 @@
+package com.zhongzheng.bo;
+
+import com.zhongzheng.util.BaseQuery;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+public class SysUserQuery extends BaseQuery {
+
+    @ApiModelProperty(  "角色ID")
+    private Integer roleId;
+
+
+}
+

+ 19 - 0
src/main/java/com/zhongzheng/bo/UserPwdBo.java

@@ -0,0 +1,19 @@
+package com.zhongzheng.bo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class UserPwdBo implements Serializable {
+
+    @ApiModelProperty("原密碼")
+    private String oldPwd;
+
+    @ApiModelProperty("密碼")
+    private String newPwd;
+
+    @ApiModelProperty("確認密碼")
+    private String affirmPwd;
+}

+ 58 - 0
src/main/java/com/zhongzheng/config/CaptchaConfig.java

@@ -0,0 +1,58 @@
+package com.zhongzheng.config;
+
+import cn.hutool.captcha.CaptchaUtil;
+import cn.hutool.captcha.CircleCaptcha;
+import cn.hutool.captcha.LineCaptcha;
+import cn.hutool.captcha.ShearCaptcha;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.awt.*;
+
+/**
+ * 验证码配置
+ *
+ * @author Lion Li
+ */
+@Configuration
+public class CaptchaConfig {
+
+    private final int width = 160;
+    private final int height = 60;
+    private final Color background = Color.PINK;
+    private final Font font = new Font("Arial", Font.BOLD, 48);
+
+    /**
+     * 圆圈干扰验证码
+     */
+    @Bean(name = "CircleCaptcha")
+    public CircleCaptcha getCircleCaptcha() {
+        CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(width, height);
+        captcha.setBackground(background);
+        captcha.setFont(font);
+        return captcha;
+    }
+
+    /**
+     * 线段干扰的验证码
+     */
+    @Bean(name = "LineCaptcha")
+    public LineCaptcha getLineCaptcha() {
+        LineCaptcha captcha = CaptchaUtil.createLineCaptcha(width, height);
+        captcha.setBackground(background);
+        captcha.setFont(font);
+        return captcha;
+    }
+
+    /**
+     * 扭曲干扰验证码
+     */
+    @Bean(name = "ShearCaptcha")
+    public ShearCaptcha getShearCaptcha() {
+        ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(width, height);
+        captcha.setBackground(background);
+        captcha.setFont(font);
+        return captcha;
+    }
+
+}

+ 20 - 0
src/main/java/com/zhongzheng/config/OssConfig.java

@@ -0,0 +1,20 @@
+package com.zhongzheng.config;
+
+import com.aliyun.oss.OSSClient;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class OssConfig {
+    @Value("${aliyun.oss.endpoint}")
+    private String ALIYUN_OSS_ENDPOINT;
+    @Value("${aliyun.oss.accessKeyId}")
+    private String ALIYUN_OSS_ACCESSKEYID;
+    @Value("${aliyun.oss.accessKeySecret}")
+    private String ALIYUN_OSS_ACCESSKEYSECRET;
+    @Bean
+    public OSSClient ossClient(){
+        return new OSSClient(ALIYUN_OSS_ENDPOINT,ALIYUN_OSS_ACCESSKEYID,ALIYUN_OSS_ACCESSKEYSECRET);
+    }
+}

+ 68 - 0
src/main/java/com/zhongzheng/config/ResourcesConfig.java

@@ -0,0 +1,68 @@
+package com.zhongzheng.config;
+
+
+import com.zhongzheng.util.Constants;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+import org.springframework.web.filter.CorsFilter;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+
+/**
+ * 通用配置
+ *
+ * @author zhongzheng
+ */
+@Configuration
+public class ResourcesConfig implements WebMvcConfigurer
+{
+//    @Autowired
+//    private HandlerInterceptorAdapter repeatSubmitInterceptor;
+
+
+    @Override
+    public void addResourceHandlers(ResourceHandlerRegistry registry)
+    {
+        /** 本地文件上传路径 */
+        registry.addResourceHandler(Constants.RESOURCE_PREFIX + "/**").addResourceLocations("file:" + RuoYiConfig.getProfile() + "/");
+
+        /** swagger配置 */
+        registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
+        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
+    }
+
+    /**
+     * 自定义拦截规则
+     */
+    @Override
+    public void addInterceptors(InterceptorRegistry registry)
+    {
+//        registry.addInterceptor(repeatSubmitInterceptor).addPathPatterns("/**");
+    }
+
+    /**
+     * 跨域配置
+     */
+    @Bean
+    public CorsFilter corsFilter()
+    {
+        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+        CorsConfiguration config = new CorsConfiguration();
+        config.setAllowCredentials(true);
+        // 设置访问源地址
+        config.addAllowedOrigin("*");
+        // 设置访问源请求头
+        config.addAllowedHeader("*");
+        // 设置访问源请求方法
+        config.addAllowedMethod("*");
+        // 对接口配置跨域设置
+        source.registerCorsConfiguration("/**", config);
+        return new CorsFilter(source);
+    }
+}

+ 76 - 0
src/main/java/com/zhongzheng/config/RuoYiConfig.java

@@ -0,0 +1,76 @@
+package com.zhongzheng.config;
+
+import lombok.Data;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * 读取项目相关配置
+ * 
+ * @author zhongzheng
+ */
+
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+@Component
+@ConfigurationProperties(prefix = "zhongzheng")
+public class RuoYiConfig
+{
+    /** 项目名称 */
+    private String name;
+
+    /** 版本 */
+    private String version;
+
+    /** 版权年份 */
+    private String copyrightYear;
+
+    /** 实例演示开关 */
+    private boolean demoEnabled;
+
+    /** 上传路径 */
+    @Getter
+    private static String profile;
+
+    /** 获取地址开关 */
+    @Getter
+    private static boolean addressEnabled;
+
+    public void setProfile(String profile)
+    {
+        RuoYiConfig.profile = profile;
+    }
+
+    public void setAddressEnabled(boolean addressEnabled)
+    {
+        RuoYiConfig.addressEnabled = addressEnabled;
+    }
+
+    /**
+     * 获取头像上传路径
+     */
+    public static String getAvatarPath()
+    {
+        return getProfile() + "/avatar";
+    }
+
+    /**
+     * 获取下载路径
+     */
+    public static String getDownloadPath()
+    {
+        return getProfile() + "/download/";
+    }
+
+    /**
+     * 获取上传路径
+     */
+    public static String getUploadPath()
+    {
+        return getProfile() + "/upload";
+    }
+}

+ 163 - 0
src/main/java/com/zhongzheng/config/SecurityConfig.java

@@ -0,0 +1,163 @@
+package com.zhongzheng.config;
+
+import com.zhongzheng.util.AuthenticationEntryPointImpl;
+import com.zhongzheng.util.JwtAuthenticationTokenFilter;
+import com.zhongzheng.util.LogoutSuccessHandlerImpl;
+import com.zhongzheng.util.UserDetailsServiceImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.http.HttpMethod;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.CorsConfigurationSource;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+
+import java.util.Arrays;
+
+import static org.springframework.security.config.Customizer.withDefaults;
+
+/**
+ * spring security配置
+ *
+ * @author zhongzheng
+ */
+@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
+public class SecurityConfig extends WebSecurityConfigurerAdapter
+{
+    /**
+     * 自定义用户认证逻辑
+     */
+    @Autowired
+    private UserDetailsServiceImpl userDetailsService;
+
+    /**
+     * 认证失败处理类
+     */
+    @Autowired
+    private AuthenticationEntryPointImpl unauthorizedHandler;
+
+    /**
+     * 退出处理类
+     */
+    @Autowired
+    @Lazy
+    private LogoutSuccessHandlerImpl logoutSuccessHandler;
+
+    /**
+     * token认证过滤器
+     */
+    @Autowired
+    private JwtAuthenticationTokenFilter authenticationTokenFilter;
+
+
+    /**
+     * 解决 无法直接注入 AuthenticationManager
+     *
+     * @return
+     * @throws Exception
+     */
+    @Bean
+    @Override
+    public AuthenticationManager authenticationManagerBean() throws Exception
+    {
+        return super.authenticationManagerBean();
+    }
+
+    /**
+     * anyRequest          |   匹配所有请求路径
+     * access              |   SpringEl表达式结果为true时可以访问
+     * anonymous           |   匿名可以访问
+     * denyAll             |   用户不能访问
+     * fullyAuthenticated  |   用户完全认证可以访问(非remember-me下自动登录)
+     * hasAnyAuthority     |   如果有参数,参数表示权限,则其中任何一个权限可以访问
+     * hasAnyRole          |   如果有参数,参数表示角色,则其中任何一个角色可以访问
+     * hasAuthority        |   如果有参数,参数表示权限,则其权限可以访问
+     * hasIpAddress        |   如果有参数,参数表示IP地址,如果用户IP和参数匹配,则可以访问
+     * hasRole             |   如果有参数,参数表示角色,则其角色可以访问
+     * permitAll           |   用户可以任意访问
+     * rememberMe          |   允许通过remember-me登录的用户访问
+     * authenticated       |   用户登录后可访问
+     */
+    @Override
+    protected void configure(HttpSecurity httpSecurity) throws Exception
+    {
+        httpSecurity
+                // CSRF禁用,因为不使用session
+                .csrf().disable()
+                .cors(withDefaults()) // 启用默认CORS配置
+                // 认证失败处理类
+                .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
+                // 基于token,所以不需要session
+                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
+                // 过滤请求
+                .authorizeRequests()
+                // 对于登录login 验证码captchaImage 允许匿名访问
+                .antMatchers("/login", "/captchaImage").anonymous()
+                .antMatchers("/admin").anonymous()
+                .antMatchers("/api/official/**").anonymous()
+                .antMatchers(
+                        HttpMethod.GET,
+                        "/*.html",
+                        "/**/*.html",
+                        "/**/*.css",
+                        "/**/*.js"
+                ).permitAll()
+                // 放行Swagger和OpenAPI的静态资源路径
+                .antMatchers(
+                        "/swagger-ui.html",
+                        "/swagger-resources/**",
+                        "/v2/api-docs",
+                        "/webjars/**"
+                ).permitAll()
+//                .antMatchers("/swagger-ui.html").anonymous()
+//                .antMatchers("/swagger-resources/**").anonymous()
+                // 除上面外的所有请求全部需要鉴权认证
+                .anyRequest().authenticated()
+                .and()
+                .headers().frameOptions().disable();
+        httpSecurity.logout().logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler);
+
+        // 添加JWT filter
+        httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
+        // 添加CORS filter
+//        httpSecurity.addFilterBefore(corsFilter, JwtAuthenticationTokenFilter.class);
+//        httpSecurity.addFilterBefore(corsFilter, LogoutFilter.class);
+    }
+
+    @Bean
+    CorsConfigurationSource corsConfigurationSource() {
+        CorsConfiguration configuration = new CorsConfiguration();
+        configuration.setAllowedOrigins(Arrays.asList("*"));
+        configuration.setAllowedMethods(Arrays.asList("GET","POST", "OPTIONS"));
+        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+        source.registerCorsConfiguration("/**", configuration);
+        return source;
+    }
+
+
+    /**
+     * 强散列哈希加密实现
+     */
+    @Bean
+    public BCryptPasswordEncoder bCryptPasswordEncoder()
+    {
+        return new BCryptPasswordEncoder();
+    }
+
+    /**
+     * 身份认证接口
+     */
+    @Override
+    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+
+        auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
+    }
+}

+ 147 - 0
src/main/java/com/zhongzheng/config/SwaggerConfig.java

@@ -0,0 +1,147 @@
+package com.zhongzheng.config;
+
+import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
+import com.github.xiaoymin.knife4j.spring.extension.OpenApiExtensionResolver;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.ParameterBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.schema.ModelRef;
+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.swagger2.annotations.EnableSwagger2WebMvc;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Swagger2的接口配置
+ *
+ * @author zhongzheng
+ */
+@Configuration
+@EnableSwagger2WebMvc
+@EnableKnife4j
+public class SwaggerConfig
+{
+
+    /** 系统基础配置 */
+    @Autowired
+    private RuoYiConfig ruoyiConfig;
+
+    /** 是否开启swagger */
+    @Value("${swagger.enabled}")
+    private boolean enabled;
+
+    /** 设置请求的统一前缀 */
+    @Value("${swagger.pathMapping}")
+    private String pathMapping;
+
+    private final OpenApiExtensionResolver openApiExtensionResolver;
+
+    /**
+     * 创建API
+     */
+    @Bean
+    public Docket createRestApi()
+    {
+        return new Docket(DocumentationType.SWAGGER_2)
+                // 是否启用Swagger
+                .enable(enabled)
+                // 用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息)
+                .apiInfo(apiInfo())
+                // 设置哪些接口暴露给Swagger展示
+                .select()
+                // 扫描所有有注解的api,用这种方式更灵活
+                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
+                // 扫描指定包中的swagger注解
+                // .apis(RequestHandlerSelectors.basePackage("com.zhongzheng.project.tool.swagger"))
+                // 扫描所有 .apis(RequestHandlerSelectors.any())
+                .paths(PathSelectors.any())
+                .build()
+                /* 设置安全模式,swagger可以设置访问token */
+           //     .securitySchemes(securitySchemes())
+                .securityContexts(securityContexts())
+                .pathMapping(pathMapping)
+                .globalOperationParameters(getGlobalOperationParameters())
+                .extensions(openApiExtensionResolver.buildSettingExtensions());
+    }
+
+    @Autowired
+    public SwaggerConfig(OpenApiExtensionResolver openApiExtensionResolver) {
+        this.openApiExtensionResolver = openApiExtensionResolver;
+    }
+
+    /**
+     * 安全模式,这里指定token通过AuthorizationToken头请求头传递
+     */
+    private List<ApiKey> securitySchemes()
+    {
+        List<ApiKey> apiKeyList = new ArrayList<ApiKey>();
+    //    apiKeyList.add(new ApiKey("AuthorizationToken", "AuthorizationToken", "header"));//强制全局参数
+        return apiKeyList;
+    }
+
+    /**
+     * 安全上下文
+     */
+    private List<SecurityContext> securityContexts()
+    {
+        List<SecurityContext> securityContexts = new ArrayList<>();
+        securityContexts.add(
+                SecurityContext.builder()
+                        .securityReferences(defaultAuth())
+                        .forPaths(PathSelectors.regex("^(?!auth).*$"))
+                        .build());
+        return securityContexts;
+    }
+
+    /**
+     * 默认的安全上引用
+     */
+    private List<SecurityReference> defaultAuth()
+    {
+        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
+        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
+        authorizationScopes[0] = authorizationScope;
+        List<SecurityReference> securityReferences = new ArrayList<>();
+        securityReferences.add(new SecurityReference("AuthorizationToken", authorizationScopes));
+        return securityReferences;
+    }
+
+    /**
+     * 添加摘要信息
+     */
+    private ApiInfo apiInfo()
+    {
+        // 用ApiInfoBuilder进行定制
+        return new ApiInfoBuilder()
+                // 设置标题
+                .title("标题:中正官网管理系统_接口文档")
+                // 描述
+                .description("描述:用于中正官网系统_接口文档")
+                // 作者信息
+                .contact(new Contact(ruoyiConfig.getName(), null, null))
+                // 版本
+                .version("版本号:0.0.1")
+
+                .build();
+    }
+
+    private List<Parameter> getGlobalOperationParameters() {
+        List<Parameter> pars = new ArrayList<>();
+        ParameterBuilder parameterBuilder = new ParameterBuilder();
+        // header query cookie
+        parameterBuilder.name("X-Auth-Token").description("token").modelRef(new ModelRef("string")).parameterType("header").defaultValue("test").required(false);
+        pars.add(parameterBuilder.build());
+        return pars;
+    }
+
+}

+ 137 - 0
src/main/java/com/zhongzheng/controller/CaptchaController.java

@@ -0,0 +1,137 @@
+package com.zhongzheng.controller;
+
+import cn.hutool.captcha.AbstractCaptcha;
+import cn.hutool.captcha.CircleCaptcha;
+import cn.hutool.captcha.LineCaptcha;
+import cn.hutool.captcha.ShearCaptcha;
+import cn.hutool.captcha.generator.CodeGenerator;
+import cn.hutool.captcha.generator.MathGenerator;
+import cn.hutool.captcha.generator.RandomGenerator;
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.core.util.StrUtil;
+import com.github.xiaoymin.knife4j.annotations.ApiSupport;
+import com.github.xiaoymin.knife4j.annotations.DynamicParameter;
+import com.github.xiaoymin.knife4j.annotations.DynamicResponseParameters;
+import com.zhongzheng.util.AjaxResult;
+import com.zhongzheng.util.Constants;
+import com.zhongzheng.util.RedisCache;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 验证码操作处理
+ *
+ * @author hjl
+ */
+@Api(tags ="系统操作管理")
+@ApiSupport(order = 1)
+@RestController
+public class CaptchaController {
+
+	// 圆圈干扰验证码
+	@Resource(name = "CircleCaptcha")
+	private CircleCaptcha circleCaptcha;
+	// 线段干扰的验证码
+	@Resource(name = "LineCaptcha")
+	private LineCaptcha lineCaptcha;
+	// 扭曲干扰验证码
+	@Resource(name = "ShearCaptcha")
+	private ShearCaptcha shearCaptcha;
+
+	@Autowired
+	private RedisCache redisCache;
+
+	// 验证码类型
+	@Value("${captcha.captchaType}")
+	private String captchaType;
+	// 验证码类别
+	@Value("${captcha.captchaCategory}")
+	private String captchaCategory;
+	// 数字验证码位数
+	@Value("${captcha.captchaNumberLength}")
+	private int numberLength;
+	// 字符验证码长度
+	@Value("${captcha.captchaCharLength}")
+	private int charLength;
+
+	/**
+	 * 生成验证码
+	 */
+	@ApiOperation("")
+	@DynamicResponseParameters(name = "CodeMapModel",properties = {
+			@DynamicParameter(name = "uuid",value = "验证码uuid"),
+			@DynamicParameter(name = "img",value = "验证码图片base64"),
+	})
+	@GetMapping("/captchaImage")
+	public AjaxResult getCode() {
+		// 保存验证码信息
+		String uuid = IdUtil.simpleUUID();
+		String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
+		String code = null;
+		// 生成验证码
+		CodeGenerator codeGenerator;
+		AbstractCaptcha captcha;
+		switch (captchaType) {
+			case "math":
+				codeGenerator = new MathGenerator(numberLength);
+				break;
+			case "char":
+				codeGenerator = new RandomGenerator(charLength);
+				break;
+			default:
+				throw new IllegalArgumentException("验证码类型异常");
+		}
+		switch (captchaCategory) {
+			case "line":
+				captcha = lineCaptcha;
+				break;
+			case "circle":
+				captcha = circleCaptcha;
+				break;
+			case "shear":
+				captcha = shearCaptcha;
+				break;
+			default:
+				throw new IllegalArgumentException("验证码类别异常");
+		}
+		captcha.setGenerator(codeGenerator);
+		captcha.createCode();
+		if ("math".equals(captchaType)) {
+			code = getCodeResult(captcha.getCode());
+		} else if ("char".equals(captchaType)) {
+			code = captcha.getCode();
+		}
+		redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
+		Map<String,Object> map = new HashMap();
+		map.put("uuid", uuid);
+		map.put("img", "data:image/jpg;base64,"+captcha.getImageBase64());
+		return AjaxResult.success(map);
+	}
+
+	private String getCodeResult(String capStr) {
+		int a = Convert.toInt(StrUtil.sub(capStr, 0, numberLength).trim());
+		char operator = capStr.charAt(numberLength);
+		int b = Convert.toInt(StrUtil.sub(capStr, numberLength + 1, numberLength + 1 + numberLength).trim());
+		switch (operator) {
+			case '*':
+				return a * b + "";
+			case '+':
+				return a + b + "";
+			case '-':
+				return a - b + "";
+			default:
+				return "";
+		}
+	}
+
+}

+ 83 - 0
src/main/java/com/zhongzheng/controller/OfficialActivityController.java

@@ -0,0 +1,83 @@
+package com.zhongzheng.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zhongzheng.bo.BatchDelBo;
+import com.zhongzheng.bo.OfficialActivityBo;
+import com.zhongzheng.bo.OfficialArticleBo;
+import com.zhongzheng.bo.OfficialArticleQuery;
+import com.zhongzheng.service.IOfficialActivityService;
+import com.zhongzheng.service.IOfficialArticleService;
+import com.zhongzheng.util.AjaxResult;
+import com.zhongzheng.util.BaseController;
+import com.zhongzheng.util.TableDataInfo;
+import com.zhongzheng.vo.OfficialActivityVo;
+import com.zhongzheng.vo.OfficialArticleVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 广告管理
+ *
+ * @author zhongzheng
+ */
+@Api(value = "广告管理", tags = {"广告管理"})
+@RestController
+@RequestMapping("/official/activity")
+public class OfficialActivityController extends BaseController {
+
+    @Autowired
+    private IOfficialActivityService officialActivityService;
+
+
+    /**
+     * 新增广告
+     */
+    @ApiOperation("新增广告")
+    @PostMapping("/save")
+    public AjaxResult add(@RequestBody OfficialActivityBo bo) {
+        return toAjax(officialActivityService.addOfficialActivity(bo) ? 1 : 0);
+    }
+
+    /**
+     * 广告列表
+     */
+    @ApiOperation("广告列表")
+    @GetMapping("/list")
+    public TableDataInfo<OfficialActivityVo> listOfficialActivity(OfficialArticleQuery query) {
+        Page<OfficialActivityVo> list = officialActivityService.listOfficialActivity(query);
+        return getDataTable(list);
+    }
+
+    /**
+     * 修改官网广告
+     */
+    @ApiOperation("修改广告")
+    @PostMapping("/edit")
+    public AjaxResult edit(@RequestBody OfficialActivityBo bo) {
+        return toAjax(officialActivityService.editOfficialActivity(bo) ? 1 : 0);
+    }
+
+
+    /**
+     * 删除广告
+     */
+    @ApiOperation("删除广告")
+    @PostMapping("/del")
+    public AjaxResult delOfficialMenu(@RequestBody BatchDelBo bo) {
+        return toAjax(officialActivityService.delOfficialActivity(bo) ? 1 : 0);
+    }
+
+
+    /**
+     * 广告详情
+     */
+    @ApiOperation("广告详情")
+    @GetMapping("/detail/{activityId}")
+    public AjaxResult<OfficialActivityVo> detailById(@PathVariable("activityId") Long activityId) {
+        OfficialActivityVo vo = officialActivityService.detailById(activityId);
+        return AjaxResult.success(vo);
+    }
+
+}

+ 80 - 0
src/main/java/com/zhongzheng/controller/OfficialArticleController.java

@@ -0,0 +1,80 @@
+package com.zhongzheng.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zhongzheng.bo.BatchDelBo;
+import com.zhongzheng.bo.OfficialArticleBo;
+import com.zhongzheng.bo.OfficialArticleQuery;
+import com.zhongzheng.service.IOfficialArticleService;
+import com.zhongzheng.util.AjaxResult;
+import com.zhongzheng.util.BaseController;
+import com.zhongzheng.util.TableDataInfo;
+import com.zhongzheng.vo.OfficialArticleVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 文章管理
+ *
+ * @author zhongzheng
+ */
+@Api(value = "文章管理", tags = {"文章管理"})
+@RestController
+@RequestMapping("/official/article")
+public class OfficialArticleController extends BaseController {
+
+    @Autowired
+    private IOfficialArticleService officialArticleService;
+
+
+    /**
+     * 新增文章
+     */
+    @ApiOperation("新增文章")
+    @PostMapping("/save")
+    public AjaxResult add(@RequestBody OfficialArticleBo bo) {
+        return toAjax(officialArticleService.addOfficialArticle(bo) ? 1 : 0);
+    }
+
+    /**
+     * 文章列表
+     */
+    @ApiOperation("文章列表")
+    @GetMapping("/list")
+    public TableDataInfo<OfficialArticleVo> listMenu(OfficialArticleQuery query) {
+        Page<OfficialArticleVo> list = officialArticleService.listOfficialArticle(query);
+        return getDataTable(list);
+    }
+
+    /**
+     * 修改官网文章
+     */
+    @ApiOperation("修改文章")
+    @PostMapping("/edit")
+    public AjaxResult edit(@RequestBody OfficialArticleBo bo) {
+        return toAjax(officialArticleService.editOfficialArticle(bo) ? 1 : 0);
+    }
+
+
+    /**
+     * 删除文章
+     */
+    @ApiOperation("删除文章")
+    @GetMapping("/del")
+    public AjaxResult delOfficialMenu(@RequestBody BatchDelBo bo) {
+        return toAjax(officialArticleService.delOfficialArticle(bo) ? 1 : 0);
+    }
+
+
+    /**
+     * 文章详情
+     */
+    @ApiOperation("文章详情")
+    @GetMapping("/detail/{articleId}")
+    public AjaxResult<OfficialArticleVo> detailById(@PathVariable("articleId") Long articleId) {
+        OfficialArticleVo vo = officialArticleService.detailById(articleId);
+        return AjaxResult.success(vo);
+    }
+
+}

+ 59 - 0
src/main/java/com/zhongzheng/controller/OfficialLinkController.java

@@ -0,0 +1,59 @@
+package com.zhongzheng.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zhongzheng.bo.*;
+import com.zhongzheng.service.IOfficialLinkService;
+import com.zhongzheng.service.IOfficialSuggestService;
+import com.zhongzheng.util.AjaxResult;
+import com.zhongzheng.util.BaseController;
+import com.zhongzheng.util.TableDataInfo;
+import com.zhongzheng.vo.OfficialLinkVo;
+import com.zhongzheng.vo.OfficialSuggestVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 友情鏈接管理
+ *
+ * @author zhongzheng
+ */
+@Api(value = "友情鏈接管理", tags = {"友情鏈接管理"})
+@RestController
+@RequestMapping("/official/link")
+public class OfficialLinkController extends BaseController {
+
+    @Autowired
+    private IOfficialLinkService officialLinkService;
+
+
+    /**
+     * 新增友情鏈接
+     */
+    @ApiOperation("新增友情鏈接")
+    @PostMapping("/save")
+    public AjaxResult add(@RequestBody OfficialLinkBo bo) {
+        return toAjax(officialLinkService.addOfficialLink(bo) ? 1 : 0);
+    }
+
+    /**
+     * 友情鏈接列表
+     */
+    @ApiOperation("友情鏈接列表")
+    @GetMapping("/list")
+    public TableDataInfo<OfficialLinkVo> listOfficialLink(OfficialLinkQuery query) {
+        Page<OfficialLinkVo> list = officialLinkService.listOfficialLink(query);
+        return getDataTable(list);
+    }
+
+    /**
+     * 删除友情鏈接
+     */
+    @ApiOperation("删除友情鏈接")
+    @PostMapping("/del")
+    public AjaxResult delOfficialLink(@RequestBody BatchDelBo bo) {
+        return toAjax(officialLinkService.delOfficialLink(bo) ? 1 : 0);
+    }
+
+}

+ 80 - 0
src/main/java/com/zhongzheng/controller/OfficialMenuController.java

@@ -0,0 +1,80 @@
+package com.zhongzheng.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zhongzheng.bo.OfficialMenuBo;
+import com.zhongzheng.bo.OfficialMenuQuery;
+import com.zhongzheng.service.IOfficialMenuService;
+import com.zhongzheng.util.AjaxResult;
+import com.zhongzheng.util.BaseController;
+import com.zhongzheng.util.TableDataInfo;
+import com.zhongzheng.vo.OfficialMenuVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 后台官网菜单
+ *
+ * @author zhongzheng
+ */
+@Api(value = "后台官网菜单", tags = {"后台官网菜单"})
+@RestController
+@RequestMapping("/official/menu")
+public class OfficialMenuController extends BaseController {
+
+    @Autowired
+    private IOfficialMenuService officialMenuService;
+
+
+    /**
+     * 新增菜单
+     */
+    @ApiOperation("新增菜单")
+    @PostMapping("/save")
+    public AjaxResult add(@RequestBody OfficialMenuBo bo) {
+
+        return toAjax(officialMenuService.addOfficialMenu(bo) ? 1 : 0);
+    }
+
+    /**
+     * 菜单列表
+     */
+    @ApiOperation("菜单列表")
+    @GetMapping("/list")
+    public TableDataInfo<OfficialMenuVo> listMenu(OfficialMenuQuery query) {
+        Page<OfficialMenuVo> list = officialMenuService.listOfficialMenu(query);
+        return getDataTable(list);
+    }
+
+    /**
+     * 修改官网菜单
+     */
+    @ApiOperation("修改官网菜单")
+    @PostMapping("/edit")
+    public AjaxResult edit(@RequestBody OfficialMenuBo bo) {
+        return toAjax(officialMenuService.editMenu(bo) ? 1 : 0);
+    }
+
+
+    /**
+     * 删除菜单
+     */
+    @ApiOperation("删除菜单")
+    @GetMapping("/del/{menuId}")
+    public AjaxResult delOfficialMenu(@PathVariable("menuId") Long menuId) {
+        return toAjax(officialMenuService.delOfficialMenu(menuId) ? 1 : 0);
+    }
+
+
+    /**
+     * 菜单详情
+     */
+    @ApiOperation("菜单详情")
+    @GetMapping("/detail/{menuId}")
+    public AjaxResult<OfficialMenuVo> menuIdDetail(@PathVariable("menuId") Long menuId) {
+        OfficialMenuVo vo = officialMenuService.menuIdDetail(menuId);
+        return AjaxResult.success(vo);
+    }
+
+}

+ 59 - 0
src/main/java/com/zhongzheng/controller/OfficialProblemController.java

@@ -0,0 +1,59 @@
+package com.zhongzheng.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zhongzheng.bo.*;
+import com.zhongzheng.service.IOfficialLinkService;
+import com.zhongzheng.service.IOfficialProblemService;
+import com.zhongzheng.util.AjaxResult;
+import com.zhongzheng.util.BaseController;
+import com.zhongzheng.util.TableDataInfo;
+import com.zhongzheng.vo.OfficialLinkVo;
+import com.zhongzheng.vo.OfficialProblemVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 常見問題管理
+ *
+ * @author zhongzheng
+ */
+@Api(value = "常見問題管理", tags = {"常見問題管理"})
+@RestController
+@RequestMapping("/official/problem")
+public class OfficialProblemController extends BaseController {
+
+    @Autowired
+    private IOfficialProblemService officialProblemService;
+
+
+    /**
+     * 新增常見問題
+     */
+    @ApiOperation("新增常見問題")
+    @PostMapping("/save")
+    public AjaxResult add(@RequestBody OfficialProblemBo bo) {
+        return toAjax(officialProblemService.addOfficialProblem(bo) ? 1 : 0);
+    }
+
+    /**
+     * 常見問題列表
+     */
+    @ApiOperation("常見問題列表")
+    @GetMapping("/list")
+    public TableDataInfo<OfficialProblemVo> listOfficialProblem(OfficialProblemQuery query) {
+        Page<OfficialProblemVo> list = officialProblemService.listOfficialProblem(query);
+        return getDataTable(list);
+    }
+
+    /**
+     * 删除常見問題
+     */
+    @ApiOperation("删除常見問題")
+    @PostMapping("/del")
+    public AjaxResult delOfficialProblem(@RequestBody BatchDelBo bo) {
+        return toAjax(officialProblemService.delOfficialProblem(bo) ? 1 : 0);
+    }
+
+}

+ 59 - 0
src/main/java/com/zhongzheng/controller/OfficialSuggestController.java

@@ -0,0 +1,59 @@
+package com.zhongzheng.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zhongzheng.bo.*;
+import com.zhongzheng.service.IOfficialActivityService;
+import com.zhongzheng.service.IOfficialSuggestService;
+import com.zhongzheng.util.AjaxResult;
+import com.zhongzheng.util.BaseController;
+import com.zhongzheng.util.TableDataInfo;
+import com.zhongzheng.vo.OfficialActivityVo;
+import com.zhongzheng.vo.OfficialSuggestVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 建议留言管理
+ *
+ * @author zhongzheng
+ */
+@Api(value = "建议留言管理", tags = {"建议留言管理"})
+@RestController
+@RequestMapping("/official/suggest")
+public class OfficialSuggestController extends BaseController {
+
+    @Autowired
+    private IOfficialSuggestService officialSuggestService;
+
+
+    /**
+     * 新增建议留言
+     */
+    @ApiOperation("新增建议留言")
+    @PostMapping("/save")
+    public AjaxResult add(@RequestBody OfficialSuggestBo bo) {
+        return toAjax(officialSuggestService.addOfficialSuggest(bo) ? 1 : 0);
+    }
+
+    /**
+     * 建议留言列表
+     */
+    @ApiOperation("建议留言列表")
+    @GetMapping("/list")
+    public TableDataInfo<OfficialSuggestVo> listOfficialSuggest(OfficialSuggestQuery query) {
+        Page<OfficialSuggestVo> list = officialSuggestService.listOfficialSuggest(query);
+        return getDataTable(list);
+    }
+
+    /**
+     * 删除建议留言
+     */
+    @ApiOperation("删除建议留言")
+    @PostMapping("/del")
+    public AjaxResult delOfficialSuggest(@RequestBody BatchDelBo bo) {
+        return toAjax(officialSuggestService.delOfficialSuggest(bo) ? 1 : 0);
+    }
+
+}

+ 47 - 0
src/main/java/com/zhongzheng/controller/OssController.java

@@ -0,0 +1,47 @@
+package com.zhongzheng.controller;
+
+
+import com.zhongzheng.bo.OssRequest;
+import com.zhongzheng.service.OssService;
+import com.zhongzheng.util.AjaxResult;
+import com.zhongzheng.util.BaseController;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 阿里OSS
+ *
+ * @author change
+ * @date 2021-05-17
+ */
+@Api(value = "阿里OSS上传文件控制器", tags = {"阿里OSS上传文件"})
+@RequiredArgsConstructor(onConstructor_ = @Autowired)
+@RestController
+@RequestMapping("/aliyun/oss")
+public class OssController extends BaseController {
+
+    private final OssService ossService;
+
+    /**
+     * upload上传文件
+     */
+    @ApiOperation("上传file图片")
+    @PostMapping("/upload")
+    public AjaxResult<String> upload(OssRequest file) throws Exception {
+        String result = ossService.upload(file);
+        return AjaxResult.success("返回图片路径",result);
+    }
+
+    @ApiOperation("上传file图片带路径")
+    @PostMapping("/uploadPath")
+    public AjaxResult<String> uploadPath(OssRequest file) throws Exception {
+        String result = ossService.uploadWithPath(file,file.getPath());
+        return AjaxResult.success("返回图片路径",result);
+    }
+
+}

+ 95 - 0
src/main/java/com/zhongzheng/controller/SysLoginController.java

@@ -0,0 +1,95 @@
+package com.zhongzheng.controller;
+
+import com.zhongzheng.bo.LoginBody;
+import com.zhongzheng.entity.SysUser;
+import com.zhongzheng.service.ISysUserService;
+import com.zhongzheng.service.impl.SysLoginService;
+import com.zhongzheng.util.*;
+import com.zhongzheng.vo.SysMenuVo;
+import com.zhongzheng.vo.SysUserVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * 登录验证
+ *
+ * @author zhongzheng
+ */
+@Api(value = "登录控制器", tags = {"登录控制器"})
+@RestController
+public class SysLoginController {
+    @Autowired
+    private SysLoginService loginService;
+
+    @Autowired
+    private TokenService tokenService;
+
+    @Autowired
+    private ISysUserService iSysUserService;
+
+
+    /**
+     * 登录方法
+     *
+     * @param loginBody 登录信息
+     * @return 结果
+     */
+    @ApiOperation("登录")
+    @PostMapping("/login")
+    public AjaxResult login(@RequestBody LoginBody loginBody)
+    {
+        AjaxResult ajax = AjaxResult.success();
+        // 生成令牌
+        String token = loginService.login(loginBody.getAccount(), loginBody.getPassword(), loginBody.getCode(), loginBody.getUuid());
+        ajax.put(Constants.TOKEN, token);
+        return ajax;
+    }
+
+    /**
+     * 获取用户信息
+     *
+     * @return 用户信息
+     */
+    @ApiOperation("登录用户信息")
+    @GetMapping("getInfo")
+    public AjaxResult<SysUserVo> getInfo()
+    {
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        SysUserVo vo = iSysUserService.getUserPermission(loginUser.getUser().getUserId());
+        return AjaxResult.success(vo);
+    }
+
+    /**
+     * 获取路由信息
+     *
+     * @return 路由信息
+     */
+    @ApiOperation("菜单信息")
+    @GetMapping("getRouters")
+    public AjaxResult<List<SysMenuVo>> getRouters()
+    {
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        // 用户信息
+        SysUser user = loginUser.getUser();
+        List<SysMenuVo> menus = iSysUserService.getUserMenu(user.getUserId());
+        return AjaxResult.success(menus);
+    }
+
+
+    @ApiOperation("初始化admin账号")
+    @GetMapping("admin")
+    public AjaxResult initAdmin()
+    {
+        iSysUserService.initAdmin();
+        return AjaxResult.success("初始化成功");
+    }
+
+
+}

+ 69 - 0
src/main/java/com/zhongzheng/controller/SysMenuController.java

@@ -0,0 +1,69 @@
+package com.zhongzheng.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zhongzheng.bo.SysMenuBo;
+import com.zhongzheng.bo.SysUserQuery;
+import com.zhongzheng.service.ISysMenuService;
+import com.zhongzheng.util.AjaxResult;
+import com.zhongzheng.util.BaseController;
+import com.zhongzheng.util.TableDataInfo;
+import com.zhongzheng.vo.SysMenuVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 后台菜单控制器
+ *
+ * @author zhongzheng
+ */
+@Api(value = "菜单控制器", tags = {"菜单控制器"})
+@RestController
+@RequestMapping("/system/menu")
+public class SysMenuController extends BaseController {
+
+    @Autowired
+    private ISysMenuService menuService;
+
+
+    /**
+     * 新增菜单
+     */
+    @ApiOperation("新增菜单")
+    @PostMapping("/save")
+    public AjaxResult add(@RequestBody SysMenuBo bo) {
+        return toAjax(menuService.addMenu(bo) ? 1 : 0);
+    }
+
+    /**
+     * 菜单列表
+     */
+    @ApiOperation("菜单列表")
+    @GetMapping("/list")
+    public TableDataInfo<SysMenuVo> listMenu(SysUserQuery query) {
+        Page<SysMenuVo> list = menuService.listMenu(query);
+        return getDataTable(list);
+    }
+
+    /**
+     * 修改菜单
+     */
+    @ApiOperation("修改菜单")
+    @PostMapping("/edit")
+    public AjaxResult edit(@RequestBody SysMenuBo bo) {
+        return toAjax(menuService.editMenu(bo) ? 1 : 0);
+    }
+
+
+    /**
+     * 菜单详情
+     */
+    @ApiOperation("菜单详情")
+    @GetMapping("/detail/{menuId}")
+    public AjaxResult<SysMenuVo> menuIdDetail(@PathVariable("menuId") Long menuId) {
+        SysMenuVo vo = menuService.menuIdDetail(menuId);
+        return AjaxResult.success(vo);
+    }
+
+}

+ 78 - 0
src/main/java/com/zhongzheng/controller/SysRoleController.java

@@ -0,0 +1,78 @@
+package com.zhongzheng.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zhongzheng.bo.SysRoleBo;
+import com.zhongzheng.bo.SysUserQuery;
+import com.zhongzheng.service.ISysRoleService;
+import com.zhongzheng.util.AjaxResult;
+import com.zhongzheng.util.BaseController;
+import com.zhongzheng.util.TableDataInfo;
+import com.zhongzheng.vo.SysRoleVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 后台角色控制器
+ *
+ * @author zhongzheng
+ */
+@Api(value = "角色控制器", tags = {"角色控制器"})
+@RestController
+@RequestMapping("/system/role")
+public class SysRoleController extends BaseController {
+
+    @Autowired
+    private ISysRoleService roleService;
+
+
+    /**
+     * 新增角色
+     */
+    @ApiOperation("新增角色")
+    @PostMapping("/save")
+    public AjaxResult add(@RequestBody SysRoleBo bo) {
+        return toAjax(roleService.addRole(bo)? 1 : 0);
+    }
+
+    /**
+     * 角色列表
+     */
+    @ApiOperation("角色列表")
+    @GetMapping("/list")
+    public TableDataInfo<SysRoleVo> listRole(SysUserQuery bo) {
+        Page<SysRoleVo> list = roleService.listRole(bo);
+        return getDataTable(list);
+    }
+
+    /**
+     * 修改角色
+     */
+    @ApiOperation("修改角色")
+    @PostMapping("/edit")
+    public AjaxResult edit(@RequestBody SysRoleBo bo) {
+        return toAjax(roleService.editRole(bo)? 1 : 0);
+    }
+
+
+    /**
+     * 删除角色
+     */
+    @ApiOperation("删除角色")
+    @GetMapping("/del/{roleId}")
+    public AjaxResult delRole(@PathVariable("roleId") Long roleId) {
+        return toAjax(roleService.delRole(roleId)? 1 : 0);
+    }
+
+    /**
+     * 角色详情
+     */
+    @ApiOperation("角色详情")
+    @GetMapping("/detail/{roleId}")
+    public AjaxResult<SysRoleVo> roleDetail(@PathVariable("roleId") Long roleId) {
+        SysRoleVo vo = roleService.roleDetail(roleId);
+        return AjaxResult.success(vo);
+    }
+
+}

+ 88 - 0
src/main/java/com/zhongzheng/controller/SysUserController.java

@@ -0,0 +1,88 @@
+package com.zhongzheng.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zhongzheng.bo.SysUserBo;
+import com.zhongzheng.bo.SysUserQuery;
+import com.zhongzheng.bo.UserPwdBo;
+import com.zhongzheng.service.ISysUserService;
+import com.zhongzheng.util.AjaxResult;
+import com.zhongzheng.util.BaseController;
+import com.zhongzheng.util.TableDataInfo;
+import com.zhongzheng.vo.SysUserVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 后台用户控制器
+ *
+ * @author zhongzheng
+ */
+@Api(value = "用户控制器", tags = {"用户控制器"})
+@RestController
+@RequestMapping("/system/user")
+public class SysUserController extends BaseController {
+
+    @Autowired
+    private ISysUserService userService;
+
+
+    /**
+     * 新增用户
+     */
+    @ApiOperation("新增用户")
+    @PostMapping("/save")
+    public AjaxResult add(@RequestBody SysUserBo user) {
+        return toAjax(userService.addUser(user)? 1 : 0);
+    }
+
+    /**
+     * 用户列表
+     */
+    @ApiOperation("用户列表")
+    @GetMapping("/list")
+    public TableDataInfo<SysUserVo> list(SysUserQuery bo) {
+        Page<SysUserVo> list = userService.selectUserList(bo);
+        return getDataTable(list);
+    }
+
+    /**
+     * 修改用户
+     */
+    @ApiOperation("修改用户")
+    @PostMapping("/edit")
+    public AjaxResult edit(@RequestBody SysUserBo bo) {
+        return toAjax(userService.editUser(bo)? 1 : 0);
+    }
+
+
+    /**
+     * 删除用户
+     */
+    @ApiOperation("删除用户")
+    @GetMapping("/del/{userId}")
+    public AjaxResult delUser(@PathVariable("userId") Long userId) {
+        return toAjax(userService.delUser(userId)? 1 : 0);
+    }
+
+    /**
+     * 用户详情
+     */
+    @ApiOperation("用户详情")
+    @GetMapping("/detail/{userId}")
+    public AjaxResult<SysUserVo> userDetail(@PathVariable("userId") Long userId) {
+        SysUserVo vo = userService.userDetail(userId);
+        return AjaxResult.success(vo);
+    }
+
+    /**
+     * 修改密碼
+     */
+    @ApiOperation("修改密碼")
+    @PostMapping("/edit/pwd")
+    public AjaxResult editPassword(@RequestBody UserPwdBo bo) {
+        return toAjax(userService.editPassword(bo)? 1 : 0);
+    }
+
+}

+ 68 - 0
src/main/java/com/zhongzheng/entity/OfficialActivity.java

@@ -0,0 +1,68 @@
+package com.zhongzheng.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+@TableName("official_activity")
+public class OfficialActivity implements Serializable {
+
+    /**
+     *
+     */
+    @TableId(value = "activity_id",type = IdType.AUTO)
+    private Long activityId;
+
+    /**
+     * 标题
+     */
+    private String title;
+
+    /**
+     * 图片地址
+     */
+    private String imageUrl;
+
+    /**
+     * 跳转地址
+     */
+    private String jumpUrl;
+
+    /**
+     * 类型:1 轮播图 2 底部
+     */
+    private Integer type;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    /**
+     * 排序字段
+     */
+    private Integer sort;
+
+    /**
+     * 1正常 0停用
+     */
+    private Integer status;
+
+    /**
+     * 创建时间
+     */
+    private Long createTime;
+
+    /**
+     * 更新时间
+     */
+    private Long updateTime;
+}

+ 58 - 0
src/main/java/com/zhongzheng/entity/OfficialArticle.java

@@ -0,0 +1,58 @@
+package com.zhongzheng.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+@TableName("official_article")
+public class OfficialArticle implements Serializable {
+
+    /**
+     *
+     */
+    @TableId(value = "article_id",type = IdType.AUTO)
+    private Long articleId;
+
+    /**
+     * 官网菜单ID
+     */
+    private Long menuId;
+
+    /**
+     * 标题
+     */
+    private String title;
+
+    /**
+     * 是否置顶:1是 0否
+     */
+    private Integer topStatus;
+
+    /**
+     * 内容(富文本框)
+     */
+    private String content;
+
+    /**
+     * 1正常 0停用
+     */
+    private Integer status;
+
+    /**
+     * 创建时间
+     */
+    private Long createTime;
+
+    /**
+     * 更新时间
+     */
+    private Long updateTime;
+}

+ 48 - 0
src/main/java/com/zhongzheng/entity/OfficialLink.java

@@ -0,0 +1,48 @@
+package com.zhongzheng.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+@TableName("official_link")
+public class OfficialLink implements Serializable {
+
+    /**
+     *
+     */
+    @TableId(value = "link_id",type = IdType.AUTO)
+    private Long linkId;
+
+    /**
+     * 標題
+     */
+    private String title;
+
+    /**
+     * 链接
+     */
+    private String url;
+
+    /**
+     * 1正常 0停用
+     */
+    private Integer status;
+
+    /**
+     * 创建时间
+     */
+    private Long createTime;
+
+    /**
+     * 更新时间
+     */
+    private Long updateTime;
+}

+ 78 - 0
src/main/java/com/zhongzheng/entity/OfficialMenu.java

@@ -0,0 +1,78 @@
+package com.zhongzheng.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+@TableName("official_menu")
+public class OfficialMenu implements Serializable {
+
+    /**
+     *
+     */
+    @TableId(value = "menu_id",type = IdType.AUTO)
+    private Long menuId;
+
+    /**
+     * 父级ID(为0时是一级)
+     */
+    private Long parentId;
+
+    /**
+     * 菜单名称
+     */
+    private String name;
+
+    /**
+     * 类型:1属于新闻大分类,可用后台吴加分类,2小类,首面不分类为0,配置不维护
+     */
+    private Integer type;
+
+    /**
+     * 用途 1文章 2列表
+     */
+    private Integer showType;
+
+    /**
+     * 标识: 1有 0没有
+     */
+    private Integer sign;
+
+    /**
+     * 排序字段
+     */
+    private Integer sortNumber;
+
+    /**
+     * 外链跳转地址
+     */
+    private String webUrl;
+
+    /**
+     * 菜单选中值
+     */
+    private String curValue;
+
+    /**
+     * 状态(1正常 0停用)
+     */
+    private Integer status;
+
+    /**
+     * 创建时间
+     */
+    private Long createTime;
+
+    /**
+     * 更新时间
+     */
+    private Long updateTime;
+}

+ 48 - 0
src/main/java/com/zhongzheng/entity/OfficialProblem.java

@@ -0,0 +1,48 @@
+package com.zhongzheng.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+@TableName("official_problem")
+public class OfficialProblem implements Serializable {
+
+    /**
+     *
+     */
+    @TableId(value = "problem_id",type = IdType.AUTO)
+    private Long problemId;
+
+    /**
+     * 問題
+     */
+    private String title;
+
+    /**
+     * 答案
+     */
+    private String answer;
+
+    /**
+     * 1正常 0停用
+     */
+    private Integer status;
+
+    /**
+     * 创建时间
+     */
+    private Long createTime;
+
+    /**
+     * 更新时间
+     */
+    private Long updateTime;
+}

+ 48 - 0
src/main/java/com/zhongzheng/entity/OfficialSuggest.java

@@ -0,0 +1,48 @@
+package com.zhongzheng.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+@TableName("official_suggest")
+public class OfficialSuggest implements Serializable {
+
+    /**
+     *
+     */
+    @TableId(value = "suggest_id",type = IdType.AUTO)
+    private Long suggestId;
+
+    /**
+     * 手机号码
+     */
+    private String phone;
+
+    /**
+     * 内容
+     */
+    private String content;
+
+    /**
+     * 1正常 0停用
+     */
+    private Integer status;
+
+    /**
+     * 创建时间
+     */
+    private Long createTime;
+
+    /**
+     * 更新时间
+     */
+    private Long updateTime;
+}

+ 84 - 0
src/main/java/com/zhongzheng/entity/SysMenu.java

@@ -0,0 +1,84 @@
+package com.zhongzheng.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+@TableName("sys_menu")
+public class SysMenu implements Serializable {
+
+    /**
+     *
+     */
+    @TableId(value = "menu_id",type = IdType.AUTO)
+    private Long menuId;
+
+    /**
+     * 父级ID(为0时是一级)
+     */
+    private Long parentId;
+
+    /**
+     * 菜单名称
+     */
+    private String name;
+
+    /**
+     * 类型:1目录 2菜单 3按钮
+     */
+    private Integer type;
+
+    /**
+     * 菜单图标
+     */
+    private String icon;
+
+    /**
+     * 排序字段
+     */
+    private Integer sort;
+
+    /**
+     * 路由地址
+     */
+    private String path;
+
+    /**
+     * 组件路径
+     */
+    private String component;
+
+    /**
+     * 权限标识
+     */
+    private String perms;
+
+    /**
+     * 菜单状态(1显示 0隐藏)
+     */
+    private Integer visible;
+
+    /**
+     * 状态(1正常 0停用)
+     */
+    private Integer status;
+
+    /**
+     * 创建时间
+     */
+    private Long createTime;
+
+    /**
+     * 更新时间
+     */
+    private Long updateTime;
+}
+

+ 54 - 0
src/main/java/com/zhongzheng/entity/SysRole.java

@@ -0,0 +1,54 @@
+package com.zhongzheng.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+@TableName("sys_role")
+public class SysRole implements Serializable {
+
+    /**
+     *
+     */
+    @TableId(value = "role_id",type = IdType.AUTO)
+    private Long roleId;
+
+    /**
+     * 角色名称
+     */
+    private String roleName;
+
+    /**
+     * 角色编码
+     */
+    private String roleCode;
+
+    /**
+     * 排序字段
+     */
+    private Integer sort;
+
+    /**
+     * 状态(1正常 0停用)
+     */
+    private Integer status;
+
+    /**
+     * 创建时间
+     */
+    private Long createTime;
+
+    /**
+     * 更新时间
+     */
+    private Long updateTime;
+}
+

+ 35 - 0
src/main/java/com/zhongzheng/entity/SysRoleMenu.java

@@ -0,0 +1,35 @@
+package com.zhongzheng.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+@TableName("sys_role_menu")
+public class SysRoleMenu implements Serializable {
+
+    /**
+     *
+     */
+    @TableId(value = "id",type = IdType.AUTO)
+    private Long Id;
+
+    /**
+     *
+     */
+    private Long roleId;
+
+    /**
+     *
+     */
+    private Long menuId;
+
+}
+

+ 64 - 0
src/main/java/com/zhongzheng/entity/SysUser.java

@@ -0,0 +1,64 @@
+package com.zhongzheng.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+@TableName("sys_user")
+public class SysUser implements Serializable {
+
+    /**
+     *
+     */
+    @TableId(value = "user_id",type = IdType.AUTO)
+    private Long userId;
+
+    /**
+     * 账号
+     */
+    private String account;
+
+    /**
+     * 用户姓名
+     */
+    private String userName;
+
+    /**
+     * 用户邮箱
+     */
+    private String email;
+
+    /**
+     * 密码
+     */
+    private String password;
+
+    /**
+     * 密码
+     */
+    private String passwordAes;
+
+    /**
+     * 帐号状态(1正常 0停用)
+     */
+    private Integer status;
+
+    /**
+     * 创建时间
+     */
+    private Long createTime;
+
+    /**
+     * 更新时间
+     */
+    private Long updateTime;
+}
+

+ 35 - 0
src/main/java/com/zhongzheng/entity/SysUserRole.java

@@ -0,0 +1,35 @@
+package com.zhongzheng.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+@TableName("sys_user_role")
+public class SysUserRole implements Serializable {
+
+    /**
+     *
+     */
+    @TableId(value = "id",type = IdType.AUTO)
+    private Long Id;
+
+    /**
+     *
+     */
+    private Long userId;
+
+    /**
+     *
+     */
+    private Long roleId;
+
+}
+

+ 43 - 0
src/main/java/com/zhongzheng/exception/CustomException.java

@@ -0,0 +1,43 @@
+package com.zhongzheng.exception;
+
+/**
+ * 自定义异常
+ * 
+ * @author zhongzheng
+ */
+public class CustomException extends RuntimeException
+{
+    private static final long serialVersionUID = 1L;
+
+    private Integer code;
+
+    private String message;
+
+    public CustomException(String message)
+    {
+        this.message = message;
+    }
+
+    public CustomException(String message, Integer code)
+    {
+        this.message = message;
+        this.code = code;
+    }
+
+    public CustomException(String message, Throwable e)
+    {
+        super(message, e);
+        this.message = message;
+    }
+
+    @Override
+    public String getMessage()
+    {
+        return message;
+    }
+
+    public Integer getCode()
+    {
+        return code;
+    }
+}

+ 14 - 0
src/main/java/com/zhongzheng/mapper/OfficialActivityMapper.java

@@ -0,0 +1,14 @@
+package com.zhongzheng.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zhongzheng.entity.OfficialActivity;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 文章菜单mapper
+ *
+ * @author zhongzheng
+ */
+@Mapper
+public interface OfficialActivityMapper extends BaseMapper<OfficialActivity> {
+}

+ 14 - 0
src/main/java/com/zhongzheng/mapper/OfficialArticleMapper.java

@@ -0,0 +1,14 @@
+package com.zhongzheng.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zhongzheng.entity.OfficialArticle;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 文章菜单mapper
+ *
+ * @author zhongzheng
+ */
+@Mapper
+public interface OfficialArticleMapper extends BaseMapper<OfficialArticle> {
+}

+ 14 - 0
src/main/java/com/zhongzheng/mapper/OfficialLinkMapper.java

@@ -0,0 +1,14 @@
+package com.zhongzheng.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zhongzheng.entity.OfficialLink;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 文章菜单mapper
+ *
+ * @author zhongzheng
+ */
+@Mapper
+public interface OfficialLinkMapper extends BaseMapper<OfficialLink> {
+}

+ 14 - 0
src/main/java/com/zhongzheng/mapper/OfficialMenuMapper.java

@@ -0,0 +1,14 @@
+package com.zhongzheng.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zhongzheng.entity.OfficialMenu;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 新闻菜单mapper
+ *
+ * @author zhongzheng
+ */
+@Mapper
+public interface OfficialMenuMapper extends BaseMapper<OfficialMenu> {
+}

+ 14 - 0
src/main/java/com/zhongzheng/mapper/OfficialProblemMapper.java

@@ -0,0 +1,14 @@
+package com.zhongzheng.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zhongzheng.entity.OfficialProblem;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 文章菜单mapper
+ *
+ * @author zhongzheng
+ */
+@Mapper
+public interface OfficialProblemMapper extends BaseMapper<OfficialProblem> {
+}

+ 14 - 0
src/main/java/com/zhongzheng/mapper/OfficialSuggestMapper.java

@@ -0,0 +1,14 @@
+package com.zhongzheng.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zhongzheng.entity.OfficialSuggest;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 文章菜单mapper
+ *
+ * @author zhongzheng
+ */
+@Mapper
+public interface OfficialSuggestMapper extends BaseMapper<OfficialSuggest> {
+}

+ 15 - 0
src/main/java/com/zhongzheng/mapper/SysMenuMapper.java

@@ -0,0 +1,15 @@
+package com.zhongzheng.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zhongzheng.entity.SysMenu;
+import com.zhongzheng.entity.SysUser;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 用户表 数据层
+ *
+ * @author zhongzheng
+ */
+@Mapper
+public interface SysMenuMapper extends BaseMapper<SysMenu> {
+}

+ 15 - 0
src/main/java/com/zhongzheng/mapper/SysRoleMapper.java

@@ -0,0 +1,15 @@
+package com.zhongzheng.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zhongzheng.entity.SysRole;
+import com.zhongzheng.entity.SysUser;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 用户表 数据层
+ *
+ * @author zhongzheng
+ */
+@Mapper
+public interface SysRoleMapper extends BaseMapper<SysRole> {
+}

+ 15 - 0
src/main/java/com/zhongzheng/mapper/SysRoleMenuMapper.java

@@ -0,0 +1,15 @@
+package com.zhongzheng.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zhongzheng.entity.SysRoleMenu;
+import com.zhongzheng.entity.SysUser;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 用户表 数据层
+ *
+ * @author zhongzheng
+ */
+@Mapper
+public interface SysRoleMenuMapper extends BaseMapper<SysRoleMenu> {
+}

+ 14 - 0
src/main/java/com/zhongzheng/mapper/SysUserMapper.java

@@ -0,0 +1,14 @@
+package com.zhongzheng.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zhongzheng.entity.SysUser;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 用户表 数据层
+ *
+ * @author zhongzheng
+ */
+@Mapper
+public interface SysUserMapper extends BaseMapper<SysUser> {
+}

+ 15 - 0
src/main/java/com/zhongzheng/mapper/SysUserRoleMapper.java

@@ -0,0 +1,15 @@
+package com.zhongzheng.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zhongzheng.entity.SysUser;
+import com.zhongzheng.entity.SysUserRole;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 用户表 数据层
+ *
+ * @author zhongzheng
+ */
+@Mapper
+public interface SysUserRoleMapper extends BaseMapper<SysUserRole> {
+}

+ 27 - 0
src/main/java/com/zhongzheng/service/IOfficialActivityService.java

@@ -0,0 +1,27 @@
+package com.zhongzheng.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zhongzheng.bo.BatchDelBo;
+import com.zhongzheng.bo.OfficialActivityBo;
+import com.zhongzheng.bo.OfficialArticleQuery;
+import com.zhongzheng.entity.OfficialActivity;
+import com.zhongzheng.vo.OfficialActivityVo;
+
+/**
+ * 用户 业务层
+ *
+ * @author zhongzheng
+ */
+public interface IOfficialActivityService extends IService<OfficialActivity> {
+
+    boolean addOfficialActivity(OfficialActivityBo bo);
+
+    Page<OfficialActivityVo> listOfficialActivity(OfficialArticleQuery query);
+
+    boolean editOfficialActivity(OfficialActivityBo bo);
+
+    OfficialActivityVo detailById(Long activityId);
+
+    boolean delOfficialActivity(BatchDelBo bo);
+}

+ 30 - 0
src/main/java/com/zhongzheng/service/IOfficialApiService.java

@@ -0,0 +1,30 @@
+package com.zhongzheng.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zhongzheng.bo.*;
+import com.zhongzheng.vo.*;
+
+import java.util.List;
+
+public interface IOfficialApiService {
+
+    List<OfficialMenuVo> listOfficialMenu(OfficialMenuQuery query);
+
+    Page<OfficialArticleVo> listArticle(OfficialArticleQuery query);
+
+    List<OfficialActivityVo> listActivity(OfficialActivityQuery query);
+
+    List<OfficialLinkVo> listLink(OfficialLinkQuery query);
+
+    List<OfficialProblemVo> listProblem(OfficialProblemQuery query);
+
+    boolean saveSuggest(OfficialSuggestBo bo);
+
+    List<EducationVo> getEduList(OfficialOpenBo bo);
+
+    OfficialArticleVo detailArticle(Long articleId);
+
+    OfficialMenuVo detailMenu(Long menuId);
+
+    List<OfficialRecommendVo> getEduGoodsList(OfficialOpenBo bo);
+}

+ 27 - 0
src/main/java/com/zhongzheng/service/IOfficialArticleService.java

@@ -0,0 +1,27 @@
+package com.zhongzheng.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zhongzheng.bo.BatchDelBo;
+import com.zhongzheng.bo.OfficialArticleBo;
+import com.zhongzheng.bo.OfficialArticleQuery;
+import com.zhongzheng.entity.OfficialArticle;
+import com.zhongzheng.vo.OfficialArticleVo;
+
+/**
+ * 用户 业务层
+ *
+ * @author zhongzheng
+ */
+public interface IOfficialArticleService extends IService<OfficialArticle> {
+
+    boolean addOfficialArticle(OfficialArticleBo bo);
+
+    Page<OfficialArticleVo> listOfficialArticle(OfficialArticleQuery query);
+
+    boolean editOfficialArticle(OfficialArticleBo bo);
+
+    boolean delOfficialArticle(BatchDelBo bo);
+
+    OfficialArticleVo detailById(Long articleId);
+}

+ 23 - 0
src/main/java/com/zhongzheng/service/IOfficialLinkService.java

@@ -0,0 +1,23 @@
+package com.zhongzheng.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zhongzheng.bo.BatchDelBo;
+import com.zhongzheng.bo.OfficialLinkBo;
+import com.zhongzheng.bo.OfficialLinkQuery;
+import com.zhongzheng.entity.OfficialLink;
+import com.zhongzheng.vo.OfficialLinkVo;
+
+/**
+ * 用户 业务层
+ *
+ * @author zhongzheng
+ */
+public interface IOfficialLinkService extends IService<OfficialLink> {
+
+    boolean addOfficialLink(OfficialLinkBo bo);
+
+    Page<OfficialLinkVo> listOfficialLink(OfficialLinkQuery query);
+
+    boolean delOfficialLink(BatchDelBo bo);
+}

+ 26 - 0
src/main/java/com/zhongzheng/service/IOfficialMenuService.java

@@ -0,0 +1,26 @@
+package com.zhongzheng.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zhongzheng.bo.OfficialMenuBo;
+import com.zhongzheng.bo.OfficialMenuQuery;
+import com.zhongzheng.entity.OfficialMenu;
+import com.zhongzheng.vo.OfficialMenuVo;
+
+/**
+ * 用户 业务层
+ *
+ * @author zhongzheng
+ */
+public interface IOfficialMenuService extends IService<OfficialMenu> {
+
+    boolean addOfficialMenu(OfficialMenuBo bo);
+
+    Page<OfficialMenuVo> listOfficialMenu(OfficialMenuQuery query);
+
+    boolean editMenu(OfficialMenuBo bo);
+
+    OfficialMenuVo menuIdDetail(Long menuId);
+
+    boolean delOfficialMenu(Long menuId);
+}

+ 23 - 0
src/main/java/com/zhongzheng/service/IOfficialProblemService.java

@@ -0,0 +1,23 @@
+package com.zhongzheng.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zhongzheng.bo.BatchDelBo;
+import com.zhongzheng.bo.OfficialProblemBo;
+import com.zhongzheng.bo.OfficialProblemQuery;
+import com.zhongzheng.entity.OfficialProblem;
+import com.zhongzheng.vo.OfficialProblemVo;
+
+/**
+ * 用户 业务层
+ *
+ * @author zhongzheng
+ */
+public interface IOfficialProblemService extends IService<OfficialProblem> {
+
+    boolean addOfficialProblem(OfficialProblemBo bo);
+
+    Page<OfficialProblemVo> listOfficialProblem(OfficialProblemQuery query);
+
+    boolean delOfficialProblem(BatchDelBo bo);
+}

+ 23 - 0
src/main/java/com/zhongzheng/service/IOfficialSuggestService.java

@@ -0,0 +1,23 @@
+package com.zhongzheng.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zhongzheng.bo.BatchDelBo;
+import com.zhongzheng.bo.OfficialSuggestBo;
+import com.zhongzheng.bo.OfficialSuggestQuery;
+import com.zhongzheng.entity.OfficialSuggest;
+import com.zhongzheng.vo.OfficialSuggestVo;
+
+/**
+ * 用户 业务层
+ *
+ * @author zhongzheng
+ */
+public interface IOfficialSuggestService extends IService<OfficialSuggest> {
+
+    boolean addOfficialSuggest(OfficialSuggestBo bo);
+
+    Page<OfficialSuggestVo> listOfficialSuggest(OfficialSuggestQuery query);
+
+    boolean delOfficialSuggest(BatchDelBo bo);
+}

+ 25 - 0
src/main/java/com/zhongzheng/service/ISysMenuService.java

@@ -0,0 +1,25 @@
+package com.zhongzheng.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zhongzheng.bo.SysMenuBo;
+import com.zhongzheng.bo.SysUserQuery;
+import com.zhongzheng.entity.SysMenu;
+import com.zhongzheng.vo.SysMenuVo;
+
+/**
+ * 用户 业务层
+ *
+ * @author zhongzheng
+ */
+public interface ISysMenuService extends IService<SysMenu> {
+
+
+    boolean addMenu(SysMenuBo bo);
+
+    Page<SysMenuVo> listMenu(SysUserQuery query);
+
+    boolean editMenu(SysMenuBo bo);
+
+    SysMenuVo menuIdDetail(Long menuId);
+}

+ 13 - 0
src/main/java/com/zhongzheng/service/ISysRoleMenuService.java

@@ -0,0 +1,13 @@
+package com.zhongzheng.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zhongzheng.entity.SysRoleMenu;
+import com.zhongzheng.entity.SysUser;
+
+/**
+ * 用户 业务层
+ *
+ * @author zhongzheng
+ */
+public interface ISysRoleMenuService extends IService<SysRoleMenu> {
+}

+ 29 - 0
src/main/java/com/zhongzheng/service/ISysRoleService.java

@@ -0,0 +1,29 @@
+package com.zhongzheng.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zhongzheng.bo.SysRoleBo;
+import com.zhongzheng.bo.SysUserQuery;
+import com.zhongzheng.entity.SysRole;
+import com.zhongzheng.entity.SysUser;
+import com.zhongzheng.vo.SysRoleVo;
+
+import java.util.Set;
+
+/**
+ * 用户 业务层
+ *
+ * @author zhongzheng
+ */
+public interface ISysRoleService extends IService<SysRole> {
+
+    boolean addRole(SysRoleBo bo);
+
+    Page<SysRoleVo> listRole(SysUserQuery bo);
+
+    boolean editRole(SysRoleBo bo);
+
+    boolean delRole(Long roleId);
+
+    SysRoleVo roleDetail(Long roleId);
+}

+ 13 - 0
src/main/java/com/zhongzheng/service/ISysUserRoleService.java

@@ -0,0 +1,13 @@
+package com.zhongzheng.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zhongzheng.entity.SysUser;
+import com.zhongzheng.entity.SysUserRole;
+
+/**
+ * 用户 业务层
+ *
+ * @author zhongzheng
+ */
+public interface ISysUserRoleService extends IService<SysUserRole> {
+}

+ 38 - 0
src/main/java/com/zhongzheng/service/ISysUserService.java

@@ -0,0 +1,38 @@
+package com.zhongzheng.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zhongzheng.bo.SysUserBo;
+import com.zhongzheng.bo.SysUserQuery;
+import com.zhongzheng.bo.UserPwdBo;
+import com.zhongzheng.entity.SysUser;
+import com.zhongzheng.vo.SysMenuVo;
+import com.zhongzheng.vo.SysUserVo;
+
+import java.util.List;
+
+/**
+ * 用户 业务层
+ *
+ * @author zhongzheng
+ */
+public interface ISysUserService extends IService<SysUser> {
+
+    boolean addUser(SysUserBo user);
+
+    Page<SysUserVo> selectUserList(SysUserQuery bo);
+
+    boolean editUser(SysUserBo bo);
+
+    boolean delUser(Long userId);
+
+    SysUserVo userDetail(Long userId);
+
+    SysUserVo getUserPermission(Long userId);
+
+    List<SysMenuVo> getUserMenu(Long userId);
+
+    void initAdmin();
+
+    boolean editPassword(UserPwdBo bo);
+}

+ 12 - 0
src/main/java/com/zhongzheng/service/OssService.java

@@ -0,0 +1,12 @@
+package com.zhongzheng.service;
+
+
+import com.zhongzheng.bo.OssRequest;
+
+public interface OssService {
+
+    String upload(OssRequest base) throws Exception;
+
+    String uploadWithPath(OssRequest base,String path) throws Exception;
+
+}

+ 75 - 0
src/main/java/com/zhongzheng/service/impl/OfficialActivityServiceImpl.java

@@ -0,0 +1,75 @@
+package com.zhongzheng.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zhongzheng.bo.BatchDelBo;
+import com.zhongzheng.bo.OfficialActivityBo;
+import com.zhongzheng.bo.OfficialArticleQuery;
+import com.zhongzheng.entity.OfficialActivity;
+import com.zhongzheng.exception.CustomException;
+import com.zhongzheng.mapper.OfficialActivityMapper;
+import com.zhongzheng.service.IOfficialActivityService;
+import com.zhongzheng.util.DateUtils;
+import com.zhongzheng.vo.OfficialActivityVo;
+import com.zhongzheng.vo.OfficialArticleVo;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.security.core.parameters.P;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+public class OfficialActivityServiceImpl extends ServiceImpl<OfficialActivityMapper, OfficialActivity> implements IOfficialActivityService {
+
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean addOfficialActivity(OfficialActivityBo bo) {
+        if (ObjectUtils.isNotNull(bo.getActivityId())){
+            return editOfficialActivity(bo);
+        }
+        OfficialActivity bean = BeanUtil.toBean(bo, OfficialActivity.class);
+        bean.setCreateTime(DateUtils.getNowTime());
+        bean.setUpdateTime(DateUtils.getNowTime());
+        return save(bean);
+    }
+
+    @Override
+    public Page<OfficialActivityVo> listOfficialActivity(OfficialArticleQuery query) {
+        Page<OfficialActivity> page = page(new Page<>(query.getPageSize(), query.getPageNum()));
+        if (CollectionUtils.isEmpty(page.getRecords())){
+            return new Page<>();
+        }
+        List<OfficialActivityVo> collect = page.getRecords().stream().map(x -> BeanUtil.toBean(x, OfficialActivityVo.class)).collect(Collectors.toList());
+        Page<OfficialActivityVo> result = new Page<>();
+        result.setTotal(page.getTotal());
+        result.setRecords(collect);
+        result.setSize(page.getSize());
+        return result;
+    }
+
+    @Override
+    public boolean editOfficialActivity(OfficialActivityBo bo) {
+        OfficialActivity bean = BeanUtil.toBean(bo, OfficialActivity.class);
+        return updateById(bean);
+    }
+
+    @Override
+    public OfficialActivityVo detailById(Long activityId) {
+        return BeanUtil.toBean(getById(activityId), OfficialActivityVo.class);
+    }
+
+    @Override
+    public boolean delOfficialActivity(BatchDelBo bo) {
+        if (CollectionUtils.isEmpty(bo.getIds())){
+            throw new CustomException("不能为空");
+        }
+        return removeByIds(bo.getIds());
+    }
+}

+ 265 - 0
src/main/java/com/zhongzheng/service/impl/OfficialApiServiceImpl.java

@@ -0,0 +1,265 @@
+package com.zhongzheng.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.extension.api.R;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zhongzheng.bo.*;
+import com.zhongzheng.entity.*;
+import com.zhongzheng.exception.CustomException;
+import com.zhongzheng.service.*;
+import com.zhongzheng.util.DateUtils;
+import com.zhongzheng.util.HttpUtils;
+import com.zhongzheng.util.ToolsUtils;
+import com.zhongzheng.vo.*;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+public class OfficialApiServiceImpl implements IOfficialApiService {
+
+    @Autowired
+    private IOfficialMenuService officialMenuService;
+
+    @Autowired
+    private IOfficialArticleService officialArticleService;
+
+    @Autowired
+    private IOfficialActivityService officialActivityService;
+
+    @Autowired
+    private IOfficialLinkService officialLinkService;
+
+    @Autowired
+    private IOfficialProblemService officialProblemService;
+
+    @Autowired
+    private IOfficialSuggestService officialSuggestService;
+
+    @Value("${studySys.eduPath}")
+    private String SYS_EDUPATH;
+
+    @Value("${studySys.goodsPath}")
+    private String SYS_GOODSPATH;
+
+    @Value("${studyApi.domain}")
+    private String SYS_DOMAIN;
+
+    @Value("${studyApi.tenantId}")
+    private String SYS_TENANTID;
+
+
+    @Override
+    public List<OfficialMenuVo> listOfficialMenu(OfficialMenuQuery query) {
+        //获取一级菜单
+        List<OfficialMenu> list = officialMenuService.list(new LambdaQueryWrapper<OfficialMenu>()
+                .eq(OfficialMenu::getParentId, ObjectUtils.isNotNull(query.getParentId())? query.getParentId() : 0)
+                .eq(OfficialMenu::getStatus,1)
+                .orderByAsc(OfficialMenu::getSortNumber));
+        if (CollectionUtils.isEmpty(list)){
+            return new ArrayList<>();
+        }
+        List<OfficialMenuVo> collect = list.stream().map(item -> {
+            OfficialMenuVo vo = BeanUtil.toBean(item, OfficialMenuVo.class);
+            //递归查询子集
+            getChildren(vo);
+            return vo;
+        }).collect(Collectors.toList());
+        return collect;
+    }
+
+    @Override
+    public Page<OfficialArticleVo> listArticle(OfficialArticleQuery query) {
+        List<Long> menuIds = new ArrayList<>();
+        if (ObjectUtils.isNotNull(query.getParentId())){
+            //获取所有子集id
+            getChildrenIds(query.getMenuId(),menuIds);
+        }
+        Page<OfficialArticle> list = officialArticleService.page(new Page<>(query.getPageSize(),query.getPageNum()),
+                new LambdaQueryWrapper<OfficialArticle>()
+                .eq(ObjectUtils.isNotNull(query.getMenuId()),OfficialArticle::getMenuId, query.getMenuId())
+                .in(CollectionUtils.isNotEmpty(menuIds),OfficialArticle::getMenuId,menuIds)
+                .eq(ObjectUtils.isNotNull(query.getArticleId()),OfficialArticle::getArticleId, query.getArticleId())
+                .like(StringUtils.isNotBlank(query.getTitle()),OfficialArticle::getTitle, query.getTitle())
+                .eq(OfficialArticle::getStatus, 1)
+                .orderByDesc(OfficialArticle::getTopStatus)
+                .orderByDesc(OfficialArticle::getCreateTime));
+        if (CollectionUtils.isEmpty(list.getRecords())){
+            return new Page<>();
+        }
+        List<OfficialArticleVo> collect = list.getRecords().stream().map(x ->BeanUtil.toBean(x, OfficialArticleVo.class)).collect(Collectors.toList());
+        Page<OfficialArticleVo> result = new Page<>();
+        result.setTotal(list.getTotal());
+        result.setRecords(collect);
+        result.setSize(list.getSize());
+        return result;
+    }
+
+    private void getChildrenIds(Long parentId,List<Long> menuIds) {
+        menuIds.add(parentId);
+        List<OfficialMenu> list = officialMenuService.list(new LambdaQueryWrapper<OfficialMenu>().eq(OfficialMenu::getParentId, parentId).eq(OfficialMenu::getStatus, 1));
+        if (CollectionUtils.isNotEmpty(list)){
+            menuIds.addAll(list.stream().map(OfficialMenu::getMenuId).collect(Collectors.toList()));
+            list.forEach(item -> {
+                getChildrenIds(item.getMenuId(),menuIds);
+            });
+        }
+    }
+
+    @Override
+    public List<OfficialActivityVo> listActivity(OfficialActivityQuery query) {
+        List<OfficialActivity> list = officialActivityService.list(new LambdaQueryWrapper<OfficialActivity>()
+                .eq(ObjectUtils.isNotNull(query.getType()), OfficialActivity::getType, query.getType())
+                .eq(OfficialActivity::getStatus, 1)
+                .orderByAsc(OfficialActivity::getSort));
+        if (CollectionUtils.isEmpty(list)){
+            return new ArrayList<>();
+        }
+        return list.stream().map(x -> BeanUtil.toBean(x, OfficialActivityVo.class)).collect(Collectors.toList());
+    }
+
+    @Override
+    public List<OfficialLinkVo> listLink(OfficialLinkQuery query) {
+        List<OfficialLink> list = officialLinkService.list(new LambdaQueryWrapper<OfficialLink>().eq(OfficialLink::getStatus, 1));
+        if (CollectionUtils.isEmpty(list)){
+            return new ArrayList<>();
+        }
+        return list.stream().map(x -> BeanUtil.toBean(x, OfficialLinkVo.class)).collect(Collectors.toList());
+    }
+
+    @Override
+    public List<OfficialProblemVo> listProblem(OfficialProblemQuery query) {
+        List<OfficialProblem> list = officialProblemService.list(new LambdaQueryWrapper<OfficialProblem>().eq(OfficialProblem::getStatus, 1));
+        if (CollectionUtils.isEmpty(list)){
+            return new ArrayList<>();
+        }
+        return list.stream().map(x -> BeanUtil.toBean(x, OfficialProblemVo.class)).collect(Collectors.toList());
+    }
+
+    @Override
+    public boolean saveSuggest(OfficialSuggestBo bo) {
+        OfficialSuggest bean = BeanUtil.toBean(bo, OfficialSuggest.class);
+        return officialSuggestService.save(bean);
+    }
+
+    @Override
+    public List<EducationVo> getEduList(OfficialOpenBo bo) {
+        CommonOfficialBo studentBo = new CommonOfficialBo();
+        Long nowTime = DateUtils.getNowTime();
+        String sign = ToolsUtils.EncoderByMd5(nowTime.toString() + "pubilc2022");
+        studentBo.setStamp(nowTime);
+        studentBo.setSign(sign);
+        HashMap<String, String> headersMap = new HashMap<>();
+        headersMap.put("TenantId",StringUtils.isNotBlank(bo.getTenantId())?bo.getTenantId():SYS_TENANTID);
+        String respone = "";
+        try {
+            respone = HttpUtils.sendPostHeader(SYS_EDUPATH, JSONObject.parseObject(JSONObject.toJSONString(studentBo)),headersMap);
+            if (!respone.contains("\"code\":200")) {
+                throw new CustomException("云学堂教育类型获取失败");
+            }
+            JSONObject jsonObject = JSONObject.parseObject(respone);
+            List<EducationVo> educationVos = JSONArray.parseArray(jsonObject.get("data").toString(), EducationVo.class);
+            if (CollectionUtils.isNotEmpty(educationVos)){
+                //填充跳转地址
+                String path = SYS_DOMAIN + "course-list?sortType=1&showStatus=1&goodsStatus=1";
+                educationVos.forEach(item -> {
+                    item.setJumpUrl(path+String.format("&educationId=%s",item.getId()));
+                    if (CollectionUtils.isNotEmpty(item.getBusinessList())){
+                        item.getBusinessList().forEach(x -> {
+                            x.setJumpUrl(path+String.format("&educationId=%s&projectId=%s&businessId=%s",item.getId(),x.getProjectId(),x.getId()));
+                        });
+                    }
+                });
+            }
+            return educationVos;
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new CustomException("云学堂教育类型获取失败");
+        }
+    }
+
+    @Override
+    public OfficialArticleVo detailArticle(Long articleId) {
+        return BeanUtil.toBean(officialArticleService.getById(articleId), OfficialArticleVo.class);
+    }
+
+    @Override
+    public OfficialMenuVo detailMenu(Long menuId) {
+        return BeanUtil.toBean(officialMenuService.getById(menuId), OfficialMenuVo.class);
+    }
+
+    @Override
+    public List<OfficialRecommendVo> getEduGoodsList(OfficialOpenBo bo) {
+        CommonOfficialBo studentBo = new CommonOfficialBo();
+        Long nowTime = DateUtils.getNowTime();
+        String sign = ToolsUtils.EncoderByMd5(nowTime.toString() + "pubilc2022");
+        studentBo.setStamp(nowTime);
+        studentBo.setSign(sign);
+        studentBo.setPlatform(2);
+        studentBo.setStatus(1);
+        HashMap<String, String> headersMap = new HashMap<>();
+        headersMap.put("TenantId",StringUtils.isNotBlank(bo.getTenantId())?bo.getTenantId():SYS_TENANTID);
+        String respone = "";
+        try {
+            respone = HttpUtils.sendPostHeader(SYS_GOODSPATH, JSONObject.parseObject(JSONObject.toJSONString(studentBo)),headersMap);
+            if (!respone.contains("\"code\":200")) {
+                throw new CustomException("云学堂推荐商品列表获取失败");
+            }
+            JSONObject jsonObject = JSONObject.parseObject(respone);
+            List<OfficialRecommendVo> educationVos = JSONArray.parseArray(jsonObject.get("data").toString(), OfficialRecommendVo.class);
+            if (CollectionUtils.isNotEmpty(educationVos)){
+                //填充跳转地址
+                String path = SYS_DOMAIN + "course-detail/";
+                String path1 = SYS_DOMAIN + "course-list?sortType=1&showStatus=1&goodsStatus=1";
+                String path2 = SYS_DOMAIN + "bank-list?sortType=1&showStatus=1&goodsStatus=1";
+                educationVos.forEach(item -> {
+                    switch (item.getType()){
+                        case 1: item.setJumpUrl(path1);
+                            break;
+                        case 2: item.setJumpUrl(path2);
+                            break;
+                        default:
+                            break;
+                    }
+                    if (CollectionUtils.isNotEmpty(item.getGoodsList())){
+                        for (OfficialGoodsVo goodsVo : item.getGoodsList()) {
+                            goodsVo.setJumpUrl(path+goodsVo.getGoodsId());
+                        }
+                    }
+                });
+            }
+            return educationVos;
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new CustomException("云学堂推荐商品列表获取失败");
+        }
+    }
+
+    private void getChildren(OfficialMenuVo parent) {
+        List<OfficialMenu> list = officialMenuService.list(new LambdaQueryWrapper<OfficialMenu>()
+                .eq(OfficialMenu::getParentId, parent.getMenuId())
+                .orderByAsc(OfficialMenu::getSortNumber));
+        if (CollectionUtils.isEmpty(list)){
+            return;
+        }
+        List<OfficialMenuVo> collect = list.stream().map(x -> BeanUtil.toBean(x, OfficialMenuVo.class)).collect(Collectors.toList());
+        parent.setChildList(collect);
+        list.forEach(item -> {
+            getChildren(BeanUtil.toBean(item,OfficialMenuVo.class));
+        });
+    }
+}

+ 96 - 0
src/main/java/com/zhongzheng/service/impl/OfficialArticleServiceImpl.java

@@ -0,0 +1,96 @@
+package com.zhongzheng.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zhongzheng.bo.BatchDelBo;
+import com.zhongzheng.bo.OfficialArticleBo;
+import com.zhongzheng.bo.OfficialArticleQuery;
+import com.zhongzheng.entity.OfficialArticle;
+import com.zhongzheng.entity.OfficialMenu;
+import com.zhongzheng.exception.CustomException;
+import com.zhongzheng.mapper.OfficialArticleMapper;
+import com.zhongzheng.service.IOfficialArticleService;
+import com.zhongzheng.service.IOfficialMenuService;
+import com.zhongzheng.util.DateUtils;
+import com.zhongzheng.vo.OfficialArticleVo;
+import com.zhongzheng.vo.OfficialMenuVo;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+public class OfficialArticleServiceImpl extends ServiceImpl<OfficialArticleMapper, OfficialArticle> implements IOfficialArticleService {
+
+
+    @Autowired
+    private IOfficialMenuService officialMenuService;
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean addOfficialArticle(OfficialArticleBo bo) {
+        if (ObjectUtils.isNotNull(bo.getArticleId())){
+            return editOfficialArticle(bo);
+        }
+        OfficialArticle bean = BeanUtil.toBean(bo, OfficialArticle.class);
+        bean.setCreateTime(DateUtils.getNowTime());
+        bean.setUpdateTime(DateUtils.getNowTime());
+        return save(bean);
+    }
+
+    @Override
+    public Page<OfficialArticleVo> listOfficialArticle(OfficialArticleQuery query) {
+        Page<OfficialArticle> page = page(new Page<>(query.getPageSize(), query.getPageSize()), new LambdaQueryWrapper<OfficialArticle>()
+                .eq(ObjectUtils.isNotNull(query.getMenuId()), OfficialArticle::getMenuId, query.getMenuId())
+                .eq(ObjectUtils.isNotNull(query.getTopStatus()), OfficialArticle::getTopStatus, query.getTopStatus())
+                .eq(ObjectUtils.isNotNull(query.getStatus()), OfficialArticle::getStatus, query.getStatus())
+                .like(ObjectUtils.isNotNull(query.getTitle()), OfficialArticle::getTitle, query.getTitle())
+        );
+        if (CollectionUtils.isEmpty(page.getRecords())){
+            return new Page<>();
+        }
+        List<OfficialArticleVo> collect = page.getRecords().stream().map(x ->{
+            OfficialArticleVo vo = BeanUtil.toBean(x, OfficialArticleVo.class);
+            //所属项目名称
+            OfficialMenu menu = officialMenuService.getById(vo.getMenuId());
+            vo.setMenuName(menu.getName());
+            return vo;
+        } ).collect(Collectors.toList());
+        Page<OfficialArticleVo> result = new Page<>();
+        result.setTotal(page.getTotal());
+        result.setRecords(collect);
+        result.setSize(page.getSize());
+        return result;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean editOfficialArticle(OfficialArticleBo bo) {
+        OfficialArticle bean = BeanUtil.toBean(bo, OfficialArticle.class);
+        return updateById(bean);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean delOfficialArticle(BatchDelBo bo) {
+        if (CollectionUtils.isEmpty(bo.getIds())){
+            throw new CustomException("数据为空");
+        }
+        return removeByIds(bo.getIds());
+    }
+
+    @Override
+    public OfficialArticleVo detailById(Long articleId) {
+        return BeanUtil.toBean(getById(articleId), OfficialArticleVo.class);
+    }
+
+
+}

+ 63 - 0
src/main/java/com/zhongzheng/service/impl/OfficialLinkServiceImpl.java

@@ -0,0 +1,63 @@
+package com.zhongzheng.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zhongzheng.bo.BatchDelBo;
+import com.zhongzheng.bo.OfficialLinkBo;
+import com.zhongzheng.bo.OfficialLinkQuery;
+import com.zhongzheng.entity.OfficialLink;
+import com.zhongzheng.entity.OfficialSuggest;
+import com.zhongzheng.exception.CustomException;
+import com.zhongzheng.mapper.OfficialLinkMapper;
+import com.zhongzheng.service.IOfficialLinkService;
+import com.zhongzheng.util.DateUtils;
+import com.zhongzheng.vo.OfficialLinkVo;
+import com.zhongzheng.vo.OfficialSuggestVo;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+public class OfficialLinkServiceImpl extends ServiceImpl<OfficialLinkMapper, OfficialLink> implements IOfficialLinkService {
+
+    @Override
+    public boolean addOfficialLink(OfficialLinkBo bo) {
+        OfficialLink bean = BeanUtil.toBean(bo, OfficialLink.class);
+        if (ObjectUtils.isNull(bean.getLinkId())){
+            bean.setCreateTime(DateUtils.getNowTime());
+        }
+        bean.setUpdateTime(DateUtils.getNowTime());
+        return saveOrUpdate(bean);
+    }
+
+    @Override
+    public Page<OfficialLinkVo> listOfficialLink(OfficialLinkQuery query) {
+        Page<OfficialLink> page = page(new Page<>(query.getPageSize(), query.getPageNum()),
+                new LambdaQueryWrapper<OfficialLink>().like(StringUtils.isNotBlank(query.getKeyword()),OfficialLink::getTitle, query.getKeyword()));
+        if (CollectionUtils.isEmpty(page.getRecords())){
+            return new Page<>();
+        }
+        List<OfficialLinkVo> collect = page.getRecords().stream().map(x -> BeanUtil.toBean(x, OfficialLinkVo.class)).collect(Collectors.toList());
+        Page<OfficialLinkVo> result = new Page<>();
+        result.setTotal(page.getTotal());
+        result.setRecords(collect);
+        result.setSize(page.getSize());
+        return result;
+    }
+
+    @Override
+    public boolean delOfficialLink(BatchDelBo bo) {
+        if (CollectionUtils.isEmpty(bo.getIds())){
+            throw new CustomException("不能为空");
+        }
+        return removeByIds(bo.getIds());
+    }
+}

+ 119 - 0
src/main/java/com/zhongzheng/service/impl/OfficialMenuServiceImpl.java

@@ -0,0 +1,119 @@
+package com.zhongzheng.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zhongzheng.bo.OfficialMenuBo;
+import com.zhongzheng.bo.OfficialMenuQuery;
+import com.zhongzheng.bo.SysMenuBo;
+import com.zhongzheng.entity.OfficialMenu;
+import com.zhongzheng.entity.SysMenu;
+import com.zhongzheng.exception.CustomException;
+import com.zhongzheng.mapper.OfficialMenuMapper;
+import com.zhongzheng.service.IOfficialMenuService;
+import com.zhongzheng.util.DateUtils;
+import com.zhongzheng.vo.OfficialMenuVo;
+import com.zhongzheng.vo.SysMenuVo;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+public class OfficialMenuServiceImpl extends ServiceImpl<OfficialMenuMapper, OfficialMenu> implements IOfficialMenuService {
+
+
+    @Override
+    public boolean addOfficialMenu(OfficialMenuBo bo) {
+        if (ObjectUtils.isNotNull(bo.getMenuId())){
+            return editMenu(bo);
+        }
+        int count = count(new LambdaQueryWrapper<OfficialMenu>().eq(OfficialMenu::getName, bo.getName()));
+        if (count > 0) {
+            throw new CustomException("菜单名称重复,请检查");
+        }
+        OfficialMenu bean = BeanUtil.toBean(bo, OfficialMenu.class);
+        bean.setCreateTime(DateUtils.getNowTime());
+        bean.setUpdateTime(DateUtils.getNowTime());
+        return save(bean);
+    }
+
+    @Override
+    public Page<OfficialMenuVo> listOfficialMenu(OfficialMenuQuery query) {
+        //获取一级菜单
+        Page<OfficialMenu> page = page(new Page<>(query.getPageNum(), query.getPageSize()),
+                new LambdaQueryWrapper<OfficialMenu>().eq(OfficialMenu::getParentId, 0)
+                        .orderByAsc(OfficialMenu::getSortNumber));
+        if (CollectionUtils.isEmpty(page.getRecords())){
+            return new Page<>();
+        }
+        List<OfficialMenuVo> collect = page.getRecords().stream().map(item -> {
+            OfficialMenuVo vo = BeanUtil.toBean(item, OfficialMenuVo.class);
+            //递归查询子集
+            getChildren(vo);
+            return vo;
+        }).collect(Collectors.toList());
+        Page<OfficialMenuVo> result = new Page<>();
+        result.setTotal(page.getTotal());
+        result.setRecords(collect);
+        result.setSize(page.getSize());
+        return result;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean editMenu(OfficialMenuBo bo) {
+        OfficialMenu bean = BeanUtil.toBean(bo, OfficialMenu.class);
+        return updateById(bean);
+    }
+
+    @Override
+    public OfficialMenuVo menuIdDetail(Long menuId) {
+        OfficialMenu menu = getById(menuId);
+        return BeanUtil.toBean(menu, OfficialMenuVo.class);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean delOfficialMenu(Long menuId) {
+        //获取改菜单下面所有的子集
+        List<Long> menuIds = new ArrayList<>();
+        menuIds.add(menuId);
+        getChildrenIds(menuIds,menuId);
+        removeByIds(menuIds);
+        return true;
+    }
+
+    private void getChildrenIds(List<Long> menuIds, Long parentId) {
+        List<OfficialMenu> list = list(new LambdaQueryWrapper<OfficialMenu>().eq(OfficialMenu::getParentId, parentId));
+        if (CollectionUtils.isNotEmpty(list)){
+            menuIds.addAll(list.stream().map(OfficialMenu::getMenuId).collect(Collectors.toList()));
+            list.forEach(item -> {
+                getChildrenIds(menuIds,item.getMenuId());
+            });
+        }
+
+    }
+
+
+    private void getChildren(OfficialMenuVo parent) {
+        List<OfficialMenu> list = list(new LambdaQueryWrapper<OfficialMenu>()
+                .eq(OfficialMenu::getParentId, parent.getMenuId())
+                .orderByAsc(OfficialMenu::getSortNumber));
+        if (CollectionUtils.isEmpty(list)){
+            return;
+        }
+        List<OfficialMenuVo> collect = list.stream().map(x -> BeanUtil.toBean(x, OfficialMenuVo.class)).collect(Collectors.toList());
+        parent.setChildList(collect);
+        list.forEach(item -> {
+            getChildren(BeanUtil.toBean(item,OfficialMenuVo.class));
+        });
+    }
+}

+ 63 - 0
src/main/java/com/zhongzheng/service/impl/OfficialProblemServiceImpl.java

@@ -0,0 +1,63 @@
+package com.zhongzheng.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zhongzheng.bo.BatchDelBo;
+import com.zhongzheng.bo.OfficialProblemBo;
+import com.zhongzheng.bo.OfficialProblemQuery;
+import com.zhongzheng.entity.OfficialLink;
+import com.zhongzheng.entity.OfficialProblem;
+import com.zhongzheng.exception.CustomException;
+import com.zhongzheng.mapper.OfficialProblemMapper;
+import com.zhongzheng.service.IOfficialProblemService;
+import com.zhongzheng.util.DateUtils;
+import com.zhongzheng.vo.OfficialLinkVo;
+import com.zhongzheng.vo.OfficialProblemVo;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+public class OfficialProblemServiceImpl extends ServiceImpl<OfficialProblemMapper, OfficialProblem> implements IOfficialProblemService {
+
+    @Override
+    public boolean addOfficialProblem(OfficialProblemBo bo) {
+        OfficialProblem bean = BeanUtil.toBean(bo, OfficialProblem.class);
+        if (ObjectUtils.isNull(bo.getProblemId())){
+            bean.setCreateTime(DateUtils.getNowTime());
+        }
+        bean.setUpdateTime(DateUtils.getNowTime());
+        return saveOrUpdate(bean);
+    }
+
+    @Override
+    public Page<OfficialProblemVo> listOfficialProblem(OfficialProblemQuery query) {
+        Page<OfficialProblem> page = page(new Page<>(query.getPageSize(), query.getPageNum()),
+                new LambdaQueryWrapper<OfficialProblem>().like(StringUtils.isNotBlank(query.getKeyword()),OfficialProblem::getTitle, query.getKeyword()));
+        if (CollectionUtils.isEmpty(page.getRecords())){
+            return new Page<>();
+        }
+        List<OfficialProblemVo> collect = page.getRecords().stream().map(x -> BeanUtil.toBean(x, OfficialProblemVo.class)).collect(Collectors.toList());
+        Page<OfficialProblemVo> result = new Page<>();
+        result.setTotal(page.getTotal());
+        result.setRecords(collect);
+        result.setSize(page.getSize());
+        return result;
+    }
+
+    @Override
+    public boolean delOfficialProblem(BatchDelBo bo) {
+        if (CollectionUtils.isEmpty(bo.getIds())){
+            throw new CustomException("不能为空");
+        }
+        return removeByIds(bo.getIds());
+    }
+}

+ 60 - 0
src/main/java/com/zhongzheng/service/impl/OfficialSuggestServiceImpl.java

@@ -0,0 +1,60 @@
+package com.zhongzheng.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zhongzheng.bo.BatchDelBo;
+import com.zhongzheng.bo.OfficialSuggestBo;
+import com.zhongzheng.bo.OfficialSuggestQuery;
+import com.zhongzheng.entity.OfficialSuggest;
+import com.zhongzheng.exception.CustomException;
+import com.zhongzheng.mapper.OfficialSuggestMapper;
+import com.zhongzheng.service.IOfficialSuggestService;
+import com.zhongzheng.util.DateUtils;
+import com.zhongzheng.vo.OfficialSuggestVo;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+public class OfficialSuggestServiceImpl extends ServiceImpl<OfficialSuggestMapper, OfficialSuggest> implements IOfficialSuggestService {
+
+
+    @Override
+    public boolean addOfficialSuggest(OfficialSuggestBo bo) {
+        OfficialSuggest bean = BeanUtil.toBean(bo, OfficialSuggest.class);
+        bean.setCreateTime(DateUtils.getNowTime());
+        bean.setUpdateTime(DateUtils.getNowTime());
+        return save(bean);
+    }
+
+    @Override
+    public Page<OfficialSuggestVo> listOfficialSuggest(OfficialSuggestQuery query) {
+        Page<OfficialSuggest> page = page(new Page<>(query.getPageSize(), query.getPageNum()),
+                new LambdaQueryWrapper<OfficialSuggest>().like(StringUtils.isNotBlank(query.getKeyword()),OfficialSuggest::getContent, query.getKeyword()));
+        if (CollectionUtils.isEmpty(page.getRecords())){
+            return new Page<>();
+        }
+        List<OfficialSuggestVo> collect = page.getRecords().stream().map(x -> BeanUtil.toBean(x, OfficialSuggestVo.class)).collect(Collectors.toList());
+        Page<OfficialSuggestVo> result = new Page<>();
+        result.setTotal(page.getTotal());
+        result.setRecords(collect);
+        result.setSize(page.getSize());
+        return result;
+    }
+
+    @Override
+    public boolean delOfficialSuggest(BatchDelBo bo) {
+        if (CollectionUtils.isEmpty(bo.getIds())){
+            throw new CustomException("不能为空");
+        }
+        return removeByIds(bo.getIds());
+    }
+}

+ 105 - 0
src/main/java/com/zhongzheng/service/impl/OssServiceImpl.java

@@ -0,0 +1,105 @@
+package com.zhongzheng.service.impl;
+
+import cn.hutool.core.lang.Validator;
+import com.aliyun.oss.OSSClient;
+import com.aliyun.oss.model.PutObjectResult;
+import com.zhongzheng.bo.OssRequest;
+import com.zhongzheng.service.OssService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import java.io.InputStream;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Random;
+
+@Service
+public class OssServiceImpl implements OssService {
+
+    @Value("${aliyun.oss.bucketName}")
+    private String ALIYUN_OSS_BUCKET_NAME;
+    @Value("${aliyun.oss.dir.prefix}")
+    private String ALIYUN_OSS_DIR_PREFIX;
+
+    @Autowired
+    private OSSClient ossClient;
+
+    //生成存储文件名
+    public String generateRandomFilename(OssRequest ossRequest) {
+        String prefixName = "";
+        String RandomFilename = "";
+        //生成随机数
+        Random rand = new Random();
+        int random = rand.nextInt();
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
+        Calendar calCurrent = Calendar.getInstance();
+        int intDay = calCurrent.get(Calendar.DATE);
+        int intMonth = calCurrent.get(Calendar.MONTH) + 1;
+        int intYear = calCurrent.get(Calendar.YEAR);
+        String now = String.valueOf(System.currentTimeMillis());
+
+        RandomFilename = now + String.valueOf(random > 0 ? random : (-1) * random);
+        switch (ossRequest.getImageStatus()) {
+            case 0:
+                RandomFilename = "avatar" + "/" + prefixName + (Validator.isNotEmpty(prefixName) ? "" : (sdf.format(new Date()))) + "/" + now;
+                break;
+            case 1:
+                RandomFilename = "IDNumber" + "/" + prefixName + (Validator.isNotEmpty(prefixName) ? "" : (sdf.format(new Date()))) + "/" + now;
+                break;
+            case 2:
+                RandomFilename = "QuestionBank" + "/" + prefixName + (Validator.isNotEmpty(prefixName) ? "" : (sdf.format(new Date()))) + "/" + now;
+                break;
+            case 3:
+                RandomFilename = "guide" + "/" + prefixName + (Validator.isNotEmpty(prefixName) ? "" : (sdf.format(new Date()))) + "/" + now;
+                break;
+            case 4:
+                RandomFilename = "advertising" + "/" + prefixName + (Validator.isNotEmpty(prefixName) ? "" : (sdf.format(new Date()))) + "/" + now;
+                break;
+        }
+
+        return RandomFilename;
+    }
+
+    @Override
+    public String upload(OssRequest file) {
+        try {
+            //获取上传文件输入流
+            InputStream inputStream = file.getFile().getInputStream();
+            String originalFilename = file.getFile().getOriginalFilename();
+            String suffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
+
+            String fileName = ALIYUN_OSS_DIR_PREFIX + generateRandomFilename(file) + "." + suffix;
+
+            //调用oss方法实现上传
+            //第一个参数  Bucket名称
+            //第二个参数  上传到oss文件路径和文件名称   aa/bb/1.jpg
+            //第三个参数  上传文件输入流
+            PutObjectResult putObjectResult = ossClient.putObject(ALIYUN_OSS_BUCKET_NAME, fileName, inputStream);
+            // 关闭OSSClient。
+            //ossClient.shutdown();
+            return fileName;
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new IllegalStateException("上传失败");
+        }
+    }
+
+    @Override
+    public String uploadWithPath(OssRequest base, String path) throws Exception {
+        try {
+            //获取上传文件输入流
+            InputStream inputStream = base.getFile().getInputStream();
+
+            PutObjectResult putObjectResult = ossClient.putObject(ALIYUN_OSS_BUCKET_NAME, path, inputStream);
+            // 关闭OSSClient。
+            //ossClient.shutdown();
+            return path;
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new IllegalStateException("上传失败");
+        }
+    }
+
+}

+ 71 - 0
src/main/java/com/zhongzheng/service/impl/SysLoginService.java

@@ -0,0 +1,71 @@
+package com.zhongzheng.service.impl;
+
+import com.zhongzheng.exception.CustomException;
+import com.zhongzheng.util.Constants;
+import com.zhongzheng.util.LoginUser;
+import com.zhongzheng.util.RedisCache;
+import com.zhongzheng.util.TokenService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+/**
+ * 登录校验方法
+ *
+ * @author zhongzheng
+ */
+@Component
+public class SysLoginService
+{
+    @Autowired
+    private TokenService tokenService;
+
+    @Resource
+    private AuthenticationManager authenticationManager;
+
+    @Autowired
+    private RedisCache redisCache;
+
+
+    /**
+     * 登录验证
+     *
+     * @param account 用户名
+     * @param password 密码
+     * @param code 验证码
+     * @param uuid 唯一标识
+     * @return 结果
+     */
+    public String login(String account, String password, String code, String uuid)
+    {
+//        String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
+//        String captcha = redisCache.getCacheObject(verifyKey);
+//        redisCache.deleteObject(verifyKey);
+//        if (captcha == null) {
+//            throw new CustomException("验证码错误");
+//        }
+//        if (!code.equalsIgnoreCase(captcha)) {
+//            throw new CustomException("验证码错误");
+//        }
+
+        // 用户验证
+        Authentication authentication = null;
+        try
+        {
+            authentication = authenticationManager
+                    .authenticate(new UsernamePasswordAuthenticationToken(account, password));
+        }
+        catch (Exception e) {
+            e.printStackTrace();
+            throw new CustomException("登入错误");
+        }
+
+        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
+        // 生成token
+        return tokenService.createToken(loginUser);
+    }
+}

+ 90 - 0
src/main/java/com/zhongzheng/service/impl/SysMenuServiceImpl.java

@@ -0,0 +1,90 @@
+package com.zhongzheng.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zhongzheng.bo.SysMenuBo;
+import com.zhongzheng.bo.SysUserQuery;
+import com.zhongzheng.entity.SysMenu;
+import com.zhongzheng.exception.CustomException;
+import com.zhongzheng.mapper.SysMenuMapper;
+import com.zhongzheng.service.ISysMenuService;
+import com.zhongzheng.util.DateUtils;
+import com.zhongzheng.vo.SysMenuVo;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements ISysMenuService {
+
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean addMenu(SysMenuBo bo) {
+        if (ObjectUtils.isNotNull(bo.getMenuId())){
+            return editMenu(bo);
+        }
+        int count = count(new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getName,bo.getName()));
+        if (count > 0) {
+            throw new CustomException("菜单名称已存在,请检查");
+        }
+        SysMenu bean = BeanUtil.toBean(bo, SysMenu.class);
+        bean.setCreateTime(DateUtils.getNowTime());
+        bean.setUpdateTime(DateUtils.getNowTime());
+        return save(bean);
+    }
+
+    @Override
+    public Page<SysMenuVo> listMenu(SysUserQuery query) {
+        //获取一级菜单
+        Page<SysMenu> page = page(new Page<>(query.getPageNum(), query.getPageSize()),
+                new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getParentId, 0));
+        if (CollectionUtils.isEmpty(page.getRecords())){
+            return new Page<>();
+        }
+        List<SysMenuVo> collect = page.getRecords().stream().map(item -> {
+            SysMenuVo vo = BeanUtil.toBean(item, SysMenuVo.class);
+            //递归查询子集
+            getChildren(vo);
+            return vo;
+        }).collect(Collectors.toList());
+        Page<SysMenuVo> result = new Page<>();
+        result.setTotal(page.getTotal());
+        result.setRecords(collect);
+        result.setSize(page.getSize());
+        return result;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean editMenu(SysMenuBo bo) {
+        SysMenu bean = BeanUtil.toBean(bo, SysMenu.class);
+        return updateById(bean);
+    }
+
+    @Override
+    public SysMenuVo menuIdDetail(Long menuId) {
+        SysMenu menu = getById(menuId);
+        return BeanUtil.toBean(menu, SysMenuVo.class);
+    }
+
+    private void getChildren(SysMenuVo parent) {
+        List<SysMenu> list = list(new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getParentId, parent.getMenuId()));
+        if (CollectionUtils.isEmpty(list)){
+            return;
+        }
+        List<SysMenuVo> collect = list.stream().map(x -> BeanUtil.toBean(x, SysMenuVo.class)).collect(Collectors.toList());
+        parent.setChildren(collect);
+        list.forEach(item -> {
+            getChildren(BeanUtil.toBean(item,SysMenuVo.class));
+        });
+    }
+}

+ 18 - 0
src/main/java/com/zhongzheng/service/impl/SysRoleMenuServiceImpl.java

@@ -0,0 +1,18 @@
+package com.zhongzheng.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zhongzheng.entity.SysRoleMenu;
+import com.zhongzheng.entity.SysUser;
+import com.zhongzheng.mapper.SysRoleMenuMapper;
+import com.zhongzheng.mapper.SysUserMapper;
+import com.zhongzheng.service.ISysRoleMenuService;
+import com.zhongzheng.service.ISysUserService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+@Slf4j
+@Service
+public class SysRoleMenuServiceImpl extends ServiceImpl<SysRoleMenuMapper, SysRoleMenu> implements ISysRoleMenuService {
+
+
+}

+ 113 - 0
src/main/java/com/zhongzheng/service/impl/SysRoleServiceImpl.java

@@ -0,0 +1,113 @@
+package com.zhongzheng.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zhongzheng.bo.SysRoleBo;
+import com.zhongzheng.bo.SysUserQuery;
+import com.zhongzheng.entity.SysRole;
+import com.zhongzheng.entity.SysRoleMenu;
+import com.zhongzheng.exception.CustomException;
+import com.zhongzheng.mapper.SysRoleMapper;
+import com.zhongzheng.service.ISysRoleMenuService;
+import com.zhongzheng.service.ISysRoleService;
+import com.zhongzheng.util.DateUtils;
+import com.zhongzheng.vo.SysRoleVo;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements ISysRoleService {
+
+
+    @Autowired
+    private ISysRoleMenuService sysRoleMenuService;
+
+    @Override
+    public boolean addRole(SysRoleBo bo) {
+        if (ObjectUtils.isNotNull(bo.getRoleId())){
+            return editRole(bo);
+        }
+        int count = count(new LambdaQueryWrapper<SysRole>().and(x -> x.eq(SysRole::getRoleName, bo.getRoleName()).or().eq(SysRole::getRoleCode, bo.getRoleCode())));
+        if (count > 0) {
+            throw new CustomException("角色名称或者编码重复,请检查");
+        }
+        SysRole role = BeanUtil.toBean(bo, SysRole.class);
+        role.setCreateTime(DateUtils.getNowTime());
+        role.setUpdateTime(DateUtils.getNowTime());
+        save(role);
+        //添加角色菜单关联信息
+        if (CollectionUtils.isNotEmpty(bo.getMenuIds())){
+            List<SysRoleMenu> collect = bo.getMenuIds().stream().map(item -> {
+                SysRoleMenu sysRoleMenu = new SysRoleMenu();
+                sysRoleMenu.setRoleId(role.getRoleId());
+                sysRoleMenu.setMenuId(item);
+                return sysRoleMenu;
+            }).collect(Collectors.toList());
+            sysRoleMenuService.saveBatch(collect);
+        }
+        return true;
+    }
+
+    @Override
+    public Page<SysRoleVo> listRole(SysUserQuery bo) {
+        Page<SysRole> page = page(new Page<>(bo.getPageNum(), bo.getPageSize()));
+        if (CollectionUtils.isEmpty(page.getRecords())){
+            return new Page<>();
+        }
+        List<SysRoleVo> roleVos = page.getRecords().stream().map(item ->BeanUtil.toBean(item, SysRoleVo.class)).collect(Collectors.toList());
+        Page<SysRoleVo> result = new Page<>();
+        result.setTotal(page.getTotal());
+        result.setRecords(roleVos);
+        result.setSize(page.getSize());
+        return result;
+    }
+
+    @Override
+    public boolean editRole(SysRoleBo bo) {
+        SysRole role = BeanUtil.toBean(bo, SysRole.class);
+        updateById(role);
+        //角色菜单
+        sysRoleMenuService.remove(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getRoleId, role.getRoleId()));
+        List<SysRoleMenu> roleMenus = bo.getMenuIds().stream().map(item -> {
+            SysRoleMenu sysRoleMenu = new SysRoleMenu();
+            sysRoleMenu.setRoleId(role.getRoleId());
+            sysRoleMenu.setMenuId(item);
+            return sysRoleMenu;
+        }).collect(Collectors.toList());
+
+        return sysRoleMenuService.saveBatch(roleMenus);
+    }
+
+    @Override
+    public boolean delRole(Long roleId) {
+        SysRole role = getById(roleId);
+        if (ObjectUtils.isNull(role)){
+            throw new CustomException("用户不存在!");
+        }
+        sysRoleMenuService.remove(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getRoleId, role.getRoleId()));
+        removeById(role);
+        return true;
+    }
+
+    @Override
+    public SysRoleVo roleDetail(Long roleId) {
+        SysRole role = getById(roleId);
+        SysRoleVo vo = BeanUtil.toBean(role, SysRoleVo.class);
+        List<SysRoleMenu> list = sysRoleMenuService.list(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getRoleId, roleId));
+        if (CollectionUtils.isNotEmpty(list)){
+            vo.setMenuIds(list.stream().map(SysRoleMenu::getMenuId).collect(Collectors.toList()));
+        }
+        return vo;
+    }
+
+
+}

+ 18 - 0
src/main/java/com/zhongzheng/service/impl/SysUserRoleServiceImpl.java

@@ -0,0 +1,18 @@
+package com.zhongzheng.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zhongzheng.entity.SysUser;
+import com.zhongzheng.entity.SysUserRole;
+import com.zhongzheng.mapper.SysUserMapper;
+import com.zhongzheng.mapper.SysUserRoleMapper;
+import com.zhongzheng.service.ISysUserRoleService;
+import com.zhongzheng.service.ISysUserService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+@Slf4j
+@Service
+public class SysUserRoleServiceImpl extends ServiceImpl<SysUserRoleMapper, SysUserRole> implements ISysUserRoleService {
+
+
+}

+ 277 - 0
src/main/java/com/zhongzheng/service/impl/SysUserServiceImpl.java

@@ -0,0 +1,277 @@
+package com.zhongzheng.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zhongzheng.bo.SysUserBo;
+import com.zhongzheng.bo.SysUserQuery;
+import com.zhongzheng.bo.UserPwdBo;
+import com.zhongzheng.entity.*;
+import com.zhongzheng.exception.CustomException;
+import com.zhongzheng.mapper.SysUserMapper;
+import com.zhongzheng.service.*;
+import com.zhongzheng.util.DateUtils;
+import com.zhongzheng.util.SecurityUtils;
+import com.zhongzheng.util.ToolsUtils;
+import com.zhongzheng.vo.SysMenuVo;
+import com.zhongzheng.vo.SysUserVo;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {
+
+    @Autowired
+    private ISysUserRoleService userRoleService;
+
+    @Autowired
+    private ISysRoleService sysRoleService;
+
+    @Autowired
+    private ISysRoleMenuService sysRoleMenuService;
+
+    @Autowired
+    private ISysMenuService sysMenuService;
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean addUser(SysUserBo user) {
+        if (ObjectUtils.isNotNull(user.getUserId())){
+            return editUser(user);
+        }
+        int count = count(new LambdaQueryWrapper<SysUser>().eq(SysUser::getAccount, user.getAccount()));
+        if (count > 0) {
+            throw new CustomException("新增用户'" + user.getUserName() + "'失败,登录账号已存在");
+        }
+
+        int count1 = count(new LambdaQueryWrapper<SysUser>().eq(SysUser::getEmail, user.getEmail()));
+        if (count1 > 0) {
+            throw new CustomException("新增用户'" + user.getUserName() + "'失败,邮箱已存在");
+        }
+        if (CollectionUtils.isEmpty(user.getRoleIds())){
+            throw new CustomException("绑定角色不能为空");
+        }
+        SysUser entity = BeanUtil.toBean(user, SysUser.class);
+        entity.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
+        entity.setPasswordAes(user.getPassword());
+        entity.setCreateTime(DateUtils.getNowTime());
+        entity.setUpdateTime(DateUtils.getNowTime());
+        save(entity);
+        //保存用户角色关联关系
+        List<SysUserRole> collect = user.getRoleIds().stream().map(item -> {
+            SysUserRole sysUserRole = new SysUserRole();
+            sysUserRole.setUserId(entity.getUserId());
+            sysUserRole.setRoleId(item);
+            return sysUserRole;
+        }).collect(Collectors.toList());
+        return userRoleService.saveBatch(collect);
+    }
+
+    @Override
+    public Page<SysUserVo> selectUserList(SysUserQuery bo) {
+        Page<SysUser> page = new Page<>();
+         if (ObjectUtils.isNull(bo.getRoleId())){
+             //全部列表
+             page = page(new Page<>(bo.getPageNum(), bo.getPageSize()));
+
+         }else {
+             List<SysUserRole> userRoleList = userRoleService.list(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getRoleId, bo.getRoleId()));
+             if (CollectionUtils.isNotEmpty(userRoleList)){
+                 page = page(new Page<>(bo.getPageNum(), bo.getPageSize()),
+                         new LambdaQueryWrapper<SysUser>().in(SysUser::getUserId, userRoleList.stream().map(SysUserRole::getUserId).collect(Collectors.toList())));
+             }
+         }
+         if (CollectionUtils.isEmpty(page.getRecords())){
+             return new Page<>();
+         }
+         //获取角色
+        List<SysUserVo> userVos = page.getRecords().stream().map(item -> {
+            SysUserVo userVo = BeanUtil.toBean(item, SysUserVo.class);
+            userVo.setPassword(item.getPasswordAes());
+            List<SysUserRole> roleList = userRoleService.list(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, item.getUserId()));
+            if (CollectionUtils.isNotEmpty(roleList)){
+                List<SysRole> sysRoles = sysRoleService.listByIds(roleList.stream().map(SysUserRole::getRoleId).collect(Collectors.toList()));
+                userVo.setRoleIds(sysRoles.stream().map(SysRole::getRoleId).collect(Collectors.toList()));
+                userVo.setRoleName(sysRoles.stream().map(x -> x.getRoleName()).collect(Collectors.joining(",")));
+            }
+            return userVo;
+        }).collect(Collectors.toList());
+
+        Page<SysUserVo> result = new Page<>();
+        result.setTotal(page.getTotal());
+        result.setRecords(userVos);
+        result.setSize(page.getSize());
+        return result;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean editUser(SysUserBo bo) {
+        SysUser user = BeanUtil.toBean(bo, SysUser.class);
+        updateById(user);
+        //用户角色关联关系
+        userRoleService.remove(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, user.getUserId()));
+        List<SysUserRole> userRoleList = bo.getRoleIds().stream().map(item -> {
+            SysUserRole sysUserRole = new SysUserRole();
+            sysUserRole.setUserId(user.getUserId());
+            sysUserRole.setRoleId(item);
+            return sysUserRole;
+        }).collect(Collectors.toList());
+
+        return userRoleService.saveBatch(userRoleList);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean delUser(Long userId) {
+        SysUser user = getById(userId);
+        if (ObjectUtils.isNull(user)){
+            throw new CustomException("用户不存在!");
+        }
+        userRoleService.remove(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, user.getUserId()));
+        removeById(userId);
+        return true;
+    }
+
+    @Override
+    public SysUserVo userDetail(Long userId) {
+        SysUser user = getById(userId);
+        SysUserVo vo = BeanUtil.toBean(user, SysUserVo.class);
+        vo.setPassword(user.getPasswordAes());
+        List<SysUserRole> list = userRoleService.list(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, userId));
+        if (CollectionUtils.isNotEmpty(list)){
+            vo.setRoleIds(list.stream().map(SysUserRole::getRoleId).collect(Collectors.toList()));
+        }
+        return vo;
+    }
+
+    @Override
+    public SysUserVo getUserPermission(Long userId) {
+        SysUser sysUser = getById(userId);
+        if (ObjectUtils.isNull(sysUser)){
+            throw new CustomException("用户获取有误");
+        }
+        SysUserVo vo = BeanUtil.toBean(sysUser, SysUserVo.class);
+        if (sysUser.getUserName().equals("admin")){
+            vo.setButtonL(Arrays.asList("*:*:*"));
+            return vo;
+        }
+        List<SysUserRole> list = userRoleService.list(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, userId));
+        if (CollectionUtils.isNotEmpty(list)){
+            List<Long> roleIds = list.stream().map(SysUserRole::getRoleId).collect(Collectors.toList());
+            vo.setRoleIds(roleIds);
+            //用户菜单权限
+            List<SysRoleMenu> menus = sysRoleMenuService.list(new LambdaQueryWrapper<SysRoleMenu>().in(SysRoleMenu::getRoleId, roleIds));
+            if (CollectionUtils.isNotEmpty(menus)){
+                List<SysMenu> sysMenus = sysMenuService.listByIds(menus.stream().map(SysRoleMenu::getMenuId).collect(Collectors.toList()));
+                if (CollectionUtils.isNotEmpty(sysMenus)){
+                    List<String> perms = sysMenus.stream().filter(x -> StringUtils.isNotBlank(x.getPerms())).map(SysMenu::getPerms).collect(Collectors.toList());
+                    vo.setButtonL(perms);
+                }
+            }
+        }
+        return vo;
+    }
+
+    @Override
+    public List<SysMenuVo> getUserMenu(Long userId) {
+        SysUser sysUser = getById(userId);
+        if (ObjectUtils.isNull(sysUser)){
+            throw new CustomException("用户获取有误");
+        }
+        if ("admin".equals(sysUser.getUserName())){
+            List<SysMenu> sysMenus = sysMenuService.list();
+            List<SysMenuVo> sysMenuVos = new ArrayList<>();
+            for (SysMenu menu : sysMenus) {
+                if (menu.getParentId() == null || menu.getParentId() == 0) {
+                    // 找到顶级节点
+                    SysMenuVo vo = BeanUtil.toBean(menu, SysMenuVo.class);
+                    vo.setChildren(getChildren(menu, sysMenus));
+                    sysMenuVos.add(vo);
+                }
+            }
+            return sysMenuVos;
+        }
+        List<SysUserRole> list = userRoleService.list(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, userId));
+        if (CollectionUtils.isEmpty(list)){
+            return new ArrayList<>();
+        }
+        List<Long> roleIds = list.stream().map(SysUserRole::getRoleId).collect(Collectors.toList());
+        //用户菜单权限
+        List<SysRoleMenu> menus = sysRoleMenuService.list(new LambdaQueryWrapper<SysRoleMenu>().in(SysRoleMenu::getRoleId, roleIds));
+        if (CollectionUtils.isEmpty(menus)){
+            return new ArrayList<>();
+        }
+        List<SysMenu> sysMenus = sysMenuService.listByIds(menus.stream().map(SysRoleMenu::getMenuId).collect(Collectors.toList()));
+        List<SysMenuVo> sysMenuVos = new ArrayList<>();
+        for (SysMenu menu : sysMenus) {
+            if (menu.getParentId() == null || menu.getParentId() == 0) {
+                // 找到顶级节点
+                SysMenuVo vo = BeanUtil.toBean(menu, SysMenuVo.class);
+                vo.setChildren(getChildren(menu, sysMenus));
+                sysMenuVos.add(vo);
+            }
+        }
+        return sysMenuVos;
+    }
+
+    @Override
+    public void initAdmin() {
+        SysUser admin = getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getAccount, "admin"));
+        if (ObjectUtils.isNotNull(admin)){
+            throw new CustomException("admin用户已存在");
+        }
+        SysUser entity = new SysUser();
+        entity.setAccount("admin");
+        entity.setUserName("admin");
+        entity.setPassword(SecurityUtils.encryptPassword("admin123"));
+        entity.setPasswordAes("admin123");
+        entity.setCreateTime(DateUtils.getNowTime());
+        entity.setUpdateTime(DateUtils.getNowTime());
+        save(entity);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean editPassword(UserPwdBo bo) {
+        if (!bo.getNewPwd().equals(bo.getAffirmPwd())){
+            throw new CustomException("二次輸入的密碼不一樣");
+        }
+        SysUser user = SecurityUtils.getLoginUser().getUser();
+        if (ObjectUtils.isNull(user)){
+            throw new CustomException("用戶獲取失敗");
+        }
+        if (!user.getPasswordAes().equals(bo.getOldPwd())){
+            throw new CustomException("舊密碼輸入有誤");
+        }
+        user.setPassword(SecurityUtils.encryptPassword(bo.getAffirmPwd()));
+        user.setPasswordAes(bo.getAffirmPwd());
+        return updateById(user);
+    }
+
+    private List<SysMenuVo> getChildren(SysMenu parent, List<SysMenu> sysMenus) {
+        List<SysMenuVo> children = new ArrayList<>();
+        for (SysMenu menu : sysMenus) {
+            if (parent.getMenuId().equals(menu.getParentId())) {
+                // 递归设置子菜单的子菜单
+                SysMenuVo vo = BeanUtil.toBean(menu, SysMenuVo.class);
+                vo.setChildren(getChildren(menu, sysMenus));
+                children.add(vo);
+            }
+        }
+        return children;
+
+    }
+}

+ 159 - 0
src/main/java/com/zhongzheng/util/AES.java

@@ -0,0 +1,159 @@
+package com.zhongzheng.util;
+
+import org.apache.commons.codec.binary.Base64;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.security.*;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+
+
+public class AES {
+    public static boolean initialized = false;
+
+    /**
+     * AES解密
+     * @param content 密文
+     * @return
+     * @throws InvalidAlgorithmParameterException
+     * @throws NoSuchProviderException
+     */
+    public static byte[] decrypt(byte[] content, byte[] keyByte, byte[] ivByte) throws InvalidAlgorithmParameterException {
+        initialize();
+        try {
+//            Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");
+            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
+            Key sKeySpec = new SecretKeySpec(keyByte, "AES");
+
+            cipher.init(Cipher.DECRYPT_MODE, sKeySpec, generateIV(ivByte));// 初始化
+            byte[] result = cipher.doFinal(content);
+            return result;
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        } catch (NoSuchPaddingException e) {
+            e.printStackTrace();
+        } catch (InvalidKeyException e) {
+            e.printStackTrace();
+        } catch (IllegalBlockSizeException e) {
+            e.printStackTrace();
+        } catch (BadPaddingException e) {
+            e.printStackTrace();
+        } catch (NoSuchProviderException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (Exception e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    public static void initialize(){
+        if (initialized) return;
+        Security.addProvider(new BouncyCastleProvider());
+        initialized = true;
+    }
+    //生成iv
+    public static AlgorithmParameters generateIV(byte[] iv) throws Exception{
+        AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
+        params.init(new IvParameterSpec(iv));
+        return params;
+    }
+
+    public static String SHA1(String decript) {
+        try {
+            MessageDigest digest = MessageDigest.getInstance("SHA-1");
+            digest.update(decript.getBytes());
+            byte messageDigest[] = digest.digest();
+            // Create Hex String
+            StringBuffer hexString = new StringBuffer();
+            // 字节数组转换为 十六进制 数
+            for (int i = 0; i < messageDigest.length; i++) {
+                String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
+                if (shaHex.length() < 2) {
+                    hexString.append(0);
+                }
+                hexString.append(shaHex);
+            }
+            return hexString.toString();
+
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        }
+        return "";
+    }
+
+    /**
+     * RSA公钥加密
+     *
+     * @param str
+     *            加密字符串
+     * @param publicKey
+     *            公钥
+     * @return 密文
+     * @throws Exception
+     *             加密过程中的异常信息
+     */
+    public static String encrypt( String str, String publicKey ) throws Exception{
+        //base64编码的公钥
+        byte[] decoded = Base64.decodeBase64(publicKey);
+        RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
+        //RSA加密
+        Cipher cipher = Cipher.getInstance("RSA");
+        cipher.init(Cipher.ENCRYPT_MODE, pubKey);
+        String outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes("UTF-8")));
+        return outStr;
+    }
+
+    /**
+     * RSA私钥解密
+     *
+     * @param str
+     *            加密字符串
+     * @param privateKey
+     *            私钥
+     * @return 铭文
+     * @throws Exception
+     *             解密过程中的异常信息
+     */
+    public static String decrypt(String str, String privateKey) throws Exception{
+        //64位解码加密后的字符串
+        byte[] inputByte = Base64.decodeBase64(str.getBytes("UTF-8"));
+        //base64编码的私钥
+        byte[] decoded = Base64.decodeBase64(privateKey);
+        RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
+        //RSA解密
+        Cipher cipher = Cipher.getInstance("RSA");
+        cipher.init(Cipher.DECRYPT_MODE, priKey);
+        String outStr = new String(cipher.doFinal(inputByte));
+        return outStr;
+    }
+
+    public static String getStringByInputStream_1(InputStream inputStream){
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        try {
+            byte[] b = new byte[10240];
+            int n;
+            while ((n = inputStream.read(b)) != -1) {
+                outputStream.write(b, 0, n);
+            }
+        } catch (Exception e) {
+            try {
+                inputStream.close();
+                outputStream.close();
+            } catch (Exception e1) {
+            }
+        }
+        return outputStream.toString();
+    }
+}

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor