新增验证码、登录日志、操作日志记录
parent
e6c56ebbb1
commit
d447ae83be
|
|
@ -11,7 +11,7 @@
|
||||||
Target Server Version : 50721
|
Target Server Version : 50721
|
||||||
File Encoding : 65001
|
File Encoding : 65001
|
||||||
|
|
||||||
Date: 06/04/2023 17:20:01
|
Date: 07/04/2023 14:54:55
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SET NAMES utf8mb4;
|
SET NAMES utf8mb4;
|
||||||
|
|
@ -64,6 +64,7 @@ CREATE TABLE `sys_login_log` (
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of sys_login_log
|
-- Records of sys_login_log
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
|
INSERT INTO `sys_login_log` VALUES ('165965da5e98b46703683bc655004384', 'admin', '123456', '成功', 'Unknown', 'Unknown', '内网IP', '127.0.0.1', '19aa0675-d451-4232-9221-73babda49078', '2023-04-07 11:33:04');
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for sys_menu
|
-- Table structure for sys_menu
|
||||||
|
|
@ -107,6 +108,7 @@ DROP TABLE IF EXISTS `sys_oper_log`;
|
||||||
CREATE TABLE `sys_oper_log` (
|
CREATE TABLE `sys_oper_log` (
|
||||||
`id` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '主键id',
|
`id` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '主键id',
|
||||||
`module` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '功能模块',
|
`module` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '功能模块',
|
||||||
|
`method` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '操作方法',
|
||||||
`type` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '操作类型',
|
`type` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '操作类型',
|
||||||
`message` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '操作描述',
|
`message` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '操作描述',
|
||||||
`req_param` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '请求参数',
|
`req_param` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '请求参数',
|
||||||
|
|
@ -114,9 +116,10 @@ CREATE TABLE `sys_oper_log` (
|
||||||
`take_up_time` int(64) NULL DEFAULT NULL COMMENT '耗时',
|
`take_up_time` int(64) NULL DEFAULT NULL COMMENT '耗时',
|
||||||
`user_id` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '操作用户id',
|
`user_id` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '操作用户id',
|
||||||
`user_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '操作用户名称',
|
`user_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '操作用户名称',
|
||||||
`method` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '操作方法',
|
`status` int(1) NULL DEFAULT NULL COMMENT '状态:0、成功,1、失败',
|
||||||
`uri` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '请求url',
|
`uri` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '请求url',
|
||||||
`ip` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '请求IP',
|
`ip` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '请求IP',
|
||||||
|
`unusual` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '异常信息',
|
||||||
`version` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '版本号',
|
`version` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '版本号',
|
||||||
`create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
|
`create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
|
|
@ -125,6 +128,7 @@ CREATE TABLE `sys_oper_log` (
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of sys_oper_log
|
-- Records of sys_oper_log
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
|
INSERT INTO `sys_oper_log` VALUES ('f052dcb16aeb0fa199bd82aa058e8eee', '菜单管理-当前用户权限菜单列表', 'com.tansci.controller.SysMenuController.menus', 'SELECT', '当前用户权限菜单列表', '{}', '{\"code\":200,\"message\":\"操作成功\",\"result\":[{\"children\":[{\"component\":\"Layout\",\"icon\":\"Grid\",\"id\":\"10001dsgf\",\"isShow\":true,\"meta\":{\"keepAlive\":false,\"openMode\":0,\"id\":\"10001dsgf\",\"title\":\"Iframe测试\",\"isShow\":true},\"name\":\"Iframe\",\"parentId\":\"b1851d1b13594e71840103c11a37a002\",\"path\":\"https://www.bing.com/?mkt=zh-CN\",\"sort\":6},{\"component\":\"Layout\",\"icon\":\"Grid\",\"id\":\"b1851d1b13594e71840103c11a37a003\",\"isShow\":true,\"meta\":{\"keepAlive\":false,\"openMode\":0,\"id\":\"b1851d1b13594e71840103c11a37a003\",\"title\":\"菜单管理\",\"isShow\":true},\"name\":\"menu\",\"parentId\":\"b1851d1b13594e71840103c11a37a002\",\"path\":\"/system/Menu\",\"sort\":2},{\"component\":\"Layout\",\"icon\":\"QuestionFilled\",\"id\":\"b1851d1b13594e71840103c11a37a004\",\"isShow\":true,\"meta\":{\"keepAlive\":false,\"openMode\":0,\"id\":\"b1851d1b13594e71840103c11a37a004\",\"title\":\"组织管理\",\"isShow\":true},\"name\":\"org\",\"parentId\":\"b1851d1b13594e71840103c11a37a002\",\"path\":\"/system/Org\",\"sort\":3},{\"component\":\"Layout\",\"icon\":\"Grid\",\"id\":\"b1851d1b13594e71840103c11a37a005\",\"isShow\":true,\"meta\":{\"keepAlive\":false,\"openMode\":0,\"id\":\"b1851d1b13594e71840103c11a37a005\",\"title\":\"权限管理\",\"isShow\":true},\"name\":\"role\",\"parentId\":\"b1851d1b13594e71840103c11a37a002\",\"path\":\"/system/Role\",\"sort\":4},{\"component\":\"Layout\",\"icon\":\"Grid\",\"id\":\"b1851d1b13594e71840103c11a37a006\",\"isShow\":true,\"meta\":{\"keepAlive\":false,\"openMode\":0,\"id\":\"b1851d1b13594e71840103c11a37a006\",\"title\":\"用户管理\",\"isShow\":true},\"name\":\"user\",\"parentId\":\"b1851d1b13594e71840103c11a37a002\",\"path\":\"/system/User\",\"sort\":5}],\"component\":\"Layout\",\"icon\":\"Grid\",\"id\":\"b1851d1b13594e71840103c11a37a002\",\"isShow\":true,\"meta\":{\"keepAlive\":false,\"openMode\":0,\"id\":\"b1851d1b13594e71840103c11a37a002\",\"title\":\"系统管理\",\"isShow\":true},\"name\":\"system\",\"parentId\":\"0\",\"path\":\"/system\",\"sort\":1}]}', 49, '534a37c366ec47878a6b0c85703d0bc2', NULL, 0, '/tansci/sysmenu/menus', '127.0.0.1', NULL, NULL, '2023-04-07 14:50:17');
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for sys_org
|
-- Table structure for sys_org
|
||||||
|
|
|
||||||
|
|
@ -69,4 +69,18 @@ export function logout(){
|
||||||
removeUser()
|
removeUser()
|
||||||
location.reload()
|
location.reload()
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证码
|
||||||
|
export function getCode(){
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
request({
|
||||||
|
url: '/tansci/auth/code',
|
||||||
|
method: 'get'
|
||||||
|
}).then((res:any) => {
|
||||||
|
resolve(res)
|
||||||
|
}).catch((e:any) => {
|
||||||
|
reject(e)
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -30,10 +30,10 @@ axiosInstance.interceptors.request.use((config: AxiosRequestConfig) => {
|
||||||
// axios实例拦截响应
|
// axios实例拦截响应
|
||||||
axiosInstance.interceptors.response.use(
|
axiosInstance.interceptors.response.use(
|
||||||
(response: AxiosResponse) => {
|
(response: AxiosResponse) => {
|
||||||
if (response.status === 200 && response.data.code == 200) {
|
if (response.status === 200 && response.data.code === 200) {
|
||||||
return response;
|
return response;
|
||||||
} else {
|
} else {
|
||||||
ElMessage.warning(showMessage(response.status));
|
ElMessage.warning(showMessage(response.data.code));
|
||||||
if (response.data.code === 402) {
|
if (response.data.code === 402) {
|
||||||
logout()
|
logout()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,15 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {onBeforeMount,reactive,ref,toRefs} from "vue"
|
import {onBeforeMount,onMounted,reactive,ref,toRefs} from "vue"
|
||||||
import type {FormInstance} from 'element-plus'
|
import type {FormInstance} from 'element-plus'
|
||||||
import {useRouter} from 'vue-router'
|
import {useRouter} from 'vue-router'
|
||||||
import {login} from '@/api/auth'
|
import {login,getCode} from '@/api/auth'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const loginFormRef = ref<FormInstance>()
|
const loginFormRef = ref<FormInstance>()
|
||||||
|
|
||||||
const logo = new URL('../../assets/image/logo.png', import.meta.url).href
|
const logo = new URL('../../assets/image/logo.png', import.meta.url).href
|
||||||
const loginLogo = new URL('../../assets/image/login-icon.png', import.meta.url).href
|
const loginLogo = new URL('../../assets/image/login-icon.png', import.meta.url).href
|
||||||
|
const codeImg = ref()
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
loading: false,
|
loading: false,
|
||||||
|
|
@ -18,6 +19,7 @@
|
||||||
loginForm: {
|
loginForm: {
|
||||||
username: '',
|
username: '',
|
||||||
password: '',
|
password: '',
|
||||||
|
code: '',
|
||||||
remember: 0
|
remember: 0
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
@ -26,11 +28,21 @@
|
||||||
state.loginStyle.height = (document.body.clientHeight || document.documentElement.clientHeight) + "px"
|
state.loginStyle.height = (document.body.clientHeight || document.documentElement.clientHeight) + "px"
|
||||||
})
|
})
|
||||||
|
|
||||||
|
onMounted(() =>{
|
||||||
|
onCode()
|
||||||
|
})
|
||||||
|
|
||||||
function copyYear(){
|
function copyYear(){
|
||||||
let date = new Date();
|
let date = new Date();
|
||||||
return date.getFullYear();
|
return date.getFullYear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onCode(){
|
||||||
|
getCode().then((res:any) =>{
|
||||||
|
codeImg.value = 'data:image/png;base64,' + res.data.result
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
async function onSubmit(formEl: FormInstance | undefined) {
|
async function onSubmit(formEl: FormInstance | undefined) {
|
||||||
if (!formEl) return;
|
if (!formEl) return;
|
||||||
await formEl.validate((valid)=>{
|
await formEl.validate((valid)=>{
|
||||||
|
|
@ -38,7 +50,8 @@
|
||||||
// 登录成功后设置token到缓存
|
// 登录成功后设置token到缓存
|
||||||
let param:any = {
|
let param:any = {
|
||||||
username: state.loginForm.username,
|
username: state.loginForm.username,
|
||||||
password: state.loginForm.password
|
password: state.loginForm.password,
|
||||||
|
code: state.loginForm.code
|
||||||
}
|
}
|
||||||
state.loading = true;
|
state.loading = true;
|
||||||
login(param).then((res:any) =>{
|
login(param).then((res:any) =>{
|
||||||
|
|
@ -81,6 +94,10 @@
|
||||||
{required: true,message: '请输入密码',trigger: 'blur'}]">
|
{required: true,message: '请输入密码',trigger: 'blur'}]">
|
||||||
<el-input type="password" v-model="state.loginForm.password" prefix-icon="Lock" show-password placeholder="请输入密码" style="width:100%"></el-input>
|
<el-input type="password" v-model="state.loginForm.password" prefix-icon="Lock" show-password placeholder="请输入密码" style="width:100%"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item prop="code" :rules="[{required: true,message: '请输入验证码',trigger: 'blur'}]">
|
||||||
|
<el-input v-model="state.loginForm.code" prefix-icon="HelpFilled" placeholder="请输入验证码" style="width:70%; margin-right: 1%"></el-input>
|
||||||
|
<img :src="codeImg" @click="onCode" style="width: 29%; height: 38px;">
|
||||||
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-checkbox v-model="state.loginForm.remember">记住密码</el-checkbox>
|
<el-checkbox v-model="state.loginForm.remember">记住密码</el-checkbox>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@
|
||||||
<druid-spring-boot.varsion>1.2.6</druid-spring-boot.varsion>
|
<druid-spring-boot.varsion>1.2.6</druid-spring-boot.varsion>
|
||||||
<sa-token-spring-boot.varsion>1.34.0</sa-token-spring-boot.varsion>
|
<sa-token-spring-boot.varsion>1.34.0</sa-token-spring-boot.varsion>
|
||||||
<knife4j-spring-boot.version>3.0.3</knife4j-spring-boot.version>
|
<knife4j-spring-boot.version>3.0.3</knife4j-spring-boot.version>
|
||||||
|
<hutool-all.version>5.7.22</hutool-all.version>
|
||||||
|
<fastjson2.version>2.0.26</fastjson2.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
@ -29,6 +31,11 @@
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-aop</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.mysql</groupId>
|
<groupId>com.mysql</groupId>
|
||||||
<artifactId>mysql-connector-j</artifactId>
|
<artifactId>mysql-connector-j</artifactId>
|
||||||
|
|
@ -65,6 +72,17 @@
|
||||||
<version>${knife4j-spring-boot.version}</version>
|
<version>${knife4j-spring-boot.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hutool</groupId>
|
||||||
|
<artifactId>hutool-all</artifactId>
|
||||||
|
<version>${hutool-all.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.fastjson2</groupId>
|
||||||
|
<artifactId>fastjson2</artifactId>
|
||||||
|
<version>${fastjson2.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
package com.tansci.common.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ClassName: Log.java
|
||||||
|
* @ClassPath: com.tansci.common.annotation.Log.java
|
||||||
|
* @Description: 自定义操作日志注解
|
||||||
|
* @Author: tanyp
|
||||||
|
* @Date: 2023/4/7 14:05
|
||||||
|
**/
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
public @interface Log {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作模块
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
String modul() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作类型
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
String type() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作说明
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
String desc() default "";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,180 @@
|
||||||
|
package com.tansci.common.aop;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.tansci.common.annotation.Log;
|
||||||
|
import com.tansci.common.constant.Constants;
|
||||||
|
import com.tansci.domain.SysOperLog;
|
||||||
|
import com.tansci.domain.vo.SysUserSessionVo;
|
||||||
|
import com.tansci.service.SysOperLogService;
|
||||||
|
import com.tansci.utils.SystemUtils;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.aspectj.lang.JoinPoint;
|
||||||
|
import org.aspectj.lang.annotation.*;
|
||||||
|
import org.aspectj.lang.reflect.MethodSignature;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.context.request.RequestAttributes;
|
||||||
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ClassName: OperLogAspect.java
|
||||||
|
* @ClassPath: com.tansci.common.aop.OperLogAspect.java
|
||||||
|
* @Description: 操作日志记录
|
||||||
|
* @Author: tanyp
|
||||||
|
* @Date: 2023/4/7 14:02
|
||||||
|
**/
|
||||||
|
@Slf4j
|
||||||
|
@Aspect
|
||||||
|
@Component
|
||||||
|
public class OperLogAspect {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统计请求的处理时间
|
||||||
|
*/
|
||||||
|
ThreadLocal<Long> startTime = new ThreadLocal<>();
|
||||||
|
@Autowired
|
||||||
|
private SysOperLogService sysOperLogService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @MonthName: logPoinCut
|
||||||
|
* @Description: 设置操作日志切入点 记录操作日志 在注解的位置切入代码
|
||||||
|
* @Author: tanyp
|
||||||
|
* @Date: 2023/4/7 14:06
|
||||||
|
* @Param: []
|
||||||
|
* @return: void
|
||||||
|
**/
|
||||||
|
@Pointcut("@annotation(com.tansci.common.annotation.Log)")
|
||||||
|
public void logPoinCut() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @MonthName: exceptionLogPoinCut
|
||||||
|
* @Description: 设置操作异常切入点记录异常日志 扫描所有controller包下操作
|
||||||
|
* @Author: tanyp
|
||||||
|
* @Date: 2023/4/7 14:07
|
||||||
|
* @Param: []
|
||||||
|
* @return: void
|
||||||
|
**/
|
||||||
|
@Pointcut("execution(* com.tansci.controller..*.*(..))")
|
||||||
|
public void exceptionLogPoinCut() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before("logPoinCut()")
|
||||||
|
public void doBefore() {
|
||||||
|
// 接收到请求,记录请求开始时间
|
||||||
|
startTime.set(System.currentTimeMillis());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @MonthName: doAfterReturning
|
||||||
|
* @Description: 正常返回通知,拦截用户操作日志,连接点正常执行完成后执行, 如果连接点抛出异常,则不会执行
|
||||||
|
* @Author: tanyp
|
||||||
|
* @Date: 2023/4/7 14:08
|
||||||
|
* @Param: [joinPoint, keys]
|
||||||
|
* @return: void
|
||||||
|
**/
|
||||||
|
@AfterReturning(value = "logPoinCut()", returning = "keys")
|
||||||
|
public void doAfterReturning(JoinPoint joinPoint, Object keys) {
|
||||||
|
try {
|
||||||
|
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
|
||||||
|
HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
|
||||||
|
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||||
|
Method method = signature.getMethod();
|
||||||
|
SysUserSessionVo sessionVo = (SysUserSessionVo) StpUtil.getSession().get(String.valueOf(StpUtil.getLoginId()));
|
||||||
|
|
||||||
|
SysOperLog operLog = SysOperLog.builder()
|
||||||
|
.reqParam(JSON.toJSONString(converMap(request.getParameterMap())))
|
||||||
|
.resParam(JSON.toJSONString(keys))
|
||||||
|
.takeUpTime(System.currentTimeMillis() - startTime.get())
|
||||||
|
.userId(String.valueOf(StpUtil.getLoginId()))
|
||||||
|
.userName(sessionVo.getUsername())
|
||||||
|
.method(joinPoint.getTarget().getClass().getName() + "." + method.getName())
|
||||||
|
.uri(request.getRequestURI())
|
||||||
|
.ip(SystemUtils.getIp(request))
|
||||||
|
.status(Constants.OPER_LOG_STATUS_SUCCESS)
|
||||||
|
.createTime(LocalDateTime.now())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Log log = method.getAnnotation(Log.class);
|
||||||
|
if (Objects.nonNull(log)) {
|
||||||
|
operLog.setModule(log.modul());
|
||||||
|
operLog.setType(log.type());
|
||||||
|
operLog.setMessage(log.desc());
|
||||||
|
}
|
||||||
|
|
||||||
|
sysOperLogService.save(operLog);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("记录操作日志异常:{}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @MonthName: doAfterThrowing
|
||||||
|
* @Description: 异常返回通知,用于拦截异常日志信息 连接点抛出异常后执行
|
||||||
|
* @Author: tanyp
|
||||||
|
* @Date: 2023/4/7 14:36
|
||||||
|
* @Param: [joinPoint, e]
|
||||||
|
* @return: void
|
||||||
|
**/
|
||||||
|
@AfterThrowing(pointcut = "exceptionLogPoinCut()", throwing = "e")
|
||||||
|
public void doAfterThrowing(JoinPoint joinPoint, Throwable e) {
|
||||||
|
try {
|
||||||
|
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
|
||||||
|
HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
|
||||||
|
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||||
|
Method method = signature.getMethod();
|
||||||
|
SysUserSessionVo sessionVo = (SysUserSessionVo) StpUtil.getSession().get(String.valueOf(StpUtil.getLoginId()));
|
||||||
|
|
||||||
|
SysOperLog operLog = SysOperLog.builder()
|
||||||
|
.reqParam(JSON.toJSONString(converMap(request.getParameterMap())))
|
||||||
|
.takeUpTime(System.currentTimeMillis() - startTime.get())
|
||||||
|
.userId(String.valueOf(StpUtil.getLoginId()))
|
||||||
|
.userName(sessionVo.getUsername())
|
||||||
|
.method(joinPoint.getTarget().getClass().getName() + "." + method.getName())
|
||||||
|
.uri(request.getRequestURI())
|
||||||
|
.ip(SystemUtils.getIp(request))
|
||||||
|
.status(Constants.OPER_LOG_STATUS_ERROR)
|
||||||
|
.unusual(stackTraceToString(e.getClass().getName(), e.getMessage(), e.getStackTrace()))
|
||||||
|
.createTime(LocalDateTime.now())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Log log = method.getAnnotation(Log.class);
|
||||||
|
if (Objects.nonNull(log)) {
|
||||||
|
operLog.setModule(log.modul());
|
||||||
|
operLog.setType(log.type());
|
||||||
|
operLog.setMessage(log.desc());
|
||||||
|
}
|
||||||
|
|
||||||
|
sysOperLogService.save(operLog);
|
||||||
|
} catch (Exception e2) {
|
||||||
|
log.error("记录操作日志异常:{}", e2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> converMap(Map<String, String[]> paramMap) {
|
||||||
|
Map<String, String> rtnMap = new HashMap<>();
|
||||||
|
for (String key : paramMap.keySet()) {
|
||||||
|
rtnMap.put(key, paramMap.get(key)[0]);
|
||||||
|
}
|
||||||
|
return rtnMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String stackTraceToString(String exceptionName, String exceptionMessage, StackTraceElement[] elements) {
|
||||||
|
StringBuffer strbuff = new StringBuffer();
|
||||||
|
for (StackTraceElement stet : elements) {
|
||||||
|
strbuff.append(stet + "<br/>");
|
||||||
|
}
|
||||||
|
String message = exceptionName + ":" + exceptionMessage + "<br/>" + strbuff.toString();
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -10,12 +10,23 @@ package com.tansci.common.constant;
|
||||||
public class Constants {
|
public class Constants {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 未删除状态
|
* 删除状态:0、正常,1、删除
|
||||||
*/
|
*/
|
||||||
public final static Integer NOT_DEL_FALG = 0;
|
public final static Integer NOT_DEL_FALG = 0;
|
||||||
/**
|
|
||||||
* 已删除状态
|
|
||||||
*/
|
|
||||||
public final static Integer IS_DEL_FALG = 1;
|
public final static Integer IS_DEL_FALG = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作日志状态:0、成功,1、失败
|
||||||
|
*/
|
||||||
|
public final static Integer OPER_LOG_STATUS_SUCCESS = 0;
|
||||||
|
public final static Integer OPER_LOG_STATUS_ERROR = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接口操作类型
|
||||||
|
*/
|
||||||
|
public final static String SELECT = "SELECT";
|
||||||
|
public final static String INSERT = "INSERT";
|
||||||
|
public final static String UPDATE = "INSERT";
|
||||||
|
public final static String DELETE = "DELETE";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ package com.tansci.controller;
|
||||||
|
|
||||||
import cn.dev33.satoken.session.SaSessionCustomUtil;
|
import cn.dev33.satoken.session.SaSessionCustomUtil;
|
||||||
import cn.dev33.satoken.stp.StpUtil;
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
|
import cn.hutool.captcha.CaptchaUtil;
|
||||||
|
import cn.hutool.captcha.LineCaptcha;
|
||||||
import com.tansci.common.WrapMapper;
|
import com.tansci.common.WrapMapper;
|
||||||
import com.tansci.common.Wrapper;
|
import com.tansci.common.Wrapper;
|
||||||
import com.tansci.domain.SysUser;
|
import com.tansci.domain.SysUser;
|
||||||
|
|
@ -13,6 +15,8 @@ import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ClassName: AuthController.java
|
* @ClassName: AuthController.java
|
||||||
* @ClassPath: com.tansci.controller.AuthController.java
|
* @ClassPath: com.tansci.controller.AuthController.java
|
||||||
|
|
@ -31,8 +35,8 @@ public class AuthController {
|
||||||
|
|
||||||
@ApiOperation(value = "登录", notes = "登录")
|
@ApiOperation(value = "登录", notes = "登录")
|
||||||
@PostMapping("/login")
|
@PostMapping("/login")
|
||||||
public Wrapper<SysUserVo> login(@RequestBody SysUser user) {
|
public Wrapper<SysUserVo> login(HttpServletRequest request, @RequestBody SysUser user) {
|
||||||
return WrapMapper.wrap(Wrapper.SUCCESS_CODE, Wrapper.SUCCESS_MESSAGE, sysUserService.login(user));
|
return WrapMapper.wrap(Wrapper.SUCCESS_CODE, Wrapper.SUCCESS_MESSAGE, sysUserService.login(request, user));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation(value = "登出", notes = "登出")
|
@ApiOperation(value = "登出", notes = "登出")
|
||||||
|
|
@ -43,4 +47,16 @@ public class AuthController {
|
||||||
return WrapMapper.wrap(Wrapper.SUCCESS_CODE, Wrapper.SUCCESS_MESSAGE, "登出成功!");
|
return WrapMapper.wrap(Wrapper.SUCCESS_CODE, Wrapper.SUCCESS_MESSAGE, "登出成功!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "验证码", notes = "验证码")
|
||||||
|
@GetMapping("/code")
|
||||||
|
public Wrapper<Object> verificationCode(HttpServletRequest request) {
|
||||||
|
LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(100, 60);
|
||||||
|
// 四则运算方式
|
||||||
|
// lineCaptcha.setGenerator(new MathGenerator());
|
||||||
|
// 验证码存session, 60秒过期
|
||||||
|
request.getSession().setMaxInactiveInterval(60);
|
||||||
|
request.getSession().setAttribute("verifyCode", lineCaptcha.getCode());
|
||||||
|
return WrapMapper.wrap(Wrapper.SUCCESS_CODE, Wrapper.SUCCESS_MESSAGE, lineCaptcha.getImageBase64());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ package com.tansci.controller;
|
||||||
|
|
||||||
import com.tansci.common.WrapMapper;
|
import com.tansci.common.WrapMapper;
|
||||||
import com.tansci.common.Wrapper;
|
import com.tansci.common.Wrapper;
|
||||||
|
import com.tansci.common.annotation.Log;
|
||||||
|
import com.tansci.common.constant.Constants;
|
||||||
import com.tansci.domain.SysMenu;
|
import com.tansci.domain.SysMenu;
|
||||||
import com.tansci.domain.vo.SysMenuVo;
|
import com.tansci.domain.vo.SysMenuVo;
|
||||||
import com.tansci.service.SysMenuService;
|
import com.tansci.service.SysMenuService;
|
||||||
|
|
@ -32,12 +34,14 @@ public class SysMenuController {
|
||||||
private SysMenuService sysMenuService;
|
private SysMenuService sysMenuService;
|
||||||
|
|
||||||
@ApiOperation(value = "当前用户权限菜单树", notes = "当前用户权限菜单树")
|
@ApiOperation(value = "当前用户权限菜单树", notes = "当前用户权限菜单树")
|
||||||
|
@Log(modul = "菜单管理-当前用户权限菜单树", type = Constants.SELECT, desc = "当前用户权限菜单树")
|
||||||
@GetMapping("/tree")
|
@GetMapping("/tree")
|
||||||
public Wrapper<List<SysMenu>> tree(SysMenu menu) {
|
public Wrapper<List<SysMenu>> tree(SysMenu menu) {
|
||||||
return WrapMapper.wrap(Wrapper.SUCCESS_CODE, Wrapper.SUCCESS_MESSAGE, sysMenuService.tree(menu));
|
return WrapMapper.wrap(Wrapper.SUCCESS_CODE, Wrapper.SUCCESS_MESSAGE, sysMenuService.tree(menu));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation(value = "当前用户权限菜单列表", notes = "当前用户权限菜单列表")
|
@ApiOperation(value = "当前用户权限菜单列表", notes = "当前用户权限菜单列表")
|
||||||
|
@Log(modul = "菜单管理-当前用户权限菜单列表", type = Constants.SELECT, desc = "当前用户权限菜单列表")
|
||||||
@GetMapping("/menus")
|
@GetMapping("/menus")
|
||||||
public Wrapper<List<SysMenuVo>> menus() {
|
public Wrapper<List<SysMenuVo>> menus() {
|
||||||
return WrapMapper.wrap(Wrapper.SUCCESS_CODE, Wrapper.SUCCESS_MESSAGE, sysMenuService.menus());
|
return WrapMapper.wrap(Wrapper.SUCCESS_CODE, Wrapper.SUCCESS_MESSAGE, sysMenuService.menus());
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.tansci.common.WrapMapper;
|
import com.tansci.common.WrapMapper;
|
||||||
import com.tansci.common.Wrapper;
|
import com.tansci.common.Wrapper;
|
||||||
|
import com.tansci.common.annotation.Log;
|
||||||
|
import com.tansci.common.constant.Constants;
|
||||||
import com.tansci.domain.SysUser;
|
import com.tansci.domain.SysUser;
|
||||||
import com.tansci.service.SysUserService;
|
import com.tansci.service.SysUserService;
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
|
|
@ -31,36 +33,42 @@ public class SysUserController {
|
||||||
private SysUserService sysUserService;
|
private SysUserService sysUserService;
|
||||||
|
|
||||||
@ApiOperation(value = "用户分页", notes = "用户分页")
|
@ApiOperation(value = "用户分页", notes = "用户分页")
|
||||||
|
@Log(modul = "用户管理-用户分页", type = Constants.SELECT, desc = "用户分页")
|
||||||
@GetMapping("/page")
|
@GetMapping("/page")
|
||||||
public Wrapper<IPage<SysUser>> page(Page page, SysUser user) {
|
public Wrapper<IPage<SysUser>> page(Page page, SysUser user) {
|
||||||
return WrapMapper.wrap(Wrapper.SUCCESS_CODE, Wrapper.SUCCESS_MESSAGE, sysUserService.page(page, user));
|
return WrapMapper.wrap(Wrapper.SUCCESS_CODE, Wrapper.SUCCESS_MESSAGE, sysUserService.page(page, user));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation(value = "用户列表", notes = "用户列表")
|
@ApiOperation(value = "用户列表", notes = "用户列表")
|
||||||
|
@Log(modul = "用户管理-用户列表", type = Constants.SELECT, desc = "用户列表")
|
||||||
@GetMapping("/list")
|
@GetMapping("/list")
|
||||||
public Wrapper<List<SysUser>> list(SysUser user) {
|
public Wrapper<List<SysUser>> list(SysUser user) {
|
||||||
return WrapMapper.wrap(Wrapper.SUCCESS_CODE, Wrapper.SUCCESS_MESSAGE, sysUserService.list(user));
|
return WrapMapper.wrap(Wrapper.SUCCESS_CODE, Wrapper.SUCCESS_MESSAGE, sysUserService.list(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation(value = "添加用户信息", notes = "添加用户信息")
|
@ApiOperation(value = "添加用户信息", notes = "添加用户信息")
|
||||||
|
@Log(modul = "用户管理-添加用户信息", type = Constants.INSERT, desc = "添加用户信息")
|
||||||
@PostMapping("/save")
|
@PostMapping("/save")
|
||||||
public Wrapper<Object> save(@RequestBody SysUser user) {
|
public Wrapper<Object> save(@RequestBody SysUser user) {
|
||||||
return WrapMapper.wrap(Wrapper.SUCCESS_CODE, Wrapper.SUCCESS_MESSAGE, sysUserService.insert(user));
|
return WrapMapper.wrap(Wrapper.SUCCESS_CODE, Wrapper.SUCCESS_MESSAGE, sysUserService.insert(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation(value = "修改用户信息", notes = "修改用户信息")
|
@ApiOperation(value = "修改用户信息", notes = "修改用户信息")
|
||||||
|
@Log(modul = "用户管理-修改用户信息", type = Constants.UPDATE, desc = "修改用户信息")
|
||||||
@PostMapping("/update")
|
@PostMapping("/update")
|
||||||
public Wrapper<Object> update(@RequestBody SysUser user) {
|
public Wrapper<Object> update(@RequestBody SysUser user) {
|
||||||
return WrapMapper.wrap(Wrapper.SUCCESS_CODE, Wrapper.SUCCESS_MESSAGE, sysUserService.update(user));
|
return WrapMapper.wrap(Wrapper.SUCCESS_CODE, Wrapper.SUCCESS_MESSAGE, sysUserService.update(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation(value = "删除用户", notes = "删除用户")
|
@ApiOperation(value = "删除用户", notes = "删除用户")
|
||||||
|
@Log(modul = "用户管理-删除用户", type = Constants.DELETE, desc = "删除用户")
|
||||||
@GetMapping("/del")
|
@GetMapping("/del")
|
||||||
public Wrapper<Object> del(SysUser user) {
|
public Wrapper<Object> del(SysUser user) {
|
||||||
return WrapMapper.wrap(Wrapper.SUCCESS_CODE, Wrapper.SUCCESS_MESSAGE, sysUserService.del(user));
|
return WrapMapper.wrap(Wrapper.SUCCESS_CODE, Wrapper.SUCCESS_MESSAGE, sysUserService.del(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation(value = "修改密码", notes = "修改密码")
|
@ApiOperation(value = "修改密码", notes = "修改密码")
|
||||||
|
@Log(modul = "用户管理-修改密码", type = Constants.UPDATE, desc = "修改密码")
|
||||||
@PostMapping("/modifyPass")
|
@PostMapping("/modifyPass")
|
||||||
public Wrapper<Object> modifyPass(@RequestBody SysUser user) {
|
public Wrapper<Object> modifyPass(@RequestBody SysUser user) {
|
||||||
return WrapMapper.wrap(Wrapper.SUCCESS_CODE, Wrapper.SUCCESS_MESSAGE, sysUserService.modifyPass(user));
|
return WrapMapper.wrap(Wrapper.SUCCESS_CODE, Wrapper.SUCCESS_MESSAGE, sysUserService.modifyPass(user));
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,9 @@ public class SysOperLog {
|
||||||
@ApiModelProperty(value = "操作用户id")
|
@ApiModelProperty(value = "操作用户id")
|
||||||
private String userId;
|
private String userId;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "状态:0、成功,1、失败")
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
@ApiModelProperty(value = "操作用户名称")
|
@ApiModelProperty(value = "操作用户名称")
|
||||||
private String userName;
|
private String userName;
|
||||||
|
|
||||||
|
|
@ -69,6 +72,9 @@ public class SysOperLog {
|
||||||
@ApiModelProperty(value = "版本号")
|
@ApiModelProperty(value = "版本号")
|
||||||
private String version;
|
private String version;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "异常信息")
|
||||||
|
private String unusual;
|
||||||
|
|
||||||
@ApiModelProperty(value = "创建时间")
|
@ApiModelProperty(value = "创建时间")
|
||||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", locale = "zh", timezone = "GMT+8")
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", locale = "zh", timezone = "GMT+8")
|
||||||
private LocalDateTime createTime;
|
private LocalDateTime createTime;
|
||||||
|
|
|
||||||
|
|
@ -98,4 +98,8 @@ public class SysUser {
|
||||||
@ApiModelProperty(value = "权限IDS")
|
@ApiModelProperty(value = "权限IDS")
|
||||||
private List<String> roleIds;
|
private List<String> roleIds;
|
||||||
|
|
||||||
|
@TableField(exist = false)
|
||||||
|
@ApiModelProperty(value = "验证码")
|
||||||
|
private String code;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import com.tansci.domain.SysUser;
|
import com.tansci.domain.SysUser;
|
||||||
import com.tansci.domain.vo.SysUserVo;
|
import com.tansci.domain.vo.SysUserVo;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -27,7 +28,7 @@ public interface SysUserService extends IService<SysUser> {
|
||||||
|
|
||||||
Object del(SysUser user);
|
Object del(SysUser user);
|
||||||
|
|
||||||
SysUserVo login(SysUser user);
|
SysUserVo login(HttpServletRequest request, SysUser user);
|
||||||
|
|
||||||
Object modifyPass(SysUser user);
|
Object modifyPass(SysUser user);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,18 +8,22 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.tansci.common.constant.Constants;
|
import com.tansci.common.constant.Constants;
|
||||||
import com.tansci.common.exception.BusinessException;
|
import com.tansci.common.exception.BusinessException;
|
||||||
|
import com.tansci.domain.SysLoginLog;
|
||||||
import com.tansci.domain.SysUser;
|
import com.tansci.domain.SysUser;
|
||||||
import com.tansci.domain.SysUserRole;
|
import com.tansci.domain.SysUserRole;
|
||||||
import com.tansci.domain.vo.SysUserSessionVo;
|
import com.tansci.domain.vo.SysUserSessionVo;
|
||||||
import com.tansci.domain.vo.SysUserVo;
|
import com.tansci.domain.vo.SysUserVo;
|
||||||
import com.tansci.mapper.SysUserMapper;
|
import com.tansci.mapper.SysUserMapper;
|
||||||
|
import com.tansci.service.SysLoginLogService;
|
||||||
import com.tansci.service.SysUserRoleService;
|
import com.tansci.service.SysUserRoleService;
|
||||||
import com.tansci.service.SysUserService;
|
import com.tansci.service.SysUserService;
|
||||||
import com.tansci.utils.Sha256Util;
|
import com.tansci.utils.Sha256Util;
|
||||||
|
import com.tansci.utils.SystemUtils;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
@ -38,6 +42,8 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private SysUserRoleService sysUserRoleService;
|
private SysUserRoleService sysUserRoleService;
|
||||||
|
@Autowired
|
||||||
|
private SysLoginLogService sysLoginLogService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IPage<SysUser> page(Page page, SysUser user) {
|
public IPage<SysUser> page(Page page, SysUser user) {
|
||||||
|
|
@ -98,11 +104,35 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SysUserVo login(SysUser user) {
|
public SysUserVo login(HttpServletRequest request, SysUser user) {
|
||||||
SysUser sysUser = this.baseMapper.selectOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, user.getUsername()));
|
SysLoginLog loginLog = SysLoginLog.builder()
|
||||||
if (Objects.nonNull(sysUser) && Objects.equals(sysUser.getPassword(), Sha256Util.getSHA256(user.getPassword()))) {
|
.username(user.getUsername())
|
||||||
|
.failPassword(user.getPassword())
|
||||||
|
.type("成功")
|
||||||
|
.ip(SystemUtils.getIp(request))
|
||||||
|
.address(SystemUtils.getAddress(request))
|
||||||
|
.browser(SystemUtils.getBrowser(request))
|
||||||
|
.os(SystemUtils.getOS(request))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 校验验证码
|
||||||
|
String code = (String) request.getSession().getAttribute("verifyCode");
|
||||||
|
if (Objects.isNull(user.getCode()) || !Objects.equals(code, user.getCode())) {
|
||||||
|
loginLog.setType("失败");
|
||||||
|
throw new BusinessException("验证码有误,请重新获取!");
|
||||||
|
}
|
||||||
|
|
||||||
|
SysUser sysUser = this.baseMapper.selectOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, user.getUsername()));
|
||||||
|
if (Objects.isNull(sysUser) && !Objects.equals(sysUser.getPassword(), Sha256Util.getSHA256(user.getPassword()))) {
|
||||||
|
loginLog.setType("失败");
|
||||||
|
throw new BusinessException("登录失败,用户名或密码有误!");
|
||||||
|
}
|
||||||
|
|
||||||
// 生成token
|
// 生成token
|
||||||
StpUtil.login(sysUser.getId());
|
StpUtil.login(sysUser.getId());
|
||||||
|
// 登录日志记录
|
||||||
|
loginLog.setToken(StpUtil.getTokenInfo().getTokenValue());
|
||||||
|
|
||||||
// 用户角色到session
|
// 用户角色到session
|
||||||
List<SysUserRole> roles = sysUserRoleService.list(Wrappers.<SysUserRole>lambdaQuery().eq(SysUserRole::getUserId, sysUser.getId()));
|
List<SysUserRole> roles = sysUserRoleService.list(Wrappers.<SysUserRole>lambdaQuery().eq(SysUserRole::getUserId, sysUser.getId()));
|
||||||
|
|
@ -126,8 +156,9 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||||
.loginTime(LocalDateTime.now())
|
.loginTime(LocalDateTime.now())
|
||||||
.token(StpUtil.getTokenInfo().getTokenValue())
|
.token(StpUtil.getTokenInfo().getTokenValue())
|
||||||
.build();
|
.build();
|
||||||
|
} finally {
|
||||||
|
sysLoginLogService.save(loginLog);
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,11 @@
|
||||||
package com.tansci.utils;
|
package com.tansci.utils;
|
||||||
|
|
||||||
|
import cn.hutool.core.net.Ipv4Util;
|
||||||
|
import cn.hutool.http.HttpUtil;
|
||||||
|
import cn.hutool.http.useragent.UserAgent;
|
||||||
|
import cn.hutool.http.useragent.UserAgentUtil;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -20,48 +26,8 @@ public class SystemUtils {
|
||||||
* @return: java.lang.String
|
* @return: java.lang.String
|
||||||
**/
|
**/
|
||||||
public static String getOS(HttpServletRequest request) {
|
public static String getOS(HttpServletRequest request) {
|
||||||
String osName = "";
|
UserAgent userAgent = UserAgentUtil.parse(request.getHeaders("User-Agent").toString());
|
||||||
String userAgent = request.getHeader("User-Agent").toUpperCase();
|
return userAgent.getBrowser().toString();
|
||||||
if (userAgent.contains("WINDOWS")) {
|
|
||||||
if (userAgent.contains("WINDOWS NT 10.0")) {
|
|
||||||
osName = "Windows 10";
|
|
||||||
} else if (userAgent.contains("WINDOWS NT 6.3")) {
|
|
||||||
osName = "Windows 8.1";
|
|
||||||
} else if (userAgent.contains("WINDOWS NT 6.2")) {
|
|
||||||
osName = "Windows 8";
|
|
||||||
} else if (userAgent.contains("WINDOWS NT 6.1")) {
|
|
||||||
osName = "Windows 7";
|
|
||||||
} else if (userAgent.contains("WINDOWS NT 6.0")) {
|
|
||||||
osName = "Windows Vista";
|
|
||||||
} else if (userAgent.contains("WINDOWS NT 5.2")) {
|
|
||||||
osName = "Windows XP";
|
|
||||||
} else if (userAgent.contains("WINDOWS NT 5.1")) {
|
|
||||||
osName = "Windows XP";
|
|
||||||
} else if (userAgent.contains("WINDOWS NT 5.01")) {
|
|
||||||
osName = "Windows 2000";
|
|
||||||
} else if (userAgent.contains("WINDOWS NT 5.0")) {
|
|
||||||
osName = "Windows 2000";
|
|
||||||
} else if (userAgent.contains("WINDOWS NT 4.0")) {
|
|
||||||
osName = "Windows NT 4.0";
|
|
||||||
} else if (userAgent.contains("WINDOWS 98; WIN 9X 4.90")) {
|
|
||||||
osName = "Windows ME";
|
|
||||||
} else if (userAgent.contains("WINDOWS 98")) {
|
|
||||||
osName = "Windows 98";
|
|
||||||
} else if (userAgent.contains("WINDOWS 95")) {
|
|
||||||
osName = "Windows 95";
|
|
||||||
} else if (userAgent.contains("WINDOWS CE")) {
|
|
||||||
osName = "Windows CE";
|
|
||||||
}
|
|
||||||
} else if (userAgent.contains("MAC")) {
|
|
||||||
osName = "Mac";
|
|
||||||
} else if (userAgent.contains("UNIX")) {
|
|
||||||
osName = "UNIX";
|
|
||||||
} else if (userAgent.contains("LINUX")) {
|
|
||||||
osName = "Linux";
|
|
||||||
} else if (userAgent.contains("SUNOS")) {
|
|
||||||
osName = "SunOS";
|
|
||||||
}
|
|
||||||
return osName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -73,31 +39,12 @@ public class SystemUtils {
|
||||||
* @return: java.lang.String
|
* @return: java.lang.String
|
||||||
**/
|
**/
|
||||||
public static String getBrowser(HttpServletRequest request) {
|
public static String getBrowser(HttpServletRequest request) {
|
||||||
String browserName = "";
|
UserAgent userAgent = UserAgentUtil.parse(request.getHeaders("User-Agent").toString());
|
||||||
String userAgent = request.getHeader("User-Agent").toUpperCase();
|
return userAgent.getOs().toString();
|
||||||
if (userAgent == null || userAgent.equals("")) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
if (userAgent.indexOf("MSIE") > 0) {
|
|
||||||
browserName = "IE";
|
|
||||||
} else if (userAgent.indexOf("FIREFOX") > 0) {
|
|
||||||
browserName = "Firefox";
|
|
||||||
} else if (userAgent.indexOf("CHROME") > 0) {
|
|
||||||
browserName = "Chrome";
|
|
||||||
} else if (userAgent.indexOf("SAFARI") > 0) {
|
|
||||||
browserName = "Safari";
|
|
||||||
} else if (userAgent.indexOf("CAMINO") > 0) {
|
|
||||||
browserName = "Camino";
|
|
||||||
} else if (userAgent.indexOf("KONQUEROR") > 0) {
|
|
||||||
browserName = "Konqueror";
|
|
||||||
} else if (userAgent.indexOf("EDGE") > 0) {
|
|
||||||
browserName = "Microsoft Edge";
|
|
||||||
}
|
|
||||||
return browserName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @methodName:getIpAddress
|
* @methodName:getIp
|
||||||
* @description:获取IP地址
|
* @description:获取IP地址
|
||||||
* @author:tanyp
|
* @author:tanyp
|
||||||
* @dateTime:2022/2/15 14:19
|
* @dateTime:2022/2/15 14:19
|
||||||
|
|
@ -105,7 +52,7 @@ public class SystemUtils {
|
||||||
* @Return: java.lang.String
|
* @Return: java.lang.String
|
||||||
* @editNote:
|
* @editNote:
|
||||||
*/
|
*/
|
||||||
public static String getIpAddress(HttpServletRequest request) {
|
public static String getIp(HttpServletRequest request) {
|
||||||
|
|
||||||
String ip = request.getHeader("X-Forwarded-For");
|
String ip = request.getHeader("X-Forwarded-For");
|
||||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||||
|
|
@ -148,4 +95,26 @@ public class SystemUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @MonthName: getAddress
|
||||||
|
* @Description: 获取地址
|
||||||
|
* @Author: tanyp
|
||||||
|
* @Date: 2023/4/7 11:24
|
||||||
|
* @Param: [ip]
|
||||||
|
* @return: java.lang.String
|
||||||
|
**/
|
||||||
|
public static String getAddress(HttpServletRequest request) {
|
||||||
|
String ip = getIp(request);
|
||||||
|
try {
|
||||||
|
if (Ipv4Util.isInnerIP(ip)) {
|
||||||
|
return "内网IP";
|
||||||
|
}
|
||||||
|
return JSONUtil.parseObj(HttpUtil.get("https://whois.pconline.com.cn/ipJson.jsp?json=true&ip=" + ip)).getStr("addr");
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
return "内网IP";
|
||||||
|
} catch (Exception e) {
|
||||||
|
return "未知";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue