Browse Source

首次提交

wuweihao 3 years ago
parent
commit
a9ca1d8b1a
100 changed files with 7915 additions and 0 deletions
  1. 17 0
      pom.xml
  2. 60 0
      run.sh
  3. 70 0
      zhoushan-system-api/pom.xml
  4. 22 0
      zhoushan-system-api/src/main/java/com/fdage/ZhoushanSystemApiApplication.java
  5. 14 0
      zhoushan-system-api/src/main/java/com/fdage/aop/WebControllerLog.java
  6. 115 0
      zhoushan-system-api/src/main/java/com/fdage/aop/WebLogAspect.java
  7. 29 0
      zhoushan-system-api/src/main/java/com/fdage/config/InterceptorConfig.java
  8. 190 0
      zhoushan-system-api/src/main/java/com/fdage/controller/ApiController.java
  9. 229 0
      zhoushan-system-api/src/main/java/com/fdage/controller/CollectionController.java
  10. 171 0
      zhoushan-system-api/src/main/java/com/fdage/controller/DataStatisticsController.java
  11. 112 0
      zhoushan-system-api/src/main/java/com/fdage/controller/EquipmentController.java
  12. 289 0
      zhoushan-system-api/src/main/java/com/fdage/controller/ExhibitionController.java
  13. 181 0
      zhoushan-system-api/src/main/java/com/fdage/controller/InformationController.java
  14. 49 0
      zhoushan-system-api/src/main/java/com/fdage/controller/LogController.java
  15. 127 0
      zhoushan-system-api/src/main/java/com/fdage/controller/LoginController.java
  16. 32 0
      zhoushan-system-api/src/main/java/com/fdage/controller/PositionController.java
  17. 39 0
      zhoushan-system-api/src/main/java/com/fdage/controller/ResourceController.java
  18. 183 0
      zhoushan-system-api/src/main/java/com/fdage/controller/RoleController.java
  19. 67 0
      zhoushan-system-api/src/main/java/com/fdage/controller/SceneController.java
  20. 127 0
      zhoushan-system-api/src/main/java/com/fdage/controller/SseController.java
  21. 280 0
      zhoushan-system-api/src/main/java/com/fdage/controller/UserController.java
  22. 67 0
      zhoushan-system-api/src/main/java/com/fdage/controller/VideoController.java
  23. 59 0
      zhoushan-system-api/src/main/java/com/fdage/listner/LoggerInterceptor.java
  24. 93 0
      zhoushan-system-api/src/main/java/com/fdage/listner/Swagger2.java
  25. 164 0
      zhoushan-system-api/src/main/java/com/fdage/shiro/JWTFilter.java
  26. 23 0
      zhoushan-system-api/src/main/java/com/fdage/shiro/JWTToken.java
  27. 73 0
      zhoushan-system-api/src/main/java/com/fdage/shiro/JWTUtil.java
  28. 34 0
      zhoushan-system-api/src/main/java/com/fdage/shiro/JwtAuthenticationException.java
  29. 225 0
      zhoushan-system-api/src/main/java/com/fdage/shiro/JwtUtil2.java
  30. 148 0
      zhoushan-system-api/src/main/java/com/fdage/shiro/MyRealm.java
  31. 156 0
      zhoushan-system-api/src/main/java/com/fdage/shiro/ShiroConfig.java
  32. 676 0
      zhoushan-system-api/src/main/java/com/fdage/util/FileUtil.java
  33. 39 0
      zhoushan-system-api/src/main/java/com/fdage/util/VerifyCodeUtil.java
  34. 70 0
      zhoushan-system-api/src/main/resources/application-dev.yml
  35. 77 0
      zhoushan-system-api/src/main/resources/application-sit.yml
  36. 36 0
      zhoushan-system-api/src/main/resources/application.yml
  37. 156 0
      zhoushan-system-api/src/main/resources/logback-spring.xml
  38. 11 0
      zhoushan-system-api/src/main/resources/sh/shutdown.sh
  39. 12 0
      zhoushan-system-api/src/main/resources/sh/startup.sh
  40. BIN
      zhoushan-system-api/src/main/resources/sh/高淳博物馆后台菜单权限(1).xlsx
  41. BIN
      zhoushan-system-api/src/main/resources/static/collection/importData.xlsx
  42. 123 0
      zhoushan-system-api/src/main/resources/static/index.html
  43. 16 0
      zhoushan-system-api/src/test/java/com/fdage/VirtualHouseApiApplicationTests.java
  44. 208 0
      zhoushan-system-common/pom.xml
  45. 12 0
      zhoushan-system-common/src/main/java/com/fdage/config/CommonConf.java
  46. 72 0
      zhoushan-system-common/src/main/java/com/fdage/constant/ConfigConstant.java
  47. 9 0
      zhoushan-system-common/src/main/java/com/fdage/constant/ConstantExcel.java
  48. 13 0
      zhoushan-system-common/src/main/java/com/fdage/constant/ConstantUrl.java
  49. 22 0
      zhoushan-system-common/src/main/java/com/fdage/constant/MsgCode.java
  50. 51 0
      zhoushan-system-common/src/main/java/com/fdage/dto/ResourceTree.java
  51. 30 0
      zhoushan-system-common/src/main/java/com/fdage/enums/ResponEnum.java
  52. 28 0
      zhoushan-system-common/src/main/java/com/fdage/enums/TypeEnum.java
  53. 15 0
      zhoushan-system-common/src/main/java/com/fdage/request/RequestBase.java
  54. 62 0
      zhoushan-system-common/src/main/java/com/fdage/request/RequestCollection.java
  55. 20 0
      zhoushan-system-common/src/main/java/com/fdage/request/RequestEquipment.java
  56. 32 0
      zhoushan-system-common/src/main/java/com/fdage/request/RequestExhibition.java
  57. 32 0
      zhoushan-system-common/src/main/java/com/fdage/request/RequestInformation.java
  58. 14 0
      zhoushan-system-common/src/main/java/com/fdage/request/RequestLog.java
  59. 24 0
      zhoushan-system-common/src/main/java/com/fdage/request/RequestRole.java
  60. 30 0
      zhoushan-system-common/src/main/java/com/fdage/request/RequestUser.java
  61. 74 0
      zhoushan-system-common/src/main/java/com/fdage/respon/ResponCollection.java
  62. 22 0
      zhoushan-system-common/src/main/java/com/fdage/respon/ResponEquipment.java
  63. 46 0
      zhoushan-system-common/src/main/java/com/fdage/respon/ResponExhibition.java
  64. 36 0
      zhoushan-system-common/src/main/java/com/fdage/respon/ResponInformation.java
  65. 30 0
      zhoushan-system-common/src/main/java/com/fdage/respon/ResponRole.java
  66. 31 0
      zhoushan-system-common/src/main/java/com/fdage/respon/ResponStatistics.java
  67. 30 0
      zhoushan-system-common/src/main/java/com/fdage/respon/ResponUser.java
  68. 129 0
      zhoushan-system-common/src/main/java/com/fdage/util/AccountValidatorUtil.java
  69. 182 0
      zhoushan-system-common/src/main/java/com/fdage/util/AjaxJson.java
  70. 35 0
      zhoushan-system-common/src/main/java/com/fdage/util/BaseRuntimeException.java
  71. 16 0
      zhoushan-system-common/src/main/java/com/fdage/util/ConstantUtils.java
  72. 9 0
      zhoushan-system-common/src/main/java/com/fdage/util/DataMappingUtil.java
  73. 397 0
      zhoushan-system-common/src/main/java/com/fdage/util/DateUtil.java
  74. 122 0
      zhoushan-system-common/src/main/java/com/fdage/util/ExcelUtil.java
  75. 83 0
      zhoushan-system-common/src/main/java/com/fdage/util/FileUtils.java
  76. 49 0
      zhoushan-system-common/src/main/java/com/fdage/util/HTMLSpirit.java
  77. 199 0
      zhoushan-system-common/src/main/java/com/fdage/util/ImportExeclUtil.java
  78. 123 0
      zhoushan-system-common/src/main/java/com/fdage/util/JwtUtil.java
  79. 190 0
      zhoushan-system-common/src/main/java/com/fdage/util/PasswordUtils.java
  80. 106 0
      zhoushan-system-common/src/main/java/com/fdage/util/Result.java
  81. 263 0
      zhoushan-system-common/src/main/java/com/fdage/util/VerifyCodeUtils.java
  82. 90 0
      zhoushan-system-dao/pom.xml
  83. 21 0
      zhoushan-system-dao/src/main/java/com/fdage/dao/base/SceneMapper.java
  84. 17 0
      zhoushan-system-dao/src/main/java/com/fdage/dao/base/TbAuthorityMapper.java
  85. 23 0
      zhoushan-system-dao/src/main/java/com/fdage/dao/base/TbCollectionMapper.java
  86. 17 0
      zhoushan-system-dao/src/main/java/com/fdage/dao/base/TbCollectionTimeMapper.java
  87. 17 0
      zhoushan-system-dao/src/main/java/com/fdage/dao/base/TbCollectionTypeMapper.java
  88. 17 0
      zhoushan-system-dao/src/main/java/com/fdage/dao/base/TbEquipmentMapper.java
  89. 17 0
      zhoushan-system-dao/src/main/java/com/fdage/dao/base/TbExhibitionCollectionMapper.java
  90. 19 0
      zhoushan-system-dao/src/main/java/com/fdage/dao/base/TbExhibitionMapper.java
  91. 17 0
      zhoushan-system-dao/src/main/java/com/fdage/dao/base/TbExhibitionTypeMapper.java
  92. 19 0
      zhoushan-system-dao/src/main/java/com/fdage/dao/base/TbInformationMapper.java
  93. 18 0
      zhoushan-system-dao/src/main/java/com/fdage/dao/base/TbLogMapper.java
  94. 26 0
      zhoushan-system-dao/src/main/java/com/fdage/dao/base/TbMenuMapper.java
  95. 17 0
      zhoushan-system-dao/src/main/java/com/fdage/dao/base/TbPositionMapper.java
  96. 17 0
      zhoushan-system-dao/src/main/java/com/fdage/dao/base/TbResourceMapper.java
  97. 17 0
      zhoushan-system-dao/src/main/java/com/fdage/dao/base/TbRoleMapper.java
  98. 17 0
      zhoushan-system-dao/src/main/java/com/fdage/dao/base/TbUserMapper.java
  99. 22 0
      zhoushan-system-dao/src/main/java/com/fdage/dao/base/VideoMapper.java
  100. 0 0
      zhoushan-system-dao/src/main/java/com/fdage/dao/cust/TbCollectionMapperCust.java

+ 17 - 0
pom.xml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>com.fdage</groupId>
+  <artifactId>museum_zhuhai</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+  <packaging>pom</packaging>
+
+
+  <modules>
+    <module>zhoushan-system-api</module>
+    <module>zhoushan-system-service</module>
+    <module>zhoushan-system-dao</module>
+    <module>zhoushan-system-common</module>
+  </modules>
+</project>

+ 60 - 0
run.sh

@@ -0,0 +1,60 @@
+#!/bin/sh
+APP_NAME=museum_wuzhong_wall.jar
+APP_PORT=8018
+APP_EVN=$2   #执行环境 sit|pro
+APP_ORDER=$1   #执行方法  start|stop|restart
+# 获取进程号
+APP_PID=`netstat -ntpl | grep $APP_PORT | grep LISTEN | awk '{print $7}' | awk -F "/" '{print $1}'`
+
+
+# 启动命令
+startApp(){
+    if [ ${APP_PID} ];
+    then
+    	echo "程序已经在运行了"
+    else
+    	echo "执行 start 方法"
+    	nohup java -jar -Xmx3072M -Xms512M ./$APP_NAME --spring.profiles.active=$APP_EVN --server.port=$APP_PORT > logs.log 2>error.log &  # 说明pid为空
+	echo Start Success!
+fi
+}
+
+# 停止命令
+stopApp(){
+    echo "执行 stop 方法"
+    if [ ${APP_PID} ];
+	then
+		echo $APP_NAME "存在,执行 stop 方法"
+			kill -9 ${APP_PID} && echo 'Kill Process!'
+	else
+		echo $APP_NAME 没有运行
+    fi
+}
+
+# 重启命令
+restartApp(){
+    echo " 1 执行 restart 方法"
+	stopApp
+	APP_PID=''  #将进程号置空
+	sleep 2
+	echo "进程号:" ${APP_PID} 
+	echo " 2 执行 restart 方法"
+	startApp
+}
+
+# 判断执行命令 取第一个参数
+case $APP_ORDER in
+    "start")
+        startApp
+        ;;
+    "stop")
+        stopApp
+        ;;
+	"restart")
+		restartApp
+        ;;
+        *)
+     ;;
+esac
+
+

+ 70 - 0
zhoushan-system-api/pom.xml

@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<groupId>org.springframework.boot</groupId>
+		<artifactId>spring-boot-starter-parent</artifactId>
+		<version>2.0.7.RELEASE</version>
+		<relativePath/> <!-- lookup parent from repository -->
+	</parent>
+	<groupId>com.fdage</groupId>
+	<artifactId>zhoushan-system-api</artifactId>
+	<version>0.0.1-SNAPSHOT</version>
+	<packaging>jar</packaging>
+	<name>zhoushan-system-api</name>
+	<description>Demo project for Spring Boot</description>
+
+	<properties>
+		<java.version>1.8</java.version>
+	</properties>
+
+	<dependencies>
+
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-test</artifactId>
+			<scope>test</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-actuator</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-tomcat</artifactId>
+			<scope>provided</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>com.fdage</groupId>
+			<artifactId>zhoushan-system-service</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+
+		<dependency>
+			<groupId>com.fdage</groupId>
+			<artifactId>zhoushan-system-common</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+
+		<dependency>
+			<groupId>com.github.pagehelper</groupId>
+			<artifactId>pagehelper-spring-boot-starter</artifactId>
+			<version>1.2.3</version>
+		</dependency>
+	</dependencies>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.springframework.boot</groupId>
+				<artifactId>spring-boot-maven-plugin</artifactId>
+			</plugin>
+		</plugins>
+		<finalName>museum_changshu</finalName>
+	</build>
+
+</project>

+ 22 - 0
zhoushan-system-api/src/main/java/com/fdage/ZhoushanSystemApiApplication.java

@@ -0,0 +1,22 @@
+package com.fdage;
+
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+
+@SpringBootApplication(scanBasePackages = "com.fdage.*")
+@MapperScan({"com.fdage.dao.*"})
+public class ZhoushanSystemApiApplication extends SpringBootServletInitializer {
+
+	@Override
+	protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+		return application.sources(ZhoushanSystemApiApplication.class);
+	}
+
+	public static void main(String[] args) {
+		SpringApplication.run(ZhoushanSystemApiApplication.class, args);
+	}
+
+}

+ 14 - 0
zhoushan-system-api/src/main/java/com/fdage/aop/WebControllerLog.java

@@ -0,0 +1,14 @@
+package com.fdage.aop;
+
+import java.lang.annotation.*;
+
+/**
+ * Created by Hb_zzZ on 2020/2/27.
+ */
+@Target({ElementType.PARAMETER, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface WebControllerLog {
+    String description() default "";
+
+}

+ 115 - 0
zhoushan-system-api/src/main/java/com/fdage/aop/WebLogAspect.java

@@ -0,0 +1,115 @@
+package com.fdage.aop;
+
+import com.fdage.pojo.TbLog;
+import com.fdage.service.ILogService;
+import com.fdage.shiro.JwtUtil2;
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.http.HttpServletRequest;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Created by owen on 2020/2/25 0025 9:24
+ */
+@Slf4j
+@Aspect
+@Component
+public class WebLogAspect {
+
+    @Autowired
+    private ILogService logService;
+
+    @Autowired
+    private HttpServletRequest request;
+
+    @Pointcut("@annotation(com.fdage.aop.WebControllerLog)")//切入点描述 这个是controller包的切入点
+    public void controllerLog(){}//签名,可以理解成这个切入点的一个名称
+
+    @Before("controllerLog()") //在切入点的方法run之前要干的
+    public void logBeforeController(JoinPoint joinPoint) throws Exception{
+
+        // 获取token
+        String token = request.getHeader("token");
+        Long userId = null;
+        if (token != null) {
+             userId = JwtUtil2.getUserId(token);
+        }
+
+
+        // 记录下请求内容
+//        log.info("request URL : {}" , request.getRequestURL().toString());
+        log.info("request Method : {}" , request.getMethod());
+        log.info("request IP : {}" , request.getRemoteAddr());
+        log.info("request Args : {}" , Arrays.toString(joinPoint.getArgs()));
+
+        String description = getControllerLogDescription(joinPoint);
+
+        log.info("request description : {}", description);
+
+        //下面这个getSignature().getDeclaringTypeName()是获取包+类名的   然后后面的joinPoint.getSignature.getName()获取了方法名
+        log.info("request Class_Method : {}" , joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
+
+        // 保存数据库
+        List<String> detail = getDetail(description);
+        TbLog logEntity = new TbLog();
+        logEntity.setCreateTime(new Date());
+        logEntity.setType(detail.get(0));
+        logEntity.setDescription(detail.get(1));
+        logEntity.setUserId(userId);
+
+        logService.save(logEntity);
+
+    }
+
+    /**
+     * 获取注解中对方法的描述信息 用于Controller层注解
+     *
+     * @param joinPoint
+     *            切点
+     * @return 方法描述
+     * @throws Exception
+     */
+    public static String getControllerLogDescription(JoinPoint joinPoint) throws Exception {
+        String targetName = joinPoint.getTarget().getClass().getName();
+        String methodName = joinPoint.getSignature().getName();
+        Object[] arguments = joinPoint.getArgs();
+        Class targetClass = Class.forName(targetName);
+        Method[] methods = targetClass.getMethods();
+        String description = "";
+        for (Method method : methods) {
+            if (method.getName().equals(methodName)) {
+                Class[] clazzs = method.getParameterTypes();
+                if (clazzs.length == arguments.length) {
+                    description = method.getAnnotation(WebControllerLog.class).description();
+                    break;
+                }
+            }
+        }
+        return description;
+    }
+
+    private static List<String> getDetail(String str){
+        String[] split = str.split("-");
+        return Arrays.asList(split);
+    }
+
+//    public static void main(String[] args) {
+//        String str = "aaaaaaa-bb";
+//        String[] detail = getDetail(str);
+//        List<String> list = Arrays.asList(detail);
+//
+//
+//        for (String i:detail) {
+//            System.out.println(i);
+//        }
+//    }
+}

+ 29 - 0
zhoushan-system-api/src/main/java/com/fdage/config/InterceptorConfig.java

@@ -0,0 +1,29 @@
+package com.fdage.config;
+
+import com.fdage.listner.LoggerInterceptor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+
+/**
+ * Created by Hb_zzZ on 2018/12/6.
+ */
+@Configuration
+public class InterceptorConfig extends WebMvcConfigurerAdapter {
+
+    @Bean
+    public LoggerInterceptor loggerInterceptor(){
+        return new LoggerInterceptor();
+    }
+
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        //这里可以添加多个拦截器
+        registry.addInterceptor(loggerInterceptor()).addPathPatterns("/**")
+                .excludePathPatterns("/","","/error","/login","/register","/resetPassword");
+        super.addInterceptors(registry);
+    }
+
+
+}

+ 190 - 0
zhoushan-system-api/src/main/java/com/fdage/controller/ApiController.java

@@ -0,0 +1,190 @@
+package com.fdage.controller;
+
+import com.fdage.aop.WebControllerLog;
+import com.fdage.enums.ResponEnum;
+import com.fdage.request.RequestCollection;
+import com.fdage.request.RequestExhibition;
+import com.fdage.request.RequestInformation;
+import com.fdage.respon.ResponCollection;
+import com.fdage.respon.ResponExhibition;
+import com.fdage.respon.ResponInformation;
+import com.fdage.service.ICollectionService;
+import com.fdage.service.IExhibitionService;
+import com.fdage.service.IInformationService;
+import com.fdage.util.AjaxJson;
+import com.fdage.util.DateUtil;
+import com.github.pagehelper.PageInfo;
+import com.github.pagehelper.util.StringUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import java.util.List;
+
+/**
+ * Created by Hb_zzZ on 2020/7/30.
+ */
+@Api(tags = "w-门户网站")
+@Controller
+@RequestMapping("/api")
+@Slf4j
+public class ApiController {
+
+    @Autowired
+    private IInformationService informationService;
+
+    @Autowired
+    private IExhibitionService exhibitionService;
+
+    @Autowired
+    private ICollectionService collectionService;
+
+    @PostMapping("informationList")
+    @ResponseBody
+    @ApiOperation("获取资讯列表")
+    public AjaxJson informationList(){
+        List<ResponInformation> list = informationService.findList(null);
+        for(ResponInformation information : list){
+            if(StringUtils.isNotEmpty(information.getStartTime())){
+                information.setStartTime(String.valueOf(DateUtil.convert2CST(information.getStartTime())));
+            }
+            if(StringUtils.isNotEmpty(information.getEndTime())){
+                information.setEndTime(String.valueOf(DateUtil.convert2CST(information.getEndTime())));
+            }
+            if(StringUtils.isNotEmpty(information.getCreateTime())){
+                information.setCreateTime(String.valueOf(DateUtil.convert2CST(information.getCreateTime())));
+            }
+
+            information.setUrlArray(information.getContentUrl().replace("\"", "").replace("[", "").replace("]", "").split(","));
+        }
+        return AjaxJson.success(list);
+    }
+
+//    @PostMapping("getExhibitionById")
+//    @ResponseBody
+//    @ApiOperation("通过展示方案找文物")
+//    @ApiImplicitParams({
+//            @ApiImplicitParam(name = "exhibitionId", value = "展览方案id", dataType = "String")})
+//    public AjaxJson getExhibitionById(@RequestBody RequestExhibition bo){
+//        if(bo == null || bo.getExhibitionId() == null){
+//            return AjaxJson.failure(ResponEnum.NOT_NULL.getCode(), ResponEnum.NOT_NULL.getMessage());
+//        }
+//
+//        return AjaxJson.success(exhibitionService.getExhibitionById(bo.getExhibitionId()));
+//    }
+
+    @PostMapping("exhibitionList")
+    @ResponseBody
+    @ApiOperation("获取展览方案列表")
+    public AjaxJson exhibitionList(){
+        List<ResponExhibition> list = exhibitionService.findList(null);
+        for(ResponExhibition exhibition : list){
+            exhibition.setCreateTime(String.valueOf(DateUtil.convert2CST(exhibition.getCreateTime())));
+        }
+        return AjaxJson.success(list);
+    }
+
+    @PostMapping("collectionList")
+    @ResponseBody
+    @ApiOperation("获取所有文物列表")
+    public AjaxJson collectionList(){
+        List<ResponCollection> list = collectionService.findList(null);
+        return AjaxJson.success(list);
+    }
+
+    @PostMapping("collectionFindById")
+    @ResponseBody
+    @ApiOperation("查询文物详情")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "文物id", dataType = "String")})
+    public AjaxJson findById(@RequestBody RequestCollection bo){
+        if(bo == null || bo.getId() == null){
+            return AjaxJson.failure(ResponEnum.NOT_NULL.getCode(), ResponEnum.NOT_NULL.getMessage());
+        }
+
+        return AjaxJson.success(collectionService.findById(bo.getId()));
+    }
+
+    @PostMapping("likeCollection")
+    @ResponseBody
+    @ApiOperation("文物点赞")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "文物id", dataType = "String")})
+    public AjaxJson likeCollection(@RequestBody RequestCollection bo){
+        if(bo.getId() == null){
+            return AjaxJson.failure("id不能为空");
+        }
+        collectionService.addLikeNumById(bo.getId());
+        return AjaxJson.success();
+    }
+
+    @PostMapping("getExhibitionById")
+    @ResponseBody
+    @ApiOperation("通过id获取展示方案")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "id", dataType = "String")})
+    public AjaxJson getExhibitionById(@RequestBody RequestExhibition bo){
+        if(bo == null || bo.getId() == null){
+            return AjaxJson.failure(ResponEnum.NOT_NULL.getCode(), ResponEnum.NOT_NULL.getMessage());
+        }
+
+        ResponExhibition responExhibition = exhibitionService.getExhibitionById(bo.getId());
+
+        exhibitionService.addOpenNum(bo.getId());
+        return AjaxJson.success(responExhibition);
+    }
+
+    @PostMapping("typeList")
+    @ResponseBody
+    @ApiOperation("获取文物类别列表")
+    public AjaxJson typeList(){
+        RequestCollection bo = new RequestCollection();
+        bo.setState(0);
+        return AjaxJson.success(collectionService.typeList(bo));
+    }
+
+    @PostMapping("searchCollection")
+    @ResponseBody
+    @ApiOperation("搜索文物")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "展览方案id", dataType = "String"),
+            @ApiImplicitParam(name = "name", value = "文物名称", dataType = "String")})
+    public AjaxJson searchCollection(@RequestBody RequestCollection bo){
+        return AjaxJson.success(collectionService.searchCollection(bo));
+    }
+
+    @PostMapping("addSearchNum")
+    @ResponseBody
+    @ApiOperation("增加文物搜索次数")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "文物id", dataType = "String")})
+    public AjaxJson addSearchNum(@RequestBody RequestCollection bo){
+        if(bo.getId() == null){
+            return AjaxJson.failure("id不能为空");
+        }
+        collectionService.addSearchNum(bo.getId());
+        return AjaxJson.success();
+    }
+
+    @PostMapping("addDownloadNum")
+    @ResponseBody
+    @ApiOperation("增加文物下载次数")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "文物id", dataType = "String")})
+    public AjaxJson addDownloadNum(@RequestBody RequestCollection bo){
+        if(bo.getId() == null){
+            return AjaxJson.failure("id不能为空");
+        }
+        collectionService.addDownloadNum(bo.getId());
+        return AjaxJson.success();
+    }
+}

+ 229 - 0
zhoushan-system-api/src/main/java/com/fdage/controller/CollectionController.java

@@ -0,0 +1,229 @@
+package com.fdage.controller;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.collection.ListUtil;
+import cn.hutool.core.util.StrUtil;
+import com.fdage.aop.WebControllerLog;
+import com.fdage.constant.ConfigConstant;
+import com.fdage.constant.ConstantUrl;
+import com.fdage.enums.ResponEnum;
+import com.fdage.pojo.TbCollection;
+import com.fdage.request.RequestCollection;
+import com.fdage.respon.ResponCollection;
+import com.fdage.service.ICollectionService;
+import com.fdage.util.AjaxJson;
+import com.fdage.util.FileUtil;
+import com.github.pagehelper.PageInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+
+/**
+ * Created by Hb_zzZ on 2019/9/11.
+ */
+@Api(tags = "文物库模块")
+@Controller
+@RequestMapping("/zhoushan/collection")
+@Slf4j
+public class CollectionController {
+
+    @Autowired
+    private ICollectionService service;
+
+    @Value("${upload.collection}")
+    private String uploadPath;
+
+    @Autowired
+    ConfigConstant configConstant;
+
+    @PostMapping("timeList")
+    @ResponseBody
+    @ApiOperation("获取年代列表")
+    public AjaxJson timeList(){
+        return AjaxJson.success(service.timeList());
+    }
+
+    @PostMapping("typeList")
+    @ResponseBody
+    @ApiOperation("获取文物类别列表")
+    public AjaxJson typeList(@RequestBody RequestCollection bo){
+        return AjaxJson.success(service.typeList(bo));
+    }
+
+    @PostMapping("addCollection")
+    @ResponseBody
+    @WebControllerLog(description = "文物库-新增文物")
+    @ApiOperation("新增文物")
+//    @ApiImplicitParams({
+//            @ApiImplicitParam(name = "name", value = "文物名称", dataType = "String"),
+//            @ApiImplicitParam(name = "description", value = "文物描述", dataType = "String"),
+//            @ApiImplicitParam(name = "timeId", value = "年代id", dataType = "String"),
+//            @ApiImplicitParam(name = "typeId", value = "类型id", dataType = "String"),
+//            @ApiImplicitParam(name = "modelUrl", value = "文物模型url", dataType = "String"),
+//            @ApiImplicitParam(name = "discoveryTime", value = "文物发现时间", dataType = "String"),
+//            @ApiImplicitParam(name = "repairTime", value = "文物维修时间", dataType = "String"),
+//            @ApiImplicitParam(name = "venue", value = "文物所在场馆", dataType = "String"),
+//            @ApiImplicitParam(name = "contentUrl", value = "多媒体内容Url", dataType = "String"),
+//            @ApiImplicitParam(name = "pic", value = "4dmodel文物的封面图", dataType = "String"),
+//            @ApiImplicitParam(name = "num", value = "藏品编号", dataType = "String"),
+//            @ApiImplicitParam(name = "state", value = "状态,0:展示,1:隐藏", dataType = "String")})
+    public AjaxJson addCollection(@RequestBody RequestCollection bo){
+        if(bo == null || StringUtils.isEmpty(bo.getName())  ||
+                bo.getTimeId() == null  || bo.getTypeId() == null){
+            return AjaxJson.failure(ResponEnum.NOT_NULL.getCode(), ResponEnum.NOT_NULL.getMessage());
+        }
+
+        TbCollection collection = new TbCollection();
+        BeanUtils.copyProperties(bo, collection);
+//        collection.setTypeImages(convertTypeImages(bo.getTypeImages()));
+        collection.setUnityUrl("/collection/unity/" + bo.getDirCode());
+//        collection.setUnityUrl(configConstant.serverBasePath + "/collection/unity/" + bo.getDirCode());
+        service.insert(collection);
+        return AjaxJson.success();
+    }
+
+    @PostMapping("updateCollection")
+    @ResponseBody
+    @WebControllerLog(description = "文物库-修改文物")
+    @ApiOperation("修改文物")
+    public AjaxJson updateCollection(@RequestBody RequestCollection bo){
+        if(bo == null || StringUtils.isEmpty(bo.getName()) ||
+                bo.getTimeId() == null  || bo.getTypeId() == null ){
+            return AjaxJson.failure(ResponEnum.NOT_NULL.getCode(), ResponEnum.NOT_NULL.getMessage());
+        }
+
+        TbCollection collection = new TbCollection();
+        BeanUtils.copyProperties(bo, collection);
+        service.update(collection);
+        return AjaxJson.success();
+    }
+
+
+
+    @PostMapping("deleteCollection")
+    @ResponseBody
+    @WebControllerLog(description = "文物库-删除文物")
+    @ApiOperation("删除文物")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "文物id", dataType = "String")})
+    public AjaxJson deleteCollection(@RequestBody RequestCollection bo){
+        if(bo == null || bo.getId() == null){
+            return AjaxJson.failure(ResponEnum.NOT_NULL.getCode(), ResponEnum.NOT_NULL.getMessage());
+        }
+        service.deleteById(bo.getId());
+        return AjaxJson.success();
+    }
+
+    @PostMapping("findById")
+    @ResponseBody
+    @WebControllerLog(description = "文物库-查询文物库详情")
+    @ApiOperation("查询文物库详情")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "文物id", dataType = "String")})
+    public AjaxJson findById(@RequestBody RequestCollection bo){
+        if(bo == null || bo.getId() == null){
+            return AjaxJson.failure(ResponEnum.NOT_NULL.getCode(), ResponEnum.NOT_NULL.getMessage());
+        }
+
+        return AjaxJson.success(service.findById(bo.getId()));
+    }
+
+    @PostMapping("list")
+    @ResponseBody
+    @WebControllerLog(description = "文物库-获取文物列表")
+    @ApiOperation("获取文物列表")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "timeId", value = "年代id", dataType = "String"),
+            @ApiImplicitParam(name = "typeId", value = "类型id", dataType = "String"),
+            @ApiImplicitParam(name = "name", value = "文物名称", dataType = "String"),
+            @ApiImplicitParam(name = "pageNum", value = "页码", dataType = "String"),
+            @ApiImplicitParam(name = "pageSize", value = "每页数量", dataType = "String")})
+    public AjaxJson list(@RequestBody RequestCollection bo){
+        List<ResponCollection> list = service.findList(bo);
+        PageInfo<ResponCollection> pageInfo = new PageInfo<>(list);
+        return AjaxJson.success(pageInfo);
+    }
+
+    @PostMapping("/upload")
+    @ResponseBody
+    @ApiOperation("上传文物图片")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "file", value = "文件流", dataType = "String")})
+    public AjaxJson upload(@RequestParam(value = "filename", defaultValue = "") String name, @RequestParam("file") MultipartFile file){
+        if(file == null){
+            return AjaxJson.failure("参数不能为空");
+        }
+        String fileName = System.currentTimeMillis() + "_";
+        if(StringUtils.isNotEmpty(name)){
+            fileName = fileName + name;
+        }else {
+            fileName = fileName + file.getOriginalFilename();
+        }
+        log.info("图片地址:" + fileName);
+        boolean flag = FileUtil.upload(file, uploadPath, fileName);
+
+        if(!flag){
+            return AjaxJson.failure("上传图片失败");
+        }
+
+//        Map<String, String> map = new HashMap<>();
+//        map.put(path + "/" + fileName, "company/" + fileName);
+//        uploadToAlibabaService.upload(map);
+
+        return AjaxJson.success((Object) ("/collection/" + fileName));
+    }
+
+
+    /**
+     * 2021-08-09
+     * @param file
+     * @param code
+     * @return
+     */
+    @PostMapping("/uploadCode")
+    @ApiOperation("上传Unity")
+    @ResponseBody
+    public AjaxJson uploadCode(MultipartFile file, String code){
+
+        return service.uploadCode(file, code);
+    }
+
+
+    @PostMapping("/importCollection")
+    @ResponseBody
+    @ApiOperation("导入文物Excel")
+    public AjaxJson importCollection(@RequestParam("file") MultipartFile file){
+        if(file == null){
+            return AjaxJson.failure("参数不能为空");
+        }
+        String fileName = System.currentTimeMillis() + "_" +  file.getOriginalFilename();
+        log.info("导入文件保存地址:" + fileName);
+        boolean flag = FileUtil.upload(file, uploadPath, fileName);
+
+        if(!flag){
+            return AjaxJson.failure("导入文物数据失败");
+        }
+
+        return service.importCollection(uploadPath + "/" + fileName);
+    }
+
+
+
+    @GetMapping("addVisit/{id}")
+    @ResponseBody
+    @ApiOperation("保存访问量")
+    public AjaxJson addVisit(@PathVariable Long id){
+        return service.addVisit(id);
+    }
+}

