diff --git a/README.md b/README.md index b4ef294..90e1fe3 100644 --- a/README.md +++ b/README.md @@ -2,16 +2,16 @@

一个开箱即用的快速开发平台.JAVA版

### 🍿 传送门 -vboot在线体验传送门 [http://zsvg.gitee.io/vboot](http://zsvg.gitee.io/vboot) +* 在线体验传送门:[http://zsvg.gitee.io/vboot](http://zsvg.gitee.io/vboot) +* QQ交流群传送门:[795417789](https://jq.qq.com/?_wv=1027&k=yoKKIlIG) 暂时就几个人哦,哈哈 ### 🍟 概述 - * 基于JAVA实现的快速开发平台。模块化插件式开发,前后端分离,开箱即用。 * 后台基于SpringBoot框架,数据库访问使用Jpa,自动生成数据库表结构。 * 前端基于Vben-Admin vxe-table框架。 * 核心模块包括:部门、用户、岗位、群组、角色、菜单、字典、日志、文件管理、定时任务等功能。 -* QQ交流群:[795417789] 暂时就几个人哦,哈哈 * .NET6实现的同功能项目地址[https://gitee.com/zsvg/vboot-net](https://gitee.com/zsvg/vboot-net) 两个项目会同步开发 +* 前端代码项目地址:[https://gitee.com/zsvg/vboot-vben](https://gitee.com/zsvg/vboot-vben) ``` 如果对您有帮助,点击右上角⭐Star⭐关注 ,感谢支持开源! ``` diff --git a/vboot-application/src/main/java/com/abc/Application.java b/vboot-application/src/main/java/com/abc/Application.java index 296453e..16e2fcd 100644 --- a/vboot-application/src/main/java/com/abc/Application.java +++ b/vboot-application/src/main/java/com/abc/Application.java @@ -11,6 +11,7 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.ComponentScan; import org.springframework.core.env.Environment; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.scheduling.annotation.EnableAsync; import java.net.InetAddress; import java.net.UnknownHostException; @@ -21,6 +22,7 @@ import java.net.UnknownHostException; @ComponentScan({"com.zsvg","com.abc"}) @EnableJpaRepositories({"com.zsvg","com.abc"}) @Slf4j +@EnableAsync //@EnableSwagger2 public class Application { diff --git a/vboot-core/pom.xml b/vboot-core/pom.xml index 8465053..5ed8aa5 100644 --- a/vboot-core/pom.xml +++ b/vboot-core/pom.xml @@ -110,10 +110,10 @@ org.springframework.boot spring-boot-starter-security - - org.springframework.session - spring-session-data-redis - + + + + diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/util/lang/JsonUtils.java b/vboot-core/src/main/java/com/zsvg/vboot/common/util/lang/JsonUtils.java new file mode 100644 index 0000000..720db25 --- /dev/null +++ b/vboot-core/src/main/java/com/zsvg/vboot/common/util/lang/JsonUtils.java @@ -0,0 +1,78 @@ +package com.zsvg.vboot.common.util.lang; + +import cn.hutool.core.util.ArrayUtil; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.zsvg.vboot.common.util.web.XspringUtil; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class JsonUtils { + + private static ObjectMapper objectMapper = XspringUtil.getBean(ObjectMapper.class); + + + public static T parseObject(String text, Class clazz) { + if (StringUtils.isEmpty(text)) { + return null; + } + try { + return objectMapper.readValue(text, clazz); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public static T parseObject(byte[] bytes, Class clazz) { + if (ArrayUtil.isEmpty(bytes)) { + return null; + } + try { + return objectMapper.readValue(bytes, clazz); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public static T parseObject(String text, TypeReference typeReference) { + if (StringUtils.isBlank(text)) { + return null; + } + try { + return objectMapper.readValue(text, typeReference); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public static Map parseMap(String text) { + if (StringUtils.isBlank(text)) { + return null; + } + try { + return objectMapper.readValue(text, new TypeReference>() { + }); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public static List parseArray(String text, Class clazz) { + if (StringUtils.isEmpty(text)) { + return new ArrayList<>(); + } + try { + return objectMapper.readValue(text, objectMapper.getTypeFactory().constructCollectionType(List.class, clazz)); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/vboot-core/src/main/java/com/zsvg/vboot/common/util/web/XaddressUtil.java b/vboot-core/src/main/java/com/zsvg/vboot/common/util/web/XaddressUtil.java new file mode 100644 index 0000000..d9f4a25 --- /dev/null +++ b/vboot-core/src/main/java/com/zsvg/vboot/common/util/web/XaddressUtil.java @@ -0,0 +1,49 @@ +package com.zsvg.vboot.common.util.web; + +import cn.hutool.core.net.NetUtil; +import cn.hutool.http.HtmlUtil; +import cn.hutool.http.HttpUtil; +import com.zsvg.vboot.common.util.lang.JsonUtils; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import java.util.Map; + +@Slf4j +public class XaddressUtil { + + // IP地址查询 + public static final String IP_URL = "http://whois.pconline.com.cn/ipJson.jsp"; + + // 未知地址 + public static final String UNKNOWN = "XX XX"; + + public static String getRealAddressByIP(String ip) { + String address = UNKNOWN; + if (StringUtils.isBlank(ip)) { + return address; + } + // 内网不查询 + ip = "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : HtmlUtil.cleanHtmlTag(ip); + if (NetUtil.isInnerIP(ip)) { + return "内网IP"; + } + try { + String rspStr = HttpUtil.createGet(IP_URL) + .body("ip=" + ip + "&json=true", "GBK") + .execute() + .body(); + if (StringUtils.isEmpty(rspStr)) { + log.error("获取地理位置异常 {}", ip); + return UNKNOWN; + } + Map obj = JsonUtils.parseMap(rspStr); + String region = obj.get("pro"); + String city = obj.get("city"); + return String.format("%s %s", region, city); + } catch (Exception e) { + log.error("获取地理位置异常 {}", ip); + } + return address; + } +} diff --git a/vboot-core/src/main/java/com/zsvg/vboot/config/security/authn/AuthnController.java b/vboot-core/src/main/java/com/zsvg/vboot/config/security/authn/AuthnController.java index 5210c8e..3b5b627 100644 --- a/vboot-core/src/main/java/com/zsvg/vboot/config/security/authn/AuthnController.java +++ b/vboot-core/src/main/java/com/zsvg/vboot/config/security/authn/AuthnController.java @@ -4,13 +4,14 @@ import cn.hutool.core.util.IdUtil; import com.zsvg.vboot.common.mvc.api.RestResult; import com.zsvg.vboot.common.mvc.dao.JdbcDao; import com.zsvg.vboot.config.AppConfig; -import com.zsvg.vboot.module.sys.org.user.SysOrgUserService; import com.zsvg.vboot.config.dbx.redis.RedisHandler; import com.zsvg.vboot.config.security.jwt.JwtHandler; import com.zsvg.vboot.config.security.pojo.Duser; import com.zsvg.vboot.config.security.pojo.Zmenu; import com.zsvg.vboot.config.security.pojo.Zmeta; import com.zsvg.vboot.config.security.pojo.Zuser; +import com.zsvg.vboot.module.sys.log.login.SysLogLoginService; +import com.zsvg.vboot.module.sys.org.user.SysOrgUserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.BeanPropertyRowMapper; @@ -21,6 +22,7 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; +import javax.servlet.http.HttpServletRequest; import javax.validation.Valid; import javax.websocket.server.PathParam; import java.io.IOException; @@ -34,8 +36,8 @@ import java.util.Map; public class AuthnController { @PostMapping("/login") - public RestResult login(@Valid @RequestBody LoginDto loginDTO) throws IOException, ClassNotFoundException { - System.out.println("开始登录"); + public RestResult login(@Valid @RequestBody LoginDto loginDTO, HttpServletRequest request) throws IOException, ClassNotFoundException { +// System.out.println("开始登录"); //1.登录验证 Duser duser = null; @@ -73,7 +75,8 @@ public class AuthnController { redisHandler.set(atokenUUID, zuser, appConfig.getJwt().getAtime());//默认8小时过期 - //3.登录日志记录 + //3.异步方式记录登录日志 +// sysLogLoginService.save(zuser,request); return RestResult.ok(backMap); } @@ -145,6 +148,9 @@ public class AuthnController { @Autowired private JdbcDao jdbcDao; + @Autowired + private SysLogLoginService sysLogLoginService; + @Autowired private SysOrgUserService userService; diff --git a/vboot-core/src/main/java/com/zsvg/vboot/config/security/authn/AuthnService.java b/vboot-core/src/main/java/com/zsvg/vboot/config/security/authn/AuthnService.java index 803b297..d3493f9 100644 --- a/vboot-core/src/main/java/com/zsvg/vboot/config/security/authn/AuthnService.java +++ b/vboot-core/src/main/java/com/zsvg/vboot/config/security/authn/AuthnService.java @@ -80,7 +80,7 @@ public class AuthnService { backMap.put("menus", menuList); backMap.put("btns", btnArr); backMap.put("zuser", zuser); - System.out.println("通过缓存"); +// System.out.println("通过缓存"); } // //初始化数据库user diff --git a/vboot-core/src/main/java/com/zsvg/vboot/config/security/authz/AuthzController.java b/vboot-core/src/main/java/com/zsvg/vboot/config/security/authz/AuthzController.java index 6e87e30..9393b1a 100644 --- a/vboot-core/src/main/java/com/zsvg/vboot/config/security/authz/AuthzController.java +++ b/vboot-core/src/main/java/com/zsvg/vboot/config/security/authz/AuthzController.java @@ -2,18 +2,23 @@ package com.zsvg.vboot.config.security.authz; import com.zsvg.vboot.common.mvc.api.RestResult; +import com.zsvg.vboot.config.security.pojo.Zuser; +import com.zsvg.vboot.module.sys.log.login.SysLogLoginService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.Authentication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; +import javax.servlet.http.HttpServletRequest; + @RestController public class AuthzController { @GetMapping("/getUserInfo") - public RestResult getUserInfo(Authentication auth) { - + public RestResult getUserInfo(Authentication auth, HttpServletRequest request) { + Zuser zuser = (Zuser) auth.getPrincipal(); + sysLogLoginService.save(zuser,request); return RestResult.ok("test"); } @@ -32,7 +37,8 @@ public class AuthzController { return RestResult.ok("test"); } - + @Autowired + private SysLogLoginService sysLogLoginService; @Autowired private AuthzService authzService; diff --git a/vboot-core/src/main/java/com/zsvg/vboot/config/security/authz/AuthzHandler.java b/vboot-core/src/main/java/com/zsvg/vboot/config/security/authz/AuthzHandler.java index a631b32..66f049c 100644 --- a/vboot-core/src/main/java/com/zsvg/vboot/config/security/authz/AuthzHandler.java +++ b/vboot-core/src/main/java/com/zsvg/vboot/config/security/authz/AuthzHandler.java @@ -11,8 +11,13 @@ public class AuthzHandler { public boolean hasPermission(HttpServletRequest request, Authentication authentication) { String uri=request.getRequestURI(); - Zuser zuser = (Zuser) authentication.getPrincipal(); + try { + Zuser zuser = (Zuser) authentication.getPrincipal(); + } catch (Exception e) { + //e.printStackTrace(); + return false; + } return true; diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/sys/log/login/SysLogLogin.java b/vboot-core/src/main/java/com/zsvg/vboot/module/sys/log/login/SysLogLogin.java index a7435b9..7ac8f32 100644 --- a/vboot-core/src/main/java/com/zsvg/vboot/module/sys/log/login/SysLogLogin.java +++ b/vboot-core/src/main/java/com/zsvg/vboot/module/sys/log/login/SysLogLogin.java @@ -1,11 +1,9 @@ package com.zsvg.vboot.module.sys.log.login; import lombok.Data; -import org.hibernate.annotations.GenericGenerator; import javax.persistence.Column; import javax.persistence.Entity; -import javax.persistence.GeneratedValue; import javax.persistence.Id; import java.util.Date; @@ -16,29 +14,31 @@ public class SysLogLogin { @Column(length = 32) private String id; + @Column(length = 32) + private String name;//用户名称 + + @Column(length = 32) + private String usnam;//登录账号 + @Column(length = 32) + private String ip;//登录ip + @Column(updatable = false) private Date crtim=new Date(); @Column(length = 32) - private String usnam;//用户名 - - @Column(length = 32) - private String uname;//用户名称 - - @Column(length = 32) - private String uip;//登录ip + private String addre;//登录地点 @Column(length = 64) - private String usession;// + private String usession;//取消了session!!! + + @Column(length = 32) + private String ageos;//客户端操作系统 + + @Column(length = 32) + private String agbro;//客户端浏览器 @Column(length = 512) - private String agentInfo;//客户端详情 - - @Column(length = 32) - private String agentOs;//客户端操作系统 - - @Column(length = 32) - private String agentBrowser;//客户端浏览器 + private String agdet;//客户端详情 diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/sys/log/login/SysLogLoginApi.java b/vboot-core/src/main/java/com/zsvg/vboot/module/sys/log/login/SysLogLoginApi.java index 15e9cbd..75fcae3 100644 --- a/vboot-core/src/main/java/com/zsvg/vboot/module/sys/log/login/SysLogLoginApi.java +++ b/vboot-core/src/main/java/com/zsvg/vboot/module/sys/log/login/SysLogLoginApi.java @@ -12,13 +12,17 @@ public class SysLogLoginApi { @GetMapping public RestResult get(String name) { - Sqler sqlHelper = new Sqler("t.id,t.uname,t.crtim,t.uip,t.agent_os as agentOs,t.agent_browser as agentBrowser,t.agent_info as agentInfo", - "sys_log_login"); + Sqler sqlHelper = new Sqler("t.*", "sys_log_login"); sqlHelper.addLike("t.uname", name); sqlHelper.addOrder("t.crtim desc"); return RestResult.ok(jdbcDao.findPageData(sqlHelper)); } + @GetMapping("one/{id}") + public RestResult getOne(@PathVariable String id) { + return RestResult.ok(repo.findById(id).get()); + } + @DeleteMapping("{ids}") public RestResult delete(@PathVariable String[] ids) { for (String id : ids) { @@ -27,6 +31,11 @@ public class SysLogLoginApi { return RestResult.ok(); } + @DeleteMapping("all") + public RestResult deleteAll() { + repo.deleteAll(); + return RestResult.ok(); + } @Autowired private JdbcDao jdbcDao; diff --git a/vboot-core/src/main/java/com/zsvg/vboot/module/sys/log/login/SysLogLoginService.java b/vboot-core/src/main/java/com/zsvg/vboot/module/sys/log/login/SysLogLoginService.java index 18f933e..fa45295 100644 --- a/vboot-core/src/main/java/com/zsvg/vboot/module/sys/log/login/SysLogLoginService.java +++ b/vboot-core/src/main/java/com/zsvg/vboot/module/sys/log/login/SysLogLoginService.java @@ -1,13 +1,15 @@ package com.zsvg.vboot.module.sys.log.login; +import cn.hutool.extra.servlet.ServletUtil; import com.zsvg.vboot.common.util.lang.XstringUtil; -import com.zsvg.vboot.common.util.web.XreqUtil; +import com.zsvg.vboot.common.util.web.XaddressUtil; import com.zsvg.vboot.config.security.pojo.Zuser; import eu.bitwalker.useragentutils.Browser; import eu.bitwalker.useragentutils.OperatingSystem; import eu.bitwalker.useragentutils.UserAgent; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletRequest; @@ -16,11 +18,12 @@ import javax.servlet.http.HttpServletRequest; @Slf4j public class SysLogLoginService { - @Autowired private SysLogLoginRepo repo; + @Async public void save(Zuser zuser, HttpServletRequest request){ + SysLogLogin logLogin = new SysLogLogin(); logLogin.setId(XstringUtil.getUUID()); try { @@ -30,25 +33,28 @@ public class SysLogLoginService { OperatingSystem os = userAgent.getOperatingSystem(); logLogin.setUsnam(zuser.getId()); - logLogin.setUname(zuser.getName()); - logLogin.setUip(XreqUtil.getIpAddress(request)); -// logLogin.setUip(request.getRemoteHost()); - logLogin.setUsession(request.getSession().getId()); + logLogin.setName(zuser.getName()); +// logLogin.setUip(XreqUtil.getIpAddress(request)); + String ip=ServletUtil.getClientIP(request); + logLogin.setIp(ip); + logLogin.setAddre(XaddressUtil.getRealAddressByIP(ip)); +// logLogin.setUsession(request.getSession().getId()); - logLogin.setAgentInfo(agent); - logLogin.setAgentBrowser(browser.toString()); + logLogin.setAgdet(agent); + logLogin.setAgbro(browser.toString()); if("IE7".equals(browser.toString())){ if (agent.contains("Trident/5")) { - logLogin.setAgentBrowser("IE9C"); + logLogin.setAgbro("IE9C"); }else if(agent.contains("Trident/6")){ - logLogin.setAgentBrowser("IE10C"); + logLogin.setAgbro("IE10C"); }else if(agent.contains("Trident/7")){ - logLogin.setAgentBrowser("IE11C"); + logLogin.setAgbro("IE11C"); } } - logLogin.setAgentOs(os.toString()); + logLogin.setAgeos(os.toString()); repo.save(logLogin); }catch (Exception e){ + e.printStackTrace(); log.error("登录日志记录异常:"+logLogin); } }