diff --git a/.gitignore b/.gitignore
index ca48c75..47fca9c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,3 +10,4 @@
/novel-front/novel-front.iml
/novel-crawl/novel-crawl.iml
/novel-crawl/target
+/novel-admin/target
diff --git a/novel-admin/novel-admin.iml b/novel-admin/novel-admin.iml
new file mode 100644
index 0000000..9efc71a
--- /dev/null
+++ b/novel-admin/novel-admin.iml
@@ -0,0 +1,165 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/novel-admin/pom.xml b/novel-admin/pom.xml
new file mode 100644
index 0000000..6587b21
--- /dev/null
+++ b/novel-admin/pom.xml
@@ -0,0 +1,265 @@
+
+
+ 4.0.0
+
+ com.java2nb
+ novel-admin
+ 1.0.0
+ jar
+
+ novel-admin
+ 小说精品屋后台管理
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.0.1.RELEASE
+
+
+
+
+ UTF-8
+ UTF-8
+ 1.8
+ 1.7
+ 5.22.0
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.springframework.boot
+ spring-boot-starter-aop
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+
+ net.sourceforge.nekohtml
+ nekohtml
+
+
+
+ mysql
+ mysql-connector-java
+ 8.0.11
+
+
+ org.mybatis
+ mybatis
+ 3.4.4
+
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+ 1.1.1
+
+
+
+ com.alibaba
+ druid
+ 1.0.28
+
+
+
+ org.apache.commons
+ commons-lang3
+ 3.6
+
+
+ commons-configuration
+ commons-configuration
+ 1.10
+
+
+ commons-io
+ commons-io
+ 2.5
+
+
+
+ org.apache.shiro
+ shiro-core
+ 1.3.2
+
+
+ org.apache.shiro
+ shiro-spring
+ 1.3.2
+
+
+
+ org.apache.shiro
+ shiro-ehcache
+
+
+ net.sf.ehcache
+ ehcache-core
+
+
+ 1.4.0
+
+
+ com.github.theborakompanioni
+ thymeleaf-extras-shiro
+ 2.0.0
+
+
+
+ com.alibaba
+ fastjson
+ 1.2.31
+
+
+
+ org.apache.velocity
+ velocity
+ 1.7
+
+
+ org.springframework.boot
+ spring-boot-starter-cache
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ io.springfox
+ springfox-swagger2
+ 2.6.1
+
+
+ io.springfox
+ springfox-swagger-ui
+ 2.6.1
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
+
+
+ redis.clients
+ jedis
+ 2.9.0
+
+
+
+
+
+ org.projectlombok
+ lombok
+
+
+
+ org.apache.commons
+ commons-text
+ 1.4
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-cache
+
+
+ net.sf.ehcache
+ ehcache
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 1.8
+ 1.8
+ UTF-8
+
+
+
+
+
+
+ nexus_release
+ release
+ http://47.106.243.172:8081/nexus/content/repositories/releases/
+
+
+ nexus_snapshots
+ snapshots
+ http://47.106.243.172:8081/nexus/content/repositories/snapshots/
+
+
+
diff --git a/novel-admin/src/main/java/com/java2nb/AdminApplication.java b/novel-admin/src/main/java/com/java2nb/AdminApplication.java
new file mode 100644
index 0000000..5eb633f
--- /dev/null
+++ b/novel-admin/src/main/java/com/java2nb/AdminApplication.java
@@ -0,0 +1,25 @@
+package com.java2nb;
+
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.web.servlet.ServletComponentScan;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+//关闭SpringSecurity的功能
+@EnableAutoConfiguration(exclude = {
+ org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class
+})
+@EnableTransactionManagement
+@ServletComponentScan
+@MapperScan("com.java2nb.*.dao")
+@SpringBootApplication
+@EnableCaching
+public class AdminApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(AdminApplication.class, args);
+ }
+
+}
diff --git a/novel-admin/src/main/java/com/java2nb/common/annotation/Log.java b/novel-admin/src/main/java/com/java2nb/common/annotation/Log.java
new file mode 100644
index 0000000..b2985b1
--- /dev/null
+++ b/novel-admin/src/main/java/com/java2nb/common/annotation/Log.java
@@ -0,0 +1,12 @@
+package com.java2nb.common.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+import java.lang.annotation.RetentionPolicy;
+
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Log {
+ String value() default "";
+}
diff --git a/novel-admin/src/main/java/com/java2nb/common/aspect/LogAspect.java b/novel-admin/src/main/java/com/java2nb/common/aspect/LogAspect.java
new file mode 100644
index 0000000..6ea0ffc
--- /dev/null
+++ b/novel-admin/src/main/java/com/java2nb/common/aspect/LogAspect.java
@@ -0,0 +1,104 @@
+package com.java2nb.common.aspect;
+
+import java.lang.reflect.Method;
+import java.util.Date;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import javax.servlet.http.HttpServletRequest;
+
+import com.java2nb.common.service.LogService;
+import com.java2nb.system.domain.UserToken;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+import com.java2nb.common.annotation.Log;
+import com.java2nb.common.dao.LogDao;
+import com.java2nb.common.domain.LogDO;
+import com.java2nb.common.utils.HttpContextUtils;
+import com.java2nb.common.utils.IPUtils;
+import com.java2nb.common.utils.JSONUtils;
+import com.java2nb.common.utils.ShiroUtils;
+import com.java2nb.system.domain.UserDO;
+
+@Aspect
+@Component
+public class LogAspect {
+ private static final Logger logger = LoggerFactory.getLogger(LogAspect.class);
+
+ @Autowired
+ LogService logService;
+
+
+ @Pointcut("@annotation(com.java2nb.common.annotation.Log)")
+ public void logPointCut() {
+ }
+
+ @Around("logPointCut()")
+ public Object around(ProceedingJoinPoint point) throws Throwable {
+ long beginTime = System.currentTimeMillis();
+ // 执行方法
+ Object result = point.proceed();
+ // 执行时长(毫秒)
+ long time = System.currentTimeMillis() - beginTime;
+ //异步保存日志
+ saveLog(point, time);
+ return result;
+ }
+
+ void saveLog(ProceedingJoinPoint joinPoint, long time) throws InterruptedException {
+ MethodSignature signature = (MethodSignature) joinPoint.getSignature();
+ Method method = signature.getMethod();
+ LogDO sysLog = new LogDO();
+ Log syslog = method.getAnnotation(Log.class);
+ if (syslog != null) {
+ // 注解上的描述
+ sysLog.setOperation(syslog.value());
+ }
+ // 请求的方法名
+ String className = joinPoint.getTarget().getClass().getName();
+ String methodName = signature.getName();
+ sysLog.setMethod(className + "." + methodName + "()");
+ // 请求的参数
+ Object[] args = joinPoint.getArgs();
+ try {
+ String params = JSONUtils.beanToJson(args[0]).substring(0, 4999);
+ sysLog.setParams(params);
+ } catch (Exception e) {
+
+ }
+ // 获取request
+ HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
+ // 设置IP地址
+ sysLog.setIp(IPUtils.getIpAddr(request));
+ // 用户名
+ UserDO currUser = ShiroUtils.getUser();
+ if (null == currUser) {
+ if (null != sysLog.getParams()) {
+ sysLog.setUserId(-1L);
+ sysLog.setUsername(sysLog.getParams());
+ } else {
+ sysLog.setUserId(-1L);
+ sysLog.setUsername("获取用户信息为空");
+ }
+ } else {
+ sysLog.setUserId(ShiroUtils.getUserId());
+ sysLog.setUsername(ShiroUtils.getUser().getUsername());
+ }
+ sysLog.setTime((int) time);
+ // 系统当前时间
+ Date date = new Date();
+ sysLog.setGmtCreate(date);
+ // 保存系统日志
+ logService.save(sysLog);
+ }
+}
diff --git a/novel-admin/src/main/java/com/java2nb/common/aspect/WebLogAspect.java b/novel-admin/src/main/java/com/java2nb/common/aspect/WebLogAspect.java
new file mode 100644
index 0000000..889fdb6
--- /dev/null
+++ b/novel-admin/src/main/java/com/java2nb/common/aspect/WebLogAspect.java
@@ -0,0 +1,61 @@
+package com.java2nb.common.aspect;
+
+import com.java2nb.common.utils.HttpContextUtils;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.*;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+import sun.net.util.IPAddressUtil;
+
+import javax.servlet.http.HttpServletRequest;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+
+@Aspect
+@Component
+public class WebLogAspect {
+
+ private static final Logger logger = LoggerFactory.getLogger(WebLogAspect.class);
+
+ @Pointcut("execution( * com.java2nb..controller.*.*(..))")//两个..代表所有子目录,最后括号里的两个..代表所有参数
+ public void logPointCut() {
+ }
+
+
+ @Before("logPointCut()")
+ public void doBefore(JoinPoint joinPoint) throws Throwable {
+ // 接收到请求,记录请求内容
+ ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+ HttpServletRequest request = attributes.getRequest();
+
+ // 记录下请求内容
+ logger.info("请求地址 : " + request.getRequestURL().toString());
+ logger.info("HTTP METHOD : " + request.getMethod());
+ // 获取真实的ip地址
+ //logger.info("IP : " + IPAddressUtil.getClientIpAddress(request));
+ logger.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "."
+ + joinPoint.getSignature().getName());
+ logger.info("参数 : " + Arrays.toString(joinPoint.getArgs()));
+// loggger.info("参数 : " + joinPoint.getArgs());
+
+ }
+
+ @AfterReturning(returning = "ret", pointcut = "logPointCut()")// returning的值和doAfterReturning的参数名一致
+ public void doAfterReturning(Object ret) throws Throwable {
+ // 处理完请求,返回内容(返回值太复杂时,打印的是物理存储空间的地址)
+ logger.debug("返回值 : " + ret);
+ }
+
+ @Around("logPointCut()")
+ public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
+ long startTime = System.currentTimeMillis();
+ Object ob = pjp.proceed();// ob 为方法的返回值
+ logger.info("耗时 : " + (System.currentTimeMillis() - startTime));
+ return ob;
+ }
+}
diff --git a/novel-admin/src/main/java/com/java2nb/common/config/ApplicationContextRegister.java b/novel-admin/src/main/java/com/java2nb/common/config/ApplicationContextRegister.java
new file mode 100644
index 0000000..0b699fa
--- /dev/null
+++ b/novel-admin/src/main/java/com/java2nb/common/config/ApplicationContextRegister.java
@@ -0,0 +1,50 @@
+package com.java2nb.common.config;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+/**
+ *
+ * @author xiongxy
+ * @date 2019-09-25 15:09:21
+ *
+ * Email 122741482@qq.com
+ *
+ * Describe:
+ */
+@Component
+public class ApplicationContextRegister implements ApplicationContextAware {
+ private static Logger logger = LoggerFactory.getLogger(ApplicationContextRegister.class);
+ private static ApplicationContext APPLICATION_CONTEXT;
+ /**
+ * 设置spring上下文
+ * @param applicationContext spring上下文
+ * @throws BeansException
+ * */
+ @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+ logger.debug("ApplicationContext registed-->{}", applicationContext);
+ APPLICATION_CONTEXT = applicationContext;
+ }
+
+ /**
+ * 获取容器
+ * @return
+ */
+ public static ApplicationContext getApplicationContext() {
+ return APPLICATION_CONTEXT;
+ }
+
+ /**
+ * 获取容器对象
+ * @param type
+ * @param
+ * @return
+ */
+ public static T getBean(Class type) {
+ return APPLICATION_CONTEXT.getBean(type);
+ }
+}
\ No newline at end of file
diff --git a/novel-admin/src/main/java/com/java2nb/common/config/BDSessionListener.java b/novel-admin/src/main/java/com/java2nb/common/config/BDSessionListener.java
new file mode 100644
index 0000000..2351af7
--- /dev/null
+++ b/novel-admin/src/main/java/com/java2nb/common/config/BDSessionListener.java
@@ -0,0 +1,32 @@
+package com.java2nb.common.config;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.shiro.session.Session;
+import org.apache.shiro.session.SessionListener;
+
+public class BDSessionListener implements SessionListener {
+
+ private final AtomicInteger sessionCount = new AtomicInteger(0);
+
+ @Override
+ public void onStart(Session session) {
+ sessionCount.incrementAndGet();
+ }
+
+ @Override
+ public void onStop(Session session) {
+ sessionCount.decrementAndGet();
+ }
+
+ @Override
+ public void onExpiration(Session session) {
+ sessionCount.decrementAndGet();
+
+ }
+
+ public int getSessionCount() {
+ return sessionCount.get();
+ }
+
+}
diff --git a/novel-admin/src/main/java/com/java2nb/common/config/Constant.java b/novel-admin/src/main/java/com/java2nb/common/config/Constant.java
new file mode 100644
index 0000000..fe8a3bc
--- /dev/null
+++ b/novel-admin/src/main/java/com/java2nb/common/config/Constant.java
@@ -0,0 +1,24 @@
+package com.java2nb.common.config;
+
+public class Constant {
+ //演示系统账户
+ public static String DEMO_ACCOUNT = "test";
+ //自动去除表前缀
+ public static String AUTO_REOMVE_PRE = "true";
+ //停止计划任务
+ public static String STATUS_RUNNING_STOP = "stop";
+ //开启计划任务
+ public static String STATUS_RUNNING_START = "start";
+ //通知公告阅读状态-未读
+ public static String OA_NOTIFY_READ_NO = "0";
+ //通知公告阅读状态-已读
+ public static int OA_NOTIFY_READ_YES = 1;
+ //部门根节点id
+ public static Long DEPT_ROOT_ID = 0l;
+ //缓存方式
+ public static String CACHE_TYPE_REDIS ="redis";
+
+ public static String LOG_ERROR = "error";
+
+
+}
diff --git a/novel-admin/src/main/java/com/java2nb/common/config/DateConverConfig.java b/novel-admin/src/main/java/com/java2nb/common/config/DateConverConfig.java
new file mode 100644
index 0000000..820b645
--- /dev/null
+++ b/novel-admin/src/main/java/com/java2nb/common/config/DateConverConfig.java
@@ -0,0 +1,40 @@
+package com.java2nb.common.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.convert.converter.Converter;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.zip.DataFormatException;
+
+/**
+ * @author xiongxy
+ * @date 2019-09-25 15:09:21
+ */
+@Configuration
+public class DateConverConfig {
+ @Bean
+ public Converter stringDateConvert() {
+ return new Converter() {
+ @Override
+ public Date convert(String source) {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ Date date = null;
+ try {
+ date = sdf.parse((String) source);
+ } catch (Exception e) {
+ SimpleDateFormat sdfday = new SimpleDateFormat("yyyy-MM-dd");
+ try {
+ date = sdfday.parse((String) source);
+ } catch (ParseException e1) {
+ e1.printStackTrace();
+ }
+ }
+ return date;
+ }
+ };
+ }
+
+}
diff --git a/novel-admin/src/main/java/com/java2nb/common/config/DruidDBConfig.java b/novel-admin/src/main/java/com/java2nb/common/config/DruidDBConfig.java
new file mode 100644
index 0000000..92a2383
--- /dev/null
+++ b/novel-admin/src/main/java/com/java2nb/common/config/DruidDBConfig.java
@@ -0,0 +1,132 @@
+package com.java2nb.common.config;
+import com.alibaba.druid.pool.DruidDataSource;
+import com.alibaba.druid.support.http.StatViewServlet;
+import com.alibaba.druid.support.http.WebStatFilter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.boot.web.servlet.ServletRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+
+import javax.sql.DataSource;
+import java.sql.SQLException;
+
+/**
+ * Created by PrimaryKey on 17/2/4.
+ */
+@SuppressWarnings("AlibabaRemoveCommentedCode")
+@Configuration
+public class DruidDBConfig {
+ private Logger logger = LoggerFactory.getLogger(DruidDBConfig.class);
+ @Value("${spring.datasource.url}")
+ private String dbUrl;
+
+ @Value("${spring.datasource.username}")
+ private String username;
+
+ @Value("${spring.datasource.password}")
+ private String password;
+
+ @Value("${spring.datasource.driverClassName}")
+ private String driverClassName;
+
+ @Value("${spring.datasource.initialSize}")
+ private int initialSize;
+
+ @Value("${spring.datasource.minIdle}")
+ private int minIdle;
+
+ @Value("${spring.datasource.maxActive}")
+ private int maxActive;
+
+ @Value("${spring.datasource.maxWait}")
+ private int maxWait;
+
+ @Value("${spring.datasource.timeBetweenEvictionRunsMillis}")
+ private int timeBetweenEvictionRunsMillis;
+
+ @Value("${spring.datasource.minEvictableIdleTimeMillis}")
+ private int minEvictableIdleTimeMillis;
+
+ @Value("${spring.datasource.validationQuery}")
+ private String validationQuery;
+
+ @Value("${spring.datasource.testWhileIdle}")
+ private boolean testWhileIdle;
+
+ @Value("${spring.datasource.testOnBorrow}")
+ private boolean testOnBorrow;
+
+ @Value("${spring.datasource.testOnReturn}")
+ private boolean testOnReturn;
+
+ @Value("${spring.datasource.poolPreparedStatements}")
+ private boolean poolPreparedStatements;
+
+ @Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}")
+ private int maxPoolPreparedStatementPerConnectionSize;
+
+ @Value("${spring.datasource.filters}")
+ private String filters;
+
+ @Value("{spring.datasource.connectionProperties}")
+ private String connectionProperties;
+
+ @Bean(initMethod = "init", destroyMethod = "close") //声明其为Bean实例
+ @Primary //在同样的DataSource中,首先使用被标注的DataSource
+ public DataSource dataSource() {
+ DruidDataSource datasource = new DruidDataSource();
+
+ datasource.setUrl(this.dbUrl);
+ datasource.setUsername(username);
+ datasource.setPassword(password);
+ datasource.setDriverClassName(driverClassName);
+
+ //configuration
+ datasource.setInitialSize(initialSize);
+ datasource.setMinIdle(minIdle);
+ datasource.setMaxActive(maxActive);
+ datasource.setMaxWait(maxWait);
+ datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
+ datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
+ datasource.setValidationQuery(validationQuery);
+ datasource.setTestWhileIdle(testWhileIdle);
+ datasource.setTestOnBorrow(testOnBorrow);
+ datasource.setTestOnReturn(testOnReturn);
+ datasource.setPoolPreparedStatements(poolPreparedStatements);
+ datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
+ try {
+ datasource.setFilters(filters);
+ } catch (SQLException e) {
+ logger.error("druid configuration initialization filter", e);
+ }
+ datasource.setConnectionProperties(connectionProperties);
+
+ return datasource;
+ }
+
+ @Bean
+ public ServletRegistrationBean druidServlet() {
+ ServletRegistrationBean reg = new ServletRegistrationBean();
+ reg.setServlet(new StatViewServlet());
+ reg.addUrlMappings("/druid/*");
+ reg.addInitParameter("allow", ""); //白名单
+ return reg;
+ }
+
+ @Bean public FilterRegistrationBean filterRegistrationBean() {
+ FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
+ filterRegistrationBean.setFilter(new WebStatFilter());
+ filterRegistrationBean.addUrlPatterns("/*");
+ filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
+ filterRegistrationBean.addInitParameter("profileEnable", "true");
+ filterRegistrationBean.addInitParameter("principalCookieName","USER_COOKIE");
+ filterRegistrationBean.addInitParameter("principalSessionName","USER_SESSION");
+ filterRegistrationBean.addInitParameter("DruidWebStatFilter","/*");
+ return filterRegistrationBean;
+ }
+}
+
diff --git a/novel-admin/src/main/java/com/java2nb/common/config/JnConfig.java b/novel-admin/src/main/java/com/java2nb/common/config/JnConfig.java
new file mode 100644
index 0000000..797ec30
--- /dev/null
+++ b/novel-admin/src/main/java/com/java2nb/common/config/JnConfig.java
@@ -0,0 +1,39 @@
+package com.java2nb.common.config;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Component
+@ConfigurationProperties(prefix="java2nb")
+public class JnConfig {
+ //上传路径
+ private String uploadPath;
+
+ private String username;
+
+ private String password;
+
+ public String getUploadPath() {
+ return uploadPath;
+ }
+
+ public void setUploadPath(String uploadPath) {
+ this.uploadPath = uploadPath;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+}
diff --git a/novel-admin/src/main/java/com/java2nb/common/config/RedisConfig.java b/novel-admin/src/main/java/com/java2nb/common/config/RedisConfig.java
new file mode 100644
index 0000000..c5a0c10
--- /dev/null
+++ b/novel-admin/src/main/java/com/java2nb/common/config/RedisConfig.java
@@ -0,0 +1,82 @@
+package com.java2nb.common.config;
+
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.PropertyAccessor;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+@Configuration
+public class RedisConfig {
+
+
+ @Bean
+ @SuppressWarnings("all")
+ public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
+
+
+ RedisTemplate template = new RedisTemplate();
+
+
+ template.setConnectionFactory(factory);
+
+
+ Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
+
+
+ ObjectMapper om = new ObjectMapper();
+
+
+ om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
+
+
+ om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
+
+
+ jackson2JsonRedisSerializer.setObjectMapper(om);
+
+
+ StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
+
+
+ // key采用String的序列化方式
+
+
+ template.setKeySerializer(stringRedisSerializer);
+
+
+ // hash的key也采用String的序列化方式
+
+
+ template.setHashKeySerializer(stringRedisSerializer);
+
+
+ // value序列化方式采用jackson
+
+
+ template.setValueSerializer(jackson2JsonRedisSerializer);
+
+
+ // hash的value序列化方式采用jackson
+
+
+ template.setHashValueSerializer(jackson2JsonRedisSerializer);
+
+
+ template.afterPropertiesSet();
+
+
+ return template;
+
+
+ }
+
+
+}
+
+
diff --git a/novel-admin/src/main/java/com/java2nb/common/config/SecuityConfig.java b/novel-admin/src/main/java/com/java2nb/common/config/SecuityConfig.java
new file mode 100644
index 0000000..fbed75a
--- /dev/null
+++ b/novel-admin/src/main/java/com/java2nb/common/config/SecuityConfig.java
@@ -0,0 +1,13 @@
+package com.java2nb.common.config;
+
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.context.annotation.Configuration;
+
+@EnableAutoConfiguration(exclude = {
+ org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class
+})
+@Configuration
+public class SecuityConfig {
+
+
+}
diff --git a/novel-admin/src/main/java/com/java2nb/common/config/ShiroConfig.java b/novel-admin/src/main/java/com/java2nb/common/config/ShiroConfig.java
new file mode 100644
index 0000000..bc2a8f7
--- /dev/null
+++ b/novel-admin/src/main/java/com/java2nb/common/config/ShiroConfig.java
@@ -0,0 +1,203 @@
+package com.java2nb.common.config;
+
+import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
+import com.java2nb.common.redis.shiro.RedisCacheManager;
+import com.java2nb.common.redis.shiro.RedisManager;
+import com.java2nb.common.redis.shiro.RedisSessionDAO;
+import com.java2nb.system.shiro.UserRealm;
+import net.sf.ehcache.CacheManager;
+import org.apache.shiro.cache.ehcache.EhCacheManager;
+import org.apache.shiro.mgt.SecurityManager;
+import org.apache.shiro.session.SessionListener;
+import org.apache.shiro.session.mgt.eis.MemorySessionDAO;
+import org.apache.shiro.session.mgt.eis.SessionDAO;
+import org.apache.shiro.spring.LifecycleBeanPostProcessor;
+import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
+import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
+import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
+import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+
+/**
+ * @author xiongxy
+ */
+@Configuration
+public class ShiroConfig {
+ @Value("${spring.redis.host}")
+ private String host;
+ @Value("${spring.redis.password}")
+ private String password;
+ @Value("${spring.redis.port}")
+ private int port;
+ @Value("${spring.redis.timeout}")
+ private int timeout;
+
+ @Value("${spring.cache.type}")
+ private String cacheType ;
+
+ @Value("${server.session-timeout}")
+ private int tomcatTimeout;
+
+ @Bean
+ public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
+ return new LifecycleBeanPostProcessor();
+ }
+
+ /**
+ * ShiroDialect,为了在thymeleaf里使用shiro的标签的bean
+ *
+ * @return
+ */
+ @Bean
+ public ShiroDialect shiroDialect() {
+ return new ShiroDialect();
+ }
+
+ @Bean
+ ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
+ ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
+ shiroFilterFactoryBean.setSecurityManager(securityManager);
+ shiroFilterFactoryBean.setLoginUrl("/login");
+ shiroFilterFactoryBean.setSuccessUrl("/index");
+ shiroFilterFactoryBean.setUnauthorizedUrl("/403");
+ LinkedHashMap filterChainDefinitionMap = new LinkedHashMap<>();
+ filterChainDefinitionMap.put("/login","anon");
+ filterChainDefinitionMap.put("/getVerify","anon");
+ filterChainDefinitionMap.put("/css/**", "anon");
+ filterChainDefinitionMap.put("/js/**", "anon");
+ filterChainDefinitionMap.put("/fonts/**", "anon");
+ filterChainDefinitionMap.put("/img/**", "anon");
+ filterChainDefinitionMap.put("/docs/**", "anon");
+ filterChainDefinitionMap.put("/layuimini/**", "anon");
+ filterChainDefinitionMap.put("/druid/**", "anon");
+ filterChainDefinitionMap.put("/upload/**", "anon");
+ filterChainDefinitionMap.put("/files/**", "anon");
+ filterChainDefinitionMap.put("/logout", "logout");
+ filterChainDefinitionMap.put("/blog", "anon");
+ filterChainDefinitionMap.put("/blog/open/**", "anon");
+ filterChainDefinitionMap.put("/**", "authc");
+ shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
+ return shiroFilterFactoryBean;
+ }
+
+
+ @Bean
+ public SecurityManager securityManager() {
+ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
+ //设置realm.
+ securityManager.setRealm(userRealm());
+ // 自定义缓存实现 使用redis
+ if (Constant.CACHE_TYPE_REDIS.equals(cacheType)) {
+ securityManager.setCacheManager(rediscacheManager());
+ } else {
+ securityManager.setCacheManager(ehCacheManager());
+ }
+ securityManager.setSessionManager(sessionManager());
+ return securityManager;
+ }
+
+ @Bean
+ UserRealm userRealm() {
+ UserRealm userRealm = new UserRealm();
+ return userRealm;
+ }
+
+ /**
+ * 开启shiro aop注解支持.
+ * 使用代理方式;所以需要开启代码支持;
+ *
+ * @param securityManager
+ * @return
+ */
+ @Bean
+ public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
+ AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
+ authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
+ return authorizationAttributeSourceAdvisor;
+ }
+
+ /**
+ * 配置shiro redisManager
+ *
+ * @return
+ */
+ @Bean
+ public RedisManager redisManager() {
+ RedisManager redisManager = new RedisManager();
+ redisManager.setHost(host);
+ redisManager.setPort(port);
+ redisManager.setExpire(1800);// 配置缓存过期时间
+ //redisManager.setTimeout(1800);
+ redisManager.setPassword(password);
+ return redisManager;
+ }
+
+ /**
+ * cacheManager 缓存 redis实现
+ * 使用的是shiro-redis开源插件
+ *
+ * @return
+ */
+ public RedisCacheManager rediscacheManager() {
+ RedisCacheManager redisCacheManager = new RedisCacheManager();
+ redisCacheManager.setRedisManager(redisManager());
+ return redisCacheManager;
+ }
+
+
+ /**
+ * RedisSessionDAO shiro sessionDao层的实现 通过redis
+ * 使用的是shiro-redis开源插件
+ */
+ @Bean
+ public RedisSessionDAO redisSessionDAO() {
+ RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
+ redisSessionDAO.setRedisManager(redisManager());
+ return redisSessionDAO;
+ }
+
+ @Bean
+ public SessionDAO sessionDAO() {
+ if (Constant.CACHE_TYPE_REDIS.equals(cacheType)) {
+ return redisSessionDAO();
+ } else {
+ return new MemorySessionDAO();
+ }
+ }
+
+ /**
+ * shiro session的管理
+ */
+ @Bean
+ public DefaultWebSessionManager sessionManager() {
+ DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
+ sessionManager.setGlobalSessionTimeout(tomcatTimeout * 1000);
+ sessionManager.setSessionDAO(sessionDAO());
+ Collection listeners = new ArrayList();
+ listeners.add(new BDSessionListener());
+ sessionManager.setSessionListeners(listeners);
+ return sessionManager;
+ }
+
+ @Bean
+ public EhCacheManager ehCacheManager() {
+ EhCacheManager em = new EhCacheManager();
+ em.setCacheManager(cacheManager());
+ return em;
+ }
+
+ @Bean("cacheManager2")
+ CacheManager cacheManager(){
+ return CacheManager.create();
+ }
+
+
+
+
+}
diff --git a/novel-admin/src/main/java/com/java2nb/common/config/SpringAsyncConfig.java b/novel-admin/src/main/java/com/java2nb/common/config/SpringAsyncConfig.java
new file mode 100644
index 0000000..2f883b0
--- /dev/null
+++ b/novel-admin/src/main/java/com/java2nb/common/config/SpringAsyncConfig.java
@@ -0,0 +1,23 @@
+package com.java2nb.common.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.task.AsyncTaskExecutor;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+import java.util.concurrent.RejectedExecutionHandler;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+@Configuration
+@EnableAsync
+public class SpringAsyncConfig {
+// @Bean
+// public AsyncTaskExecutor taskExecutor() {
+// ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+// executor.setMaxPoolSize(10);
+// return executor;
+// }
+}
\ No newline at end of file
diff --git a/novel-admin/src/main/java/com/java2nb/common/config/Swagger2Config.java b/novel-admin/src/main/java/com/java2nb/common/config/Swagger2Config.java
new file mode 100644
index 0000000..90b912c
--- /dev/null
+++ b/novel-admin/src/main/java/com/java2nb/common/config/Swagger2Config.java
@@ -0,0 +1,48 @@
+package com.java2nb.common.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.Contact;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+/**
+ * ${DESCRIPTION}
+ *
+ * @author xiongxy
+ * @create 2019-11-02 23:53
+ */
+@EnableSwagger2
+@Configuration
+public class Swagger2Config {
+
+ @Bean
+ public Docket createRestApi() {
+ return new Docket(DocumentationType.SWAGGER_2)
+ .apiInfo(apiInfo())
+ .select()
+ //为当前包路径
+ .apis(RequestHandlerSelectors.any())
+ .paths(PathSelectors.any())
+ .build();
+ }
+
+ //构建 api文档的详细信息函数
+ private ApiInfo apiInfo() {
+ return new ApiInfoBuilder()
+ //页面标题
+ .title("功能测试")
+ //创建人
+ .contact(new Contact("xiongxy", "1179705413@qq.com", "1179705413@qq.com"))
+ //版本号
+ .version("1.0")
+ //描述
+ .description("API 描述")
+ .build();
+ }
+}
\ No newline at end of file
diff --git a/novel-admin/src/main/java/com/java2nb/common/config/WebConfigurer.java b/novel-admin/src/main/java/com/java2nb/common/config/WebConfigurer.java
new file mode 100644
index 0000000..6e65e53
--- /dev/null
+++ b/novel-admin/src/main/java/com/java2nb/common/config/WebConfigurer.java
@@ -0,0 +1,17 @@
+package com.java2nb.common.config;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+
+@Component
+class WebConfigurer extends WebMvcConfigurerAdapter {
+ @Autowired
+ JnConfig jnConfig;
+ @Override
+ public void addResourceHandlers(ResourceHandlerRegistry registry) {
+ registry.addResourceHandler("/files/**").addResourceLocations("file:///"+ jnConfig.getUploadPath());
+ }
+
+}
\ No newline at end of file
diff --git a/novel-admin/src/main/java/com/java2nb/common/controller/BaseController.java b/novel-admin/src/main/java/com/java2nb/common/controller/BaseController.java
new file mode 100644
index 0000000..59b9129
--- /dev/null
+++ b/novel-admin/src/main/java/com/java2nb/common/controller/BaseController.java
@@ -0,0 +1,21 @@
+package com.java2nb.common.controller;
+
+import com.java2nb.system.domain.UserToken;
+import org.springframework.stereotype.Controller;
+import com.java2nb.common.utils.ShiroUtils;
+import com.java2nb.system.domain.UserDO;
+
+@Controller
+public class BaseController {
+ public UserDO getUser() {
+ return ShiroUtils.getUser();
+ }
+
+ public Long getUserId() {
+ return getUser().getUserId();
+ }
+
+ public String getUsername() {
+ return getUser().getUsername();
+ }
+}
\ No newline at end of file
diff --git a/novel-admin/src/main/java/com/java2nb/common/controller/DictController.java b/novel-admin/src/main/java/com/java2nb/common/controller/DictController.java
new file mode 100644
index 0000000..3a91fac
--- /dev/null
+++ b/novel-admin/src/main/java/com/java2nb/common/controller/DictController.java
@@ -0,0 +1,148 @@
+package com.java2nb.common.controller;
+
+import com.java2nb.common.config.Constant;
+import com.java2nb.common.domain.DictDO;
+import com.java2nb.common.service.DictService;
+import com.java2nb.common.utils.PageBean;
+import com.java2nb.common.utils.Query;
+import com.java2nb.common.utils.R;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 字典表
+ * @author xiongxy
+ * @email 1179705413@qq.com
+ * @date 2019-09-29 18:28:07
+ */
+
+@Controller
+@RequestMapping("/common/dict")
+public class DictController extends BaseController {
+ @Autowired
+ private DictService dictService;
+
+ @GetMapping()
+ @RequiresPermissions("common:dict:dict")
+ String dict() {
+ return "common/dict/dict";
+ }
+
+ @ResponseBody
+ @GetMapping("/list")
+ @RequiresPermissions("common:dict:dict")
+ public PageBean list(@RequestParam Map params) {
+ // 查询列表数据
+ Query query = new Query(params);
+ List dictList = dictService.list(query);
+ int total = dictService.count(query);
+ PageBean pageBean = new PageBean(dictList, total);
+ return pageBean;
+ }
+
+ @GetMapping("/add")
+ @RequiresPermissions("common:dict:add")
+ String add() {
+ return "common/dict/add";
+ }
+
+ @GetMapping("/edit/{id}")
+ @RequiresPermissions("common:dict:edit")
+ String edit(@PathVariable("id") Long id, Model model) {
+ DictDO dict = dictService.get(id);
+ model.addAttribute("dict", dict);
+ return "common/dict/edit";
+ }
+
+ /**
+ * 保存
+ */
+ @ResponseBody
+ @PostMapping("/save")
+ @RequiresPermissions("common:dict:add")
+ public R save(DictDO dict) {
+ if (Constant.DEMO_ACCOUNT.equals(getUsername())) {
+ return R.error(1, "演示系统不允许修改,完整体验请部署程序");
+ }
+ if (dictService.save(dict) > 0) {
+ return R.ok();
+ }
+ return R.error();
+ }
+
+ /**
+ * 修改
+ */
+ @ResponseBody
+ @RequestMapping("/update")
+ @RequiresPermissions("common:dict:edit")
+ public R update(DictDO dict) {
+ if (Constant.DEMO_ACCOUNT.equals(getUsername())) {
+ return R.error(1, "演示系统不允许修改,完整体验请部署程序");
+ }
+ dictService.update(dict);
+ return R.ok();
+ }
+
+ /**
+ * 删除
+ */
+ @PostMapping("/remove")
+ @ResponseBody
+ @RequiresPermissions("common:dict:remove")
+ public R remove(Long id) {
+ if (Constant.DEMO_ACCOUNT.equals(getUsername())) {
+ return R.error(1, "演示系统不允许修改,完整体验请部署程序");
+ }
+ if (dictService.remove(id) > 0) {
+ return R.ok();
+ }
+ return R.error();
+ }
+
+ /**
+ * 删除
+ */
+ @PostMapping("/batchRemove")
+ @ResponseBody
+ @RequiresPermissions("common:dict:batchRemove")
+ public R remove(@RequestParam("ids[]") Long[] ids) {
+ if (Constant.DEMO_ACCOUNT.equals(getUsername())) {
+ return R.error(1, "演示系统不允许修改,完整体验请部署程序");
+ }
+ dictService.batchRemove(ids);
+ return R.ok();
+ }
+
+ @GetMapping("/type")
+ @ResponseBody
+ public List listType() {
+ return dictService.listType();
+ };
+
+ // 类别已经指定增加
+ @GetMapping("/add/{type}/{description}")
+ @RequiresPermissions("common:dict:add")
+ String addD(Model model, @PathVariable("type") String type, @PathVariable("description") String description) {
+ model.addAttribute("type", type);
+ model.addAttribute("description", description);
+ return "common/dict/add";
+ }
+
+ @ResponseBody
+ @GetMapping("/list/{type}")
+ public List listByType(@PathVariable("type") String type) {
+ // 查询列表数据
+ Map map = new HashMap<>(16);
+ map.put("type", type);
+ List dictList = dictService.list(map);
+ return dictList;
+ }
+}
diff --git a/novel-admin/src/main/java/com/java2nb/common/controller/FileController.java b/novel-admin/src/main/java/com/java2nb/common/controller/FileController.java
new file mode 100644
index 0000000..363dfe7
--- /dev/null
+++ b/novel-admin/src/main/java/com/java2nb/common/controller/FileController.java
@@ -0,0 +1,196 @@
+package com.java2nb.common.controller;
+
+import com.java2nb.common.config.JnConfig;
+import com.java2nb.common.domain.FileDO;
+import com.java2nb.common.service.FileService;
+import com.java2nb.common.utils.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.*;
+import java.net.URLEncoder;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 文件上传
+ *
+ * @author xiongxy
+ * @email 1179705413@qq.com
+ * @date 2019-09-19 16:02:20
+ */
+@Controller
+@RequestMapping("/common/sysFile")
+public class FileController extends BaseController {
+
+ @Autowired
+ private FileService sysFileService;
+
+ @Autowired
+ private JnConfig jnConfig;
+
+ @GetMapping()
+ @RequiresPermissions("common:sysFile:sysFile")
+ String sysFile(Model model) {
+ Map params = new HashMap<>(16);
+ return "common/file/file";
+ }
+
+ @ResponseBody
+ @GetMapping("/list")
+ @RequiresPermissions("common:sysFile:sysFile")
+ public PageBean list(@RequestParam Map params) {
+ // 查询列表数据
+ Query query = new Query(params);
+ List sysFileList = sysFileService.list(query);
+ int total = sysFileService.count(query);
+ PageBean pageBean = new PageBean(sysFileList, total);
+ return pageBean;
+ }
+
+ @GetMapping("/add")
+ // @RequiresPermissions("common:bComments")
+ String add() {
+ return "common/sysFile/add";
+ }
+
+ @GetMapping("/edit")
+ // @RequiresPermissions("common:bComments")
+ String edit(Long id, Model model) {
+ FileDO sysFile = sysFileService.get(id);
+ model.addAttribute("sysFile", sysFile);
+ return "common/sysFile/edit";
+ }
+
+ /**
+ * 信息
+ */
+ @RequestMapping("/info/{id}")
+ @RequiresPermissions("common:info")
+ public R info(@PathVariable("id") Long id) {
+ FileDO sysFile = sysFileService.get(id);
+ return R.ok().put("sysFile", sysFile);
+ }
+
+ /**
+ * 保存
+ */
+ @ResponseBody
+ @PostMapping("/save")
+ @RequiresPermissions("common:save")
+ public R save(FileDO sysFile) {
+ if (sysFileService.save(sysFile) > 0) {
+ return R.ok();
+ }
+ return R.error();
+ }
+
+ /**
+ * 修改
+ */
+ @RequestMapping("/update")
+ @RequiresPermissions("common:update")
+ public R update(@RequestBody FileDO sysFile) {
+ sysFileService.update(sysFile);
+
+ return R.ok();
+ }
+
+ /**
+ * 删除
+ */
+ @PostMapping("/remove")
+ @ResponseBody
+ // @RequiresPermissions("common:remove")
+ public R remove(Long id, HttpServletRequest request) {
+ if ("test".equals(getUsername())) {
+ return R.error(1, "演示系统不允许修改,完整体验请部署程序");
+ }
+ String fileName = jnConfig.getUploadPath() + sysFileService.get(id).getUrl().replace("/files/", "");
+ if (sysFileService.remove(id) > 0) {
+ boolean b = FileUtil.deleteFile(fileName);
+ if (!b) {
+ return R.error("数据库记录删除成功,文件删除失败");
+ }
+ return R.ok();
+ } else {
+ return R.error();
+ }
+ }
+
+ /**
+ * 删除
+ */
+ @PostMapping("/batchRemove")
+ @ResponseBody
+ @RequiresPermissions("common:remove")
+ public R remove(@RequestParam("ids[]") Long[] ids) {
+ if ("test".equals(getUsername())) {
+ return R.error(1, "演示系统不允许修改,完整体验请部署程序");
+ }
+ sysFileService.batchRemove(ids);
+ return R.ok();
+ }
+
+ @ResponseBody
+ @PostMapping("/upload")
+ R upload(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
+ if ("test".equals(getUsername())) {
+ return R.error(1, "演示系统不允许修改,完整体验请部署程序");
+ }
+ Date date = new Date();
+ String year = DateUtils.format(date,DateUtils.YEAR_PATTERN);
+ String month = DateUtils.format(date,DateUtils.MONTH_PATTERN);
+ String day = DateUtils.format(date,DateUtils.DAY_PATTERN);
+
+ String fileName = file.getOriginalFilename();
+ String fileDir = year+"/"+month+"/"+day + "/";
+ fileName = FileUtil.renameToUUID(fileName);
+ FileDO sysFile = new FileDO(FileType.fileType(fileName), "/files/" + fileDir + fileName, date);
+ try {
+ FileUtil.uploadFile(file.getBytes(), jnConfig.getUploadPath()+fileDir, fileName);
+ } catch (Exception e) {
+ return R.error();
+ }
+
+ if (sysFileService.save(sysFile) > 0) {
+ return R.ok().put("fileName",sysFile.getUrl());
+ }
+ return R.error();
+ }
+
+ /**
+ * 文件下载
+ */
+ @RequestMapping(value = "/download")
+ public void fileDownload(String filePath,String fileName, HttpServletResponse resp) throws Exception {
+ String realFilePath = jnConfig.getUploadPath() + filePath;
+ InputStream in = new FileInputStream(realFilePath);
+ //设置响应头,对文件进行url编码
+ fileName = URLEncoder.encode(fileName, "UTF-8");
+ resp.setHeader("Content-Disposition", "attachment;filename=" + fileName);
+
+ resp.setContentLength(in.available());
+
+ OutputStream out = resp.getOutputStream();
+ byte[] b = new byte[1024];
+ int len = 0;
+ while ((len = in.read(b)) != -1) {
+ out.write(b, 0, len);
+ }
+ out.flush();
+ out.close();
+ in.close();
+ }
+
+
+}
diff --git a/novel-admin/src/main/java/com/java2nb/common/controller/GeneratorController.java b/novel-admin/src/main/java/com/java2nb/common/controller/GeneratorController.java
new file mode 100644
index 0000000..9df2efd
--- /dev/null
+++ b/novel-admin/src/main/java/com/java2nb/common/controller/GeneratorController.java
@@ -0,0 +1,157 @@
+package com.java2nb.common.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.java2nb.common.domain.GenColumnsDO;
+import com.java2nb.common.service.GeneratorService;
+import com.java2nb.common.utils.GenUtils;
+import com.java2nb.common.utils.PageBean;
+import com.java2nb.common.utils.R;
+import io.swagger.annotations.ApiOperation;
+import lombok.SneakyThrows;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.apache.commons.io.IOUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@RequestMapping("/common/generator")
+@Controller
+public class GeneratorController {
+ String prefix = "common/generator";
+ @Autowired
+ GeneratorService generatorService;
+
+ @Autowired
+ private ObjectMapper objectMapper;
+
+ @GetMapping()
+ String generator() {
+ return prefix + "/list";
+ }
+
+ @ResponseBody
+ @GetMapping("/list")
+ List