+ 171 - 0
zhoushan-system-api/src/main/java/com/fdage/controller/DataStatisticsController.java

@@ -0,0 +1,171 @@
+//package com.fdage.controller;
+//
+//import com.fdage.constant.ConstantExcel;
+//import com.fdage.respon.ResponCollection;
+//import com.fdage.respon.ResponStatistics;
+//import com.fdage.service.ICollectionService;
+//import com.fdage.service.IExhibitionService;
+//import com.fdage.util.AjaxJson;
+//import com.fdage.util.ExcelUtil;
+//import io.swagger.annotations.Api;
+//import io.swagger.annotations.ApiOperation;
+//import lombok.extern.slf4j.Slf4j;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.beans.factory.annotation.Value;
+//import org.springframework.stereotype.Controller;
+//import org.springframework.web.bind.annotation.PostMapping;
+//import org.springframework.web.bind.annotation.RequestMapping;
+//import org.springframework.web.bind.annotation.ResponseBody;
+//
+//import javax.servlet.http.HttpServletRequest;
+//import javax.servlet.http.HttpServletResponse;
+//import java.io.*;
+//import java.net.URLEncoder;
+//import java.text.DateFormat;
+//import java.text.SimpleDateFormat;
+//import java.util.*;
+//
+///**
+// * Created by Hb_zzZ on 2020/9/8.
+// */
+//@Api(tags = "数据统计模块")
+//@Controller
+//@RequestMapping("/zhoushan/statistics")
+//@Slf4j
+//public class DataStatisticsController {
+//
+//    @Autowired
+//    private IExhibitionService exhibitionService;
+//
+//    @Autowired
+//    private ICollectionService collectionService;
+//
+//    @Value("${upload.collection}")
+//    private String collectionPath;
+//
+//    @PostMapping("collectionTotal")
+//    @ResponseBody
+//    @ApiOperation("数据总量")
+//    public AjaxJson collectionTotal(){
+//        return AjaxJson.success(collectionService.findList(null));
+//    }
+//
+//    @PostMapping("exportCollectionTotal")
+//    @ResponseBody
+//    @ApiOperation("数据总量")
+//    public void exportCollectionTotal(HttpServletRequest request, HttpServletResponse response){
+//        List<ResponCollection> list = collectionService.findList(null);
+//
+//        //导出的数据
+//        int serNum = 1;
+//        Map<String, Object> item = null;
+//        List<Map> dataList = new ArrayList<Map>();
+//
+//        for(ResponCollection collection : list){
+//            item = new HashMap();
+//            item.put(ConstantExcel.COLLECTION_NAME[0], String.valueOf(serNum));
+//            item.put(ConstantExcel.COLLECTION_NAME[1], collection.getName());
+//            item.put(ConstantExcel.COLLECTION_NAME[2], collection.getTypeName());
+//            item.put(ConstantExcel.COLLECTION_NAME[3], collection.getTimeName());
+//            item.put(ConstantExcel.COLLECTION_NAME[4], collection.getLikeNum());
+//            item.put(ConstantExcel.COLLECTION_NAME[5], collection.getDownloadNum());
+//            item.put(ConstantExcel.COLLECTION_NAME[6], collection.getSearchNum());
+//
+//            serNum++;
+//            dataList.add(item);
+//        }
+//
+//        try{
+//            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+//            String dateStr = dateFormat.format(new Date());
+//            String fileName = "文物数据-" + dateStr + ".xls";
+//            File file = new File(collectionPath + File.separator + fileName + ".xls");
+//
+//            ExcelUtil.writeExcel(dataList, collectionPath + File.separator + fileName + ".xls");
+//
+//            String agent = request.getHeader("User-Agent");
+//            if (agent != null && (agent.contains("MSIE")||agent.contains("Trident"))) {
+//                fileName = URLEncoder.encode(fileName, "UTF-8");
+//            } else {
+//                //非IE浏览器的处理:
+//                fileName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");
+//            }
+//            response.setHeader("Content-Disposition", "attachment; filename=\""+fileName+"\"");
+//            response.setContentType(request.getServletContext().getMimeType(fileName));
+//            response.setContentLength((int) file.length());
+//            output(response, file);
+//        }catch (Exception e){
+//            e.printStackTrace();
+//        }
+//    }
+//
+//    @PostMapping("total")
+//    @ResponseBody
+//    @ApiOperation("数据总量")
+//    public AjaxJson total(){
+//
+//        ResponStatistics result = collectionService.collectionTotal();
+//
+//        // 2021-08-16 by owen 改用流量量
+////        Long exhibitionTotal = exhibitionService.exhibitionTotal();
+//        Long exhibitionTotal = collectionService.countVisit();
+//
+//
+//
+//        result.setExhibitionTotal(exhibitionTotal);
+//
+//        result.setExhibitionList(exhibitionService.findListOrderBy());
+//
+//        Map<String, String> map = new HashMap<>();
+//        map.put("order", "desc");
+//        map.put("sidx", "a.search_num");
+////        result.setCollectionSearchList(collectionService.findListOrderBy(map).subList(0, 5));
+//
+//        List<ResponCollection> listOrderBy = collectionService.findListOrderBy(map);
+//        int max = listOrderBy.size() > 5 ? 5 : listOrderBy.size();
+//        result.setCollectionSearchList(listOrderBy.subList(0, max));
+//
+//
+//
+//
+//        map.put("sidx", "a.like_num");
+////        result.setCollectionLikeList(collectionService.findListOrderBy(map).subList(0, 10));
+//
+//        List<ResponCollection> listOrderBy2 = collectionService.findListOrderBy(map);
+//        int max2 = listOrderBy2.size() > 10 ? 10 : listOrderBy2.size();
+//        result.setCollectionLikeList(listOrderBy2.subList(0, max2));
+//        map.put("sidx", "a.open_num");
+////        result.setCollectionOpenList(collectionService.findListOrderBy(map).subList(0, 3));
+//        List<ResponCollection> list3 = collectionService.findListOrderBy(map);
+//        int max3 = listOrderBy2.size() > 3 ? 3 : listOrderBy2.size();
+//
+//        result.setCollectionOpenList(list3.subList(0, max3));
+//
+//        result.setCollectionTypeTotal(collectionService.typeTotal());
+//
+//        return AjaxJson.success(result);
+//    }
+//
+//    private static void output(HttpServletResponse resp, File file) {
+//        OutputStream os = null;
+//        BufferedInputStream bis = null;
+//        byte[] buff = new byte[1024];
+//        try {
+//            os = resp.getOutputStream();
+//            bis = new BufferedInputStream(new FileInputStream(file));
+//            int i = 0;
+//            while ((i = bis.read(buff)) != -1) {
+//                os.write(buff, 0, i);
+//                os.flush();
+//            }
+//        } catch (IOException e) {
+//            e.printStackTrace();
+//        } finally {
+//            try {
+//                bis.close();
+//            } catch (IOException e) {
+//                e.printStackTrace();
+//            }
+//        }
+//    }
+//}

+ 112 - 0
zhoushan-system-api/src/main/java/com/fdage/controller/EquipmentController.java

@@ -0,0 +1,112 @@
+//package com.fdage.controller;
+//
+//import com.fdage.aop.WebControllerLog;
+//import com.fdage.enums.ResponEnum;
+//import com.fdage.pojo.TbEquipment;
+//import com.fdage.pojo.TbUser;
+//import com.fdage.request.RequestEquipment;
+//import com.fdage.request.RequestUser;
+//import com.fdage.respon.ResponEquipment;
+//import com.fdage.service.IEquipmentService;
+//import com.fdage.util.AjaxJson;
+//import com.fdage.util.PasswordUtils;
+//import com.github.pagehelper.PageInfo;
+//import io.swagger.annotations.Api;
+//import io.swagger.annotations.ApiImplicitParam;
+//import io.swagger.annotations.ApiImplicitParams;
+//import io.swagger.annotations.ApiOperation;
+//import lombok.extern.slf4j.Slf4j;
+//import org.apache.commons.lang3.StringUtils;
+//import org.springframework.beans.BeanUtils;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.stereotype.Controller;
+//import org.springframework.web.bind.annotation.PostMapping;
+//import org.springframework.web.bind.annotation.RequestBody;
+//import org.springframework.web.bind.annotation.RequestMapping;
+//import org.springframework.web.bind.annotation.ResponseBody;
+//
+//import java.util.List;
+//
+///**
+// * Created by Hb_zzZ on 2019/9/11.
+// */
+//@Controller
+//@RequestMapping("/zhoushan/equipment")
+//@Slf4j
+//@Api(tags = "设备管理模块")
+//public class EquipmentController {
+//
+//    @Autowired
+//    private IEquipmentService service;
+//
+//    @PostMapping("addEquipment")
+//    @ResponseBody
+//    @WebControllerLog(description = "设备管理-新增设备")
+//    @ApiOperation("新增设备")
+//    @ApiImplicitParams({
+//            @ApiImplicitParam(name = "name", value = "设备名称", dataType = "String"),
+//            @ApiImplicitParam(name = "uuid", value = "设备id", dataType = "String"),
+//            @ApiImplicitParam(name = "positionId", value = "位置id", dataType = "String"),
+//            @ApiImplicitParam(name = "state", value = "状态,0:启用,1:禁用", dataType = "String")})
+//    public AjaxJson addEquipment(@RequestBody RequestEquipment bo){
+//        if(bo == null || StringUtils.isEmpty(bo.getName()) || bo.getPositionId() == null ||
+//                StringUtils.isEmpty(bo.getUuid()) || bo.getState() == null){
+//            return AjaxJson.failure(ResponEnum.NOT_NULL.getCode(), ResponEnum.NOT_NULL.getMessage());
+//        }
+//        TbEquipment equipment = new TbEquipment();
+//        BeanUtils.copyProperties(bo, equipment);
+//        service.insert(equipment);
+//        return AjaxJson.success();
+//    }
+//
+//    @PostMapping("updateEquipment")
+//    @ResponseBody
+//    @WebControllerLog(description = "设备管理-修改设备")
+//    @ApiOperation("修改设备")
+//    @ApiImplicitParams({
+//            @ApiImplicitParam(name = "id", value = "文物id", dataType = "String"),
+//            @ApiImplicitParam(name = "name", value = "设备名称", dataType = "String"),
+//            @ApiImplicitParam(name = "uuid", value = "设备id", dataType = "String"),
+//            @ApiImplicitParam(name = "positionId", value = "位置id", dataType = "String"),
+//            @ApiImplicitParam(name = "state", value = "状态,0:启用,1:禁用", dataType = "String")})
+//    public AjaxJson updateEquipment(@RequestBody RequestEquipment bo){
+//        if(bo == null || StringUtils.isEmpty(bo.getName()) || bo.getPositionId() == null ||
+//                StringUtils.isEmpty(bo.getUuid()) || bo.getState() == null || bo.getId() == null){
+//            return AjaxJson.failure(ResponEnum.NOT_NULL.getCode(), ResponEnum.NOT_NULL.getMessage());
+//        }
+//        TbEquipment equipment = new TbEquipment();
+//        BeanUtils.copyProperties(bo, equipment);
+//        service.update(equipment);
+//        return AjaxJson.success();
+//    }
+//
+//    @PostMapping("updateState")
+//    @ResponseBody
+//    @WebControllerLog(description = "设备管理-设备启用/停用")
+//    @ApiOperation("设备启用/停用")
+//    @ApiImplicitParams({
+//            @ApiImplicitParam(name = "id", value = "文物id", dataType = "String"),
+//            @ApiImplicitParam(name = "state", value = "状态,0:启用,1:禁用", dataType = "String")})
+//    public AjaxJson updateState(@RequestBody RequestEquipment bo){
+//        if(bo == null || bo.getState() == null || bo.getId() == null){
+//            return AjaxJson.failure(ResponEnum.NOT_NULL.getCode(), ResponEnum.NOT_NULL.getMessage());
+//        }
+//        TbEquipment equipment = new TbEquipment();
+//        BeanUtils.copyProperties(bo, equipment);
+//        service.update(equipment);
+//        return AjaxJson.success();
+//    }
+//
+//    @PostMapping("list")
+//    @ResponseBody
+//    @WebControllerLog(description = "设备管理-获取设备列表")
+//    @ApiOperation("获取设备列表")
+//    @ApiImplicitParams({
+//            @ApiImplicitParam(name = "pageNum", value = "页码", dataType = "String"),
+//            @ApiImplicitParam(name = "pageSize", value = "每页数量", dataType = "String")})
+//    public AjaxJson list(@RequestBody RequestEquipment bo){
+//        List<ResponEquipment> list = service.findList(bo);
+//        PageInfo<ResponEquipment> pageInfo = new PageInfo<>(list);
+//        return AjaxJson.success(pageInfo);
+//    }
+//}

+ 289 - 0
zhoushan-system-api/src/main/java/com/fdage/controller/ExhibitionController.java

@@ -0,0 +1,289 @@
+package com.fdage.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fdage.aop.WebControllerLog;
+import com.fdage.enums.ResponEnum;
+import com.fdage.pojo.TbExhibition;
+import com.fdage.pojo.TbExhibitionCollection;
+import com.fdage.request.RequestCollection;
+import com.fdage.request.RequestExhibition;
+import com.fdage.respon.ResponExhibition;
+import com.fdage.respon.ResponInformation;
+import com.fdage.service.IExhibitionService;
+import com.fdage.util.AjaxJson;
+import com.fdage.util.DateUtil;
+import com.fdage.util.FileUtil;
+import com.github.pagehelper.PageInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Controller;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import springfox.documentation.annotations.ApiIgnore;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Created by Hb_zzZ on 2019/9/12.
+ */
+@ApiIgnore
+@Controller
+@RequestMapping("/zhoushan/exhibition")
+@Slf4j
+@Api(tags = "展示管理模块")
+public class ExhibitionController {
+
+    @Value("${upload.exhibition}")
+    private String uploadPath;
+
+    @Autowired
+    private IExhibitionService service;
+
+    @PostMapping("insertExhibitionCollection")
+    @ResponseBody
+    @ApiOperation("新增展览方案-推送给文通")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "exhibitionId", value = "展览id", dataType = "String"),
+            @ApiImplicitParam(name = "collectionId", value = "文物id", dataType = "String")})
+    public AjaxJson insertExhibitionCollection(@RequestBody RequestExhibition bo){
+        if(bo == null || bo.getExhibitionId() == null || StringUtils.isEmpty(bo.getCollectionId())){
+
+//        if(bo == null || bo.getExhibitionId() == null){
+            return AjaxJson.failure(ResponEnum.NOT_NULL.getCode(), ResponEnum.NOT_NULL.getMessage());
+        }
+        String[] ids = bo.getCollectionId().split(",");
+
+        TbExhibitionCollection exhibitionCollection = new TbExhibitionCollection();
+        for(int i = 0, len = ids.length; i < len; i++){
+            exhibitionCollection.setExhibitionId(bo.getExhibitionId());
+            // 2021-08-16 by owen
+//            if (ids.length > 1) {
+//                exhibitionCollection.setCollectionId(Long.valueOf(ids[i]));
+//            }
+            exhibitionCollection.setCollectionId(Long.valueOf(ids[i]));
+            service.insertExhibitionCollection(exhibitionCollection);
+        }
+
+        //发送sse消息
+        SseController.send("data:" + "0\r\n");
+        return AjaxJson.success();
+    }
+
+    @PostMapping("updateExhibitionCollection")
+    @ResponseBody
+    @ApiOperation("修改展览方案-推送给文通")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "exhibitionId", value = "展览id", dataType = "String"),
+            @ApiImplicitParam(name = "collectionId", value = "文物id", dataType = "String")})
+    public AjaxJson updateExhibitionCollection(@RequestBody RequestExhibition bo){
+        if(bo == null || bo.getExhibitionId() == null || StringUtils.isEmpty(bo.getCollectionId())){
+            return AjaxJson.failure(ResponEnum.NOT_NULL.getCode(), ResponEnum.NOT_NULL.getMessage());
+        }
+
+        service.deleteExhibitionCollection(bo.getExhibitionId());
+
+
+        String[] ids = bo.getCollectionId().split(",");
+        TbExhibitionCollection exhibitionCollection = new TbExhibitionCollection();
+        for(int i = 0, len = ids.length; i < len; i++){
+            exhibitionCollection.setExhibitionId(bo.getExhibitionId());
+            exhibitionCollection.setCollectionId(Long.valueOf(ids[i]));
+            service.insertExhibitionCollection(exhibitionCollection);
+        }
+
+        //发送sse消息
+        SseController.send("data:" + "0\r\n");
+        return AjaxJson.success();
+    }
+
+    @PostMapping("addExhibition")
+    @ResponseBody
+    @WebControllerLog(description = "展示管理-新增展览方案")
+    @ApiOperation("新增展览方案")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "name", value = "展览方案名称", dataType = "String"),
+            @ApiImplicitParam(name = "exhibitionId", value = "展览id", dataType = "String"),
+            @ApiImplicitParam(name = "equipmentId", value = "关联设备id", dataType = "String"),
+            @ApiImplicitParam(name = "webUrl", value = "展示封面", dataType = "String"),
+            @ApiImplicitParam(name = "state", value = "状态,0:启用,1:禁用", dataType = "String")})
+    public AjaxJson addExhibition(@RequestBody RequestExhibition bo){
+        if(bo == null || StringUtils.isEmpty(bo.getName()) || bo.getTypeId() == null || bo.getState() == null){
+            return AjaxJson.failure(ResponEnum.NOT_NULL.getCode(), ResponEnum.NOT_NULL.getMessage());
+        }
+
+        TbExhibition exhibition = new TbExhibition();
+        BeanUtils.copyProperties(bo, exhibition);
+        service.insert(exhibition);
+        return AjaxJson.success(exhibition);
+    }
+
+    @PostMapping("updateExhibition")
+    @ResponseBody
+    @WebControllerLog(description = "展示管理-修改展览方案")
+    @ApiOperation("修改展览方案")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "isSend", value = "是否推送给问题,1推送", dataType = "String"),
+            @ApiImplicitParam(name = "id", value = "展览方案id", dataType = "String"),
+            @ApiImplicitParam(name = "name", value = "展览方案名称", dataType = "String"),
+            @ApiImplicitParam(name = "exhibitionId", value = "展览id", dataType = "String"),
+            @ApiImplicitParam(name = "equipmentId", value = "关联设备id", dataType = "String"),
+            @ApiImplicitParam(name = "state", value = "状态,0:启用,1:禁用", dataType = "String")})
+    public AjaxJson updateExhibition(@RequestBody RequestExhibition bo){
+        if(bo == null || StringUtils.isEmpty(bo.getName()) || bo.getTypeId() == null || bo.getState() == null){
+            return AjaxJson.failure(ResponEnum.NOT_NULL.getCode(), ResponEnum.NOT_NULL.getMessage());
+        }
+
+        TbExhibition exhibition = new TbExhibition();
+        BeanUtils.copyProperties(bo, exhibition);
+        exhibition.setCreateTime(new Date());
+        service.update(exhibition);
+        if(bo.getIsSend() != null && bo.getIsSend() == 1){
+            //发送sse消息
+            SseController.send("data:" + "0\r\n");
+        }
+        return AjaxJson.success(exhibition);
+    }
+
+    @PostMapping("deleteExhibition")
+    @ResponseBody
+    @WebControllerLog(description = "展示管理-删除展览方案")
+    @ApiOperation("删除展览方案")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "展览方案id", dataType = "String")})
+    public AjaxJson deleteExhibition(@RequestBody RequestExhibition bo){
+        if(bo == null || bo.getId() == null){
+            return AjaxJson.failure(ResponEnum.NOT_NULL.getCode(), ResponEnum.NOT_NULL.getMessage());
+        }
+
+        service.delete(bo.getId());
+        return AjaxJson.success();
+    }
+
+    @PostMapping("copyExhibition")
+    @ResponseBody
+    @WebControllerLog(description = "展示管理-复制展览方案")
+    @ApiOperation("复制展览方案")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "展览方案id", dataType = "String")})
+    public AjaxJson copyExhibition(@RequestBody RequestExhibition bo){
+        if(bo == null || bo.getId() == null){
+            return AjaxJson.failure(ResponEnum.NOT_NULL.getCode(), ResponEnum.NOT_NULL.getMessage());
+        }
+
+        TbExhibition exhibition = service.findById(bo.getId());
+        exhibition.setId(null);
+        exhibition.setState(1);
+        service.insert(exhibition);
+
+        List<ResponExhibition> list = service.findExhibitionCollection(bo.getId());
+        TbExhibitionCollection exhibitionCollection = new TbExhibitionCollection();
+        for(ResponExhibition responExhibition : list){
+            exhibitionCollection.setExhibitionId(exhibition.getId());
+            exhibitionCollection.setCollectionId(responExhibition.getCollectionId());
+            service.insertExhibitionCollection(exhibitionCollection);
+        }
+        return AjaxJson.success();
+    }
+
+    @PostMapping("findCollectionByExhibition")
+    @ResponseBody
+    @ApiOperation("通过展示方案找文物")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "exhibitionId", value = "展览方案id", dataType = "String")})
+    public AjaxJson findCollectionByExhibition(@RequestBody RequestExhibition bo){
+        if(bo == null || bo.getExhibitionId() == null){
+            return AjaxJson.failure(ResponEnum.NOT_NULL.getCode(), ResponEnum.NOT_NULL.getMessage());
+        }
+
+        return AjaxJson.success(service.findCollectionByExhibition(bo.getExhibitionId()));
+    }
+
+    @PostMapping("list")
+    @ResponseBody
+    @WebControllerLog(description = "展示管理-获取展览方案列表")
+    @ApiOperation("获取展览方案列表")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "name", value = "方案名称", dataType = "String"),
+            @ApiImplicitParam(name = "pageNum", value = "页码", dataType = "String"),
+            @ApiImplicitParam(name = "pageSize", value = "每页数量", dataType = "String")})
+    public AjaxJson list(@RequestBody RequestExhibition bo){
+        List<ResponExhibition> list = service.findList(bo);
+        for(ResponExhibition exhibition : list){
+            exhibition.setCreateTime(String.valueOf(DateUtil.convert2CST(exhibition.getCreateTime())));
+        }
+        PageInfo<ResponExhibition> pageInfo = new PageInfo<>(list);
+        return AjaxJson.success(pageInfo);
+    }
+
+    @PostMapping("getExhibitionByEquipmentId")
+    @ResponseBody
+    @ApiOperation("通过设备id获取展示方案")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "equipmentId", value = "设备id", dataType = "String")})
+    public AjaxJson getExhibitionByEquipmentId(@RequestBody RequestExhibition bo){
+        if(bo == null || bo.getEquipmentId() == null){
+            return AjaxJson.failure(ResponEnum.NOT_NULL.getCode(), ResponEnum.NOT_NULL.getMessage());
+        }
+
+        ResponExhibition responExhibition = service.getExhibitionByEquipmentId(bo.getEquipmentId());
+        return AjaxJson.success(responExhibition);
+    }
+
+    @PostMapping("getExhibitionById")
+    @ResponseBody
+    @ApiOperation("通过id获取展示方案")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "id", dataType = "String")})
+    public AjaxJson getExhibitionById(@RequestBody RequestExhibition bo){
+        if(bo == null || bo.getId() == null){
+            return AjaxJson.failure(ResponEnum.NOT_NULL.getCode(), ResponEnum.NOT_NULL.getMessage());
+        }
+
+        ResponExhibition responExhibition = service.getExhibitionById(bo.getId());
+        return AjaxJson.success(responExhibition);
+    }
+
+    @PostMapping("/upload")
+    @ResponseBody
+    @ApiOperation("上传展示方案图片")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "file", value = "文件流", dataType = "String")})
+    public AjaxJson upload(@RequestParam(value = "filename", defaultValue = "") String name, @RequestParam("file") MultipartFile file){
+        if(file == null){
+            return AjaxJson.failure("参数不能为空");
+        }
+        String fileName = System.currentTimeMillis() + "_";
+        if(org.apache.commons.lang3.StringUtils.isNotEmpty(name)){
+            fileName = fileName + name;
+        }else {
+            fileName = fileName + file.getOriginalFilename();
+        }
+        log.info("图片地址:" + fileName);
+        boolean flag = FileUtil.upload(file, uploadPath, fileName);
+
+        if(!flag){
+            return AjaxJson.failure("上传图片失败");
+        }
+
+//        Map<String, String> map = new HashMap<>();
+//        map.put(path + "/" + fileName, "company/" + fileName);
+//        uploadToAlibabaService.upload(map);
+
+        return AjaxJson.success((Object) ("/exhibition/" + fileName));
+    }
+
+    @PostMapping("typeList")
+    @ResponseBody
+    @ApiOperation("获取展示类别列表")
+    public AjaxJson typeList(){
+        return AjaxJson.success(service.typeList());
+    }
+}

+ 181 - 0
zhoushan-system-api/src/main/java/com/fdage/controller/InformationController.java

@@ -0,0 +1,181 @@
+//package com.fdage.controller;
+//
+//import com.alibaba.fastjson.JSONObject;
+//import com.fdage.aop.WebControllerLog;
+//import com.fdage.constant.ConstantUrl;
+//import com.fdage.enums.ResponEnum;
+//import com.fdage.pojo.TbInformation;
+//import com.fdage.request.RequestInformation;
+//import com.fdage.respon.ResponInformation;
+//import com.fdage.service.IInformationService;
+//import com.fdage.util.AjaxJson;
+//import com.fdage.util.DateUtil;
+//import com.fdage.util.FileUtil;
+//import com.github.pagehelper.PageInfo;
+//import io.swagger.annotations.Api;
+//import io.swagger.annotations.ApiImplicitParam;
+//import io.swagger.annotations.ApiImplicitParams;
+//import io.swagger.annotations.ApiOperation;
+//import lombok.extern.slf4j.Slf4j;
+//import org.apache.commons.lang3.StringUtils;
+//import org.springframework.beans.BeanUtils;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.beans.factory.annotation.Value;
+//import org.springframework.stereotype.Controller;
+//import org.springframework.web.bind.annotation.*;
+//import org.springframework.web.multipart.MultipartFile;
+//
+//import java.util.List;
+//
+///**
+// * Created by Hb_zzZ on 2019/9/11.
+// */
+//@Controller
+//@RequestMapping("/zhoushan/information")
+//@Slf4j
+//@Api(tags = "轮播管理模块")
+//public class InformationController {
+//
+//    @Autowired
+//    private IInformationService service;
+//
+//    @Value("${upload.information}")
+//    private String uploadPath;
+//
+//    @PostMapping("addInformation")
+//    @ResponseBody
+//    @WebControllerLog(description = "轮播管理-新增")
+//    @ApiOperation("新增")
+//    @ApiImplicitParams({
+//            @ApiImplicitParam(name = "name", value = "资讯名称", dataType = "String"),
+//            @ApiImplicitParam(name = "type", value = "资讯类型", dataType = "String"),
+//            @ApiImplicitParam(name = "contentUrl", value = "轮播内容,视频为url,图片类型为json", dataType = "String"),
+//            @ApiImplicitParam(name = "contentNum", value = "轮播板式", dataType = "String"),
+//            @ApiImplicitParam(name = "description", value = "资讯说明", dataType = "String"),
+//            @ApiImplicitParam(name = "orderNum", value = "展示顺序编码", dataType = "String"),
+//            @ApiImplicitParam(name = "startTime", value = "轮播开始时间", dataType = "String"),
+//            @ApiImplicitParam(name = "endTime", value = "轮播结束时间", dataType = "String"),
+//            @ApiImplicitParam(name = "state", value = "状态,0:启用,1:禁用", dataType = "String")})
+//    public AjaxJson addInformation(@RequestBody RequestInformation bo){
+//        if(bo == null || StringUtils.isEmpty(bo.getName()) ||
+//                bo.getType() == null  || StringUtils.isEmpty(bo.getContentUrl())){
+//            return AjaxJson.failure(ResponEnum.NOT_NULL.getCode(), ResponEnum.NOT_NULL.getMessage());
+//        }
+//
+//        TbInformation information = new TbInformation();
+//        BeanUtils.copyProperties(bo, information);
+//        service.insert(information);
+//        //发送sse消息
+//        SseController.send("data:" + "1\r\n");
+//        return AjaxJson.success();
+//    }
+//
+//    @PostMapping("updateInformation")
+//    @ResponseBody
+//    @WebControllerLog(description = "轮播管理-修改")
+//    @ApiOperation("修改")
+//    @ApiImplicitParams({
+//            @ApiImplicitParam(name = "id", value = "id", dataType = "String"),
+//            @ApiImplicitParam(name = "name", value = "资讯名称", dataType = "String"),
+//            @ApiImplicitParam(name = "type", value = "资讯类型", dataType = "String"),
+//            @ApiImplicitParam(name = "contentUrl", value = "轮播内容,视频为url,图片类型为json", dataType = "String"),
+//            @ApiImplicitParam(name = "contentNum", value = "轮播板式", dataType = "String"),
+//            @ApiImplicitParam(name = "description", value = "资讯说明", dataType = "String"),
+//            @ApiImplicitParam(name = "orderNum", value = "展示顺序编码", dataType = "String"),
+//            @ApiImplicitParam(name = "startTime", value = "轮播开始时间", dataType = "String"),
+//            @ApiImplicitParam(name = "endTime", value = "轮播结束时间", dataType = "String"),
+//            @ApiImplicitParam(name = "state", value = "状态,0:启用,1:禁用", dataType = "String")})
+//    public AjaxJson updateInformation(@RequestBody RequestInformation bo){
+//        if(bo == null || StringUtils.isEmpty(bo.getName()) ||
+//                bo.getType() == null  || StringUtils.isEmpty(bo.getContentUrl())){
+//            return AjaxJson.failure(ResponEnum.NOT_NULL.getCode(), ResponEnum.NOT_NULL.getMessage());
+//        }
+//
+//        TbInformation information = new TbInformation();
+//        BeanUtils.copyProperties(bo, information);
+//        service.update(information);
+//
+//        //发送sse消息
+//        SseController.send("data:" + "1\r\n");
+//        return AjaxJson.success();
+//    }
+//
+//    @PostMapping("deleteInformation")
+//    @ResponseBody
+//    @WebControllerLog(description = "轮播管理-删除")
+//    @ApiOperation("删除")
+//    @ApiImplicitParams({
+//            @ApiImplicitParam(name = "id", value = "id", dataType = "String")})
+//    public AjaxJson deleteInformation(@RequestBody RequestInformation bo){
+//        if(bo == null || bo.getId() == null ){
+//            return AjaxJson.failure(ResponEnum.NOT_NULL.getCode(), ResponEnum.NOT_NULL.getMessage());
+//        }
+//        service.delete(bo.getId());
+//
+//        //发送sse消息
+//        SseController.send("data:" + "1\r\n");
+//        return AjaxJson.success();
+//    }
+//
+//    @PostMapping("list")
+//    @ResponseBody
+//    @WebControllerLog(description = "轮播管理-列表")
+//    @ApiOperation("列表")
+//    @ApiImplicitParams({
+//            @ApiImplicitParam(name = "type", value = "资讯类型,0表示海报,1表示视频", dataType = "String"),
+//            @ApiImplicitParam(name = "name", value = "资讯名称", dataType = "String"),
+//            @ApiImplicitParam(name = "pageNum", value = "页码", dataType = "String"),
+//            @ApiImplicitParam(name = "pageSize", value = "每页数量", dataType = "String")})
+//    public AjaxJson list(@RequestBody RequestInformation bo){
+//        List<ResponInformation> list = service.findList(bo);
+//        for(ResponInformation information : list){
+//            if(StringUtils.isNotEmpty(information.getStartTime())){
+//                information.setStartTime(String.valueOf(DateUtil.convert2CST(information.getStartTime())));
+//            }
+//            if(StringUtils.isNotEmpty(information.getEndTime())){
+//                information.setEndTime(String.valueOf(DateUtil.convert2CST(information.getEndTime())));
+//            }
+//            if(StringUtils.isNotEmpty(information.getCreateTime())){
+//                information.setCreateTime(String.valueOf(DateUtil.convert2CST(information.getCreateTime())));
+//            }
+//        }
+//        PageInfo<ResponInformation> pageInfo = new PageInfo<>(list);
+//        return AjaxJson.success(pageInfo);
+//    }
+//
+//    @PostMapping("listAll")
+//    @ResponseBody
+//    @ApiOperation("所有资讯")
+//    public AjaxJson listAll(){
+//        return AjaxJson.success(service.listAll());
+//    }
+//
+//    @PostMapping("/upload")
+//    @ResponseBody
+//    @ApiOperation("上传资讯图片")
+//    @ApiImplicitParams({
+//            @ApiImplicitParam(name = "file", value = "文件流", dataType = "String")})
+//    public AjaxJson upload(@RequestParam(value = "filename", defaultValue = "") String name, @RequestParam("file") MultipartFile file){
+//        if(file == null){
+//            return AjaxJson.failure("参数不能为空");
+//        }
+//        String fileName = System.currentTimeMillis() + "_";
+//        if(StringUtils.isNotEmpty(name)){
+//            fileName = fileName + name;
+//        }else {
+//            fileName = fileName + file.getOriginalFilename();
+//        }
+//        log.info("图片地址:" + fileName);
+//        boolean flag = FileUtil.upload(file, uploadPath, fileName);
+//
+//        if(!flag){
+//            return AjaxJson.failure("上传图片失败");
+//        }
+//
+////        Map<String, String> map = new HashMap<>();
+////        map.put(path + "/" + fileName, "company/" + fileName);
+////        uploadToAlibabaService.upload(map);
+//
+//        return AjaxJson.success((Object) ("/information/" + fileName));
+//    }
+//}

+ 49 - 0
zhoushan-system-api/src/main/java/com/fdage/controller/LogController.java

@@ -0,0 +1,49 @@
+package com.fdage.controller;
+
+import com.fdage.aop.WebControllerLog;
+import com.fdage.pojo.TbLog;
+import com.fdage.request.RequestLog;
+import com.fdage.service.ILogService;
+import com.fdage.util.AjaxJson;
+import com.github.pagehelper.PageInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import java.util.List;
+
+/**
+ * Created by Hb_zzZ on 2020/7/28.
+ */
+@Controller
+@RequestMapping("/zhoushan/log")
+@Slf4j
+@Api(tags = "sys-工作日志模块")
+public class LogController {
+
+    @Autowired
+    private ILogService logService;
+
+    @PostMapping("list")
+    @ResponseBody
+    @WebControllerLog(description = "工作日志-获取日志列表")
+    @ApiOperation("获取日志列表")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "type", value = "资讯类型,0表示海报,1表示视频", dataType = "String"),
+            @ApiImplicitParam(name = "name", value = "资讯名称", dataType = "String"),
+            @ApiImplicitParam(name = "pageNum", value = "页码", dataType = "String"),
+            @ApiImplicitParam(name = "pageSize", value = "每页数量", dataType = "String")})
+    public AjaxJson list(@RequestBody RequestLog bo){
+        List<TbLog> list = logService.findList(bo);
+        PageInfo<TbLog> pageInfo = new PageInfo<>(list);
+        return AjaxJson.success(pageInfo);
+    }
+}

+ 127 - 0
zhoushan-system-api/src/main/java/com/fdage/controller/LoginController.java

@@ -0,0 +1,127 @@
+package com.fdage.controller;
+
+import com.fdage.dto.ResourceTree;
+import com.fdage.enums.ResponEnum;
+import com.fdage.pojo.TbLog;
+import com.fdage.pojo.TbUser;
+import com.fdage.request.RequestUser;
+import com.fdage.respon.ResponUser;
+import com.fdage.service.ILogService;
+import com.fdage.service.IResourceService;
+import com.fdage.service.IRoleService;
+import com.fdage.service.IUserService;
+import com.fdage.shiro.JwtUtil2;
+import com.fdage.util.AjaxJson;
+import com.fdage.util.PasswordUtils;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Created by Hb_zzZ on 2019/9/11.
+ */
+@Slf4j
+@Controller
+@Api(tags = "sys-登陆模块")
+public class LoginController {
+
+    @Autowired
+    private IUserService userService;
+
+    @Autowired
+    private IResourceService resourceService;
+
+    @Autowired
+    private RedisTemplate<String, String> redisTemplate;
+
+    @Autowired
+    private ILogService logService;
+
+    @PostMapping("/login")
+    @ResponseBody
+    @ApiOperation("登陆1")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "userName", value = "用户名", dataType = "String"),
+            @ApiImplicitParam(name = "password", value = "密码", dataType = "String")})
+    public AjaxJson login(@RequestBody RequestUser bo){
+        log.info("RequestUser: {}", bo.toString());
+        if(bo == null || StringUtils.isEmpty(bo.getUserName()) || StringUtils.isEmpty(bo.getPassword())){
+            return AjaxJson.failure(ResponEnum.NOT_NULL.getCode(), ResponEnum.NOT_NULL.getMessage());
+        }
+
+        TbUser user = userService.findByUserName(bo.getUserName());
+        if(user == null){
+            return AjaxJson.failure(ResponEnum.USER_NOT_EXIST.getCode(), ResponEnum.USER_NOT_EXIST.getMessage());
+        }
+
+        String encryptPwd = PasswordUtils.encrypt(bo.getPassword(), bo.getUserName(), PasswordUtils.getStaticSalt());
+        if(!encryptPwd.equals(user.getPassword())){
+            return AjaxJson.failure(ResponEnum.PASSWORD_ERROR.getCode(), ResponEnum.PASSWORD_ERROR.getMessage());
+        }
+
+        // 检查账号是否启用
+        if (user.getState() != 0) {
+            log.error("账号已停用: {}", user.getUserName());
+            return AjaxJson.failure(ResponEnum.USER_STOP_USING.getCode(), ResponEnum.USER_STOP_USING.getMessage());
+        }
+
+//        ResponUser result = new ResponUser();
+//        BeanUtils.copyProperties(user, result);
+
+
+        List<ResourceTree> resourcesTreeByUserPermission = resourceService.getResourcesAllByUserPermission(user);
+//        log.info("获取权限 success");
+
+        // 获取用户角色
+        List<String> roles = userService.findRoleByUserId(user.getId());
+//        log.info("获取角色 success");
+
+
+        // 创建新token
+        HashMap<String, Object> tokenMap = new HashMap<>();
+        tokenMap.put("userName", user.getUserName());
+        tokenMap.put("id", user.getId());
+        tokenMap.put("role", roles);
+
+
+        String token = JwtUtil2.createJWT(-1, tokenMap);
+
+        HashMap<String, Object> result = new HashMap<>();
+        result.put("user", user);
+        result.put("token", token);
+        result.put("permission", resourcesTreeByUserPermission);
+        result.put("role", roles);
+//        log.info("token create");
+
+
+        // 更新到 redis, 有效期24h, 旧token无效
+        redisTemplate.opsForValue().set(user.getUserName(), token, Long.parseLong("23"), TimeUnit.HOURS);
+
+        TbLog logEntity = new TbLog();
+        logEntity.setCreateTime(new Date());
+        logEntity.setType("登陆");
+        logEntity.setDescription("登陆系统");
+        logEntity.setUserId(user.getId());
+
+        logService.save(logEntity);
+
+        return AjaxJson.success(result);
+    }
+}

+ 32 - 0
zhoushan-system-api/src/main/java/com/fdage/controller/PositionController.java

@@ -0,0 +1,32 @@
+//package com.fdage.controller;
+//
+//import com.fdage.service.IPositionService;
+//import com.fdage.util.AjaxJson;
+//import io.swagger.annotations.Api;
+//import io.swagger.annotations.ApiOperation;
+//import lombok.extern.slf4j.Slf4j;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.stereotype.Controller;
+//import org.springframework.web.bind.annotation.PostMapping;
+//import org.springframework.web.bind.annotation.RequestMapping;
+//import org.springframework.web.bind.annotation.ResponseBody;
+//
+///**
+// * Created by Hb_zzZ on 2019/9/11.
+// */
+//@Controller
+//@RequestMapping("/zhoushan/position")
+//@Slf4j
+//@Api(tags = "位置模块")
+//public class PositionController {
+//
+//    @Autowired
+//    private IPositionService service;
+//
+//    @PostMapping("list")
+//    @ResponseBody
+//    @ApiOperation("获取所有位置")
+//    public AjaxJson list(){
+//        return AjaxJson.success(service.list());
+//    }
+//}

+ 39 - 0
zhoushan-system-api/src/main/java/com/fdage/controller/ResourceController.java

@@ -0,0 +1,39 @@
+package com.fdage.controller;
+
+import com.fdage.dto.ResourceTree;
+import com.fdage.service.IResourceService;
+import com.fdage.util.AjaxJson;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import java.util.List;
+
+/**
+ * Created by Hb_zzZ on 2020/7/28.
+ */
+@Controller
+@RequestMapping("/zhoushan/resource")
+@Slf4j
+@Api(tags = "sys-权限资源模块")
+public class ResourceController {
+
+    @Autowired
+    private IResourceService resourceService;
+
+    @PostMapping("find")
+    @ResponseBody
+    @ApiOperation("获取所以资源(树形结构)")
+    public AjaxJson find() throws Exception {
+//        List<ResourceEntity> result = resourceService.findList(Sort.by("sort").ascending());
+        List<ResourceTree> listTree = resourceService.getTree();
+        return AjaxJson.success(listTree);
+    }
+
+
+}

+ 183 - 0
zhoushan-system-api/src/main/java/com/fdage/controller/RoleController.java

@@ -0,0 +1,183 @@
+package com.fdage.controller;
+
+import com.fdage.aop.WebControllerLog;
+import com.fdage.pojo.TbRole;
+import com.fdage.pojo.TbUser;
+import com.fdage.request.RequestBase;
+import com.fdage.request.RequestRole;
+import com.fdage.respon.ResponRole;
+import com.fdage.service.IResourceService;
+import com.fdage.service.IRoleService;
+import com.fdage.service.IUserService;
+import com.fdage.util.AjaxJson;
+import com.github.pagehelper.PageInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import java.util.List;
+
+/**
+ * Created by Hb_zzZ on 2020/7/28.
+ */
+@Controller
+@RequestMapping("/zhoushan/role")
+@Slf4j
+@Api(tags = "sys-角色管理模块")
+public class RoleController {
+
+    @Autowired
+    private IRoleService roleService;
+
+    @Autowired
+    private IResourceService resourceService;
+
+    @Autowired
+    private IUserService userService;
+
+
+
+    @PostMapping("save")
+    @ResponseBody
+    @WebControllerLog(description = "角色管理-新增/修改角色")
+    @ApiOperation("新增/修改角色")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "roleName", value = "角色名称", dataType = "String"),
+            @ApiImplicitParam(name = "resources", value = "资源id集合", dataType = "String"),
+            @ApiImplicitParam(name = "id", value = "id", dataType = "String"),
+            @ApiImplicitParam(name = "description", value = "角色描述", dataType = "String"),
+            @ApiImplicitParam(name = "state", value = "状态,0:启用,1:禁用", dataType = "String"),
+            @ApiImplicitParam(name = "roleKey", value = "角色key", dataType = "String")})
+    public AjaxJson save(@RequestBody RequestRole param){
+
+        if (StringUtils.isBlank(param.getRoleName())){
+            log.error("角色名称不能为空");
+            return AjaxJson.failure("角色名称不能为空");
+        }
+
+        if (param.getResources() == null){
+            log.error("权限不能为空");
+            return AjaxJson.failure("权限不能为空");
+        }
+
+
+        TbRole roleEntity = null;
+        int n = 0;
+
+        if (param.getId() == null) {
+            roleEntity = new TbRole();
+            BeanUtils.copyProperties(param, roleEntity);
+            n = roleService.save(roleEntity);
+        } else {
+            roleEntity = roleService.findById(param.getId());
+            if (roleEntity == null) {
+                return AjaxJson.failure("该角色不存在");
+
+            }
+            BeanUtils.copyProperties(param, roleEntity);
+
+            // 2021-8-16 检查该角色是否被用户使用
+            if (roleEntity.getState() == 1){
+                if (checkUseRole(roleEntity.getId())) {
+                    return AjaxJson.failure("当前角色还有关联用户,请先处理用户角色");
+                }
+            }
+
+
+            n = roleService.update(roleEntity);
+
+            // 每次修改,删除角色资源表信息,重新添加
+            roleService.deleteRoleResource(param.getId());
+        }
+
+        // 添加权限
+        if (n >= 0){
+            if (param.getResources() != null){
+                for (long i : param.getResources()) {
+                    roleService.saveRoleResource(roleEntity.getId(), i);
+                }
+                return AjaxJson.success();
+            }
+        }
+
+        return AjaxJson.failure("新增角色失败");
+    }
+
+
+    private Boolean checkUseRole(Long id){
+        List<String> list = roleService.findUserNameByRoleId(id);
+        if(list != null && list.size() > 0){
+            return true;
+//            return AjaxJson.failure("当前角色还有关联用户,请先处理用户角色");
+        }
+        return false;
+    }
+
+    @PostMapping("list")
+    @ResponseBody
+    @WebControllerLog(description = "角色管理-获取角色列表")
+    @ApiOperation("获取角色列表")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "pageNum", value = "页码", dataType = "String"),
+            @ApiImplicitParam(name = "pageSize", value = "每页数量", dataType = "String")})
+    public AjaxJson list(@RequestBody RequestBase bo){
+        List<ResponRole> list = roleService.findRoleList(bo);
+        PageInfo<ResponRole> pageInfo = new PageInfo<>(list);
+        return AjaxJson.success(pageInfo);
+    }
+
+    @PostMapping("findUserListByRoleId")
+    @ResponseBody
+    @ApiOperation("获取角色关联的用户列表")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "角色id", dataType = "String")})
+    public AjaxJson findUserListByRoleId(@RequestBody RequestRole bo){
+        return AjaxJson.success(roleService.findUserListByRoleId(bo.getId()));
+    }
+
+    @PostMapping("updateState")
+    @ResponseBody
+    @ApiOperation("角色启用/停用")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "角色id", dataType = "String"),
+            @ApiImplicitParam(name = "state", value = "状态,0:启用,1:禁用", dataType = "String")})
+    public AjaxJson updateState(@RequestBody RequestRole bo){
+        if(bo.getId() == null || bo.getState() == null){
+            return AjaxJson.failure("id或者状态不能为空");
+        }
+
+        List<String> list = roleService.findUserNameByRoleId(bo.getId());
+        if(list != null && list.size() > 0){
+            return AjaxJson.failure("当前角色还有关联用户,请先处理用户角色");
+        }
+        TbRole role = new TbRole();
+        role.setId(bo.getId());
+        role.setState(bo.getState());
+        roleService.update(role);
+        return AjaxJson.success();
+    }
+
+    @PostMapping("findRoleById")
+    @ResponseBody
+    @ApiOperation("根据id获取角色详情")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "角色id", dataType = "String")})
+    public AjaxJson findRoleById(@RequestBody RequestRole bo){
+        if(bo.getId() == null){
+            return AjaxJson.failure("id不能为空");
+        }
+        ResponRole responRole = roleService.findRoleById(bo.getId());
+        responRole.setResources(resourceService.getResourcesAllByRolePermission(bo.getId()));
+        return AjaxJson.success(responRole);
+    }
+}

+ 67 - 0
zhoushan-system-api/src/main/java/com/fdage/controller/SceneController.java

@@ -0,0 +1,67 @@
+package com.fdage.controller;
+
+import com.fdage.aop.WebControllerLog;
+import com.fdage.dto.SceneDto;
+import com.fdage.entity.SceneEntity;
+import com.fdage.service.SceneService;
+import com.fdage.util.AjaxJson;
+import com.fdage.util.Result;
+import com.github.pagehelper.PageInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.validation.Valid;
+
+/**
+ * Created by owen on 2021/8/23 0023 15:35
+ */
+@ApiIgnore
+@Api(tags = "场景管理")
+@RestController
+@RequestMapping("/zhoushan/scene")
+public class SceneController {
+    @Autowired
+    SceneService sceneService;
+
+    @ApiOperation("列表")
+    @PostMapping("list")
+    public Result list() {
+        return sceneService.findAll();
+    }
+
+    @WebControllerLog(description = "场景管理-新增/编辑")
+    @ApiOperation("新增/编辑")
+    @PostMapping("save")
+    public Result<SceneEntity> save(@Valid @RequestBody SceneDto param) {
+        return sceneService.saveEntity(param);
+    }
+
+
+    @WebControllerLog(description = "场景管理-删除")
+    @ApiOperation(value = "删除", notes = "db数据软删除, 物理数据真删除")
+    @GetMapping("remove/{id}")
+    public Result remove(@PathVariable Long id) {
+        return sceneService.remove(id);
+    }
+
+    @WebControllerLog(description = "场景管理-详情")
+    @ApiOperation(value = "详情")
+    @GetMapping("detail/{id}")
+    public Result detail(@PathVariable Long id) {
+
+        return sceneService.detail(id);
+    }
+
+
+    @ApiOperation(value = "上传", notes = "重命名文件")
+    @PostMapping("upload")
+    public Result upload(MultipartFile file) {
+
+        return sceneService.upload(file, null, false);
+    }
+}

+ 127 - 0
zhoushan-system-api/src/main/java/com/fdage/controller/SseController.java

@@ -0,0 +1,127 @@
+package com.fdage.controller;
+
+import io.swagger.annotations.ApiOperation;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.servlet.AsyncContext;
+import javax.servlet.AsyncEvent;
+import javax.servlet.AsyncListener;
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Created by Hb_zzZ on 2019/9/16.
+ */
+@ApiIgnore
+@WebServlet(urlPatterns = { "/sendMessage" }, asyncSupported = true)
+@Controller
+public class SseController extends HttpServlet {
+
+    private static final long serialVersionUID = 1L;
+    private final static int DEFAULT_TIME_OUT = 10 * 60 * 1000;
+    public static List<AsyncContext> actxList =new ArrayList<AsyncContext>();
+
+    @Override
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+        // TODO Auto-generated method stub
+        resp.setContentType("text/event-stream");
+        resp.setCharacterEncoding("UTF-8");
+        req.setAttribute("org.apache.catalina.ASYNC_SUPPORTED", true);//注意这里
+
+        AsyncContext actx = req.startAsync(req, resp);
+        actx.setTimeout(DEFAULT_TIME_OUT);
+        actx.addListener(new AsyncListener() {
+            @Override
+            public void onComplete(AsyncEvent arg0) throws IOException {
+                // TODO Auto-generated method stub
+                System.out.println("[echo]event complete:" + arg0.getSuppliedRequest().getRemoteAddr());
+            }
+
+            @Override
+            public void onError(AsyncEvent arg0) throws IOException {
+                // TODO Auto-generated method stub
+                System.out.println("[echo]event has error");
+            }
+
+            @Override
+            public void onStartAsync(AsyncEvent arg0) throws IOException {
+                // TODO Auto-generated method stub
+                System.out.println("[echo]event start:" + arg0.getSuppliedRequest().getRemoteAddr());
+            }
+
+            @Override
+            public void onTimeout(AsyncEvent arg0) throws IOException {
+                // TODO Auto-generated method stub
+                System.out.println("[echo]event time lost");
+            }
+        });
+
+        actxList.add(actx);
+
+//        PrintWriter out = actx.getResponse().getWriter();
+//        out.println("data:" + new Date().getTime());  //js页面EventSource接收数据格式:data:数据 + "\r\n"
+//        out.flush();
+//        new Thread(new AsyncWebService(actx)).start();
+    }
+
+    @GetMapping("send")
+    @ResponseBody
+    public static String send(String msg){
+        //打印当前AsyncContext
+        System.out.println(actxList.size());
+        if(actxList.size()>0){
+            for(int i = 0;i<actxList.size();i++){
+                AsyncContext obj = actxList.get(i);
+                PrintWriter out;
+
+                try {
+                    if (obj.getTimeout()>0){
+                        out = obj.getResponse().getWriter();
+                        out.println(msg);  //js页面EventSource接收数据格式:data:数据 + "\r\n"
+                        out.flush();
+                    }
+                } catch (Exception e) {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                }
+            }
+        }
+        return "发送消息";
+    }
+
+//    class AsyncWebService implements Runnable {
+//        AsyncContext ctx;
+//
+//        public AsyncWebService(AsyncContext ctx) {
+//            this.ctx = ctx;
+//        }
+//
+//        public void run() {
+//            try {
+//                //等待十秒钟,以模拟业务方法的执行
+//                Thread.sleep(10000);
+//                PrintWriter out = ctx.getResponse().getWriter();
+//                out.println("data:中文" + new Date() + "\r\n");  //js页面EventSource接收数据格式:data:数据 + "\r\n"
+//
+//                out.flush();
+//                ctx.complete();
+//            } catch (Exception e) {
+//                e.printStackTrace();
+//            }
+//
+//        }
+//
+//    }
+}

+ 280 - 0
zhoushan-system-api/src/main/java/com/fdage/controller/UserController.java

@@ -0,0 +1,280 @@
+package com.fdage.controller;
+
+import com.fdage.aop.WebControllerLog;
+import com.fdage.constant.ConstantUrl;
+import com.fdage.enums.ResponEnum;
+import com.fdage.pojo.TbRole;
+import com.fdage.pojo.TbUser;
+import com.fdage.request.RequestUser;
+import com.fdage.respon.ResponUser;
+import com.fdage.service.IRoleService;
+import com.fdage.service.IUserService;
+import com.fdage.util.AjaxJson;
+import com.fdage.util.FileUtil;
+import com.fdage.util.PasswordUtils;
+import com.github.pagehelper.PageInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+
+/**
+ * Created by Hb_zzZ on 2019/9/11.
+ */
+@Controller
+@RequestMapping("/zhoushan/user")
+@Slf4j
+@Api(tags = "sys-用户管理模块")
+public class UserController {
+
+    @Autowired
+    private IUserService userService;
+
+    @Autowired
+    private IRoleService roleService;
+
+    @Value("${upload.head}")
+    private String userHead;
+
+    @PostMapping("addUser")
+    @ResponseBody
+    @WebControllerLog(description = "用户管理-新增用户")
+    @ApiOperation("新增用户")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "userName", value = "用户名", dataType = "String"),
+            @ApiImplicitParam(name = "roleId", value = "角色id", dataType = "String"),
+            @ApiImplicitParam(name = "phone", value = "手机号码", dataType = "String"),
+            @ApiImplicitParam(name = "head", value = "头像连接地址", dataType = "String"),
+            @ApiImplicitParam(name = "state", value = "状态,0:启用,1:禁用", dataType = "String")})
+    public AjaxJson addUser(@RequestBody RequestUser bo){
+        if(bo == null || StringUtils.isEmpty(bo.getUserName()) ||
+                bo.getRoleId() == null || StringUtils.isEmpty(bo.getPhone()) || bo.getState() == null){
+            return AjaxJson.failure(ResponEnum.NOT_NULL.getCode(), ResponEnum.NOT_NULL.getMessage());
+        }
+
+        TbUser user = userService.findByUserName(bo.getUserName());
+        if(user != null){
+            return AjaxJson.failure(ResponEnum.USER_EXIST.getCode(), ResponEnum.USER_EXIST.getMessage());
+        }
+
+        user = new TbUser();
+        BeanUtils.copyProperties(bo, user);
+        user.setPassword(PasswordUtils.encrypt("1234abcd", bo.getUserName(), PasswordUtils.getStaticSalt()));
+        userService.insert(user);
+
+        roleService.saveRoleUser(bo.getRoleId(), user.getId());
+        return AjaxJson.success(user);
+    }
+
+    @PostMapping("updateUser")
+    @ResponseBody
+    @WebControllerLog(description = "用户管理-修改用户")
+    @ApiOperation("修改用户")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "id", dataType = "String"),
+            @ApiImplicitParam(name = "userName", value = "用户名", dataType = "String"),
+            @ApiImplicitParam(name = "roleId", value = "角色id", dataType = "String"),
+            @ApiImplicitParam(name = "phone", value = "手机号码", dataType = "String"),
+            @ApiImplicitParam(name = "head", value = "头像连接地址", dataType = "String"),
+            @ApiImplicitParam(name = "state", value = "状态,0:启用,1:禁用", dataType = "String")})
+    public AjaxJson updateUser(@RequestBody RequestUser bo){
+        if(bo == null || StringUtils.isEmpty(bo.getUserName()) ||
+                bo.getRoleId() == null || StringUtils.isEmpty(bo.getPhone()) || bo.getState() == null ){
+            return AjaxJson.failure(ResponEnum.NOT_NULL.getCode(), ResponEnum.NOT_NULL.getMessage());
+        }
+
+        TbUser user = userService.findByUserName(bo.getUserName());
+        if(user == null){
+            return AjaxJson.failure(ResponEnum.USER_NOT_EXIST.getCode(), ResponEnum.USER_NOT_EXIST.getMessage());
+        }
+
+        bo.setId(user.getId());
+        BeanUtils.copyProperties(bo, user);
+        user.setPassword(PasswordUtils.encrypt(bo.getPassword(), bo.getUserName(), PasswordUtils.getStaticSalt()));
+        userService.update(user);
+
+        roleService.deleteRoleUser(user.getId());
+        roleService.saveRoleUser(bo.getRoleId(), user.getId());
+        return AjaxJson.success();
+    }
+
+    @PostMapping("deleteUser")
+    @ResponseBody
+    @WebControllerLog(description = "用户管理-删除用户")
+    @ApiOperation("删除用户")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "id", dataType = "String")})
+    public AjaxJson deleteUser(@RequestBody RequestUser bo){
+        if(bo == null || bo.getId() == null){
+            return AjaxJson.failure(ResponEnum.NOT_NULL.getCode(), ResponEnum.NOT_NULL.getMessage());
+        }
+
+        TbUser user = userService.findById(bo.getId());
+        if(user == null){
+            return AjaxJson.failure(ResponEnum.USER_NOT_EXIST.getCode(), ResponEnum.USER_NOT_EXIST.getMessage());
+        }
+
+        userService.delete(user.getId());
+        roleService.deleteRoleUser(user.getId());
+        return AjaxJson.success();
+    }
+
+    @PostMapping("updateState")
+    @ResponseBody
+    @WebControllerLog(description = "用户管理-用户启用/停用")
+    @ApiOperation("用户启用/停用")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "id", dataType = "String"),
+            @ApiImplicitParam(name = "state", value = "状态,0:启用,1:禁用", dataType = "String")})
+    public AjaxJson updateState(@RequestBody RequestUser bo){
+        if(bo == null || bo.getId() == null || bo.getState() == null){
+            return AjaxJson.failure(ResponEnum.NOT_NULL.getCode(), ResponEnum.NOT_NULL.getMessage());
+        }
+
+        TbUser user = userService.findById(bo.getId());
+        if(user == null){
+            return AjaxJson.failure(ResponEnum.USER_NOT_EXIST.getCode(), ResponEnum.USER_NOT_EXIST.getMessage());
+        }
+
+        user.setState(bo.getState());
+        userService.update(user);
+        return AjaxJson.success();
+    }
+
+    @PostMapping("findById")
+    @ResponseBody
+    @ApiOperation("通过id查找用户")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "id", dataType = "String")})
+    public AjaxJson findById(@RequestBody RequestUser bo){
+        if(bo == null || bo.getId() == null){
+            return AjaxJson.failure(ResponEnum.NOT_NULL.getCode(), ResponEnum.NOT_NULL.getMessage());
+        }
+
+        TbUser user = userService.findById(bo.getId());
+        if(user == null){
+            return AjaxJson.failure(ResponEnum.USER_NOT_EXIST.getCode(), ResponEnum.USER_NOT_EXIST.getMessage());
+        }
+
+        user.setPassword("");
+        return AjaxJson.success(user);
+    }
+
+    @PostMapping("updatePassword")
+    @ResponseBody
+    @WebControllerLog(description = "用户管理-用户修改密码")
+    @ApiOperation("用户修改密码")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "id", dataType = "String"),
+            @ApiImplicitParam(name = "repeatPassword", value = "重复新密码", dataType = "String"),
+            @ApiImplicitParam(name = "newPassword", value = "新密码", dataType = "String"),
+            @ApiImplicitParam(name = "password", value = "当前密码", dataType = "String")})
+    public AjaxJson updatePassword(@RequestBody RequestUser bo){
+        if(bo == null || bo.getId() == null || StringUtils.isEmpty(bo.getPassword()) ||
+                StringUtils.isEmpty(bo.getRepeatPassword()) || StringUtils.isEmpty(bo.getNewPassword())){
+            return AjaxJson.failure(ResponEnum.NOT_NULL.getCode(), ResponEnum.NOT_NULL.getMessage());
+        }
+
+        if(!bo.getRepeatPassword().equals(bo.getNewPassword())){
+            return AjaxJson.failure(ResponEnum.PASSWORD_INCONSISTENCY.getCode(), ResponEnum.PASSWORD_INCONSISTENCY.getMessage());
+        }
+
+        TbUser user = userService.findById(bo.getId());
+        if(user == null){
+            return AjaxJson.failure(ResponEnum.USER_NOT_EXIST.getCode(), ResponEnum.USER_NOT_EXIST.getMessage());
+        }
+
+        String encryptPwd = PasswordUtils.encrypt(bo.getPassword(), user.getUserName(), PasswordUtils.getStaticSalt());
+        if(!encryptPwd.equals(user.getPassword())){
+            return AjaxJson.failure(ResponEnum.PASSWORD_ERROR.getCode(), ResponEnum.PASSWORD_ERROR.getMessage());
+        }
+
+        user.setPassword(PasswordUtils.encrypt(bo.getNewPassword(), user.getUserName(), PasswordUtils.getStaticSalt()));
+        userService.update(user);
+        return AjaxJson.success();
+    }
+
+    @PostMapping("resetPassword")
+    @ResponseBody
+    @WebControllerLog(description = "用户管理-用户重置密码")
+    @ApiOperation("用户重置密码")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "id", dataType = "String")})
+    public AjaxJson resetPassword(@RequestBody RequestUser bo){
+        if(bo == null || bo.getId() == null){
+            return AjaxJson.failure(ResponEnum.NOT_NULL.getCode(), ResponEnum.NOT_NULL.getMessage());
+        }
+
+        TbUser user = userService.findById(bo.getId());
+        if(user == null){
+            return AjaxJson.failure(ResponEnum.USER_NOT_EXIST.getCode(), ResponEnum.USER_NOT_EXIST.getMessage());
+        }
+
+        user.setPassword(PasswordUtils.encrypt("1234abcd", user.getUserName(), PasswordUtils.getStaticSalt()));
+        userService.update(user);
+        return AjaxJson.success();
+    }
+
+    @PostMapping("list")
+    @ResponseBody
+    @WebControllerLog(description = "用户管理-获取用户列表")
+    @ApiOperation("获取用户列表")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "status", value = "状态,0:启用,1:禁用", dataType = "String"),
+            @ApiImplicitParam(name = "userName", value = "用户名", dataType = "String"),
+            @ApiImplicitParam(name = "pageNum", value = "页码", dataType = "String"),
+            @ApiImplicitParam(name = "pageSize", value = "每页数量", dataType = "String")})
+    public AjaxJson list(@RequestBody RequestUser bo){
+        List<ResponUser> list = userService.findUserList(bo);
+        PageInfo<ResponUser> pageInfo = new PageInfo<>(list);
+        return AjaxJson.success(pageInfo);
+    }
+
+    @PostMapping("roleList")
+    @ResponseBody
+    @ApiOperation("获取所有角色")
+    public AjaxJson roleList(){
+        List<TbRole> list = userService.roleList();
+        return AjaxJson.success(list);
+    }
+
+    @RequestMapping("/uploadHead")
+    @ResponseBody
+    @WebControllerLog(description = "用户管理-用户上传头像")
+    @ApiOperation("用户上传头像")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "file", value = "文件流", dataType = "String")})
+    public AjaxJson upload(@RequestParam(value = "filename", defaultValue = "") String name,@RequestParam("file") MultipartFile file){
+        if(file == null){
+            return AjaxJson.failure("参数不能为空");
+        }
+        String fileName = System.currentTimeMillis() + "_";
+        if(StringUtils.isNotEmpty(name)){
+            fileName = fileName + name;
+        }else {
+            fileName = fileName + file.getOriginalFilename();
+        }
+        log.info("图片地址:" + fileName);
+        boolean flag = FileUtil.upload(file, userHead, fileName);
+
+        if(!flag){
+            return AjaxJson.failure("上传图片失败");
+        }
+
+//        Map<String, String> map = new HashMap<>();
+//        map.put(path + "/" + fileName, "company/" + fileName);
+//        uploadToAlibabaService.upload(map);
+
+        return AjaxJson.success((Object) ("/head/" + fileName));
+    }
+}

+ 67 - 0
zhoushan-system-api/src/main/java/com/fdage/controller/VideoController.java

@@ -0,0 +1,67 @@
+package com.fdage.controller;
+
+import com.fdage.aop.WebControllerLog;
+import com.fdage.dto.SceneDto;
+import com.fdage.dto.VideoDto;
+import com.fdage.entity.SceneEntity;
+import com.fdage.entity.VideoEntity;
+import com.fdage.service.SceneService;
+import com.fdage.service.VideoService;
+import com.fdage.util.Result;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.validation.Valid;
+
+/**
+ * Created by owen on 2021/8/30 0023 15:35
+ */
+@ApiIgnore
+@Api(tags = "视频管理")
+@RestController
+@RequestMapping("/zhoushan/video")
+public class VideoController {
+    @Autowired
+    VideoService videoService;
+
+    @ApiOperation("列表")
+    @PostMapping("list")
+    public Result list() {
+        return videoService.findAll();
+    }
+
+    @WebControllerLog(description = "视频管理-新增/编辑")
+    @ApiOperation("新增/编辑")
+    @PostMapping("save")
+    public Result<VideoEntity> save(@Valid @RequestBody VideoDto param) {
+        return videoService.saveEntity(param);
+    }
+
+
+    @WebControllerLog(description = "视频管理-删除")
+    @ApiOperation(value = "删除", notes = "db数据软删除, 物理数据真删除")
+    @GetMapping("remove/{id}")
+    public Result remove(@PathVariable Long id) {
+        return videoService.remove(id);
+    }
+
+    @WebControllerLog(description = "视频管理-详情")
+    @ApiOperation(value = "详情")
+    @GetMapping("detail/{id}")
+    public Result detail(@PathVariable Long id) {
+
+        return videoService.detail(id);
+    }
+
+
+    @ApiOperation(value = "上传", notes = "重命名文件")
+    @PostMapping("upload")
+    public Result upload(MultipartFile file) {
+
+        return videoService.upload(file, null, false);
+    }
+}

+ 59 - 0
zhoushan-system-api/src/main/java/com/fdage/listner/LoggerInterceptor.java

@@ -0,0 +1,59 @@
+package com.fdage.listner;
+
+//import com.fdage.util.JwtUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+        import org.springframework.web.servlet.HandlerInterceptor;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Created by Hb_zzZ on 2018/12/6.
+ */
+@Slf4j
+@Component
+public class LoggerInterceptor implements HandlerInterceptor {
+
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+        String uri = request.getRequestURI();
+        log.info("进入" + uri + "请求");
+
+//        String token = request.getHeader("token");
+//        if(StringUtils.isEmpty(token) || "null".equals(token)){
+//            log.info(uri + "请求token为空");
+//            response.setContentType("text/html;charset=UTF-8");
+//            JSONObject responseJson = new JSONObject();
+//            responseJson.put("code", 202);
+//            responseJson.put("message", "token不能为空");
+//            response.getWriter().println(responseJson);
+//            return false;
+//        }
+//        Claims claims = JwtUtil.parseJWT(token);
+//        Object obj = redisUtils.get(CommonConf.REDIS_LOGIN_TOKEN + claims.get("username", String.class));
+//        if(obj == null || !obj.equals(token)){
+//            log.info(uri + "请求token错误被拦截");
+//            response.setContentType("text/html;charset=UTF-8");
+//            JSONObject responseJson = new JSONObject();
+//            responseJson.put("code", 202);
+//            responseJson.put("message", "token不正确请重新登陆");
+//            response.getWriter().println(responseJson);
+//            return false;
+//        }
+        return true;
+    }
+
+    @Override
+    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
+
+    }
+
+    @Override
+    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
+        String uri = request.getRequestURI();
+        log.info(uri + "请求结束");
+    }
+}

+ 93 - 0
zhoushan-system-api/src/main/java/com/fdage/listner/Swagger2.java

@@ -0,0 +1,93 @@
+package com.fdage.listner;
+
+import com.fdage.constant.ConfigConstant;
+import com.google.common.collect.Lists;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.ApiKey;
+import springfox.documentation.service.AuthorizationScope;
+import springfox.documentation.service.SecurityReference;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spi.service.contexts.SecurityContext;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by owen on 2020/2/18
+ *
+ * 集成Swagger有3步:
+ * 1.pom.xml添加依赖
+ * 2.添加Swagger2.class
+ * 3.Application.class 加上注解@EnableSwagger2 表示开启Swagger
+ * 4.http://localhost:8080/doc.html#/
+ *
+ * 2.9.2 不需要字启动类配置注解
+ */
+//@EnableKnife4j 开启动态响应值
+@Configuration
+@EnableSwagger2
+public class Swagger2 {
+
+    @Autowired
+    ConfigConstant configConstant;
+
+    @Bean
+    public Docket createRestApi() {
+        return new Docket(DocumentationType.SWAGGER_2)
+                .apiInfo(apiInfo())
+                .select()
+                .apis(RequestHandlerSelectors.basePackage(configConstant.swaggerPackage))
+                .paths(PathSelectors.any())
+                .build()
+                //添加登录认证,可以使用token
+                .securityContexts(securityContexts())
+                .securitySchemes(securitySchemes())
+                ;
+    }
+
+    private ApiInfo apiInfo() {
+        return new ApiInfoBuilder()
+                .title(configConstant.swaggerTitle)
+                .description(configConstant.swaggerDescription)
+                .version(configConstant.swaggerVersion)
+                .build();
+    }
+
+    private List<ApiKey> securitySchemes() {
+        //设置请求头信息
+        List<ApiKey> result = new ArrayList<>();
+//        ApiKey apiKey = new ApiKey("Authorization", "Authorization", "header");
+        ApiKey apiKey = new ApiKey("Authorization", "token", "header");
+        result.add(apiKey);
+        return result;
+
+    }
+
+
+    private List<SecurityContext> securityContexts() {
+
+        SecurityContext context = SecurityContext.builder()
+                .securityReferences(defaultAuth())
+                .build();
+
+        return Lists.newArrayList(context);
+
+    }
+
+    private List<SecurityReference> defaultAuth() {
+        List<SecurityReference> result = new ArrayList<>();
+        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
+        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
+        authorizationScopes[0] = authorizationScope;
+        result.add(new SecurityReference("Authorization", authorizationScopes));
+        return result;
+    }
+}

+ 164 - 0
zhoushan-system-api/src/main/java/com/fdage/shiro/JWTFilter.java

@@ -0,0 +1,164 @@
+package com.fdage.shiro;
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.log4j.Log4j2;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+
+/**
+ * 自定义拦截规则
+ */
+@Log4j2
+public class JWTFilter extends BasicHttpAuthenticationFilter {
+
+
+
+    /**
+     * 判断用户是否想要登入。
+     * 检测header里面是否包含token字段即可
+     *
+     * return false:直接不校验就可以访问api
+     */
+    @Override
+    protected boolean isLoginAttempt(ServletRequest request, ServletResponse response) {
+        HttpServletRequest req = (HttpServletRequest) request;
+        String token = req.getHeader("token");
+
+        if (StringUtils.isEmpty(token)) {
+            log.error("token is null");
+
+            // 先这样抛出异常,这个种不是接口的形式
+//            throw new AuthenticationException("token is null");
+//            throw new JwtAuthenticationException(5008, "token is null 123");
+//            throw new BaseRuntimeException(5001, "token is null");
+
+            // 直接返回Response信息
+//            JSONObject jsonObject = new JSONObject();
+//            jsonObject.put("status", 5001);
+//            jsonObject.put("message", "token is null 123");
+//            this.writeResponse(response, jsonObject);
+
+            // 直接返回false, ExceptionController的ShiroException.class是能捕捉到5003那个异常的
+//            return false;
+        }
+
+        return true;
+
+    }
+
+
+
+    /**
+     * 执行登录验证
+     */
+    @Override
+    protected boolean executeLogin(ServletRequest request, ServletResponse response) {
+        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
+        String token = httpServletRequest.getHeader("token");
+        JWTToken jwtToken = new JWTToken(token);
+
+        // 提交给realm进行登入,如果错误他会抛出异常并被捕获
+        getSubject(request, response).login(jwtToken);
+
+        // 如果没有抛出异常则代表登入成功,返回true
+        return true;
+    }
+
+    /**
+     * 这里我们详细说明下为什么最终返回的都是true,即允许访问
+     * 例如我们提供一个地址 GET /article
+     * 登入用户和游客看到的内容是不同的
+     * 如果在这里返回了false,请求会被直接拦截,用户看不到任何东西
+     * 所以我们在这里返回true,Controller中可以通过 subject.isAuthenticated() 来判断用户是否登入
+     * 如果有些资源只有登入用户才能访问,我们只需要在方法上面加上 @RequiresAuthentication 注解即可
+     * 但是这样做有一个缺点,就是不能够对GET,POST等请求进行分别过滤鉴权(因为我们重写了官方的方法),但实际上对应用影响不大
+     *
+     * owen:
+     *  return false ,表示全局拦截,必须登录才可以访问接口,除非配置了免拦截
+     *  "" @RequiresAuthentication 现在不需要配置这个注解来免登录
+     *
+     */
+    @Override
+    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
+        if (isLoginAttempt(request, response)) {
+            try {
+                executeLogin(request, response);
+
+            } catch (Exception e) {
+                /** 这个异常需要自己写,全局捕获不了*/
+
+                // 认证出现异常,传递错误信息msg
+                String msg = e.getMessage();
+                // 获取应用异常(该Cause是导致抛出此throwable(异常)的throwable(异常))
+                Throwable throwable = e.getCause();
+                JSONObject jsonObject = new JSONObject();
+                if (throwable instanceof JwtAuthenticationException) {
+                    jsonObject.put("code", ((JwtAuthenticationException) throwable).getCode());
+                    jsonObject.put("msg", ((JwtAuthenticationException) throwable).getMsg());
+                }else{
+                    log.error(msg);
+                    jsonObject.put("code", 5002);
+                    jsonObject.put("msg", "token invalid");
+                }
+                // 直接返回Response信息
+                this.writeResponse(response, jsonObject);
+//                return false;
+            }
+        }
+        // return false 前端没有响应,接收不到异常
+        return true;
+    }
+
+    /**
+     * 对跨域提供支持
+     * 只对需要token验证的有效,不需要验证的还是需要用注解处理一下
+     *
+     */
+    @Override
+    protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
+        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
+        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
+        httpServletResponse.setHeader("Access-control-Allow-Origin", httpServletRequest.getHeader("Origin"));
+        httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE");
+        httpServletResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers"));
+        // 跨域时会首先发送一个option请求,这里我们给option请求直接返回正常状态
+        if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {
+            httpServletResponse.setStatus(HttpStatus.OK.value());
+            return false;
+        }
+        return super.preHandle(request, response);
+    }
+
+
+    /**
+     * 无需转发,直接返回Response信息
+     *
+     */
+    private void writeResponse(ServletResponse response, JSONObject msg) {
+        response.setCharacterEncoding("UTF-8");
+        response.setContentType("application/json; charset=utf-8");
+        ServletOutputStream outputStream = null;
+        try {
+            outputStream = response.getOutputStream();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        assert outputStream != null;
+        PrintWriter printWriter = new PrintWriter(outputStream, true);
+        printWriter.write(msg.toString());//直接将json输出到页面
+        printWriter.flush();
+        printWriter.close();
+
+    }
+}

+ 23 - 0
zhoushan-system-api/src/main/java/com/fdage/shiro/JWTToken.java

@@ -0,0 +1,23 @@
+package com.fdage.shiro;
+
+import org.apache.shiro.authc.AuthenticationToken;
+
+public class JWTToken implements AuthenticationToken {
+
+    // 密钥
+    private String token;
+
+    public JWTToken(String token) {
+        this.token = token;
+    }
+
+    @Override
+    public Object getPrincipal() {
+        return token;
+    }
+
+    @Override
+    public Object getCredentials() {
+        return token;
+    }
+}

+ 73 - 0
zhoushan-system-api/src/main/java/com/fdage/shiro/JWTUtil.java

@@ -0,0 +1,73 @@
+package com.fdage.shiro;//package com.xiaoan.web.shiro;
+//
+//import com.auth0.jwt.JWT;
+//import com.auth0.jwt.JWTVerifier;
+//import com.auth0.jwt.algorithms.Algorithm;
+//import com.auth0.jwt.exceptions.JWTDecodeException;
+//import com.auth0.jwt.interfaces.DecodedJWT;
+//import lombok.extern.log4j.Log4j2;
+//
+//import java.io.UnsupportedEncodingException;
+//import java.util.Date;
+//
+//@Log4j2
+//public class JWTUtil {
+//
+//    // 过期时间24小时
+//    private static final long EXPIRE_TIME = 24*60*60*1000;
+//
+//
+//    /**
+//     * 校验token是否正确
+//     * @param token 密钥
+//     * @param secret 用户的密码
+//     * @return 是否正确
+//     */
+//    public static boolean verify(String token, String username, String secret) {
+//        try {
+//            Algorithm algorithm = Algorithm.HMAC256(secret);
+//            JWTVerifier verifier = JWT.require(algorithm)
+//                    .withClaim("username", username)
+//                    .build();
+//            DecodedJWT jwt = verifier.verify(token);
+//            return true;
+//        } catch (Exception e) {
+//            e.getMessage();
+//            log.error(e.getMessage());
+//            return false;
+//        }
+//    }
+//
+//    /**
+//     * 获得token中的信息无需secret解密也能获得
+//     * @return token中包含的用户名
+//     */
+//    public static String getUsername(String token) {
+//        try {
+//            DecodedJWT jwt = JWT.decode(token);
+//            return jwt.getClaim("username").asString();
+//        } catch (JWTDecodeException e) {
+//            return null;
+//        }
+//    }
+//
+//    /**
+//     * 生成签名,5min后过期
+//     * @param username 用户名
+//     * @param secret 用户的密码
+//     * @return 加密的token
+//     */
+//    public static String sign(String username, String secret) {
+//        try {
+//            Date date = new Date(System.currentTimeMillis()+EXPIRE_TIME);
+//            Algorithm algorithm = Algorithm.HMAC256(secret);
+//            // 附带username信息
+//            return JWT.create()
+//                    .withClaim("username", username)
+//                    .withExpiresAt(date)
+//                    .sign(algorithm);
+//        } catch (UnsupportedEncodingException e) {
+//            return null;
+//        }
+//    }
+//}

+ 34 - 0
zhoushan-system-api/src/main/java/com/fdage/shiro/JwtAuthenticationException.java

@@ -0,0 +1,34 @@
+package com.fdage.shiro;
+
+import org.apache.shiro.ShiroException;
+
+public class JwtAuthenticationException extends ShiroException {
+
+    private static final long serialVersionUID = 2899335020273674736L;
+
+    private int code;
+
+    private String msg;
+
+    public JwtAuthenticationException(int code, String msg){
+        super(msg);
+        this.code = code;
+        this.msg = msg;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+}

+ 225 - 0
zhoushan-system-api/src/main/java/com/fdage/shiro/JwtUtil2.java

@@ -0,0 +1,225 @@
+package com.fdage.shiro;
+
+import com.auth0.jwt.JWT;
+import com.auth0.jwt.exceptions.JWTDecodeException;
+import com.auth0.jwt.interfaces.Claim;
+import com.auth0.jwt.interfaces.DecodedJWT;
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.JwtBuilder;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+
+import java.util.*;
+
+public class JwtUtil2 {
+
+    //生成签名的时候使用的秘钥secret
+    private static final String SECRET = "XX#$%()(#*!()!KL<><MQLMNQNQJQK&sdfkjsdrow32234545fdf>?N<:{LWPW";
+
+    /**
+     * 用户登录成功后生成Jwt
+     * 使用Hs256算法  私匙使用用户密码
+     *
+     * @param ttlMillis jwt过期时间
+     * @param userName  用户名
+     * @return
+     */
+    public static String createJWT(long ttlMillis, String userName) {
+        //指定签名的时候使用的签名算法,也就是header那部分,jjwt已经将这部分内容封装好了。
+        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
+
+        //生成JWT的时间
+        long nowMillis = System.currentTimeMillis();
+        Date now = new Date(nowMillis);
+
+        //创建payload的私有声明(根据特定的业务需要添加,如果要拿这个做验证,一般是需要和jwt的接收方提前沟通好验证方式的)
+        Map<String, Object> claims = new HashMap<String, Object>();
+        claims.put("userName", userName);
+
+        //下面就是在为payload添加各种标准声明和私有声明了
+        //这里其实就是new一个JwtBuilder,设置jwt的body
+        JwtBuilder builder = Jwts.builder()
+                //如果有私有声明,一定要先设置这个自己创建的私有的声明,这个是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明的
+                .setClaims(claims)
+                //设置jti(JWT ID):是JWT的唯一标识,根据业务需要,这个可以设置为一个不重复的值,主要用来作为一次性token,从而回避重放攻击。
+                .setId(UUID.randomUUID().toString())
+                //iat: jwt的签发时间
+                .setIssuedAt(now)
+                //代表这个JWT的主体,即它的所有人,这个是一个json格式的字符串,可以存放什么userid,roldid之类的,作为什么用户的唯一标志。
+                .setSubject(userName)
+                //设置签名使用的签名算法和签名使用的秘钥
+                .signWith(signatureAlgorithm, SECRET);
+
+        if (ttlMillis >= 0) {
+            long expMillis = nowMillis + ttlMillis;
+            Date exp = new Date(expMillis);
+            //设置过期时间
+            builder.setExpiration(exp);
+        }/*else{
+            //设置过期时间半小时
+            DateTime expDate = new DateTime().plusMinutes(30);
+            builder.setExpiration(expDate.toDate());
+        }*/
+        return builder.compact();
+    }
+
+
+    /**
+     * Token的解密
+     * @param token 加密后的token
+     * @return
+     */
+    public static Claims parseJWT(String token) {
+        //得到DefaultJwtParser
+        Claims claims = Jwts.parser()
+                //设置签名的秘钥
+                .setSigningKey(SECRET)
+                //设置需要解析的jwt
+                .parseClaimsJws(token).getBody();
+        return claims;
+    }
+
+
+    /**
+     * 校验token
+     * 在这里可以使用官方的校验,我这里校验的是token中携带的密码于数据库一致的话就校验通过
+     * @param token
+     * @param userName
+     * @return
+     */
+    public static Boolean isVerify(String token, String userName) {
+
+        //得到DefaultJwtParser
+        Claims claims = Jwts.parser()
+                //设置签名的秘钥
+                .setSigningKey(SECRET)
+                //设置需要解析的jwt
+                .parseClaimsJws(token).getBody();
+
+        if (claims.get("userName").equals(userName)) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 获得token中的信息无需secret解密也能获得
+     *
+     * @return token中包含的用户名
+     */
+    public static String getUsername(String token) {
+        try {
+            DecodedJWT jwt = JWT.decode(token);
+            return jwt.getClaim("userName").asString();
+        } catch (JWTDecodeException e) {
+            return null;
+        }
+    }
+
+
+
+    public static List getUserRole(String token) {
+//        try {
+            DecodedJWT jwt = JWT.decode(token);
+            Claim role = jwt.getClaim("role");
+            return role.as(List.class);
+//        } catch (JWTDecodeException e) {
+//            return null;
+//        }
+    }
+
+
+    public static String createJWT(long ttlMillis, Map<String, Object> paramMap) {
+        //指定签名的时候使用的签名算法,也就是header那部分,jjwt已经将这部分内容封装好了。
+        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
+
+        String userName = paramMap.get("userName").toString();
+
+        //生成JWT的时间
+        long nowMillis = System.currentTimeMillis();
+        Date now = new Date(nowMillis);
+
+        //创建payload的私有声明(根据特定的业务需要添加,如果要拿这个做验证,一般是需要和jwt的接收方提前沟通好验证方式的)
+        Map<String, Object> claims = new HashMap<String, Object>();
+        claims.put("userName", userName);
+        claims.put("id", paramMap.get("id"));
+        claims.put("role", paramMap.get("role"));
+
+        //下面就是在为payload添加各种标准声明和私有声明了
+        //这里其实就是new一个JwtBuilder,设置jwt的body
+        JwtBuilder builder = Jwts.builder()
+                //如果有私有声明,一定要先设置这个自己创建的私有的声明,这个是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明的
+                .setClaims(claims)
+                //设置jti(JWT ID):是JWT的唯一标识,根据业务需要,这个可以设置为一个不重复的值,主要用来作为一次性token,从而回避重放攻击。
+                .setId(UUID.randomUUID().toString())
+                //iat: jwt的签发时间
+                .setIssuedAt(now)
+                //代表这个JWT的主体,即它的所有人,这个是一个json格式的字符串,可以存放什么userid,roldid之类的,作为什么用户的唯一标志。
+                .setSubject(userName)
+                //设置签名使用的签名算法和签名使用的秘钥
+                .signWith(signatureAlgorithm, SECRET);
+
+        if (ttlMillis >= 0) {
+            long expMillis = nowMillis + ttlMillis;
+            Date exp = new Date(expMillis);
+            //设置过期时间
+            builder.setExpiration(exp);
+        }/*else{
+            //设置过期时间半小时
+            DateTime expDate = new DateTime().plusMinutes(30);
+            builder.setExpiration(expDate.toDate());
+        }*/
+        return builder.compact();
+    }
+
+    public static Long getUserId(String token) {
+        try {
+            DecodedJWT jwt = JWT.decode(token);
+            Claim id = jwt.getClaim("id");
+            return id.asLong();
+        } catch (JWTDecodeException e) {
+            return null;
+        }
+    }
+
+    public static void main(String[] args) {
+//        test3();
+//        test2();
+        long nowMillis = System.currentTimeMillis();
+        System.out.println(nowMillis);
+        Date exp = new Date(nowMillis);
+        System.out.println(exp);
+    }
+
+    public static void test2(){
+        String token = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsInJvbGUiOlsiYWRtaW4iLCJyb290Il0sImlkIjoxLCJ1c2VyTmFtZSI6ImFkbWluIiwiaWF0IjoxNTgzODA5MzkzLCJqdGkiOiJkNjZiZTFkYi00MTQ0LTQxMTYtYTNlNi01ZDBjNjhlNTI3ODAifQ.-4AdsVP2RwmPS2grtO4aC8ov9PwkilzaGdThGetBJok";
+        System.out.println(getUserRole(token));
+
+    }
+
+    public static void test3(){
+        HashMap<String, Object> map = new HashMap<>();
+
+        ArrayList<Object> list = new ArrayList<>();
+        list.add("admin");
+        list.add("root");
+
+        map.put("userName", "admin");
+        map.put("id", Long.valueOf("1"));
+        map.put("role", list);
+
+        String token = createJWT(-1, map);
+        System.out.println(token);
+
+        Boolean isVerify = isVerify(token, "admin");
+        System.out.println(isVerify);
+
+    }
+
+    private static void testList(){
+        ArrayList<Object> list = new ArrayList<>();
+        list.add("admin");
+        list.add("root");
+    }
+
+}

+ 148 - 0
zhoushan-system-api/src/main/java/com/fdage/shiro/MyRealm.java

@@ -0,0 +1,148 @@
+package com.fdage.shiro;
+
+import com.fdage.pojo.TbResource;
+import com.fdage.pojo.TbRole;
+import com.fdage.pojo.TbUser;
+import com.fdage.service.IResourceService;
+import com.fdage.service.IRoleService;
+import com.fdage.service.IUserService;
+import lombok.extern.log4j.Log4j2;
+import org.apache.shiro.authc.AuthenticationException;
+import org.apache.shiro.authc.AuthenticationInfo;
+import org.apache.shiro.authc.AuthenticationToken;
+import org.apache.shiro.authc.SimpleAuthenticationInfo;
+import org.apache.shiro.authz.AuthorizationInfo;
+import org.apache.shiro.authz.SimpleAuthorizationInfo;
+import org.apache.shiro.realm.AuthorizingRealm;
+import org.apache.shiro.subject.PrincipalCollection;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Service;
+
+import java.math.BigInteger;
+import java.util.*;
+
+/**
+ * 配置不校验的话,是不会走这个方法的
+ */
+@Log4j2
+@Service
+public class MyRealm extends AuthorizingRealm {
+
+
+
+    @Autowired
+    private RedisTemplate<String, String> redisTemplate;
+
+    @Autowired
+    private IUserService userService;
+
+    @Autowired
+    private IRoleService roleService;
+
+    @Autowired
+    private IResourceService resourceService;
+
+
+
+    /**
+     * 大坑!,必须重写此方法,不然Shiro会报错
+     */
+    @Override
+    public boolean supports(AuthenticationToken token) {
+        return token instanceof JWTToken;
+    }
+
+    /**
+     * 只有当需要检测用户权限的时候才会调用此方法,例如checkRole,checkPermission之类的
+     *
+     * principals: 是token
+     */
+    @Override
+    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
+        String username = JwtUtil2.getUsername(principals.toString());
+
+        TbUser dbUserEntity = userService.findByUserName(username);
+
+        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
+
+        Map<String, Set<String>> resultMap = getRole(dbUserEntity);
+        Set<String> rolekeys = resultMap.get("role");
+
+
+        // 获取用户权限
+        Set<String> permissions = new HashSet<>();
+        try {
+            List<TbResource> userPermissionList = resourceService.getResourcesByUserPermission(dbUserEntity);
+            for (TbResource i : userPermissionList) {
+                permissions.add(i.getResourceKey());
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        // 设置角色、权限
+        simpleAuthorizationInfo.addRoles(rolekeys);
+        simpleAuthorizationInfo.addStringPermissions(permissions);
+        return simpleAuthorizationInfo;
+    }
+
+    /**
+     * 获取角色相关信息
+     */
+    private Map<String, Set<String>> getRole(TbUser userEntity){
+
+        Set<Long> roleIds = userService.findUserRoleByUserId(userEntity.getId());
+        Set<String> roleKeys = new HashSet<>();
+        for (Long i : roleIds) {
+            TbRole dbRoleEntity = roleService.findById(i.longValue());
+            roleKeys.add(dbRoleEntity.getRoleKey());
+        }
+
+        HashMap<String, Set<String>> resultMap = new HashMap<>();
+        resultMap.put("role", roleKeys);
+
+        return resultMap;
+    }
+
+    /**
+     * 默认使用此方法进行用户名正确与否验证,错误抛出异常即可。
+     */
+    @Override
+    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException {
+        String token = (String) auth.getCredentials();
+        // 解密获得username,用于和数据库进行对比
+        if(token == null){
+            log.error("error token");
+            throw new JwtAuthenticationException(5001, "token is null");
+        }
+        String username = JwtUtil2.getUsername(token);
+        if (username == null) {
+            log.error("error token username");
+            throw new JwtAuthenticationException(5001, "token invalid");
+        }
+
+        TbUser userEntity = userService.findByUserName(username);
+        if (userEntity == null) {
+            log.error("error token userEntity");
+            throw new JwtAuthenticationException(5001, "User didn't existed!");
+        }
+
+        // 校验请求token是否跟redis token一致
+        String redisToken = redisTemplate.opsForValue().get(userEntity.getUserName());
+        if (!token.equals(redisToken)) {
+            log.error("error token redis");
+            throw new JwtAuthenticationException(5001, "token invalid");
+
+        }
+
+
+        if (! JwtUtil2.isVerify(token, username)) {
+            log.error("error token username or password");
+            throw new JwtAuthenticationException(5001, "token invalid");
+        }
+
+
+        return new SimpleAuthenticationInfo(token, token, "my_realm");
+    }
+}

+ 156 - 0
zhoushan-system-api/src/main/java/com/fdage/shiro/ShiroConfig.java

@@ -0,0 +1,156 @@
+package com.fdage.shiro;
+
+import com.alibaba.fastjson.serializer.SerializerFeature;
+import com.alibaba.fastjson.support.config.FastJsonConfig;
+import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
+import lombok.extern.log4j.Log4j2;
+import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
+import org.apache.shiro.mgt.DefaultSubjectDAO;
+import org.apache.shiro.spring.LifecycleBeanPostProcessor;
+import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
+import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
+import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
+import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
+import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.DependsOn;
+import org.springframework.http.MediaType;
+
+import javax.servlet.Filter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Log4j2
+@Configuration
+public class ShiroConfig {
+
+    @Bean("securityManager")
+    public DefaultWebSecurityManager getManager(MyRealm realm) {
+        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
+        // 使用自己的realm
+        manager.setRealm(realm);
+
+        /*
+         * 关闭shiro自带的session,详情见文档
+         * http://shiro.apache.org/session-management.html#SessionManagement-StatelessApplications%28Sessionless%29
+         */
+        DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
+        DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();
+        defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
+        subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
+        manager.setSubjectDAO(subjectDAO);
+
+        return manager;
+    }
+
+    @Bean("shiroFilter")
+    public ShiroFilterFactoryBean factory(DefaultWebSecurityManager securityManager) {
+        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
+
+        // 添加自己的过滤器并且取名为jwt
+        Map<String, Filter> filterMap = new HashMap<>();
+        filterMap.put("jwt", new JWTFilter());
+
+        factoryBean.setFilters(filterMap);
+
+        factoryBean.setSecurityManager(securityManager);
+        factoryBean.setUnauthorizedUrl("/401");
+
+        /*
+         * 自定义url规则
+         * http://shiro.apache.org/web.html#urls-
+         */
+        Map<String, String> filterRuleMap = new HashMap<>();
+
+        // 不拦截
+        filterRuleMap.put("/login", "anon");
+        filterRuleMap.put("/logout", "anon");
+        filterRuleMap.put("/", "anon");
+
+
+        // swagger 不拦截
+        filterRuleMap.put("/swagger-resources/**", "anon");
+        filterRuleMap.put("/webjars/**", "anon");
+        filterRuleMap.put("/v2/**", "anon");
+        filterRuleMap.put("/doc.html/**", "anon");
+
+
+        // 所有请求通过我们自己的JWT Filter
+        filterRuleMap.put("/zhoushan/**", "jwt");
+
+
+        // 访问401和404页面不通过我们的Filter
+        filterRuleMap.put("/401", "anon");
+        factoryBean.setFilterChainDefinitionMap(filterRuleMap);
+        return factoryBean;
+    }
+
+    /**
+     * 下面的代码是添加注解支持
+     */
+    @Bean
+    @DependsOn("lifecycleBeanPostProcessor")
+    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
+        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
+        // 强制使用cglib,防止重复代理和可能引起代理出错的问题
+        // https://zhuanlan.zhihu.com/p/29161098
+        defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
+        return defaultAdvisorAutoProxyCreator;
+    }
+
+    @Bean
+    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
+        return new LifecycleBeanPostProcessor();
+    }
+
+    @Bean
+    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
+        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
+        advisor.setSecurityManager(securityManager);
+        return advisor;
+    }
+
+
+    /**
+     * fastJson相关设置
+     * Dto包含json,需要配置不然会异常
+     * @return
+     */
+    @Bean
+    public HttpMessageConverters customConverters() {
+//        log.warn("run customConverters");
+
+
+        FastJsonHttpMessageConverter fastJson = new FastJsonHttpMessageConverter();
+
+        // 创建FastJson信息转换对象
+        FastJsonConfig fastJsonConfig = new FastJsonConfig();
+
+
+        // 设置全程返回时间
+        fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
+        // 设置返回值为null是时输出,不写的话,null 字段 不返回。也可以设置返回空串
+        fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteNullStringAsEmpty);
+        fastJson.setFastJsonConfig(fastJsonConfig);
+
+        //3、中文乱码解决方案
+        List<MediaType> mediaTypeList = new ArrayList<>();
+        mediaTypeList.add(MediaType.APPLICATION_JSON_UTF8);
+        mediaTypeList.add(MediaType.valueOf("text/html;charset=UTF-8"));
+
+
+        //4、将转换规则应用于转换对象
+        fastJson.setSupportedMediaTypes(mediaTypeList);
+
+
+        return new HttpMessageConverters(fastJson);
+    }
+
+
+
+
+
+}

