commit 2f813b341859d09bf457c539be43430b164660bd
Author: huanghui <2397241381@qq.com>
Date: Wed Jan 31 14:19:24 2024 +0800
初始化仓库
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..347f78c
--- /dev/null
+++ b/README.md
@@ -0,0 +1,105 @@
+## 后端springboot
+
+### 采用redis缓存
+
+#### 1.pom.xml文件改动
+- 1、增加redis依赖,删除exclusions即可
+```xml
+
+ com.anji-plus
+ spring-boot-gaea
+ 2.0.5.RELEASE
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
+
+
+
+```
+
+- 2、 删除ehcache相关依赖
+```xml
+
+ net.sf.ehcache
+ ehcache
+ 2.10.6
+
+```
+
+
+#### 2.删除代码
+- 1、删除cache文件夹
+目录地址:com.anjiplus.template.gaea.business.cache
+
+- 2、删除相关bean
+文件地址:com.anjiplus.template.gaea.business.config.BusinessAutoConfiguration.java
+```java
+ @Bean
+ public CacheHelper gaeaCacheHelper(){
+ return new ReportCacheHelper();
+ }
+
+ @Bean
+ public EhCacheCache ehCacheCache() {
+ return (EhCacheCache) ehCacheCacheManager().getCache("reportCache");
+ }
+
+ /**
+ * 创建ehCacheCacheManager
+ */
+ @Bean
+ public EhCacheCacheManager ehCacheCacheManager() {
+
+ return new EhCacheCacheManager();
+ }
+```
+
+底层的实现方式如下:
+CacheHelper底层默认实现为RedisCacheHelper。
+@ConditionalOnMissingBean 注解起到的作用
+```java
+package com.anji.plus.gaea;
+
+@Configuration
+@EnableConfigurationProperties({GaeaProperties.class})
+public class GaeaAutoConfiguration {
+ @Bean
+ @ConditionalOnClass({RedisAutoConfiguration.class})
+ @ConditionalOnMissingBean
+ public CacheHelper cacheHelper() {
+ return new RedisCacheHelper();
+ }
+}
+```
+
+#### 3.bootstrap.yml加上对应的redis配置
+注意yml格式
+```yaml
+spring:
+ redis:
+ host: 10.108.x.x
+ port: 6379
+ password: ****
+ database: 1
+ timeout: 10000
+ pool:
+ max-active: 8
+ max-idle: 8
+ max-wait: -1
+ min-idle: 0
+
+```
+哨兵模式
+```yaml
+spring:
+ redis:
+ sentinel:
+ master: master01
+ nodes: 10.108.xx.xx:26379,10.108.xx.xx:26379,10.108.xx.xx:26379
+ database: 1
+ password: *******
+ timeout: 10000
+```
diff --git a/lib/kudu/ImpalaJDBC41-2.5.41.jar b/lib/kudu/ImpalaJDBC41-2.5.41.jar
new file mode 100644
index 0000000..058a54d
Binary files /dev/null and b/lib/kudu/ImpalaJDBC41-2.5.41.jar differ
diff --git a/lib/kudu/hive-metastore-1.2.1.jar b/lib/kudu/hive-metastore-1.2.1.jar
new file mode 100644
index 0000000..074aaf2
Binary files /dev/null and b/lib/kudu/hive-metastore-1.2.1.jar differ
diff --git a/lib/kudu/hive-service-1.2.1.jar b/lib/kudu/hive-service-1.2.1.jar
new file mode 100644
index 0000000..75557f9
Binary files /dev/null and b/lib/kudu/hive-service-1.2.1.jar differ
diff --git a/lib/kudu/libfb303-0.9.2.jar b/lib/kudu/libfb303-0.9.2.jar
new file mode 100644
index 0000000..f693b42
Binary files /dev/null and b/lib/kudu/libfb303-0.9.2.jar differ
diff --git a/lib/kudu/libthrift-0.9.2.jar b/lib/kudu/libthrift-0.9.2.jar
new file mode 100644
index 0000000..39143a5
Binary files /dev/null and b/lib/kudu/libthrift-0.9.2.jar differ
diff --git a/lib/kudu/logback-classic-1.2.3.jar b/lib/kudu/logback-classic-1.2.3.jar
new file mode 100644
index 0000000..bed00c0
Binary files /dev/null and b/lib/kudu/logback-classic-1.2.3.jar differ
diff --git a/lib/kudu/logback-core-1.2.3.jar b/lib/kudu/logback-core-1.2.3.jar
new file mode 100644
index 0000000..487b395
Binary files /dev/null and b/lib/kudu/logback-core-1.2.3.jar differ
diff --git a/lib/kudu/slf4j-api-1.7.30.jar b/lib/kudu/slf4j-api-1.7.30.jar
new file mode 100644
index 0000000..29ac26f
Binary files /dev/null and b/lib/kudu/slf4j-api-1.7.30.jar differ
diff --git a/lib/mssqlserver/sqljdbc4-4.0.jar b/lib/mssqlserver/sqljdbc4-4.0.jar
new file mode 100644
index 0000000..d6b7f6d
Binary files /dev/null and b/lib/mssqlserver/sqljdbc4-4.0.jar differ
diff --git a/lib/oracle/ojdbc6-11.2.0.4.jar b/lib/oracle/ojdbc6-11.2.0.4.jar
new file mode 100644
index 0000000..767eba7
Binary files /dev/null and b/lib/oracle/ojdbc6-11.2.0.4.jar differ
diff --git a/lib/postgresql/postgresql-9.4.1212.jre7.jar b/lib/postgresql/postgresql-9.4.1212.jre7.jar
new file mode 100644
index 0000000..36c01b5
Binary files /dev/null and b/lib/postgresql/postgresql-9.4.1212.jre7.jar differ
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..2aa88e4
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,250 @@
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.3.5.RELEASE
+
+
+
+ BigData
+ 4.0.0
+
+ com.BigData
+ BigData
+ 1.0.1
+
+
+ UTF-8
+ -Xdoclint:none
+ 1.8
+ 1.8
+ true
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.apache.logging.log4j
+ log4j-to-slf4j
+
+
+
+
+
+ org.apache.logging.log4j
+ log4j-to-slf4j
+ 2.15.0
+
+
+
+ org.apache.logging.log4j
+ log4j-api
+ 2.15.0
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-cache
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+ org.springframework
+ spring-mock
+ 2.0.8
+
+
+
+ org.springframework.cloud
+ spring-cloud-context
+ 2.2.6.RELEASE
+
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ true
+
+
+
+ com.anji-plus
+ spring-boot-gaea
+ 2.0.5.RELEASE
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
+
+
+
+
+ com.anji-plus
+ spring-boot-starter-gaea-oss
+ 2.0.5.RELEASE
+
+
+
+ com.baomidou
+ mybatis-plus-boot-starter
+ 3.3.2
+
+
+
+ mysql
+ mysql-connector-java
+ 8.0.28
+
+
+ org.flywaydb
+ flyway-core
+ 5.2.1
+
+
+
+ net.sf.ehcache
+ ehcache
+ 2.10.6
+
+
+
+ org.apache.httpcomponents
+ httpclient
+ 4.5.13
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.10
+ true
+
+
+
+ com.itextpdf
+ itextpdf
+ 5.5.13.2
+
+
+ com.itextpdf
+ itext-asian
+ 5.2.0
+
+
+
+ org.apache.poi
+ poi
+ 4.1.2
+
+
+ org.apache.poi
+ poi-ooxml
+ 4.1.2
+
+
+ org.apache.poi
+ poi-ooxml-schemas
+ 4.1.2
+
+
+
+ org.codehaus.groovy
+ groovy
+ 3.0.9
+
+
+
+ org.xhtmlrenderer
+ core-renderer
+ R8
+
+
+
+ com.itextpdf.tool
+ xmlworker
+ 5.5.13
+
+
+
+
+
+
+ develop.anji-plus.com
+ MS@anji-plus.com
+ https://github.com/anji-plus
+
+
+
+
+
+ dev
+
+ dev
+
+
+ true
+
+
+
+
+
+
+
+ src/main/resources
+ true
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ true
+
+
+
+ org.apache.maven.plugins
+ maven-resources-plugin
+
+
+ ttf
+ woff
+ woff2
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+ 3.3.0
+
+
+ src/main/assembly/assembly.xml
+
+
+
+
+ make-assembly
+ package
+
+ single
+
+
+
+
+
+
+
diff --git a/src/main/assembly/assembly.xml b/src/main/assembly/assembly.xml
new file mode 100644
index 0000000..694d0b9
--- /dev/null
+++ b/src/main/assembly/assembly.xml
@@ -0,0 +1,62 @@
+
+ assembly
+
+ zip
+
+
+ true
+
+
+ lib/mssqlserver
+ lib
+ 0755
+
+
+ lib/kudu
+ lib
+ 0755
+
+
+ lib/oracle
+ lib
+ 0755
+
+
+ src/main/assembly/bin
+ bin
+ 0755
+
+
+ src/main/resources
+ conf
+
+ bootstrap.yml
+
+
+
+ target
+ lib
+
+ aj-report-*.jar
+
+
+ *-javadoc.jar
+ *-sources.jar
+
+ 0755
+
+
+ ./../
+ /
+
+ LICENSE
+ NOTICE
+
+
+
+
diff --git a/src/main/assembly/bin/restart.sh b/src/main/assembly/bin/restart.sh
new file mode 100644
index 0000000..9a5e416
--- /dev/null
+++ b/src/main/assembly/bin/restart.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+cd `dirname $0`
+./stop.sh
+./start.sh
+
diff --git a/src/main/assembly/bin/start.bat b/src/main/assembly/bin/start.bat
new file mode 100644
index 0000000..e0650a8
--- /dev/null
+++ b/src/main/assembly/bin/start.bat
@@ -0,0 +1,42 @@
+@echo off & setlocal enabledelayedexpansion
+
+rem 判断cmd中是否有JAVA_HOME
+rem set JAVA_HOME=D:\App\Java\jdk1.8.0_172
+IF "%JAVA_HOME%" == "" (
+ goto END
+) ELSE (
+ goto START
+)
+
+:END
+ rem cmd中未找到JAVA_HOME,请在此启动文件中第4行指定,然后尝试
+ echo Not JAVA_HOME Find, Please add JAVA_HOME in this file line 4
+ pause
+ exit
+
+:START
+ rem 获取应用的根目录
+ cd ../
+ set BIN_DIR=%cd%
+ set CONF_YML=%BIN_DIR%\conf\bootstrap.yml
+
+ cd %BIN_DIR%\lib
+ rem 查找aj-report*.jar启动文件,版本号每次会变
+ for /f "delims=" %%i in ('dir /a-d /b /on aj-report*.jar') do (
+ set BOOT_JAR=%%i
+ )
+
+ rem 查找附加的驱动,加到java启动的classpath中
+ for %%i in ("*") do (
+ if "%%i" neq "%BOOT_JAR%" (
+ set LIB_JARS=!LIB_JARS!%BIN_DIR%\lib\%%i;
+ )
+ )
+
+ rem 启动内存设置,请根据自己需要调整
+ cd %BIN_DIR%\bin
+ set JAVA_OPTS= -server -Xms1g -Xmx2g -Xmn256m -XX:PermSize=128m -Xss256k
+
+ rem 正式启动
+ "%JAVA_HOME%"\bin\java %JAVA_OPTS% -Xbootclasspath/a:%LIB_JARS% -jar -Dspring.config.location=%CONF_YML% %BIN_DIR%\lib\%BOOT_JAR%
+ pause
diff --git a/src/main/assembly/bin/start.sh b/src/main/assembly/bin/start.sh
new file mode 100644
index 0000000..6287380
--- /dev/null
+++ b/src/main/assembly/bin/start.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+#判断java是否存在
+command -v java >/dev/null 2>&1 || { echo >&2 "require java but it's not installed. Aborting."; sleep 5;exit 1; }
+
+cd `dirname $0`
+BIN_DIR=`pwd` #安装目录
+cd ../
+DEPLOY_DIR=`pwd`
+LIB_DIR=$DEPLOY_DIR/lib #jar目录
+CONF_DIR=$DEPLOY_DIR/conf #conf目录
+LOGS_DIR=$DEPLOY_DIR/logs #log目录
+
+LIB_JARS=`ls $LIB_DIR|grep -v aj-report|awk '{print "'$LIB_DIR'/"$0}'|tr "\n" ":"`
+
+PIDS=`ps -f | grep java | grep "aj-report" |awk '{print $2}'`
+if [ -n "$PIDS" ]; then
+ echo "ERROR: The AJ-Report already started!"
+ echo "PID: $PIDS"
+ exit 1
+fi
+
+JAVA_OPTS=" -server -Xms1g -Xmx2g -Xmn256m -XX:PermSize=128m -Xss256k "
+nohup java $JAVA_OPTS -Xbootclasspath/a:$LIB_JARS -jar -Dspring.config.location=$CONF_DIR/bootstrap.yml $LIB_DIR/aj-report-*.jar >/dev/null 2>&1 &
+
+echo "AJ-Report 正在后台执行,请查看aj-report.log日志(${DEPLOY_DIR}/logs/aj-report.log),确定软件运行情况"
diff --git a/src/main/assembly/bin/stop.sh b/src/main/assembly/bin/stop.sh
new file mode 100644
index 0000000..c6ca5d5
--- /dev/null
+++ b/src/main/assembly/bin/stop.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+pid=`ps ax | grep -i 'aj-report' | grep java | grep -v grep | awk '{print $1}'`
+if [ -z "$pid" ] ; then
+ echo "No AJ-Report Server running."
+ exit -1;
+fi
+
+kill -9 ${pid}
+
+echo "Send shutdown request to aj-reporte(${pid}) OK"
+
+
diff --git a/src/main/java/com/anjiplus/template/gaea/business/ReportApplication.java b/src/main/java/com/anjiplus/template/gaea/business/ReportApplication.java
new file mode 100644
index 0000000..c0b5a0d
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/ReportApplication.java
@@ -0,0 +1,29 @@
+package com.anjiplus.template.gaea.business;
+
+import com.anji.plus.gaea.annotation.enabled.EnabledGaeaConfiguration;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+/**
+ * 业务模板
+ * @author lr
+ * @since 2021-02-03
+ */
+@EnabledGaeaConfiguration
+@SpringBootApplication(scanBasePackages = {
+ "com.anjiplus.template.gaea",
+ "com.anji.plus"
+})
+@MapperScan(basePackages = {
+ "com.anjiplus.template.gaea.business.modules.*.dao",
+ "com.anjiplus.template.gaea.business.modules.*.**.dao",
+ "com.anji.plus.gaea.*.module.*.dao"
+})
+@EnableSwagger2
+public class ReportApplication {
+ public static void main( String[] args ) {
+ SpringApplication.run(ReportApplication.class);
+ }
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/base/BaseController.java b/src/main/java/com/anjiplus/template/gaea/business/base/BaseController.java
new file mode 100644
index 0000000..0052d6c
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/base/BaseController.java
@@ -0,0 +1,25 @@
+package com.anjiplus.template.gaea.business.base;
+
+import org.springframework.context.i18n.LocaleContextHolder;
+
+import com.anji.plus.gaea.curd.controller.GaeaBaseController;
+import com.anji.plus.gaea.curd.dto.BaseDTO;
+import com.anji.plus.gaea.curd.entity.BaseEntity;
+import com.anji.plus.gaea.curd.params.PageParam;
+
+/**
+ * 项目级的Controller公共处理基类
+ *
+ * @author WongBin
+ * @date 2021/3/26
+ */
+public abstract class BaseController
+ extends GaeaBaseController
{
+ /**
+ * 获取当前语言类型
+ * @return
+ */
+ public String getI18nLang(){
+ return LocaleContextHolder.getLocale().getLanguage();
+ }
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/base/BaseService.java b/src/main/java/com/anjiplus/template/gaea/business/base/BaseService.java
new file mode 100644
index 0000000..6808cb9
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/base/BaseService.java
@@ -0,0 +1,15 @@
+package com.anjiplus.template.gaea.business.base;
+
+import com.anji.plus.gaea.curd.entity.BaseEntity;
+import com.anji.plus.gaea.curd.params.PageParam;
+import com.anji.plus.gaea.curd.service.GaeaBaseService;
+import org.springframework.context.i18n.LocaleContextHolder;
+
+/**
+ * 项目级的Service公共处理基类
+ * @author WongBin
+ * @date 2021/3/26
+ */
+public interface BaseService
extends GaeaBaseService
{
+
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/base/HealthController.java b/src/main/java/com/anjiplus/template/gaea/business/base/HealthController.java
new file mode 100644
index 0000000..63a5c64
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/base/HealthController.java
@@ -0,0 +1,21 @@
+package com.anjiplus.template.gaea.business.base;
+
+import com.anji.plus.gaea.bean.ResponseBean;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @desc 用户管理 controller
+ * @author 木子李·De
+ * @date 2019-02-17 08:50:11.902
+ **/
+@RestController
+public class HealthController {
+
+ @GetMapping("health")
+ public ResponseBean health() {
+ return ResponseBean.builder().build();
+ }
+
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/cache/ReportCacheHelper.java b/src/main/java/com/anjiplus/template/gaea/business/cache/ReportCacheHelper.java
new file mode 100644
index 0000000..7cb03a5
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/cache/ReportCacheHelper.java
@@ -0,0 +1,150 @@
+package com.anjiplus.template.gaea.business.cache;
+
+
+import com.anji.plus.gaea.cache.CacheHelper;
+import com.google.common.collect.Maps;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.Cache;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class ReportCacheHelper implements CacheHelper, ApplicationContextAware {
+
+ @Autowired
+ private Cache cache;
+
+ @Override
+ public String stringGet(String key) {
+ Cache.ValueWrapper valueWrapper = cache.get(key);
+ if (valueWrapper != null) {
+ return (String) valueWrapper.get();
+ }
+ return CacheHelper.super.stringGet(key);
+ }
+
+ @Override
+ public Boolean setIfAbsent(String key, String value) {
+ cache.putIfAbsent(key, value);
+ return true;
+ }
+
+
+ @Override
+ public boolean exist(String key) {
+ String cacheHoldTime = stringGet(key + "_HoldTime");
+ if (cacheHoldTime != null && Long.parseLong(cacheHoldTime) > 0) {
+ if (Long.parseLong(cacheHoldTime) < System.currentTimeMillis()) {
+ delete(key + "_HoldTime");
+ delete(key);
+ return false;
+ }
+ }
+ return cache.get(key) != null;
+ }
+
+
+ @Override
+ public void stringSet(String key, String value) {
+ cache.put(key, value);
+ }
+
+
+ @Override
+ public String regKey(String key) {
+ return CacheHelper.super.regKey(key);
+ }
+
+ @Override
+ public void stringSetExpire(String key, String value, long seconds) {
+ stringSet(key, value);
+ if (seconds > 0) {
+ //缓存失效时间
+ stringSet(key + "_HoldTime", String.valueOf(System.currentTimeMillis() + seconds * 1000));
+ }
+ }
+
+ @Override
+ public Map hashGet(String key) {
+ Cache.ValueWrapper t = cache.get(key);
+ if (t != null) {
+ return (Map) t.get();
+ }
+ return Maps.newHashMap();
+ }
+
+ @Override
+ public String hashGetString(String key, String hashKey) {
+ Map stringStringMap = hashGet(key);
+ return stringStringMap.get(hashKey);
+ }
+
+ @Override
+ public void hashDel(String key, String hashKey) {
+ Map stringStringMap = hashGet(key);
+ stringStringMap.remove(hashKey);
+ }
+
+ @Override
+ public void hashBatchDel(String key, Set hashKeys) {
+ Map stringStringMap = hashGet(key);
+ hashKeys.forEach(stringStringMap::remove);
+ }
+
+ @Override
+ public boolean hashExist(String key, String hashKey) {
+ if (exist(key)) {
+ Map map = hashGet(key);
+ return map.containsKey(hashKey);
+ }
+ return false;
+ }
+
+ @Override
+ public boolean hashAnyExist(String key, String[] hashKeys) {
+ return CacheHelper.super.hashAnyExist(key, hashKeys);
+ }
+
+ @Override
+ public void hashSet(String key, String hashKey, String hashValue) {
+ Map map;
+ if (exist(key)) {
+ map = hashGet(key);
+ } else {
+ map = new HashMap<>();
+ }
+ map.put(hashKey, hashValue);
+ hashSet(key, map);
+ }
+
+ @Override
+ public void hashSet(String key, Map hash) {
+ cache.put(key, hash);
+ }
+
+ @Override
+ public boolean delete(String key) {
+ if (exist(key)) {
+ cache.evict(key);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean delete(List keys) {
+ keys.forEach(this::delete);
+ return true;
+ }
+
+
+ @Override
+ public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+ /*基于内存的本地缓存*/
+ cache = (Cache) applicationContext.getBean("ehCacheCache");
+ }
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/code/ResponseCode.java b/src/main/java/com/anjiplus/template/gaea/business/code/ResponseCode.java
new file mode 100644
index 0000000..0cefc8b
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/code/ResponseCode.java
@@ -0,0 +1,139 @@
+package com.anjiplus.template.gaea.business.code;
+
+/**
+ * 响应码
+ * @author lr
+ * @since 2021-02-22
+ */
+public interface ResponseCode {
+
+ String NOT_NULL = "field.not.null";
+ String NOT_EMPTY = "field.not.empty";
+ String MIN = "field.min";
+ String MAX = "field.max";
+ String DICT_ERROR = "field.dict.error";
+
+ String USER_PASSWORD_ERROR = "User.password.error";
+ /**
+ * 用户名或者密码不正确
+ */
+ String LOGIN_ERROR = "login.error";
+
+ /**
+ * 新密码不能和原密码一致
+ */
+ String USER_PASSWORD_CONFIG_PASSWORD_CANOT_EQUAL = "user.password.config.password.canot.equal";
+
+ /**
+ * 密码和确认密码不一致
+ */
+ String USER_INCONSISTENT_PASSWORD_ERROR = "user.inconsistent.password.error";
+
+ /**
+ * 旧密码不正确
+ */
+ String USER_OLD_PASSWORD_ERROR = "user.old.password.error";
+
+
+
+ /**
+ * 用户token过期
+ */
+ String USER_TOKEN_EXPIRED = "User.token.expired";
+
+ /**
+ * 字典项重复
+ */
+ String DICT_ITEM_REPEAT = "Dict.item.code.exist";
+
+ /**
+ * 数字字典国际化标识不能为null
+ */
+ String DICT_CODE_LOCALE_NULL = "500-00002";
+
+ /**
+ * 参数为空
+ */
+ String PARAM_IS_NULL = "Rule.execute.param.null";
+
+ /**
+ * 规则编译不通过
+ */
+ String RULE_CONTENT_COMPILE_ERROR = "Rule.content.compile.error";
+
+ /**
+ * 规则执行不通过
+ */
+ String RULE_CONTENT_EXECUTE_ERROR = "Rule.content.execute.error";
+
+ /**
+ * 规则编码已存在
+ */
+ String RULE_CODE_EXIST = "Rule.code.exist";
+
+ /**
+ * 对应规则内容不存在
+ */
+ String RULE_CONTENT_NOT_EXIST = "Rule.content.not.exist";
+
+ /**
+ * 对应规则字段值不存在
+ */
+ String RULE_FIELDS_NOT_EXIST = "Rule.fields.not.exist";
+
+ /**
+ * 规则字段必填
+ */
+ String RULE_FIELD_VALUE_IS_REQUIRED = "Rule.field.value.is.required";
+
+ /**
+ * 规则字段值类型错误
+ */
+ String RULE_FIELD_VALUE_TYPE_ERROR = "Rule.field.value.type.error";
+
+ /**
+ * 规则参数校验不通过
+ */
+ String RULE_FIELDS_CHECK_ERROR = "Rule.fields.check.error";
+ /**
+ * 组件未加载
+ */
+ String COMPONENT_NOT_LOAD = "Component.load.check.error";
+
+ String AUTH_PASSWORD_NOTSAME = "1001";
+ String OLD_PASSWORD_ERROR = "1003";
+ String USER_ONTEXIST_ORGINFO = "1004";
+ String USER_ONTEXIST_ROLEINFO = "1005";
+ String MENU_TABLE_CODE_EXIST = "1006";
+ String USER_CODE_ISEXIST = "1007";
+ String ROLE_CODE_ISEXIST = "1008";
+ String MENU_CODE_ISEXIST = "1009";
+ String ORG_CODE_ISEXIST = "1010";
+ String SEARCHNAME_ISEXIST = "1011";
+ String SETTINGNAME_ISEXIST = "1012";
+ String DICCODE_ISEXIST = "1013";
+ String DEVICEID_LENGTH = "1014";
+ String USERINFO_EMPTY = "1015";
+ String FILE_EMPTY_FILENAME = "2001";
+ String FILE_SUFFIX_UNSUPPORTED = "2002";
+ String FILE_UPLOAD_ERROR = "2003";
+ String FILE_ONT_EXSIT = "2004";
+ String FILE_OPERATION_FAILED = "file.operation.failed";
+
+ String PUSHCODE_NEED_UNIQUE = "3001";
+ String RECEIVER_IS_EMPTY = "3002";
+ String DATA_SOURCE_CONNECTION_FAILED = "4001";
+ String DATA_SOURCE_TYPE_DOES_NOT_MATCH_TEMPORARILY = "4002";
+ String EXECUTE_SQL_ERROR = "4003";
+ String INCOMPLETE_PARAMETER_REPLACEMENT_VALUES = "4004";
+ String EXECUTE_JS_ERROR = "4005";
+ String ANALYSIS_DATA_ERROR = "4006";
+ String REPORT_CODE_ISEXIST = "4007";
+ String SET_CODE_ISEXIST = "4008";
+ String SOURCE_CODE_ISEXIST = "4009";
+ String CLASS_NOT_FOUND = "4010";
+ String EXECUTE_GROOVY_ERROR = "4011";
+
+ String REPORT_SHARE_LINK_INVALID = "report.share.link.invalid";
+
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/config/BusinessAutoConfiguration.java b/src/main/java/com/anjiplus/template/gaea/business/config/BusinessAutoConfiguration.java
new file mode 100644
index 0000000..a5fbff0
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/config/BusinessAutoConfiguration.java
@@ -0,0 +1,51 @@
+package com.anjiplus.template.gaea.business.config;
+
+import com.anji.plus.gaea.cache.CacheHelper;
+import com.anjiplus.template.gaea.business.cache.ReportCacheHelper;
+import com.anjiplus.template.gaea.business.runner.ApplicationInitRunner;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.cache.ehcache.EhCacheCache;
+import org.springframework.cache.ehcache.EhCacheCacheManager;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * business配置类
+ * @author lr
+ * @since 2021-04-08
+ */
+@Configuration
+@MapperScan(basePackages = {
+ "com.anjiplus.template.gaea.business.modules.*.dao",
+ "com.anjiplus.template.gaea.business.modules.*.**.dao"
+})
+public class BusinessAutoConfiguration {
+
+ /**
+ * 系统启动完执行
+ * @return
+ */
+ @Bean
+ public ApplicationInitRunner applicationInitRunner() {
+ return new ApplicationInitRunner();
+ }
+
+ @Bean
+ public CacheHelper gaeaCacheHelper(){
+ return new ReportCacheHelper();
+ }
+
+ @Bean
+ public EhCacheCache ehCacheCache() {
+ return (EhCacheCache) ehCacheCacheManager().getCache("reportCache");
+ }
+
+ /**
+ * 创建ehCacheCacheManager
+ */
+ @Bean
+ public EhCacheCacheManager ehCacheCacheManager() {
+
+ return new EhCacheCacheManager();
+ }
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/config/DatabaseInitializer.java b/src/main/java/com/anjiplus/template/gaea/business/config/DatabaseInitializer.java
new file mode 100644
index 0000000..129c42d
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/config/DatabaseInitializer.java
@@ -0,0 +1,56 @@
+package com.anjiplus.template.gaea.business.config;
+
+import com.zaxxer.hikari.HikariDataSource;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.autoconfigure.flyway.FlywayProperties;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+/**
+ * Created by raodeming on 2021/7/5.
+ */
+@Slf4j
+@Component
+@AllArgsConstructor
+@ConditionalOnProperty(value = {"spring.flyway.enabled"})
+public class DatabaseInitializer {
+
+ private final FlywayProperties flywayProperties;
+ private final DataSourceProperties dataSourceProperties;
+
+ @PostConstruct
+ public void init() throws SQLException {
+ log.info("DatabaseInitializer uses flyway init-sqls to initiate database");
+ String url = dataSourceProperties.getUrl();
+ // jdbc url最后一个 '/' 用于分割具体 schema?参数
+ int lastSplitIndex = url.lastIndexOf('?');
+ // 获取spring.datasource.url具体数据库schema前的jdbc url
+ String addressUrl = url.substring(0, lastSplitIndex);
+ String addresslast = url.substring(lastSplitIndex);
+ addressUrl = addressUrl.substring(0, addressUrl.lastIndexOf("/"));
+ // 直连数据库地址:jdbc:mysql://yourIp:port
+ HikariDataSource dataSource = new HikariDataSource();
+ dataSource.setJdbcUrl(addressUrl.concat(addresslast));
+ dataSource.setUsername(dataSourceProperties.getUsername());
+ dataSource.setPassword(dataSourceProperties.getPassword());
+ Connection connection = dataSource.getConnection();
+ Statement statement = connection.createStatement();
+ for (String sql : flywayProperties.getInitSqls()) {
+ // 通过flyway的init-sqls配置进行建库与数据库配置
+ // executeUpdate:执行给定的SQL语句,该语句可以是INSERT,UPDATE或DELETE语句或不返回任何内容的SQL语句,例如SQL DDL语句。
+ statement.executeUpdate(sql);
+ }
+ statement.close();
+ connection.close();
+ dataSource.close();
+ log.info("DatabaseInitializer initialize completed");
+ }
+
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/config/HikariPoolProperties.java b/src/main/java/com/anjiplus/template/gaea/business/config/HikariPoolProperties.java
new file mode 100644
index 0000000..91d3a5d
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/config/HikariPoolProperties.java
@@ -0,0 +1,34 @@
+package com.anjiplus.template.gaea.business.config;
+
+import com.zaxxer.hikari.HikariConfig;
+import com.zaxxer.hikari.pool.HikariPool;
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * Created by raodeming on 2021/8/6.
+ */
+@Component
+@ConfigurationProperties(prefix = "spring.datasource.hikari")
+@Data
+public class HikariPoolProperties extends HikariConfig {
+
+
+ public HikariPool dataSource(String url, String username, String password, String driverClassName) {
+ HikariConfig hikariConfig = new HikariConfig();
+ hikariConfig.setJdbcUrl(url);
+ hikariConfig.setUsername(username);
+ hikariConfig.setPassword(password);
+ hikariConfig.setDriverClassName(driverClassName);
+
+ hikariConfig.setConnectionTimeout(getConnectionTimeout());
+ hikariConfig.setValidationTimeout(getValidationTimeout());
+ hikariConfig.setIdleTimeout(getIdleTimeout());
+ hikariConfig.setMaxLifetime(getMaxLifetime());
+ hikariConfig.setMaximumPoolSize(getMaximumPoolSize());
+ hikariConfig.setMinimumIdle(getMinimumIdle());
+ HikariPool hikariPool = new HikariPool(hikariConfig);
+ return hikariPool;
+ }
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/constant/BusinessConstant.java b/src/main/java/com/anjiplus/template/gaea/business/constant/BusinessConstant.java
new file mode 100644
index 0000000..4e2aa8f
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/constant/BusinessConstant.java
@@ -0,0 +1,39 @@
+package com.anjiplus.template.gaea.business.constant;
+
+/**
+ * 常量
+ * @author lr
+ * @since 2021-03-26
+ */
+public interface BusinessConstant {
+
+ String LEFT_BIG_BOAST = "{";
+ String RIGTH_BIG_BOAST = "}";
+ String LEFT_MIDDLE_BOAST = "[";
+ String RIGHT_MIDDLE_BOAST = "]";
+ String SLASH = "/";
+
+ String USER_GUEST = "guest";
+ String USER_ADMIN = "admin";
+
+
+ /**
+ * 字典项重复
+ */
+ String DICT_ITEM_EXIST_GROUP = "dictItemExist";
+
+ /**
+ * 所有url的权限码缓存key
+ */
+ String GAEA_SECURITY_AUTHORITIES= "gaea:security:authorities:all";
+
+ /**
+ * 用户登录的token缓存key
+ */
+ String GAEA_SECURITY_LOGIN_TOKEN = "gaea:security:login:token:%s";
+
+ /**
+ * 用户登录的主信息缓存信息
+ */
+ String GAEA_SECURITY_LOGIN_USER = "gaea:security:login:user:%s";
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/enums/DeleteFlagEnum.java b/src/main/java/com/anjiplus/template/gaea/business/enums/DeleteFlagEnum.java
new file mode 100644
index 0000000..a883408
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/enums/DeleteFlagEnum.java
@@ -0,0 +1,47 @@
+package com.anjiplus.template.gaea.business.enums;
+public enum DeleteFlagEnum {
+ DELETED(1,"已删除"),
+ UNDELETED(0,"未删除"),
+ ;
+
+ private int codeValue;
+ private String codeDesc;
+
+ private DeleteFlagEnum(int codeValue, String codeDesc) {
+ this.codeValue = codeValue;
+ this.codeDesc = codeDesc;
+ }
+
+ public int getCodeValue(){ return this.codeValue;}
+
+ public String getCodeDesc(){ return this.codeDesc;}
+
+ //根据codeValue获取枚举
+ public static DeleteFlagEnum parseFromCodeValue(int codeValue){
+ for (DeleteFlagEnum e : DeleteFlagEnum.values()){
+ if(e.codeValue == codeValue){ return e;}
+ }
+ return null;
+ }
+
+ //根据codeValue获取描述
+ public static String getCodeDescByCodeValue(int codeValue){
+ DeleteFlagEnum enumItem = parseFromCodeValue(codeValue);
+ return enumItem == null ? "" : enumItem.getCodeDesc();
+ }
+
+ //验证codeValue是否有效
+ public static boolean validateCodeValue(int codeValue){ return parseFromCodeValue(codeValue)!=null;}
+
+ //列出所有值字符串
+ public static String getString(){
+ StringBuffer buffer = new StringBuffer();
+ for (DeleteFlagEnum e : DeleteFlagEnum.values()){
+ buffer.append(e.codeValue).append("--").append(e.getCodeDesc()).append(", ");
+ }
+ buffer.deleteCharAt(buffer.lastIndexOf(","));
+ return buffer.toString().trim();
+ }
+
+
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/enums/EnableFlagEnum.java b/src/main/java/com/anjiplus/template/gaea/business/enums/EnableFlagEnum.java
new file mode 100644
index 0000000..5d4b207
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/enums/EnableFlagEnum.java
@@ -0,0 +1,47 @@
+package com.anjiplus.template.gaea.business.enums;
+public enum EnableFlagEnum {
+ ENABLE(1,"启用"),
+ DISABLE(0,"禁用"),
+ ;
+
+ private int codeValue;
+ private String codeDesc;
+
+ private EnableFlagEnum(int codeValue, String codeDesc) {
+ this.codeValue = codeValue;
+ this.codeDesc = codeDesc;
+ }
+
+ public int getCodeValue(){ return this.codeValue;}
+
+ public String getCodeDesc(){ return this.codeDesc;}
+
+ //根据codeValue获取枚举
+ public static EnableFlagEnum parseFromCodeValue(int codeValue){
+ for (EnableFlagEnum e : EnableFlagEnum.values()){
+ if(e.codeValue == codeValue){ return e;}
+ }
+ return null;
+ }
+
+ //根据codeValue获取描述
+ public static String getCodeDescByCodeBalue(int codeValue){
+ EnableFlagEnum enumItem = parseFromCodeValue(codeValue);
+ return enumItem == null ? "" : enumItem.getCodeDesc();
+ }
+
+ //验证codeValue是否有效
+ public static boolean validateCodeValue(int codeValue){ return parseFromCodeValue(codeValue)!=null;}
+
+ //列出所有值字符串
+ public static String getString(){
+ StringBuffer buffer = new StringBuffer();
+ for (EnableFlagEnum e : EnableFlagEnum.values()){
+ buffer.append(e.codeValue).append("--").append(e.getCodeDesc()).append(", ");
+ }
+ buffer.deleteCharAt(buffer.lastIndexOf(","));
+ return buffer.toString().trim();
+ }
+
+
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/enums/ExcelCenterStyleEnum.java b/src/main/java/com/anjiplus/template/gaea/business/enums/ExcelCenterStyleEnum.java
new file mode 100644
index 0000000..b0efbc6
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/enums/ExcelCenterStyleEnum.java
@@ -0,0 +1,73 @@
+package com.anjiplus.template.gaea.business.enums;
+
+/**
+ * @author zhouhang
+ * @description EXCEL居中方式
+ * @date 2021/4/26
+ */
+public enum ExcelCenterStyleEnum {
+ /**
+ * 左对齐
+ */
+ LEFT((short) 1, 1, "左对齐"),
+ /**
+ * 右对齐
+ */
+ RIGHT((short) 3, 2, "右对齐"),
+ /**
+ * 居中
+ */
+ CENTER((short) 2, 0, "居中"),
+ ;
+
+ /**
+ * excel居中code
+ */
+ private final short excelCode;
+
+ /**
+ * 在线文档居中code
+ */
+ private final Integer onlineExcelCode;
+
+ /**
+ * 名称
+ */
+ private final String name;
+
+
+ public Integer getOnlineExcelCode() {
+ return onlineExcelCode;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public short getExcelCode() {
+ return excelCode;
+ }
+
+ ExcelCenterStyleEnum(short excelCode, Integer onlineExcelCode, String name) {
+ this.excelCode = excelCode;
+ this.onlineExcelCode = onlineExcelCode;
+ this.name = name;
+ }
+
+ /**
+ * @param code excel居中样式code
+ * @return Enum_ExcelCenterStyle
+ * @description 根据excel居中样式获取在线文档居中样式
+ * @author zhouhang
+ * @date 2021/4/26
+ */
+ public static ExcelCenterStyleEnum getExcelCenterStyleByExcelCenterCode(short code) {
+ for (ExcelCenterStyleEnum value : ExcelCenterStyleEnum.values()) {
+ if (code == value.getExcelCode()) {
+ return value;
+ }
+ }
+ return CENTER;
+ }
+
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/enums/ExportTypeEnum.java b/src/main/java/com/anjiplus/template/gaea/business/enums/ExportTypeEnum.java
new file mode 100644
index 0000000..6b01a17
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/enums/ExportTypeEnum.java
@@ -0,0 +1,30 @@
+package com.anjiplus.template.gaea.business.enums;
+
+/**
+ * Created by raodeming on 2021/9/3.
+ */
+public enum ExportTypeEnum {
+
+ /**gaea_excel*/
+ GAEA_TEMPLATE_EXCEL("gaea_template_excel", "gaea_template_excel"),
+ /**gaea_pdf*/
+ GAEA_TEMPLATE_PDF("gaea_template_pdf", "gaea_template_pdf"),
+ ;
+
+ private String codeValue;
+ private String codeDesc;
+
+ private ExportTypeEnum(String codeValue, String codeDesc) {
+ this.codeValue = codeValue;
+ this.codeDesc = codeDesc;
+ }
+
+ public String getCodeValue() {
+ return this.codeValue;
+ }
+
+ public String getCodeDesc() {
+ return this.codeDesc;
+ }
+
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/enums/ReportTypeEnum.java b/src/main/java/com/anjiplus/template/gaea/business/enums/ReportTypeEnum.java
new file mode 100644
index 0000000..f2d267a
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/enums/ReportTypeEnum.java
@@ -0,0 +1,33 @@
+package com.anjiplus.template.gaea.business.enums;
+
+/**
+ * Created by raodeming on 2022/5/8.
+ */
+public enum ReportTypeEnum {
+
+ /**report_screen*/
+ report_screen("report_screen", "大屏报表"),
+ /**report_excel*/
+ report_excel("report_excel", "excel报表"),
+ ;
+
+ private String codeValue;
+ private String codeDesc;
+
+ ReportTypeEnum() {
+ }
+
+ private ReportTypeEnum(String codeValue, String codeDesc) {
+ this.codeValue = codeValue;
+ this.codeDesc = codeDesc;
+ }
+
+ public String getCodeValue() {
+ return this.codeValue;
+ }
+
+ public String getCodeDesc() {
+ return this.codeDesc;
+ }
+
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/enums/SetTypeEnum.java b/src/main/java/com/anjiplus/template/gaea/business/enums/SetTypeEnum.java
new file mode 100644
index 0000000..a0242f3
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/enums/SetTypeEnum.java
@@ -0,0 +1,56 @@
+package com.anjiplus.template.gaea.business.enums;
+
+public enum SetTypeEnum {
+ SQL("sql", "sql"),
+ HTTP("http", "http"),
+ ;
+
+ private String codeValue;
+ private String codeDesc;
+
+ private SetTypeEnum(String codeValue, String codeDesc) {
+ this.codeValue = codeValue;
+ this.codeDesc = codeDesc;
+ }
+
+ public String getCodeValue() {
+ return this.codeValue;
+ }
+
+ public String getCodeDesc() {
+ return this.codeDesc;
+ }
+
+ //根据codeValue获取枚举
+ public static SetTypeEnum parseFromCodeValue(String codeValue) {
+ for (SetTypeEnum e : SetTypeEnum.values()) {
+ if (e.codeValue == codeValue) {
+ return e;
+ }
+ }
+ return null;
+ }
+
+ //根据codeValue获取描述
+ public static String getCodeDescByCodeBalue(String codeValue) {
+ SetTypeEnum enumItem = parseFromCodeValue(codeValue);
+ return enumItem == null ? "" : enumItem.getCodeDesc();
+ }
+
+ //验证codeValue是否有效
+ public static boolean validateCodeValue(String codeValue) {
+ return parseFromCodeValue(codeValue) != null;
+ }
+
+ //列出所有值字符串
+ public static String getString() {
+ StringBuffer buffer = new StringBuffer();
+ for (SetTypeEnum e : SetTypeEnum.values()) {
+ buffer.append(e.codeValue).append("--").append(e.getCodeDesc()).append(", ");
+ }
+ buffer.deleteCharAt(buffer.lastIndexOf(","));
+ return buffer.toString().trim();
+ }
+
+
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/filter/CorsFilter.java b/src/main/java/com/anjiplus/template/gaea/business/filter/CorsFilter.java
new file mode 100644
index 0000000..243a7fd
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/filter/CorsFilter.java
@@ -0,0 +1,43 @@
+package com.anjiplus.template.gaea.business.filter;
+
+import org.springframework.core.Ordered;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * Created by raodeming on 2021/6/24.
+ */
+@Component
+@Order(Ordered.HIGHEST_PRECEDENCE)
+public class CorsFilter implements Filter {
+
+ @Override
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
+ throws IOException, ServletException {
+ HttpServletRequest req = (HttpServletRequest) request;
+ HttpServletResponse res = (HttpServletResponse) response;
+ // 设置允许Cookie
+ res.addHeader("Access-Control-Allow-Credentials", "true");
+ // 允许http://www.xxx.com域(自行设置,这里只做示例)发起跨域请求
+ res.addHeader("Access-Control-Allow-Origin", req.getHeader("Origin"));
+ // 设置允许跨域请求的方法
+ res.addHeader("Access-Control-Allow-Methods", "*");
+ // 允许跨域请求包含content-type
+ res.addHeader("Access-Control-Allow-Headers", "*");
+ res.addHeader("Access-Control-Expose-Headers", "*");
+ chain.doFilter(req, res);
+ }
+
+ @Override
+ public void destroy() {
+ }
+
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {
+ }
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/filter/TokenFilter.java b/src/main/java/com/anjiplus/template/gaea/business/filter/TokenFilter.java
new file mode 100644
index 0000000..b9214f6
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/filter/TokenFilter.java
@@ -0,0 +1,245 @@
+package com.anjiplus.template.gaea.business.filter;
+
+import com.alibaba.fastjson.JSONObject;
+import com.anji.plus.gaea.bean.ResponseBean;
+import com.anji.plus.gaea.cache.CacheHelper;
+import com.anji.plus.gaea.constant.GaeaConstant;
+import com.anji.plus.gaea.utils.JwtBean;
+import com.anjiplus.template.gaea.business.constant.BusinessConstant;
+import com.anjiplus.template.gaea.business.modules.accessuser.controller.dto.GaeaUserDto;
+import com.anjiplus.template.gaea.business.util.JwtUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.http.entity.ContentType;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.util.AntPathMatcher;
+
+import javax.servlet.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.regex.Pattern;
+
+import static com.anji.plus.gaea.constant.GaeaConstant.URL_REPLACEMENT;
+
+/**
+ * 简单的鉴权
+ * @author raodeming
+ * @date 2021/6/24.
+ */
+@Component
+@Order(Integer.MIN_VALUE + 99)
+public class TokenFilter implements Filter {
+ private static final Pattern PATTERN = Pattern.compile(".*().*");
+
+ @Value("${server.servlet.context-path:/}")
+ private String SLASH = "/";
+ private AntPathMatcher antPathMatcher = new AntPathMatcher();
+
+ @Autowired
+ private CacheHelper cacheHelper;
+ @Autowired
+ private JwtBean jwtBean;
+
+ /**
+ * 跳过token验证和权限验证的url清单
+ */
+ @Value("#{'${customer.skip-authenticate-urls:}'.split(',')}")
+ private List skipAuthenticateUrls;
+ private Pattern skipAuthenticatePattern;
+
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {
+ // 生成匹配正则,跳过token验证和权限验证的url
+ skipAuthenticatePattern = fitByList(skipAuthenticateUrls);
+ Filter.super.init(filterConfig);
+ }
+
+ @Override
+ public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
+ HttpServletRequest request = (HttpServletRequest) servletRequest;
+ HttpServletResponse response = (HttpServletResponse) servletResponse;
+ String uri = request.getRequestURI();
+
+ // TODO 暂时先不校验 直接放行
+ /*if (true) {
+ filterChain.doFilter(request, response);
+ return;
+ }*/
+
+ //OPTIONS直接放行
+ if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
+ filterChain.doFilter(request, response);
+ return;
+ }
+
+ // swagger相关的直接放行
+ if (uri.contains("swagger-ui") || uri.contains("swagger-resources")) {
+ filterChain.doFilter(request, response);
+ return;
+ }
+
+
+ if (SLASH.equals(uri) || SLASH.concat(BusinessConstant.SLASH).equals(uri)) {
+ if (BusinessConstant.SLASH.equals(uri)) {
+ response.sendRedirect("/index.html");
+ return;
+ }
+ response.sendRedirect(SLASH + "/index.html");
+ return;
+ }
+
+ // 不需要token验证和权限验证的url,直接放行
+ boolean skipAuthenticate = skipAuthenticatePattern.matcher(uri).matches();
+ if (skipAuthenticate) {
+ filterChain.doFilter(request, response);
+ return;
+ }
+ //获取token
+ String token = request.getHeader("Authorization");
+ //针对大屏分享,优先处理
+ String shareToken = request.getHeader("Share-Token");
+ if (StringUtils.isNotBlank(shareToken) && StringUtils.isBlank(token)) {
+ //需要处理
+ // /reportDashboard/getData
+ // /reportDashboard/{reportCode}
+ // /reportExcel/preview
+ List reportCodeList = JwtUtil.getReportCodeList(shareToken);
+ if (!uri.endsWith("/reportDashboard/getData") && !uri.endsWith("/reportExcel/preview") && reportCodeList.stream().noneMatch(uri::contains)) {
+ ResponseBean responseBean = ResponseBean.builder().code("50014")
+ .message("分享链接已过期").build();
+ response.getWriter().print(JSONObject.toJSONString(responseBean));
+ return;
+ }
+ filterChain.doFilter(request, response);
+ return;
+ }
+
+
+
+ if (StringUtils.isBlank(token)) {
+ error(response);
+ return;
+ }
+
+ // 判断token是否过期
+ String loginName = jwtBean.getUsername(token);
+ String tokenKey = String.format(BusinessConstant.GAEA_SECURITY_LOGIN_TOKEN, loginName);
+ String userKey = String.format(BusinessConstant.GAEA_SECURITY_LOGIN_USER, loginName);
+ if (!cacheHelper.exist(tokenKey)) {
+ error(response);
+ return;
+ }
+
+ String gaeaUserJsonStr = cacheHelper.stringGet(userKey);
+
+ // 判断用户是否有该url的权限
+ if (!BusinessConstant.USER_ADMIN.equals(loginName)) {
+ AtomicBoolean authorizeFlag = authorize(request, gaeaUserJsonStr);
+ if (!authorizeFlag.get()) {
+ authError(response);//无权限
+ return;
+ }
+ }
+
+ // 延长有效期
+ cacheHelper.stringSetExpire(tokenKey, token, 3600);
+ cacheHelper.stringSetExpire(userKey, gaeaUserJsonStr, 3600);
+
+
+ //执行
+ filterChain.doFilter(request, response);
+ }
+
+ @Override
+ public void destroy() {
+ Filter.super.destroy();
+ }
+
+ /**
+ * 根据名单,生成正则
+ *
+ * @param skipUrlList
+ * @return
+ */
+ private Pattern fitByList(List skipUrlList) {
+ if (skipUrlList == null || skipUrlList.size() == 0) {
+ return PATTERN;
+ }
+ StringBuffer patternString = new StringBuffer();
+ patternString.append(".*(");
+
+ skipUrlList.stream().forEach(url -> {
+ patternString.append(url.trim());
+ patternString.append("|");
+ });
+ if (skipUrlList.size() > 0) {
+ patternString.deleteCharAt(patternString.length() - 1);
+ }
+ patternString.append(").*");
+
+ return Pattern.compile(patternString.toString());
+ }
+
+ /** 判断用户是否有该接口的权限
+ * @return
+ */
+ private AtomicBoolean authorize(HttpServletRequest request, String gaeaUserJsonStr){
+
+ //判断接口权限
+ //请求路径
+ String requestUrl = request.getRequestURI();
+ if (!BusinessConstant.SLASH.equals(SLASH)) {
+ requestUrl = requestUrl.substring(SLASH.length());
+ }
+ String methodValue = request.getMethod();
+ //请求方法+#+请求路径
+ String path = methodValue + GaeaConstant.URL_SPLIT + requestUrl;
+
+ GaeaUserDto gaeaUserDto = JSONObject.parseObject(gaeaUserJsonStr, GaeaUserDto.class);
+ List userAuthorities = gaeaUserDto.getAuthorities();
+ Map authoritiesAllMap = cacheHelper.hashGet(BusinessConstant.GAEA_SECURITY_AUTHORITIES);
+
+ AtomicBoolean authFlag = new AtomicBoolean(false);
+
+ // 接口GET#/gaeaDictItem/pageList
+ if(authoritiesAllMap.containsKey(path)){
+ String permissionCode = authoritiesAllMap.get(path);
+ boolean flag = userAuthorities.contains(permissionCode);
+ authFlag.set(flag);
+ return authFlag;
+ }
+
+ // 接口GET#/accessUser/roleTree/**
+ Optional optionalMatchKey = authoritiesAllMap.keySet().stream()
+ .filter(key -> StringUtils.isNotBlank(key) && key.contains(URL_REPLACEMENT))
+ .filter(key -> antPathMatcher.match(key, path)).findFirst();
+ if(optionalMatchKey.isPresent() == false){
+ authFlag.set(true);
+ return authFlag;
+ }
+ String authoritieKey = optionalMatchKey.get();
+ String needPermission = authoritiesAllMap.get(authoritieKey);
+ boolean flag = userAuthorities.contains(needPermission);
+ authFlag.set(flag);
+ return authFlag;
+ }
+
+ private void error(HttpServletResponse response) throws IOException {
+ ResponseBean responseBean = ResponseBean.builder().code("User.credentials.expired").message("The Token has expired").build();
+ response.setContentType(ContentType.APPLICATION_JSON.getMimeType());
+ response.getWriter().print(JSONObject.toJSONString(responseBean));
+ }
+
+ private void authError(HttpServletResponse response) throws IOException {
+ ResponseBean responseBean = ResponseBean.builder().code("User.no.authority").message("no auth").build();
+ response.setContentType(ContentType.APPLICATION_JSON.getMimeType());
+ response.getWriter().print(JSONObject.toJSONString(responseBean));
+ }
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/filter/UrlDecodeFilter.java b/src/main/java/com/anjiplus/template/gaea/business/filter/UrlDecodeFilter.java
new file mode 100644
index 0000000..0d79a3a
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/filter/UrlDecodeFilter.java
@@ -0,0 +1,77 @@
+package com.anjiplus.template.gaea.business.filter;
+
+import com.anji.plus.gaea.constant.GaeaConstant;
+import org.apache.catalina.util.ParameterMap;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.ibatis.ognl.IteratorEnumeration;
+import org.springframework.core.Ordered;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import java.io.IOException;
+import java.net.URLDecoder;
+import java.util.Enumeration;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author: Raod
+ * @since: 2022-01-26
+ */
+@Component
+@Order(Ordered.HIGHEST_PRECEDENCE + 1)
+public class UrlDecodeFilter implements Filter {
+
+ @Override
+ public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
+ HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
+ ParameterMap parameterMap = (ParameterMap) httpServletRequest.getParameterMap();
+ ParamHttpServletRequestWrapper wrapper = new ParamHttpServletRequestWrapper(httpServletRequest, parameterMap);
+
+ Enumeration parameterNames = wrapper.getParameterNames();
+ while (parameterNames.hasMoreElements()) {
+ String paramName = parameterNames.nextElement();
+ String parameter = httpServletRequest.getParameter(paramName);
+ if (StringUtils.isNotBlank(parameter)) {
+ String decode = URLDecoder.decode(parameter, GaeaConstant.CHARSET_UTF8);
+ parameterMap.setLocked(false);
+ parameterMap.put(paramName, new String[]{decode});
+ }
+ }
+ filterChain.doFilter(wrapper, servletResponse);
+ }
+
+ /**
+ * 参数
+ */
+ class ParamHttpServletRequestWrapper extends HttpServletRequestWrapper {
+
+ private ParameterMap parameterMap;
+
+ public ParamHttpServletRequestWrapper(HttpServletRequest request, ParameterMap parameterMap) {
+ super(request);
+ this.parameterMap = parameterMap;
+ }
+
+ @Override
+ public Map getParameterMap() {
+ return parameterMap;
+ }
+
+ @Override
+ public Enumeration getParameterNames() {
+
+ Set keySet = parameterMap.keySet();
+ IteratorEnumeration iteratorEnumeration = new IteratorEnumeration(keySet.iterator());
+ return iteratorEnumeration;
+ }
+
+ @Override
+ public String[] getParameterValues(String name) {
+ return parameterMap.get(name);
+ }
+ }
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/accessauthority/controller/AccessAuthorityController.java b/src/main/java/com/anjiplus/template/gaea/business/modules/accessauthority/controller/AccessAuthorityController.java
new file mode 100644
index 0000000..6da7ba0
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/accessauthority/controller/AccessAuthorityController.java
@@ -0,0 +1,67 @@
+
+package com.anjiplus.template.gaea.business.modules.accessauthority.controller;
+
+import com.anji.plus.gaea.annotation.Permission;
+import com.anji.plus.gaea.annotation.AccessKey;
+import com.anji.plus.gaea.bean.KeyValue;
+import com.anji.plus.gaea.bean.ResponseBean;
+import com.anji.plus.gaea.bean.TreeNode;
+import com.anji.plus.gaea.curd.controller.GaeaBaseController;
+import com.anji.plus.gaea.curd.service.GaeaBaseService;
+import com.anji.plus.gaea.holder.UserContentHolder;
+import com.anji.plus.gaea.utils.GaeaBeanUtils;
+import com.anji.plus.gaea.utils.GaeaUtils;
+import com.anjiplus.template.gaea.business.modules.accessauthority.dao.entity.AccessAuthority;
+import com.anjiplus.template.gaea.business.modules.accessauthority.service.AccessAuthorityService;
+import com.anjiplus.template.gaea.business.modules.accessauthority.controller.dto.AccessAuthorityDto;
+import com.anjiplus.template.gaea.business.modules.accessauthority.controller.param.AccessAuthorityParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.i18n.LocaleContextHolder;
+import org.springframework.web.bind.annotation.*;
+import io.swagger.annotations.Api;
+
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+* @desc 权限管理 controller
+* @author 木子李·De
+* @date 2019-02-17 08:50:10.009
+**/
+@RestController
+@Api(tags = "权限管理管理")
+@RequestMapping("/accessAuthority")
+@Permission(code = "authorityManage", name = "权限管理")
+public class AccessAuthorityController extends GaeaBaseController {
+
+ @Autowired
+ private AccessAuthorityService accessAuthorityService;
+
+ @Override
+ public GaeaBaseService getService() {
+ return accessAuthorityService;
+ }
+
+ @Override
+ public AccessAuthority getEntity() {
+ return new AccessAuthority();
+ }
+
+ @Override
+ public AccessAuthorityDto getDTO() {
+ return new AccessAuthorityDto();
+ }
+
+ /**
+ * 获取一二级菜单
+ * @return
+ */
+ @Permission( code = "query", name = "查询")
+ @GetMapping("/menuTree")
+ public ResponseBean menuTree(){
+ String username = UserContentHolder.getContext().getUsername();
+ List parentTreeList = accessAuthorityService.getAuthorityTree(username, false);
+ return responseSuccessWithData(parentTreeList);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/accessauthority/controller/dto/AccessAuthorityDto.java b/src/main/java/com/anjiplus/template/gaea/business/modules/accessauthority/controller/dto/AccessAuthorityDto.java
new file mode 100644
index 0000000..77cc98f
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/accessauthority/controller/dto/AccessAuthorityDto.java
@@ -0,0 +1,58 @@
+
+package com.anjiplus.template.gaea.business.modules.accessauthority.controller.dto;
+
+import java.io.Serializable;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+
+import com.anji.plus.gaea.annotation.Query;
+import com.anji.plus.gaea.constant.QueryEnum;
+import com.anji.plus.gaea.curd.dto.GaeaBaseDTO;
+import io.swagger.annotations.ApiModelProperty;
+import com.anji.plus.gaea.annotation.Formatter;
+import lombok.Data;
+
+/**
+*
+* @description 权限管理 dto
+* @author 木子李·De
+* @date 2019-02-17 08:50:10.009
+**/
+@Data
+public class AccessAuthorityDto extends GaeaBaseDTO implements Serializable {
+ /** 父菜单代码 */
+ @ApiModelProperty(value = "父菜单代码")
+ private String parentTarget;
+
+ /** 目标菜单 */
+ @ApiModelProperty(value = "菜单代码")
+ @NotEmpty(message = "6002")
+ private String target;
+
+ /** 目标菜单名称 */
+ @ApiModelProperty(value = "菜单名称")
+ @NotEmpty(message = "6002")
+ private String targetName;
+
+ /** 目标按钮 */
+ @ApiModelProperty(value = "按钮代码")
+ @NotEmpty(message = "6002")
+ private String action;
+
+ /** 目标按钮名称 */
+ @ApiModelProperty(value = "按钮名称")
+ @NotEmpty(message = "6002")
+ private String actionName;
+
+ /** 0--未删除 1--已删除 DIC_NAME=DEL_FLAG */
+ @ApiModelProperty(value = " 0--未删除 1--已删除 DIC_NAME=DEL_FLAG")
+ private Integer deleteFlag;
+
+ /** 0--已禁用 1--已启用 DIC_NAME=ENABLE_FLAG */
+ @ApiModelProperty(value = "0--已禁用 1--已启用 DIC_NAME=ENABLE_FLAG")
+ @NotNull(message = "6002")
+ private Integer enableFlag;
+
+ @ApiModelProperty(value = "sort")
+ private Integer sort;
+}
\ No newline at end of file
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/accessauthority/controller/param/AccessAuthorityParam.java b/src/main/java/com/anjiplus/template/gaea/business/modules/accessauthority/controller/param/AccessAuthorityParam.java
new file mode 100644
index 0000000..344a14c
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/accessauthority/controller/param/AccessAuthorityParam.java
@@ -0,0 +1,44 @@
+/**/
+package com.anjiplus.template.gaea.business.modules.accessauthority.controller.param;
+
+import lombok.Data;
+import java.io.Serializable;
+import com.anji.plus.gaea.annotation.Query;
+import com.anji.plus.gaea.constant.QueryEnum;
+import com.anji.plus.gaea.curd.params.PageParam;
+import java.util.List;
+
+import java.util.Date;
+
+/**
+* @desc AccessAuthority 权限管理查询输入类
+* @author 木子李·De
+* @date 2019-02-17 08:50:10.009
+**/
+@Data
+public class AccessAuthorityParam extends PageParam implements Serializable{
+
+ /** 父菜单代码 */
+ @Query(value = QueryEnum.LIKE)
+ private String parentTarget;
+
+ /** 菜单代码 */
+ @Query(value = QueryEnum.LIKE)
+ private String target;
+
+ /** 菜单名称 */
+ @Query(value = QueryEnum.LIKE)
+ private String targetName;
+
+ /** 按钮代码 */
+ @Query(value = QueryEnum.LIKE)
+ private String action;
+
+ /** 按钮名称 */
+ @Query(value = QueryEnum.LIKE)
+ private String actionName;
+
+ // 0--已禁用 1--已启用 DIC_NAME=ENABLE_FLAG
+ @Query
+ private Integer enableFlag;
+}
\ No newline at end of file
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/accessauthority/dao/AccessAuthorityMapper.java b/src/main/java/com/anjiplus/template/gaea/business/modules/accessauthority/dao/AccessAuthorityMapper.java
new file mode 100644
index 0000000..9395dd2
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/accessauthority/dao/AccessAuthorityMapper.java
@@ -0,0 +1,17 @@
+package com.anjiplus.template.gaea.business.modules.accessauthority.dao;
+
+import org.apache.ibatis.annotations.Mapper;
+import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
+import com.anjiplus.template.gaea.business.modules.accessauthority.dao.entity.AccessAuthority;
+
+import java.util.List;
+
+/**
+* AccessAuthority Mapper
+* @author 木子李·De
+* @date 2019-02-17 08:50:10.009
+**/
+@Mapper
+public interface AccessAuthorityMapper extends GaeaBaseMapper {
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/accessauthority/dao/entity/AccessAuthority.java b/src/main/java/com/anjiplus/template/gaea/business/modules/accessauthority/dao/entity/AccessAuthority.java
new file mode 100644
index 0000000..1d04d89
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/accessauthority/dao/entity/AccessAuthority.java
@@ -0,0 +1,43 @@
+
+package com.anjiplus.template.gaea.business.modules.accessauthority.dao.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import com.anji.plus.gaea.curd.entity.GaeaBaseEntity;
+import com.baomidou.mybatisplus.annotation.TableName;
+import javax.validation.constraints.*;
+import java.util.Date;
+/**
+* @description 权限管理 entity
+* @author 木子李·De
+* @date 2019-02-17 08:50:10.009
+**/
+@TableName(keepGlobalPrefix=true, value="access_authority")
+@Data
+public class AccessAuthority extends GaeaBaseEntity {
+ /** 父菜单代码 */
+ private String parentTarget;
+
+ /** 菜单代码 */
+ private String target;
+
+ /** 菜单名称 */
+ private String targetName;
+
+ /** 按钮代码 */
+ private String action;
+
+ /** 按钮名称 */
+ private String actionName;
+
+ /** 0--未删除 1--已删除 DIC_NAME=DEL_FLAG */
+ private Integer deleteFlag;
+
+ /** 0--已禁用 1--已启用 DIC_NAME=ENABLE_FLAG */
+ private Integer enableFlag;
+
+ private Integer sort;
+
+
+
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/accessauthority/service/AccessAuthorityService.java b/src/main/java/com/anjiplus/template/gaea/business/modules/accessauthority/service/AccessAuthorityService.java
new file mode 100644
index 0000000..0e3e023
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/accessauthority/service/AccessAuthorityService.java
@@ -0,0 +1,29 @@
+
+package com.anjiplus.template.gaea.business.modules.accessauthority.service;
+
+import com.anji.plus.gaea.bean.TreeNode;
+import com.anjiplus.template.gaea.business.modules.accessauthority.dao.entity.AccessAuthority;
+import com.anjiplus.template.gaea.business.modules.accessauthority.controller.param.AccessAuthorityParam;
+import com.anji.plus.gaea.curd.service.GaeaBaseService;
+
+import java.util.List;
+
+/**
+* @desc AccessAuthority 权限管理服务接口
+* @author 木子李·De
+* @date 2019-02-17 08:50:10.009
+**/
+public interface AccessAuthorityService extends GaeaBaseService {
+
+ /**
+ * @param loginName 当前登录的用户名
+ * @param withActionNode 带第三层的按钮节点
+ * @return
+ */
+ List getAuthorityTree(String loginName, boolean withActionNode);
+
+ /**
+ * 扫描所有mvc url的需要权限码,建立拦截体系
+ */
+ void scanGaeaSecurityAuthorities();
+}
\ No newline at end of file
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/accessauthority/service/impl/AccessAuthorityServiceImpl.java b/src/main/java/com/anjiplus/template/gaea/business/modules/accessauthority/service/impl/AccessAuthorityServiceImpl.java
new file mode 100644
index 0000000..b261862
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/accessauthority/service/impl/AccessAuthorityServiceImpl.java
@@ -0,0 +1,140 @@
+
+package com.anjiplus.template.gaea.business.modules.accessauthority.service.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.anji.plus.gaea.bean.TreeNode;
+import com.anji.plus.gaea.cache.CacheHelper;
+import com.anji.plus.gaea.constant.Enabled;
+import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
+import com.anji.plus.gaea.init.InitRequestUrlMappings;
+import com.anjiplus.template.gaea.business.constant.BusinessConstant;
+import com.anjiplus.template.gaea.business.modules.accessauthority.dao.entity.AccessAuthority;
+import com.anjiplus.template.gaea.business.modules.accessauthority.service.AccessAuthorityService;
+import com.anjiplus.template.gaea.business.modules.accessauthority.dao.AccessAuthorityMapper;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+* @desc AccessAuthority 权限管理服务实现
+* @author 木子李·De
+* @date 2019-02-17 08:50:10.009
+**/
+@Service
+public class AccessAuthorityServiceImpl implements AccessAuthorityService {
+
+ @Autowired
+ private InitRequestUrlMappings initRequestUrlMappings;
+
+ @Autowired
+ private CacheHelper cacheHelper;
+
+ @Autowired
+ private AccessAuthorityMapper accessAuthorityMapper;
+
+ @Override
+ public GaeaBaseMapper getMapper() {
+ return accessAuthorityMapper;
+ }
+
+ @Override
+ public List getAuthorityTree(String loginName, boolean withActionNode) {
+ // 查询出所有的菜单记录
+ LambdaQueryWrapper wrapper = Wrappers.lambdaQuery();
+ wrapper.select(AccessAuthority::getParentTarget, AccessAuthority::getTarget, AccessAuthority::getTargetName, AccessAuthority::getAction, AccessAuthority::getActionName)
+ .eq(AccessAuthority::getEnableFlag, 1)
+ .eq(AccessAuthority::getDeleteFlag, 0)
+ .orderByAsc(AccessAuthority::getSort);
+ // 按operator去筛选 后面再加where
+ List accessAuthorityList = getMapper().selectList(wrapper);
+
+ // 筛选出一级菜单
+ List parentNodes = accessAuthorityList.stream().filter(accessAuthority -> StringUtils.isBlank(accessAuthority.getParentTarget()))
+ .map(item -> {
+ TreeNode treeNode = new TreeNode();
+ treeNode.setId(item.getTarget());
+ treeNode.setLabel(item.getTargetName());
+ return treeNode;
+ }).collect(Collectors.toList());
+
+ // 菜单-按钮的map
+ Map> targetActionsMap = accessAuthorityList.stream()
+ .filter(accessAuthority -> StringUtils.isNoneBlank(accessAuthority.getParentTarget()))
+ .collect(Collectors.groupingBy(AccessAuthority::getTarget));
+
+ // 设置每个一级菜单的二菜单
+ parentNodes.stream().forEach(parentNode -> {
+ List alreadyTargets = new ArrayList<>();
+
+ accessAuthorityList.stream().forEach(authority -> {
+ if(!StringUtils.equals(parentNode.getId(), authority.getParentTarget()) || alreadyTargets.contains(authority.getTarget())){
+ return;
+ }
+ // 找到一级菜单对应的二级菜单
+
+ // 初始化二级菜单节点
+ TreeNode levelTwoMenuNode = new TreeNode();
+ levelTwoMenuNode.setId(authority.getTarget());
+ levelTwoMenuNode.setLabel(authority.getTargetName());
+ levelTwoMenuNode.setChildren(new ArrayList());
+
+ // 初始化二级菜单的按钮
+ if(withActionNode){
+ List actionList = targetActionsMap.get(authority.getTarget());
+ if(actionList != null && !actionList.isEmpty()){
+ actionList.stream().forEach(action ->{
+ TreeNode buttonNode = new TreeNode();
+ buttonNode.setId(String.format("%s_%s", action.getTarget(), action.getAction()));
+ buttonNode.setLabel(action.getActionName());
+ levelTwoMenuNode.getChildren().add(buttonNode);
+ });
+ }
+ }
+
+ // 将上面找到的二级菜单加入到一菜单的子树中去
+ List children = parentNode.getChildren();
+ if(children == null){
+ children = new ArrayList();
+ }
+ children.add(levelTwoMenuNode);
+ parentNode.setChildren(children);
+
+ // 已经找过的二级菜单,后面不在重复添加
+ alreadyTargets.add(authority.getTarget());
+ });
+ });
+
+ return parentNodes;
+ }
+
+ @Override
+ public void scanGaeaSecurityAuthorities() {
+ /* 获取当前应用中所有的请求信息
+ {
+ "applicationName": "aj-report",
+ "authCode": "authorityManage:query",
+ "authName": "权限管理查询",
+ "beanName": "accessAuthorityController",
+ "menuCode": "authorityManage",
+ "path": "GET#/accessAuthority/menuTree"
+ }*/
+ List requestInfos = initRequestUrlMappings.getRequestInfos(Enabled.YES.getValue());
+
+ // key="GET#/accessAuthority/menuTree" value="authorityManage:query"
+ Map securityAuthorityMap = new HashMap();
+ requestInfos.stream().forEach(requestInfo -> {
+ securityAuthorityMap.put(requestInfo.getPath(), requestInfo.getAuthCode());
+ });
+
+ // 将key存入到缓存中
+ cacheHelper.hashSet(BusinessConstant.GAEA_SECURITY_AUTHORITIES, securityAuthorityMap);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/accessrole/controller/AccessRoleController.java b/src/main/java/com/anjiplus/template/gaea/business/modules/accessrole/controller/AccessRoleController.java
new file mode 100644
index 0000000..5614a30
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/accessrole/controller/AccessRoleController.java
@@ -0,0 +1,75 @@
+
+package com.anjiplus.template.gaea.business.modules.accessrole.controller;
+
+import com.anji.plus.gaea.annotation.Permission;
+import com.anji.plus.gaea.annotation.AccessKey;
+import com.anji.plus.gaea.bean.ResponseBean;
+import com.anji.plus.gaea.bean.TreeNode;
+import com.anji.plus.gaea.curd.controller.GaeaBaseController;
+import com.anji.plus.gaea.curd.service.GaeaBaseService;
+import com.anji.plus.gaea.holder.UserContentHolder;
+import com.anji.plus.gaea.utils.GaeaBeanUtils;
+import com.anji.plus.gaea.utils.GaeaUtils;
+import com.anjiplus.template.gaea.business.modules.accessrole.dao.entity.AccessRole;
+import com.anjiplus.template.gaea.business.modules.accessrole.service.AccessRoleService;
+import com.anjiplus.template.gaea.business.modules.accessrole.controller.dto.AccessRoleDto;
+import com.anjiplus.template.gaea.business.modules.accessrole.controller.param.AccessRoleParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import io.swagger.annotations.Api;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+* @desc 角色管理 controller
+* @author 木子李·De
+* @date 2019-02-17 08:50:14.136
+**/
+@RestController
+@Api(tags = "角色管理管理")
+@RequestMapping("/accessRole")
+@Permission(code = "roleManage", name = "角色管理")
+public class AccessRoleController extends GaeaBaseController {
+
+ @Autowired
+ private AccessRoleService accessRoleService;
+
+ @Override
+ public GaeaBaseService getService() {
+ return accessRoleService;
+ }
+
+ @Override
+ public AccessRole getEntity() {
+ return new AccessRole();
+ }
+
+ @Override
+ public AccessRoleDto getDTO() {
+ return new AccessRoleDto();
+ }
+
+ /**
+ * 获取角色的 菜单按钮树 一级菜单 二级菜单 三级按钮
+ * @return
+ */
+ @Permission( code = "grantAuthority", name = "分配权限")
+ @GetMapping("/authorityTree/{roleCode}")
+ public ResponseBean authorityTree(@PathVariable("roleCode")String roleCode){
+ String operator = UserContentHolder.getContext().getUsername();
+ Map map = accessRoleService.getAuthorityTree(roleCode, operator);
+ return responseSuccessWithData(map);
+ }
+
+ /**
+ * 保存角色的权限
+ * @return
+ */
+ @Permission( code = "grantAuthority", name = "分配权限")
+ @PostMapping("/saveAuthorityTree")
+ public ResponseBean saveAuthorityTree(@RequestBody AccessRoleDto dto){
+ Boolean data = accessRoleService.saveAuthorityTree(dto);
+ return responseSuccessWithData(data);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/accessrole/controller/dto/AccessRoleDto.java b/src/main/java/com/anjiplus/template/gaea/business/modules/accessrole/controller/dto/AccessRoleDto.java
new file mode 100644
index 0000000..c7e1062
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/accessrole/controller/dto/AccessRoleDto.java
@@ -0,0 +1,46 @@
+
+package com.anjiplus.template.gaea.business.modules.accessrole.controller.dto;
+
+import java.io.Serializable;
+import java.util.List;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+
+import com.anji.plus.gaea.annotation.Query;
+import com.anji.plus.gaea.constant.QueryEnum;
+import com.anji.plus.gaea.curd.dto.GaeaBaseDTO;
+import io.swagger.annotations.ApiModelProperty;
+import com.anji.plus.gaea.annotation.Formatter;
+import lombok.Data;
+
+/**
+*
+* @description 角色管理 dto
+* @author 木子李·De
+* @date 2019-02-17 08:50:14.136
+**/
+@Data
+public class AccessRoleDto extends GaeaBaseDTO implements Serializable {
+
+ /** 角色编码 */
+ @ApiModelProperty(value = "角色编码")
+ @NotEmpty(message = "6002")
+ private String roleCode;
+
+ /** 角色名称 */
+ @ApiModelProperty(value = "角色名称")
+ @NotEmpty(message = "6002")
+ private String roleName;
+
+ /** 0--未删除 1--已删除 DIC_NAME=DEL_FLAG */
+ @ApiModelProperty(value = " 0--未删除 1--已删除 DIC_NAME=DEL_FLAG")
+ private Integer deleteFlag;
+
+ /** 0--已禁用 1--已启用 DIC_NAME=ENABLE_FLAG */
+ @ApiModelProperty(value = "0--已禁用 1--已启用 DIC_NAME=ENABLE_FLAG")
+ @NotNull(message = "6002")
+ private Integer enableFlag;
+
+ /** 角色保存的权限 */
+ private List authorityList;
+}
\ No newline at end of file
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/accessrole/controller/param/AccessRoleParam.java b/src/main/java/com/anjiplus/template/gaea/business/modules/accessrole/controller/param/AccessRoleParam.java
new file mode 100644
index 0000000..5e5d59f
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/accessrole/controller/param/AccessRoleParam.java
@@ -0,0 +1,33 @@
+/**/
+package com.anjiplus.template.gaea.business.modules.accessrole.controller.param;
+
+import lombok.Data;
+import java.io.Serializable;
+import com.anji.plus.gaea.annotation.Query;
+import com.anji.plus.gaea.constant.QueryEnum;
+import com.anji.plus.gaea.curd.params.PageParam;
+import java.util.List;
+
+import java.util.Date;
+
+/**
+* @desc AccessRole 角色管理查询输入类
+* @author 木子李·De
+* @date 2019-02-17 08:50:14.136
+**/
+@Data
+public class AccessRoleParam extends PageParam implements Serializable{
+
+ /** 角色编码 */
+ @Query(value = QueryEnum.LIKE)
+ private String roleCode;
+
+ // 角色名称
+ @Query(value = QueryEnum.LIKE)
+ private String roleName;
+
+ // 0--已禁用 1--已启用 DIC_NAME=ENABLE_FLAG
+ @Query
+ private Integer enableFlag;
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/accessrole/dao/AccessRoleAuthorityMapper.java b/src/main/java/com/anjiplus/template/gaea/business/modules/accessrole/dao/AccessRoleAuthorityMapper.java
new file mode 100644
index 0000000..7fe9995
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/accessrole/dao/AccessRoleAuthorityMapper.java
@@ -0,0 +1,15 @@
+package com.anjiplus.template.gaea.business.modules.accessrole.dao;
+
+import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
+import com.anjiplus.template.gaea.business.modules.accessrole.dao.entity.AccessRoleAuthority;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* AccessRoleAuthority Mapper
+* @author 木子李·De
+* @date 2019-02-17 08:50:14.136
+**/
+@Mapper
+public interface AccessRoleAuthorityMapper extends GaeaBaseMapper {
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/accessrole/dao/AccessRoleMapper.java b/src/main/java/com/anjiplus/template/gaea/business/modules/accessrole/dao/AccessRoleMapper.java
new file mode 100644
index 0000000..9b78e95
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/accessrole/dao/AccessRoleMapper.java
@@ -0,0 +1,22 @@
+package com.anjiplus.template.gaea.business.modules.accessrole.dao;
+
+import org.apache.ibatis.annotations.Mapper;
+import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
+import com.anjiplus.template.gaea.business.modules.accessrole.dao.entity.AccessRole;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Constants;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+/**
+* AccessRole Mapper
+* @author 木子李·De
+* @date 2019-02-17 08:50:14.136
+**/
+@Mapper
+public interface AccessRoleMapper extends GaeaBaseMapper {
+
+ List checkedAuthoritys(@Param("roleCode")String roleCode);
+}
\ No newline at end of file
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/accessrole/dao/entity/AccessRole.java b/src/main/java/com/anjiplus/template/gaea/business/modules/accessrole/dao/entity/AccessRole.java
new file mode 100644
index 0000000..e8e7b1a
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/accessrole/dao/entity/AccessRole.java
@@ -0,0 +1,30 @@
+
+package com.anjiplus.template.gaea.business.modules.accessrole.dao.entity;
+
+import lombok.Data;
+import com.anji.plus.gaea.curd.entity.GaeaBaseEntity;
+import com.baomidou.mybatisplus.annotation.TableName;
+import javax.validation.constraints.*;
+import java.util.Date;
+/**
+* @description 角色管理 entity
+* @author 木子李·De
+* @date 2019-02-17 08:50:14.136
+**/
+@TableName(keepGlobalPrefix=true, value="access_role")
+@Data
+public class AccessRole extends GaeaBaseEntity {
+
+ /** 角色编码 */
+ private String roleCode;
+
+ /** 角色名称 */
+ private String roleName;
+
+ /** 0--未删除 1--已删除 DIC_NAME=DEL_FLAG */
+ private Integer deleteFlag;
+
+ /** 0--已禁用 1--已启用 DIC_NAME=ENABLE_FLAG */
+ private Integer enableFlag;
+
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/accessrole/dao/entity/AccessRoleAuthority.java b/src/main/java/com/anjiplus/template/gaea/business/modules/accessrole/dao/entity/AccessRoleAuthority.java
new file mode 100644
index 0000000..cb20a8f
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/accessrole/dao/entity/AccessRoleAuthority.java
@@ -0,0 +1,44 @@
+package com.anjiplus.template.gaea.business.modules.accessrole.dao.entity;
+
+import com.anji.plus.gaea.curd.entity.GaeaBaseEntity;
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.Version;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * @description 角色--菜单--按钮关联关系 entity
+ * @author 木子李·De
+ * @date 2019-02-17 08:50:14.136
+ **/
+@TableName(keepGlobalPrefix=true, value="access_role_authority")
+@Data
+public class AccessRoleAuthority extends GaeaBaseEntity {
+
+ /** 角色编码 */
+ private String roleCode;
+
+ /** 菜单代码 */
+ private String target;
+
+ /** 按钮代码 */
+ private String action;
+
+ @TableField(exist = false)
+ private String createBy;
+
+ @TableField(exist = false)
+ private Date createTime;
+
+ @TableField(exist = false)
+ private String updateBy;
+
+ @TableField(exist = false)
+ private Date updateTime;
+
+ @TableField(exist = false)
+ private Integer version;
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/accessrole/service/AccessRoleService.java b/src/main/java/com/anjiplus/template/gaea/business/modules/accessrole/service/AccessRoleService.java
new file mode 100644
index 0000000..639fd1a
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/accessrole/service/AccessRoleService.java
@@ -0,0 +1,34 @@
+
+package com.anjiplus.template.gaea.business.modules.accessrole.service;
+
+import com.anji.plus.gaea.bean.ResponseBean;
+import com.anjiplus.template.gaea.business.modules.accessrole.controller.dto.AccessRoleDto;
+import com.anjiplus.template.gaea.business.modules.accessrole.dao.entity.AccessRole;
+import com.anjiplus.template.gaea.business.modules.accessrole.controller.param.AccessRoleParam;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.anji.plus.gaea.curd.service.GaeaBaseService;
+
+import java.util.Map;
+
+/**
+* @desc AccessRole 角色管理服务接口
+* @author 木子李·De
+* @date 2019-02-17 08:50:14.136
+**/
+public interface AccessRoleService extends GaeaBaseService {
+
+ /** 查询某角色的权限树
+ * @param roleCode 被操作的对象
+ * @param operator 当前登录者
+ * @return
+ */
+ Map getAuthorityTree(String roleCode, String operator);
+
+
+ /** 保存角色的权限
+ * @param accessRoleDto
+ * @return
+ */
+ Boolean saveAuthorityTree(AccessRoleDto accessRoleDto);
+}
\ No newline at end of file
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/accessrole/service/impl/AccessRoleServiceImpl.java b/src/main/java/com/anjiplus/template/gaea/business/modules/accessrole/service/impl/AccessRoleServiceImpl.java
new file mode 100644
index 0000000..dea1b15
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/accessrole/service/impl/AccessRoleServiceImpl.java
@@ -0,0 +1,101 @@
+
+package com.anjiplus.template.gaea.business.modules.accessrole.service.impl;
+
+import com.anji.plus.gaea.bean.TreeNode;
+import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
+import com.anji.plus.gaea.exception.BusinessExceptionBuilder;
+import com.anjiplus.template.gaea.business.code.ResponseCode;
+import com.anjiplus.template.gaea.business.modules.accessauthority.service.AccessAuthorityService;
+import com.anjiplus.template.gaea.business.modules.accessrole.controller.dto.AccessRoleDto;
+import com.anjiplus.template.gaea.business.modules.accessrole.dao.AccessRoleAuthorityMapper;
+import com.anjiplus.template.gaea.business.modules.accessrole.dao.entity.AccessRole;
+import com.anjiplus.template.gaea.business.modules.accessrole.dao.entity.AccessRoleAuthority;
+import com.anjiplus.template.gaea.business.modules.accessrole.service.AccessRoleService;
+import com.anjiplus.template.gaea.business.modules.accessrole.dao.AccessRoleMapper;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+* @desc AccessRole 角色管理服务实现
+* @author 木子李·De
+* @date 2019-02-17 08:50:14.136
+**/
+@Service
+public class AccessRoleServiceImpl implements AccessRoleService {
+
+ @Autowired
+ private AccessRoleMapper accessRoleMapper;
+
+ @Autowired
+ private AccessRoleAuthorityMapper accessRoleAuthorityMapper;
+
+ @Autowired
+ private AccessAuthorityService accessAuthorityService;
+
+ @Override
+ public GaeaBaseMapper getMapper() {
+ return accessRoleMapper;
+ }
+
+ @Override
+ public Map getAuthorityTree(String roleCode, String operator) {
+ Map result = new HashMap();
+
+ // 菜单按钮树
+ List treeData = accessAuthorityService.getAuthorityTree(operator, true);
+
+ // 该角色已选中的菜单及按钮
+// List checkedKeys = accessRoleMapper.checkedAuthoritys(roleCode);
+
+ LambdaQueryWrapper accessRoleAuthorityWrapper = Wrappers.lambdaQuery();
+ accessRoleAuthorityWrapper.select(AccessRoleAuthority::getTarget, AccessRoleAuthority::getAction);
+ accessRoleAuthorityWrapper.eq(AccessRoleAuthority::getRoleCode, roleCode);
+ List accessRoleAuthorities = accessRoleAuthorityMapper.selectList(accessRoleAuthorityWrapper);
+ List checkedKeys = accessRoleAuthorities.stream()
+ .map(accessRoleAuthority -> accessRoleAuthority.getTarget().concat("_").concat(accessRoleAuthority.getAction())).distinct().collect(Collectors.toList());
+
+ result.put("treeData", treeData);
+ result.put("checkedKeys", checkedKeys);
+ return result;
+ }
+
+ @Override
+ public Boolean saveAuthorityTree(AccessRoleDto accessRoleDto) {
+ // 校验
+ String roleCode = accessRoleDto.getRoleCode();
+ List authorityList = accessRoleDto.getAuthorityList();
+ if(StringUtils.isBlank(roleCode)){
+ throw BusinessExceptionBuilder.build(ResponseCode.NOT_EMPTY, roleCode);
+ }
+ if(authorityList == null || authorityList.isEmpty()){
+ throw BusinessExceptionBuilder.build(ResponseCode.NOT_EMPTY, authorityList);
+ }
+
+ // 先清除该角色已保存的权限
+ LambdaQueryWrapper wrapper = Wrappers.lambdaQuery();
+ wrapper.eq(AccessRoleAuthority::getRoleCode, roleCode);
+ accessRoleAuthorityMapper.delete(wrapper);
+
+ // 保存勾选的权限(菜单和按钮)
+ authorityList.stream().forEach(authorityStr -> {
+ if(!authorityStr.contains("_")){
+ return;
+ }
+ String[] array = authorityStr.split("_");
+ AccessRoleAuthority accessRoleAuthority = new AccessRoleAuthority();
+ accessRoleAuthority.setRoleCode(roleCode);
+ accessRoleAuthority.setTarget(array[0].trim());
+ accessRoleAuthority.setAction(array[1].trim());
+ accessRoleAuthorityMapper.insert(accessRoleAuthority);
+ });
+ return true;
+ }
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/accessuser/controller/AccessUserController.java b/src/main/java/com/anjiplus/template/gaea/business/modules/accessuser/controller/AccessUserController.java
new file mode 100644
index 0000000..3781adf
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/accessuser/controller/AccessUserController.java
@@ -0,0 +1,113 @@
+
+package com.anjiplus.template.gaea.business.modules.accessuser.controller;
+
+import com.anji.plus.gaea.annotation.Permission;
+import com.anji.plus.gaea.bean.ResponseBean;
+import com.anji.plus.gaea.curd.controller.GaeaBaseController;
+import com.anji.plus.gaea.curd.service.GaeaBaseService;
+import com.anji.plus.gaea.holder.UserContentHolder;
+import com.anjiplus.template.gaea.business.modules.accessuser.controller.dto.GaeaUserDto;
+import com.anjiplus.template.gaea.business.modules.accessuser.controller.dto.UpdatePasswordDto;
+import com.anjiplus.template.gaea.business.modules.accessuser.dao.entity.AccessUser;
+import com.anjiplus.template.gaea.business.modules.accessuser.service.AccessUserService;
+import com.anjiplus.template.gaea.business.modules.accessuser.controller.dto.AccessUserDto;
+import com.anjiplus.template.gaea.business.modules.accessuser.controller.param.AccessUserParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+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.RestController;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import io.swagger.annotations.Api;
+
+import java.util.Map;
+
+/**
+* @desc 用户管理 controller
+* @author 木子李·De
+* @date 2019-02-17 08:50:11.902
+**/
+@RestController
+@Api(tags = "用户管理管理")
+@RequestMapping("/accessUser")
+@Permission(code = "userManage", name = "用户管理")
+public class AccessUserController extends GaeaBaseController {
+
+ @Autowired
+ private AccessUserService accessUserService;
+
+ @Override
+ public GaeaBaseService getService() {
+ return accessUserService;
+ }
+
+ @Override
+ public AccessUser getEntity() {
+ return new AccessUser();
+ }
+
+ @Override
+ public AccessUserDto getDTO() {
+ return new AccessUserDto();
+ }
+
+
+ /**
+ * 获取用户的角色树
+ * @return
+ */
+ @Permission( code = "grantRole", name = "分配角色")
+ @GetMapping("/roleTree/{loginName}")
+ public ResponseBean getRoleTree(@PathVariable("loginName")String loginName){
+ String operator = UserContentHolder.getContext().getUsername();
+ Map map = accessUserService.getRoleTree(loginName, operator);
+ return responseSuccessWithData(map);
+ }
+
+ /**
+ * 保存用户的角色树
+ * @return
+ */
+ @Permission( code = "grantRole", name = "分配角色")
+ @PostMapping("/saveRoleTree")
+ public ResponseBean saveRoleTree(@RequestBody AccessUserDto dto){
+ Boolean data = accessUserService.saveRoleTree(dto);
+ return responseSuccessWithData(data);
+ }
+
+
+ /**
+ * 重置密码
+ * @param dto
+ * @return
+ */
+ @Permission( code = "resetPassword", name = "重置密码")
+ @PostMapping({"/resetPassword"})
+ public ResponseBean resetPassword(@RequestBody GaeaUserDto dto) {
+ Boolean data = accessUserService.resetPassword(dto);
+ return responseSuccessWithData(data);
+ }
+
+ /**
+ * 简单实现登录
+ * @param dto
+ * @return
+ */
+ @PostMapping({"/login"})
+ public ResponseBean login(@RequestBody @Validated GaeaUserDto dto) {
+ return responseSuccessWithData(accessUserService.login(dto));
+ }
+
+ /**
+ * 修改自己的密码
+ * @param dto
+ * @return
+ */
+ @PostMapping("/updatePassword")
+ public ResponseBean updatePassword(@RequestBody UpdatePasswordDto dto) {
+ return responseSuccessWithData(accessUserService.updatePassword(dto));
+ }
+
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/accessuser/controller/dto/AccessUserDto.java b/src/main/java/com/anjiplus/template/gaea/business/modules/accessuser/controller/dto/AccessUserDto.java
new file mode 100644
index 0000000..11d1fb9
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/accessuser/controller/dto/AccessUserDto.java
@@ -0,0 +1,66 @@
+
+package com.anjiplus.template.gaea.business.modules.accessuser.controller.dto;
+
+import java.io.Serializable;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+
+import com.anji.plus.gaea.curd.dto.GaeaBaseDTO;
+import com.anjiplus.template.gaea.business.modules.accessuser.dao.entity.AccessUser;
+import io.swagger.annotations.ApiModelProperty;
+import com.anji.plus.gaea.annotation.Formatter;
+import lombok.Data;
+import java.util.Date;
+import java.util.List;
+
+/**
+*
+* @description 用户管理 dto
+* @author 木子李·De
+* @date 2019-02-17 08:50:11.902
+**/
+@Data
+public class AccessUserDto extends GaeaBaseDTO implements Serializable {
+
+ /** 登录名 */
+ @ApiModelProperty(value = " 登录名")
+ @NotEmpty(message = "6002")
+ private String loginName;
+
+ /** 真实用户 */
+ @ApiModelProperty(value = "真实用户")
+ @NotEmpty(message = "6002")
+ private String realName;
+
+ /** 手机号码 */
+ @ApiModelProperty(value = "手机号码")
+ private String phone;
+
+ /** 用户邮箱 */
+ @ApiModelProperty(value = "用户邮箱")
+ private String email;
+
+ /** 0--已禁用 1--已启用 DIC_NAME=ENABLE_FLAG */
+ @ApiModelProperty(value = "0--已禁用 1--已启用 DIC_NAME=ENABLE_FLAG")
+ @NotNull(message = "6002")
+ private Integer enableFlag;
+
+ /** 0--未删除 1--已删除 DIC_NAME=DEL_FLAG */
+ @ApiModelProperty(value = " 0--未删除 1--已删除 DIC_NAME=DEL_FLAG")
+ private Integer deleteFlag;
+
+ /** 最后一次登录IP */
+ @ApiModelProperty(value = "最后一次登录IP")
+ private String lastLoginIp;
+
+ /** 最后一次登陆时间 */
+ @ApiModelProperty(value = "最后一次登陆时间")
+ private Date lastLoginTime;
+
+ /** 备注 */
+ @ApiModelProperty(value = "备注")
+ private String remark;
+
+ /** 用户勾选的角色 */
+ private List roleCodeList;
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/accessuser/controller/dto/GaeaUserDto.java b/src/main/java/com/anjiplus/template/gaea/business/modules/accessuser/controller/dto/GaeaUserDto.java
new file mode 100644
index 0000000..02a9d19
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/accessuser/controller/dto/GaeaUserDto.java
@@ -0,0 +1,30 @@
+package com.anjiplus.template.gaea.business.modules.accessuser.controller.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import java.util.List;
+
+@ApiModel(value = "用户登录")
+@Data
+public class GaeaUserDto {
+
+ @ApiModelProperty(value = "登录名")
+ @NotBlank
+ private String loginName;
+
+ @ApiModelProperty(value = "密码")
+ @NotBlank
+ private String password;
+
+ /** 真实用户 */
+ private String realName;
+
+ /** 登录成功后的 */
+ private String token;
+
+ /** 用户所拥有的权限合集 */
+ private List authorities;
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/accessuser/controller/dto/UpdatePasswordDto.java b/src/main/java/com/anjiplus/template/gaea/business/modules/accessuser/controller/dto/UpdatePasswordDto.java
new file mode 100644
index 0000000..daf8417
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/accessuser/controller/dto/UpdatePasswordDto.java
@@ -0,0 +1,25 @@
+package com.anjiplus.template.gaea.business.modules.accessuser.controller.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import java.util.List;
+
+@ApiModel(value = "修改密码")
+@Data
+public class UpdatePasswordDto {
+
+ @ApiModelProperty(value = "旧密码密码")
+ @NotBlank
+ private String oldPassword;
+
+ @ApiModelProperty(value = "密码")
+ @NotBlank
+ private String password;
+
+ @ApiModelProperty(value = "密码")
+ @NotBlank
+ private String confirmPassword;
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/accessuser/controller/param/AccessUserParam.java b/src/main/java/com/anjiplus/template/gaea/business/modules/accessuser/controller/param/AccessUserParam.java
new file mode 100644
index 0000000..0005c14
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/accessuser/controller/param/AccessUserParam.java
@@ -0,0 +1,37 @@
+/**/
+package com.anjiplus.template.gaea.business.modules.accessuser.controller.param;
+
+import lombok.Data;
+import java.io.Serializable;
+import com.anji.plus.gaea.annotation.Query;
+import com.anji.plus.gaea.constant.QueryEnum;
+import com.anji.plus.gaea.curd.params.PageParam;
+import java.util.List;
+
+import java.util.Date;
+
+/**
+* @desc AccessUser 用户管理查询输入类
+* @author 木子李·De
+* @date 2019-02-17 08:50:11.902
+**/
+@Data
+public class AccessUserParam extends PageParam implements Serializable{
+
+ // 登录名
+ @Query(value = QueryEnum.LIKE)
+ private String loginName;
+
+ // 真实用户
+ @Query(value = QueryEnum.LIKE)
+ private String realName;
+
+ // 手机号码
+ @Query(value = QueryEnum.LIKE)
+ private String phone;
+
+ // 0--已禁用 1--已启用 DIC_NAME=ENABLE_FLAG
+ @Query
+ private Integer enableFlag;
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/accessuser/dao/AccessUserMapper.java b/src/main/java/com/anjiplus/template/gaea/business/modules/accessuser/dao/AccessUserMapper.java
new file mode 100644
index 0000000..0d8aa18
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/accessuser/dao/AccessUserMapper.java
@@ -0,0 +1,26 @@
+package com.anjiplus.template.gaea.business.modules.accessuser.dao;
+
+import org.apache.ibatis.annotations.Mapper;
+import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
+import com.anjiplus.template.gaea.business.modules.accessuser.dao.entity.AccessUser;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Constants;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+/**
+* AccessUser Mapper
+* @author 木子李·De
+* @date 2019-02-17 08:50:11.902
+**/
+@Mapper
+public interface AccessUserMapper extends GaeaBaseMapper {
+
+ /** 查询用户所拥有的所有角色下的权限
+ * @param loginName
+ * @return
+ */
+ List queryAuthoritiesByLoginName(@Param("loginName")String loginName);
+}
\ No newline at end of file
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/accessuser/dao/AccessUserRoleMapper.java b/src/main/java/com/anjiplus/template/gaea/business/modules/accessuser/dao/AccessUserRoleMapper.java
new file mode 100644
index 0000000..2e4e687
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/accessuser/dao/AccessUserRoleMapper.java
@@ -0,0 +1,15 @@
+package com.anjiplus.template.gaea.business.modules.accessuser.dao;
+
+import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
+import com.anjiplus.template.gaea.business.modules.accessuser.dao.entity.AccessUserRole;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* AccessUser Mapper
+* @author 木子李·De
+* @date 2019-02-17 08:50:11.902
+**/
+@Mapper
+public interface AccessUserRoleMapper extends GaeaBaseMapper {
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/accessuser/dao/entity/AccessUser.java b/src/main/java/com/anjiplus/template/gaea/business/modules/accessuser/dao/entity/AccessUser.java
new file mode 100644
index 0000000..5cd3815
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/accessuser/dao/entity/AccessUser.java
@@ -0,0 +1,48 @@
+
+package com.anjiplus.template.gaea.business.modules.accessuser.dao.entity;
+
+import lombok.Data;
+import com.anji.plus.gaea.curd.entity.GaeaBaseEntity;
+import com.baomidou.mybatisplus.annotation.TableName;
+import javax.validation.constraints.*;
+import java.util.Date;
+/**
+* @description 用户管理 entity
+* @author 木子李·De
+* @date 2019-02-17 08:50:11.902
+**/
+@TableName(keepGlobalPrefix=true, value="access_user")
+@Data
+public class AccessUser extends GaeaBaseEntity {
+
+ /** 登录名 */
+ private String loginName;
+
+ /** 密码 */
+ private String password;
+
+ /** 真实用户 */
+ private String realName;
+
+ /** 手机号码 */
+ private String phone;
+
+ /** 用户邮箱 */
+ private String email;
+
+ /** 备注 */
+ private String remark;
+
+ /** 0--已禁用 1--已启用 DIC_NAME=ENABLE_FLAG */
+ private Integer enableFlag;
+
+ /** 0--未删除 1--已删除 DIC_NAME=DEL_FLAG */
+ private Integer deleteFlag;
+
+ /** 最后一次登录IP */
+ private String lastLoginIp;
+
+ /** 最后一次登陆时间 */
+ private Date lastLoginTime;
+
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/accessuser/dao/entity/AccessUserRole.java b/src/main/java/com/anjiplus/template/gaea/business/modules/accessuser/dao/entity/AccessUserRole.java
new file mode 100644
index 0000000..a56be7a
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/accessuser/dao/entity/AccessUserRole.java
@@ -0,0 +1,40 @@
+
+package com.anjiplus.template.gaea.business.modules.accessuser.dao.entity;
+
+import com.anji.plus.gaea.curd.entity.GaeaBaseEntity;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+* @description 用户--角色关联关系 entity
+* @author 木子李·De
+* @date 2019-02-17 08:50:11.902
+**/
+@TableName(keepGlobalPrefix=true, value="access_user_role")
+@Data
+public class AccessUserRole extends GaeaBaseEntity {
+
+ /** 登录名 */
+ private String loginName;
+
+ /** 角色编码 */
+ private String roleCode;
+
+ @TableField(exist = false)
+ private String createBy;
+
+ @TableField(exist = false)
+ private Date createTime;
+
+ @TableField(exist = false)
+ private String updateBy;
+
+ @TableField(exist = false)
+ private Date updateTime;
+
+ @TableField(exist = false)
+ private Integer version;
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/accessuser/service/AccessUserService.java b/src/main/java/com/anjiplus/template/gaea/business/modules/accessuser/service/AccessUserService.java
new file mode 100644
index 0000000..900cee3
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/accessuser/service/AccessUserService.java
@@ -0,0 +1,52 @@
+
+package com.anjiplus.template.gaea.business.modules.accessuser.service;
+
+import com.anjiplus.template.gaea.business.modules.accessuser.controller.dto.AccessUserDto;
+import com.anjiplus.template.gaea.business.modules.accessuser.controller.dto.GaeaUserDto;
+import com.anjiplus.template.gaea.business.modules.accessuser.controller.dto.UpdatePasswordDto;
+import com.anjiplus.template.gaea.business.modules.accessuser.dao.entity.AccessUser;
+import com.anjiplus.template.gaea.business.modules.accessuser.controller.param.AccessUserParam;
+import com.anji.plus.gaea.curd.service.GaeaBaseService;
+
+import java.util.Map;
+
+/**
+* @desc AccessUser 用户管理服务接口
+* @author 木子李·De
+* @date 2019-02-17 08:50:11.902
+**/
+public interface AccessUserService extends GaeaBaseService {
+
+ /** 获取用户的角色树
+ * @param loginName 被操作的对象
+ * @param operator 当前登录者
+ * @return
+ */
+ Map getRoleTree(String loginName, String operator);
+
+
+ /** 保存用户的角色树
+ * @param accessUserDto
+ * @return
+ */
+ Boolean saveRoleTree(AccessUserDto accessUserDto);
+
+ /** 重置密码
+ * @param gaeaUserDto
+ * @return
+ */
+ Boolean resetPassword(GaeaUserDto gaeaUserDto);
+
+ /** 用户登录
+ * @param gaeaUserDto
+ * @return
+ */
+ GaeaUserDto login(GaeaUserDto gaeaUserDto);
+
+ /**
+ * 修改密码
+ * @param dto
+ * @return
+ */
+ Boolean updatePassword(UpdatePasswordDto dto);
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/accessuser/service/impl/AccessUserServiceImpl.java b/src/main/java/com/anjiplus/template/gaea/business/modules/accessuser/service/impl/AccessUserServiceImpl.java
new file mode 100644
index 0000000..1ca1fe5
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/accessuser/service/impl/AccessUserServiceImpl.java
@@ -0,0 +1,277 @@
+
+package com.anjiplus.template.gaea.business.modules.accessuser.service.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.anji.plus.gaea.bean.TreeNode;
+import com.anji.plus.gaea.cache.CacheHelper;
+import com.anji.plus.gaea.constant.BaseOperationEnum;
+import com.anji.plus.gaea.constant.GaeaConstant;
+import com.anji.plus.gaea.exception.BusinessException;
+import com.anji.plus.gaea.exception.BusinessExceptionBuilder;
+import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
+import com.anji.plus.gaea.holder.UserContentHolder;
+import com.anji.plus.gaea.utils.GaeaUtils;
+import com.anji.plus.gaea.utils.JwtBean;
+import com.anjiplus.template.gaea.business.code.ResponseCode;
+import com.anjiplus.template.gaea.business.constant.BusinessConstant;
+import com.anjiplus.template.gaea.business.modules.accessrole.dao.AccessRoleAuthorityMapper;
+import com.anjiplus.template.gaea.business.modules.accessrole.dao.AccessRoleMapper;
+import com.anjiplus.template.gaea.business.modules.accessrole.dao.entity.AccessRole;
+import com.anjiplus.template.gaea.business.modules.accessrole.dao.entity.AccessRoleAuthority;
+import com.anjiplus.template.gaea.business.modules.accessuser.controller.dto.AccessUserDto;
+import com.anjiplus.template.gaea.business.modules.accessuser.controller.dto.GaeaUserDto;
+import com.anjiplus.template.gaea.business.modules.accessuser.controller.dto.UpdatePasswordDto;
+import com.anjiplus.template.gaea.business.modules.accessuser.dao.AccessUserRoleMapper;
+import com.anjiplus.template.gaea.business.modules.accessuser.dao.entity.AccessUser;
+import com.anjiplus.template.gaea.business.modules.accessuser.dao.entity.AccessUserRole;
+import com.anjiplus.template.gaea.business.modules.accessuser.service.AccessUserService;
+import com.anjiplus.template.gaea.business.modules.accessuser.dao.AccessUserMapper;
+import com.anjiplus.template.gaea.business.util.MD5Util;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+* @desc AccessUser 用户管理服务实现
+* @author 木子李·De
+* @date 2019-02-17 08:50:11.902
+**/
+@Service
+public class AccessUserServiceImpl implements AccessUserService {
+
+ @Autowired
+ private AccessRoleMapper accessRoleMapper;
+
+ @Autowired
+ private AccessUserMapper accessUserMapper;
+
+ @Autowired
+ private AccessUserRoleMapper accessUserRoleMapper;
+
+ @Autowired
+ private AccessRoleAuthorityMapper accessRoleAuthorityMapper;
+
+ @Value("${customer.user.default.password:'123456'}")
+ private String defaultPassword;
+
+ @Override
+ public GaeaBaseMapper getMapper() {
+ return accessUserMapper;
+ }
+
+ @Autowired
+ private JwtBean jwtBean;
+
+ @Autowired
+ private CacheHelper cacheHelper;
+
+ @Override
+ public Map getRoleTree(String loginName, String operator) {
+ Map result = new HashMap();
+ List treeData = new ArrayList<>();
+ List checkedKeys = new ArrayList();
+
+ // 角色树
+ LambdaQueryWrapper roleQuery = Wrappers.lambdaQuery();
+ roleQuery.select(AccessRole::getRoleCode, AccessRole::getRoleName);
+ // 按operator去筛选role 后面再加where
+ List roleList = accessRoleMapper.selectList(roleQuery);
+ if(roleList == null || roleList.isEmpty()){
+ result.put("treeData", treeData);
+ result.put("checkedKeys", checkedKeys);
+ return result;
+ }
+ treeData = roleList.stream().map(role -> {
+ TreeNode treeNode = new TreeNode();
+ treeNode.setId(role.getRoleCode());
+ treeNode.setLabel(role.getRoleName());
+ return treeNode;
+ }).collect(Collectors.toList());
+
+ // 该用户已保存的角色
+ LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery();
+ queryWrapper.select(AccessUserRole::getRoleCode)
+ .eq(AccessUserRole::getLoginName, loginName);
+ checkedKeys = accessUserRoleMapper.selectObjs(queryWrapper);
+
+ result.put("treeData", treeData);
+ result.put("checkedKeys", checkedKeys);
+ return result;
+ }
+
+ @Override
+ public Boolean saveRoleTree(AccessUserDto accessUserDto) {
+ // 校验
+ String loginName = accessUserDto.getLoginName();
+ List roleCodeList = accessUserDto.getRoleCodeList();
+ if(StringUtils.isBlank(loginName)){
+ throw BusinessExceptionBuilder.build(ResponseCode.NOT_EMPTY, loginName);
+ }
+ if(roleCodeList == null || roleCodeList.isEmpty()){
+ throw BusinessExceptionBuilder.build(ResponseCode.NOT_EMPTY, roleCodeList);
+ }
+
+ // 先清除该用户已保存的角色
+ LambdaQueryWrapper wrapper = Wrappers.lambdaQuery();
+ wrapper.eq(AccessUserRole::getLoginName, loginName);
+ accessUserRoleMapper.delete(wrapper);
+
+ // 保存勾选的角色
+ roleCodeList.stream().forEach(roleCode -> {
+ AccessUserRole accessUserRole = new AccessUserRole();
+ accessUserRole.setLoginName(loginName);
+ accessUserRole.setRoleCode(roleCode);
+ accessUserRoleMapper.insert(accessUserRole);
+ });
+ return true;
+ }
+
+ @Override
+ public Boolean resetPassword(GaeaUserDto gaeaUserDto) {
+ String loginName = gaeaUserDto.getLoginName();
+ if (GaeaConstant.SUPER_USER_NAME.equalsIgnoreCase(loginName)) {
+ throw BusinessExceptionBuilder.build("admin不允许重置密码");
+ }
+ // 1.判断用户是否存在
+ LambdaQueryWrapper wrapper = Wrappers.lambdaQuery();
+ wrapper.eq(AccessUser::getLoginName, loginName);
+ AccessUser accessUser = accessUserMapper.selectOne(wrapper);
+ if (accessUser == null) {
+ throw BusinessExceptionBuilder.build("用户不存在");
+ }
+ //默认密码
+ accessUser.setPassword(MD5Util.encrypt(MD5Util.encrypt(defaultPassword.concat("gaea"))));
+ accessUserMapper.updateById(accessUser);
+ return true;
+ }
+
+ @Override
+ public GaeaUserDto login(GaeaUserDto gaeaUserDto) {
+
+ String loginName = gaeaUserDto.getLoginName();
+ String password = gaeaUserDto.getPassword();
+
+ // 1.判断用户是否存在
+ LambdaQueryWrapper wrapper = Wrappers.lambdaQuery();
+ wrapper.eq(AccessUser::getLoginName, loginName);
+ AccessUser accessUser = accessUserMapper.selectOne(wrapper);
+ if (null == accessUser) {
+ throw BusinessExceptionBuilder.build(ResponseCode.LOGIN_ERROR);
+ }
+ // 2.密码错误
+ if (!accessUser.getPassword().equals(MD5Util.encrypt(password))) {
+ throw BusinessExceptionBuilder.build(ResponseCode.USER_PASSWORD_ERROR);
+ }
+
+ // 3.如果该用户登录未过期,这里允许一个用户在多个终端登录
+ String tokenKey = String.format(BusinessConstant.GAEA_SECURITY_LOGIN_TOKEN, loginName);
+ String token = "";
+ GaeaUserDto gaeaUser = new GaeaUserDto();
+ if (cacheHelper.exist(tokenKey)) {
+ token = cacheHelper.stringGet(tokenKey);
+ } else {
+ // 生成用户token
+ String uuid = GaeaUtils.UUID();
+ token = jwtBean.createToken(loginName, uuid, 0, GaeaConstant.TENANT_CODE);
+ cacheHelper.stringSetExpire(tokenKey, token, 3600);
+ }
+
+ // 4.读取用户最新人权限主信息
+ String userKey = String.format(BusinessConstant.GAEA_SECURITY_LOGIN_USER, loginName);
+
+ //为了兼容底层其他数据库,不再写自定义sql
+// List authorities = accessUserMapper.queryAuthoritiesByLoginName(loginName);
+
+ //当前用户的roleCode集合
+ LambdaQueryWrapper accessUserWrapper = Wrappers.lambdaQuery();
+ accessUserWrapper.select(AccessUserRole::getRoleCode);
+ accessUserWrapper.eq(AccessUserRole::getLoginName, loginName);
+ List accessUserRoles = accessUserRoleMapper.selectList(accessUserWrapper);
+ Set roleCodeSet = accessUserRoles.stream().map(AccessUserRole::getRoleCode).collect(Collectors.toSet());
+ if (roleCodeSet.size() < 1) {
+ gaeaUser.setAuthorities(new ArrayList<>());
+ }else {
+ LambdaQueryWrapper accessRoleAuthorityWrapper = Wrappers.lambdaQuery();
+ accessRoleAuthorityWrapper.select(AccessRoleAuthority::getTarget, AccessRoleAuthority::getAction);
+ accessRoleAuthorityWrapper.in(AccessRoleAuthority::getRoleCode, roleCodeSet);
+ List accessRoleAuthorities = accessRoleAuthorityMapper.selectList(accessRoleAuthorityWrapper);
+ List authorities = accessRoleAuthorities.stream()
+ .map(accessRoleAuthority -> accessRoleAuthority.getTarget().concat(":").concat(accessRoleAuthority.getAction())).distinct().collect(Collectors.toList());
+ gaeaUser.setAuthorities(authorities);
+ }
+
+ gaeaUser.setLoginName(loginName);
+ gaeaUser.setRealName(accessUser.getRealName());
+ gaeaUser.setToken(token);
+
+ String gaeaUserStr = JSONObject.toJSONString(gaeaUser);
+ cacheHelper.stringSetExpire(userKey, gaeaUserStr, 3600);
+
+ return gaeaUser;
+ }
+
+ /**
+ * 修改密码
+ *
+ * @param dto
+ * @return
+ */
+ @Override
+ public Boolean updatePassword(UpdatePasswordDto dto) {
+ if (!dto.getConfirmPassword().equals(dto.getPassword())) {
+ //密码和确认密码不一致
+ throw BusinessExceptionBuilder.build(ResponseCode.USER_INCONSISTENT_PASSWORD_ERROR);
+ }
+ //新密码不能与老密码一样
+ if(StringUtils.equals(dto.getOldPassword(), dto.getPassword())){
+ throw BusinessExceptionBuilder.build(ResponseCode.USER_PASSWORD_CONFIG_PASSWORD_CANOT_EQUAL);
+ }
+
+ String username = UserContentHolder.getUsername();
+
+
+ LambdaQueryWrapper wrapper = Wrappers.lambdaQuery();
+ wrapper.eq(AccessUser::getLoginName, username);
+ AccessUser accessUser = selectOne(wrapper);
+ String password = accessUser.getPassword();
+ if (!MD5Util.encrypt(dto.getOldPassword()).equals(password)) {
+ throw BusinessExceptionBuilder.build(ResponseCode.USER_OLD_PASSWORD_ERROR);
+ }
+ accessUser.setPassword(MD5Util.encrypt(dto.getPassword()));
+
+ accessUserMapper.updateById(accessUser);
+ return true;
+ }
+
+ /**
+ * 操作前处理
+ *
+ * @param entity 前端传递的对象
+ * @param operationEnum 操作类型
+ * @throws BusinessException 阻止程序继续执行或回滚事务
+ */
+ @Override
+ public void processBeforeOperation(AccessUser entity, BaseOperationEnum operationEnum) throws BusinessException {
+ //过滤密码
+ switch (operationEnum) {
+ case INSERT:
+ //gaea是为了和前端加密保持一致
+ entity.setPassword(MD5Util.encrypt(MD5Util.encrypt(defaultPassword.concat("gaea"))));
+ break;
+ case UPDATE:
+ //更新用户不允许修改密码
+ entity.setPassword(null);
+ break;
+ default:
+
+ break;
+ }
+
+ }
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/controller/ReportDashboardController.java b/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/controller/ReportDashboardController.java
new file mode 100644
index 0000000..fdb66fb
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/controller/ReportDashboardController.java
@@ -0,0 +1,109 @@
+
+package com.anjiplus.template.gaea.business.modules.dashboard.controller;
+
+import com.anji.plus.gaea.annotation.Permission;
+import com.anji.plus.gaea.annotation.log.GaeaAuditLog;
+import com.anji.plus.gaea.bean.ResponseBean;
+import com.anjiplus.template.gaea.business.modules.dashboard.service.ReportDashboardService;
+import com.anjiplus.template.gaea.business.modules.dashboard.controller.dto.ChartDto;
+import com.anjiplus.template.gaea.business.modules.dashboard.controller.dto.ReportDashboardObjectDto;
+import com.anjiplus.template.gaea.business.modules.reportshare.controller.dto.ReportShareDto;
+import com.anjiplus.template.gaea.business.modules.reportshare.service.ReportShareService;
+import io.swagger.annotations.Api;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+* @desc 大屏设计 controller
+* @website https://gitee.com/anji-plus/gaea
+* @author Raod
+* @date 2021-04-12 14:52:21.761
+**/
+@RestController
+@Api(tags = "大屏设计管理")
+@Permission(code = "bigScreenManage", name = "大屏报表")
+@RequestMapping("/reportDashboard")
+public class ReportDashboardController {
+
+ @Autowired
+ private ReportDashboardService reportDashboardService;
+
+ @Autowired
+ private ReportShareService reportShareService;
+
+ /**
+ * 预览、查询大屏详情
+ * @param reportCode
+ * @return
+ */
+ @GetMapping({"/{reportCode}"})
+ @Permission(code = "view", name = "查看大屏")
+ public ResponseBean detail(@PathVariable("reportCode") String reportCode) {
+ return ResponseBean.builder().data(reportDashboardService.getDetail(reportCode)).build();
+ }
+
+ /**
+ * 保存大屏设计
+ * @param dto
+ * @return
+ */
+ @PostMapping
+ @Permission(code = "design", name = "设计大屏")
+ @GaeaAuditLog(pageTitle = "新增")
+ public ResponseBean insert(@RequestBody ReportDashboardObjectDto dto) {
+ reportDashboardService.insertDashboard(dto);
+ return ResponseBean.builder().build();
+ }
+
+
+ /**
+ * 获取去单个图层数据
+ * @param dto
+ * @return
+ */
+ @PostMapping("/getData")
+ @Permission(code = "view", name = "查看大屏")
+ public ResponseBean getData(@RequestBody ChartDto dto) {
+ return ResponseBean.builder().data(reportDashboardService.getChartData(dto)).build();
+ }
+
+
+ /**
+ * 导出大屏
+ * @param reportCode
+ * @return
+ */
+ @GetMapping("/export")
+ @Permission(code = "export", name = "导出大屏")
+ public ResponseEntity exportDashboard(HttpServletRequest request, HttpServletResponse response,
+ @RequestParam("reportCode") String reportCode, @RequestParam(value = "showDataSet",required = false, defaultValue = "1") Integer showDataSet) {
+ return reportDashboardService.exportDashboard(request, response, reportCode, showDataSet);
+ }
+
+ /**
+ * 导入大屏
+ * @param file 导入的zip文件
+ * @param reportCode
+ * @return
+ */
+ @PostMapping("/import/{reportCode}")
+ @Permission(code = "import", name = "导入大屏")
+ public ResponseBean importDashboard(@RequestParam("file") MultipartFile file, @PathVariable("reportCode") String reportCode) {
+ reportDashboardService.importDashboard(file, reportCode);
+ return ResponseBean.builder().build();
+ }
+
+ @PostMapping("/share")
+ @GaeaAuditLog(pageTitle = "分享")
+ @Permission(code = "share", name = "分享报表")
+ public ResponseBean share(@Validated @RequestBody ReportShareDto dto) {
+ return ResponseBean.builder().data(reportShareService.insertShare(dto)).build();
+ }
+
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/controller/dto/ChartDto.java b/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/controller/dto/ChartDto.java
new file mode 100644
index 0000000..d6b67f8
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/controller/dto/ChartDto.java
@@ -0,0 +1,51 @@
+
+package com.anjiplus.template.gaea.business.modules.dashboard.controller.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Map;
+
+
+/**
+*
+* @description 大屏设计 dto
+* @author Raod
+* @date 2021-04-12 14:52:21.761
+**/
+@Data
+public class ChartDto implements Serializable {
+
+ private String chartType;
+
+ /**数据集编码*/
+ private String setCode;
+
+ /** 传入的自定义参数*/
+ private Map contextData;
+
+ /**图表属性*/
+ private Map chartProperties;
+
+ /**时间字段*/
+ private String timeLineFiled;
+
+ /**时间颗粒度*/
+ private String particles;
+
+ /**时间格式化*/
+ private String dataTimeFormat;
+
+ /**时间展示层*/
+ private String timeLineFormat;
+
+ private int timeUnit;
+
+ /**时间区间*/
+ private String startTime;
+
+ /**时间区间*/
+ private String endTime;
+
+
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/controller/dto/ReportDashboardDto.java b/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/controller/dto/ReportDashboardDto.java
new file mode 100644
index 0000000..6812352
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/controller/dto/ReportDashboardDto.java
@@ -0,0 +1,55 @@
+
+package com.anjiplus.template.gaea.business.modules.dashboard.controller.dto;
+
+import com.anji.plus.gaea.curd.dto.GaeaBaseDTO;
+import com.anjiplus.template.gaea.business.modules.dashboardwidget.controller.dto.ReportDashboardWidgetDto;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+
+/**
+*
+* @description 大屏设计 dto
+* @author Raod
+* @date 2021-04-12 14:52:21.761
+**/
+@Data
+public class ReportDashboardDto extends GaeaBaseDTO implements Serializable {
+ /** 报表编码 */
+ private String reportCode;
+
+ /** 看板标题 */
+ private String title;
+
+ /** 宽度px */
+ private Long width;
+
+ /** 高度px */
+ private Long height;
+
+ /** 背景色 */
+ private String backgroundColor;
+
+ /** 背景图片 */
+ private String backgroundImage;
+
+ /** 工作台中的辅助线 */
+ private String presetLine;
+
+ /** 自动刷新间隔秒,数据字典REFRESH_TYPE */
+ private Integer refreshSeconds;
+
+ /** 0--已禁用 1--已启用 DIC_NAME=ENABLE_FLAG */
+ private Integer enableFlag;
+
+ /** 0--未删除 1--已删除 DIC_NAME=DEL_FLAG */
+ private Integer deleteFlag;
+
+ /** 排序,降序 */
+ private Integer sort;
+
+ private List widgets;
+
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/controller/dto/ReportDashboardObjectDto.java b/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/controller/dto/ReportDashboardObjectDto.java
new file mode 100644
index 0000000..cc4ca08
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/controller/dto/ReportDashboardObjectDto.java
@@ -0,0 +1,32 @@
+
+package com.anjiplus.template.gaea.business.modules.dashboard.controller.dto;
+
+import com.anjiplus.template.gaea.business.modules.dashboardwidget.controller.dto.ReportDashboardWidgetDto;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+
+/**
+*
+* @description 大屏设计 dto
+* @author Raod
+* @date 2021-04-12 14:52:21.761
+**/
+@Data
+public class ReportDashboardObjectDto implements Serializable {
+
+ /** 报表编码 */
+ private String reportCode;
+ /**
+ * 报表编码
+ */
+ private ReportDashboardDto dashboard;
+
+ /**
+ * 大屏画布中的组件
+ */
+ private List widgets;
+
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/controller/param/ReportDashboardParam.java b/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/controller/param/ReportDashboardParam.java
new file mode 100644
index 0000000..d044b96
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/controller/param/ReportDashboardParam.java
@@ -0,0 +1,20 @@
+/**/
+package com.anjiplus.template.gaea.business.modules.dashboard.controller.param;
+
+import lombok.Data;
+import java.io.Serializable;
+import com.anji.plus.gaea.annotation.Query;
+import com.anji.plus.gaea.constant.QueryEnum;
+import com.anji.plus.gaea.curd.params.PageParam;
+
+import java.util.List;
+
+
+/**
+* @desc ReportDashboard 大屏设计查询输入类
+* @author Raod
+* @date 2021-04-12 14:52:21.761
+**/
+@Data
+public class ReportDashboardParam extends PageParam implements Serializable{
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/dao/ReportDashboardMapper.java b/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/dao/ReportDashboardMapper.java
new file mode 100644
index 0000000..173e822
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/dao/ReportDashboardMapper.java
@@ -0,0 +1,16 @@
+package com.anjiplus.template.gaea.business.modules.dashboard.dao;
+
+import org.apache.ibatis.annotations.Mapper;
+
+import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
+import com.anjiplus.template.gaea.business.modules.dashboard.dao.entity.ReportDashboard;
+
+/**
+* ReportDashboard Mapper
+* @author Raod
+* @date 2021-04-12 14:52:21.761
+**/
+@Mapper
+public interface ReportDashboardMapper extends GaeaBaseMapper {
+
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/dao/entity/ReportDashboard.java b/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/dao/entity/ReportDashboard.java
new file mode 100644
index 0000000..76ad6cb
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/dao/entity/ReportDashboard.java
@@ -0,0 +1,54 @@
+
+package com.anjiplus.template.gaea.business.modules.dashboard.dao.entity;
+
+import com.anji.plus.gaea.annotation.Unique;
+import com.anji.plus.gaea.curd.entity.GaeaBaseEntity;
+import com.anjiplus.template.gaea.business.code.ResponseCode;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+* @description 大屏设计 entity
+* @author Raod
+* @date 2021-04-12 14:52:21.761
+**/
+@TableName(keepGlobalPrefix=true, value="gaea_report_dashboard")
+@Data
+public class ReportDashboard extends GaeaBaseEntity {
+ @ApiModelProperty(value = "报表编码")
+ @Unique(code = ResponseCode.REPORT_CODE_ISEXIST)
+ private String reportCode;
+
+ @ApiModelProperty(value = "看板标题")
+ private String title;
+
+ @ApiModelProperty(value = "宽度px")
+ private Long width;
+
+ @ApiModelProperty(value = "高度px")
+ private Long height;
+
+ @ApiModelProperty(value = "背景色")
+ private String backgroundColor;
+
+ @ApiModelProperty(value = "背景图片")
+ private String backgroundImage;
+
+ @ApiModelProperty(value = "工作台中的辅助线")
+ private String presetLine;
+
+ @ApiModelProperty(value = "自动刷新间隔秒,数据字典REFRESH_TYPE")
+ private Integer refreshSeconds;
+
+ @ApiModelProperty(value = "0--已禁用 1--已启用 DIC_NAME=ENABLE_FLAG")
+ private Integer enableFlag;
+
+ @ApiModelProperty(value = " 0--未删除 1--已删除 DIC_NAME=DEL_FLAG")
+ private Integer deleteFlag;
+
+ @ApiModelProperty(value = "排序,降序")
+ private Integer sort;
+
+
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/service/ChartStrategy.java b/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/service/ChartStrategy.java
new file mode 100644
index 0000000..ccaa4b0
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/service/ChartStrategy.java
@@ -0,0 +1,26 @@
+package com.anjiplus.template.gaea.business.modules.dashboard.service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.anjiplus.template.gaea.business.modules.dashboard.controller.dto.ChartDto;
+
+import java.util.List;
+
+/**
+ * Created by raodeming on 2021/4/26.
+ */
+public interface ChartStrategy {
+
+ /**
+ * 图表类型
+ * @return
+ */
+ String type();
+
+ /**
+ * 针对每种图表类型做单独的数据转换解析
+ *
+ * @param dto
+ * @return
+ */
+ Object transform(ChartDto dto, List data);
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/service/ReportDashboardService.java b/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/service/ReportDashboardService.java
new file mode 100644
index 0000000..2b8c1e3
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/service/ReportDashboardService.java
@@ -0,0 +1,61 @@
+
+package com.anjiplus.template.gaea.business.modules.dashboard.service;
+
+import com.anji.plus.gaea.curd.service.GaeaBaseService;
+import com.anjiplus.template.gaea.business.modules.dashboard.controller.dto.ChartDto;
+import com.anjiplus.template.gaea.business.modules.dashboard.controller.dto.ReportDashboardObjectDto;
+import com.anjiplus.template.gaea.business.modules.dashboard.controller.param.ReportDashboardParam;
+import com.anjiplus.template.gaea.business.modules.dashboard.dao.entity.ReportDashboard;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+* @desc ReportDashboard 大屏设计服务接口
+* @author Raod
+* @date 2021-04-12 14:52:21.761
+**/
+public interface ReportDashboardService extends GaeaBaseService {
+
+ /***
+ * 查询详情
+ *
+ * @param reportCode
+ */
+ ReportDashboardObjectDto getDetail(String reportCode);
+
+ /***
+ * 保存大屏设计
+ *
+ * @param dto
+ */
+ void insertDashboard(ReportDashboardObjectDto dto);
+
+
+ /**
+ * 获取单个图表数据
+ * @param dto
+ * @return
+ */
+ Object getChartData(ChartDto dto);
+
+
+ /**
+ * 导出大屏,zip文件
+ * @param request
+ * @param response
+ * @param reportCode
+ * @return
+ */
+ ResponseEntity exportDashboard(HttpServletRequest request, HttpServletResponse response, String reportCode, Integer showDataSet);
+
+ /**
+ * 导入大屏zip
+ * @param file
+ * @param reportCode
+ * @return
+ */
+ void importDashboard(MultipartFile file, String reportCode);
+}
diff --git a/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/service/impl/BarChartServiceImpl.java b/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/service/impl/BarChartServiceImpl.java
new file mode 100644
index 0000000..7874721
--- /dev/null
+++ b/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/service/impl/BarChartServiceImpl.java
@@ -0,0 +1,79 @@
+package com.anjiplus.template.gaea.business.modules.dashboard.service.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.anjiplus.template.gaea.business.modules.dashboard.controller.dto.ChartDto;
+import com.anjiplus.template.gaea.business.modules.dashboard.service.ChartStrategy;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * 柱状体或者折线图
+ * Created by raodeming on 2021/4/26.
+ */
+@Component
+public class BarChartServiceImpl implements ChartStrategy {
+ /**
+ * 图表类型
+ *
+ * @return
+ */
+ @Override
+ public String type() {
+ return "widget-barchart|widget-linechart";
+ }
+
+ /**
+ * 针对每种图表类型做单独的数据转换解析
+ *
+ * @param dto
+ * @param data
+ * @return
+ */
+ @Override
+ public Object transform(ChartDto dto, List data) {
+// JSONObject json = new JSONObject();
+// List