diff --git a/renren-admin/pom.xml b/renren-admin/pom.xml
index b1403129..90d7eda3 100644
--- a/renren-admin/pom.xml
+++ b/renren-admin/pom.xml
@@ -90,11 +90,38 @@
+
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ provided
+ true
+
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jsr310
+ 2.9.2
+
+
+ org.mybatis
+ mybatis-typehandlers-jsr310
+ 1.0.2
+
+
${project.artifactId}
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ true
+
+
org.springframework.boot
spring-boot-maven-plugin
diff --git a/renren-admin/src/main/java/io/renren/common/config/JacksonConfig.java b/renren-admin/src/main/java/io/renren/common/config/JacksonConfig.java
new file mode 100644
index 00000000..74c087bf
--- /dev/null
+++ b/renren-admin/src/main/java/io/renren/common/config/JacksonConfig.java
@@ -0,0 +1,34 @@
+package io.renren.common.config;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
+
+/**
+ * @author 李帅超
+ * @Description: SpringMVC整合LocalDateTime用到jackson
+ * @date 2018-03-06 11:01
+ */
+@Configuration
+public class JacksonConfig {
+
+ @Bean(name = "mapperObject")
+ public ObjectMapper getObjectMapper() {
+ ObjectMapper om = new ObjectMapper();
+ JavaTimeModule javaTimeModule = new JavaTimeModule();
+ javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+ javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
+ javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
+ om.registerModule(javaTimeModule);
+ return om;
+ }
+}
diff --git a/renren-admin/src/main/java/io/renren/common/config/ShiroConfig.java b/renren-admin/src/main/java/io/renren/common/config/ShiroConfig.java
index 5ba87538..e8b62aa7 100644
--- a/renren-admin/src/main/java/io/renren/common/config/ShiroConfig.java
+++ b/renren-admin/src/main/java/io/renren/common/config/ShiroConfig.java
@@ -77,6 +77,7 @@ public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
shiroFilter.setUnauthorizedUrl("/");
Map filterMap = new LinkedHashMap<>();
+ filterMap.put("/sys/captcha", "anon");
filterMap.put("/swagger/**", "anon");
filterMap.put("/v2/api-docs", "anon");
filterMap.put("/swagger-ui.html", "anon");
diff --git a/renren-admin/src/main/java/io/renren/common/utils/Constant.java b/renren-admin/src/main/java/io/renren/common/utils/Constant.java
index 12bf3322..2c8dc5c1 100644
--- a/renren-admin/src/main/java/io/renren/common/utils/Constant.java
+++ b/renren-admin/src/main/java/io/renren/common/utils/Constant.java
@@ -85,6 +85,10 @@ public int getValue() {
* 云服务商
*/
public enum CloudService {
+ /**
+ * 服务器
+ */
+ LOCAL(0),
/**
* 七牛云
*/
diff --git a/renren-admin/src/main/java/io/renren/modules/oss/cloud/CloudStorageConfig.java b/renren-admin/src/main/java/io/renren/modules/oss/cloud/CloudStorageConfig.java
index 777f767b..587ed854 100644
--- a/renren-admin/src/main/java/io/renren/modules/oss/cloud/CloudStorageConfig.java
+++ b/renren-admin/src/main/java/io/renren/modules/oss/cloud/CloudStorageConfig.java
@@ -37,7 +37,7 @@ public class CloudStorageConfig implements Serializable {
private static final long serialVersionUID = 1L;
//类型 1:七牛 2:阿里云 3:腾讯云
- @Range(min=1, max=3, message = "类型错误")
+ @Range(min=0, max=3, message = "类型错误")
private Integer type;
//七牛绑定的域名
diff --git a/renren-admin/src/main/java/io/renren/modules/oss/cloud/LocalCloudStorageService.java b/renren-admin/src/main/java/io/renren/modules/oss/cloud/LocalCloudStorageService.java
new file mode 100644
index 00000000..d585724c
--- /dev/null
+++ b/renren-admin/src/main/java/io/renren/modules/oss/cloud/LocalCloudStorageService.java
@@ -0,0 +1,84 @@
+package io.renren.modules.oss.cloud;
+
+import io.renren.common.exception.RRException;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+import org.springframework.util.ResourceUtils;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.Random;
+
+/**
+ * @author 李帅超
+ * @Description: TODO
+ * @date 2018-03-06 12:49
+ */
+@Component
+public class LocalCloudStorageService extends CloudStorageService {
+ @Value("${upload.base.dir}")
+ private String baseDir;
+
+
+ public LocalCloudStorageService(){
+
+ }
+
+ @Override
+ public String upload(byte[] data, String path) {
+ return upload(new ByteArrayInputStream(data), path);
+ }
+
+ @Override
+ public String upload(InputStream inputStream, String path) {
+ try {
+ FileUtils.copyInputStreamToFile(inputStream,new File(getBaseDir() + path));
+ } catch (Exception e){
+ throw new RRException("上传文件失败,请检查配置信息", e);
+ }
+
+ return path;
+ }
+
+ @Override
+ public String uploadSuffix(byte[] data, String suffix) {
+ String path = getPathBySuffix(suffix);
+ return upload(data, path);
+ }
+
+ @Override
+ public String uploadSuffix(InputStream inputStream, String suffix) {
+ String path = getPathBySuffix(suffix);
+ return upload(inputStream, path);
+ }
+
+ /**
+ * 通过文件后缀生成文件本地路径
+ * @param suffix
+ * @return
+ */
+ private String getPathBySuffix(String suffix) {
+ LocalDate localDate = LocalDate.now();
+ DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
+ String str = "/";
+ String dir = "/resource/";
+ return dir + localDate.format(dateTimeFormatter) + str +System.currentTimeMillis() + new Random().nextInt(10000)+suffix;
+ }
+
+ private String getBaseDir(){
+ if(StringUtils.isBlank(baseDir)){
+ try {
+ baseDir = ResourceUtils.getURL("classpath:public").getPath();
+ } catch (FileNotFoundException e) {
+ throw new RRException("上传文件失败,请检查本地路径配置信息", e);
+ }
+ }
+ return baseDir;
+ }
+}
diff --git a/renren-admin/src/main/java/io/renren/modules/oss/cloud/OSSFactory.java b/renren-admin/src/main/java/io/renren/modules/oss/cloud/OSSFactory.java
index 9ec9d614..6a26b65b 100644
--- a/renren-admin/src/main/java/io/renren/modules/oss/cloud/OSSFactory.java
+++ b/renren-admin/src/main/java/io/renren/modules/oss/cloud/OSSFactory.java
@@ -38,8 +38,10 @@ public final class OSSFactory {
public static CloudStorageService build(){
//获取云存储配置信息
CloudStorageConfig config = sysConfigService.getConfigObject(ConfigConstant.CLOUD_STORAGE_CONFIG_KEY, CloudStorageConfig.class);
-
- if(config.getType() == Constant.CloudService.QINIU.getValue()){
+ if(config.getType() == Constant.CloudService.LOCAL.getValue()){
+ //return new LocalCloudStorageService();
+ return SpringContextUtils.getBean("localCloudStorageService",LocalCloudStorageService.class);
+ }else if(config.getType() == Constant.CloudService.QINIU.getValue()){
return new QiniuCloudStorageService(config);
}else if(config.getType() == Constant.CloudService.ALIYUN.getValue()){
return new AliyunCloudStorageService(config);
diff --git a/renren-admin/src/main/java/io/renren/modules/oss/controller/SysOssController.java b/renren-admin/src/main/java/io/renren/modules/oss/controller/SysOssController.java
index f980ebd1..290ec9f5 100644
--- a/renren-admin/src/main/java/io/renren/modules/oss/controller/SysOssController.java
+++ b/renren-admin/src/main/java/io/renren/modules/oss/controller/SysOssController.java
@@ -141,7 +141,6 @@ public R upload(@RequestParam("file") MultipartFile file) throws Exception {
@RequiresPermissions("sys:oss:all")
public R delete(@RequestBody Long[] ids){
sysOssService.deleteBatchIds(Arrays.asList(ids));
-
return R.ok();
}
diff --git a/renren-admin/src/main/java/io/renren/modules/sys/controller/SysLoginController.java b/renren-admin/src/main/java/io/renren/modules/sys/controller/SysLoginController.java
index a8109014..79db8d1e 100644
--- a/renren-admin/src/main/java/io/renren/modules/sys/controller/SysLoginController.java
+++ b/renren-admin/src/main/java/io/renren/modules/sys/controller/SysLoginController.java
@@ -24,7 +24,9 @@
import org.apache.shiro.authc.*;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@@ -32,6 +34,7 @@
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.IOException;
@@ -46,51 +49,97 @@
public class SysLoginController {
@Autowired
private Producer producer;
-
+ private String errorNumber = "errorNumber";
+ @Value("${captcha.error.number:5}")
+ private Integer captchaErrorNumber;
+
+ /**
+ * 生成验证码
+ * @param response
+ * @throws IOException
+ */
@RequestMapping("captcha.jpg")
public void captcha(HttpServletResponse response)throws IOException {
response.setHeader("Cache-Control", "no-store, no-cache");
response.setContentType("image/jpeg");
-
//生成文字验证码
String text = producer.createText();
//生成图片验证码
BufferedImage image = producer.createImage(text);
//保存到shiro session
ShiroUtils.setSessionAttribute(Constants.KAPTCHA_SESSION_KEY, text);
-
ServletOutputStream out = response.getOutputStream();
ImageIO.write(image, "jpg", out);
}
+
+ /**
+ * 登陆是否需要输入验证码
+ * @return
+ */
+ @GetMapping("/sys/captcha")
+ @ResponseBody
+ public R geterrorNumber(HttpSession session){
+ //判断次数
+ Integer errorNum = (Integer) session.getAttribute(errorNumber);
+ if (captchaErrorNumber==null){
+ captchaErrorNumber = 0;
+ }
+ if(errorNum == null||errorNum < captchaErrorNumber){
+ return R.ok().put("code",0);
+ }else{
+ return R.error("请求次数过多,需要显示验证码").put("code",1);
+ }
+ }
+
/**
* 登录
*/
@ResponseBody
@RequestMapping(value = "/sys/login", method = RequestMethod.POST)
- public R login(String username, String password, String captcha) {
+ public R login(String username, String password, String captcha,HttpSession session) {
String kaptcha = ShiroUtils.getKaptcha(Constants.KAPTCHA_SESSION_KEY);
- if(!captcha.equalsIgnoreCase(kaptcha)){
- return R.error("验证码不正确");
+ //验证码输错次数
+ Integer errorNum = (Integer) session.getAttribute(errorNumber);
+ if (captchaErrorNumber==null){
+ captchaErrorNumber = 0;
+ }
+ if(errorNum != null&&errorNum >= captchaErrorNumber){
+ if(!captcha.equalsIgnoreCase(kaptcha)){
+ return R.error("验证码不正确");
+ }
}
-
+
try{
Subject subject = ShiroUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
subject.login(token);
}catch (UnknownAccountException e) {
+ addErrorNumber(session);
return R.error(e.getMessage());
}catch (IncorrectCredentialsException e) {
+ addErrorNumber(session);
return R.error("账号或密码不正确");
}catch (LockedAccountException e) {
+ addErrorNumber(session);
return R.error("账号已被锁定,请联系管理员");
}catch (AuthenticationException e) {
+ addErrorNumber(session);
return R.error("账户验证失败");
}
return R.ok();
}
-
+
+ /**
+ * 增加验证错误次数
+ */
+ private void addErrorNumber(HttpSession session) {
+ Integer errorNum = (Integer) session.getAttribute(errorNumber);
+ session.setAttribute(errorNumber, (errorNum==null?0:errorNum) + 1);
+ }
+
+
/**
* 退出
*/
diff --git a/renren-admin/src/main/java/io/renren/modules/sys/shiro/ShiroUtils.java b/renren-admin/src/main/java/io/renren/modules/sys/shiro/ShiroUtils.java
index 614ca77f..3f17d64c 100644
--- a/renren-admin/src/main/java/io/renren/modules/sys/shiro/ShiroUtils.java
+++ b/renren-admin/src/main/java/io/renren/modules/sys/shiro/ShiroUtils.java
@@ -16,7 +16,6 @@
package io.renren.modules.sys.shiro;
-import io.renren.common.exception.RRException;
import io.renren.modules.sys.entity.SysUserEntity;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.crypto.hash.SimpleHash;
@@ -74,9 +73,9 @@ public static void logout() {
public static String getKaptcha(String key) {
Object kaptcha = getSessionAttribute(key);
- if(kaptcha == null){
+ /*if(kaptcha == null){
throw new RRException("验证码已失效");
- }
+ }*/
getSession().removeAttribute(key);
return kaptcha.toString();
}
diff --git a/renren-admin/src/main/resources/application-dev.yml b/renren-admin/src/main/resources/application-dev.yml
index d4a3765b..a7432928 100644
--- a/renren-admin/src/main/resources/application-dev.yml
+++ b/renren-admin/src/main/resources/application-dev.yml
@@ -4,13 +4,13 @@ spring:
driverClassName: com.mysql.jdbc.Driver
druid:
first: #数据源1
- url: jdbc:mysql://localhost:3306/renren_security?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8
- username: renren
- password: 123456
+ url: jdbc:mysql://192.168.29.212:3306/renren_security?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8
+ username: root
+ password: ABCabc@123.
second: #数据源2
- url: jdbc:mysql://10.10.168.18:3306/renren_security?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8
- username: renren
- password: 123456
+ url: jdbc:mysql://192.168.29.212:3306/renren_security?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8
+ username: root
+ password: ABCabc@123.
initial-size: 10
max-active: 100
min-idle: 10
diff --git a/renren-admin/src/main/resources/application.yml b/renren-admin/src/main/resources/application.yml
index 87b8b1e4..5a4d03ea 100644
--- a/renren-admin/src/main/resources/application.yml
+++ b/renren-admin/src/main/resources/application.yml
@@ -6,9 +6,19 @@ server:
min-spare-threads: 30
port: 8080
context-path: /renren-admin
-
+#文件上传文件夹
+upload:
+ base:
+ dir: #D:/ziyuan/
+captcha:
+ error:
+ number: 5
# mysql
spring:
+ mvc:
+ static-path-pattern: /**
+ resources:
+ static-locations: classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,file:${upload.base.dir}
# 环境 dev|test|prod
profiles:
active: dev
@@ -35,6 +45,7 @@ spring:
freemarker:
suffix: .html
request-context-attribute: request
+
# Mybatis配置
#mybatis:
# mapperLocations: classpath:mapper/**/*.xml
@@ -78,4 +89,4 @@ mybatis-plus:
call-setters-on-nulls: true
#logging
logging:
- level: debug
\ No newline at end of file
+ level: debug
diff --git a/renren-admin/src/main/resources/statics/js/modules/oss/oss.js b/renren-admin/src/main/resources/statics/js/modules/oss/oss.js
index ff900b48..a5a9cff1 100644
--- a/renren-admin/src/main/resources/statics/js/modules/oss/oss.js
+++ b/renren-admin/src/main/resources/statics/js/modules/oss/oss.js
@@ -4,8 +4,9 @@ $(function () {
datatype: "json",
colModel: [
{ label: 'id', name: 'id', width: 20, key: true },
- { label: 'URL地址', name: 'url', width: 160 },
- { label: '创建时间', name: 'createDate', width: 40 }
+ { label: '图片', name: 'url', width: 10 ,index: 'dsource_alarm',align: "center", sortable: false, editable: false, formatter: alarmFormatter },
+ { label: 'URL地址', name: 'url', width: 150 },
+ { label: '创建时间', name: 'createDate', width: 40}
],
viewrecords: true,
height: 385,
@@ -32,7 +33,12 @@ $(function () {
$("#jqGrid").closest(".ui-jqgrid-bdiv").css({ "overflow-x" : "hidden" });
}
});
+ function alarmFormatter(cellvalue, options, rowdata)
+ {
+ return '';
+
+ }
new AjaxUpload('#upload', {
action: baseURL + "sys/oss/upload",
name: 'file',
diff --git a/renren-admin/src/main/resources/templates/index.html b/renren-admin/src/main/resources/templates/index.html
index 124f77c8..449a10ec 100644
--- a/renren-admin/src/main/resources/templates/index.html
+++ b/renren-admin/src/main/resources/templates/index.html
@@ -27,9 +27,9 @@
- 人人
+ XMS
- 人人权限系统
+ 北京新模式