add: 用户心跳在线保持功能
1. 数据库增加了字段 2. users对象增加字段. 3. 缓存增加key
正在显示
12 个修改的文件
包含
353 行增加
和
10 行删除
| @@ -7,6 +7,7 @@ import com.google.code.kaptcha.impl.DefaultKaptcha; | @@ -7,6 +7,7 @@ import com.google.code.kaptcha.impl.DefaultKaptcha; | ||
| 7 | import com.thoughtworks.xstream.core.util.Base64Encoder; | 7 | import com.thoughtworks.xstream.core.util.Base64Encoder; |
| 8 | import com.tianbo.warehouse.controller.response.ResultJson; | 8 | import com.tianbo.warehouse.controller.response.ResultJson; |
| 9 | import com.tianbo.warehouse.model.ROLE; | 9 | import com.tianbo.warehouse.model.ROLE; |
| 10 | +import com.tianbo.warehouse.model.Token; | ||
| 10 | import com.tianbo.warehouse.service.RoleService; | 11 | import com.tianbo.warehouse.service.RoleService; |
| 11 | 12 | ||
| 12 | import com.tianbo.warehouse.util.RedisUtils; | 13 | import com.tianbo.warehouse.util.RedisUtils; |
| @@ -74,7 +75,7 @@ public class AnonymousController { | @@ -74,7 +75,7 @@ public class AnonymousController { | ||
| 74 | String verifyToken = ""; | 75 | String verifyToken = ""; |
| 75 | try { | 76 | try { |
| 76 | verifyToken = UUID.randomUUID().toString(); | 77 | verifyToken = UUID.randomUUID().toString(); |
| 77 | - redisUtils.set("verifyToken:" + verifyToken,String.valueOf(sum),1200); | 78 | + redisUtils.set(Token.VERIFY_TOKEN_KEY + verifyToken,String.valueOf(sum),1200); |
| 78 | ImageIO.write(bi, "jpeg", outputStream); | 79 | ImageIO.write(bi, "jpeg", outputStream); |
| 79 | map.put("verifyImg","data:image/jpeg;base64,"+encoder.encode(outputStream.toByteArray())); | 80 | map.put("verifyImg","data:image/jpeg;base64,"+encoder.encode(outputStream.toByteArray())); |
| 80 | } catch (IOException e) { | 81 | } catch (IOException e) { |
| 1 | +package com.tianbo.warehouse.controller; | ||
| 2 | + | ||
| 3 | +import com.alibaba.fastjson.JSON; | ||
| 4 | +import com.alibaba.fastjson.JSONObject; | ||
| 5 | +import com.tianbo.warehouse.controller.response.ResultJson; | ||
| 6 | +import com.tianbo.warehouse.dao.USERSMapper; | ||
| 7 | +import com.tianbo.warehouse.model.Token; | ||
| 8 | +import com.tianbo.warehouse.model.USERS; | ||
| 9 | +import com.tianbo.warehouse.util.RedisUtils; | ||
| 10 | +import io.swagger.annotations.ApiOperation; | ||
| 11 | +import lombok.extern.slf4j.Slf4j; | ||
| 12 | +import org.apache.commons.lang.StringUtils; | ||
| 13 | +import org.springframework.beans.factory.annotation.Autowired; | ||
| 14 | +import org.springframework.web.bind.annotation.PostMapping; | ||
| 15 | +import org.springframework.web.bind.annotation.RestController; | ||
| 16 | + | ||
| 17 | +import javax.annotation.Resource; | ||
| 18 | +import javax.servlet.http.HttpServletRequest; | ||
| 19 | +import javax.servlet.http.HttpServletResponse; | ||
| 20 | +import java.util.Date; | ||
| 21 | + | ||
| 22 | +@RestController() | ||
| 23 | +@Slf4j | ||
| 24 | +public class HeartBeatController { | ||
| 25 | + | ||
| 26 | + @Autowired | ||
| 27 | + private RedisUtils redisUtils; | ||
| 28 | + | ||
| 29 | + @Resource | ||
| 30 | + private USERSMapper usersMapper; | ||
| 31 | + | ||
| 32 | + //检查token时效是否低于标准线 | ||
| 33 | + static final long TOKEN_TTL_CHECK_MIN= 36000L; | ||
| 34 | + | ||
| 35 | + //重置token时效为标准线 | ||
| 36 | + static final long TOKEN_TTL_ADD= 86400L; | ||
| 37 | + | ||
| 38 | + //心跳每次续费时长 | ||
| 39 | + static final long HEARTBEAT_TOKEN_TTL_ADD= 10L; | ||
| 40 | + | ||
| 41 | + @ApiOperation(value = "用户心跳接口", notes = "心跳续期") | ||
| 42 | + @PostMapping("/heartbeat") | ||
| 43 | + public ResultJson heartbeat(HttpServletRequest request, HttpServletResponse response){ | ||
| 44 | + try { | ||
| 45 | + | ||
| 46 | + //1. 获取客户端IP,因为有反向代理所以要从头部获取代理过来的头部IP | ||
| 47 | + String clientIP =null; | ||
| 48 | + clientIP = request.getRemoteAddr(); | ||
| 49 | + String header_forwarded = request.getHeader("x-forwarded-for"); | ||
| 50 | + if (StringUtils.isNotBlank(header_forwarded)) { | ||
| 51 | + clientIP = request.getHeader("x-forwarded-for"); | ||
| 52 | + // 多次反向代理后会有多个ip值,第一个ip才是真实ip | ||
| 53 | + if (clientIP.contains(",")) { | ||
| 54 | + clientIP = clientIP.split(",")[0]; | ||
| 55 | + } | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + //2.获取token | ||
| 59 | + String token = request.getHeader("Authorization"); | ||
| 60 | + /** | ||
| 61 | + * key样式 | ||
| 62 | + * accessToken:token | ||
| 63 | + */ | ||
| 64 | + if (token!=null && !token.isEmpty() && token.startsWith(Token.VERIFY_TOKEN_TYPE)){ | ||
| 65 | + token = token.substring(Token.VERIFY_TOKEN_TYPE.length()); | ||
| 66 | + String accessToken = token; | ||
| 67 | + String userDetailStr = redisUtils.get(accessToken); | ||
| 68 | + | ||
| 69 | + | ||
| 70 | + //4. 更新用户心跳时间及在线状态IP等资料 | ||
| 71 | + if (StringUtils.isNotBlank(userDetailStr)){ | ||
| 72 | + | ||
| 73 | + JSONObject u = JSON.parseObject(userDetailStr); | ||
| 74 | + Integer userId= u.getInteger("userId"); | ||
| 75 | + String username = u.getString("username"); | ||
| 76 | + | ||
| 77 | + /**3.续期token过期时间 | ||
| 78 | + * 增加过期时间,考虑到程序及网络传输中间的时间损耗, | ||
| 79 | + * 每10秒一个的心跳直接续费10秒的话,token的过期时间还是会随着时间逐步减少 | ||
| 80 | + */ | ||
| 81 | + long tokenExpireTime= redisUtils.getExpire(accessToken); | ||
| 82 | + if(tokenExpireTime < TOKEN_TTL_CHECK_MIN){ | ||
| 83 | + redisUtils.expire(accessToken, TOKEN_TTL_ADD); | ||
| 84 | + redisUtils.expire(Token.USER_TOKEN_KEY+username, TOKEN_TTL_ADD); | ||
| 85 | + }else{ | ||
| 86 | + redisUtils.expire(accessToken,tokenExpireTime+HEARTBEAT_TOKEN_TTL_ADD); | ||
| 87 | + redisUtils.expire(Token.USER_TOKEN_KEY+username, tokenExpireTime+HEARTBEAT_TOKEN_TTL_ADD); | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + USERS user = new USERS(); | ||
| 91 | + user.setUserId(userId); | ||
| 92 | + user.loginIp = clientIP; | ||
| 93 | + user.loginDate = new Date(); | ||
| 94 | + //1 为在线状态 | ||
| 95 | + user.setUserStatus(1); | ||
| 96 | + int i = usersMapper.updateByPrimaryKeySelective(user); | ||
| 97 | + | ||
| 98 | + return i > 0 ? new ResultJson("200","心跳成功"): new ResultJson("400","心跳失败"); | ||
| 99 | + } | ||
| 100 | + | ||
| 101 | + } | ||
| 102 | + return new ResultJson("400","心跳失败"); | ||
| 103 | + | ||
| 104 | + }catch (Exception e){ | ||
| 105 | + log.error("[HEART-BEAT-ERROR]-",e); | ||
| 106 | + return new ResultJson("400","心跳失败"); | ||
| 107 | + } | ||
| 108 | + } | ||
| 109 | +} | ||
| 110 | + |
| @@ -24,6 +24,8 @@ public interface USERSMapper { | @@ -24,6 +24,8 @@ public interface USERSMapper { | ||
| 24 | 24 | ||
| 25 | List<USERS> selectAllUser(USERS users); | 25 | List<USERS> selectAllUser(USERS users); |
| 26 | 26 | ||
| 27 | + List<USERS> selectOnlineUser(); | ||
| 28 | + | ||
| 27 | USERS getUserDataPermissionsByPath(@Param("userId") Integer userId,@Param("path") String path); | 29 | USERS getUserDataPermissionsByPath(@Param("userId") Integer userId,@Param("path") String path); |
| 28 | 30 | ||
| 29 | } | 31 | } |
| 1 | +package com.tianbo.warehouse.heartbeat; | ||
| 2 | + | ||
| 3 | +import com.tianbo.warehouse.dao.USERSMapper; | ||
| 4 | +import com.tianbo.warehouse.model.USERS; | ||
| 5 | +import lombok.extern.slf4j.Slf4j; | ||
| 6 | +import org.springframework.stereotype.Component; | ||
| 7 | + | ||
| 8 | +import javax.annotation.PostConstruct; | ||
| 9 | +import javax.annotation.Resource; | ||
| 10 | +import java.util.Date; | ||
| 11 | + | ||
| 12 | +@Component | ||
| 13 | +@Slf4j | ||
| 14 | +public class OfflineTheardJob implements Runnable { | ||
| 15 | + | ||
| 16 | + private static OfflineTheardJob offlineTheardJob; | ||
| 17 | + | ||
| 18 | + private USERS user; | ||
| 19 | + | ||
| 20 | + //用户掉线判定时间差 | ||
| 21 | + static final long OFFLINE_= 120L; | ||
| 22 | + | ||
| 23 | + @Resource | ||
| 24 | + private USERSMapper userMapper; | ||
| 25 | + | ||
| 26 | + OfflineTheardJob() { | ||
| 27 | + | ||
| 28 | + } | ||
| 29 | + OfflineTheardJob(USERS user) { | ||
| 30 | + this.user = user; | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | + @PostConstruct | ||
| 34 | + public void init(){ | ||
| 35 | + offlineTheardJob = this; | ||
| 36 | + } | ||
| 37 | + | ||
| 38 | + @Override | ||
| 39 | + public void run(){ | ||
| 40 | + Date userLoginTime = user.loginDate; | ||
| 41 | + if(userLoginTime!=null){ | ||
| 42 | + long diff= Math.abs(System.currentTimeMillis() - userLoginTime.getTime()); | ||
| 43 | + long s = diff / 1000; | ||
| 44 | + | ||
| 45 | + log.info("[HEAT-BEAT]-用户{}心跳-时间相差{}秒",user.getUsername(),s); | ||
| 46 | + | ||
| 47 | + | ||
| 48 | + if (s > OFFLINE_){ | ||
| 49 | + setOffline(); | ||
| 50 | + } | ||
| 51 | + }else { | ||
| 52 | + setOffline(); | ||
| 53 | + } | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + private void setOffline(){ | ||
| 57 | + user.setUserStatus(2); | ||
| 58 | + int i = offlineTheardJob.userMapper.updateByPrimaryKeySelective(user); | ||
| 59 | + if (i>0){ | ||
| 60 | + log.info("用户id:{},用户名称:{},从IP:{}掉线",user.getUserId(),user.getUsername(),user.loginIp); | ||
| 61 | + } | ||
| 62 | + } | ||
| 63 | +} |
| 1 | +package com.tianbo.warehouse.heartbeat; | ||
| 2 | + | ||
| 3 | +import com.tianbo.warehouse.dao.USERSMapper; | ||
| 4 | +import com.tianbo.warehouse.model.USERS; | ||
| 5 | +import lombok.extern.slf4j.Slf4j; | ||
| 6 | +import org.springframework.scheduling.annotation.Scheduled; | ||
| 7 | +import org.springframework.stereotype.Component; | ||
| 8 | + | ||
| 9 | +import javax.annotation.Resource; | ||
| 10 | +import java.util.List; | ||
| 11 | +import java.util.concurrent.ThreadPoolExecutor; | ||
| 12 | + | ||
| 13 | +/** | ||
| 14 | + * 清理心跳超时的在线用户,判定为离线 | ||
| 15 | + * @author xyh | ||
| 16 | + * @date | ||
| 17 | + * 记得给用户ID,用户名称,用户心跳时间,用户登录ip,用户在线状态的数据库字段设置索引。 | ||
| 18 | + */ | ||
| 19 | +@Slf4j | ||
| 20 | +@Component | ||
| 21 | +public class OfflineUserTask { | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + @Resource | ||
| 25 | + private USERSMapper userMapper; | ||
| 26 | + | ||
| 27 | + @Scheduled(fixedRate = 60000) | ||
| 28 | + private void offlineUserHeartBeat(){ | ||
| 29 | + | ||
| 30 | + //初始化线程池 | ||
| 31 | + ThreadPoolExecutor threadPool = XMLThreadPoolFactory.instance(); | ||
| 32 | + | ||
| 33 | + List<USERS> userList = userMapper.selectOnlineUser(); | ||
| 34 | + if (userList!=null && !userList.isEmpty()){ | ||
| 35 | + log.trace("用户掉线判定开始,共需判定{}个在线标识用户",userList.size()); | ||
| 36 | + for (USERS user:userList) { | ||
| 37 | + OfflineTheardJob offlineTheardJob = new OfflineTheardJob(user); | ||
| 38 | + threadPool.execute(offlineTheardJob); | ||
| 39 | + } | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + } | ||
| 43 | +} |
| 1 | +package com.tianbo.warehouse.heartbeat; | ||
| 2 | + | ||
| 3 | +import java.util.ArrayList; | ||
| 4 | +import java.util.Date; | ||
| 5 | +import java.util.Iterator; | ||
| 6 | +import java.util.List; | ||
| 7 | +import java.util.concurrent.ThreadFactory; | ||
| 8 | + | ||
| 9 | +public class XMLThreadFactory implements ThreadFactory { | ||
| 10 | + | ||
| 11 | + private int counter; | ||
| 12 | + private String name; | ||
| 13 | + private List<String> stats; | ||
| 14 | + | ||
| 15 | + public XMLThreadFactory(String name) | ||
| 16 | + { | ||
| 17 | + counter = 1; | ||
| 18 | + this.name = name; | ||
| 19 | + stats = new ArrayList<String>(); | ||
| 20 | + } | ||
| 21 | + | ||
| 22 | + @Override | ||
| 23 | + public Thread newThread(Runnable runnable) | ||
| 24 | + { | ||
| 25 | + Thread t = new Thread(runnable, name + "-Thread_" + counter); | ||
| 26 | + counter++; | ||
| 27 | + stats.add(String.format("Created thread %d with name %s on %s \n", t.getId(), t.getName(), new Date())); | ||
| 28 | + return t; | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | + public String getStats() | ||
| 32 | + { | ||
| 33 | + StringBuffer buffer = new StringBuffer(); | ||
| 34 | + Iterator<String> it = stats.iterator(); | ||
| 35 | + while (it.hasNext()) | ||
| 36 | + { | ||
| 37 | + buffer.append(it.next()); | ||
| 38 | + } | ||
| 39 | + return buffer.toString(); | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | +} |
| 1 | +package com.tianbo.warehouse.heartbeat; | ||
| 2 | + | ||
| 3 | + | ||
| 4 | +import java.util.concurrent.LinkedBlockingQueue; | ||
| 5 | +import java.util.concurrent.ThreadPoolExecutor; | ||
| 6 | +import java.util.concurrent.TimeUnit; | ||
| 7 | + | ||
| 8 | +public class XMLThreadPoolFactory { | ||
| 9 | + | ||
| 10 | + private static ThreadPoolExecutor threadPool; | ||
| 11 | + | ||
| 12 | + public static ThreadPoolExecutor instance(){ | ||
| 13 | + if (threadPool==null){ | ||
| 14 | + XMLThreadFactory xmlThreadFactory = new XMLThreadFactory("heartbeatTask"); | ||
| 15 | + threadPool = new ThreadPoolExecutor(12, 128, | ||
| 16 | + 0L, TimeUnit.MILLISECONDS, | ||
| 17 | + new LinkedBlockingQueue<Runnable>(2048), | ||
| 18 | + xmlThreadFactory, | ||
| 19 | + new ThreadPoolExecutor.AbortPolicy()); | ||
| 20 | + } | ||
| 21 | + return threadPool; | ||
| 22 | + } | ||
| 23 | +} |
| @@ -58,6 +58,14 @@ public class USERS implements UserDetails { | @@ -58,6 +58,14 @@ public class USERS implements UserDetails { | ||
| 58 | 58 | ||
| 59 | private String token; | 59 | private String token; |
| 60 | 60 | ||
| 61 | + private Integer userStatus; | ||
| 62 | + | ||
| 63 | + public String loginIp; | ||
| 64 | + | ||
| 65 | + public Date loginDate; | ||
| 66 | + | ||
| 67 | + public String createBy; | ||
| 68 | + | ||
| 61 | //用户所属企业ID,企业ID为用户绑定的组织机构顶层parentid为0的组织机构ID | 69 | //用户所属企业ID,企业ID为用户绑定的组织机构顶层parentid为0的组织机构ID |
| 62 | private Integer companyId; | 70 | private Integer companyId; |
| 63 | private String companyName; | 71 | private String companyName; |
| @@ -219,6 +227,14 @@ public class USERS implements UserDetails { | @@ -219,6 +227,14 @@ public class USERS implements UserDetails { | ||
| 219 | this.token = token; | 227 | this.token = token; |
| 220 | } | 228 | } |
| 221 | 229 | ||
| 230 | + public Integer getUserStatus() { | ||
| 231 | + return userStatus; | ||
| 232 | + } | ||
| 233 | + | ||
| 234 | + public void setUserStatus(Integer userStatus) { | ||
| 235 | + this.userStatus = userStatus; | ||
| 236 | + } | ||
| 237 | + | ||
| 222 | public Integer getCompanyId() { | 238 | public Integer getCompanyId() { |
| 223 | return companyId; | 239 | return companyId; |
| 224 | } | 240 | } |
| @@ -258,7 +274,12 @@ public class USERS implements UserDetails { | @@ -258,7 +274,12 @@ public class USERS implements UserDetails { | ||
| 258 | */ | 274 | */ |
| 259 | @Override | 275 | @Override |
| 260 | public boolean isAccountNonLocked(){ | 276 | public boolean isAccountNonLocked(){ |
| 261 | - return true; | 277 | + if (state){ |
| 278 | + return true; | ||
| 279 | + }else { | ||
| 280 | + return false; | ||
| 281 | + } | ||
| 282 | + | ||
| 262 | } | 283 | } |
| 263 | 284 | ||
| 264 | /** | 285 | /** |
| @@ -3,6 +3,7 @@ package com.tianbo.warehouse.security.handel; | @@ -3,6 +3,7 @@ package com.tianbo.warehouse.security.handel; | ||
| 3 | import com.alibaba.fastjson.JSON; | 3 | import com.alibaba.fastjson.JSON; |
| 4 | import com.fasterxml.jackson.databind.ObjectMapper; | 4 | import com.fasterxml.jackson.databind.ObjectMapper; |
| 5 | import com.tianbo.warehouse.bean.AuthSuccessResponse; | 5 | import com.tianbo.warehouse.bean.AuthSuccessResponse; |
| 6 | +import com.tianbo.warehouse.model.Token; | ||
| 6 | import com.tianbo.warehouse.model.USERS; | 7 | import com.tianbo.warehouse.model.USERS; |
| 7 | import com.tianbo.warehouse.security.config.SecurityProperties; | 8 | import com.tianbo.warehouse.security.config.SecurityProperties; |
| 8 | import com.tianbo.warehouse.security.filter.JwtTokenUtil; | 9 | import com.tianbo.warehouse.security.filter.JwtTokenUtil; |
| @@ -52,6 +53,7 @@ public class MyAuthenticationSuccessHandler extends SavedRequestAwareAuthenticat | @@ -52,6 +53,7 @@ public class MyAuthenticationSuccessHandler extends SavedRequestAwareAuthenticat | ||
| 52 | RedisUtils redisUtils; | 53 | RedisUtils redisUtils; |
| 53 | @Override | 54 | @Override |
| 54 | public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws ServletException, IOException { | 55 | public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws ServletException, IOException { |
| 56 | + int expirationSeconds = 3600*24*7; | ||
| 55 | logger.info("登录成功"); | 57 | logger.info("登录成功"); |
| 56 | if (LoginType.JSON.equals(securityProperties.getBrowser().getLoginType())){ | 58 | if (LoginType.JSON.equals(securityProperties.getBrowser().getLoginType())){ |
| 57 | //将 authention 信息打包成json格式返回 | 59 | //将 authention 信息打包成json格式返回 |
| @@ -77,7 +79,8 @@ public class MyAuthenticationSuccessHandler extends SavedRequestAwareAuthenticat | @@ -77,7 +79,8 @@ public class MyAuthenticationSuccessHandler extends SavedRequestAwareAuthenticat | ||
| 77 | loginedUser.setToken(jwtToken); | 79 | loginedUser.setToken(jwtToken); |
| 78 | //这里将登录成功的[user]对象数据写入redis缓存,KEY为token value为user的JSON对象 | 80 | //这里将登录成功的[user]对象数据写入redis缓存,KEY为token value为user的JSON对象 |
| 79 | String json = JSON.toJSONString(user); | 81 | String json = JSON.toJSONString(user); |
| 80 | - redisUtils.set(jwtToken, json,3600*24*7); | 82 | + redisUtils.set(jwtToken, json,expirationSeconds); |
| 83 | + redisUtils.set(Token.USER_TOKEN_KEY + user.getUsername(),jwtToken,expirationSeconds); | ||
| 81 | Map<String,Object> menuMap = permissionService.getUserMenus(user.getUserId()); | 84 | Map<String,Object> menuMap = permissionService.getUserMenus(user.getUserId()); |
| 82 | //返回用户信息和用户可访问的目录列表 | 85 | //返回用户信息和用户可访问的目录列表 |
| 83 | response.getWriter().write(objectMapper.writeValueAsString(new AuthSuccessResponse(loginedUser,menuMap))); | 86 | response.getWriter().write(objectMapper.writeValueAsString(new AuthSuccessResponse(loginedUser,menuMap))); |
| 1 | package com.tianbo.warehouse.security.login; | 1 | package com.tianbo.warehouse.security.login; |
| 2 | 2 | ||
| 3 | +import com.tianbo.warehouse.model.Token; | ||
| 3 | import com.tianbo.warehouse.security.handel.MyAuthenticationFailHandler; | 4 | import com.tianbo.warehouse.security.handel.MyAuthenticationFailHandler; |
| 4 | import com.tianbo.warehouse.security.handel.MyAuthenticationSuccessHandler; | 5 | import com.tianbo.warehouse.security.handel.MyAuthenticationSuccessHandler; |
| 5 | import com.tianbo.warehouse.util.RedisUtils; | 6 | import com.tianbo.warehouse.util.RedisUtils; |
| @@ -58,7 +59,7 @@ public class MyLoginAuthenticationProcessFilter extends AbstractAuthenticationPr | @@ -58,7 +59,7 @@ public class MyLoginAuthenticationProcessFilter extends AbstractAuthenticationPr | ||
| 58 | //验证码判断 | 59 | //验证码判断 |
| 59 | String verify = ""; | 60 | String verify = ""; |
| 60 | 61 | ||
| 61 | - verify = redisUtils.get("verifyToken:" + verifyToken); | 62 | + verify = redisUtils.get(Token.VERIFY_TOKEN_KEY + verifyToken); |
| 62 | 63 | ||
| 63 | if(verify != null && loginVerify != null && verify.equals(loginVerify)){ | 64 | if(verify != null && loginVerify != null && verify.equals(loginVerify)){ |
| 64 | authRequest = new UsernamePasswordAuthenticationToken(loginUserName,loginUserPass, null); | 65 | authRequest = new UsernamePasswordAuthenticationToken(loginUserName,loginUserPass, null); |
| @@ -17,6 +17,10 @@ | @@ -17,6 +17,10 @@ | ||
| 17 | <result column="email" property="email" jdbcType="VARCHAR" /> | 17 | <result column="email" property="email" jdbcType="VARCHAR" /> |
| 18 | <result column="age" property="age" jdbcType="INTEGER" /> | 18 | <result column="age" property="age" jdbcType="INTEGER" /> |
| 19 | <result column="company_id" property="companyId" jdbcType="INTEGER" /> | 19 | <result column="company_id" property="companyId" jdbcType="INTEGER" /> |
| 20 | + <result column="user_status" property="userStatus" jdbcType="INTEGER" /> | ||
| 21 | + <result column="login_ip" property="loginIp" jdbcType="VARCHAR" /> | ||
| 22 | + <result column="login_date" property="loginDate" jdbcType="TIMESTAMP" /> | ||
| 23 | + <result column="create_by" property="createBy" jdbcType="VARCHAR" /> | ||
| 20 | </resultMap> | 24 | </resultMap> |
| 21 | <resultMap id="SecurityResult" type="com.tianbo.warehouse.model.USERS"> | 25 | <resultMap id="SecurityResult" type="com.tianbo.warehouse.model.USERS"> |
| 22 | <id column="user_id" property="userId" jdbcType="INTEGER" /> | 26 | <id column="user_id" property="userId" jdbcType="INTEGER" /> |
| @@ -102,10 +106,12 @@ | @@ -102,10 +106,12 @@ | ||
| 102 | 106 | ||
| 103 | <sql id="Base_Column_List" > | 107 | <sql id="Base_Column_List" > |
| 104 | user_id, username, password, birthday, sex, address, state, mobilePhone, creatTime, | 108 | user_id, username, password, birthday, sex, address, state, mobilePhone, creatTime, |
| 105 | - updateTime, userFace, realName, email, age,company_id | 109 | + updateTime, userFace, realName, email, age, company_id, |
| 110 | + user_status, login_ip, login_date, create_by | ||
| 106 | </sql> | 111 | </sql> |
| 107 | <sql id="user_List" > | 112 | <sql id="user_List" > |
| 108 | - user_id, username, birthday, sex, address, state, mobilePhone,userFace, realName, email, age | 113 | + user_id, username, birthday, sex, address, state, mobilePhone,userFace, realName, email, age, |
| 114 | + user_status, login_ip, login_date, create_by | ||
| 109 | </sql> | 115 | </sql> |
| 110 | <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" > | 116 | <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" > |
| 111 | select | 117 | select |
| @@ -155,12 +161,13 @@ | @@ -155,12 +161,13 @@ | ||
| 155 | realName, | 161 | realName, |
| 156 | email, | 162 | email, |
| 157 | age, | 163 | age, |
| 158 | - company_id, | 164 | + company_id,user_status, login_ip, login_date, create_by, |
| 159 | r.role_id,role_name,role_sign,r.description AS rdescription,`type`,parentId,rsort,customs_reg_code,business_license,departmentId,mq_code | 165 | r.role_id,role_name,role_sign,r.description AS rdescription,`type`,parentId,rsort,customs_reg_code,business_license,departmentId,mq_code |
| 160 | FROM | 166 | FROM |
| 161 | ( | 167 | ( |
| 162 | SELECT | 168 | SELECT |
| 163 | - user_id,username,birthday,sex,address,state,mobilePhone,creatTime,updateTime,userFace,realName,email,age,company_id | 169 | + user_id,username,birthday,sex,address,state,mobilePhone,creatTime,updateTime,userFace,realName,email,age,company_id, |
| 170 | + user_status, login_ip, login_date, create_by | ||
| 164 | FROM users | 171 | FROM users |
| 165 | <where> | 172 | <where> |
| 166 | <if test=" username != null and username != ''" > | 173 | <if test=" username != null and username != ''" > |
| @@ -186,12 +193,12 @@ | @@ -186,12 +193,12 @@ | ||
| 186 | birthday, sex, address, | 193 | birthday, sex, address, |
| 187 | state, mobilePhone, creatTime, | 194 | state, mobilePhone, creatTime, |
| 188 | updateTime, userFace, realName, | 195 | updateTime, userFace, realName, |
| 189 | - email, age) | 196 | + email, age,create_by) |
| 190 | values (#{userId,jdbcType=INTEGER}, #{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, | 197 | values (#{userId,jdbcType=INTEGER}, #{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, |
| 191 | #{birthday,jdbcType=TIMESTAMP}, #{sex,jdbcType=CHAR}, #{address,jdbcType=VARCHAR}, | 198 | #{birthday,jdbcType=TIMESTAMP}, #{sex,jdbcType=CHAR}, #{address,jdbcType=VARCHAR}, |
| 192 | #{state,jdbcType=BIT}, #{mobilephone,jdbcType=VARCHAR}, #{creattime,jdbcType=TIMESTAMP}, | 199 | #{state,jdbcType=BIT}, #{mobilephone,jdbcType=VARCHAR}, #{creattime,jdbcType=TIMESTAMP}, |
| 193 | #{updatetime,jdbcType=TIMESTAMP}, #{userface,jdbcType=VARCHAR}, #{realname,jdbcType=VARCHAR}, | 200 | #{updatetime,jdbcType=TIMESTAMP}, #{userface,jdbcType=VARCHAR}, #{realname,jdbcType=VARCHAR}, |
| 194 | - #{email,jdbcType=VARCHAR}, #{age,jdbcType=INTEGER}) | 201 | + #{email,jdbcType=VARCHAR}, #{age,jdbcType=INTEGER},#{createBy,jdbcType=VARCHAR}) |
| 195 | </insert> | 202 | </insert> |
| 196 | <insert id="insertSelective" parameterType="com.tianbo.warehouse.model.USERS" > | 203 | <insert id="insertSelective" parameterType="com.tianbo.warehouse.model.USERS" > |
| 197 | insert into users | 204 | insert into users |
| @@ -241,6 +248,9 @@ | @@ -241,6 +248,9 @@ | ||
| 241 | <if test="companyId != null" > | 248 | <if test="companyId != null" > |
| 242 | company_id, | 249 | company_id, |
| 243 | </if> | 250 | </if> |
| 251 | + <if test="createBy != null" > | ||
| 252 | + create_by, | ||
| 253 | + </if> | ||
| 244 | </trim> | 254 | </trim> |
| 245 | <trim prefix="values (" suffix=")" suffixOverrides="," > | 255 | <trim prefix="values (" suffix=")" suffixOverrides="," > |
| 246 | <if test="userId != null" > | 256 | <if test="userId != null" > |
| @@ -288,6 +298,9 @@ | @@ -288,6 +298,9 @@ | ||
| 288 | <if test="companyId != null" > | 298 | <if test="companyId != null" > |
| 289 | #{companyId,jdbcType=INTEGER}, | 299 | #{companyId,jdbcType=INTEGER}, |
| 290 | </if> | 300 | </if> |
| 301 | + <if test="createBy != null" > | ||
| 302 | + #{createBy,jdbcType=VARCHAR}, | ||
| 303 | + </if> | ||
| 291 | </trim> | 304 | </trim> |
| 292 | </insert> | 305 | </insert> |
| 293 | <update id="updateByPrimaryKeySelective" parameterType="com.tianbo.warehouse.model.USERS" > | 306 | <update id="updateByPrimaryKeySelective" parameterType="com.tianbo.warehouse.model.USERS" > |
| @@ -332,6 +345,12 @@ | @@ -332,6 +345,12 @@ | ||
| 332 | <if test="companyId != null" > | 345 | <if test="companyId != null" > |
| 333 | company_id = #{companyId,jdbcType=INTEGER}, | 346 | company_id = #{companyId,jdbcType=INTEGER}, |
| 334 | </if> | 347 | </if> |
| 348 | + <if test="userStatus != null" > | ||
| 349 | + user_status = #{userStatus,jdbcType=INTEGER}, | ||
| 350 | + </if> | ||
| 351 | + <if test="loginDate != null" > | ||
| 352 | + login_date = #{loginDate,jdbcType=TIMESTAMP}, | ||
| 353 | + </if> | ||
| 335 | </set> | 354 | </set> |
| 336 | where user_id = #{userId,jdbcType=INTEGER} | 355 | where user_id = #{userId,jdbcType=INTEGER} |
| 337 | </update> | 356 | </update> |
| @@ -365,4 +384,11 @@ | @@ -365,4 +384,11 @@ | ||
| 365 | and path = #{path,jdbcType=VARCHAR} | 384 | and path = #{path,jdbcType=VARCHAR} |
| 366 | and dp.perm_status = 0 | 385 | and dp.perm_status = 0 |
| 367 | </select> | 386 | </select> |
| 387 | + | ||
| 388 | + <select id="selectOnlineUser" resultMap="BaseResultMap" > | ||
| 389 | + select | ||
| 390 | + <include refid="Base_Column_List" /> | ||
| 391 | + from users | ||
| 392 | + where user_status = 1; | ||
| 393 | + </select> | ||
| 368 | </mapper> | 394 | </mapper> |
-
请 注册 或 登录 后发表评论