Browse Source

feature:添加记录用户行为的逻辑和接口

xuexiaobo 6 years ago
parent
commit
b9cd241c0c

+ 17 - 0
mooctest-user-server/src/main/java/cn/iselab/mooctest/user/mapper/OperationRecordDao.java

@@ -0,0 +1,17 @@
+package cn.iselab.mooctest.user.mapper;
+
+import cn.iselab.mooctest.user.model.OperationRecord;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.repository.CrudRepository;
+
+import javax.transaction.Transactional;
+
+/**
+ * @author: Diors.Po
+ * @Email: 171256175@qq.com
+ * @date 2019-09-15 20:57
+ */
+@Transactional
+public interface OperationRecordDao extends CrudRepository<OperationRecord, Long>, JpaSpecificationExecutor<OperationRecord> {
+
+}

+ 3 - 0
mooctest-user-server/src/main/java/cn/iselab/mooctest/user/service/UserService.java

@@ -1,6 +1,7 @@
 package cn.iselab.mooctest.user.service;
 
 
+import cn.iselab.mooctest.user.model.OperationRecord;
 import cn.iselab.mooctest.user.model.User;
 
 import java.util.List;
@@ -21,6 +22,8 @@ public interface UserService {
 
     User update(User user);
 
+    OperationRecord recordOperation(OperationRecord record);
+
     List<User> findByFuzzyName(String name);
 
     List<User> findByFuzzyEmail(String email);

+ 10 - 0
mooctest-user-server/src/main/java/cn/iselab/mooctest/user/service/impl/UserServiceImpl.java

@@ -1,6 +1,8 @@
 package cn.iselab.mooctest.user.service.impl;
 
+import cn.iselab.mooctest.user.mapper.OperationRecordDao;
 import cn.iselab.mooctest.user.mapper.UserMapper;
+import cn.iselab.mooctest.user.model.OperationRecord;
 import cn.iselab.mooctest.user.model.User;
 import cn.iselab.mooctest.user.service.UserService;
 import lombok.extern.java.Log;
@@ -22,6 +24,9 @@ public class UserServiceImpl implements UserService {
     @Autowired
     private UserMapper userMapper;
 
+    @Autowired
+    private OperationRecordDao operationRecordDao;
+
     @Override
     public User findByEmail(String email) {
         return userMapper.findByEmail(email);
@@ -60,6 +65,11 @@ public class UserServiceImpl implements UserService {
     }
 
     @Override
+    public OperationRecord recordOperation(OperationRecord record) {
+        return operationRecordDao.save(record);
+    }
+
+    @Override
     public List<User> findByFuzzyName(String name) {
         return userMapper.findByFuzzyName(name);
     }

+ 10 - 0
mooctest-user-server/src/main/java/cn/iselab/mooctest/user/web/ctrl/PageController.java

@@ -9,6 +9,7 @@ import cn.iselab.mooctest.user.data.ResponseResult;
 import cn.iselab.mooctest.user.data.UserInfo;
 import cn.iselab.mooctest.user.model.UserThirdParty;
 import cn.iselab.mooctest.user.service.ThirdPartyAuthService;
+import cn.iselab.mooctest.user.service.UserService;
 import cn.iselab.mooctest.user.util.EncryptionUtil;
 import cn.iselab.mooctest.user.web.data.UserVO;
 import cn.iselab.mooctest.user.web.logic.ThirdPartyLogic;
@@ -43,6 +44,7 @@ public class PageController extends BaseController{
     @Autowired
     WechatLogic wechatLogic;
 
+
     @RequestMapping(value = UrlConstants.PAGE + "login", method = RequestMethod.GET)
     public String login(@RequestParam(value = "redirect", required = false)String redirect, HttpServletRequest request){
         LOG.info("redirect:" + redirect);
@@ -83,6 +85,7 @@ public class PageController extends BaseController{
             LOG.info((String)session.getAttribute("redirectURL"));
             String afterLogin = session.getAttribute("redirectURL")==null?
                     UrlConstants.DFAULT_GOTO:(String)session.getAttribute("redirectURL");
+            userLogic.recordLoginAction(request, ((UserDTO)result.getData()).getId() , "password");
             LOG.info("redirectURL: "+afterLogin);
             return "redirect:" + afterLogin;
         }
@@ -107,6 +110,7 @@ public class PageController extends BaseController{
         HttpSession session = request.getSession();
         session.setAttribute("userId", ((UserDTO)result.getData()).getId()+"");
         session.setAttribute("userName", ((UserDTO)result.getData()).getEmail());
+        userLogic.recordLoginAction(request, ((UserDTO)result.getData()).getId(), "mobile");
         String redirectURL = (String) request.getSession().getAttribute("redirectURL");
         redirectURL = redirectURL==null?UrlConstants.DFAULT_GOTO:redirectURL;
         return "redirect:"+redirectURL;
@@ -146,6 +150,7 @@ public class PageController extends BaseController{
         UserDTO user = userLogic.getUserById(((UserThirdParty)result.getData()).getUserId());
         session.setAttribute("userId", user.getId()+"");
         session.setAttribute("userName", user.getEmail());
+        userLogic.recordLoginAction(request, user.getId(), "github");
         String redirectUrl = (String)request.getSession().getAttribute("redirectURL");
         if (redirectUrl==null || redirectUrl.isEmpty())
             redirectUrl = UrlConstants.DFAULT_GOTO;
@@ -167,6 +172,7 @@ public class PageController extends BaseController{
         HttpSession session = request.getSession();
         session.setAttribute("userId", userWechatDTO.getUser().getId()+"");
         session.setAttribute("userName", userWechatDTO.getUser().getEmail());
+        userLogic.recordLoginAction(request,userWechatDTO.getUser().getId(), "wechat");
         String redirectUrl = (String) session.getAttribute("redirectURL");
         if (redirectUrl==null || redirectUrl.isEmpty())
             redirectUrl = UrlConstants.DFAULT_GOTO;
@@ -200,6 +206,8 @@ public class PageController extends BaseController{
             wechatUserInfoDTO.setOpenid(userVO.getOpenid());
             userWechatDTO.setUserInfo(wechatUserInfoDTO);
             wechatLogic.setUserWechat(userWechatDTO);
+            userLogic.recordUserOperation(request, userToBind.getId(), "bind to third party", "wechat");
+            userLogic.recordLoginAction(request, userToBind.getId(), "wechat");
         }else {
             UserThirdParty userThirdParty = new UserThirdParty();
             userThirdParty.setThirdPartyIdentity(userVO.getThirdPartyId());
@@ -208,6 +216,8 @@ public class PageController extends BaseController{
             userThirdParty.setIsDelete(0);
             LOG.info(userThirdParty.getUserId()+"--"+userThirdParty.getThirdPartyIdentity()+"---"+userThirdParty.getType());
             thirdPartyAuthService.save(userThirdParty);
+            userLogic.recordUserOperation(request, userToBind.getId(), "bind to third party", userThirdParty.getType());
+            userLogic.recordLoginAction(request, userToBind.getId(), userThirdParty.getType());
         }
         HttpSession session = request.getSession();
         session.setAttribute("userId", ((UserDTO)result.getData()).getId()+"");

+ 8 - 0
mooctest-user-server/src/main/java/cn/iselab/mooctest/user/web/ctrl/UserController.java

@@ -4,10 +4,12 @@ import cn.iselab.mooctest.rpc.user.data.UserDTO;
 import cn.iselab.mooctest.user.constants.ResponseStatus;
 import cn.iselab.mooctest.user.constants.UrlConstants;
 import cn.iselab.mooctest.user.data.ResponseResult;
+import cn.iselab.mooctest.user.model.OperationRecord;
 import cn.iselab.mooctest.user.model.User;
 import cn.iselab.mooctest.user.util.EncryptionUtil;
 import cn.iselab.mooctest.user.util.OSSUtil;
 import cn.iselab.mooctest.user.web.data.BankAccountInfoVO;
+import cn.iselab.mooctest.user.web.data.OperationRecordVO;
 import cn.iselab.mooctest.user.web.data.UserVO;
 import cn.iselab.mooctest.user.web.logic.UserLogic;
 import lombok.extern.slf4j.Slf4j;
@@ -129,10 +131,16 @@ public class UserController extends BaseController {
         ResponseResult<Object> result = userLogic.setBankInfo(infoVO, request);
         if (result.getStatus()==ResponseStatus.SUCCESS){
             // return new ModelAndView("redirect:"+(String) request.getSession().getAttribute("redirectURL"));
+            userLogic.recordUserOperation(request, Long.parseLong((String) request.getSession().getAttribute("userId")), "Upload Bank Info", "user center");
             return new ModelAndView("success_page").addObject("message","银行账户信息上传成功!");
         }
         ModelAndView modelAndView = new ModelAndView("error_page");
         modelAndView.addObject("message", result.getMsg());
         return modelAndView;
     }
+
+    @RequestMapping(value = UrlConstants.API + "operation_record", method = RequestMethod.POST)
+    public void recordUserOperation(@RequestBody OperationRecordVO recordVO){
+        userLogic.recordUserOperation(recordVO.toOperationRecord());
+    }
 }

+ 37 - 0
mooctest-user-server/src/main/java/cn/iselab/mooctest/user/web/data/OperationRecordVO.java

@@ -0,0 +1,37 @@
+package cn.iselab.mooctest.user.web.data;
+
+import cn.iselab.mooctest.user.model.OperationRecord;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.beans.BeanUtils;
+
+import java.sql.Timestamp;
+
+/**
+ * @author: Diors.Po
+ * @Email: 171256175@qq.com
+ * @date 2019-09-15 22:19
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class OperationRecordVO {
+
+    private Long id;
+    private String ip;
+    private Long userId;
+    private String operation;
+    private String resource;
+    private Timestamp createTime;
+
+    public OperationRecordVO(OperationRecord record){
+        BeanUtils.copyProperties(record, this);
+    }
+
+    public OperationRecord toOperationRecord(){
+        OperationRecord record = new OperationRecord();
+        BeanUtils.copyProperties(this, record);
+        return record;
+    }
+}

+ 11 - 0
mooctest-user-server/src/main/java/cn/iselab/mooctest/user/web/logic/UserLogic.java

@@ -3,6 +3,7 @@ package cn.iselab.mooctest.user.web.logic;
 import cn.iselab.mooctest.rpc.user.data.UserDTO;
 import cn.iselab.mooctest.user.constants.ResponseStatus;
 import cn.iselab.mooctest.user.data.ResponseResult;
+import cn.iselab.mooctest.user.model.OperationRecord;
 import cn.iselab.mooctest.user.web.data.BankAccountInfoVO;
 import cn.iselab.mooctest.user.web.data.UserVO;
 
@@ -61,5 +62,15 @@ public interface UserLogic {
 
     void saveRedirectUrl(String redirect, HttpServletRequest request);
 
+    void recordLoginAction(HttpServletRequest request, Long userId, String resource);
+
+    void recordLogoutAction(HttpServletRequest request, Long userId, String resource);
+
+    void recordUserOperation(HttpServletRequest request, Long userId, String operation, String resource);
+
+    void recordUserOperation(OperationRecord record);
+
+    void recordUserOperation(String ip, Long userId, String operation, String resource);
+
     Boolean isLogin(HttpServletRequest request);
 }

+ 103 - 4
mooctest-user-server/src/main/java/cn/iselab/mooctest/user/web/logic/impl/UserLogicImpl.java

@@ -5,10 +5,7 @@ import cn.iselab.mooctest.user.configure.MailProperties;
 import cn.iselab.mooctest.user.constants.VerifyConstants;
 import cn.iselab.mooctest.user.constants.ResponseStatus;
 import cn.iselab.mooctest.user.data.ResponseResult;
-import cn.iselab.mooctest.user.model.BankAccountInfo;
-import cn.iselab.mooctest.user.model.User;
-import cn.iselab.mooctest.user.model.UserIntegral;
-import cn.iselab.mooctest.user.model.VerifyCode;
+import cn.iselab.mooctest.user.model.*;
 import cn.iselab.mooctest.user.service.*;
 import cn.iselab.mooctest.user.util.EncryptionUtil;
 import cn.iselab.mooctest.user.util.MSUtil;
@@ -24,6 +21,7 @@ import cn.iselab.mooctest.user.web.wrapper.UserWrapper;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.codec.binary.Base64;
 import org.apache.commons.validator.routines.EmailValidator;
+import org.apache.zookeeper.Op;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -668,5 +666,106 @@ public class UserLogicImpl extends BaseLogic implements UserLogic {
         return true;
     }
 
+    @Override
+    public void recordLoginAction(HttpServletRequest request, Long userId, String resource) {
+        OperationRecord record = this.buildUserOperation(request,userId,resource);
+        if(record==null)
+            return;
+        record.setOperation("Login");
+        userService.recordOperation(record);
+        Timestamp current = new Timestamp(System.currentTimeMillis());
+        log.info(String.format("User[%d] Login at [%s] IP(%s)",userId,current.toString(), record.getIp()));
+    }
+
+    @Override
+    public void recordLogoutAction(HttpServletRequest request, Long userId, String resource) {
+        OperationRecord userOperation = this.buildUserOperation(request,userId, resource);
+        if(userOperation==null)
+            return;
+        userOperation.setOperation("Logout");
+        userService.recordOperation(userOperation);
+        Timestamp current = new Timestamp(System.currentTimeMillis());
+        log.info(String.format("User[%d] Logout at [%s]",userId,current.toString()));
+    }
+
+    @Override
+    public void recordUserOperation(HttpServletRequest request, Long userId, String operation, String resource) {
+        OperationRecord record = this.buildUserOperation(request, userId, resource);
+        record.setOperation(operation);
+        userService.recordOperation(record);
+        Timestamp current = new Timestamp(System.currentTimeMillis());
+        log.info(String.format("User[%d] [%s] at [%s]", userId, operation,current.toString()));
+    }
+
+    @Override
+    public void recordUserOperation(OperationRecord record) {
+        userService.recordOperation(record);
+        Timestamp current = new Timestamp(System.currentTimeMillis());
+        log.info(String.format("User[%d] [%s] at [%s]",record.getUserId(),record.getOperation(),current.toString()));
+    }
+
+    @Override
+    public void recordUserOperation(String ip, Long userId, String operation, String resource) {
+        OperationRecord record = this.buildUserOperation(ip, userId, resource);
+        record.setOperation(operation);
+        userService.recordOperation(record);
+        Timestamp current = new Timestamp(System.currentTimeMillis());
+        log.info(String.format("User[%d] [%s] at [%s]", userId, operation,current.toString()));
+    }
+
+    private OperationRecord buildUserOperation(HttpServletRequest request, Long userId, String resource) {
+        String ip = this.getRequestIp(request);
+        if("101.37.78.167".equals(ip)) {
+            return null;
+        }
+        OperationRecord userOperation = new OperationRecord();
+        userOperation.setIp(ip);
+        userOperation.setUserId(userId);
+        userOperation.setResource(resource);
+        return userOperation;
+    }
+
+    private OperationRecord buildUserOperation(String ip, Long userId, String resource) {
+        if("101.37.78.167".equals(ip)) {
+            return null;
+        }
+        OperationRecord userOperation = new OperationRecord();
+        userOperation.setIp(ip);
+        userOperation.setUserId(userId);
+        userOperation.setResource(resource);
+        return userOperation;
+    }
+
+    private String getRequestIp(HttpServletRequest request){
+        String ip = request.getHeader("x-forwarded-for");
+        if (isNotValidIP(ip)) {
+            ip = request.getHeader("Proxy-Client-IP");
+        }
+        if (isNotValidIP(ip)) {
+            ip = request.getHeader("WL-Proxy-Client-IP");
+        }
+        if (isNotValidIP(ip)) {
+            ip = request.getRemoteAddr();
+        }
+        if (isNotValidIP(ip)) {
+            ip = request.getHeader("http_client_ip");
+        }
+        if (isNotValidIP(ip)) {
+            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
+        }
+        if (ip.equals("0:0:0:0:0:0:0:1")) {
+            ip = "127.0.0.1";
+        }
+        if (ip.split(",").length > 1) {
+            ip = ip.split(",")[0];
+        }
+        return ip;
+    }
+
+    private boolean isNotValidIP(String ip) {
+        return ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip);
+    }
+
+
 
 }