+ 676 - 0
zhoushan-system-api/src/main/java/com/fdage/util/FileUtil.java

@@ -0,0 +1,676 @@
+package com.fdage.util;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fdage.respon.ResponExhibition;
+import lombok.extern.slf4j.Slf4j;
+//import org.apache.commons.codec.digest.DigestUtils;
+//import org.apache.tools.zip.ZipEntry;
+//import org.apache.tools.zip.ZipFile;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+
+/**
+ * 文件管理工具类
+ * Created by Hb_zzZ on 2018/11/26.
+ */
+@Slf4j
+public class FileUtil {
+
+    /**
+     * 上传文件
+     * @param file 文件
+     * @param path 文件存放路径
+     * @param fileName 源文件名
+     * @return
+     */
+    public static boolean upload(MultipartFile file, String path, String fileName){
+
+        // 生成新的文件名
+        //String realPath = path + "/" + FileNameUtils.getFileName(fileName);
+
+        //使用原文件名
+        String realPath = path + "/" + fileName;
+
+        File dest = new File(realPath);
+
+        //判断文件父目录是否存在
+        if(!dest.getParentFile().exists()){
+            dest.getParentFile().mkdir();
+        }
+
+        try {
+            //保存文件
+            file.transferTo(dest);
+            return true;
+        } catch (IllegalStateException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+            return false;
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    public static void writeFile(String filePath,String str) throws IOException {
+        File fout = new File(filePath);
+        FileOutputStream fos = new FileOutputStream(fout);
+        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos));
+        bw.write(str);
+        bw.close();
+    }
+
+    //按行读文件
+    public static String readFile(String path)throws Exception
+    {
+        File f = new File(path);
+        if(!f.exists()){
+            return null;
+        }
+
+        ByteArrayOutputStream bos = new ByteArrayOutputStream((int)f.length());
+        BufferedInputStream in = null;
+        try{
+            in = new BufferedInputStream(new FileInputStream(f));
+            int buf_size = 1024;
+            byte[] buffer = new byte[buf_size];
+            int len = 0;
+            while(-1 != (len = in.read(buffer,0,buf_size))){
+                bos.write(buffer,0,len);
+            }
+            return bos.toString();
+        }catch (IOException e) {
+            e.printStackTrace();
+            throw e;
+        }finally{
+            try{
+                in.close();
+            }catch (IOException e) {
+                e.printStackTrace();
+            }
+            bos.close();
+        }
+    }
+
+    //按行读文件
+    public static int readLineCount(String path)throws Exception
+    {
+        File f = new File(path);
+        if(!f.exists()){
+            return 0;
+        }
+
+        int count = 0;
+        //BufferedReader是可以按行读取文件
+        FileInputStream inputStream = new FileInputStream(path);
+        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
+
+        String str = null;
+        while((str = bufferedReader.readLine()) != null)
+        {
+            if(str==null||str.trim().equals(""))
+            {
+                continue;
+            }
+            else
+            {
+                ++count;
+            }
+        }
+
+        //close
+        inputStream.close();
+        bufferedReader.close();
+
+        return count;
+    }
+
+    //按行读文件
+    public static List<String> readFileByLine(String path)throws Exception
+    {
+        File f = new File(path);
+        if(!f.exists()){
+            return null;
+        }
+
+        List<String> result = new ArrayList<String>();
+        //BufferedReader是可以按行读取文件
+        FileInputStream inputStream = new FileInputStream(path);
+        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
+
+        String str = null;
+        while((str = bufferedReader.readLine()) != null)
+        {
+            if(str==null||str.trim().equals(""))
+            {
+                continue;
+            }
+            else
+            {
+                result.add(str);
+            }
+        }
+
+        //close
+        inputStream.close();
+        bufferedReader.close();
+
+        return result;
+    }
+
+    public static void decodeBase64(String path,String str) throws Exception{
+        byte[] bt = null;
+        try {
+            sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();
+
+            if(str.startsWith("data:image/png;base64,"))
+            {
+                bt = decoder.decodeBuffer( str.replace("data:image/png;base64,", "") );
+            }
+            else if(str.startsWith("data:image/jpeg;base64,"))
+            {
+                bt = decoder.decodeBuffer( str.replace("data:image/jpeg;base64,", "") );
+            }
+            else if(str.startsWith("data:image/bmp;base64,"))
+            {
+                bt = decoder.decodeBuffer( str.replace("data:image/bmp;base64,", "") );
+            }
+            else
+            {
+                log.error("FileUtil-decodeBase64:"+path);
+                return;
+            }
+
+            //bt = decoder.decodeBuffer(str);
+            writeBinary(bt,path);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static void writeBinary(byte[] buf,String filePath)throws Exception
+    {
+        File fout = new File(filePath);
+        if(!fout.getParentFile().exists())
+        {
+            fout.getParentFile().mkdirs();
+        }
+        FileOutputStream fos = new FileOutputStream(fout);
+        ByteArrayInputStream stream = new ByteArrayInputStream(buf);
+        BufferedOutputStream bos = new BufferedOutputStream(fos);//设置输出路径
+        BufferedInputStream bis = new BufferedInputStream(stream);
+        int b = -1;
+        while ((b = bis.read()) != -1) {
+            bos.write(b);
+        }
+        bis.close();
+        bos.close();
+    }
+
+    public static boolean deleteFile(String sPath) {
+
+        boolean flag = false;
+        File file = new File(sPath);
+        // 路径为文件且不为空则进行删除
+        if (file.isFile() && file.exists()) {
+            file.delete();
+            flag = true;
+        }
+        return flag;
+    }
+
+    //下载多个文件
+//    public static void downLoadFromUrls(String urlStr,String fileName,String savePath,String projectNum){
+//
+//        try
+//        {
+//            File file = new File(savePath+File.separator+fileName);
+//            if(file.exists())
+//            {
+//                List<String> list = readFileByLine(savePath+File.separator+fileName);
+//                for(int i=0;i<list.size();++i)
+//                {
+//                    String str = list.get(i);
+//                    String name = str.substring(str.lastIndexOf("/")+1);
+//                    downLoadFromUrl( str, name, savePath+File.separator+name, projectNum);
+//                }
+//            }
+//            else
+//            {
+//                downLoadFromUrl( urlStr, fileName, savePath, projectNum);
+//            }
+//        }
+//        catch(Exception e)
+//        {
+//            log.info("下载场景文件失败!"+projectNum+":"+urlStr);
+//            e.printStackTrace();
+//            StringWriter trace=new StringWriter();
+//            e.printStackTrace(new PrintWriter(trace));
+//            log.error(trace.toString());
+//            deleteFile(savePath+File.separator+fileName);
+//            downLoadFromUrls( urlStr, fileName, savePath, projectNum);
+//        }
+//    }
+
+//    public static void downLoadFromUrl(String urlStr,String fileName,String savePath,String projectNum){
+//        try
+//        {
+//            URL url = new URL(urlStr);
+//            HttpURLConnection conn = (HttpURLConnection)url.openConnection();
+//            //设置超时间为3秒
+//            conn.setConnectTimeout(3*1000);
+//            //防止屏蔽程序抓取而返回403错误
+//            conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
+//
+//            //得到输入流
+//            InputStream inputStream = conn.getInputStream();
+//            //获取自己数组
+//            byte[] getData = readInputStream(inputStream);
+//
+//            //文件保存位置
+//            File saveDir = new File(savePath);
+//            if(!saveDir.exists()){
+//                saveDir.mkdir();
+//            }
+//            File file = new File(saveDir+File.separator+fileName);
+//            FileOutputStream fos = new FileOutputStream(file);
+//            fos.write(getData);
+//
+//            //获取文件md5
+//            DigestUtils.md5Hex(new FileInputStream(saveDir+File.separator+fileName));
+//            if(fos!=null){
+//                fos.close();
+//            }
+//            if(inputStream!=null){
+//                inputStream.close();
+//            }
+//            log.info("下载场景文件成功!"+projectNum+":"+urlStr);
+//        }
+//        catch(FileNotFoundException e)
+//        {
+//            log.info("要下载场景的文件不存在"+projectNum+":"+urlStr);
+//        }
+//        catch(Exception e)
+//        {
+//            log.info("下载场景文件失败!"+projectNum+":"+urlStr);
+//            e.printStackTrace();
+//            StringWriter trace=new StringWriter();
+//            e.printStackTrace(new PrintWriter(trace));
+//            log.error(trace.toString());
+//            deleteFile(savePath+File.separator+fileName);
+//            downLoadFromUrl( urlStr, fileName, savePath, projectNum);
+//        }
+//    }
+
+    public static void downLoadFromUrl(String urlStr,String fileName,String savePath){
+        try
+        {
+            //文件保存位置
+            File saveDir = new File(savePath);
+            if(!saveDir.exists()){
+                saveDir.mkdir();
+            }
+            File file = new File(savePath+File.separator+fileName);
+            if(file.exists())
+            {
+                return;
+            }
+
+            URL url = new URL(urlStr);
+            HttpURLConnection conn = (HttpURLConnection)url.openConnection();
+            //设置超时间为3秒
+            conn.setConnectTimeout(3*1000);
+            //防止屏蔽程序抓取而返回403错误
+            conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
+
+            //得到输入流
+            InputStream inputStream = conn.getInputStream();
+            //获取自己数组
+            byte[] getData = readInputStream(inputStream);
+
+            FileOutputStream fos = new FileOutputStream(file);
+            fos.write(getData);
+            if(fos!=null){
+                fos.close();
+            }
+            if(inputStream!=null){
+                inputStream.close();
+            }
+            log.info("下载文件成功!"+":"+urlStr);
+        }
+        catch(FileNotFoundException e)
+        {
+            log.info("要下载的文件不存在:"+urlStr);
+        }
+        catch(Exception e)
+        {
+            log.info("下载文件失败!"+":"+urlStr);
+            e.printStackTrace();
+            StringWriter trace=new StringWriter();
+            e.printStackTrace(new PrintWriter(trace));
+            log.error(trace.toString());
+            deleteFile(savePath+File.separator+fileName);
+            downLoadFromUrl( urlStr, fileName, savePath);
+        }
+    }
+
+    public static byte[] readInputStream(InputStream inputStream) throws IOException {
+        byte[] buffer = new byte[1024];
+        int len = 0;
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        while((len = inputStream.read(buffer)) != -1) {
+            bos.write(buffer, 0, len);
+        }
+        bos.close();
+        return bos.toByteArray();
+    }
+
+//    public static void decompress(String srcPath, String dest) throws Exception {
+//
+//        File file = new File(srcPath);
+//
+//        if (!file.exists()) {
+//
+//            throw new RuntimeException(srcPath + "所指文件不存在");
+//
+//        }
+//
+//        ZipFile zf = new ZipFile(file);
+//
+//        Enumeration entries = zf.getEntries();
+//
+//        ZipEntry entry = null;
+//
+//        while (entries.hasMoreElements()) {
+//
+//            entry = (ZipEntry) entries.nextElement();
+//
+//            log.info("解压" + entry.getName());
+//
+//            if (entry.isDirectory()) {
+//
+//                String dirPath = dest + File.separator + entry.getName();
+//
+//                File dir = new File(dirPath);
+//
+//                dir.mkdirs();
+//
+//            } else {
+//
+//                // 表示文件
+//
+//                File f = new File(dest + File.separator + entry.getName());
+//
+//                if (!f.exists()) {
+//
+//                    //String dirs = FileUtils.getParentPath(f);
+//                    String dirs =  f.getParent();
+//
+//                    File parentDir = new File(dirs);
+//
+//                    parentDir.mkdirs();
+//
+//
+//
+//                }
+//
+//                f.createNewFile();
+//
+//                // 将压缩文件内容写入到这个文件中
+//
+//                InputStream is = zf.getInputStream(entry);
+//
+//                FileOutputStream fos = new FileOutputStream(f);
+//
+//
+//
+//                int count;
+//
+//                byte[] buf = new byte[8192];
+//
+//                while ((count = is.read(buf)) != -1) {
+//
+//                    fos.write(buf, 0, count);
+//
+//                }
+//
+//                is.close();
+//
+//                fos.close();
+//
+//            }
+//
+//        }
+//
+//    }
+
+    public static boolean copyFile(String srcFileName, String destFileName,  boolean overlay) {
+        File srcFile = new File(srcFileName);
+
+        // 判断源文件是否存在
+        if (!srcFile.exists()) {
+            return false;
+        } else if (!srcFile.isFile()) {
+            return false;
+        }
+
+        // 判断目标文件是否存在
+        File destFile = new File(destFileName);
+        if (destFile.exists()) {
+            // 如果目标文件存在并允许覆盖
+            if (overlay) {
+                // 删除已经存在的目标文件,无论目标文件是目录还是单个文件
+                new File(destFileName).delete();
+            }
+        } else {
+            // 如果目标文件所在目录不存在,则创建目录
+            if (!destFile.getParentFile().exists()) {
+                // 目标文件所在目录不存在
+                if (!destFile.getParentFile().mkdirs()) {
+                    // 复制文件失败:创建目标文件所在目录失败
+                    return false;
+                }
+            }
+        }
+
+        // 复制文件
+        int byteread = 0; // 读取的字节数
+        InputStream in = null;
+        OutputStream out = null;
+
+        try {
+            in = new FileInputStream(srcFile);
+            out = new FileOutputStream(destFile);
+            byte[] buffer = new byte[1024];
+
+            while ((byteread = in.read(buffer)) != -1) {
+                out.write(buffer, 0, byteread);
+            }
+            return true;
+        } catch (FileNotFoundException e) {
+            return false;
+        } catch (IOException e) {
+            return false;
+        } finally {
+            try {
+                if (out != null)
+                    out.close();
+                if (in != null)
+                    in.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    public static String[]readfileNamesForDirectory(String path) throws Exception{
+        File file = new File(path);
+        if(file.isDirectory()) {
+            String[] fileNames = file.list();
+            return fileNames;
+        }
+        return null;
+    }
+
+    public static List<String> readfileNamesForDirectory(String path,String except) throws Exception{
+        File file = new File(path);
+        if(file.isDirectory())
+        {
+            String[] fileNames = file.list();
+            List<String> list = new ArrayList<String>();
+            if(fileNames!=null)
+            {
+                for(int i=0;i<fileNames.length;++i)
+                {
+                    if(fileNames[i].toLowerCase().endsWith(except) )
+                    {
+                        list.add(fileNames[i]);
+                    }
+                }
+            }
+
+            return list;
+        }
+        return null;
+    }
+
+    //删除文件夹
+    public static void delFolder(String folderPath) {
+        try {
+            delAllFile(folderPath); //删除完里面所有内容
+            String filePath = folderPath;
+            filePath = filePath.toString();
+            File myFilePath = new File(filePath);
+            myFilePath.delete(); //删除空文件夹
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    //删除指定文件夹下的所有文件
+    public static boolean delAllFile(String path) {
+        boolean flag = false;
+        File file = new File(path);
+        if (!file.exists()) {
+            return flag;
+        }
+        if (!file.isDirectory()) {
+            return flag;
+        }
+        String[] tempList = file.list();
+        File temp = null;
+        if(tempList!=null)
+        {
+            for (int i = 0; i < tempList.length; i++) {
+                if (path.endsWith(File.separator)) {
+                    temp = new File(path + tempList[i]);
+                } else {
+                    temp = new File(path + File.separator + tempList[i]);
+                }
+                if (temp.isFile()) {
+                    temp.delete();
+                }
+                if (temp.isDirectory()) {
+                    delAllFile(path + "/" + tempList[i]);//先删除文件夹里面的文件
+                    delFolder(path + "/" + tempList[i]);//再删除空文件夹
+                    flag = true;
+                }
+            }
+        }
+
+        //再删除当前空文件夹
+        file.delete();
+        return flag;
+    }
+
+    // 流转化成字符串
+    public static String inputStream2String(InputStream is) throws IOException
+    {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        int i = -1;
+        while ((i = is.read()) != -1)
+        {
+            baos.write(i);
+        }
+        return baos.toString();
+    }
+
+    // 流转化成文件
+    public static void inputStream2File(InputStream is, String savePath)throws Exception
+    {
+        log.info("来自app的录屏音频文件保存路径为:" + savePath);
+        File file = new File(savePath);
+        if(file.exists())
+        {
+            deleteFile(savePath);
+        }
+        InputStream inputSteam = is;
+        BufferedInputStream fis = new BufferedInputStream(inputSteam);
+        FileOutputStream fos = new FileOutputStream(file);
+        int f;
+        while ((f = fis.read()) != -1)
+        {
+            fos.write(f);
+        }
+        fos.flush();
+        fos.close();
+        fis.close();
+        inputSteam.close();
+    }
+
+    public static void saveImageToDisk(String accessToken, String mediaId, String picName, String picPath,InputStream inputStream)
+            throws Exception {
+        byte[] data = new byte[10240];
+        int len = 0;
+        FileOutputStream fileOutputStream = null;
+        try {
+            fileOutputStream = new FileOutputStream(picPath+picName+".amr");
+            while ((len = inputStream.read(data)) != -1) {
+                fileOutputStream.write(data, 0, len);
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            if (inputStream != null) {
+                try {
+                    inputStream.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+            if (fileOutputStream != null) {
+                try {
+                    fileOutputStream.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    public static void main(String[] args) {
+        try{
+//            FileUtil.writeFile("G:\\java project\\test.json","{\"scenePsd\":\"\",\"public\":0,\"sceneType\":\"0\",\"sceneName\":\"1314家装互联网峰会\",\"shootCount\":\"40\",\"thumbImg\":0,\"floorLogo\":0,\"version\":1,\"hasBGM\":\"欢快\"}");
+//            File saveDir = new File("G:\\java project\\test.json");
+//            System.out.println("路径:" + saveDir);
+//            String parametr = "7sd:;szx";
+//            Integer resolution = new Integer(1);
+//            parametr += ":;" + (resolution == null ? 0 : resolution.intValue());
+            ResponExhibition responExhibition = new ResponExhibition();
+            responExhibition.setName("123asd");
+            JSONObject jsonObject = new JSONObject();
+            jsonObject.put("type", 0);
+            jsonObject.put("data", responExhibition);
+            System.out.println(jsonObject.toJSONString());
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+}

+ 39 - 0
zhoushan-system-api/src/main/java/com/fdage/util/VerifyCodeUtil.java

@@ -0,0 +1,39 @@
+package com.fdage.util;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+
+/**
+ * Created by Hb_zzZ on 2019/4/29.
+ */
+public class VerifyCodeUtil {
+
+    public static String validImage(HttpServletRequest request, HttpSession session) {
+        String code = request.getParameter("code");
+        Object verCode = session.getAttribute("verCode");
+        if (null == verCode) {
+            request.setAttribute("errmsg", "验证码已失效,请重新输入");
+            return "-1";
+//            return "验证码已失效,请重新输入";
+        }
+        String verCodeStr = verCode.toString();
+        LocalDateTime localDateTime = (LocalDateTime) session.getAttribute("codeTime");
+        long past = localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
+        long now = LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
+        if (verCodeStr == null || code == null || code.isEmpty() || !verCodeStr.equalsIgnoreCase(code)) {
+            request.setAttribute("errmsg", "验证码错误");
+            return "-2";
+//            return "验证码错误";
+        } else if ((now - past) / 1000 / 60 > 5) {
+            request.setAttribute("errmsg", "验证码已过期,重新获取");
+            return "-3";
+//            return "验证码已过期,重新获取";
+        } else {
+            //验证成功,删除存储的验证码
+            session.removeAttribute("verCode");
+            return "200";
+        }
+    }
+}

+ 70 - 0
zhoushan-system-api/src/main/resources/application-dev.yml

@@ -0,0 +1,70 @@
+
+
+
+spring:
+  jmx:
+    default-domain: zhoushan_system
+    enabled: false
+  application:
+    name: zhoushan_system
+  servlet:
+    multipart:
+      maxFileSize: 1000MB
+      maxRequestSize: 1000MB
+  datasource:
+    # db 项目测试服务器
+    url: jdbc:mysql://8.135.106.227:3306/${project.en}?useSSL=false&useUnicode=true&characterEncoding=utf-8&autoReconnect=true
+    username: root
+    password: 4dkk2021testproject%
+    driver-class-name: com.mysql.jdbc.Driver
+# Redis数据库索引(默认为0)
+  redis:
+    database: 0
+    host: 127.0.0.1
+    port: 6379
+    password:
+# 连接超时时间 单位 ms(毫秒)
+    timeout: 3000ms
+# 连接池中的最大空闲连接,默认值也是8。
+    jedis:
+      pool:
+        max-idle: 8
+#连接池中的最小空闲连接,默认值也是0。
+        min-idle: 0
+# 如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
+        max-active: 8
+# 等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException
+        max-wait: -1ms
+# 配置静态资源跟目录
+  mvc:
+    static-path-pattern: /**
+  resources:
+    static-locations: file:${my.file.path}
+
+upload:
+  head: ${my.file.path}/head
+  information: ${my.file.path}/information
+  collection: ${my.file.path}/collection
+  exhibition: ${my.file.path}/exhibition
+
+
+
+swagger:
+  package: com.fdage.controller
+  title: ${project.sc}-dev
+  description: ${swagger.title}
+  version: 1.0
+
+
+# 服务器存放地址
+my:
+  file:
+    path: E:/data/${project.en}_data
+
+logging:
+  path: E:/log/${project.en}_log
+  config: classpath:logback-spring.xml
+  level:
+    com:
+      fdage: debug
+

+ 77 - 0
zhoushan-system-api/src/main/resources/application-sit.yml

@@ -0,0 +1,77 @@
+
+
+
+spring:
+  jmx:
+    default-domain: zhoushan_system
+    enabled: false
+  application:
+    name: zhoushan_system
+  servlet:
+    multipart:
+      maxFileSize: 1000MB
+      maxRequestSize: 1000MB
+  datasource:
+#    url: jdbc:mysql://47.107.253.212:3306/zhoushan_system?useSSL=false&useUnicode=true&characterEncoding=utf-8&autoReconnect=true
+#    username: root
+#    password: 4dagecui2019
+    # db 项目测试服务器
+    url: jdbc:mysql://8.135.106.227:3306/${project.en}?useSSL=false&useUnicode=true&characterEncoding=utf-8&autoReconnect=true
+    username: root
+    password: 4dkk2021testproject%
+    driver-class-name: com.mysql.jdbc.Driver
+# Redis数据库索引(默认为0)
+  redis:
+    database: 0
+    host: 127.0.0.1
+    port: 6379
+    password:
+# 连接超时时间 单位 ms(毫秒)
+    timeout: 3000ms
+# 连接池中的最大空闲连接,默认值也是8。
+    jedis:
+      pool:
+        max-idle: 8
+#连接池中的最小空闲连接,默认值也是0。
+        min-idle: 0
+# 如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
+        max-active: 8
+# 等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException
+        max-wait: -1ms
+# 配置静态资源跟目录
+  mvc:
+    static-path-pattern: /**
+  resources:
+    static-locations: file:${my.file.path}
+
+upload:
+  head: ${my.file.path}/head
+  information: ${my.file.path}/information
+  collection: ${my.file.path}/collection
+  exhibition: ${my.file.path}/exhibition
+
+
+
+swagger:
+  package: com.fdage.controller
+  title: ${project.sc}-sit
+  description: ${swagger.title}
+  version: 1.0
+
+
+# 服务器存放地址
+my:
+  file:
+    path: /root/data/${project.en}_data
+
+
+logging:
+  path: /root/log/${project.en}_log
+  config: classpath:logback-spring.xml
+  level:
+    com:
+      fdage: debug
+
+
+
+

+ 36 - 0
zhoushan-system-api/src/main/resources/application.yml

@@ -0,0 +1,36 @@
+spring:
+  profiles:
+    active: dev
+
+server:
+  port: 8018
+
+mybatis:
+  mapperLocations: classpath*:mapper/*/*.xml
+  typeAliasesPackage: com.fdage.pojo
+  configuration:
+    map-underscore-to-camel-case: true
+
+# page分页
+pagehelper:
+  helperDialect: mysql
+  reasonable: true
+  supportMethodsArguments: true
+  params: count=countSql
+
+
+project:
+  sc: 吴忠万物墙
+  en: museum_wuzhong_wall
+
+
+# tk.mybatis 配置自动识别字段转换
+#mapper:
+#  identity: MYSQL
+#  mappers: tk.mybatis.mapper.common.Mapper
+
+# 允许上传文件后缀
+my:
+  file:
+    allow: .jpg,.gif,.png,.ico,.bmp,.jpeg,.zip,.zp,.rar,.mp3,.mp4,.avi,.mov,.4dage,.wav,.wma,.m4a,.obj
+

+ 156 - 0
zhoushan-system-api/src/main/resources/logback-spring.xml

@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration scan="true" scanPeriod="60 seconds" debug="false">
+    <property name="LOG_MAX_HISTORY" value="180"/>
+    <springProperty scope="context" name="LOG_PATH" source="logging.path"/>
+
+    <!-- 控制台输出 -->
+    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
+            <pattern>${LOG_PATH}/%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+            <!--<charset>utf-8</charset>-->
+        </encoder>
+    </appender>
+    <!-- 按照每天生成日志文件:主项目日志 -->
+    <appender name="file.all" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 追加日志到原文件结尾 -->
+        <Prudent>true</Prudent>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!--日志文件输出的文件名 -->
+            <FileNamePattern>${LOG_PATH}/%d{yyyy-MM-dd}.%i.log</FileNamePattern>
+            <MaxHistory>${LOG_MAX_HISTORY}</MaxHistory>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <!-- 除按日志记录之外,还配置了日志文件不能超过10M(默认),若超过10M,日志文件会以索引0开始, -->
+                <maxFileSize>10MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{500} - %msg%n</pattern>
+            <!--<charset>utf-8</charset>-->
+        </encoder>
+    </appender>
+
+    <!--info日志统一输出到这里-->
+    <appender name="file.info" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <Prudent>true</Prudent>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!--日志文件输出的文件名 每小时生成日志文件 -->
+            <FileNamePattern>${LOG_PATH}/%d{yyyy-MM-dd}/info/console-info.%d{yyyy-MM-dd-HH}.%i.log</FileNamePattern>
+            <MaxHistory>${LOG_MAX_HISTORY}</MaxHistory>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <!-- 除按日志记录之外,还配置了日志文件不能超过10M(默认),若超过10M,日志文件会以索引0开始, -->
+                <maxFileSize>10MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %method 方法名  %L 行数 %msg:日志消息,%n是换行符-->
+            <pattern> %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{56}.%method:%L - %msg%n</pattern>
+            <!--<charset>utf-8</charset>-->
+        </encoder>
+        <!-- 此日志文件只记录info级别的 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>INFO</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!--错误日志统一输出到这里-->
+    <appender name="file.error" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <Prudent>true</Prudent>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!--日志文件输出的文件名-->
+            <FileNamePattern>${LOG_PATH}/%d{yyyy-MM-dd}/error/console-error.%d{yyyy-MM-dd-HH}.%i.log</FileNamePattern>
+            <!--日志文件保留天数-->
+            <MaxHistory>${LOG_MAX_HISTORY}</MaxHistory>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <!-- 除按日志记录之外,还配置了日志文件不能超过10M(默认),若超过10M,日志文件会以索引0开始, -->
+                <maxFileSize>10MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %method 方法名  %L 行数 %msg:日志消息,%n是换行符-->
+            <pattern> %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{56}.%method:%L - %msg%n</pattern>
+            <!--<charset>utf-8</charset>-->
+        </encoder>
+        <!-- 此日志文件只记录error级别的 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>ERROR</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!--warn日志统一输出到这里-->
+    <appender name="file.warn" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <Prudent>true</Prudent>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!--日志文件输出的文件名 按小时生成日志-->
+            <FileNamePattern>${LOG_PATH}/%d{yyyy-MM-dd}/warn/console-warn.%d{yyyy-MM-dd-HH}.%i.log</FileNamePattern>
+            <!--日志文件保留天数-->
+            <MaxHistory>${LOG_MAX_HISTORY}</MaxHistory>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <!-- 除按日志记录之外,还配置了日志文件不能超过10M(默认),若超过10M,日志文件会以索引0开始, -->
+                <maxFileSize>10MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %method 方法名  %L 行数 %msg:日志消息,%n是换行符-->
+            <pattern> %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{56}.%method:%L - %msg%n</pattern>
+            <!--<charset>utf-8</charset>-->
+        </encoder>
+        <!-- 此日志文件只记录warn级别的 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>WARN</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!--debug级别日志统一输出到这里-->
+    <appender name="file.debug" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <Prudent>true</Prudent>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!--日志文件输出的文件名 按小时生成日志-->
+            <FileNamePattern>${LOG_PATH}/%d{yyyy-MM-dd}/debug/console-debug.%d{yyyy-MM-dd-HH}.%i.log</FileNamePattern>
+            <!--日志文件保留天数-->
+            <MaxHistory>${LOG_MAX_HISTORY}</MaxHistory>
+            <!-- 除按日志记录之外,还配置了日志文件不能超过5M,若超过5M,日志文件会以索引0开始,命名日志文件,例如console-debug.2018-08-24-09.1.log -->
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>10MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %method 方法名  %L 行数 %msg:日志消息,%n是换行符-->
+            <pattern> %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{56}.%method:%L - %msg%n</pattern>
+            <!--<charset>utf-8</charset>-->
+        </encoder>
+        <!-- 此日志文件只记录debug级别的 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>DEBUG</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY </onMismatch>
+        </filter>
+    </appender>
+
+    <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
+    <appender name="file.async" class="ch.qos.logback.classic.AsyncAppender">
+        <discardingThreshold>0</discardingThreshold>
+        <queueSize>256</queueSize>
+        <includeCallerData>true</includeCallerData>
+        <appender-ref ref="file.all" />
+    </appender>
+
+    <!--  日志输出级别 -->
+    <!-- TRACE\DEBUG\INFO\WARN\ERROR\FATAL\OFF -->
+    <root level="INFO">
+        <appender-ref ref="console" />
+        <appender-ref ref="file.async"/>
+        <appender-ref ref="file.error" />
+        <appender-ref ref="file.info" />
+        <appender-ref ref="file.debug" />
+        <appender-ref ref="file.warn" />
+    </root>
+
+</configuration>

+ 11 - 0
zhoushan-system-api/src/main/resources/sh/shutdown.sh

@@ -0,0 +1,11 @@
+#!/bin/bash
+RESOURCE_NAME=museum_changshu.jar
+   Pid=`awk '{print $1}' tpid`
+
+if [ ${Pid} ]; then
+kill -9 $Pid
+echo 'Kill Process!'
+else
+echo 'Stop failed!'
+fi
+

+ 12 - 0
zhoushan-system-api/src/main/resources/sh/startup.sh

@@ -0,0 +1,12 @@
+#!/bin/sh
+RESOURCE_NAME=museum_changshu.jar
+rm -f tpid
+nohup java -jar ./$RESOURCE_NAME --spring.profiles.active=sit --server.port=8002 & echo $! > tpid
+echo Start Success!
+echo
+
+
+
+
+
+

BIN
zhoushan-system-api/src/main/resources/sh/高淳博物馆后台菜单权限(1).xlsx


BIN
zhoushan-system-api/src/main/resources/static/collection/importData.xlsx


+ 123 - 0
zhoushan-system-api/src/main/resources/static/index.html

@@ -0,0 +1,123 @@
+<!DOCTYPE html>
+<!--<html>-->
+<!--<head>-->
+	<!--<title>数据库管理系统-应用列表</title>-->
+	<!--<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">-->
+	<!--<link rel="stylesheet" type="text/css" href="./static/css/index.css">-->
+<!--</head>-->
+<!--<body>-->
+	<!--<div class="open">-->
+		<!--<div id="nav">-->
+			<!--<ul>-->
+				<!--<li>-->
+					<!--<div>-->
+						<!--<img src="./static/img/application.png" alt="应用">-->
+						<!--<p>应用</p>-->
+					<!--</div>-->
+				<!--</li>-->
+			<!--</ul>-->
+		<!--</div>-->
+		<!--<div id="main">-->
+			<!--<div class="main-top">-->
+				<!--<button class="btn-create"> + 创建应用 </button>-->
+				<!--<div class="user-msg">-->
+					<!--<img src="./static/img/people_fill.png">-->
+					<!--<p id="name"></p>-->
+					<!--<p id="logout">登出</p>-->
+				<!--</div>-->
+			<!--</div>-->
+			<!--<div class="main-middle"></div>-->
+		<!--</div>-->
+	<!--</div>-->
+	<!--<div class="modal">-->
+		<!--<div class="modal-content">-->
+			<!--<div class="modal-header">-->
+				<!--<h4>创建应用</h4>-->
+				<!--<button class="btn-close">×</button>-->
+			<!--</div>-->
+			<!--<div>-->
+				<!--<div class="modal-body">-->
+					<!--<div class="form-group">-->
+						<!--<label>应用名称:</label>-->
+						<!--<input id="app-name" type="text" class="formControl" placeholder="必填"/>-->
+						<!--<span class="error"></span>-->
+					<!--</div>-->
+				<!--</div>-->
+			<!--</div>-->
+			<!--<div class="modal-footer">-->
+				<!--<button class="button btn-close" type="button">关闭</button>-->
+				<!--<button id="btn" class="submit" type="submit">创建应用</button>-->
+			<!--</div>-->
+		<!--</div>-->
+	<!--</div>-->
+	<!--<div id="hide"></div>-->
+	<!--<script src="./static/js/jquery-3.3.1.min.js"></script>-->
+	<!--<script src="./layer/layer.js"></script>-->
+	<!--<script src="./static/js/index.js"></script>-->
+<!--</body>-->
+<!--</html>-->
+
+
+<html lang="en">
+<head>
+	<title>Server-Sent Events Demo</title>
+	<meta charset="UTF-8" />
+	<script>
+		window.addEventListener("load", function() {
+			var button = document.getElementById("connect");
+			var status = document.getElementById("status");
+			var output = document.getElementById("output");
+			var connectTime = document.getElementById("connecttime");
+			var source;
+
+			function connect() {
+				source = new EventSource("http://192.168.0.207:8100/sendMessage"); //连接的Api
+				source.addEventListener("message", function(event) {
+					output.textContent = event.data;
+					//这是回调的信息
+
+				}, false);
+
+				source.addEventListener("connecttime", function(event) {
+					connectTime.textContent = "Connection was last established at: " + event.data;
+				}, false);
+
+				source.addEventListener("open", function(event) {
+					button.value = "Disconnect";
+					button.onclick = function(event) {
+						source.close();
+						button.value = "Connect";
+						button.onclick = connect;
+						status.textContent = "Connection closed!";
+					};
+					status.textContent = "Connection open!";
+				}, false);
+
+				source.addEventListener("error", function(event) {
+					if (event.target.readyState === EventSource.CLOSED) {
+						source.close();
+						status.textContent = "Connection closed!";
+					} else if (event.target.readyState === EventSource.CONNECTING) {
+						status.textContent = "Connection closed. Attempting to reconnect!";
+					} else {
+						status.textContent = "Connection closed. Unknown error!";
+					}
+				}, false);
+			}
+
+			if (!!window.EventSource) {
+				connect();
+			} else {
+				button.style.display = "none";
+				status.textContent = "浏览器不支持-请用现代浏览器";  //通常是IE浏览器不支持
+			}
+		}, false);
+	</script>
+</head>
+<body>
+<input type="button" id="connect" value="Connect" /><br />
+<span id="status">Connection closed!</span><br />
+<span id="connecttime"></span><br />
+<span id="output"></span>
+</body>
+</html>

+ 16 - 0
zhoushan-system-api/src/test/java/com/fdage/VirtualHouseApiApplicationTests.java

@@ -0,0 +1,16 @@
+package com.fdage;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class VirtualHouseApiApplicationTests {
+
+	@Test
+	public void contextLoads() {
+	}
+
+}

+ 208 - 0
zhoushan-system-common/pom.xml

@@ -0,0 +1,208 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.0.7.RELEASE</version>
+        <relativePath/> <!-- lookup parent from repository -->
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>com.fdage</groupId>
+    <version>0.0.1-SNAPSHOT</version>
+    <artifactId>zhoushan-system-common</artifactId>
+    <packaging>jar</packaging>
+    <name>zhoushan-system-common</name>
+    <description>Demo project for Spring Boot</description>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <java.version>1.8</java.version>
+        <tk.mybatis.version>2.0.2</tk.mybatis.version>
+        <pagehelper.version>1.2.5</pagehelper.version>
+    </properties>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.45</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid</artifactId>
+            <version>1.1.12</version>
+        </dependency>
+
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <version>5.1.41</version>
+        </dependency>
+
+        <dependency>
+            <groupId>io.jsonwebtoken</groupId>
+            <artifactId>jjwt</artifactId>
+            <version>0.9.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+            <version>3.4</version>
+        </dependency>
+
+        <!-- Spring Boot Redis依赖 -->
+        <!-- 注意:1.5版本的依赖和2.0的依赖不一样,注意看哦 1.5我记得名字里面应该没有“data”, 2.0必须是“spring-boot-starter-data-redis” 这个才行-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+            <!-- 1.5的版本默认采用的连接池技术是jedis  2.0以上版本默认连接池是lettuce, 在这里采用jedis,所以需要排除lettuce的jar -->
+            <exclusions>
+                <exclusion>
+                    <groupId>redis.clients</groupId>
+                    <artifactId>jedis</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>io.lettuce</groupId>
+                    <artifactId>lettuce-core</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <!-- 添加jedis客户端 -->
+        <dependency>
+            <groupId>redis.clients</groupId>
+            <artifactId>jedis</artifactId>
+        </dependency>
+
+        <!--spring2.0集成redis所需common-pool2-->
+        <!-- 必须加上,jedis依赖此  -->
+        <!-- spring boot 2.0 的操作手册有标注 大家可以去看看 地址是:https://docs.spring.io/spring-boot/docs/2.0.3.RELEASE/reference/htmlsingle/-->
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-pool2</artifactId>
+            <version>2.5.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+
+        <!-- shiro -->
+        <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-spring</artifactId>
+            <version>1.4.0</version>
+        </dependency>
+
+        <!-- jwt -->
+        <dependency>
+            <groupId>com.auth0</groupId>
+            <artifactId>java-jwt</artifactId>
+            <version>3.2.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.github.xiaoymin</groupId>
+            <artifactId>knife4j-spring-boot-starter</artifactId>
+            <version>2.0.2</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.aspectj</groupId>
+            <artifactId>aspectjweaver</artifactId>
+            <version>1.9.3</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi</artifactId>
+            <version>3.8</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-ooxml</artifactId>
+            <version>3.8</version>
+        </dependency>
+
+
+        <!-- 工具类 -->
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.3.3</version>
+        </dependency>
+
+
+        <!--tk.mybatis 依赖-->
+        <dependency>
+            <groupId>tk.mybatis</groupId>
+            <artifactId>mapper-spring-boot-starter</artifactId>
+            <version>${tk.mybatis.version}</version>
+            <!-- tk.mybatis 跟springboot jap 包冲突-->
+            <!--<exclusions>-->
+                <!--<exclusion>-->
+                    <!--<groupId>javax.persistence</groupId>-->
+                    <!--<artifactId>persistence-api</artifactId>-->
+                <!--</exclusion>-->
+            <!--</exclusions>-->
+
+        </dependency>
+
+        <!--分页插件-->
+        <dependency>
+            <groupId>com.github.pagehelper</groupId>
+            <artifactId>pagehelper-spring-boot-starter</artifactId>
+            <version>${pagehelper.version}</version>
+        </dependency>
+
+        <!-- 字段校验 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-validation</artifactId>
+        </dependency>
+
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 12 - 0
zhoushan-system-common/src/main/java/com/fdage/config/CommonConf.java

@@ -0,0 +1,12 @@
+package com.fdage.config;
+
+/**
+ * Created by Hb_zzZ on 2019/4/29.
+ */
+public class CommonConf {
+
+    /**
+     * redis 相关
+     */
+    public static final String REDIS_LOGIN_TOKEN = "ZHOUSHAN.HOSE.TOKEN.";               //redis新增token
+}

+ 72 - 0
zhoushan-system-common/src/main/java/com/fdage/constant/ConfigConstant.java

@@ -0,0 +1,72 @@
+package com.fdage.constant;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+/**
+ * Created by owen on 2020/12/31 0031 14:22
+ *
+ * 全局动态参数
+ */
+@Component
+public class ConfigConstant {
+
+    /** 服务器文件地址*/
+    @Value("${my.file.path}")
+    public  String serverBasePath;
+
+
+    @Value("${my.file.allow}")
+    public String serverFileFallow;
+
+    /**redis token前缀*/
+//    @Value("${redis.prefix}")
+//    public  String redisPrefix;
+
+//    /**允许上传的文件后缀*/
+//    @Value("${file.allow}")
+//    public String fileAllow;
+
+//    @Value("${project.en}")
+//    public String projectEn;
+
+//    @Value("${project.name}")
+//    public String serverDomain;
+
+//    @Value("${oss.point}")
+//    public  String ossPoint;
+//
+//    @Value("${oss.key}")
+//    public  String ossKey;
+//
+//    @Value("${oss.secrecy}")
+//    public  String ossSecrecy;
+//
+//    @Value("${oss.bucket}")
+//    public  String ossBucket;
+//
+//    @Value("${oss.file.path}")
+//    public  String ossBasePath;
+//
+//    @Value("${oss.domain}")
+//    public  String ossDomain;
+
+
+    @Value("${swagger.package}")
+    public  String swaggerPackage;
+
+    @Value("${swagger.title}")
+    public  String swaggerTitle;
+
+    @Value("${swagger.description}")
+    public  String swaggerDescription;
+
+    @Value("${swagger.version}")
+    public  String swaggerVersion;
+
+
+
+
+
+
+}

+ 9 - 0
zhoushan-system-common/src/main/java/com/fdage/constant/ConstantExcel.java

@@ -0,0 +1,9 @@
+package com.fdage.constant;
+
+/**
+ * Created by Hb_zzZ on 2020/9/14.
+ */
+public class ConstantExcel {
+
+    public static final String[] COLLECTION_NAME = {"序号","文物名称","文物类别","文物年代","点赞数","下载数","搜索数"};
+}

+ 13 - 0
zhoushan-system-common/src/main/java/com/fdage/constant/ConstantUrl.java

@@ -0,0 +1,13 @@
+package com.fdage.constant;
+
+/**
+ * Created by Hb_zzZ on 2019/9/11.
+ */
+public class ConstantUrl {
+
+//    public static final String MAIN_URL = "http://127.0.0.1:8100/";
+
+    public static final String MAIN_URL = "http://119.23.129.199:8100/";
+
+    public static final String FDMODEL_PIC = "http://model3d.4dage.com/model/";
+}

+ 22 - 0
zhoushan-system-common/src/main/java/com/fdage/constant/MsgCode.java

@@ -0,0 +1,22 @@
+package com.fdage.constant;
+
+/**
+ * Created by owen on 2021/6/1 0001 16:45
+ */
+public class MsgCode {
+
+    /** 对象不存在*/
+    public static final Integer e3001 = 3001;
+
+    /** 长传文件非法*/
+    public static final Integer e3002 = 3002;
+
+    /** 空目录*/
+    public static final Integer e3003 = 3003;
+
+    /** 状态非法*/
+    public static final Integer e3004 = 3004;
+
+    /** 验证码失效*/
+    public static final Integer e3005 = 3005;
+}

+ 51 - 0
zhoushan-system-common/src/main/java/com/fdage/dto/ResourceTree.java

@@ -0,0 +1,51 @@
+package com.fdage.dto;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class ResourceTree {
+
+    private Long id;
+
+    private String name;
+
+    private Long parentId;
+
+    @JSONField(serialize = false)
+    private boolean checked = false;
+
+    @JSONField(serialize = false)
+    private boolean spread = false;
+
+    @JSONField(serialize = false)
+    private String isHeader = "0";
+
+    @JSONField(serialize = false)
+    private String url;
+
+    @JSONField(serialize = false)
+    private String icon;
+
+    @JSONField(serialize = false)
+    private String resourceKey;
+
+    @JSONField(serialize = false)
+    private String resourceType;
+
+    @JSONField(serialize = false)
+    private String order = "1";
+
+    // 子菜单/或按钮
+    private List<ResourceTree> children;
+
+    @JSONField(serialize = false)
+    private int level;
+
+    // 默认都没有权限
+    private boolean authority ;
+
+
+}

+ 30 - 0
zhoushan-system-common/src/main/java/com/fdage/enums/ResponEnum.java

@@ -0,0 +1,30 @@
+package com.fdage.enums;
+
+/**
+ * Created by Hb_zzZ on 2019/9/11.
+ */
+public enum ResponEnum {
+
+    NOT_NULL(3001, "参数不能为空"),
+    USER_NOT_EXIST(3002, "用户不存在"),
+    PASSWORD_ERROR(3003, "密码错误"),
+    USER_EXIST(3004, "用户已存在"),
+    PASSWORD_INCONSISTENCY(3005, "两次密码不一致"),
+    USER_STOP_USING(3006, "用户已停用");
+
+    private final int code;
+    private final String message;
+
+    ResponEnum(int code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public String getMessage() {
+        return this.message;
+    }
+
+    public int getCode() {
+        return this.code;
+    }
+}

+ 28 - 0
zhoushan-system-common/src/main/java/com/fdage/enums/TypeEnum.java

@@ -0,0 +1,28 @@
+package com.fdage.enums;
+
+/**
+ * Created by Hb_zzZ on 2019/5/5.
+ */
+public enum  TypeEnum {
+
+    STRING(0, "字符串"),
+    NUM(1, "数字"),
+    DATA(2, "日期"),
+    FILE(3, "文件");
+
+    private final int code;
+    private final String message;
+
+    private TypeEnum(int code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public String getMessage() {
+        return this.message;
+    }
+
+    public int getCode() {
+        return this.code;
+    }
+}

+ 15 - 0
zhoushan-system-common/src/main/java/com/fdage/request/RequestBase.java

@@ -0,0 +1,15 @@
+package com.fdage.request;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class RequestBase implements Serializable {
+
+    private int pageNum;
+
+    private int pageSize;
+
+    private int start;
+}

+ 62 - 0
zhoushan-system-common/src/main/java/com/fdage/request/RequestCollection.java

@@ -0,0 +1,62 @@
+package com.fdage.request;
+
+import io.swagger.annotations.ApiModelProperty;
+import io.swagger.annotations.ApiOperation;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Created by Hb_zzZ on 2019/9/11.
+ */
+@Data
+public class RequestCollection extends RequestBase{
+
+    private Long id;
+
+    private String name;
+
+    private Long typeId;
+
+    private Long timeId;
+
+    private Date discoveryTime;
+
+    private Date repairTime;
+
+    private String venue;
+
+    private String modelUrl;
+
+    private String contentUrl;
+
+    private Integer state;
+
+    private String description;
+
+    private String pic;
+
+    private String num;
+
+    private String unityPic;
+
+    private String unityUrl;
+
+    // 图片 2021-08-02
+    @ApiModelProperty(value = "图片")
+    private String icon;
+
+    @ApiModelProperty(value = "目录code", notes = "上传文件使用")
+    private String dirCode;
+
+    // 2021-09-22
+    @ApiModelProperty(value = "类型: 2D 、 3D")
+    private String type;
+
+    @ApiModelProperty(value = "轮播板式")
+    private String urlList;
+
+    @ApiModelProperty(value = "二维码")
+    private String qrCode;
+}

+ 20 - 0
zhoushan-system-common/src/main/java/com/fdage/request/RequestEquipment.java

@@ -0,0 +1,20 @@
+package com.fdage.request;
+
+import lombok.Data;
+
+/**
+ * Created by Hb_zzZ on 2019/9/11.
+ */
+@Data
+public class RequestEquipment extends RequestBase{
+
+    private Long id;
+
+    private String name;
+
+    private String uuid;
+
+    private Long positionId;
+
+    private Integer state;
+}

+ 32 - 0
zhoushan-system-common/src/main/java/com/fdage/request/RequestExhibition.java

@@ -0,0 +1,32 @@
+package com.fdage.request;
+
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * Created by Hb_zzZ on 2019/9/12.
+ */
+@Data
+public class RequestExhibition extends RequestBase{
+
+    private Long id;
+
+    private String name;
+
+    private Long typeId;
+
+    private Long equipmentId;
+
+    private Integer state;
+
+    private String description;
+
+    private Long exhibitionId;
+
+    private String collectionId;
+
+    private Integer isSend;
+
+    private String webUrl;
+}

+ 32 - 0
zhoushan-system-common/src/main/java/com/fdage/request/RequestInformation.java

@@ -0,0 +1,32 @@
+package com.fdage.request;
+
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * Created by Hb_zzZ on 2019/9/11.
+ */
+@Data
+public class RequestInformation extends RequestBase{
+
+    private Long id;
+
+    private String name;
+
+    private Integer type;
+
+    private String contentUrl;
+
+    private Integer contentNum;
+
+    private Integer orderNum;
+
+    private Integer state;
+
+    private Date startTime;
+
+    private Date endTime;
+
+    private String description;
+}

+ 14 - 0
zhoushan-system-common/src/main/java/com/fdage/request/RequestLog.java

@@ -0,0 +1,14 @@
+package com.fdage.request;
+
+import lombok.Data;
+
+/**
+ * Created by Hb_zzZ on 2020/7/28.
+ */
+@Data
+public class RequestLog extends RequestBase{
+
+    private String type;
+
+    private String description;
+}

+ 24 - 0
zhoushan-system-common/src/main/java/com/fdage/request/RequestRole.java

@@ -0,0 +1,24 @@
+package com.fdage.request;
+
+import lombok.Data;
+
+import java.util.Set;
+
+/**
+ * Created by Hb_zzZ on 2020/7/28.
+ */
+@Data
+public class RequestRole {
+
+    private Long id;
+
+    private String roleName;
+
+    private Set<Long> resources;
+
+    private String description;
+
+    private Integer state;
+
+    private String roleKey;
+}

+ 30 - 0
zhoushan-system-common/src/main/java/com/fdage/request/RequestUser.java

@@ -0,0 +1,30 @@
+package com.fdage.request;
+
+import lombok.Data;
+
+/**
+ * Created by Hb_zzZ on 2019/9/11.
+ */
+@Data
+public class RequestUser extends RequestBase{
+
+    private Long id;
+
+    private String userName;
+
+    private String password;
+
+    private String repeatPassword;
+
+    private String newPassword;
+
+    private Long roleId;
+
+    private String phone;
+
+    private String head;
+
+    private Integer state;
+
+    private String searchKey;
+}

+ 74 - 0
zhoushan-system-common/src/main/java/com/fdage/respon/ResponCollection.java

@@ -0,0 +1,74 @@
+package com.fdage.respon;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Created by Hb_zzZ on 2019/9/11.
+ */
+@Data
+public class ResponCollection {
+
+    private Long id;
+
+    private String name;
+
+    private Long typeId;
+
+    private Long timeId;
+
+    private String discoveryTime;
+
+    private String repairTime;
+
+    private String venue;
+
+    private String modelUrl;
+
+    private String contentUrl;
+
+    private Integer state;
+
+    private String description;
+
+    private String typeName;
+
+    private String timeName;
+
+    private String pic;
+
+    private String num;
+
+    private Integer likeNum;
+
+    private Integer openNum;
+
+    private Integer searchNum;
+
+    private Integer downloadNum;
+
+    private String unityPic;
+
+    private String unityUrl;
+
+    // 图片 2021-08-02
+    @ApiModelProperty(value = "图片")
+    private String icon;
+
+    @ApiModelProperty(value = "目录code", notes = "上传文件使用")
+    private String dirCode;
+
+
+    // 2021-09-22
+    @ApiModelProperty(value = "类型: 2D 、 3D")
+    private String type;
+
+    @ApiModelProperty(value = "轮播板式")
+    private String urlList;
+
+    @ApiModelProperty(value = "二维码")
+    private String qrCode;
+}

+ 22 - 0
zhoushan-system-common/src/main/java/com/fdage/respon/ResponEquipment.java

@@ -0,0 +1,22 @@
+package com.fdage.respon;
+
+import lombok.Data;
+
+/**
+ * Created by Hb_zzZ on 2019/9/11.
+ */
+@Data
+public class ResponEquipment {
+
+    private Long id;
+
+    private String name;
+
+    private String uuid;
+
+    private Long positionId;
+
+    private Integer state;
+
+    private String positionName;
+}

+ 46 - 0
zhoushan-system-common/src/main/java/com/fdage/respon/ResponExhibition.java

@@ -0,0 +1,46 @@
+package com.fdage.respon;
+
+import lombok.Data;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Created by Hb_zzZ on 2019/9/12.
+ */
+@Data
+public class ResponExhibition {
+
+    private Long id;
+
+    private String name;
+
+    private Long typeId;
+
+    private Long equipmentId;
+
+    private Integer state;
+
+    private String description;
+
+    private Long exhibitionId;
+
+    private Long collectionId;
+
+    private String collectionName;
+
+    private String typeName;
+
+    private String timeName;
+
+    private String equipmentName;
+
+    private String createTime;
+
+    private List<ResponCollection> collectionList;
+
+    private String webUrl;
+
+    private Long openNum;
+
+}

+ 36 - 0
zhoushan-system-common/src/main/java/com/fdage/respon/ResponInformation.java

@@ -0,0 +1,36 @@
+package com.fdage.respon;
+
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * Created by Hb_zzZ on 2019/9/11.
+ */
+@Data
+public class ResponInformation {
+
+    private Long id;
+
+    private String name;
+
+    private Integer type;
+
+    private String contentUrl;
+
+    private Integer contentNum;
+
+    private Integer orderNum;
+
+    private Integer state;
+
+    private String startTime;
+
+    private String endTime;
+
+    private String createTime;
+
+    private String description;
+
+    private String[] urlArray;
+}

+ 30 - 0
zhoushan-system-common/src/main/java/com/fdage/respon/ResponRole.java

@@ -0,0 +1,30 @@
+package com.fdage.respon;
+
+import com.fdage.dto.ResourceTree;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Created by Hb_zzZ on 2020/7/29.
+ */
+@Data
+public class ResponRole {
+
+    private Long id;
+
+    private String roleName;
+
+    private String description;
+
+    private String roleKey;
+
+    private Integer state;
+
+    private Date createTime;
+
+    private List<String> userName;
+
+    private List<ResourceTree> resources;
+}

+ 31 - 0
zhoushan-system-common/src/main/java/com/fdage/respon/ResponStatistics.java

@@ -0,0 +1,31 @@
+package com.fdage.respon;
+
+import lombok.Data;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Created by Hb_zzZ on 2020/9/11.
+ */
+@Data
+public class ResponStatistics {
+
+    private Long total;
+
+    private Long likeTotal;
+
+    private Long downloadNum;
+
+    private Long exhibitionTotal;
+
+    private List<ResponExhibition> exhibitionList;
+
+    List<ResponCollection> collectionSearchList;
+
+    List<ResponCollection> collectionLikeList;
+
+    List<ResponCollection> collectionOpenList;
+
+    List<Map<String, Object>> collectionTypeTotal;
+}

+ 30 - 0
zhoushan-system-common/src/main/java/com/fdage/respon/ResponUser.java

@@ -0,0 +1,30 @@
+package com.fdage.respon;
+
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * Created by Hb_zzZ on 2019/9/11.
+ */
+@Data
+public class ResponUser {
+
+    private Long id;
+
+    private String userName;
+
+    private String password;
+
+    private String phone;
+
+    private String head;
+
+    private Integer state;
+
+    private Date createTime;
+
+    private Long roleId;
+
+    private String roleName;
+}

+ 129 - 0
zhoushan-system-common/src/main/java/com/fdage/util/AccountValidatorUtil.java

@@ -0,0 +1,129 @@
+package com.fdage.util;
+
+import java.util.regex.Pattern;
+
+/**
+ * Created by Hb_zzZ on 2019/4/29.
+ */
+public class AccountValidatorUtil {
+
+    /**
+     * 正则表达式:验证用户名
+     */
+    public static final String REGEX_USERNAME = "^[a-zA-Z]\\w{5,20}$";
+
+    /**
+     * 正则表达式:验证密码
+     */
+    public static final String REGEX_PASSWORD = "^[a-zA-Z0-9]{6,20}$";
+
+    /**
+     * 正则表达式:验证手机号
+     */
+    public static final String REGEX_MOBILE = "^((17[0-9])|(14[0-9])|(13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$";
+
+    /**
+     * 正则表达式:验证邮箱
+     */
+    public static final String REGEX_EMAIL = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
+
+    /**
+     * 正则表达式:验证汉字
+     */
+    public static final String REGEX_CHINESE = "^[\u4e00-\u9fa5],{0,}$";
+
+    /**
+     * 正则表达式:验证身份证
+     */
+    public static final String REGEX_ID_CARD = "(^\\d{18}$)|(^\\d{15}$)";
+
+    /**
+     * 正则表达式:验证URL
+     */
+    public static final String REGEX_URL = "http(s)?://([\\w-]+\\.)+[\\w-]+(/[\\w- ./?%&=]*)?";
+
+    /**
+     * 正则表达式:验证IP地址
+     */
+    public static final String REGEX_IP_ADDR = "(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)";
+
+    /**
+     * 校验用户名
+     *
+     * @param username
+     * @return 校验通过返回true,否则返回false
+     */
+    public static boolean isUsername(String username) {
+        return Pattern.matches(REGEX_USERNAME, username);
+    }
+
+    /**
+     * 校验密码
+     *
+     * @param password
+     * @return 校验通过返回true,否则返回false
+     */
+    public static boolean isPassword(String password) {
+        return Pattern.matches(REGEX_PASSWORD, password);
+    }
+
+    /**
+     * 校验手机号
+     *
+     * @param mobile
+     * @return 校验通过返回true,否则返回false
+     */
+    public static boolean isMobile(String mobile) {
+        return Pattern.matches(REGEX_MOBILE, mobile);
+    }
+
+    /**
+     * 校验邮箱
+     *
+     * @param email
+     * @return 校验通过返回true,否则返回false
+     */
+    public static boolean isEmail(String email) {
+        return Pattern.matches(REGEX_EMAIL, email);
+    }
+
+    /**
+     * 校验汉字
+     *
+     * @param chinese
+     * @return 校验通过返回true,否则返回false
+     */
+    public static boolean isChinese(String chinese) {
+        return Pattern.matches(REGEX_CHINESE, chinese);
+    }
+
+    /**
+     * 校验身份证
+     *
+     * @param idCard
+     * @return 校验通过返回true,否则返回false
+     */
+    public static boolean isIDCard(String idCard) {
+        return Pattern.matches(REGEX_ID_CARD, idCard);
+    }
+
+    /**
+     * 校验URL
+     *
+     * @param url
+     * @return 校验通过返回true,否则返回false
+     */
+    public static boolean isUrl(String url) {
+        return Pattern.matches(REGEX_URL, url);
+    }
+
+    /**
+     * 校验IP地址
+     *
+     * @param ipAddr
+     * @return
+     */
+    public static boolean isIPAddr(String ipAddr) {
+        return Pattern.matches(REGEX_IP_ADDR, ipAddr);
+    }
+}

+ 182 - 0
zhoushan-system-common/src/main/java/com/fdage/util/AjaxJson.java

@@ -0,0 +1,182 @@
+package com.fdage.util;
+
+import java.io.Serializable;
+
+
+/**
+ * $.ajax后需要接受的JSON
+ *
+ * @author
+ */
+public class AjaxJson implements Serializable {
+    private static final long serialVersionUID = -1491499610244557029L;
+
+    public static int CODE_SUCCESS = 0;
+    public static int CODE_FAILURED = -1;
+    public static String[] NOOP = new String[]{};
+
+    /**
+     * 处理状态:0: 成功, -1: 失败
+     */
+    private int code;
+    /**
+     * 消息
+     */
+    private String msg;
+    /**
+     * 返回数据
+     */
+    private Object data;
+    /**
+     * 返回数据的总数
+     */
+    private int count;
+
+    private AjaxJson(int code, String msg, Object data, int count) {
+        this.code = code;
+        this.msg = msg;
+        this.data = data;
+        this.count = count;
+    }
+
+    /**
+     * 处理成功,并返回数据
+     *
+     * @param data 数据对象
+     * @return data
+     */
+    public static final AjaxJson success(Object data) {
+        return new AjaxJson(CODE_SUCCESS, ConstantUtils.SUCCESS_MSG, data, 0);
+    }
+
+    /**
+     * 处理成功,并返回数据
+     *
+     * @param data 数据对象
+     * @return data
+     */
+    public static final AjaxJson success(Object data, int count) {
+        return new AjaxJson(CODE_SUCCESS, ConstantUtils.SUCCESS_MSG, data, count);
+    }
+
+    /**
+     * 处理成功
+     *
+     * @return data
+     */
+    public static final AjaxJson success() {
+        return new AjaxJson(CODE_SUCCESS, ConstantUtils.SUCCESS_MSG, NOOP, 0);
+    }
+
+    /**
+     * 处理成功
+     *
+     * @param msg 消息
+     * @return data
+     */
+    public static final AjaxJson success(String msg) {
+        return new AjaxJson(CODE_SUCCESS, msg, NOOP, 0);
+    }
+
+    /**
+     * 处理成功
+     *
+     * @param msg  消息
+     * @param data 数据对象
+     * @return data
+     */
+    public static final AjaxJson success(String msg, Object data) {
+        return new AjaxJson(CODE_SUCCESS, msg, data, 0);
+    }
+
+    /**
+     * 处理成功
+     *
+     * @param msg  消息
+     * @param data 数据对象
+     * @return data
+     */
+    public static final AjaxJson success(String msg, Object data, int count) {
+        return new AjaxJson(CODE_SUCCESS, msg, data, count);
+    }
+
+    /**
+     * 处理失败,并返回数据(一般为错误信息)
+     *
+     * @param code 错误代码
+     * @param msg  消息
+     * @return data
+     */
+    public static final AjaxJson failure(int code, String msg) {
+        return new AjaxJson(code, msg, NOOP, 0);
+    }
+
+    /**
+     * 处理失败,并返回数据(一般为错误信息)
+     *
+     * @param code 错误代码
+     * @param msg  消息
+     * @return data
+     */
+    public static final AjaxJson failure(int code, String msg, Object data) {
+        return new AjaxJson(code, msg, data, 0);
+    }
+
+    /**
+     * 处理失败
+     *
+     * @param msg 消息
+     * @return data
+     */
+    public static final AjaxJson failure(String msg) {
+        return failure(CODE_FAILURED, msg);
+    }
+
+    /**
+     * 处理失败
+     *
+     * @param msg 消息
+     * @return data
+     */
+    public static final AjaxJson failure(String msg, Object data) {
+        return failure(CODE_FAILURED, msg, data);
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+
+    public Object getData() {
+        return data;
+    }
+
+    public void setData(Object data) {
+        this.data = data;
+    }
+
+    public int getCount() {
+        return count;
+    }
+
+    public void setCount(int count) {
+        this.count = count;
+    }
+
+    @Override
+    public String toString() {
+        return "JsonResult [code=" + code + ", msg=" + msg + ", data="
+                + data + "]";
+    }
+}

+ 35 - 0
zhoushan-system-common/src/main/java/com/fdage/util/BaseRuntimeException.java

@@ -0,0 +1,35 @@
+package com.fdage.util;
+
+public class BaseRuntimeException extends RuntimeException{
+
+    private static final long serialVersionUID = -1518945670203783450L;
+    private Integer code;
+    private String msg;
+
+    public BaseRuntimeException(String msg){
+        super(msg);
+        this.msg = msg;
+    }
+
+    public BaseRuntimeException(Integer code, String msg){
+        super(msg);
+        this.code = code;
+        this.msg = msg;
+    }
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public void setCode(Integer code) {
+        this.code = code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+}

+ 16 - 0
zhoushan-system-common/src/main/java/com/fdage/util/ConstantUtils.java

@@ -0,0 +1,16 @@
+package com.fdage.util;
+
+public class ConstantUtils {
+
+    public static final String MEMBER_LOGIN_SESSION = "memberLoginSession";
+
+    public static final String SUCCESS_MSG = "操作成功。";
+
+    public static final int FAILURE_CODE_01 = 11;
+    public static final String FAILURE_MSG_01 = "token不能为空。";
+
+    public static final int FAILURE_CODE_102 = 102;
+    public static final String FAILURE_MSG_102 = "token失效,请重新登录。";
+
+
+}

+ 9 - 0
zhoushan-system-common/src/main/java/com/fdage/util/DataMappingUtil.java

@@ -0,0 +1,9 @@
+package com.fdage.util;
+
+/**
+ * Created by Hb_zzZ on 2019/5/5.
+ */
+public class DataMappingUtil {
+
+
+}

+ 397 - 0
zhoushan-system-common/src/main/java/com/fdage/util/DateUtil.java

@@ -0,0 +1,397 @@
+/*
+ * PROJECT NAME: openplatform
+ * CREATED TIME: 15-4-30 下午4:16
+ *       AUTHOR: lizhiming
+ *    COPYRIGHT: Copyright(c) 2015~2020 All Rights Reserved.
+ *
+ */
+package com.fdage.util;
+
+
+import lombok.extern.slf4j.Slf4j;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * 日期工具类
+ *
+ * @author lizhiming
+ */
+@Slf4j
+public final class DateUtil {
+
+	/**
+     * 时间格式
+     */
+    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
+
+    public static final String YYYY_MM_DD_DATE_FORMAT = "yyyy-MM-dd";
+
+    public static final String YYYYMMDD_DATA_FORMAT = "yyyyMMdd";
+
+    public static final String HHMMSS_DATA_FORMAT = "HHmmss";
+
+    public static final String YYYYMMDDHHMMSSSSS_DATA_FORMAT = "yyyyMMddHHmmssSSS";
+
+    public static final String YYYYMMDDHHMMSS_DATA_FORMAT = "yyyyMMddHHmmss";
+    
+    public static final String YYMMDDHHMMSS_DATA_FORMAT = "yyMMddHHmmss";
+    
+    public static final String YYMMDDHHMM_DATA_FORMAT = "yyyyMMddHHmm";
+    
+	
+	/**
+	 * 过去的Date对象,TIMESTAMP值可以从1970的某时的开始一直到2037年
+	 */
+	public static final Date PASSED_DATE = DateUtil.string2Date("2000-01-01 00:00:00",
+			DEFAULT_DATE_FORMAT);;
+	/**
+	 * 永久的Date对象,TIMESTAMP值可以从1970的某时的开始一直到2037年
+	 */
+	public static final Date FOREVER_DATE = DateUtil.string2Date("9999-12-31 23:59:59",
+			DEFAULT_DATE_FORMAT);
+
+	private DateUtil() {
+	}
+
+	/**
+	 * 把时间转成北京时间的时间戳
+	 *
+	 * @param input
+	 * @return
+	 */
+	public static long convert2CST(String input) {
+		SimpleDateFormat dff = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		dff.setTimeZone(TimeZone.getTimeZone("GMT+08"));
+
+		long result = -1;
+		try {
+			Date cstDate = dff.parse(input);
+			result = cstDate.getTime();
+		} catch (Exception e) {
+			log.error("convert2CST meet exception.", e);
+		}
+
+		return result;
+	}
+
+	/**
+	 * 把时间戳转成北京时间的字符串表示
+	 *
+	 * @param input
+	 * @return
+	 */
+	public static String convert2CST(long input) {
+		SimpleDateFormat dff = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		dff.setTimeZone(TimeZone.getTimeZone("GMT+08"));
+
+		try {
+			return dff.format(new Date(input));
+		} catch (Exception e) {
+			log.error("convert2CST meet exception.", e);
+		}
+
+		return "";
+	}
+
+
+	/**
+	 * 判断两个日期是否是同一天
+	 *
+	 * @param dateA
+	 *            日期1
+	 * @param dateB
+	 *            日期2
+	 * @return true:false
+	 */
+	public static boolean isSameDay(Date dateA, Date dateB) {
+		Calendar calDateA = Calendar.getInstance();
+		calDateA.setTime(dateA);
+
+		Calendar calDateB = Calendar.getInstance();
+		calDateB.setTime(dateB);
+
+		return calDateA.get(Calendar.YEAR) == calDateB.get(Calendar.YEAR)
+				&& calDateA.get(Calendar.MONTH) == calDateB.get(Calendar.MONTH)
+				&& calDateA.get(Calendar.DAY_OF_MONTH) == calDateB.get(Calendar.DAY_OF_MONTH);
+	}
+
+	/**
+	 * 将Java日期转成以秒为单位,去除毫秒信息
+	 * java中Date类中的getTime()是获取时间戳的,java中生成的时间戳精确到毫秒级别,而unix中精确到秒级别,
+	 * 所以通过java生成的时间戳需要除以1000
+	 *
+	 * @param date
+	 * @return
+	 */
+	public static Date truncMesc(Date date) {
+		String strDate = DateUtil.date2String(date, DEFAULT_DATE_FORMAT);
+
+		Date result = null;
+		try {
+			SimpleDateFormat dateFmt = new SimpleDateFormat(DEFAULT_DATE_FORMAT);
+			result = dateFmt.parse(strDate);
+		} catch (Exception e) {
+			log.error("truncMesc meet exception", e);
+		}
+
+		return result;
+	}
+
+	/**
+	 * 判断当前时间是否在指定的有效期内
+	 *
+	 * @param beginDate
+	 *            开始时间
+	 * @param endDate
+	 *            结束时间
+	 * @return true : false
+	 */
+	public static boolean isInPeriod(Date beginDate, Date endDate) {
+		Date now = new Date();
+
+		if (beginDate == null || endDate == null) {
+			log.error("isInPeriod meet null argument.");
+			throw new IllegalArgumentException("isInPeriod meet null argument.");
+		}
+
+		if (beginDate.before(endDate) == false) {
+			log.error("isInPeriod meet invalid date argument.");
+			throw new IllegalArgumentException("isInPeriod meet invalid date argument.");
+		}
+
+		if (now.after(beginDate) && now.before(endDate)) {
+			return true;
+		} else {
+			return false;
+		}
+	}
+
+	/**
+	 * 判断目标时间是否比当前时间早
+	 *
+	 * @param targetDate
+	 *            需比较的时间
+	 * @return
+	 */
+	public static boolean isBeforeNow(Date targetDate) {
+		if (targetDate == null) {
+			log.error("isBeforeNow meet null argument.");
+			throw new IllegalArgumentException("isBeforeNow meet null argument.");
+		}
+
+		Date now = new Date();
+
+		return (now.after(targetDate)) ? true : false;
+	}
+
+	/**
+	 * @param beginDate
+	 *            开始时期
+	 * @param days
+	 *            偏离天数,> 0 往后推算; < 0 往前推算
+	 * @return
+	 */
+	public static Date daysCalculate(Date beginDate, int days) {
+		return timesCalculate(beginDate, days, GregorianCalendar.DATE);
+	}
+
+	/**
+	 * @param beginDate
+	 *            开始时期
+	 * @return
+	 */
+	public static Date hoursCalculate(Date beginDate, int hours) {
+		return timesCalculate(beginDate, hours, GregorianCalendar.HOUR);
+	}
+
+	public static Date timesCalculate(Date beginDate, int times, int type) {
+		/*
+		 * GregorianCalendar类的add(int field,int amount)方法表示年月日加减.
+		 * field参数表示年,月,周,日等. amount参数表示要加减的数量.
+		 */
+		GregorianCalendar gc = new GregorianCalendar();
+		gc.setTime(beginDate);
+		gc.add(type, times);
+		return gc.getTime();
+	}
+
+	/**
+	 * 将日期对象按照格式转成字符串
+	 *
+	 * @param date
+	 *            日期对象
+	 * @param format
+	 *            日期格式
+	 * @return 字符串
+	 */
+	public static String date2String(Date date, String format) {
+		if (date == null) {
+			log.error("date2String meet null argument.");
+			throw new IllegalArgumentException("argument is null.");
+		}
+
+		if (format == null) {
+			format = DEFAULT_DATE_FORMAT;
+		}
+
+		String result = null;
+		try {
+			DateFormat fmt = new SimpleDateFormat(format);
+			result = fmt.format(date);
+		} catch (Exception e) {
+			log.error("date2String meet exception. " + e.getLocalizedMessage());
+		}
+		return result;
+	}
+
+	/**
+	 * 将字符串转成日期对象
+	 *
+	 * @param date
+	 *            日期字符串
+	 * @param format
+	 *            日期格式
+	 * @return 日期对象
+	 */
+	public static Date string2Date(String date, String format) {
+		if (date == null) {
+			log.error("string2Date meet null argument.");
+			throw new IllegalArgumentException("argument is null.");
+		}
+
+		if (format == null) {
+			format = DEFAULT_DATE_FORMAT;
+		}
+
+		Date result = null;
+		try {
+			DateFormat fmt = new SimpleDateFormat(format);
+			result = fmt.parse(date);
+		} catch (Exception e) {
+			log.error("string2Date meet exception. " + e.getLocalizedMessage());
+		}
+
+		return result;
+	}
+
+	/**
+	 * java时间戳转换到php时间戳
+	 *
+	 * @param time
+	 * @return
+	 */
+	public static long javaTimestamp(long time) {
+		if (time <= 0) {
+			log.error("javaTimestamp meet null argument.");
+			throw new IllegalArgumentException("argument is null.");
+		}
+		// mysql 时间戳只有10位,只精确到秒,而Java时间戳精确到毫秒,故要做处理
+		String dateline = String.valueOf(time);
+		dateline = dateline.substring(0, 10);
+		return Long.parseLong(dateline);
+	}
+
+	public static long javaTimestamp(Date now) {
+		return javaTimestamp(now.getTime());
+	}
+
+	/**
+	 * 计算两个日期之间相差的天数
+	 *
+	 * @param smdate
+	 *            较小的时间
+	 * @param bdate
+	 *            较大的时间
+	 * @return 相差天数
+	 * @throws ParseException
+	 */
+	public static int daysBetween(Date smdate, Date bdate) {
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+		try {
+			smdate = sdf.parse(sdf.format(smdate));
+			bdate = sdf.parse(sdf.format(bdate));
+		} catch (ParseException e) {
+			log.error("ParseException:", e);
+		}
+		Calendar cal = Calendar.getInstance();
+		cal.setTime(smdate);
+		long time1 = cal.getTimeInMillis();
+		cal.setTime(bdate);
+		long time2 = cal.getTimeInMillis();
+		long between_days = (time2 - time1) / (1000 * 3600 * 24);
+
+		return Integer.parseInt(String.valueOf(between_days));
+	}
+
+	/**
+	 * 把日期推后一天
+	 * @return 相差天数
+	 * @throws ParseException
+	 */
+	public static Date dayDelay(String dateTime) {
+		Date date = string2Date(dateTime, "yyyy-MM-dd");
+		Calendar calendar = new GregorianCalendar();
+		calendar.setTime(date);
+		calendar.add(calendar.DATE, 1);// 把日期往后增加一天.整数往后推,负数往前移动
+		date = calendar.getTime(); // 这个时间就是日期往后推一天的结果
+
+		return date;
+	}
+
+	/**
+	 * 获取某年某月的最后一天日期
+	 */
+	public static Date getLastDayOfMonth(int year, int month) {
+		Calendar cal = Calendar.getInstance();
+		cal.set(Calendar.YEAR, year);
+		cal.set(Calendar.MONTH, month - 1);
+		int lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
+		cal.set(Calendar.DAY_OF_MONTH, lastDay);
+		return cal.getTime();
+	}
+
+	/**
+	 * 获取某年某月的第一天 日期
+	 */
+	public static Date getFisrtDayOfMonth(int year, int month) {
+		Calendar cal = Calendar.getInstance();
+		cal.set(Calendar.YEAR, year);
+		cal.set(Calendar.MONTH, month - 1);
+		int firstDay = cal.getActualMinimum(Calendar.DAY_OF_MONTH);
+		cal.set(Calendar.DAY_OF_MONTH, firstDay);
+		return cal.getTime();
+	}
+
+	/**
+	 * 根据开始时间和结束时间返回时间段内的时间集合
+	 *
+	 * @param beginDate
+	 * @param endDate
+	 * int calendarType 差距的时间 如获取间隔为一天 输入Calendar.DAY_OF_MONTH
+	 * @return List
+	 */
+	public static List<Date> getDatesBetweenTwoDate(Date beginDate, Date endDate,int calendarType) {
+		List<Date> lDate = new ArrayList<Date>();
+		lDate.add(beginDate);// 把开始时间加入集合
+		Calendar cal = Calendar.getInstance();
+		// 使用给定的 Date 设置此 Calendar 的时间
+		cal.setTime(beginDate);
+		boolean bContinue = true;
+		while (bContinue) {
+			// 根据日历的规则,为给定的日历字段添加或减去指定的时间量
+			cal.add(calendarType, 1);
+			// 测试此日期是否在指定日期之后
+			if (endDate.after(cal.getTime())) {
+				lDate.add(cal.getTime());
+			} else {
+				break;
+			}
+		}
+		lDate.add(endDate);// 把结束时间加入集合
+		return lDate;
+	}
+}

+ 122 - 0
zhoushan-system-common/src/main/java/com/fdage/util/ExcelUtil.java

@@ -0,0 +1,122 @@
+package com.fdage.util;
+
+import com.fdage.constant.ConstantExcel;
+import lombok.extern.log4j.Log4j2;
+import org.apache.poi.hssf.usermodel.*;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Log4j2
+public class ExcelUtil {
+
+    private static final String EXCEL_XLS = "xls";
+    private static final String EXCEL_XLSX = "xlsx";
+
+    public static void main(String[] args) {
+//        Map<String, String> dataMap = new HashMap<String, String>();
+//        dataMap.put("BankName", "BankName");
+//        dataMap.put("Addr", "Addr");
+//        dataMap.put("Phone", "Phone");
+//        List<Map> list = new ArrayList<Map>();
+//        list.add(dataMap);
+//        new ExcelUtil().writeExcel(list, "D:/writeExcel.xls");
+        Object o = new Integer(1);
+        System.out.println(o.toString());
+    }
+
+    public static Workbook writeExcel(List<Map> dataList, String xlsxPath) {
+        OutputStream out = null;
+        try {
+            // 读取Excel文档
+            File xlsxFile = new File(xlsxPath);
+            HSSFWorkbook workBook = new HSSFWorkbook();
+            // sheet 对应一个工作页
+            HSSFSheet sheet = workBook.createSheet();
+            HSSFCellStyle cellstyle = workBook.createCellStyle();
+            HSSFRow hssfRow = sheet.createRow((short) 0);
+            sheet.createFreezePane(0, 1);
+            for (int i = 0; i < ConstantExcel.COLLECTION_NAME.length; ++i) {
+                HSSFCell cell = hssfRow.createCell((short)i);
+                cell.setCellValue(ConstantExcel.COLLECTION_NAME[i]);
+                cell.setCellStyle(cellstyle);
+            }
+            // 创建文件输出流,输出电子表格:这个必须有,否则你在sheet上做的任何操作都不会有效
+            out = new FileOutputStream(xlsxPath);
+            workBook.write(out);
+            /**
+             * 往Excel中写新数据
+             */
+            for (int j = 0; j < dataList.size(); j++) {
+                // 创建一行:从第二行开始,跳过属性列
+                Row row = sheet.createRow(j + 1);
+                // 得到要插入的每一条记录
+                Map<String, Object> dataMap = dataList.get(j);
+
+                for (int i = 0; i < ConstantExcel.COLLECTION_NAME.length; ++i) {
+                    Object value = dataMap.get(ConstantExcel.COLLECTION_NAME[i]);
+                    Cell cell = row.createCell(i);
+                    cell.setCellValue(value.toString());
+                }
+            }
+            // 创建文件输出流,准备输出电子表格:这个必须有,否则你在sheet上做的任何操作都不会有效
+            out = new FileOutputStream(xlsxPath);
+            workBook.write(out);
+            log.info("数据导出成功");
+            return workBook;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        } finally {
+            try {
+                if (out != null) {
+                    out.flush();
+                    out.close();
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * 判断Excel的版本,获取Workbook
+     *
+     * @return
+     * @throws IOException
+     */
+    public static Workbook getWorkbok(File file) throws IOException {
+        try {
+            Workbook wb = null;
+            InputStream in = new FileInputStream(file);
+
+            if (!in.markSupported()) {
+                in = new PushbackInputStream(in, 8);
+            }
+
+            if (file.getName().endsWith(EXCEL_XLS)) {
+                wb = new HSSFWorkbook(in);
+            } else if (file.getName().endsWith(EXCEL_XLSX)) {
+                wb = new XSSFWorkbook(in);
+            } else {
+                log.error("你的excel版本目前poi解析不了");
+            }
+            return wb;
+        } catch (Exception e) {
+            log.error("WriteExcelServiceImpl-getWorkbok");
+            StringWriter trace = new StringWriter();
+            e.printStackTrace(new PrintWriter(trace));
+            log.error(trace.toString());
+            return null;
+        }
+    }
+
+
+}

+ 83 - 0
zhoushan-system-common/src/main/java/com/fdage/util/FileUtils.java

@@ -0,0 +1,83 @@
+package com.fdage.util;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.io.FileUtil;
+import com.fdage.constant.ConfigConstant;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.time.LocalDateTime;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * Created by owen on 2020/5/12 0012 17:21
+ */
+@Slf4j
+@Component
+public class FileUtils {
+
+    @Autowired
+    ConfigConstant configConstant;
+
+    public boolean checkFile(MultipartFile file) {
+        //设置允许上传文件类型
+//        String suffixList = ".jpg,.gif,.png,.ico,.bmp,.jpeg,.zip,.zp,.rar,.mp3,.mp4,.avi,.mov,.4dage,.wav,.wma,.m4a";
+        String suffixList = configConstant.serverFileFallow;
+        // 获取文件后缀
+        if(file == null){
+            log.info("文件流为空不可上传");
+            return false;
+        }
+        String fileName = file.getOriginalFilename();
+        String suffix = fileName.substring(fileName.lastIndexOf(".")
+                + 1, fileName.length());
+        if (suffixList.contains(suffix.trim().toLowerCase())) {
+            log.info("无非法参数可以放行!!!");
+            return true;
+        }
+        log.info("存在非法参数不能放行!请核对上传文件格式,重新刷新页面再次上传!");
+        return false;
+    }
+
+
+    /**
+     *
+     * @param file
+     * @param urlBasePath 目前传入需要/ , 结尾不要/ , 保存的中间目录, 文件名后加
+     * @return
+     */
+    public Map<String, Object> upload(MultipartFile file, String urlBasePath) {
+
+        // 检查非法文件上传
+        boolean checkFile = this.checkFile(file);
+        if (!checkFile) {
+            throw new BaseRuntimeException("非法文件, 请重新上传");
+        }
+
+        // 文件目录
+        String fileName = file.getOriginalFilename();
+        String suffix = StringUtils.substringAfterLast(fileName, ".");
+
+        String newName = DateUtil.format(LocalDateTime.now(), "yyyyMMdd_HHmmssSSS") + "." + suffix;
+        String resUrl =  urlBasePath + "/" + newName;
+        String savePath = configConstant.serverBasePath + resUrl;
+        log.info("保存文件地址:{}", savePath);
+
+        try {
+            FileUtil.writeFromStream(file.getInputStream(), savePath);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        HashMap<String, Object> result = new HashMap<>();
+        result.put("fileName", fileName);
+        result.put("filePath", resUrl);
+        return result;
+    }
+
+}

File diff suppressed because it is too large
+ 49 - 0
zhoushan-system-common/src/main/java/com/fdage/util/HTMLSpirit.java


+ 199 - 0
zhoushan-system-common/src/main/java/com/fdage/util/ImportExeclUtil.java

@@ -0,0 +1,199 @@
+package com.fdage.util;
+
+import org.apache.poi.hssf.usermodel.HSSFCell;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by Hb_zzZ on 2020/3/19.
+ */
+public class ImportExeclUtil {
+
+    /** 总行数 */
+    private int totalRows = 0;
+    /** 总列数 */
+    private int totalCells = 0;
+    /** 错误信息 */
+    private String errorInfo;
+    /** 构造方法 */
+    public ImportExeclUtil() {
+    }
+
+
+    public int getTotalRows() {
+        return totalRows;
+    }
+    public int getTotalCells() {
+        return totalCells;
+    }
+    public String getErrorInfo() {
+        return errorInfo;
+    }
+
+    public boolean validateExcel(String filePath) {
+        /** 检查文件名是否为空或者是否是Excel格式的文件 */
+        if (filePath == null
+                || !(WDWUtil.isExcel2003(filePath) || WDWUtil
+                .isExcel2007(filePath))) {
+            errorInfo = "文件名不是excel格式";
+            return false;
+        }
+        /** 检查文件是否存在 */
+        File file = new File(filePath);
+        if (file == null || !file.exists()) {
+            errorInfo = "文件不存在";
+            return false;
+        }
+        return true;
+    }
+
+    public List<List<String>> read(String filePath) {
+        List<List<String>> dataLst = new ArrayList<List<String>>();
+        InputStream is = null;
+        try {
+            /** 验证文件是否合法 */
+            if (!validateExcel(filePath)) {
+                System.out.println(errorInfo);
+                return null;
+            }
+            /** 判断文件的类型,是2003还是2007 */
+            boolean isExcel2003 = true;
+            if (WDWUtil.isExcel2007(filePath)) {
+                isExcel2003 = false;
+            }
+            /** 调用本类提供的根据流读取的方法 */
+            File file = new File(filePath);
+            is = new FileInputStream(file);
+            dataLst = read(is, isExcel2003);
+            is.close();
+        } catch (Exception ex) {
+            ex.printStackTrace();
+        } finally {
+            if (is != null) {
+                try {
+                    is.close();
+                } catch (IOException e) {
+                    is = null;
+                    e.printStackTrace();
+                }
+            }
+        }
+        /** 返回最后读取的结果 */
+        return dataLst;
+    }
+
+
+    public List<List<String>> read(InputStream inputStream, boolean isExcel2003) {
+        List<List<String>> dataLst = null;
+        try {
+            /** 根据版本选择创建Workbook的方式 */
+            Workbook wb = null;
+            if (isExcel2003) {
+                wb = new HSSFWorkbook(inputStream);
+            } else {
+                wb = new XSSFWorkbook(inputStream);
+            }
+            dataLst = read(wb);
+        } catch (IOException e) {
+
+            e.printStackTrace();
+        }
+        return dataLst;
+    }
+
+
+    private List<List<String>> read(Workbook wb) {
+        List<List<String>> dataLst = new ArrayList<List<String>>();
+        /** 得到第一个shell */
+        Sheet sheet = wb.getSheetAt(0);
+        /** 得到Excel的行数 */
+        this.totalRows = sheet.getPhysicalNumberOfRows();
+        /** 得到Excel的列数 */
+        if (this.totalRows >= 1 && sheet.getRow(0) != null) {
+            this.totalCells = sheet.getRow(0).getPhysicalNumberOfCells();
+        }
+        /** 循环Excel的行 */
+        for (int r = 0; r < this.totalRows; r++) {
+            Row row = sheet.getRow(r);
+            if (row == null) {
+                continue;
+            }
+            List<String> rowLst = new ArrayList<String>();
+            /** 循环Excel的列 */
+            for (int c = 0; c < this.getTotalCells(); c++) {
+                Cell cell = row.getCell(c);
+                String cellValue = "";
+                if (null != cell) {
+                    // 以下是判断数据的类型
+                    switch (cell.getCellType()) {
+                        case HSSFCell.CELL_TYPE_NUMERIC: // 数字
+                            cellValue = cell.getNumericCellValue() + "";
+                            break;
+                        case HSSFCell.CELL_TYPE_STRING: // 字符串
+                            cellValue = cell.getStringCellValue();
+                            break;
+                        case HSSFCell.CELL_TYPE_BOOLEAN: // Boolean
+                            cellValue = cell.getBooleanCellValue() + "";
+                            break;
+                        case HSSFCell.CELL_TYPE_FORMULA: // 公式
+                            cellValue = cell.getCellFormula() + "";
+                            break;
+                        case HSSFCell.CELL_TYPE_BLANK: // 空值
+                            cellValue = "";
+                            break;
+                        case HSSFCell.CELL_TYPE_ERROR: // 故障
+                            cellValue = "非法字符";
+                            break;
+                        default:
+                            cellValue = "未知类型";
+                            break;
+                    }
+                }
+                rowLst.add(cellValue);
+            }
+            /** 保存第r行的第c列 */
+            dataLst.add(rowLst);
+        }
+        return dataLst;
+    }
+    public static void main(String[] args) throws Exception {
+        ImportExeclUtil poi = new ImportExeclUtil();
+        // List<List<String>> list = poi.read("d:/aaa.xls");
+        List<List<String>> list = poi.read("G:\\javaProject\\四维看看需求原型\\四维看看后台表格与流程\\订单管理-SN号.xlsx");
+        if (list != null) {
+            for (int i = 0; i < list.size(); i++) {
+                System.out.print("第" + (i) + "行");
+                List<String> cellList = list.get(i);
+                for (int j = 0; j < cellList.size(); j++) {
+
+                    System.out.print("    " + cellList.get(j).toString().trim());
+
+                }
+                System.out.println();
+            }
+
+        }
+
+    }
+
+}
+
+class WDWUtil {
+    public static boolean isExcel2003(String filePath) {
+        return filePath.matches("^.+\\.(?i)(xls)$");
+    }
+    public static boolean isExcel2007(String filePath) {
+        return filePath.matches("^.+\\.(?i)(xlsx)$");
+    }
+}

+ 123 - 0
zhoushan-system-common/src/main/java/com/fdage/util/JwtUtil.java

@@ -0,0 +1,123 @@
+//package com.fdage.util;
+//
+//import io.jsonwebtoken.Claims;
+//import io.jsonwebtoken.JwtBuilder;
+//import io.jsonwebtoken.Jwts;
+//import io.jsonwebtoken.SignatureAlgorithm;
+//
+//import java.util.Date;
+//import java.util.HashMap;
+//import java.util.Map;
+//import java.util.UUID;
+//
+///**
+// * Created by Hb_zzZ on 2018/12/7.
+// */
+//public class JwtUtil {
+//
+//    /**
+//     * 用户登录成功后生成Jwt
+//     * 使用Hs256算法  私匙使用用户密码
+//     *
+//     * @request ttlMillis jwt过期时间
+//     * @request map      登录成功的user对象
+//     * @return
+//     */
+//    public static String createJWT(long ttlMillis, Map<String, String> map) {
+//        //指定签名的时候使用的签名算法,也就是header那部分,jjwt已经将这部分内容封装好了。
+//        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
+//
+//        //生成JWT的时间
+//        long nowMillis = System.currentTimeMillis();
+//        Date now = new Date(nowMillis);
+//
+//        //创建payload的私有声明(根据特定的业务需要添加,如果要拿这个做验证,一般是需要和jwt的接收方提前沟通好验证方式的)
+//        Map<String, Object> claims = new HashMap<String, Object>();
+//        claims.put("id", map.get("id"));
+//        claims.put("username", map.get("username"));
+//        claims.put("password", map.get("password") == null ? "4dage" : map.get("password"));
+//
+//        //生成签名的时候使用的秘钥secret,这个方法本地封装了的,一般可以从本地配置文件中读取,切记这个秘钥不能外露哦。它就是你服务端的私钥,在任何场景都不应该流露出去。一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了。
+//        String key = "zhiHouse_4dage";
+//
+//        //生成签发人
+//        String subject = map.get("username");
+//
+//
+//
+//        //下面就是在为payload添加各种标准声明和私有声明了
+//        //这里其实就是new一个JwtBuilder,设置jwt的body
+//        JwtBuilder builder = Jwts.builder()
+//                //如果有私有声明,一定要先设置这个自己创建的私有的声明,这个是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明的
+//                .setClaims(claims)
+//                //设置jti(JWT ID):是JWT的唯一标识,根据业务需要,这个可以设置为一个不重复的值,主要用来作为一次性token,从而回避重放攻击。
+//                .setId(UUID.randomUUID().toString())
+//                //iat: jwt的签发时间
+//                .setIssuedAt(now)
+//                //代表这个JWT的主体,即它的所有人,这个是一个json格式的字符串,可以存放什么userid,roldid之类的,作为什么用户的唯一标志。
+//                .setSubject(subject)
+//                //设置签名使用的签名算法和签名使用的秘钥
+//                .signWith(signatureAlgorithm, key);
+//        if (ttlMillis >= 0) {
+//            long expMillis = nowMillis + ttlMillis;
+//            Date exp = new Date(expMillis);
+//            //设置过期时间
+//            builder.setExpiration(exp);
+//        }
+//        return builder.compact();
+//    }
+//
+//
+//    /**
+//     * Token的解密
+//     * @request token 加密后的token
+//     * @return
+//     */
+//    public static Claims parseJWT(String token) {
+//        //签名秘钥,和生成的签名的秘钥一模一样
+//        String key = "zhiHouse_4dage";
+//
+//        //得到DefaultJwtParser
+//        Claims claims = Jwts.parser()
+//                //设置签名的秘钥
+//                .setSigningKey(key)
+//                //设置需要解析的jwt
+//                .parseClaimsJws(token).getBody();
+//        return claims;
+//    }
+//
+//
+//    /**
+//     * 校验token
+//     * 在这里可以使用官方的校验,我这里校验的是token中携带的密码于数据库一致的话就校验通过
+//     * @request token
+//     * @request map
+//     * @return
+//     */
+//    public static Boolean isVerify(String token, Map<String, String> map) {
+//        //签名秘钥,和生成的签名的秘钥一模一样
+//        String key = map.get("password");
+//
+//        //得到DefaultJwtParser
+//        Claims claims = Jwts.parser()
+//                //设置签名的秘钥
+//                .setSigningKey(key)
+//                //设置需要解析的jwt
+//                .parseClaimsJws(token).getBody();
+//
+//        if (claims.get("password").equals(map.get("password"))) {
+//            return true;
+//        }
+//
+//        return false;
+//    }
+//
+//    public static void main(String[] args) {
+//        Map<String, String> map = new HashMap<String, String>();
+//        map.put("id","1");
+//        map.put("username","13800138000");
+//        map.put("password","123456");
+//        String token = createJWT(-1, map);
+//        System.out.println("token:" + token);
+//    }
+//}

+ 190 - 0
zhoushan-system-common/src/main/java/com/fdage/util/PasswordUtils.java

@@ -0,0 +1,190 @@
+package com.fdage.util;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.PBEParameterSpec;
+import java.security.Key;
+import java.security.SecureRandom;
+
+public class PasswordUtils {
+
+
+    /**
+     * JAVA6支持以下任意一种算法 PBEWITHMD5ANDDES PBEWITHMD5ANDTRIPLEDES
+     * PBEWITHSHAANDDESEDE PBEWITHSHA1ANDRC2_40 PBKDF2WITHHMACSHA1
+     * */
+
+    /**
+     * 定义使用的算法为:PBEWITHMD5andDES算法
+     */
+    public static final String ALGORITHM = "PBEWithMD5AndDES";//加密算法
+    public static final String Salt = "63293188";//密钥
+
+    /**
+     * 定义迭代次数为1000次
+     */
+    private static final int ITERATIONCOUNT = 1000;
+
+    /**
+     * 获取加密算法中使用的盐值,解密中使用的盐值必须与加密中使用的相同才能完成操作. 盐长度必须为8字节
+     *
+     * @return byte[] 盐值
+     */
+    public static byte[] getSalt() throws Exception {
+        // 实例化安全随机数
+        SecureRandom random = new SecureRandom();
+        // 产出盐
+        return random.generateSeed(8);
+    }
+
+    public static byte[] getStaticSalt() {
+        // 产出盐
+        return Salt.getBytes();
+    }
+
+    /**
+     * 根据PBE密码生成一把密钥
+     *
+     * @param password 生成密钥时所使用的密码
+     * @return Key PBE算法密钥
+     */
+    private static Key getPBEKey(String password) {
+        // 实例化使用的算法
+        SecretKeyFactory keyFactory;
+        SecretKey secretKey = null;
+        try {
+            keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
+            // 设置PBE密钥参数
+            PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
+            // 生成密钥
+            secretKey = keyFactory.generateSecret(keySpec);
+        } catch (Exception e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+
+        return secretKey;
+    }
+
+    /**
+     * 加密明文字符串
+     *
+     * @param plaintext 待加密的明文字符串
+     * @param password  生成密钥时所使用的密码
+     * @param salt      盐值
+     * @return 加密后的密文字符串
+     * @throws Exception
+     */
+    public static String encrypt(String plaintext, String password, byte[] salt) {
+
+        Key key = getPBEKey(password);
+        byte[] encipheredData = null;
+        PBEParameterSpec parameterSpec = new PBEParameterSpec(salt, ITERATIONCOUNT);
+        try {
+            Cipher cipher = Cipher.getInstance(ALGORITHM);
+
+            cipher.init(Cipher.ENCRYPT_MODE, key, parameterSpec);
+
+            encipheredData = cipher.doFinal(plaintext.getBytes());
+        } catch (Exception e) {
+        }
+        return bytesToHexString(encipheredData);
+    }
+
+    /**
+     * 解密密文字符串
+     *
+     * @param ciphertext 待解密的密文字符串
+     * @param password   生成密钥时所使用的密码(如需解密,该参数需要与加密时使用的一致)
+     * @param salt       盐值(如需解密,该参数需要与加密时使用的一致)
+     * @return 解密后的明文字符串
+     * @throws Exception
+     */
+    public static String decrypt(String ciphertext, String password, byte[] salt) {
+
+        Key key = getPBEKey(password);
+        byte[] passDec = null;
+        PBEParameterSpec parameterSpec = new PBEParameterSpec(getStaticSalt(), ITERATIONCOUNT);
+        try {
+            Cipher cipher = Cipher.getInstance(ALGORITHM);
+
+            cipher.init(Cipher.DECRYPT_MODE, key, parameterSpec);
+
+            passDec = cipher.doFinal(hexStringToBytes(ciphertext));
+        } catch (Exception e) {
+            // TODO: handle exception
+        }
+        return new String(passDec);
+    }
+
+    /**
+     * 将字节数组转换为十六进制字符串
+     *
+     * @param src 字节数组
+     * @return
+     */
+    public static String bytesToHexString(byte[] src) {
+        StringBuilder stringBuilder = new StringBuilder("");
+        if (src == null || src.length <= 0) {
+            return null;
+        }
+        for (int i = 0; i < src.length; i++) {
+            int v = src[i] & 0xFF;
+            String hv = Integer.toHexString(v);
+            if (hv.length() < 2) {
+                stringBuilder.append(0);
+            }
+            stringBuilder.append(hv);
+        }
+        return stringBuilder.toString();
+    }
+
+    /**
+     * 将十六进制字符串转换为字节数组
+     *
+     * @param hexString 十六进制字符串
+     * @return
+     */
+    public static byte[] hexStringToBytes(String hexString) {
+        if (hexString == null || hexString.equals("")) {
+            return null;
+        }
+        hexString = hexString.toUpperCase();
+        int length = hexString.length() / 2;
+        char[] hexChars = hexString.toCharArray();
+        byte[] d = new byte[length];
+        for (int i = 0; i < length; i++) {
+            int pos = i * 2;
+            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
+        }
+        return d;
+    }
+
+    private static byte charToByte(char c) {
+        return (byte) "0123456789ABCDEF".indexOf(c);
+    }
+
+    public static void main(String[] args) {
+
+        String userName = "admin_p1";
+        String password = "123456";
+
+        try {
+            byte[] salt = PasswordUtils.getStaticSalt();
+            String ciphertext = PasswordUtils.encrypt(password, userName, salt);
+            System.out.println(ciphertext);
+            String plaintext = PasswordUtils.decrypt("2cd4167b1c627f11a6ce4ce7cadf1b18", "admin", salt);
+            System.out.println(plaintext);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+
+
+
+    }
+
+
+}

+ 106 - 0
zhoushan-system-common/src/main/java/com/fdage/util/Result.java

@@ -0,0 +1,106 @@
+package com.fdage.util;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 通用返回类
+ *
+ * @author
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class Result<T> implements Serializable {
+    private static final long serialVersionUID = -1491499610244557029L;
+    public static final String SUCCESS_MSG = "操作成功";
+    public static int CODE_SUCCESS = 0;
+    public static int CODE_FAILURE = -1;
+    public static String[] NOOP = new String[]{};
+    public static LocalDateTime dataTime = LocalDateTime.now();
+
+    /**
+     * 处理状态:0: 成功, 1: 失败
+     */
+    @ApiModelProperty(value = "处理状态:0: 成功, -1: 失败", name = "code")
+    private int code;
+    /**
+     * 消息
+     */
+    @ApiModelProperty(value = "消息", name = "msg")
+    private String msg;
+    /**
+     * 返回数据
+     */
+    @ApiModelProperty(value = "返回数据", name = "data")
+    private T data;
+
+    @ApiModelProperty(value = "时间戳", name = "timestamp")
+    private LocalDateTime timestamp;
+    /**
+     * 处理成功,并返回数据
+     *
+     * @param data 数据对象
+     * @return data
+     */
+    public static Result success(Object data) {
+        return new Result(CODE_SUCCESS, SUCCESS_MSG, data, dataTime);
+    }
+    /**
+     * 处理成功
+     *
+     * @return data
+     */
+    public static Result success() {
+        return new Result(CODE_SUCCESS, SUCCESS_MSG, NOOP, dataTime);
+    }
+    /**
+     * 处理成功
+     *
+     * @param msg 消息
+     * @return data
+     */
+    public static Result success(String msg) {
+        return new Result(CODE_SUCCESS, msg, NOOP, dataTime);
+    }
+    /**
+     * 处理成功
+     *
+     * @param msg  消息
+     * @param data 数据对象
+     * @return data
+     */
+    public static Result success(String msg, Object data) {
+        return new Result(CODE_SUCCESS, msg, data, dataTime);
+    }
+    /**
+     * 处理失败,并返回数据(一般为错误信息)
+     *
+     * @param code 错误代码
+     * @param msg  消息
+     * @return data
+     */
+    public static Result failure(int code, String msg) {
+        return new Result(code, msg, NOOP , dataTime);
+    }
+    /**
+     * 处理失败
+     *
+     * @param msg 消息
+     * @return data
+     */
+    public static Result failure(String msg) {
+        return failure(CODE_FAILURE, msg);
+    }
+
+    @Override
+    public String toString() {
+        return "JsonResult [code=" + code + ", msg=" + msg + ", data="
+                + data + ", timestamp="+ dataTime + "]";
+    }
+}

+ 263 - 0
zhoushan-system-common/src/main/java/com/fdage/util/VerifyCodeUtils.java

@@ -0,0 +1,263 @@
+package com.fdage.util;
+
+/**
+ * Created by Hb_zzZ on 2019/4/29.
+ */
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.Random;
+
+import javax.imageio.ImageIO;
+
+public class VerifyCodeUtils{
+
+    //使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,去掉了1,0,i,o几个容易混淆的字符
+    public static final String VERIFY_CODES = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
+    private static Random random = new Random();
+
+
+    /**
+     * 使用系统默认字符源生成验证码
+     * @param verifySize    验证码长度
+     * @return
+     */
+    public static String generateVerifyCode(int verifySize){
+        return generateVerifyCode(verifySize, VERIFY_CODES);
+    }
+    /**
+     * 使用指定源生成验证码
+     * @param verifySize    验证码长度
+     * @param sources   验证码字符源
+     * @return
+     */
+    public static String generateVerifyCode(int verifySize, String sources){
+        if(sources == null || sources.length() == 0){
+            sources = VERIFY_CODES;
+        }
+        int codesLen = sources.length();
+        Random rand = new Random(System.currentTimeMillis());
+        StringBuilder verifyCode = new StringBuilder(verifySize);
+        for(int i = 0; i < verifySize; i++){
+            verifyCode.append(sources.charAt(rand.nextInt(codesLen-1)));
+        }
+        return verifyCode.toString();
+    }
+
+    /**
+     * 生成随机验证码文件,并返回验证码值
+     * @param w
+     * @param h
+     * @param outputFile
+     * @param verifySize
+     * @return
+     * @throws IOException
+     */
+    public static String outputVerifyImage(int w, int h, File outputFile, int verifySize) throws IOException{
+        String verifyCode = generateVerifyCode(verifySize);
+        outputImage(w, h, outputFile, verifyCode);
+        return verifyCode;
+    }
+
+    /**
+     * 输出随机验证码图片流,并返回验证码值
+     * @param w
+     * @param h
+     * @param os
+     * @param verifySize
+     * @return
+     * @throws IOException
+     */
+    public static String outputVerifyImage(int w, int h, OutputStream os, int verifySize) throws IOException{
+        String verifyCode = generateVerifyCode(verifySize);
+        outputImage(w, h, os, verifyCode);
+        return verifyCode;
+    }
+
+    /**
+     * 生成指定验证码图像文件
+     * @param w
+     * @param h
+     * @param outputFile
+     * @param code
+     * @throws IOException
+     */
+    public static void outputImage(int w, int h, File outputFile, String code) throws IOException{
+        if(outputFile == null){
+            return;
+        }
+        File dir = outputFile.getParentFile();
+        if(!dir.exists()){
+            dir.mkdirs();
+        }
+        try{
+            outputFile.createNewFile();
+            FileOutputStream fos = new FileOutputStream(outputFile);
+            outputImage(w, h, fos, code);
+            fos.close();
+        } catch(IOException e){
+            throw e;
+        }
+    }
+
+    /**
+     * 输出指定验证码图片流
+     * @param w
+     * @param h
+     * @param os
+     * @param code
+     * @throws IOException
+     */
+    public static void outputImage(int w, int h, OutputStream os, String code) throws IOException{
+        int verifySize = code.length();
+        BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
+        Random rand = new Random();
+        Graphics2D g2 = image.createGraphics();
+        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
+        Color[] colors = new Color[5];
+        Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN,
+                Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE,
+                Color.PINK, Color.YELLOW };
+        float[] fractions = new float[colors.length];
+        for(int i = 0; i < colors.length; i++){
+            colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];
+            fractions[i] = rand.nextFloat();
+        }
+        Arrays.sort(fractions);
+
+        g2.setColor(Color.GRAY);// 设置边框色
+        g2.fillRect(0, 0, w, h);
+
+        Color c = getRandColor(200, 250);
+        g2.setColor(c);// 设置背景色
+        g2.fillRect(0, 2, w, h-4);
+
+        //绘制干扰线
+        Random random = new Random();
+        g2.setColor(getRandColor(160, 200));// 设置线条的颜色
+        for (int i = 0; i < 20; i++) {
+            int x = random.nextInt(w - 1);
+            int y = random.nextInt(h - 1);
+            int xl = random.nextInt(6) + 1;
+            int yl = random.nextInt(12) + 1;
+            g2.drawLine(x, y, x + xl + 40, y + yl + 20);
+        }
+
+        // 添加噪点
+        float yawpRate = 0.05f;// 噪声率
+        int area = (int) (yawpRate * w * h);
+        for (int i = 0; i < area; i++) {
+            int x = random.nextInt(w);
+            int y = random.nextInt(h);
+            int rgb = getRandomIntColor();
+            image.setRGB(x, y, rgb);
+        }
+
+        shear(g2, w, h, c);// 使图片扭曲
+
+        g2.setColor(getRandColor(100, 160));
+        int fontSize = h-4;
+        Font font = new Font("Algerian", Font.ITALIC, fontSize);
+        g2.setFont(font);
+        char[] chars = code.toCharArray();
+        for(int i = 0; i < verifySize; i++){
+            AffineTransform affine = new AffineTransform();
+            affine.setToRotation(Math.PI / 4 * rand.nextDouble() * (rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize/2, h/2);
+            g2.setTransform(affine);
+            g2.drawChars(chars, i, 1, ((w-10) / verifySize) * i + 5, h/2 + fontSize/2 - 10);
+        }
+
+        g2.dispose();
+        ImageIO.write(image, "jpg", os);
+    }
+
+    private static Color getRandColor(int fc, int bc) {
+        if (fc > 255)
+            fc = 255;
+        if (bc > 255)
+            bc = 255;
+        int r = fc + random.nextInt(bc - fc);
+        int g = fc + random.nextInt(bc - fc);
+        int b = fc + random.nextInt(bc - fc);
+        return new Color(r, g, b);
+    }
+
+    private static int getRandomIntColor() {
+        int[] rgb = getRandomRgb();
+        int color = 0;
+        for (int c : rgb) {
+            color = color << 8;
+            color = color | c;
+        }
+        return color;
+    }
+
+    private static int[] getRandomRgb() {
+        int[] rgb = new int[3];
+        for (int i = 0; i < 3; i++) {
+            rgb[i] = random.nextInt(255);
+        }
+        return rgb;
+    }
+
+    private static void shear(Graphics g, int w1, int h1, Color color) {
+        shearX(g, w1, h1, color);
+        shearY(g, w1, h1, color);
+    }
+
+    private static void shearX(Graphics g, int w1, int h1, Color color) {
+
+        int period = random.nextInt(2);
+
+        boolean borderGap = true;
+        int frames = 1;
+        int phase = random.nextInt(2);
+
+        for (int i = 0; i < h1; i++) {
+            double d = (double) (period >> 1)
+                    * Math.sin((double) i / (double) period
+                    + (6.2831853071795862D * (double) phase)
+                    / (double) frames);
+            g.copyArea(0, i, w1, 1, (int) d, 0);
+            if (borderGap) {
+                g.setColor(color);
+                g.drawLine((int) d, i, 0, i);
+                g.drawLine((int) d + w1, i, w1, i);
+            }
+        }
+
+    }
+
+    private static void shearY(Graphics g, int w1, int h1, Color color) {
+
+        int period = random.nextInt(40) + 10; // 50;
+
+        boolean borderGap = true;
+        int frames = 20;
+        int phase = 7;
+        for (int i = 0; i < w1; i++) {
+            double d = (double) (period >> 1)
+                    * Math.sin((double) i / (double) period
+                    + (6.2831853071795862D * (double) phase)
+                    / (double) frames);
+            g.copyArea(i, 0, 1, h1, 0, (int) d);
+            if (borderGap) {
+                g.setColor(color);
+                g.drawLine(i, (int) d, i, 0);
+                g.drawLine(i, (int) d + h1, i, h1);
+            }
+
+        }
+
+    }
+}
+

+ 90 - 0
zhoushan-system-dao/pom.xml

@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.0.7.RELEASE</version>
+        <relativePath/> <!-- lookup parent from repository -->
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>com.fdage</groupId>
+    <version>0.0.1-SNAPSHOT</version>
+    <artifactId>zhoushan-system-dao</artifactId>
+    <packaging>jar</packaging>
+    <name>zhoushan-system-dao</name>
+    <description>Demo project for Spring Boot</description>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <java.version>1.8</java.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.fdage</groupId>
+            <artifactId>zhoushan-system-common</artifactId>
+            <version>0.0.1-SNAPSHOT</version>
+        </dependency>
+
+        <!-- 添加 MyBatis -->
+        <dependency>
+            <groupId>org.mybatis.spring.boot</groupId>
+            <artifactId>mybatis-spring-boot-starter</artifactId>
+            <version>1.2.0</version>
+        </dependency>
+
+        <!--&lt;!&ndash; jdbc操作数据库 &ndash;&gt;-->
+        <!--<dependency>-->
+            <!--<groupId>org.springframework.boot</groupId>-->
+            <!--<artifactId>spring-boot-starter-jdbc</artifactId>-->
+        <!--</dependency>-->
+
+        <!--<dependency>-->
+            <!--<groupId>org.hsqldb</groupId>-->
+            <!--<artifactId>hsqldb</artifactId>-->
+            <!--<scope>runtime</scope>-->
+        <!--</dependency>-->
+
+        <!--<dependency>-->
+            <!--<groupId>org.springframework.boot</groupId>-->
+            <!--<artifactId>spring-boot-starter-jdbc</artifactId>-->
+            <!--<exclusions>-->
+                <!--<exclusion>-->
+                    <!--<groupId>org.apache.tomcat</groupId>-->
+                    <!--<artifactId>tomcat-jdbc</artifactId>-->
+                <!--</exclusion>-->
+            <!--</exclusions>-->
+        <!--</dependency>-->
+
+        <!--<dependency>-->
+            <!--<groupId>mysql</groupId>-->
+            <!--<artifactId>mysql-connector-java</artifactId>-->
+            <!--<version>5.1.21</version>-->
+        <!--</dependency>-->
+
+        <!--&lt;!&ndash; 分页插件 &ndash;&gt;-->
+        <!--<dependency>-->
+            <!--<groupId>com.github.pagehelper</groupId>-->
+            <!--<artifactId>pagehelper-spring-boot-starter</artifactId>-->
+            <!--<version>1.1.2</version>-->
+        <!--</dependency>-->
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 21 - 0
zhoushan-system-dao/src/main/java/com/fdage/dao/base/SceneMapper.java

@@ -0,0 +1,21 @@
+package com.fdage.dao.base;
+
+import com.fdage.entity.SceneEntity;
+
+import java.util.List;
+
+/**
+ * Created by owen on 2021/8/23 0023 17:56
+ */
+public interface SceneMapper {
+
+    List<SceneEntity> findAll();
+
+    SceneEntity findById(Long id);
+
+    int insert(SceneEntity entity);
+
+    int update(SceneEntity entity);
+
+    int remove(Long id);
+}

+ 17 - 0
zhoushan-system-dao/src/main/java/com/fdage/dao/base/TbAuthorityMapper.java

@@ -0,0 +1,17 @@
+package com.fdage.dao.base;
+
+import com.fdage.pojo.TbAuthority;
+
+public interface TbAuthorityMapper {
+    int deleteByPrimaryKey(Long id);
+
+    int insert(TbAuthority record);
+
+    int insertSelective(TbAuthority record);
+
+    TbAuthority selectByPrimaryKey(Long id);
+
+    int updateByPrimaryKeySelective(TbAuthority record);
+
+    int updateByPrimaryKey(TbAuthority record);
+}

+ 23 - 0
zhoushan-system-dao/src/main/java/com/fdage/dao/base/TbCollectionMapper.java

@@ -0,0 +1,23 @@
+package com.fdage.dao.base;
+
+import com.fdage.pojo.TbCollection;
+
+public interface TbCollectionMapper {
+    int deleteByPrimaryKey(Long id);
+
+    int insert(TbCollection record);
+
+    int insertSelective(TbCollection record);
+
+    TbCollection selectByPrimaryKey(Long id);
+
+    int updateByPrimaryKeySelective(TbCollection record);
+
+//    int updateByPrimaryKeyWithBLOBs(TbCollection record);
+
+    int updateByPrimaryKey(TbCollection record);
+
+    void addVisit(Long id);
+
+    Long countVisit();
+}

+ 17 - 0
zhoushan-system-dao/src/main/java/com/fdage/dao/base/TbCollectionTimeMapper.java

@@ -0,0 +1,17 @@
+package com.fdage.dao.base;
+
+import com.fdage.pojo.TbCollectionTime;
+
+public interface TbCollectionTimeMapper {
+    int deleteByPrimaryKey(Long id);
+
+    int insert(TbCollectionTime record);
+
+    int insertSelective(TbCollectionTime record);
+
+    TbCollectionTime selectByPrimaryKey(Long id);
+
+    int updateByPrimaryKeySelective(TbCollectionTime record);
+
+    int updateByPrimaryKey(TbCollectionTime record);
+}

+ 17 - 0
zhoushan-system-dao/src/main/java/com/fdage/dao/base/TbCollectionTypeMapper.java

@@ -0,0 +1,17 @@
+package com.fdage.dao.base;
+
+import com.fdage.pojo.TbCollectionType;
+
+public interface TbCollectionTypeMapper {
+    int deleteByPrimaryKey(Long id);
+
+    int insert(TbCollectionType record);
+
+    int insertSelective(TbCollectionType record);
+
+    TbCollectionType selectByPrimaryKey(Long id);
+
+    int updateByPrimaryKeySelective(TbCollectionType record);
+
+    int updateByPrimaryKey(TbCollectionType record);
+}

+ 17 - 0
zhoushan-system-dao/src/main/java/com/fdage/dao/base/TbEquipmentMapper.java

@@ -0,0 +1,17 @@
+package com.fdage.dao.base;
+
+import com.fdage.pojo.TbEquipment;
+
+public interface TbEquipmentMapper {
+    int deleteByPrimaryKey(Long id);
+
+    int insert(TbEquipment record);
+
+    int insertSelective(TbEquipment record);
+
+    TbEquipment selectByPrimaryKey(Long id);
+
+    int updateByPrimaryKeySelective(TbEquipment record);
+
+    int updateByPrimaryKey(TbEquipment record);
+}

+ 17 - 0
zhoushan-system-dao/src/main/java/com/fdage/dao/base/TbExhibitionCollectionMapper.java

@@ -0,0 +1,17 @@
+package com.fdage.dao.base;
+
+import com.fdage.pojo.TbExhibitionCollection;
+
+public interface TbExhibitionCollectionMapper {
+    int deleteByPrimaryKey(Long id);
+
+    int insert(TbExhibitionCollection record);
+
+    int insertSelective(TbExhibitionCollection record);
+
+    TbExhibitionCollection selectByPrimaryKey(Long id);
+
+    int updateByPrimaryKeySelective(TbExhibitionCollection record);
+
+    int updateByPrimaryKey(TbExhibitionCollection record);
+}

+ 19 - 0
zhoushan-system-dao/src/main/java/com/fdage/dao/base/TbExhibitionMapper.java

@@ -0,0 +1,19 @@
+package com.fdage.dao.base;
+
+import com.fdage.pojo.TbExhibition;
+
+public interface TbExhibitionMapper {
+    int deleteByPrimaryKey(Long id);
+
+    int insert(TbExhibition record);
+
+    int insertSelective(TbExhibition record);
+
+    TbExhibition selectByPrimaryKey(Long id);
+
+    int updateByPrimaryKeySelective(TbExhibition record);
+
+    int updateByPrimaryKeyWithBLOBs(TbExhibition record);
+
+    int updateByPrimaryKey(TbExhibition record);
+}

+ 17 - 0
zhoushan-system-dao/src/main/java/com/fdage/dao/base/TbExhibitionTypeMapper.java

@@ -0,0 +1,17 @@
+package com.fdage.dao.base;
+
+import com.fdage.pojo.TbExhibitionType;
+
+public interface TbExhibitionTypeMapper {
+    int deleteByPrimaryKey(Long id);
+
+    int insert(TbExhibitionType record);
+
+    int insertSelective(TbExhibitionType record);
+
+    TbExhibitionType selectByPrimaryKey(Long id);
+
+    int updateByPrimaryKeySelective(TbExhibitionType record);
+
+    int updateByPrimaryKey(TbExhibitionType record);
+}

+ 19 - 0
zhoushan-system-dao/src/main/java/com/fdage/dao/base/TbInformationMapper.java

@@ -0,0 +1,19 @@
+package com.fdage.dao.base;
+
+import com.fdage.pojo.TbInformation;
+
+public interface TbInformationMapper {
+    int deleteByPrimaryKey(Long id);
+
+    int insert(TbInformation record);
+
+    int insertSelective(TbInformation record);
+
+    TbInformation selectByPrimaryKey(Long id);
+
+    int updateByPrimaryKeySelective(TbInformation record);
+
+    int updateByPrimaryKeyWithBLOBs(TbInformation record);
+
+    int updateByPrimaryKey(TbInformation record);
+}

+ 18 - 0
zhoushan-system-dao/src/main/java/com/fdage/dao/base/TbLogMapper.java

@@ -0,0 +1,18 @@
+package com.fdage.dao.base;
+
+
+import com.fdage.pojo.TbLog;
+
+public interface TbLogMapper {
+    int deleteByPrimaryKey(Long id);
+
+    int insert(TbLog record);
+
+    int insertSelective(TbLog record);
+
+    TbLog selectByPrimaryKey(Long id);
+
+    int updateByPrimaryKeySelective(TbLog record);
+
+    int updateByPrimaryKey(TbLog record);
+}

+ 26 - 0
zhoushan-system-dao/src/main/java/com/fdage/dao/base/TbMenuMapper.java

@@ -0,0 +1,26 @@
+package com.fdage.dao.base;
+
+import com.fdage.pojo.TbMenu;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Component;
+
+public interface TbMenuMapper {
+    int deleteByPrimaryKey(Long id);
+
+    int insert(TbMenu record);
+
+    int insertSelective(TbMenu record);
+
+    TbMenu selectByPrimaryKey(Long id);
+
+    int updateByPrimaryKeySelective(TbMenu record);
+
+    int updateByPrimaryKey(TbMenu record);
+
+    @Component
+    @Mapper
+    interface SceneMapper  {
+
+
+    }
+}

+ 17 - 0
zhoushan-system-dao/src/main/java/com/fdage/dao/base/TbPositionMapper.java

@@ -0,0 +1,17 @@
+package com.fdage.dao.base;
+
+import com.fdage.pojo.TbPosition;
+
+public interface TbPositionMapper {
+    int deleteByPrimaryKey(Long id);
+
+    int insert(TbPosition record);
+
+    int insertSelective(TbPosition record);
+
+    TbPosition selectByPrimaryKey(Long id);
+
+    int updateByPrimaryKeySelective(TbPosition record);
+
+    int updateByPrimaryKey(TbPosition record);
+}

+ 17 - 0
zhoushan-system-dao/src/main/java/com/fdage/dao/base/TbResourceMapper.java

@@ -0,0 +1,17 @@
+package com.fdage.dao.base;
+
+import com.fdage.pojo.TbResource;
+
+public interface TbResourceMapper {
+    int deleteByPrimaryKey(Long id);
+
+    int insert(TbResource record);
+
+    int insertSelective(TbResource record);
+
+    TbResource selectByPrimaryKey(Long id);
+
+    int updateByPrimaryKeySelective(TbResource record);
+
+    int updateByPrimaryKey(TbResource record);
+}

+ 17 - 0
zhoushan-system-dao/src/main/java/com/fdage/dao/base/TbRoleMapper.java

@@ -0,0 +1,17 @@
+package com.fdage.dao.base;
+
+import com.fdage.pojo.TbRole;
+
+public interface TbRoleMapper {
+    int deleteByPrimaryKey(Long id);
+
+    int insert(TbRole record);
+
+    int insertSelective(TbRole record);
+
+    TbRole selectByPrimaryKey(Long id);
+
+    int updateByPrimaryKeySelective(TbRole record);
+
+    int updateByPrimaryKey(TbRole record);
+}

+ 17 - 0
zhoushan-system-dao/src/main/java/com/fdage/dao/base/TbUserMapper.java

@@ -0,0 +1,17 @@
+package com.fdage.dao.base;
+
+import com.fdage.pojo.TbUser;
+
+public interface TbUserMapper {
+    int deleteByPrimaryKey(Long id);
+
+    int insert(TbUser record);
+
+    int insertSelective(TbUser record);
+
+    TbUser selectByPrimaryKey(Long id);
+
+    int updateByPrimaryKeySelective(TbUser record);
+
+    int updateByPrimaryKey(TbUser record);
+}

+ 22 - 0
zhoushan-system-dao/src/main/java/com/fdage/dao/base/VideoMapper.java

@@ -0,0 +1,22 @@
+package com.fdage.dao.base;
+
+import com.fdage.entity.SceneEntity;
+import com.fdage.entity.VideoEntity;
+
+import java.util.List;
+
+/**
+ * Created by owen on 2021/8/23 0023 17:56
+ */
+public interface VideoMapper {
+
+    List<VideoEntity> findAll();
+
+    VideoEntity findById(Long id);
+
+    int insert(VideoEntity entity);
+
+    int update(VideoEntity entity);
+
+    int remove(Long id);
+}

+ 0 - 0
zhoushan-system-dao/src/main/java/com/fdage/dao/cust/TbCollectionMapperCust.java


Some files were not shown because too many files changed in this diff