pms-parent/pms-common/src/main/java/com/dy/common/util/ObjectToMapUtil.java
New file @@ -0,0 +1,35 @@ package com.dy.common.util; import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; public class ObjectToMapUtil { /** * 将对象转换为Map。 * * @param obj 要转换的对象。 * @return 包含对象字段和值的Map。 */ public static Map<String, Object> objectToMap(Object obj) { if (obj == null) { return null; } Map<String, Object> map = new HashMap<>(); Class<?> clazz = obj.getClass(); Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { try { field.setAccessible(true); // 设置字段可访问 map.put(field.getName(), field.get(obj)); } catch (IllegalAccessException e) { throw new RuntimeException("Error accessing field: " + field.getName(), e); } } return map; } } pms-parent/pms-global/src/main/java/com/dy/pmsGlobal/aop/LogSv.java
New file @@ -0,0 +1,24 @@ package com.dy.pmsGlobal.aop; import com.dy.pmsGlobal.daoBa.BaLogMapper; import com.dy.pmsGlobal.pojoBa.BaLog; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.Date; @Service public class LogSv { @Autowired private BaLogMapper logMapper; public void save(long operator, String operation,String resIp) { BaLog log = new BaLog(); log.setUserId(operator); log.setContent(operation); log.setCreateDt(new Date()); log.setResIp(resIp); logMapper.insert(log); } } pms-parent/pms-global/src/main/java/com/dy/pmsGlobal/aop/OperationDescription.java
New file @@ -0,0 +1,12 @@ package com.dy.pmsGlobal.aop; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface OperationDescription { String value(); } pms-parent/pms-global/src/main/java/com/dy/pmsGlobal/aop/OperationLogAspect.java
New file @@ -0,0 +1,117 @@ package com.dy.pmsGlobal.aop; import com.dy.common.util.ObjectToMapUtil; import com.dy.common.webFilter.UserTokenContext; import com.dy.common.webUtil.BaseResponse; import com.dy.common.webUtil.BaseResponseUtils; import com.dy.pmsGlobal.pojoBa.BaUser; import com.mysql.cj.util.StringUtils; import jakarta.servlet.http.HttpServletRequest; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.util.UriComponentsBuilder; import java.util.Map; @Aspect @Component public class OperationLogAspect { @Value("${pms.sso.curUserUrl}") public String SsoCurUserUrl ; private LogSv logSv; @Autowired public void setLogSv(LogSv logSv){ this.logSv = logSv; } private RestTemplate restTemplate; @Autowired public void setRestTemplate(RestTemplate restTemplate){ this.restTemplate = restTemplate ; } @AfterReturning(pointcut = "@annotation(com.dy.pmsGlobal.aop.OperationDescription)", returning = "result") public void logAfterReturning(JoinPoint joinPoint, Object result) { // 获取方法的中文描述 MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); OperationDescription operationDescription = methodSignature.getMethod().getAnnotation(OperationDescription.class); String operationName = operationDescription.value(); //结果 BaseResponse response = (BaseResponse)result; response.isSuccess(); // 获取用户信息 BaUser user = (BaUser)getCurUser(response); Long operator = user!=null?user.id: 1l; // 获取IP地址 String ipAddress = getRemoteHost(); // 记录日志 logSv.save(operator, operationName,ipAddress); } /** * 调用SSO获取用户信息 * @param response (获取token) * @return 返回对象 */ private Object getCurUser(BaseResponse response){ if(!StringUtils.isNullOrEmpty(SsoCurUserUrl)){ String token = UserTokenContext.get(); if(StringUtils.isNullOrEmpty(token)){ Map<String,Object> resMap = ObjectToMapUtil.objectToMap(response.getContent()); token =resMap.containsKey("token")?resMap.get("token").toString():""; } String url = UriComponentsBuilder.fromUriString(SsoCurUserUrl) .queryParam("token", token) .build() .toUriString(); HttpHeaders headers = new HttpHeaders(); HttpEntity<?> httpEntity = new HttpEntity<>(headers); ResponseEntity<BaUser> myResponse = null; try { // 通过Get方式调用接口 myResponse = restTemplate.exchange(url, HttpMethod.GET, httpEntity, BaUser.class); } catch (Exception e) { e.printStackTrace(); } assert myResponse != null; return myResponse.getBody(); }else { return BaseResponseUtils.buildError("后端系统出错,未得到SsoCurUserUrl"); } } /** * 获取IP地址 * @return */ private String getRemoteHost() { // 获取请求对象 HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); String ip = request.getHeader("x-forwarded-for"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip; } } pms-parent/pms-global/src/main/java/com/dy/pmsGlobal/daoBa/BaLogMapper.java
New file @@ -0,0 +1,18 @@ package com.dy.pmsGlobal.daoBa; import com.dy.pmsGlobal.pojoBa.BaLog; import org.apache.ibatis.annotations.Mapper; import java.util.List; import java.util.Map; @Mapper public interface BaLogMapper { int insert(BaLog record); int insertSelective(BaLog record); BaLog selectByPrimaryKey(Long id); List<BaLog> selectSome(Map<String, Object> params); } pms-parent/pms-global/src/main/java/com/dy/pmsGlobal/pojoBa/BaLog.java
New file @@ -0,0 +1,36 @@ package com.dy.pmsGlobal.pojoBa; import com.baomidou.mybatisplus.annotation.TableName; import lombok.*; import java.util.Date; @TableName(value="ba_log", autoResultMap = true) @Data @Builder @ToString @NoArgsConstructor @AllArgsConstructor public class BaLog { private Long id; /** * 用户ID */ private Long userId; /** * 日志内容 */ private String content; /** * 请求IP */ private String resIp; /** * 创建时间 */ private Date createDt; } pms-parent/pms-global/src/main/resources/application-global.yml
@@ -53,6 +53,7 @@ webPort: 8000 sso: checkUrl: http://127.0.0.1:12344/sso/sso/ssoCheck curUserUrl: http://127.0.0.1:12344/sso/sso/ssoCurUser webPort: 12344 idSuffix: 1 base: pms-parent/pms-global/src/main/resources/mapper/BaLogMapper.xml
New file @@ -0,0 +1,93 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.dy.pmsGlobal.daoBa.BaLogMapper"> <resultMap id="BaseResultMap" type="com.dy.pmsGlobal.pojoBa.BaLog"> <!--@mbg.generated--> <!--@Table ba_log--> <id column="id" jdbcType="BIGINT" property="id" /> <result column="user_id" jdbcType="BIGINT" property="userId" /> <result column="content" jdbcType="VARCHAR" property="content" /> <result column="res_ip" jdbcType="VARCHAR" property="resIp" /> <result column="create_dt" jdbcType="TIMESTAMP" property="createDt" /> </resultMap> <sql id="Base_Column_List"> <!--@mbg.generated--> id, user_id, content, create_dt,res_ip </sql> <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap"> <!--@mbg.generated--> select <include refid="Base_Column_List" /> from ba_log where id = #{id,jdbcType=BIGINT} </select> <insert id="insert" keyColumn="id" keyProperty="id" parameterType="com.dy.pmsGlobal.pojoBa.BaLog" useGeneratedKeys="true"> <!--@mbg.generated--> insert into ba_log (user_id, content, create_dt,res_ip ) values (#{userId,jdbcType=BIGINT}, #{content,jdbcType=VARCHAR}, #{createDt,jdbcType=TIMESTAMP} , #{resIp,jdbcType=VARCHAR} ) </insert> <insert id="insertSelective" keyColumn="id" keyProperty="id" parameterType="com.dy.pmsGlobal.pojoBa.BaLog" useGeneratedKeys="true"> <!--@mbg.generated--> insert into ba_log <trim prefix="(" suffix=")" suffixOverrides=","> <if test="userId != null"> user_id, </if> <if test="content != null"> content, </if> <if test="createDt != null"> create_dt, </if> <if test="resIp != null"> res_ip, </if> </trim> <trim prefix="values (" suffix=")" suffixOverrides=","> <if test="userId != null"> #{userId,jdbcType=BIGINT}, </if> <if test="content != null"> #{content,jdbcType=VARCHAR}, </if> <if test="createDt != null"> #{createDt,jdbcType=TIMESTAMP}, </if> <if test="resIp != null"> #{resIp,jdbcType=VARCHAR}, </if> </trim> </insert> <select id="selectSome" resultMap="BaseResultMap"> select <include refid="Base_Column_List" > <property name="alias" value="r"/> </include> from ba_log r where <trim prefix="and" suffixOverrides="and"> <if test="userId != null and userId != ''"> user_id = #{userId,jdbcType=BIGINT} and </if> <if test="content != null and content != '' "> content like concat('%', #{content}, '%') and </if> <if test="createDt != null and createDt != '' "> create_dt = #{createDt,jdbcType=TIMESTAMP} and </if> <if test="resIp != null and resIp != '' "> res_ip =#{resIp,jdbcType=VARCHAR} and </if> </trim> order by id DESC <trim prefix="limit " > <if test="start != null and count != null"> #{start}, #{count} </if> </trim> </select> </mapper> pms-parent/pms-web-base/src/main/java/com/dy/pmsBase/role/RoleCtrl.java
@@ -5,6 +5,7 @@ import com.dy.common.webUtil.BaseResponse; import com.dy.common.webUtil.BaseResponseUtils; import com.dy.common.webUtil.QueryResultVo; import com.dy.pmsGlobal.aop.OperationDescription; import com.dy.pmsGlobal.pojoBa.BaRole; import jakarta.validation.Valid; import lombok.extern.slf4j.Slf4j; @@ -36,6 +37,7 @@ */ @PostMapping(path="save") @SsoPowerAop(power = "10100011") @OperationDescription("保存角色信息") public BaseResponse<BaRole> save(@RequestBody @Valid BaRole role,BindingResult bindingResult){ try { role.setDeleted(false); @@ -56,6 +58,7 @@ */ @PostMapping(path="update") @SsoPowerAop(power = "10100011") @OperationDescription("更新角色信息") public BaseResponse<BaRole> update(@RequestBody @Valid BaRole role,BindingResult bindingResult){ try { return BaseResponseUtils.buildSuccess(roleSv.update(role)); @@ -73,6 +76,7 @@ */ @PostMapping(path="delete") @SsoPowerAop(power = "10100011") @OperationDescription("删除角色信息") public BaseResponse<BaRole> delete(String id,BindingResult bindingResult){ try { return BaseResponseUtils.buildSuccess(roleSv.delete(Long.parseLong(id))); @@ -89,6 +93,7 @@ */ @GetMapping(path="one") @SsoPowerAop(power = "10100010") //登录与权限同时验证 @OperationDescription("根据ID查询角色信息") public BaseResponse<BaRole> one(String id){ try{ BaRole role=roleSv.selectById(id); @@ -106,6 +111,7 @@ */ @PostMapping(path="some") @SsoPowerAop(power = "10100010") @OperationDescription("分页查询角色信息") public BaseResponse<QueryResultVo<List<BaRole>>> some(@RequestBody QueryVo vo){ try { QueryResultVo<List<BaRole>> list = roleSv.selectSome(vo) ; pms-parent/pms-web-base/src/main/java/com/dy/pmsBase/user/UserCtrl.java
@@ -6,6 +6,7 @@ import com.dy.common.webUtil.BaseResponse; import com.dy.common.webUtil.BaseResponseUtils; import com.dy.common.webUtil.QueryResultVo; import com.dy.pmsGlobal.aop.OperationDescription; import com.dy.pmsGlobal.pojoBa.BaUser; import com.dy.pmsGlobal.util.Constant; import com.mysql.cj.util.StringUtils; @@ -44,6 +45,7 @@ * @return 默认密码 */ @GetMapping(path = "defaultPassword") @OperationDescription("客户端请求得到默认密码") public BaseResponse<String> defaultPassword(){ if(defaultTrueRandomFalsePassword){ return BaseResponseUtils.buildSuccess(defaultPassword) ; @@ -60,6 +62,7 @@ @PostMapping(path = "some", consumes = MediaType.APPLICATION_JSON_VALUE) //@SsoAop() //只有登录验证,没有权限验证 @SsoPowerAop(power = "10100010") //登录与权限同时验证 @OperationDescription("分页查询用户") public BaseResponse<QueryResultVo<List<BaUser>>> some(@RequestBody QueryVo vo) { try { QueryResultVo<List<BaUser>> res = this.sv.selectSome(vo); @@ -78,6 +81,7 @@ @GetMapping(path = "one") //@SsoAop() //只有登录验证,没有权限验证 @SsoPowerAop(power = "10100010") //登录与权限同时验证 @OperationDescription("查询单个用户") public BaseResponse<BaUser> one(String id) { try { return BaseResponseUtils.buildSuccess(this.sv.selectById(Long.parseLong(id))); @@ -96,6 +100,7 @@ @PostMapping(path = "save", consumes = MediaType.APPLICATION_JSON_VALUE) //@SsoAop() //只有登录验证,没有权限验证 @SsoPowerAop(power = "10100011") //登录与权限同时验证 @OperationDescription("保存用户信息") public BaseResponse<Boolean> save(@RequestBody @Valid BaUser po, BindingResult bindingResult) { if (bindingResult != null && bindingResult.hasErrors()) { return BaseResponseUtils.buildFail(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage()); @@ -136,6 +141,7 @@ @PostMapping(path = "update", consumes = MediaType.APPLICATION_JSON_VALUE) //@SsoAop() //只有登录验证,没有权限验证 @SsoPowerAop(power = "10100011") //登录与权限同时验证 @OperationDescription("更新用户信息") public BaseResponse<Boolean> update(@RequestBody @Validated BaUser po, BindingResult bindingResult) { int count; try { @@ -168,6 +174,7 @@ //@GetMapping(path = "changePassword", consumes = MediaType.TEXT_PLAIN_VALUE) @GetMapping(path = "changePassword") @SsoAop() @OperationDescription("修改密码") public BaseResponse<Boolean> changePassword(String id, String oldPassword, String newPassword) { int count; try { @@ -220,6 +227,7 @@ @PostMapping(path = "resetPassword", consumes = MediaType.APPLICATION_JSON_VALUE) //@SsoAop() //只有登录验证,没有权限验证 @SsoPowerAop(power = "10100011") //登录与权限同时验证 @OperationDescription("重置密码") public BaseResponse<Boolean> resetPassword(@RequestBody @Validated ResetPasswordVo vo, BindingResult bindingResult) { int count; try { pms-parent/pms-web-sso/src/main/java/com/dy/sso/busi/SsoCtrl.java
@@ -4,6 +4,7 @@ import com.dy.common.util.MD5; import com.dy.common.webUtil.BaseResponse; import com.dy.common.webUtil.BaseResponseUtils; import com.dy.pmsGlobal.aop.OperationDescription; import com.dy.pmsGlobal.pojoBa.BaUser; import com.mysql.cj.util.StringUtils; import jakarta.servlet.http.HttpServletRequest; @@ -45,6 +46,7 @@ * @return 登录用户值对象 */ @PostMapping(path = "login", consumes = MediaType.APPLICATION_JSON_VALUE)//前端提交json数据 @OperationDescription("用户登录(json)") public BaseResponse<UserVo> login(@RequestBody @Valid LoginVo vo, BindingResult bindingResult) { try { if(bindingResult != null && bindingResult.hasErrors()){ @@ -63,6 +65,7 @@ * @return 登录用户值对象 */ @PostMapping(path = "loginForm", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)//前端提交form表单数据 @OperationDescription("用户登录(form)") public BaseResponse<UserVo> loginForm(@RequestBody @Valid LoginVo vo, BindingResult bindingResult){ try{ if(bindingResult != null && bindingResult.hasErrors()){ @@ -82,6 +85,7 @@ * @return 正常退出登录返回true,否则返回false */ @GetMapping(path = "logout") @OperationDescription("退出登录") public BaseResponse<Boolean> logout(HttpServletRequest hr){ try{ String token = hr.getHeader("token") ;