/**
|
* Copyright © 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
|
*/
|
package com.jeeplus.modules.sys.service;
|
|
import java.util.Collection;
|
import java.util.Date;
|
import java.util.List;
|
|
import org.apache.shiro.session.Session;
|
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import com.jeeplus.common.config.Global;
|
import com.jeeplus.common.persistence.Page;
|
import com.jeeplus.common.security.Digests;
|
import com.jeeplus.common.security.shiro.session.SessionDAO;
|
import com.jeeplus.common.service.BaseService;
|
import com.jeeplus.common.service.ServiceException;
|
import com.jeeplus.common.utils.CacheUtils;
|
import com.jeeplus.common.utils.Encodes;
|
import com.jeeplus.common.utils.StringUtils;
|
import com.jeeplus.modules.sys.dao.MenuDao;
|
import com.jeeplus.modules.sys.dao.RoleDao;
|
import com.jeeplus.modules.sys.dao.UserDao;
|
import com.jeeplus.modules.sys.entity.Menu;
|
import com.jeeplus.modules.sys.entity.Office;
|
import com.jeeplus.modules.sys.entity.Role;
|
import com.jeeplus.modules.sys.entity.User;
|
import com.jeeplus.modules.sys.security.SystemAuthorizingRealm;
|
import com.jeeplus.modules.sys.utils.LogUtils;
|
import com.jeeplus.modules.sys.utils.UserUtils;
|
|
/**
|
* 系统管理,安全相关实体的管理类,包括用户、角色、菜单.
|
* @author jeeplus
|
* @version 2013-12-05
|
*/
|
@Service
|
@Transactional(readOnly = true)
|
public class SystemService extends BaseService implements InitializingBean {
|
|
public static final String HASH_ALGORITHM = "SHA-1";
|
public static final int HASH_INTERATIONS = 1024;
|
public static final int SALT_SIZE = 8;
|
|
@Autowired
|
private UserDao userDao;
|
@Autowired
|
private RoleDao roleDao;
|
@Autowired
|
private MenuDao menuDao;
|
@Autowired
|
private SessionDAO sessionDao;
|
@Autowired
|
private SystemAuthorizingRealm systemRealm;
|
|
public SessionDAO getSessionDao() {
|
return sessionDao;
|
}
|
|
|
//-- User Service --//
|
|
/**
|
* 获取用户
|
* @param id
|
* @return
|
*/
|
public User getUser(String id) {
|
return UserUtils.get(id);
|
}
|
|
/**
|
* 根据登录名获取用户
|
* @param loginName
|
* @return
|
*/
|
public User getUserByLoginName(String loginName) {
|
return UserUtils.getByLoginName(loginName);
|
}
|
|
public Page<User> findUser(Page<User> page, User user) {
|
// 生成数据权限过滤条件(dsf为dataScopeFilter的简写,在xml中使用 ${sqlMap.dsf}调用权限SQL)
|
user.getSqlMap().put("dsf", dataScopeFilter(user.getCurrentUser(), "o", "a"));
|
// 设置分页参数
|
user.setPage(page);
|
// 执行分页查询
|
page.setList(userDao.findList(user));
|
return page;
|
}
|
|
/**
|
* 无分页查询人员列表
|
* @param user
|
* @return
|
*/
|
public List<User> findUser(User user){
|
// 生成数据权限过滤条件(dsf为dataScopeFilter的简写,在xml中使用 ${sqlMap.dsf}调用权限SQL)
|
user.getSqlMap().put("dsf", dataScopeFilter(user.getCurrentUser(), "o", "a"));
|
List<User> list = userDao.findList(user);
|
return list;
|
}
|
|
/**
|
* 通过部门ID获取用户列表,仅返回用户id和name(树查询用户时用)
|
* @param user
|
* @return
|
*/
|
@SuppressWarnings("unchecked")
|
public List<User> findUserByOfficeId(String officeId) {
|
List<User> list = (List<User>)CacheUtils.get(UserUtils.USER_CACHE, UserUtils.USER_CACHE_LIST_BY_OFFICE_ID_ + officeId);
|
if (list == null){
|
User user = new User();
|
user.setOffice(new Office(officeId));
|
list = userDao.findUserByOfficeId(user);
|
CacheUtils.put(UserUtils.USER_CACHE, UserUtils.USER_CACHE_LIST_BY_OFFICE_ID_ + officeId, list);
|
}
|
return list;
|
}
|
|
@Transactional(readOnly = false)
|
public void saveUser(User user) {
|
if (StringUtils.isBlank(user.getId())){
|
user.preInsert();
|
userDao.insert(user);
|
}else{
|
// 清除原用户机构用户缓存
|
User oldUser = userDao.get(user.getId());
|
if (oldUser.getOffice() != null && oldUser.getOffice().getId() != null){
|
CacheUtils.remove(UserUtils.USER_CACHE, UserUtils.USER_CACHE_LIST_BY_OFFICE_ID_ + oldUser.getOffice().getId());
|
}
|
// 更新用户数据
|
user.preUpdate();
|
userDao.update(user);
|
}
|
if (StringUtils.isNotBlank(user.getId())){
|
// 更新用户与角色关联
|
userDao.deleteUserRole(user);
|
if (user.getRoleList() != null && user.getRoleList().size() > 0){
|
userDao.insertUserRole(user);
|
}else{
|
throw new ServiceException(user.getLoginName() + "没有设置角色!");
|
}
|
// 清除用户缓存
|
UserUtils.clearCache(user);
|
// // 清除权限缓存
|
// systemRealm.clearAllCachedAuthorizationInfo();
|
}
|
}
|
|
@Transactional(readOnly = false)
|
public void updateUserInfo(User user) {
|
user.preUpdate();
|
userDao.updateUserInfo(user);
|
// 清除用户缓存
|
UserUtils.clearCache(user);
|
// // 清除权限缓存
|
// systemRealm.clearAllCachedAuthorizationInfo();
|
}
|
|
@Transactional(readOnly = false)
|
public void deleteUser(User user) {
|
userDao.delete(user);
|
// 清除用户缓存
|
UserUtils.clearCache(user);
|
// // 清除权限缓存
|
// systemRealm.clearAllCachedAuthorizationInfo();
|
}
|
|
@Transactional(readOnly = false)
|
public void updatePasswordById(String id, String loginName, String newPassword) {
|
User user = new User(id);
|
user.setPassword(entryptPassword(newPassword));
|
userDao.updatePasswordById(user);
|
// 清除用户缓存
|
user.setLoginName(loginName);
|
UserUtils.clearCache(user);
|
// // 清除权限缓存
|
// systemRealm.clearAllCachedAuthorizationInfo();
|
}
|
|
@Transactional(readOnly = false)
|
public void updateUserLoginInfo(User user) {
|
// 保存上次登录信息
|
user.setOldLoginIp(user.getLoginIp());
|
user.setOldLoginDate(user.getLoginDate());
|
// 更新本次登录信息
|
user.setLoginIp(UserUtils.getSession().getHost());
|
user.setLoginDate(new Date());
|
userDao.updateLoginInfo(user);
|
}
|
|
/**
|
* 生成安全的密码,生成随机的16位salt并经过1024次 sha-1 hash
|
*/
|
public static String entryptPassword(String plainPassword) {
|
byte[] salt = Digests.generateSalt(SALT_SIZE);
|
byte[] hashPassword = Digests.sha1(plainPassword.getBytes(), salt, HASH_INTERATIONS);
|
return Encodes.encodeHex(salt)+Encodes.encodeHex(hashPassword);
|
}
|
|
/**
|
* 验证密码
|
* @param plainPassword 明文密码
|
* @param password 密文密码
|
* @return 验证成功返回true
|
*/
|
public static boolean validatePassword(String plainPassword, String password) {
|
byte[] salt = Encodes.decodeHex(password.substring(0,16));
|
byte[] hashPassword = Digests.sha1(plainPassword.getBytes(), salt, HASH_INTERATIONS);
|
return password.equals(Encodes.encodeHex(salt)+Encodes.encodeHex(hashPassword));
|
}
|
|
/**
|
* 获得活动会话
|
* @return
|
*/
|
public Collection<Session> getActiveSessions(){
|
return sessionDao.getActiveSessions(false);
|
}
|
|
//-- Role Service --//
|
|
public Role getRole(String id) {
|
return roleDao.get(id);
|
}
|
|
public Role getRoleByName(String name) {
|
Role r = new Role();
|
r.setName(name);
|
return roleDao.getByName(r);
|
}
|
|
public Role getRoleByEnname(String enname) {
|
Role r = new Role();
|
r.setEnname(enname);
|
return roleDao.getByEnname(r);
|
}
|
|
public List<Role> findRole(Role role){
|
return roleDao.findList(role);
|
}
|
|
public List<Role> findAllRole(){
|
return UserUtils.getRoleList();
|
}
|
|
@Transactional(readOnly = false)
|
public void saveRole(Role role) {
|
if (StringUtils.isBlank(role.getId())){
|
role.preInsert();
|
roleDao.insert(role);
|
}else{
|
role.preUpdate();
|
roleDao.update(role);
|
}
|
// 更新角色与菜单关联
|
roleDao.deleteRoleMenu(role);
|
if (role.getMenuList().size() > 0){
|
roleDao.insertRoleMenu(role);
|
}
|
// 更新角色与部门关联
|
roleDao.deleteRoleOffice(role);
|
if (role.getOfficeList().size() > 0){
|
roleDao.insertRoleOffice(role);
|
}
|
// 清除用户角色缓存
|
UserUtils.removeCache(UserUtils.CACHE_ROLE_LIST);
|
// // 清除权限缓存
|
// systemRealm.clearAllCachedAuthorizationInfo();
|
}
|
|
@Transactional(readOnly = false)
|
public void deleteRole(Role role) {
|
roleDao.delete(role);
|
// 清除用户角色缓存
|
UserUtils.removeCache(UserUtils.CACHE_ROLE_LIST);
|
// // 清除权限缓存
|
// systemRealm.clearAllCachedAuthorizationInfo();
|
}
|
|
@Transactional(readOnly = false)
|
public Boolean outUserInRole(Role role, User user) {
|
List<Role> roles = user.getRoleList();
|
for (Role e : roles){
|
if (e.getId().equals(role.getId())){
|
roles.remove(e);
|
saveUser(user);
|
return true;
|
}
|
}
|
return false;
|
}
|
|
@Transactional(readOnly = false)
|
public User assignUserToRole(Role role, User user) {
|
if (user == null){
|
return null;
|
}
|
List<String> roleIds = user.getRoleIdList();
|
if (roleIds.contains(role.getId())) {
|
return null;
|
}
|
user.getRoleList().add(role);
|
saveUser(user);
|
return user;
|
}
|
|
//-- Menu Service --//
|
|
public Menu getMenu(String id) {
|
return menuDao.get(id);
|
}
|
|
public List<Menu> findAllMenu(){
|
return UserUtils.getMenuList();
|
}
|
|
@Transactional(readOnly = false)
|
public void saveMenu(Menu menu) {
|
|
// 获取父节点实体
|
menu.setParent(this.getMenu(menu.getParent().getId()));
|
|
// 获取修改前的parentIds,用于更新子节点的parentIds
|
String oldParentIds = menu.getParentIds();
|
|
// 设置新的父节点串
|
menu.setParentIds(menu.getParent().getParentIds()+menu.getParent().getId()+",");
|
|
// 保存或更新实体
|
if (StringUtils.isBlank(menu.getId())){
|
menu.preInsert();
|
menuDao.insert(menu);
|
}else{
|
menu.preUpdate();
|
menuDao.update(menu);
|
}
|
|
// 更新子节点 parentIds
|
Menu m = new Menu();
|
m.setParentIds("%,"+menu.getId()+",%");
|
List<Menu> list = menuDao.findByParentIdsLike(m);
|
for (Menu e : list){
|
e.setParentIds(e.getParentIds().replace(oldParentIds, menu.getParentIds()));
|
menuDao.updateParentIds(e);
|
}
|
// 清除用户菜单缓存
|
UserUtils.removeCache(UserUtils.CACHE_MENU_LIST);
|
// // 清除权限缓存
|
// systemRealm.clearAllCachedAuthorizationInfo();
|
// 清除日志相关缓存
|
CacheUtils.remove(LogUtils.CACHE_MENU_NAME_PATH_MAP);
|
}
|
|
@Transactional(readOnly = false)
|
public void updateMenuSort(Menu menu) {
|
menuDao.updateSort(menu);
|
// 清除用户菜单缓存
|
UserUtils.removeCache(UserUtils.CACHE_MENU_LIST);
|
// // 清除权限缓存
|
// systemRealm.clearAllCachedAuthorizationInfo();
|
// 清除日志相关缓存
|
CacheUtils.remove(LogUtils.CACHE_MENU_NAME_PATH_MAP);
|
}
|
|
@Transactional(readOnly = false)
|
public void deleteMenu(Menu menu) {
|
menuDao.delete(menu);
|
// 清除用户菜单缓存
|
UserUtils.removeCache(UserUtils.CACHE_MENU_LIST);
|
// // 清除权限缓存
|
// systemRealm.clearAllCachedAuthorizationInfo();
|
// 清除日志相关缓存
|
CacheUtils.remove(LogUtils.CACHE_MENU_NAME_PATH_MAP);
|
}
|
|
/**
|
* 获取Key加载信息
|
*/
|
public static boolean printKeyLoadMessage(){
|
StringBuilder sb = new StringBuilder();
|
sb.append("\r\n======================================================================\r\n");
|
sb.append("\r\n 欢迎使用 "+Global.getConfig("productName")+" - Powered By http://www.jeeplus.org\r\n");
|
sb.append("\r\n======================================================================\r\n");
|
System.out.println(sb.toString());
|
return true;
|
}
|
|
|
@Override
|
public void afterPropertiesSet() throws Exception {
|
// TODO Auto-generated method stub
|
|
}
|
|
|
|
}
|