package com.gkhy.exam.system.service.impl;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gkhy.exam.common.annotation.DataScope;
import com.gkhy.exam.common.api.CommonPage;
import com.gkhy.exam.common.constant.CacheConstant;
import com.gkhy.exam.common.constant.UserConstant;
import com.gkhy.exam.common.domain.entity.SysRole;
import com.gkhy.exam.common.domain.entity.SysUser;
import com.gkhy.exam.common.enums.UserTypeEnum;
import com.gkhy.exam.common.exception.ApiException;
import com.gkhy.exam.common.utils.PageUtils;
import com.gkhy.exam.common.utils.RedisUtils;
import com.gkhy.exam.common.utils.SecurityUtils;
import com.gkhy.exam.common.utils.StringUtils;
import com.gkhy.exam.system.domain.ExStudent;
import com.gkhy.exam.system.domain.SysUserRole;
import com.gkhy.exam.system.mapper.SysUserMapper;
import com.gkhy.exam.system.mapper.SysUserRoleMapper;
import com.gkhy.exam.system.service.ExStudentService;
import com.gkhy.exam.system.service.SysConfigService;
import com.gkhy.exam.system.service.SysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.validation.Validator;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
*
* 用户表 服务实现类
*
*
* @author kzy
* @since 2023-10-17 14:26:29
*/
@Service
public class SysUserServiceImpl extends ServiceImpl implements SysUserService {
@Autowired
private RedisUtils redisUtils;
@Autowired
private SysConfigService configService;
@Autowired
private Validator validator;
@Autowired
private SysUserRoleMapper userRoleMapper;
@Autowired
private ExStudentService exStudentService;
@Override
public CommonPage selectUserList(SysUser user) {
SysUser currentUser = SecurityUtils.getLoginUser().getUser();
List users = new ArrayList<>();
if (!currentUser.getUserType().equals(UserTypeEnum.WORKSHOP_USER.getCode())) {
if (!currentUser.getUserType().equals(UserTypeEnum.SYSTEM_USER.getCode())) {
user.setCompanyId(currentUser.getCompanyId());
Map paramsMap = new HashMap<>();
// paramsMap.put("userType",currentUser.getUserType());
user.setParams(paramsMap);
}
PageUtils.startPage();
users = baseMapper.userList(user);
}
return CommonPage.restPage(users);
}
/**
* 根据条件分页查询已分配用户角色列表
*
* @param user 用户信息
* @return 用户信息集合信息
*/
@Override
@DataScope(userAlias = "u")
public List selectAllocatedList(SysUser user) {
return baseMapper.selectAllocatedList(user);
}
/**
* 根据条件分页查询未分配用户角色列表
*
* @param user 用户信息
* @return 用户信息集合信息
*/
@Override
@DataScope(userAlias = "u")
public List selectUnallocatedList(SysUser user) {
return baseMapper.selectUnallocatedList(user);
}
@Override
public SysUser selectUserByUsername(String username) {
String key = redisUtils.generateKey(CacheConstant.SYS_ADMIN_USER_NAME + username);
SysUser sysUser = null;
if (redisUtils.hasKey(key)) {
sysUser = (SysUser) redisUtils.get(key);
} else {
sysUser = baseMapper.getUserByUsername(username);
redisUtils.set(key, sysUser, 10, TimeUnit.MINUTES);
}
return sysUser;
}
public void delCacheByUsername(String username) {
String key = redisUtils.generateKey(CacheConstant.SYS_ADMIN_USER_NAME + username);
redisUtils.del(key);
}
@Override
public SysUser selectUserByPhone(String phone) {
return baseMapper.getUserByPhone(phone);
}
@Override
public SysUser selectUserById(Long userId) {
return baseMapper.getUserById(userId);
}
@Override
public int deleteUserById(Long userId) {
SysUser user = checkUserDataScope(userId);
if (user.getId().toString().equals("1")) {
throw new ApiException("管理员用户不能被删除");
}
delCacheByUsername(user.getUsername());
return baseMapper.deleteUserById(userId);
}
@Override
@Transactional(rollbackFor = RuntimeException.class)
public int addUser(SysUser user) {
ExStudent exStudent = new ExStudent();
exStudent.setCompanyId(user.getCompanyId());
exStudent.setName(user.getName());
exStudent.setPassword(user.getPassword());
exStudent.setDeptId(user.getDeptId());
exStudent.setDuty(user.getDuty());
exStudent.setSex(user.getSex());
exStudent.setPhone(user.getPhone());
checkRequestData(user);
checkUserAllowed(user);
user.setCreateBy(SecurityUtils.getUsername());
user.setPassword(SecurityUtils.encryptPassword(Base64.decodeStr(user.getPassword())));
int row = baseMapper.insert(user);
batchSaveRole(user.getRoles(), user.getId(), false);
exStudentService.insertStudent(exStudent);
if (row < 1) {
throw new ApiException("新增用户失败");
}
return row;
}
public void batchSaveRole(List roleIds, Long userId, boolean isUpdate) {
if (isUpdate) {
userRoleMapper.deleteUserRoleByUserId(userId);
}
List userRoleList = new ArrayList<>();
if (roleIds != null && !roleIds.isEmpty()) {
for (SysRole roleId : roleIds) {
SysUserRole sysUserRole = new SysUserRole();
sysUserRole.setUserId(userId);
sysUserRole.setRoleId(roleId.getRoleId());
userRoleList.add(sysUserRole);
}
} else {
SysUserRole sysUserRole = new SysUserRole();
sysUserRole.setUserId(userId);
sysUserRole.setRoleId(2L);
userRoleList.add(sysUserRole);
}
userRoleMapper.batchUserRole(userRoleList);
}
@Override
public int updateUser(SysUser user) {
checkRequestData(user);
checkUserAllowed(user);
user.setUpdateBy(SecurityUtils.getUsername());
user.setPassword(null);
int row = baseMapper.updateById(user);
batchSaveRole(user.getRoles(), user.getId(), true);
if (row < 1) {
throw new ApiException("更新用户信息失败");
}
delCacheByUsername(user.getUsername());
return row;
}
public void checkRequestData(SysUser user) {
if (!user.getUserType().equals(UserTypeEnum.SYSTEM_USER.getCode()) && user.getCompanyId() == null) {
throw new ApiException("所属公司不能为空");
}
if (!checkUsernameUnique(user)) {
throw new ApiException("登录账号已存在");
}
if (StringUtils.isNotBlank(user.getPhone()) && !checkPhoneUnique(user)) {
throw new ApiException("手机号已存在");
}
}
@Override
public int updateUserStatus(SysUser user) {
SysUser existUser = checkUserDataScope(user.getId());
SysUser su = new SysUser().setId(user.getId()).setStatus(user.getStatus());
su.setUpdateBy(SecurityUtils.getUsername());
int row = baseMapper.updateById(su);
if (row < 1) {
throw new ApiException("更新用户状态失败");
}
delCacheByUsername(existUser.getUsername());
return row;
}
@Override
public int updateSpecialCertificate(SysUser user) {
SysUser existUser = checkUserDataScope(user.getId());
SysUser su = new SysUser().setId(user.getId()).setOperationCertificate(user.getOperationCertificate());
su.setUpdateBy(SecurityUtils.getUsername());
int row = baseMapper.updateById(su);
if (row < 1) {
throw new ApiException("更新用户状态失败");
}
return row;
}
@Override
public boolean resetUserPwd(SysUser user) {
SysUser existUser = checkUserDataScope(user.getId());
SysUser su = new SysUser().setId(user.getId()).setPassword(SecurityUtils.encryptPassword(Base64.decodeStr(user.getPassword())));
su.setUpdateBy(SecurityUtils.getUsername());
delCacheByUsername(existUser.getUsername());
return updateById(su);
}
@Override
public boolean checkUsernameUnique(SysUser user) {
Long userId = user.getId() == null ? -1L : user.getId();
SysUser info = baseMapper.checkLoginNameUnique(user.getUsername());
if (info != null && info.getId().longValue() != userId.longValue()) {
return UserConstant.NOT_UNIQUE;
}
return UserConstant.UNIQUE;
}
@Override
public Map getUserData(Long companyId) {
List sysUsers = baseMapper.selectList(new LambdaQueryWrapper<>(
SysUser.class
).eq(SysUser::getCompanyId, companyId).eq(SysUser::getDelFlag, UserConstant.ENABLE));
int totalUser = sysUsers.size();
Map map = new HashMap<>();
//总人数
map.put("totalUser", totalUser);
//专业
map.put("post", sysUsers.stream()
.map(SysUser::getPost)
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.joining(",")));
//学历硕士以上
// 统计学历为硕士(4)和博士及以上(5)的人数
long count = sysUsers.stream()
.filter(user -> user.getQualification() != null)
.filter(user -> user.getQualification() >= 4) // 4: 硕士, 5: 博士及以上
.count();
map.put("qualification", count);
long qualification1 = sysUsers.stream()
.filter(user -> user.getQualification() != null)
.filter(user -> user.getQualification().equals("1"))
.count();
map.put("qualification1", qualification1);//学历1、高中及以下
long qualification2 = sysUsers.stream()
.filter(user -> user.getQualification() != null)
.filter(user -> user.getQualification().equals("2"))
.count();
map.put("qualification2", qualification2);//学历2、专科
long qualification3 = sysUsers.stream()
.filter(user -> user.getQualification() != null)
.filter(user -> user.getQualification().equals("3"))
.count();
map.put("qualification3", qualification3);//学历3本科
long qualification4 = sysUsers.stream()
.filter(user -> user.getQualification() != null)
.filter(user -> user.getQualification().equals("4"))
.count();
map.put("qualification4", qualification4);//学历4硕士
long qualification5 = sysUsers.stream()
.filter(user -> user.getQualification() != null)
.filter(user -> user.getQualification().equals("5"))
.count();
map.put("qualification5", qualification5);//学历5博士及以上
//高级职称人数
long positionalCount = sysUsers.stream()
.filter(user -> user.getPositional() != null)
.filter(user -> user.getPositional().equals("3")) // 4: 硕士, 5: 博士及以上
.count();
map.put("positional3", positionalCount);
long positionalCount2 = sysUsers.stream()
.filter(user -> user.getPositional() != null)
.filter(user -> user.getPositional().equals("2")) // 4: 硕士, 5: 博士及以上
.count();
map.put("positional2", positionalCount2);//中级
long positionalCount1 = sysUsers.stream()
.filter(user -> user.getPositional() != null)
.filter(user -> user.getPositional().equals("1")) // 4: 硕士, 5: 博士及以上
.count();
map.put("positional1", positionalCount1);//初级
map.put("positional12", positionalCount2 + positionalCount1);//中级+初级
long countBk = sysUsers.stream()
.filter(user -> user.getQualification() != null)
.filter(user -> user.getQualification() >= 3) // 本科以上
.count();
//本科人数
map.put("qualificationBK", countBk);
double bachelorRatio = totalUser > 0 ? (double) countBk / totalUser * 100 : 0;
//本科占比
map.put("qualificationBKRatio", String.format("%.2f%%", bachelorRatio));
long countJS = sysUsers.stream()
.filter(user -> user.getPersonType() != null)
.filter(user -> user.getPersonType() == 1) // 技术类
.count();
map.put("personTypeJS", countJS);
double jsRatio = totalUser > 0 ? (double) countJS / totalUser * 100 : 0;
map.put("jsRatio", String.format("%.2f%%", jsRatio));
double averageAge = sysUsers.stream()
.filter(user -> user.getAge() != null) // 过滤年龄为null的用户
.mapToInt(SysUser::getAge) // 提取年龄值
.average() // 计算平均值
.orElse(0.0);
map.put("avgAge", String.format("%.1f", averageAge));//平均年龄
long countAge40 = sysUsers.stream()
.filter(user -> user.getAge() != null)
.filter(user -> user.getAge() >= 40) // 40以上人数
.count();
map.put("age40", countAge40);
double age40Ratio = totalUser > 0 ? (double) countAge40 / totalUser * 100 : 0;
map.put("age40Ratio", String.format("%.2f%%", age40Ratio));
long countAge30 = totalUser - countAge40;
map.put("age1840", countAge30);//18-40
double age30Ratio = totalUser > 0 ? (double) countAge30 / totalUser * 100 : 0;
map.put("age1840Ratio", String.format("%.2f%%", age30Ratio));
return Collections.emptyMap();
}
@Override
public boolean checkPhoneUnique(SysUser user) {
Long userId = user.getId() == null ? -1L : user.getId();
SysUser info = baseMapper.checkPhoneUnique(user.getPhone());
if (info != null && info.getId().longValue() != userId.longValue()) {
return UserConstant.NOT_UNIQUE;
}
return UserConstant.UNIQUE;
}
@Override
public void checkUserAllowed(SysUser user) {
SysUser currentUser = SecurityUtils.getLoginUser().getUser();
Integer currentUserType = currentUser.getUserType();
Integer userType = user.getUserType();
//校验权限,规则:上一级用户可以增加下一级用户类型的用户
// if(currentUserType.equals(UserTypeEnum.SYSTEM_USER.getCode())){
// if( !userType.equals(UserTypeEnum.SYSTEM_USER.getCode())&&!userType.equals(UserTypeEnum.OTHER_USER.getCode()) &&!userType.equals(UserTypeEnum.COMPANY_USER.getCode())){
// throw new ApiException("管理员只能操作管理员、企业级和其他类型的用户");
// }
// if (user.getId().toString().equals("1")){
// throw new ApiException("管理员用户不能被删除");
// }
// }else{
if (!currentUserType.equals(UserTypeEnum.SYSTEM_USER.getCode())) {
if (userType.equals(UserTypeEnum.OTHER_USER.getCode())) {
throw new ApiException("没有权限操作或者更新上级用户类型的用户");
}
if (currentUserType.equals(UserTypeEnum.OTHER_USER.getCode()) || currentUserType.equals(UserTypeEnum.COMPANY_ADMIN.getCode())) {
if (userType <= UserTypeEnum.COMPANY_USER.getCode() && !currentUserType.equals(UserTypeEnum.COMPANY_ADMIN.getCode())) {
throw new ApiException("没有权限操作或者更新上级用户类型的用户");
}
} else {
if (userType < currentUserType) {
throw new ApiException("没有权限操作或者更新上级用户类型的用户");
}
}
}
}
@Override
public SysUser checkUserDataScope(Long userId) {
if (userId == null) {
throw new ApiException("用户id为空!");
}
SysUser user = getById(userId);
if (ObjectUtil.isNull(user)) {
throw new ApiException("用户数据不存在!");
}
checkUserAllowed(user);
return user;
}
}