Commit c5935130 by kenzo

merge

parents ab4c94e7 693c0e52
......@@ -42,6 +42,16 @@
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>retrofit</artifactId>
<version>2.9.0</version>
......@@ -112,6 +122,11 @@
<artifactId>easy-captcha</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.21</version>
</dependency>
</dependencies>
......
......@@ -4,25 +4,31 @@ import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.IdcardUtil;
import com.cnooc.expert.common.constant.TokenConstants;
import com.cnooc.expert.common.exception.BusinessException;
import com.cnooc.expert.common.exception.GlobalErrorCodeConstants;
import com.cnooc.expert.common.utils.JwtUtils;
import com.cnooc.expert.common.utils.Sm2Util;
import com.cnooc.expert.common.utils.UserUtils;
import com.cnooc.expert.common.utils.ValidUtils;
import com.cnooc.expert.external.expert.auth.service.LoginServicesClient;
import com.cnooc.expert.external.expert.model.response.ExpertInfoAppResp;
import com.cnooc.expert.external.expert.model.response.ExpertInfoResp;
import com.cnooc.expert.system.entity.pojo.ZhuanJiaUser;
import com.cnooc.expert.system.entity.vo.LoginVO;
import com.cnooc.expert.system.entity.vo.VerifyCodeVO;
import com.cnooc.expert.system.entity.vo.ZhuanJiaInfoAppVo;
import com.cnooc.expert.system.entity.vo.ZhuanJiaInfoVo;
import com.cnooc.expert.auth.service.LoginService;
import com.cnooc.expert.auth.service.SmsService;
import com.cnooc.expert.auth.service.SysCaptchaService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.security.crypto.password.PasswordEncoder;
import javax.annotation.Resource;
import java.time.Duration;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
/**
* @Author: songYuHang
......@@ -32,8 +38,8 @@ import java.util.UUID;
@Slf4j
public class LoginServiceImpl implements LoginService {
@Autowired
private StringRedisTemplate redisTemplate;
@Resource(name="redisCommonTemplate")
private RedisTemplate<String, Object> redisTemplate;
@Autowired
private SmsService smsService;
......@@ -60,6 +66,7 @@ public class LoginServiceImpl implements LoginService {
@Override
public String login(LoginVO loginVO) {
log.info("开始执行登录逻辑");
ValidUtils.isNotNull(loginVO.getLoginType(), GlobalErrorCodeConstants.PARAM_REQUIRED);
String token;
switch (loginVO.getLoginType()) {
case ID_NUMBER_PASSWORD:
......@@ -89,11 +96,11 @@ public class LoginServiceImpl implements LoginService {
//return Result.success("验证码已发送");
boolean flag = sysCaptchaService.validate(vo.getKey(), vo.getCaptcha());
if(!flag){
return "验证码错误";
throw new BusinessException(GlobalErrorCodeConstants.CAPTCHA_EXPIRED.getCode(),GlobalErrorCodeConstants.CAPTCHA_EXPIRED.getMsg());
}else{
boolean smsfalg = smsService.sendSmsCode(vo.getPhoneNumber());
if(!smsfalg) {
return "短信验证码发送失败";
throw new BusinessException(GlobalErrorCodeConstants.SEND_SMS_ERROR.getCode(),GlobalErrorCodeConstants.SEND_SMS_ERROR.getMsg());
} else {
return "短信验证码发送成功";
}
......@@ -107,41 +114,38 @@ public class LoginServiceImpl implements LoginService {
ValidUtils.isText(loginVO.getPhoneCode(), "请输入验证码");
ValidUtils.isTrue(Validator.isMobile(loginVO.getPhoneNumber()), "请输入正确格式的手机号");
ValidUtils.isText(loginVO.getPassword(), "请输入密码");
ValidUtils.isValidPassword(loginVO.getPassword(),GlobalErrorCodeConstants.PARAM_PASSWORD_FORMAT_ERROR);
//1.根据手机号去库中查询是否存在
ZhuanJiaInfoVo zhuanJiaInfoVo = new ZhuanJiaInfoVo();
zhuanJiaInfoVo.setMobile(loginVO.getPhoneNumber());
zhuanJiaInfoVo = loginServicesClient.querySingleByShengFenZhengOrMobile(zhuanJiaInfoVo);
if(zhuanJiaInfoVo == null){
return "用户信息不存在";
ExpertInfoResp expertInfoResp = loginServicesClient.querySingleByShengFenZhengOrMobile(loginVO.getPhoneNumber(),null);
if(expertInfoResp == null){
throw new BusinessException(GlobalErrorCodeConstants.USER_NOT_EXISTS.getCode(),GlobalErrorCodeConstants.USER_NOT_EXISTS.getMsg());
}
//2.判断密码是否存在
ZhuanJiaInfoAppVo zhuanJiaInfoAppVo = new ZhuanJiaInfoAppVo();
zhuanJiaInfoAppVo.setBaseGuid(zhuanJiaInfoVo.getBaseGuid());
zhuanJiaInfoAppVo = loginServicesClient.getZhuanJiaInfoAppById(zhuanJiaInfoAppVo);
ExpertInfoAppResp expertInfoAppResp = loginServicesClient.getZhuanJiaInfoAppById(expertInfoResp.getZhuanJiaGuid());
String pwd = Sm2Util.decrypt(loginVO.getPassword());
if(zhuanJiaInfoAppVo == null){
if(expertInfoAppResp == null){
//没有记录的话就是新建记录
zhuanJiaInfoAppVo = new ZhuanJiaInfoAppVo();
zhuanJiaInfoAppVo.setPassword(passwordEncoder.encode(pwd));
loginServicesClient.saveZhuanJiaInfoApp(zhuanJiaInfoAppVo);
loginServicesClient.saveZhuanJiaInfoApp(null,passwordEncoder.encode(pwd));
}else{
//否则更新密码
zhuanJiaInfoAppVo.setPassword(passwordEncoder.encode(pwd));
loginServicesClient.updateZhuanJiaInfoApp(zhuanJiaInfoAppVo);
loginServicesClient.updateZhuanJiaInfoApp(expertInfoAppResp.getBaseGuid(),passwordEncoder.encode(pwd));
}
//手机号,验证码,图形验证码都需要判断
//判断密码是否符合规则
//进行解密处理
//调用数据库更新密码
return "ok";
return "密码重置成功";
}
@Override
public String verifyCode(VerifyCodeVO codeVO) {
log.info("手机验证码验证逻辑");
ValidUtils.isText(codeVO.getPhoneNumber(), "请输入手机号");
ValidUtils.isText(codeVO.getPhoneCode(), "请输入验证码");
ValidUtils.isTrue(Validator.isMobile(codeVO.getPhoneNumber()), "请输入正确格式的手机号");
boolean smsfalg = smsService.verifySmsCode(codeVO.getPhoneNumber(),codeVO.getPhoneCode());
if(!smsfalg){
return "短信验证码验证失败";
throw new BusinessException(GlobalErrorCodeConstants.CAPTCHA_EXPIRED.getCode(),GlobalErrorCodeConstants.CAPTCHA_EXPIRED.getMsg());
}else{
return "短信验证码验证成功";
}
......@@ -158,41 +162,41 @@ public class LoginServiceImpl implements LoginService {
ValidUtils.isText(loginVO.getIdNumber(), "请输入身份证号");
ValidUtils.isText(loginVO.getPassword(), "请输入密码");
ValidUtils.isTrue(IdcardUtil.isValidCard(loginVO.getIdNumber()), "请输入正确的身份证号");
ZhuanJiaInfoVo zhuanJiaInfoVo = new ZhuanJiaInfoVo();
zhuanJiaInfoVo.setShengfenzheng(loginVO.getIdNumber());
zhuanJiaInfoVo = loginServicesClient.querySingleByShengFenZhengOrMobile(zhuanJiaInfoVo);
if(zhuanJiaInfoVo == null){
return "用户信息不存在";
}
ZhuanJiaInfoAppVo zhuanJiaInfoAppVo = new ZhuanJiaInfoAppVo();
zhuanJiaInfoAppVo.setBaseGuid(zhuanJiaInfoVo.getBaseGuid());
zhuanJiaInfoAppVo = loginServicesClient.getZhuanJiaInfoAppById(zhuanJiaInfoAppVo);
if(zhuanJiaInfoAppVo == null){
return "该用户还没有设置密码";
ValidUtils.isValidPassword(loginVO.getPassword(),GlobalErrorCodeConstants.PARAM_PASSWORD_FORMAT_ERROR);
ExpertInfoResp expertInfoResp = loginServicesClient.querySingleByShengFenZhengOrMobile(null,loginVO.getIdNumber());
if(expertInfoResp == null){
throw new BusinessException(GlobalErrorCodeConstants.USER_NOT_EXISTS.getCode(),GlobalErrorCodeConstants.USER_NOT_EXISTS.getMsg());
}
ExpertInfoAppResp expertInfoAppResp = loginServicesClient.getZhuanJiaInfoAppById(expertInfoResp.getZhuanJiaGuid());
if(expertInfoAppResp == null){
throw new BusinessException(GlobalErrorCodeConstants.PASSWORD_NOT_EXIST.getCode(),GlobalErrorCodeConstants.PASSWORD_NOT_EXIST.getMsg());
}
// 验证码效验
boolean flag = sysCaptchaService.validate(loginVO.getKey(), loginVO.getCaptcha());
if (!flag) {
// 保存登录日志
//sysLogLoginService.save(login.getUsername(), Constant.FAIL, LoginOperationEnum.CAPTCHA_FAIL.getValue());
throw new BusinessException("图形验证码错误");
throw new BusinessException(GlobalErrorCodeConstants.CAPTCHA_EXPIRED.getCode(),GlobalErrorCodeConstants.CAPTCHA_EXPIRED.getMsg());
}
//1.需要去库中查询,是否存在
//2.存在校验密码
//解密
String pwd = Sm2Util.decrypt(loginVO.getPassword());
flag = passwordEncoder.matches(pwd, zhuanJiaInfoAppVo.getPassword());
flag = passwordEncoder.matches(pwd, expertInfoAppResp.getPassword());
if (!flag) {
// 登录日志
//sysLogLoginService.savePortal(login.getAccountName(), Constant.FAIL, LoginOperationEnum.ACCOUNT_FAIL.getValue(), 1);
throw new IllegalArgumentException("密码错误");
throw new BusinessException(GlobalErrorCodeConstants.PASSWORD_ERROR.getCode(),GlobalErrorCodeConstants.PASSWORD_ERROR.getMsg());
}
//3.生成相应的uuid作为redis的key
// // todo userid
String uuidKey = UUID.randomUUID().toString();
String token = JwtUtils.createToken(1,uuidKey);
tokenSetRedis(token, uuidKey);
ZhuanJiaUser zhuanJiaUser = convert2ZhuanjiaUser( expertInfoResp );
redisTemplate.opsForValue().set(TokenConstants.LOGIN_USER_KEY_ + expertInfoResp.getZhuanJiaGuid(), zhuanJiaUser, 48, TimeUnit.HOURS);
UserUtils.setUserId(zhuanJiaUser);
String token = JwtUtils.createToken(expertInfoResp.getZhuanJiaGuid(),uuidKey);
//6.返回token
return token;
}
......@@ -208,33 +212,55 @@ public class LoginServiceImpl implements LoginService {
ValidUtils.isText(loginVO.getPhoneCode(), "请输入验证码");
ValidUtils.isTrue(Validator.isMobile(loginVO.getPhoneNumber()), "请输入正确格式的手机号");
//1.根据手机号去库中查询是否存在
ZhuanJiaInfoVo zhuanJiaInfoVo = new ZhuanJiaInfoVo();
zhuanJiaInfoVo.setMobile(loginVO.getPhoneNumber());
zhuanJiaInfoVo = loginServicesClient.querySingleByShengFenZhengOrMobile(zhuanJiaInfoVo);
if(zhuanJiaInfoVo == null){
return "用户信息不存在";
ExpertInfoResp expertInfoResp = loginServicesClient.querySingleByShengFenZhengOrMobile(loginVO.getPhoneNumber(),null);
if(expertInfoResp == null){
throw new BusinessException(GlobalErrorCodeConstants.USER_NOT_EXISTS.getCode(),GlobalErrorCodeConstants.USER_NOT_EXISTS.getMsg());
}
//2.存在校验验证码
if (!smsService.verifySmsCode(loginVO.getPhoneNumber(), loginVO.getPhoneCode())) {
//登录日志
//sysLogLoginService.savePortal(login.getPhone(), Constant.FAIL, LoginOperationEnum.CAPTCHA_FAIL.getValue(), 1);
throw new IllegalArgumentException("手机验证码错误");
throw new BusinessException(GlobalErrorCodeConstants.CAPTCHA_EXPIRED.getCode(),GlobalErrorCodeConstants.CAPTCHA_EXPIRED.getMsg());
}
//3.生成相应的uuid作为redis的key
// todo userid
String uuidKey = UUID.randomUUID().toString();
String token = JwtUtils.createToken(1,uuidKey);
tokenSetRedis(token, uuidKey);
//expertInfoResp = new ExpertInfoResp();
//expertInfoResp.setZhuanJiaGuid("1234");
ZhuanJiaUser zhuanJiaUser = convert2ZhuanjiaUser( expertInfoResp );
redisTemplate.opsForValue().set(TokenConstants.LOGIN_USER_KEY_ + expertInfoResp.getZhuanJiaGuid(), zhuanJiaUser, 48, TimeUnit.HOURS);
UserUtils.setUserId(zhuanJiaUser);
String token = JwtUtils.createToken(expertInfoResp.getZhuanJiaGuid(),uuidKey);
return token;
}
/**
* 缓存存入token
* @param token token
* @param uuidKey uuidKey
*/
private void tokenSetRedis(String token, String uuidKey) {
String redisTokenKey = TokenConstants.TOKEN_KEY_ + uuidKey;
redisTemplate.opsForValue().set(redisTokenKey, token, Duration.ofHours(24));
// /**
// * 缓存存入token
// * @param token token
// * @param uuidKey uuidKey
// */
// private void tokenSetRedis(String token, String uuidKey) {
// String redisTokenKey = TokenConstants.TOKEN_KEY_ + uuidKey;
// redisTemplate.opsForValue().set(redisTokenKey, token, Duration.ofHours(24));
// }
private ZhuanJiaUser convert2ZhuanjiaUser(ExpertInfoResp expertInfoResp){
if( expertInfoResp == null ){
return null;
}
ZhuanJiaUser zhuanJiaUser = new ZhuanJiaUser();
zhuanJiaUser.setZhuanJiaGuid(expertInfoResp.getZhuanJiaGuid());
zhuanJiaUser.setMobile(expertInfoResp.getMobile());
zhuanJiaUser.setShenFenZheng(expertInfoResp.getShenFenZheng());
zhuanJiaUser.setShiFouYiFaZhuanJia(expertInfoResp.getShiFouYiFaZhuanJia());
zhuanJiaUser.setZhuanJiaCode(expertInfoResp.getZhuanJiaCode());
zhuanJiaUser.setSuoShuBuMeng(expertInfoResp.getSuoShuBuMeng());
zhuanJiaUser.setZhuanJiaName(expertInfoResp.getZhuanJiaName());
zhuanJiaUser.setZhuanJiaShiXiangGuid(expertInfoResp.getZhuanJiaShiXiangGuid());
zhuanJiaUser.setZhuanJiaZhuangTai(expertInfoResp.getZhuanJiaZhuangTai());
return zhuanJiaUser;
}
}
......@@ -33,7 +33,7 @@ public class SysCaptchaServiceImpl implements SysCaptchaService {
// 保存到缓存
String redisKey = RedisKeys.getCaptchaKey(key);
//redisTemplate.opsForValue().set(redisKey, captcha.text(), EXPIRE_MINUTES, TimeUnit.MINUTES);
redisTemplate.opsForValue().set(redisKey, captcha.text(), EXPIRE_MINUTES, TimeUnit.MINUTES);
// 封装返回数据
SysCaptchaVO captchaVO = new SysCaptchaVO();
......
......@@ -33,4 +33,8 @@ public class TokenConstants
*/
public static final String TOKEN_KEY_ = "TOKEN:TOKEN_KEY_";
/**
* 用于登录用户信息的key
*/
public static final String LOGIN_USER_KEY_ = "LOGIN:USER_KEY_";
}
......@@ -18,17 +18,20 @@ public interface GlobalErrorCodeConstants {
ErrorCode CAPTCHA_EXPIRED = new ErrorCode(1011, "验证码错误");
ErrorCode CODE_REDIS_KEY = new ErrorCode(1011, "验证码已过期");
ErrorCode SYSTEM_ERROR = new ErrorCode(1012, "系统内部异常");
ErrorCode SEND_SMS_ERROR = new ErrorCode(1013, "发送短信验证码失败");
// ========== 用户认证相关错误 (2000-2999) ==========
ErrorCode LOGIN_EXPIRED = new ErrorCode(2001, "请先登录");
ErrorCode USER_NOT_EXISTS = new ErrorCode(2002, "用户不存在");
ErrorCode PASSWORD_ERROR = new ErrorCode(2003, "密码错误");
ErrorCode USER_DISABLED = new ErrorCode(2004, "用户已被禁用");
ErrorCode PASSWORD_NOT_EXIST = new ErrorCode(2005, "密码不存在,请先重置密码");
// ========== 参数校验错误 (3000-3999) ==========
ErrorCode PARAM_REQUIRED = new ErrorCode(3001, "必填字段不能为空");
ErrorCode PARAM_FORMAT_ERROR = new ErrorCode(3002, "参数格式不正确");
ErrorCode PARAM_RANGE_ERROR = new ErrorCode(3003, "参数超出范围");
ErrorCode PARAM_PASSWORD_FORMAT_ERROR = new ErrorCode(3004, "密码强度不符合要求:密码必须包含大小写字母、数字和特殊字符,且长度不少于8位");
// ========== 业务逻辑错误 (4000-4999) ==========
ErrorCode OPERATION_TOO_FREQUENT = new ErrorCode(4001, "操作太频繁,请稍后再试");
......
......@@ -4,6 +4,7 @@ import com.cnooc.expert.common.response.ApiResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
......@@ -59,6 +60,18 @@ public class GlobalExceptionHandler {
return ApiResult.error(GlobalErrorCodeConstants.SYSTEM_ERROR.getCode(), GlobalErrorCodeConstants.SYSTEM_ERROR.getMsg());
}
/**
* 处理 HTTP 方法不支持异常
*/
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
public ApiResult<String> handleHttpRequestMethodNotSupportedException(
HttpRequestMethodNotSupportedException e, HttpServletRequest request) {
log.warn("HTTP方法不支持: {},请求URL: {}", e.getMessage(), request.getRequestURI());
return ApiResult.error(HttpStatus.METHOD_NOT_ALLOWED.value(),
"不支持 " + e.getMethod() + " 请求方法 ");
}
@ExceptionHandler(Exception.class)
public ApiResult<String> handleException(Exception e, HttpServletRequest request) {
log.error("系统异常: {},请求URL: {}", e.getMessage(), request.getRequestURI(), e);
......
......@@ -7,13 +7,16 @@ import com.cnooc.expert.common.exception.GlobalErrorCodeConstants;
import com.cnooc.expert.common.utils.JwtUtils;
import com.cnooc.expert.common.utils.UserUtils;
import com.cnooc.expert.common.utils.ValidUtils;
import com.cnooc.expert.system.entity.pojo.ZhuanJiaUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
......@@ -26,13 +29,14 @@ import java.util.Map;
@Component
public class LoginInterceptor implements HandlerInterceptor {
@Autowired
private StringRedisTemplate redisTemplate;
@Resource(name="redisCommonTemplate")
private RedisTemplate<String, Object> redisTemplate;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token = request.getHeader("Authorization");
log.info("request uri :"+request.getRequestURI());
if (token == null || token.trim().isEmpty()) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
throw new BusinessException(HttpServletResponse.SC_UNAUTHORIZED, GlobalErrorCodeConstants.LOGIN_EXPIRED.getMsg());
......@@ -43,16 +47,13 @@ public class LoginInterceptor implements HandlerInterceptor {
String uuidKey = userMap.get(TokenConstants.UUID_KEY);
ValidUtils.isNotNull(uuidKey, "登录异常,请重新登录");
// String cachedToken = redisTemplate.opsForValue().get(TokenConstants.TOKEN_KEY_ + userId);
//
// if (cachedToken == null || !cachedToken.equals(token)) {
// // token不存在或不匹配,说明已退出登录或token失效
// response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
// response.getWriter().write("{\"code\":401,\"msg\":\"请先登录\"}");
// return false;
// }
// todo 通过token解析出用户id,代用UserUtils.setUserId(userId)方法进行存储
ZhuanJiaUser zhuanjiaUser = (ZhuanJiaUser)redisTemplate.opsForValue().get(TokenConstants.LOGIN_USER_KEY_ + userId);
if (zhuanjiaUser==null ){
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write("{\"httpCode\":401,\"message\":\"请先登录\"}");
return false;
}
UserUtils.setUserId(zhuanjiaUser);
// 所有条件都满足,放行请求
return true;
......
......@@ -28,7 +28,7 @@ public class JwtUtils {
* 生成token
* @return token字符串
*/
public static String createToken(Integer userId , String uuidKey) {
public static String createToken(String userId , String uuidKey) {
// 生成token
return Jwts.builder()
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
......@@ -63,7 +63,7 @@ public class JwtUtils {
public static void main(String[] args) throws Exception{
String portalToken = JwtUtils.createToken(111, "testtest");
String portalToken = JwtUtils.createToken("111", "testtest");
Thread.sleep(5000);
Map<String, String> claims = JwtUtils.getTokenInfo(portalToken);
System.out.print(JSON.toJSONString(claims, true));
......
package com.cnooc.expert.common.utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.support.SendResult;
import org.springframework.stereotype.Component;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.util.concurrent.ListenableFutureCallback;
@Component
public class KafkaProducerUtil {
@Autowired
private KafkaTemplate<String, Object> kafkaTemplate;
/**
* 发送消息到指定主题
* @param topic 主题名称
* @param message 消息内容
*/
public void sendMessage(String topic, Object message) {
kafkaTemplate.send(topic, message);
}
/**
* 发送消息到指定主题(带key)
* @param topic 主题名称
* @param key 消息key
* @param message 消息内容
*/
public void sendMessage(String topic, String key, Object message) {
kafkaTemplate.send(topic, key, message);
}
/**
* 发送消息到指定主题(带分区和key)
* @param topic 主题名称
* @param partition 分区
* @param key 消息key
* @param message 消息内容
*/
public void sendMessage(String topic, Integer partition, String key, Object message) {
kafkaTemplate.send(topic, partition, key, message);
}
/**
* 异步发送消息,带回调函数
* @param topic 主题名称
* @param message 消息内容
* @param callback 回调函数
*/
public void sendMessageWithCallback(String topic, Object message,
ListenableFutureCallback<SendResult<String, Object>> callback) {
ListenableFuture<SendResult<String, Object>> future = kafkaTemplate.send(topic, message);
future.addCallback(callback);
}
/**
* 异步发送消息,带默认回调
* @param topic 主题名称
* @param message 消息内容
*/
public void sendMessageWithCallback(String topic, Object message) {
ListenableFuture<SendResult<String, Object>> future = kafkaTemplate.send(topic, message);
future.addCallback(new ListenableFutureCallback<SendResult<String, Object>>() {
@Override
public void onSuccess(SendResult<String, Object> result) {
System.out.println("发送消息成功: " + message + ", offset: " +
result.getRecordMetadata().offset());
}
@Override
public void onFailure(Throwable ex) {
System.err.println("发送消息失败: " + message + ", 错误: " + ex.getMessage());
}
});
}
}
\ No newline at end of file
......@@ -90,5 +90,11 @@ public class ValidUtils {
}
}
//判断是否有效的密码
public static void isValidPassword(String password, ErrorCode errorCode) {
String passwordRegex = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[!@#$%^&*()_+\\-=\\[\\]{};':\"\\\\|,.<>\\/?~`])[a-zA-Z\\d!@#$%^&*()_+\\-=\\[\\]{};':\"\\\\|,.<>\\/?~`]{8,}$";
if (!password.matches(passwordRegex)) {
throw new BusinessException(errorCode.getCode(), errorCode.getMsg());
}
}
}
package com.cnooc.expert.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Bean(name="redisCommonTemplate")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
// 使用 StringRedisSerializer 来序列化和反序列化 redis 的 key 值
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
// 使用 GenericJackson2JsonRedisSerializer 来序列化和反序列化 redis 的 value 值
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
template.afterPropertiesSet();
return template;
}
@Bean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
\ No newline at end of file
......@@ -30,9 +30,34 @@ public class TheWebMvcConfigurer implements WebMvcConfigurer {
// registry.addInterceptor(webAuthInterceptor());
// }
<<<<<<< HEAD
// @Bean-
// public WebAuthInterceptor webAuthInterceptor() {
// return new WebAuthInterceptor();
// }
=======
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册登录拦截器,并设置拦截路径和排除路径
registry.addInterceptor(loginInterceptor)
.addPathPatterns("/**") // 拦截所有路径
.excludePathPatterns( // 排除一些路径
"/sys/**",
"/verify/**",
"/person/**",
"/text/**",
"/error/**",
"/error"
);
registry.addInterceptor(webAuthInterceptor());
}
@Bean
public WebAuthInterceptor webAuthInterceptor() {
return new WebAuthInterceptor();
}
>>>>>>> 693c0e523aee3f3c218470be2387b4420ce73972
}
package com.cnooc.expert.controller.auth;
import com.alibaba.fastjson.JSON;
import com.cnooc.expert.auth.service.SysCaptchaService;
import com.cnooc.expert.common.constant.TokenConstants;
import com.cnooc.expert.common.response.ApiResult;
import com.cnooc.expert.auth.service.LoginService;
import com.cnooc.expert.common.utils.JwtUtils;
import com.cnooc.expert.common.utils.KafkaProducerUtil;
import com.cnooc.expert.external.expert.model.response.ExpertInfoResp;
import com.cnooc.expert.system.entity.pojo.ZhuanJiaUser;
import com.cnooc.expert.system.entity.vo.LoginVO;
import com.cnooc.expert.system.entity.vo.SysCaptchaVO;
import com.cnooc.expert.system.entity.vo.VerifyCodeVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@Slf4j
@RestController
@RequestMapping("/sys")
public class LoginController {
@Autowired
private LoginService loginService;
@Autowired
private SysCaptchaService sysCaptchaService;
// 测试代码,先注掉
// @Autowired
// private KafkaProducerUtil kafkaProducerUtil;
//
// @Resource(name="redisCommonTemplate")
// private RedisTemplate<String, Object> redisTemplate;
//
// private ZhuanJiaUser convert2ZhuanjiaUser(ExpertInfoResp expertInfoResp){
// if( expertInfoResp == null ){
// return null;
// }
//
// ZhuanJiaUser zhuanJiaUser = new ZhuanJiaUser();
// zhuanJiaUser.setZhuanJiaGuid(expertInfoResp.getZhuanJiaGuid());
// zhuanJiaUser.setMobile(expertInfoResp.getMobile());
// zhuanJiaUser.setShenFenZheng(expertInfoResp.getShenFenZheng());
// zhuanJiaUser.setShiFouYiFaZhuanJia(expertInfoResp.getShiFouYiFaZhuanJia());
// zhuanJiaUser.setZhuanJiaCode(expertInfoResp.getZhuanJiaCode());
// zhuanJiaUser.setSuoShuBuMeng(expertInfoResp.getSuoShuBuMeng());
// zhuanJiaUser.setZhuanJiaName(expertInfoResp.getZhuanJiaName());
// zhuanJiaUser.setZhuanJiaShiXiangGuid(expertInfoResp.getZhuanJiaShiXiangGuid());
// zhuanJiaUser.setZhuanJiaZhuangTai(expertInfoResp.getZhuanJiaZhuangTai());
//
// return zhuanJiaUser;
// }
//
// /**
// * 手机号验证码/身份证号密码 登录功能
// * @return Result<String> 统一返回操作码及信息
// */
// @GetMapping("/test")
// public ApiResult<String> test() {
// // 校验loginType 不为空
//
//
// ExpertInfoResp expertInfoResp = new ExpertInfoResp();
// expertInfoResp.setZhuanJiaGuid("1234");
//
// ZhuanJiaUser zhuanJiaUser = convert2ZhuanjiaUser(expertInfoResp);
// zhuanJiaUser.setZhuanJiaZhuangTai((short)2);
// zhuanJiaUser.setMobile("18611383771");
// zhuanJiaUser.setZhuanJiaCode("ttt");
// zhuanJiaUser.setZhuanJiaGuid("11111111111");
// zhuanJiaUser.setZhuanJiaName("weisong");
// zhuanJiaUser.setSuoShuBuMeng("技术部");
//
//
// redisTemplate.opsForValue().set(TokenConstants.LOGIN_USER_KEY_ + zhuanJiaUser.getZhuanJiaGuid(), zhuanJiaUser, 48, TimeUnit.HOURS);
//
// log.info("set complete: "+TokenConstants.LOGIN_USER_KEY_ + zhuanJiaUser.getZhuanJiaGuid());
//
// ZhuanJiaUser zhuanjiaUser1 = (ZhuanJiaUser)redisTemplate.opsForValue().get(TokenConstants.LOGIN_USER_KEY_ + zhuanJiaUser.getZhuanJiaGuid());
//
// log.info("get complete:");
//
// log.info(JSON.toJSONString(zhuanjiaUser1));
//
//
// String token = JwtUtils.createToken("1234","ttttt");
// System.out.println("token is: "+token);
//
// kafkaProducerUtil.sendMessage("test-topic", zhuanjiaUser1);
// return ApiResult.success();
// }
/**
* 手机号验证码/身份证号密码 登录功能
* @param loginVO 登录表单
* @return Result<String> 统一返回操作码及信息
*/
@PostMapping("/login")
public ApiResult<String> login(@Validated @RequestBody LoginVO loginVO) {
// 校验loginType 不为空
return ApiResult.successWithResult(loginService.login(loginVO));
}
/**
* 获取验证码
* @param vo 手机号等信息
* @return Result<Integer> 统一返回操作结果及验证码
*/
// @GetMapping("/sendCode/{phoneNumber}")
@PostMapping("/sendSmsCode")
public ApiResult<String> sendCode(@RequestBody LoginVO vo) {
log.info("获取验证码的手机号: {}", vo.getPhoneNumber());
return ApiResult.successWithResult(loginService.sendPhoneCode(vo));
}
@PostMapping("/verifyCode")
public ApiResult<String> verifyCode(@RequestBody VerifyCodeVO codeVO) {
return ApiResult.successWithResult(loginService.verifyCode(codeVO));
}
/**
* 账号修改
* @param loginVO
* @return
*/
@PostMapping("/changePass")
public ApiResult<String> changePass(@RequestBody LoginVO loginVO) {
return ApiResult.successWithResult(loginService.changePass(loginVO));
}
@GetMapping("/captcha")
public ApiResult<Map<String, String>> captcha() {
SysCaptchaVO captchaVO = sysCaptchaService.generate();
// 5. 构建响应
Map<String, String> response = new HashMap<>();
response.put("captchaId", captchaVO.getKey());
response.put("image", captchaVO.getImage());
return ApiResult.successWithResult(response);
}
/**
* 验证图片验证码
*/
@PostMapping("/verifyCaptcha")
public ResponseEntity<Map<String, Object>> verifyCaptchaNew(
@RequestParam String captchaId,
@RequestParam String inputCode) {
Map<String, Object> result = new HashMap<>();
boolean flag = sysCaptchaService.validate(captchaId, inputCode);
String msg = "验证成功";
if (!flag) {
msg = "验证失败";
}
result.put("success", flag);
result.put("message", msg);
return ResponseEntity.ok(result);
}
}
package com.cnooc.expert.external.expert.api;
<<<<<<< HEAD
import com.cnooc.expert.external.expert.model.request.ExpertInfoGetReq;
import com.cnooc.expert.external.expert.model.response.ExpertInfoGetTestResp;
=======
import com.cnooc.expert.external.expert.model.request.ExpertInfoAppReq;
import com.cnooc.expert.external.expert.model.request.ExpertInfoReq;
import com.cnooc.expert.external.expert.model.response.ExpertInfoAppResp;
import com.cnooc.expert.external.expert.model.response.ExpertInfoResp;
>>>>>>> 693c0e523aee3f3c218470be2387b4420ce73972
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.HeaderMap;
......@@ -10,6 +17,20 @@ import retrofit2.http.POST;
import java.util.Map;
public interface LoginServiceApi {
<<<<<<< HEAD
@POST("/")
Call<ExpertInfoGetTestResp> expertDetailUpDate(@HeaderMap Map<String, Object> headers, @Body ExpertInfoGetReq user);
=======
@POST("/zjfw/zggrxxgl/querySingleByShengFenZhengOrMobile")
Call<ExpertInfoResp> querySingleByShengFenZhengOrMobile(@HeaderMap Map<String, Object> headers, @Body ExpertInfoReq expertInfoReq);
@POST("/zjfw/zggrxxgl/getZhuanJiaInfoAppById")
Call<ExpertInfoAppResp> getZhuanJiaInfoAppById(@HeaderMap Map<String, Object> headers, @Body ExpertInfoAppReq expertInfoAppReq);
@POST("/zjfw/zggrxxgl/saveZhuanJiaInfoApp")
Call<ExpertInfoAppResp> saveZhuanJiaInfoApp(@HeaderMap Map<String, Object> headers, @Body ExpertInfoAppReq expertInfoAppReq);
@POST("/zjfw/zggrxxgl/updateZhuanJiaInfoApp")
Call<ExpertInfoAppResp> updateZhuanJiaInfoApp(@HeaderMap Map<String, Object> headers, @Body ExpertInfoAppReq expertInfoAppReq);
>>>>>>> 693c0e523aee3f3c218470be2387b4420ce73972
}
package com.cnooc.expert.external.expert.auth.service;
import com.cnooc.expert.external.common.AbstractRetrofitManager;
import com.cnooc.expert.system.entity.vo.ZhuanJiaInfoVo;
import com.cnooc.expert.system.entity.vo.ZhuanJiaInfoAppVo;
import com.cnooc.expert.external.expert.api.LoginServiceApi;
import com.cnooc.expert.external.expert.model.request.ExpertInfoAppReq;
import com.cnooc.expert.external.expert.model.request.ExpertInfoReq;
import com.cnooc.expert.external.expert.model.response.ExpertInfoAppResp;
import com.cnooc.expert.external.expert.model.response.ExpertInfoResp;
import com.google.common.collect.Maps;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import retrofit2.Call;
import retrofit2.Retrofit;
import java.util.Map;
@Service
public class LoginServicesClient extends AbstractRetrofitManager {
public ZhuanJiaInfoVo querySingleByShengFenZhengOrMobile(ZhuanJiaInfoVo zhuanJiaInfoVo){
ZhuanJiaInfoVo res = new ZhuanJiaInfoVo();
private final LoginServiceApi loginServiceApi;
public LoginServicesClient(@Qualifier("retrofitExpert") Retrofit retrofit) {
this.loginServiceApi = retrofit.create(LoginServiceApi.class);
}
public ExpertInfoResp querySingleByShengFenZhengOrMobile(String mobile,String shenfenzheng){
Map<String, Object> headers = Maps.newHashMap();
ExpertInfoReq expertInfoReq = new ExpertInfoReq();
expertInfoReq.setMobile(mobile);
expertInfoReq.setShengfenzheng(shenfenzheng);
Call<ExpertInfoResp> call = loginServiceApi.querySingleByShengFenZhengOrMobile(headers,expertInfoReq);
return this.getResponseBody(call, "querySingleByShengFenZhengOrMobile");
/* String jsonString = JsonUtils.toJsonString(zhuanJiaInfoVo);
res = RestUtils.sendPostRequest2Expert("/zjfw/zggrxxgl/querySingleByShengFenZhengOrMobile",jsonString,null);
*/ return res;
*/
}
public ZhuanJiaInfoAppVo getZhuanJiaInfoAppById(ZhuanJiaInfoAppVo zhuanJiaInfoAppVo){
ZhuanJiaInfoAppVo res = new ZhuanJiaInfoAppVo();
public ExpertInfoAppResp getZhuanJiaInfoAppById(String baseGuid){
ExpertInfoAppReq expertInfoAppReq = new ExpertInfoAppReq();
Map<String, Object> headers = Maps.newHashMap();
expertInfoAppReq.setBaseGuid(baseGuid);
Call<ExpertInfoAppResp> call = loginServiceApi.getZhuanJiaInfoAppById(headers,expertInfoAppReq);
return this.getResponseBody(call, "getZhuanJiaInfoAppById");
/* String jsonString = JsonUtils.toJsonString(zhuanJiaInfoAppVo);
res = RestUtils.sendPostRequest2Expert("/zjfw/zggrxxgl/getZhuanJiaInfoAppById",jsonString,null);*/
return res;
}
public ZhuanJiaInfoAppVo saveZhuanJiaInfoApp(ZhuanJiaInfoAppVo zhuanJiaInfoAppVo){
ZhuanJiaInfoAppVo res = new ZhuanJiaInfoAppVo();
public ExpertInfoAppResp saveZhuanJiaInfoApp(String baseGuid,String password){
ExpertInfoAppReq expertInfoAppReq = new ExpertInfoAppReq();
Map<String, Object> headers = Maps.newHashMap();
expertInfoAppReq.setBaseGuid(baseGuid);
expertInfoAppReq.setPassword(password);
Call<ExpertInfoAppResp> call = loginServiceApi.saveZhuanJiaInfoApp(headers,expertInfoAppReq);
return this.getResponseBody(call, "saveZhuanJiaInfoApp");
/* String jsonString = JsonUtils.toJsonString(zhuanJiaInfoAppVo);
res = RestUtils.sendPostRequest2Expert("/zjfw/zggrxxgl/saveZhuanJiaInfoApp",jsonString,null);*/
return res;
}
public ZhuanJiaInfoAppVo updateZhuanJiaInfoApp(ZhuanJiaInfoAppVo zhuanJiaInfoAppVo){
ZhuanJiaInfoAppVo res = new ZhuanJiaInfoAppVo();
public ExpertInfoAppResp updateZhuanJiaInfoApp(String baseGuid,String password){
ExpertInfoAppReq expertInfoAppReq = new ExpertInfoAppReq();
Map<String, Object> headers = Maps.newHashMap();
expertInfoAppReq.setBaseGuid(baseGuid);
expertInfoAppReq.setPassword(password);
Call<ExpertInfoAppResp> call = loginServiceApi.updateZhuanJiaInfoApp(headers,expertInfoAppReq);
return this.getResponseBody(call, "updateZhuanJiaInfoApp");
/* String jsonString = JsonUtils.toJsonString(zhuanJiaInfoAppVo);
res = RestUtils.sendPostRequest2Expert("/zjfw/zggrxxgl/updateZhuanJiaInfoApp",jsonString,null);*/
return res;
}
}
package com.cnooc.expert.system.entity.vo;
package com.cnooc.expert.external.expert.model.request;
import lombok.Data;
import java.io.Serializable;
@Data
public class ZhuanJiaInfoAppVo implements Serializable {
private static final long serialVersionUID = 1L;
public class ExpertInfoAppReq {
private String baseGuid;
private String password;
}
package com.cnooc.expert.system.entity.vo;
package com.cnooc.expert.external.expert.model.request;
import lombok.Data;
import java.io.Serializable;
@Data
public class ZhuanJiaInfoVo implements Serializable {
public class ExpertInfoReq {
private String baseGuid;
private String mobile;
private String shengfenzheng;
......
package com.cnooc.expert.external.expert.model.response;
import lombok.Data;
@Data
public class ExpertInfoAppResp {
private String baseGuid;
private String password;
}
package com.cnooc.expert.external.expert.model.response;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
@Data
public class ExpertInfoResp {
private String shenFenZheng;
private Long subjectId;
private String subjectName;
private String subjectCode;
private Integer subjectType;
private String tenantId_;
private String tenantName;
private String authPassWithImport;
private String zhuanJiaGuid;
private String zhuanJiaShiXiangGuid;
private String zhuanJiaName;
private String zhuanJiaCode;
private Short zhuanJiaZhuangTai;
private Boolean shiFouYiFaZhuanJia;
private String birthday;
private Boolean sex;
private Short age;
private String mobile;
private String email;
private String zhengZhiMianMao;
private String waiYuChengDu;//东风去掉该字段
private String xueLi;
private String xueWei;
private String xueLiZhuanYe;//东风去掉该字段
private String xueWeiZhuanYe;
private String biYeYuanXiao;
private String graduationDate;
private String jiaTingDiZhi; //通讯地址
private String jiaTingPost;
private String jiaTingPhone;
private Short gongZuoZhuangTai;
private String gongZuoDanWei;
private String gongZuoDanWeiBH;
private String gongZuoDanWeiDiZhi;
private String gongZuoPhone;
private String gongZuoZhiWu;
private String gongZuoPost;
private String gongZuoZhuanYeName;//所学专业
private String gongZuoZhuanYeYears;
private Short pingBiaoTuiJianLX;//东风修改为专家级别
private String pingBiaoChangZhuDiQu;
private String pingBiaoQiTaDiQu;
private String pingBiaoYingJiDiQu;
private Boolean pingBiaoIsYingJi;
private String zhuanYeJingLi;
private String canYuXiangMu;
private String danRenQiTaZhuanJia;
private String zhuanYeTeChang;
private String buNengRuXuanQingKong;
private String fuJianGuids;
private Long ruKuTime;
private String photoGuid;
private Long tiJiaoTime;
private Short shenPiZhuangTai;
private String shenPiRen;
private String shenPiYiJian;
private Long shenPiShiJian;
private Short shenQingLeiXing;
private Short bianGengXuHao;
private Boolean isDeleted;
private String creatorName;
private Long createTime;
private String modifierName;
private Long modifyTime;
private String tuiKuYuanYin;
private List<String> auths; //权限
private String zhangHao;
private String password;
private String chouQuNum;
private Boolean isImport;
private Boolean isXiuGai;
private String fanMianFuJianGuids;
private Long leiJiFenZhi;
private Long leiJiZhanTingTime;
private Long ziDongZanTingEndTime;
private Long ziDongZanTingStartTime;
// 专家聘任期,单位年
private Short zhuanjiaQinRenQi;
// 聘期开始时间
private Long pinqiStartTime;
// 聘期结束时间
private Long pinqiEndTime;
/*--------------------东风系统 增加开始 ------------------------*/
private String yinHangKa;
private String yinHang;
private String yinHang1;
private String minZu;
private String jianKangZhuangKuang;
private String sfzFileGuid;//身份证扫描件
private String fax;
private String byzFileGuid;//毕业证扫描件
private String suoShuBuMeng;//所在部门
private String suoShuHangYe;
private String city;
private String jgdmFileGuid;//机构代码扫描件
private String suoShuZhaoBiaoDaiLi;//所属的招标代理导入的,记录招标代理的jgdm,形成独自的库。注册的专家设置为平台的机构代码
private String mobileGuoJiQuHao;
/*--------------------东风系统 增加结束 ------------------------*/
/****************20180530*******************/
/**
* author yanjw
* 2019-04-26
*/
//
private BigDecimal kaoShiFenShu;
private Long leiJiJiaFen;
private Short jiDu;
//20200916 2.0新加
private String jinJiLianXiRenGuid;
private String jinJiLianXiRenName;
private String jinJiLianXiRenPhone;
private Boolean isSenior;//是否資深專家
private String danweiGuid;//单位GUID
//20221019 是否合格
private Boolean isQualified;
// 是否阅读入库承诺书
private Boolean isReadRuKuPromise;
// 阅读入库承诺书时间
private Long readRuKuPromiseTime;
/**
* 评标专业
*/
private String zhuanYeGuid;
private String zhengJianType;
/**
* 应急状态(0=冻结,1=正常)
*/
private Integer yingJiZhuangTai;
/****************20180530*******************/
/**
* 银行卡正面扫描件
*/
private String yinHangKaFileGuid;
//专家所在地区
private String zhuanJiaSuoZaiDiNames;
private String zhuanJiaSuoZaiDiGuids;
//专家类型
private Short zhuanJiaType;
// 所属专业库(1-新一级专业,2-老一级专业)
private String professionLevel;
// 专家分类:1:一类,2:二类
private Short zhuanJiaFenLei;
// 二开-集团内外专家,0:集团内专家,1:集团外专家
private Boolean inGroup;
// 其他联系方式
private String qiTaLianXiFangShi;
// 是否拥有职业资格
private Boolean isZhiYeZiGe;
// 专家来源类型,0:自主入库,1:指定邀请,2:导入邀请'
private Short zhuanJiaSourceType;
// 所属单位名称
private String suoShuDanWeiName;
// 工作时间
private Long gongZuoTime;
//专家分级 10 A级 20 B级 默认B级
private Short zhuanJiaFenJi;
//二开-廉洁意见书
private String lianJieYiJianShuFuJianGuid;
//二开-是否存在生效期内的廉洁处理意见
private Boolean isHasLianJieChuLiYiJian;
// 二开-AD域账号
private String adAccount;
// 二开-专家综合编号
private String zhuanJiaZongHeBianHao;
// 二开-是否存在生效期内的廉洁处理意见
private Boolean hasLianJieChuLiYiJian;
// 二开-集团公司二级单位编号
private String jiTuanErJiDanWeiCode;
// 二开-集团公司二级单位名称
private String jiTuanErJiDanWeiName;
// 二开-所在其他专家库
private String suoZaiQitaZhuanJiaKu;
// 二开-获奖情况
private String huoJiangQingKuang;
// 二开-资历条件
private String zhuanJiaZiZhiTiaoJian;
// 二开-工作备注
private String gongZuoBeiZhu;
private Boolean isTuiSongSJTJ;//是否已推送到数据统计平台
private Integer tuiSongShiBaiCiShuSJTJ;//推送到数据统计平台失败次数
private String pingBiaoChangZhuDiQuName;
}
package com.cnooc.expert.system.operatelog.aspect;
import com.alibaba.fastjson.JSON;
import com.cnooc.expert.system.operatelog.dto.LogBody;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.cnooc.expert.common.exception.BusinessException;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
@Aspect
@Component
@Order(1)
@Slf4j
public class LogAspectj {
private static final String EXCEPTION_CODE = "500";
private String host="";
@Pointcut("execution(* com.cnooc.expert.controller.auth.*.*(..)) ||"+
"execution(* com.cnooc.expert.controller.expert.*.*(..)) || " +
"execution(* com.cnooc.expert.controller.portal.*.*(..)) || " +
"execution(* com.cnooc.expert.controller.workflow.*.*(..))")
public void loginLog() {
}
/**
* 抛出异常后通知(@AfterThrowing):方法抛出异常退出时执行的通知
* 注意在这里不能使用ProceedingJoinPoint
* 不然会报错ProceedingJoinPoint is only supported for around advice
* throwing注解为错误信息
*
* @param joinPoint
* @param ex
*/
@AfterThrowing(value = "loginLog()", throwing = "ex")
public void afterThrowingMethod(JoinPoint joinPoint, Exception ex) throws Exception {
Map<String,String> resp = new HashMap<>();
if (ex instanceof BusinessException) {
BusinessException BusinessEx = (BusinessException) ex;
resp.put("HttpCode", BusinessEx.getErrorCode()+"");
resp.put("Message", BusinessEx.getMessage());
}else {
resp.put("HttpCode", EXCEPTION_CODE);
resp.put("Message", ex.getMessage());
}
System.out.println("进入afterThrowingMethod方法=========");
this.sendLog( resp);
}
/**
* 返回后通知(@AfterReturning):在某连接点(joinpoint)
* 正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回
* 方法执行完毕之后
* 注意在这里不能使用ProceedingJoinPoint
* 不然会报错ProceedingJoinPoint is only supported for around advice
* crmAspect()指向需要控制的方法
* returning 注解返回值
*
* @param joinPoint
* @param returnValue 返回值
* @throws Exception
*/
@AfterReturning(value = "loginLog()", returning = "returnValue")
public void doAfterReturning(JoinPoint joinPoint, Object returnValue) throws Exception {
System.out.println("进入doAfterReturning方法========");
this.sendLog(returnValue);
}
/**
* 获取当前的request
* 这里如果报空指针异常是因为单独使用spring获取request
* 需要在配置文件里添加监听
* <listener>
* <listener-class>
* org.springframework.web.context.request.RequestContextListener
* </listener-class>
* </listener>
*
* @return
*/
private HttpServletRequest getHttpServletRequest() {
RequestAttributes ra = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes sra = (ServletRequestAttributes) ra;
HttpServletRequest request = sra.getRequest();
return request;
}
private String getCurrentUser() {
//这里需要添加代码
return "";
}
/**
* mysql
* 新增 processRecord
*
* @param returnValue
*/
private void sendLog(Object returnValue) {
try {
System.out.println("进入sendLog方法========");
HttpServletRequest httpServletRequest = getHttpServletRequest();
String method = httpServletRequest.getMethod();
String account = getCurrentUser();
LogBody logBody = new LogBody();
Enumeration<String> headers = httpServletRequest.getHeaderNames();
List<String> headerList = Collections.list(headers);
log.info("[sendLog]enter, headerList:{}", headerList);
logBody.setOperationTs(System.currentTimeMillis());
logBody.setRequestMethod(method);
logBody.setIp(this.getRemoteIP(httpServletRequest));
//请求路径:域名+路径
logBody.setRequestPath(host+httpServletRequest.getRequestURI());
if(null != returnValue && JSON.toJSONString(returnValue).length() > 5000){
logBody.setResponseContent("返回消息体大于5000字符");
}else {
logBody.setResponseContent(JSON.toJSONString(returnValue));
}
System.out.println("logBody对象信息如下=========");
System.out.println(logBody);
//将数据发送到kafka,这里需要加代码逻辑
} catch (Exception e) {
e.printStackTrace();
}
}
public String getRemoteIP(HttpServletRequest request) {
if (request == null) {
return "unknown";
}
String ip = request.getHeader("x-Original-Forwarded-For");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("x-real-ip");
}
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.getHeader("X-Real-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("X-Forwarded-For");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
ip = "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
if (ip.indexOf(":") > 0) {
ip = ip.substring(ip.lastIndexOf(":"));
}
if (ip.indexOf(",") > 0) {
ip = ip.substring(0, ip.indexOf(",")).trim();
}
return ip;
}
}
package com.cnooc.expert.system.operatelog.dto;
import lombok.Data;
@Data
public class LogBody {
/**
* 业务模块标识
*/
private String appId;
/**
* 业务模块名称
*/
private String appName;
/**
* 用户账号
*/
private String account;
/**
* 用户名称
*/
private String userName;
/**
* 操作所在IP地址(用户操作实际ip非系统代理ip)
*/
private String ip;
/**
* 用户操作时间戳(毫秒)服务器时间
*/
private long operationTs;
/**
* 用户所属单位id(取到部门一级)
*/
private Long domainId;
/**
* 用户所属单位名称(取到部门一级)
*/
private String domainName;
/**
* 请求方法
*/
private String requestMethod;
/**
* 请求路径path
*/
private String requestPath;
/**
* 请求参数
*/
private String requestArgs;
/**
* 返回参数,文件下载无需该字段
*/
private String responseContent;
/**
* 身份类型(内部用户、内部供应商、外部供应商、内部专家、外部专家)
*/
private String role;
/**
* 操作事件类型(1:登录,2:登出,3:添加,4:编辑,5:删除,6:查询,7:下载,8:打印,9:导入,10:导出,11:启动,12:停用,13:其它)
*/
private Integer action;
/**
* 操作记录id,使用UUID.randomUUID().toString()生成
*/
private String operateRecordId;
/**
* imos的用户id
*/
private String userId;
}
......@@ -25,5 +25,23 @@ spring:
fail-on-unknown-properties: false
default-property-inclusion: non_null
kafka:
# Kafka服务器地址
bootstrap-servers: localhost:9092
producer:
key-serializer: org.apache.kafka.common.serialization.StringSerializer
value-serializer: org.springframework.kafka.support.serializer.JsonSerializer
properties:
acks: all
retries: 3
batch-size: 16384
linger-ms: 1
buffer-memory: 33554432
server:
port: 9090
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment