新增账号过期时间、密码过期时间

This commit is contained in:
wanggeng888 2021-02-27 19:16:25 +08:00
parent 4d3438d756
commit 5682f8c448
22 changed files with 530 additions and 99 deletions

View File

@ -180,5 +180,14 @@ public interface ISystemConstant {
* admin
*/
String ADMIN = "admin";
/**
* 日期格式化年月日
*/
String DATE_FORMATTER_YYYY_MM_DD = "yyyy-MM-dd";
/**
* 日期格式化年月日时分秒
*/
String DATE_FORMATTER_YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
}

View File

@ -28,6 +28,8 @@ public class UserDTO implements Serializable {
private Integer userType;
@ApiModelProperty(name = "userState", value = "用户状态0正常1冻结")
private Integer userState;
@ApiModelProperty(name = "userExpiredDate", value = "超时时间,空表示永不超时")
private String userExpiredDate;
@ApiModelProperty(name = "userAvatar", value = "用户头像ID")
private String userAvatar;
@ApiModelProperty(name = "lastLoginAddress", value = "最后登录IP")
@ -119,6 +121,14 @@ public class UserDTO implements Serializable {
this.userState = userState;
}
public String getUserExpiredDate() {
return userExpiredDate == null ? "" : userExpiredDate;
}
public void setUserExpiredDate(String userExpiredDate) {
this.userExpiredDate = userExpiredDate;
}
public String getUserAvatar() {
return userAvatar == null ? "" : userAvatar.trim();
}
@ -226,48 +236,50 @@ public class UserDTO implements Serializable {
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("{");
sb.append("\"userId\":")
.append("\"").append(userId).append("\"");
sb.append(",\"userUsername\":")
.append("\"").append(userUsername).append("\"");
sb.append(",\"userName\":")
.append("\"").append(userName).append("\"");
sb.append(",\"userPhone\":")
.append("\"").append(userPhone).append("\"");
sb.append(",\"userEmail\":")
.append("\"").append(userEmail).append("\"");
sb.append(",\"userUKey\":")
.append("\"").append(userUKey).append("\"");
sb.append("\"userId\":\"")
.append(userId).append('\"');
sb.append(",\"userUsername\":\"")
.append(userUsername).append('\"');
sb.append(",\"userName\":\"")
.append(userName).append('\"');
sb.append(",\"userPhone\":\"")
.append(userPhone).append('\"');
sb.append(",\"userEmail\":\"")
.append(userEmail).append('\"');
sb.append(",\"userUKey\":\"")
.append(userUKey).append('\"');
sb.append(",\"userType\":")
.append(userType);
sb.append(",\"userState\":")
.append(userState);
sb.append(",\"userAvatar\":")
.append("\"").append(userAvatar).append("\"");
sb.append(",\"lastLoginAddress\":")
.append("\"").append(lastLoginAddress).append("\"");
sb.append(",\"lastLoginTime\":")
.append("\"").append(lastLoginTime).append("\"");
sb.append(",\"userLongitude\":")
.append("\"").append(userLongitude).append("\"");
sb.append(",\"userLatitude\":")
.append("\"").append(userLatitude).append("\"");
sb.append(",\"departmentIds\":")
.append("\"").append(departmentIds).append("\"");
sb.append(",\"departmentNames\":")
.append("\"").append(departmentNames).append("\"");
sb.append(",\"roleIds\":")
.append("\"").append(roleIds).append("\"");
sb.append(",\"roleNames\":")
.append("\"").append(roleNames).append("\"");
sb.append(",\"positionIds\":")
.append("\"").append(positionIds).append("\"");
sb.append(",\"positionNames\":")
.append("\"").append(positionNames).append("\"");
sb.append(",\"userExpiredDate\":")
.append(userExpiredDate);
sb.append(",\"userAvatar\":\"")
.append(userAvatar).append('\"');
sb.append(",\"lastLoginAddress\":\"")
.append(lastLoginAddress).append('\"');
sb.append(",\"lastLoginTime\":\"")
.append(lastLoginTime).append('\"');
sb.append(",\"userLongitude\":\"")
.append(userLongitude).append('\"');
sb.append(",\"userLatitude\":\"")
.append(userLatitude).append('\"');
sb.append(",\"departmentIds\":\"")
.append(departmentIds).append('\"');
sb.append(",\"departmentNames\":\"")
.append(departmentNames).append('\"');
sb.append(",\"roleIds\":\"")
.append(roleIds).append('\"');
sb.append(",\"roleNames\":\"")
.append(roleNames).append('\"');
sb.append(",\"positionIds\":\"")
.append(positionIds).append('\"');
sb.append(",\"positionNames\":\"")
.append(positionNames).append('\"');
sb.append(",\"loginType\":")
.append(loginType);
sb.append(",\"gmtCreate\":")
.append("\"").append(gmtCreate).append("\"");
sb.append(",\"gmtCreate\":\"")
.append(gmtCreate).append('\"');
sb.append('}');
return sb.toString();
}

View File

@ -39,17 +39,13 @@ import java.util.Map;
* @Version: 1.0
**/
@Controller
public class IndexController {
public class ApiInfoController {
private static String API_TYPE_GET = "get";
private static String API_TYPE_POST = "post";
private static String API_TYPE_PUT = "put";
private static String API_TYPE_DELETE = "delete";
@Autowired(required = false)
private IMenuBaseService menuBaseService;
@Autowired(required = false)
private IUserCheckService userCheckService;
@Autowired
private DocumentationCache documentationCache;
@Autowired
@ -105,25 +101,4 @@ public class IndexController {
systemApiDTO.setApis(apis);
return systemApiDTO;
}
@GetMapping("index")
public ModelAndView goIndex() {
ModelAndView mv = new ModelAndView("index");
if (menuBaseService != null) {
List<MenuDTO> menus;
// 加载菜单
if (userCheckService != null) {
// 引入用户模块是统一用户系统加载统一用户系统菜单
menus = menuBaseService.listAllByParentId(IMenuBaseService.MENU_UNIFIED_USER);
} else {
// 未引入用户模块是客户端系统加载客户端菜单
menus = new ArrayList<>();
}
mv.addObject("menus", menus);
}
return mv;
}
}

View File

@ -0,0 +1,71 @@
package ink.wgink.login.base.controller.route;
import ink.wgink.common.component.SecurityComponent;
import ink.wgink.interfaces.menu.IMenuBaseService;
import ink.wgink.interfaces.user.IUserCheckService;
import ink.wgink.login.base.config.properties.SystemProperties;
import ink.wgink.login.base.consts.IUserCenterConst;
import ink.wgink.login.base.manager.ConfigManager;
import ink.wgink.pojo.bos.UserInfoBO;
import ink.wgink.pojo.dtos.menu.MenuDTO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* When you feel like quitting. Think about why you started
* 当你想要放弃的时候想想当初你为何开始
*
* @ClassName: IndexRouteController
* @Description: index
* @Author: wanggeng
* @Date: 2021/2/27 3:38 下午
* @Version: 1.0
*/
@Controller
public class IndexRouteController {
@Autowired
private SecurityComponent securityComponent;
@Autowired
private SystemProperties systemProperties;
@Autowired(required = false)
private IMenuBaseService menuBaseService;
@GetMapping("index")
public ModelAndView goIndex() {
ModelAndView mv = new ModelAndView("index");
UserInfoBO userInfoBO = securityComponent.getCurrentUser();
mv.addObject("userUsername", userInfoBO.getUserUsername());
Map<String, Object> config = ConfigManager.getInstance().getConfig();
if (!Objects.isNull(config.get(IUserCenterConst.LOGIN_PAGE_NAME)) && !StringUtils.isBlank(config.get(IUserCenterConst.LOGIN_PAGE_NAME).toString())) {
mv.addObject(IUserCenterConst.LOGIN_PAGE_NAME, config.get(IUserCenterConst.LOGIN_PAGE_NAME).toString());
} else {
mv.addObject(IUserCenterConst.LOGIN_PAGE_NAME, systemProperties.getLoginPageName());
}
if (!Objects.isNull(config.get(IUserCenterConst.SYSTEM_TITLE)) && !StringUtils.isBlank(config.get(IUserCenterConst.SYSTEM_TITLE).toString())) {
mv.addObject(IUserCenterConst.SYSTEM_TITLE, config.get(IUserCenterConst.SYSTEM_TITLE).toString());
} else {
mv.addObject(IUserCenterConst.SYSTEM_TITLE, systemProperties.getTitle());
}
// 系统LOGO
if (!Objects.isNull(config.get(IUserCenterConst.SYSTEM_LOGO)) && !StringUtils.isBlank(config.get(IUserCenterConst.SYSTEM_LOGO).toString())) {
mv.addObject(IUserCenterConst.SYSTEM_LOGO, config.get(IUserCenterConst.SYSTEM_LOGO).toString());
} else {
mv.addObject(IUserCenterConst.SYSTEM_LOGO, "");
}
mv.addObject("ws", systemProperties.getWs());
if (menuBaseService != null) {
List<MenuDTO> menus = menuBaseService.listAllByParentId(IMenuBaseService.MENU_UNIFIED_USER);
mv.addObject("menus", menus);
}
return mv;
}
}

View File

@ -1,9 +1,12 @@
package ink.wgink.login.base.controller.route;
import ink.wgink.interfaces.consts.ISystemConstant;
import ink.wgink.interfaces.menu.IMenuBaseService;
import ink.wgink.interfaces.user.IUserCheckService;
import ink.wgink.login.base.config.properties.SystemProperties;
import ink.wgink.login.base.consts.IUserCenterConst;
import ink.wgink.login.base.manager.ConfigManager;
import ink.wgink.pojo.dtos.menu.MenuDTO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
@ -15,6 +18,8 @@ import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

View File

@ -9,6 +9,7 @@ import ink.wgink.interfaces.role.IRoleMenuBaseService;
import ink.wgink.interfaces.role.IRolePermissionBaseService;
import ink.wgink.interfaces.role.IRoleUserBaseService;
import ink.wgink.login.base.exceptions.UserAuthenticationException;
import ink.wgink.login.base.manager.ConfigManager;
import ink.wgink.pojo.bos.LoginUser;
import ink.wgink.pojo.bos.RoleGrantedAuthorityBO;
import ink.wgink.pojo.pos.DepartmentPO;
@ -18,20 +19,21 @@ import ink.wgink.pojo.pos.RolePO;
import ink.wgink.service.department.service.IDepartmentUserService;
import ink.wgink.service.user.pojo.pos.UserPO;
import ink.wgink.service.user.service.IUserService;
import ink.wgink.util.date.DateUtil;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.*;
/**
* @ClassName: UserDetailServiceImpl
@ -78,15 +80,9 @@ public class UserDetailServiceImpl implements UserDetailsService {
if (null == userPO) {
throw new UserAuthenticationException("账号不存在");
}
if (userPO.getUserType() != 1) {
throw new UserAuthenticationException("非系统用户,无法登录");
}
if (userPO.getUserState() == 1) {
throw new UserAuthenticationException("账号已冻结");
}
if (userPO.getUserState() == 2) {
throw new UserAuthenticationException("账号已锁定");
}
LOG.debug("设置权限权限");
LoginUser loginUser;
@ -95,7 +91,6 @@ public class UserDetailServiceImpl implements UserDetailsService {
grantedAuthorities.add(new RoleGrantedAuthorityBO(ISystemConstant.ADMIN));
loginUser = createUserBO(userPO, grantedAuthorities);
} else {
List<RolePO> rolePOs = null;
// 先处理授权再创建对象否则 grantedAuthorities 中无法赋值
if (roleUserBaseService != null) {
@ -139,7 +134,11 @@ public class UserDetailServiceImpl implements UserDetailsService {
* @return
*/
private LoginUser createUserBO(UserPO userPO, Set<GrantedAuthority> grantedAuthorities) {
LoginUser loginUser = new LoginUser(userPO.getUserUsername(), userPO.getUserPassword(), userPO.getUserState() == 0 ? true : false, true, true, true, grantedAuthorities);
LoginUser loginUser = new LoginUser(userPO.getUserUsername(), userPO.getUserPassword(),
userPO.getUserType() == 1 ? true : false,
isAccountNonExpired(userPO),
isCredentialsNonExpired(userPO),
userPO.getUserState() == 0 ? true : false, grantedAuthorities);
loginUser.setUserId(userPO.getUserId());
loginUser.setUserName(userPO.getUserName());
loginUser.setUserPhone(userPO.getUserPhone());
@ -150,6 +149,56 @@ public class UserDetailServiceImpl implements UserDetailsService {
return loginUser;
}
/**
* 账号是否没有过期
*
* @param userPO
* @return
*/
private boolean isAccountNonExpired(UserPO userPO) {
if (StringUtils.equals(userPO.getUserUsername(), ISystemConstant.ADMIN)) {
return true;
}
if (!StringUtils.isBlank(userPO.getUserExpiredDate())) {
// 判断用户是否超时失效
DateTime expiredDateTime = DateTime.parse(userPO.getUserExpiredDate(), DateTimeFormat.forPattern(ISystemConstant.DATE_FORMATTER_YYYY_MM_DD_HH_MM_SS));
DateTime nowDateTime = DateTime.now();
if (expiredDateTime.isBefore(nowDateTime)) {
return false;
}
}
return true;
}
/**
* 密码是否没有过期
*
* @param userPO
* @return
*/
private boolean isCredentialsNonExpired(UserPO userPO) {
if (StringUtils.equals(userPO.getUserUsername(), ISystemConstant.ADMIN)) {
return true;
}
Map<String, Object> config = ConfigManager.getInstance().getConfig();
Object passwordValidity = config.get("passwordValidity");
// 自定义密码有效期
if (passwordValidity != null && StringUtils.equals(passwordValidity.toString(), "custom")) {
Object passwordValidityDays = config.get("passwordValidityDays");
int validityDays = passwordValidityDays == null ? 0 : (Integer) passwordValidityDays;
if (validityDays <= 0) {
return true;
}
DateTime passwordModifiedDateTime = DateTime.parse(userPO.getGmtPasswordModified(), DateTimeFormat.forPattern(ISystemConstant.DATE_FORMATTER_YYYY_MM_DD_HH_MM_SS));
DateTime passwordExpiredDateTime = passwordModifiedDateTime.plusDays(validityDays);
DateTime nowDateTime = DateTime.now();
if (passwordExpiredDateTime.isBefore(nowDateTime)) {
return false;
}
}
return true;
}
/**
* 角色授权列表
*
@ -177,6 +226,9 @@ public class UserDetailServiceImpl implements UserDetailsService {
* @param rolePOs
*/
private void removalDuplicateRole(List<RolePO> rolePOs) {
if (rolePOs == null || rolePOs.isEmpty()) {
return;
}
for (int i = 0; i < rolePOs.size(); i++) {
RolePO rolePO = rolePOs.get(i);
boolean isExist = false;

View File

@ -135,15 +135,15 @@ public class ServiceMenuStartUp implements ApplicationRunner {
* @param menuParentId
*/
private void initMenuManage(Map<String, Object> params, String menuParentId) {
LOG.debug("初始化菜单:菜单管理");
LOG.debug("初始化菜单:系统菜单");
params.remove("menuId");
params.put("menuCode", "000100010001");
MenuDTO menuDTO = menuDao.getSimple(params);
if (menuDTO == null) {
params.put("menuId", UUIDUtil.getUUID());
params.put("menuParentId", menuParentId);
params.put("menuName", "菜单");
params.put("menuSummary", "菜单");
params.put("menuName", "系统菜单");
params.put("menuSummary", "系统菜单");
params.put("menuUrl", "/route/menu/list-tree");
params.put("menuType", "1");
params.put("menuIcon", "fa-icon-color-white fa fa-list");

View File

@ -7,6 +7,7 @@ import ink.wgink.interfaces.consts.IFileConstant;
import ink.wgink.interfaces.consts.ISystemConstant;
import ink.wgink.pojo.vos.IdsVO;
import ink.wgink.service.user.pojo.vos.RestPasswordVO;
import ink.wgink.service.user.pojo.vos.UpdateExpiredDateVO;
import ink.wgink.service.user.pojo.vos.UpdateUsernameVO;
import ink.wgink.pojo.ListPage;
import ink.wgink.pojo.dtos.user.UserDTO;
@ -92,11 +93,14 @@ public class UserController extends DefaultBaseController {
if (!StringUtils.isBlank(userVO.getUserEmail()) && !RegexUtil.isEmail(userVO.getUserEmail())) {
throw new ParamsException("用户邮箱格式错误");
}
if (!StringUtils.isBlank(userVO.getUserExpiredDate()) && !RegexUtil.isDatetime(userVO.getUserExpiredDate())) {
throw new ParamsException("过期时间格式错误");
}
}
@ApiOperation(value = "用户重置密码", notes = "用户重置密码接口")
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
@PutMapping("resetpassword/{userId}")
@PutMapping("reset-password/{userId}")
@CheckRequestBodyAnnotation
public SuccessResult resetPassword(@PathVariable("userId") String userId, @RequestBody RestPasswordVO restPasswordVO) {
userService.resetPassword(userId, restPasswordVO);
@ -105,13 +109,22 @@ public class UserController extends DefaultBaseController {
@ApiOperation(value = "用户修改用户名", notes = "用户修改用户名接口")
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
@PutMapping("updateusername/{userId}")
@PutMapping("update-username/{userId}")
@CheckRequestBodyAnnotation
public SuccessResult updateUsername(@PathVariable("userId") String userId, @RequestBody UpdateUsernameVO updateUsernameVO) throws Exception {
userService.updateUsername(userId, updateUsernameVO);
return new SuccessResult();
}
@ApiOperation(value = "更新过期时间", notes = "更新过期时间接口")
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
@PutMapping("update-expired-date/{userId}")
@CheckRequestBodyAnnotation
public SuccessResult updateExpiredDate(@PathVariable("userId") String userId, @RequestBody UpdateExpiredDateVO updateExpiredDateVO) throws Exception {
userService.updateExpiredDate(userId, updateExpiredDateVO);
return new SuccessResult();
}
@ApiOperation(value = "用户导入Excel", notes = "用户导入Excel接口")
@ApiImplicitParams({
@ApiImplicitParam(name = "excel", value = "文件名称", paramType = "query"),

View File

@ -58,6 +58,11 @@ public class UserRouteController {
return new ModelAndView("user/update-password");
}
@GetMapping("update-expired-date")
public ModelAndView updateExpiredDate() {
return new ModelAndView("user/update-expired-date");
}
@GetMapping("upload/upload-excel")
public ModelAndView uploadExcel() {
return new ModelAndView("user/upload/upload-excel");

View File

@ -71,6 +71,14 @@ public interface IUserDao {
*/
void updateUsername(Map<String, Object> params) throws UpdateException;
/**
* 更新过期时间
*
* @param params
* @throws UpdateException
*/
void updateExpiredDate(Map<String, Object> params) throws UpdateException;
/**
* 更新登录信息
*

View File

@ -27,12 +27,14 @@ public class UserPO implements Serializable {
private String userUKey;
private Integer userType;
private Integer userState;
private String userExpiredDate;
private String userAvatar;
private String lastLoginAddress;
private String lastLoginTime;
private String userLongitude;
private String userLatitude;
private Integer loginType;
private String gmtPasswordModified;
public String getUserId() {
return userId == null ? "" : userId;
@ -106,6 +108,14 @@ public class UserPO implements Serializable {
this.userState = userState;
}
public String getUserExpiredDate() {
return userExpiredDate == null ? "" : userExpiredDate;
}
public void setUserExpiredDate(String userExpiredDate) {
this.userExpiredDate = userExpiredDate;
}
public String getUserAvatar() {
return userAvatar == null ? "" : userAvatar;
}
@ -154,6 +164,14 @@ public class UserPO implements Serializable {
this.loginType = loginType;
}
public String getGmtPasswordModified() {
return gmtPasswordModified == null ? "" : gmtPasswordModified;
}
public void setGmtPasswordModified(String gmtPasswordModified) {
this.gmtPasswordModified = gmtPasswordModified;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("{");
@ -175,6 +193,8 @@ public class UserPO implements Serializable {
.append(userType);
sb.append(",\"userState\":")
.append(userState);
sb.append(",\"userExpiredDate\":\"")
.append(userExpiredDate).append('\"');
sb.append(",\"userAvatar\":\"")
.append(userAvatar).append('\"');
sb.append(",\"lastLoginAddress\":\"")
@ -187,6 +207,8 @@ public class UserPO implements Serializable {
.append(userLatitude).append('\"');
sb.append(",\"loginType\":")
.append(loginType);
sb.append(",\"gmtPasswordModified\":\"")
.append(gmtPasswordModified).append('\"');
sb.append('}');
return sb.toString();
}

View File

@ -0,0 +1,40 @@
package ink.wgink.service.user.pojo.vos;
import ink.wgink.annotation.CheckEmptyAnnotation;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
* When you feel like quitting. Think about why you started
* 当你想要放弃的时候想想当初你为何开始
*
* @ClassName: AddExpiredDateVO
* @Description: 添加过期时间
* @Author: wanggeng
* @Date: 2021/2/27 6:16 下午
* @Version: 1.0
*/
@ApiModel
public class UpdateExpiredDateVO {
@ApiModelProperty(name = "expiredDate", value = "过期时间")
@CheckEmptyAnnotation(name = "过期时间", verifyType = "datetime")
private String expiredDate;
public String getExpiredDate() {
return expiredDate == null ? "" : expiredDate;
}
public void setExpiredDate(String expiredDate) {
this.expiredDate = expiredDate;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("{");
sb.append("\"expiredDate\":\"")
.append(expiredDate).append('\"');
sb.append('}');
return sb.toString();
}
}

View File

@ -34,8 +34,12 @@ public class UserVO {
private String userPhone;
@ApiModelProperty(name = "userEmail", value = "用户邮件")
private String userEmail;
@ApiModelProperty(name = "userExpiredDate", value = "过期时间")
private String userExpiredDate;
@ApiModelProperty(name = "userAvatar", value = "用户头像ID")
private String userAvatar;
@ApiModelProperty(name = "remarks", value = "备注")
private String remarks;
public String getUserUsername() {
return userUsername == null ? "" : userUsername.trim();
@ -93,6 +97,14 @@ public class UserVO {
this.userEmail = userEmail;
}
public String getUserExpiredDate() {
return userExpiredDate == null ? "" : userExpiredDate;
}
public void setUserExpiredDate(String userExpiredDate) {
this.userExpiredDate = userExpiredDate;
}
public String getUserAvatar() {
return userAvatar == null ? "" : userAvatar.trim();
}
@ -101,6 +113,14 @@ public class UserVO {
this.userAvatar = userAvatar;
}
public String getRemarks() {
return remarks == null ? "" : remarks;
}
public void setRemarks(String remarks) {
this.remarks = remarks;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("{");
@ -118,8 +138,12 @@ public class UserVO {
.append(userPhone).append('\"');
sb.append(",\"userEmail\":\"")
.append(userEmail).append('\"');
sb.append(",\"userExpiredDate\":\"")
.append(userExpiredDate).append('\"');
sb.append(",\"userAvatar\":\"")
.append(userAvatar).append('\"');
sb.append(",\"remarks\":\"")
.append(remarks).append('\"');
sb.append('}');
return sb.toString();
}

View File

@ -6,6 +6,7 @@ import ink.wgink.interfaces.user.IUserBaseService;
import ink.wgink.interfaces.user.IUserCheckService;
import ink.wgink.service.user.pojo.pos.UserPO;
import ink.wgink.service.user.pojo.vos.RestPasswordVO;
import ink.wgink.service.user.pojo.vos.UpdateExpiredDateVO;
import ink.wgink.service.user.pojo.vos.UpdateUsernameVO;
import ink.wgink.service.user.pojo.vos.UserVO;
import ink.wgink.pojo.result.UploadExcelResultDTO;
@ -77,6 +78,14 @@ public interface IUserService extends IUserBaseService, IUserCheckService {
*/
void updateUsername(String userId, UpdateUsernameVO updateUsernameVO);
/**
* 更新过期时间
*
* @param userId
* @param updateExpiredDateVO
*/
void updateExpiredDate(String userId, UpdateExpiredDateVO updateExpiredDateVO);
/**
* 导入Excel
*
@ -98,7 +107,7 @@ public interface IUserService extends IUserBaseService, IUserCheckService {
* 更新登陆信息
*
* @param params
* @throws UpdateException
*/
void updateLoginInfo(Map<String, Object> params) throws UpdateException;
void updateLoginInfo(Map<String, Object> params);
}

View File

@ -16,6 +16,7 @@ import ink.wgink.service.user.excel.UserExcelListener;
import ink.wgink.service.user.pojo.bos.UserAdjustmentBO;
import ink.wgink.service.user.pojo.pos.UserPO;
import ink.wgink.service.user.pojo.vos.RestPasswordVO;
import ink.wgink.service.user.pojo.vos.UpdateExpiredDateVO;
import ink.wgink.service.user.pojo.vos.UpdateUsernameVO;
import ink.wgink.service.user.pojo.vos.UserVO;
import ink.wgink.service.user.service.IUserAdjustmentService;
@ -38,6 +39,7 @@ import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -90,6 +92,7 @@ public class UserServiceImpl extends DefaultBaseService implements IUserService
String userId = UUIDUtil.getUUID();
Map<String, Object> params = HashMapUtil.beanToMap(userVO);
params.put("userId", userId);
params.put("userExpiredDate", DateUtil.getTime());
if (isRegister) {
setSaveInfoByUserId(params, userId);
} else {
@ -159,6 +162,18 @@ public class UserServiceImpl extends DefaultBaseService implements IUserService
updateUsernameAdjustment(userId, oldUserDTO.getUserUsername(), updateUsernameVO);
}
@Override
public void updateExpiredDate(String userId, UpdateExpiredDateVO updateExpiredDateVO) {
UserDTO oldUserDTO = get(userId);
if (oldUserDTO == null) {
throw new SearchException("用户不存在");
}
Map<String, Object> params = new HashMap<>(4);
params.put("userId", userId);
params.put("userExpiredDate", updateExpiredDateVO.getExpiredDate());
userDao.updateExpiredDate(params);
}
@Override
public UploadExcelResultDTO importExcel(MultipartFile excel) throws IOException {
Map<String, Object> params = getHashMap(16);

View File

@ -15,11 +15,13 @@
<result property="userAvatar" column="user_avatar"/>
<result property="userType" column="user_type"/>
<result property="userState" column="user_state"/>
<result property="userExpiredDate" column="user_expired_date"/>
<result property="lastLoginAddress" column="last_login_address"/>
<result property="lastLoginTime" column="last_login_time"/>
<result property="userLongitude" column="user_longitude"/>
<result property="userLatitude" column="user_latitude"/>
<result property="loginType" column="login_type"/>
<result property="gmtPasswordModified" column="gmt_password_modified"/>
</resultMap>
<resultMap id="userDTO" type="ink.wgink.pojo.dtos.user.UserDTO">
@ -32,6 +34,7 @@
<result property="userAvatar" column="user_avatar"/>
<result property="userType" column="user_type"/>
<result property="userState" column="user_state"/>
<result property="userExpiredDate" column="user_expired_date"/>
<result property="lastLoginAddress" column="last_login_address"/>
<result property="lastLoginTime" column="last_login_time"/>
<result property="userLongitude" column="user_longitude"/>
@ -59,13 +62,14 @@
`user_ukey_electronic_secret_key` text COMMENT '用户UKey电子秘钥',
`user_type` int(2) DEFAULT '2' COMMENT '1:系统用户2:普通用户',
`user_state` int(2) DEFAULT '0' COMMENT '用户状态',
`user_expired_date` varchar(20) DEFAULT NULL COMMENT '用户过期时间',
`user_avatar` char(36) DEFAULT NULL COMMENT '头像',
`user_longitude` varchar(255) DEFAULT '0' COMMENT '经度',
`user_latitude` varchar(255) DEFAULT '0' COMMENT '纬度',
`last_login_address` varchar(255) DEFAULT NULL COMMENT '最后登录地址',
`last_login_time` datetime DEFAULT NULL COMMENT '最后登录时间',
`login_type` int(1) DEFAULT '1' COMMENT '登录类型',
`gmt_password_modified` date DEFAULT NULL COMMENT '密码修改时间',
`gmt_password_modified` datetime DEFAULT NULL COMMENT '密码修改时间',
`remarks` varchar(255) DEFAULT NULL COMMENT '备注',
`creator` char(36) DEFAULT NULL,
`gmt_create` datetime DEFAULT NULL,
@ -94,6 +98,7 @@
user_email,
user_type,
user_state,
user_expired_date,
user_avatar,
creator,
gmt_create,
@ -109,6 +114,7 @@
#{userEmail},
#{userType},
#{userState},
#{userExpiredDate},
#{userAvatar},
#{creator},
#{gmtCreate},
@ -156,6 +162,9 @@
<if test="userState != null">
user_state = #{userState},
</if>
<if test="userExpiredDate != null">
user_expired_date = #{userExpiredDate},
</if>
<if test="userAvatar != null and userAvatar != ''">
user_avatar = #{userAvatar},
</if>
@ -228,6 +237,16 @@
user_id = #{userId}
</update>
<!-- 更新过期时间 -->
<update id="updateExpiredDate" parameterType="map" flushCache="true">
UPDATE
sys_user
SET
user_expired_date = #{userExpiredDate}
WHERE
user_id = #{userId}
</update>
<!-- 获取用户 -->
<select id="getPO" parameterType="map" resultMap="userPO" useCache="true">
SELECT
@ -241,13 +260,14 @@
user_ukey_electronic_secret_key,
user_type,
user_state,
user_expired_date,
user_avatar,
user_longitude,
user_latitude,
last_login_address,
LEFT(last_login_time, 19) last_login_time,
login_type,
gmt_password_modified,
LEFT(gmt_password_modified, 19) gmt_password_modified,
remarks,
LEFT(gmt_create, 19) gmt_create
FROM
@ -281,6 +301,7 @@
user_ukey_electronic_secret_key,
user_type,
user_state,
user_expired_date,
user_avatar,
user_longitude,
user_latitude,
@ -321,6 +342,7 @@
user_ukey_electronic_secret_key,
user_type,
user_state,
user_expired_date,
user_avatar,
user_longitude,
user_latitude,

View File

@ -141,6 +141,16 @@
return item.userEmail;
}
},
{field:'userExpiredDate', width:180, title: '账号过期时间', align:'center',
templet: function(item) {
if(!item.userExpiredDate) {
return '<button type="button" class="layui-btn layui-btn-xs" lay-event="userExpiredDateEvent">' +
'<i class="fa fa-clock-o"></i> 设置时间' +
'</button>';
}
return item.userExpiredDate;
}
},
{field:'lastLoginAddress', width:140, title: '登录地址', align:'center',
templet: function(item) {
if(!item.lastLoginAddress) {
@ -149,7 +159,7 @@
return item.lastLoginAddress;
}
},
{field:'lastLoginTime', width:200, title: '最后登录系统时间', align:'center',
{field:'lastLoginTime', width:180, title: '最后登录系统时间', align:'center',
templet: function(item) {
if(!item.lastLoginTime) {
return '-';
@ -157,7 +167,7 @@
return item.lastLoginTime;
}
},
{field:'gmtCreate', width:200, title: '创建时间', align:'center',
{field:'gmtCreate', width:180, title: '创建时间', align:'center',
templet: function(item) {
if(!item.gmtCreate) {
return '-';
@ -333,6 +343,16 @@
reloadTable();
}
});
} else if(layEvent === 'userExpiredDateEvent') {
top.dialog.open({
url: top.restAjax.path('route/user/update-expired-date?userId={userId}', [data.userId]),
title: '【'+ data.userName +'】设置账号过期时间',
width: '274px',
height: '395px',
onClose: function() {
reloadTable();
}
});
}
});
// 事件-排序

View File

@ -54,7 +54,7 @@
top.dialog.confirm(top.dataMessage.update, function(index) {
top.dialog.close(index);
var loadLayerIndex;
top.restAjax.put(top.restAjax.path('api/user/resetpassword/{userId}', [userId]), formData.field, null, function(code, data) {
top.restAjax.put(top.restAjax.path('api/user/reset-password/{userId}', [userId]), formData.field, null, function(code, data) {
var layerIndex = top.dialog.msg(top.dataMessage.updateSuccess, {
time: 0,
btn: [top.dataMessage.button.yes, top.dataMessage.button.no],

View File

@ -47,14 +47,11 @@
<input type="radio" name="userType" value="2" title="普通用户" checked>
</div>
</div>
<div class="layui-form-item">
<div class="layui-form-item" pane>
<label class="layui-form-label">状态 *</label>
<div class="layui-input-block">
<select name="userState" lay-verify="required">
<option value="0">正常</option>
<option value="1">冻结</option>
<option value="2">锁定</option>
</select>
<input type="radio" name="userState" value="0" title="正常" checked>
<input type="radio" name="userState" value="1" title="锁定">
</div>
</div>
<div class="layui-form-item">
@ -69,6 +66,18 @@
<input type="text" name="userEmail" placeholder="请输入邮箱" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">过期时间</label>
<div class="layui-input-block">
<input type="text" name="userExpiredDate" id="userExpiredDate" placeholder="请选择过期日期,空表示永不过期" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">备注</label>
<div class="layui-input-block">
<input type="text" name="remarks" placeholder="请输入备注" class="layui-input">
</div>
</div>
<div class="layui-form-item layui-form-text">
<label class="layui-form-label">头像</label>
<div class="layui-input-block">
@ -99,10 +108,22 @@
index: 'lib/index' //主入口模块
}).use(['index', 'form', 'laydate'], function(){
var $ = layui.$;
var laydate = layui.laydate;
var form = layui.form;
function closeBox() {
parent.layer.close(parent.layer.getFrameIndex(window.name));
}
function initDate() {
laydate.render({
elem: '#userExpiredDate',
trigger: 'click',
format: 'yyyy-MM-dd HH:mm:ss'
});
}
initDate();
// 提交表单
form.on('submit(submitForm)', function(formData) {
var authorizedGrantTypes = top.restAjax.checkBoxToString(formData.field, 'authorizedGrantTypes');

View File

@ -0,0 +1,86 @@
<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<base th:href="${#request.getContextPath() + '/'}">
<meta charset="utf-8">
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
<link rel="stylesheet" href="assets/fonts/font-awesome/css/font-awesome.css"/>
<link rel="stylesheet" href="assets/layuiadmin/layui/css/layui.css" media="all">
<link rel="stylesheet" href="assets/layuiadmin/style/admin.css" media="all">
</head>
<body>
<div class="layui-anim layui-anim-fadein" style="padding: 0;overflow: hidden;">
<div class="layui-card">
<div class="layui-card-body" style="padding: 0px;">
<form id="dataForm" class="layui-form layui-form-pane" lay-filter="dataForm">
<input type="hidden" name="expiredDate" id="expiredDate" class="layui-input">
<div id="expiredDateBox"></div>
<button id="submitForm" type="button" class="layui-btn" lay-submit lay-filter="submitForm" style="display: none;">提交编辑</button>
</form>
</div>
</div>
</div>
<script src="assets/layuiadmin/layui/layui.js"></script>
<script>
layui.config({
base: 'assets/layuiadmin/' //静态资源所在路径
}).extend({
index: 'lib/index' //主入口模块
}).use(['index', 'form', 'laydate'], function(){
var $ = layui.$;
var laydate = layui.laydate;
var form = layui.form;
var userId = top.restAjax.params(window.location.href).userId;
function closeBox() {
parent.layer.close(parent.layer.getFrameIndex(window.name));
}
laydate.render({
elem: '#expiredDateBox',
position: 'static',
type: 'datetime',
btns: ['now', 'confirm'],
done: function(value, date, endDate) {
$('#expiredDate').val(value);
$('#submitForm').click();
}
});
// 提交表单
form.on('submit(submitForm)', function(formData) {
top.dialog.confirm(top.dataMessage.update, function(index) {
top.dialog.close(index);
var loadLayerIndex;
top.restAjax.put(top.restAjax.path('api/user/update-expired-date/{userId}', [userId]), formData.field, null, function(code, data) {
var layerIndex = top.dialog.msg(top.dataMessage.updateSuccess, {
time: 0,
btn: [top.dataMessage.button.yes, top.dataMessage.button.no],
shade: 0.3,
yes: function(index) {
top.dialog.close(index);
window.location.reload();
},
btn2: function() {
closeBox();
}
});
}, function(code, data) {
top.dialog.msg(data.msg);
}, function() {
loadLayerIndex = top.dialog.msg(top.dataMessage.updating, {icon: 16, time: 0, shade: 0.3});
}, function() {
top.dialog.close(loadLayerIndex);
});
});
return false;
});
$('.close').on('click', function() {
closeBox();
});
});
</script>
</body>
</html>

View File

@ -60,7 +60,7 @@
top.dialog.confirm(top.dataMessage.update, function(index) {
top.dialog.close(index);
var loadLayerIndex;
top.restAjax.put(top.restAjax.path('api/user/updateusername/{userId}', [userId]), formData.field, null, function(code, data) {
top.restAjax.put(top.restAjax.path('api/user/update-username/{userId}', [userId]), formData.field, null, function(code, data) {
var layerIndex = top.dialog.msg(top.dataMessage.updateSuccess, {
time: 0,
btn: [top.dataMessage.button.yes, top.dataMessage.button.no],

View File

@ -47,14 +47,11 @@
<input type="radio" name="userType" value="2" title="普通用户">
</div>
</div>
<div class="layui-form-item">
<div class="layui-form-item" pane>
<label class="layui-form-label">状态 *</label>
<div class="layui-input-block">
<select name="userState" lay-verify="required">
<option value="0">正常</option>
<option value="1">冻结</option>
<option value="2">锁定</option>
</select>
<input type="radio" name="userState" value="0" title="正常">
<input type="radio" name="userState" value="1" title="锁定">
</div>
</div>
<div class="layui-form-item">
@ -69,6 +66,18 @@
<input type="text" name="userEmail" placeholder="请输入邮箱" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">过期时间</label>
<div class="layui-input-block">
<input type="text" name="userExpiredDate" id="userExpiredDate" placeholder="请选择过期日期,空表示永不过期" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">备注</label>
<div class="layui-input-block">
<input type="text" name="remarks" placeholder="请输入备注" class="layui-input">
</div>
</div>
<div class="layui-form-item layui-form-text">
<label class="layui-form-label">头像</label>
<div class="layui-input-block">
@ -99,11 +108,23 @@
index: 'lib/index' //主入口模块
}).use(['index', 'form', 'laydate'], function(){
var $ = layui.$;
var laydate = layui.laydate;
var form = layui.form;
var userId = top.restAjax.params(window.location.href).userId;
function closeBox() {
parent.layer.close(parent.layer.getFrameIndex(window.name));
}
function initDate() {
laydate.render({
elem: '#userExpiredDate',
trigger: 'click',
format: 'yyyy-MM-dd HH:mm:ss'
});
}
initDate();
// 初始化
function initData() {
var self = this;
@ -117,6 +138,7 @@
userState: data.userState +'',
userPhone: data.userPhone,
userEmail: data.userEmail.toString(),
userExpiredDate: data.userExpiredDate
});
form.render(null, 'dataForm');
if($('#userAvatar').val() != '') {