package com.vci.ubcs.system.service.impl; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.vci.ubcs.common.constant.CommonConstant; import com.vci.ubcs.system.cache.NacosConfigCache; import com.vci.ubcs.system.entity.Strategy; import com.vci.ubcs.system.mapper.StrategyMapper; import com.vci.ubcs.system.service.IStrategyService; import com.vci.ubcs.system.user.feign.IUserClient; import org.springblade.core.cache.utils.CacheUtil; import org.springblade.core.log.exception.ServiceException; import org.springblade.core.mp.support.Query; import org.springblade.core.secure.utils.AuthUtil; import org.springblade.core.tool.utils.Func; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.util.Date; import java.util.List; import static org.springblade.core.cache.constant.CacheConstant.SYS_CACHE; /** * 密码策略(Strategy)表服务实现类 * * @author makejava * @since 2023-03-20 15:25:05 */ @Service public class StrategyServiceImpl extends ServiceImpl implements IStrategyService { @Resource private StrategyMapper strategyMapper; @Resource private UserPwdstrategyServiceImpl userPwdstrategyService; @Resource private IUserClient userClient; /** * 通过ID查询单条数据 * * @param id 主键 * @return 实例对象 */ @Override public Strategy queryById(String id) { return this.getById(id); } /** * 查询默认密码策略 * @return */ @Override public Strategy queryByIsDefault() { return this.strategyMapper.queryByIsDefault(AuthUtil.getTenantId() .equals( NacosConfigCache .getAdminUserInfo() .getTenantId() ) ? null:AuthUtil.getTenantId() ); } /** * 分页查询 * * @param query 分页对象 * @return 查询结果 */ @Override public IPage queryAllByPage(Query query) { Page strategyPage = new Page<>(query.getCurrent(), query.getSize()); // 添加租户查询条件 IPage strategyIPage = this.strategyMapper.queryAllByPage( strategyPage, AuthUtil.getTenantId() .equals( NacosConfigCache .getAdminUserInfo() .getTenantId() ) ? null:AuthUtil.getTenantId() ); return strategyIPage; } /** * 新增数据或者修改数据 * * @param strategy 实例对象 * @return 实例对象 */ @Override @Transactional(rollbackFor = Exception.class) public boolean submit(Strategy strategy) { //老的默认密码策略 Long oldIsDefaultStrategy = null; //判断是否携带id,不携带id为新增操作 if(Func.isEmpty(strategy.getId())){ //执行新增 Strategy dbstrategy = this.getOne(Wrappers.query().lambda() .eq(Strategy::getStrategyName, strategy.getStrategyName())); //如果数据库中存在这条组合名称的记录直接返回 if(!Func.isEmpty(dbstrategy)){ throw new ServiceException("该密码策略已存在!"); } //检验密码策略是否符合要求 checkPwdStrategy(strategy); //如果当前新增设置为默认密码策略,需要将已存在默认密码策略修改为非默认 if(strategy.getIsDefault().equals("1") || strategy.getIsDefault() == 1){ //查询老的默认密码策略,便于下面修改 oldIsDefaultStrategy = this.queryByIsDefault().getId(); this.update(Wrappers.update().lambda() .set(Strategy::getIsDefault, CommonConstant.NOT_DEFAULT) .eq(Strategy::getIsDefault, CommonConstant.IS_DEFAULT)); } //创建时间和修改时间添加 if(Func.isEmpty(strategy.getCreateTime())||Func.isEmpty(strategy.getUpdateTime())){ strategy.setCreateTime(new Date()); strategy.setUpdateTime(new Date()); } boolean temp = super.saveOrUpdate(strategy); return temp && updateUserStrategyDefault(temp,oldIsDefaultStrategy); }else { //检验密码策略是否符合要求 checkPwdStrategy(strategy); //如果当前修改设置为默认密码策略,需要将已存在默认密码策略修改为非默认 if((strategy.getIsDefault().toString()).equals("1")){ //查询老的默认密码策略,便于下面修改 Strategy strategyDefault = this.queryByIsDefault(); // 在数据不出现问题的情况下不会出现strategyDefault为空的情况 if(Func.isNotEmpty(strategyDefault)){ oldIsDefaultStrategy = strategyDefault.getId(); this.update(Wrappers.update().lambda() .set(Strategy::getIsDefault,CommonConstant.NOT_DEFAULT) .eq(Strategy::getIsDefault,CommonConstant.IS_DEFAULT)); } }else { // 避免用户将唯一的默认密码策略改为非默认 if(Func.isEmpty(queryByIsDefault())){ throw new ServiceException("默认密码策略必须有且仅有一条!"); } } strategy.setUpdateTime(new Date()); CacheUtil.clear(SYS_CACHE, Boolean.FALSE); boolean temp1 = this.update(strategy,Wrappers.update().lambda().eq(Strategy::getId,strategy.getId())); boolean temp2 = false; if(Func.isNotEmpty(oldIsDefaultStrategy)){ temp2 = updateUserStrategyDefault(temp1, oldIsDefaultStrategy); } return temp1 || temp2; } } /** * 修改使用默认密码策略的用户状态 * @param oldIsDefaultStrategy */ private boolean updateUserStrategyDefault(boolean temp,Long oldIsDefaultStrategy){ boolean resBoolean = false; /** * 产生新的默认密码策略,需要将以前采用默认密码策略的用户做一个更改提醒,由于未出现在关联表中的用户都是采用的默认密码策略,所以需要做一个连接查询出用户id */ if(temp && Func.isNotEmpty(oldIsDefaultStrategy)){ List userIds = userPwdstrategyService.queryByUseISDefault(oldIsDefaultStrategy); if (Func.isNotEmpty(userIds)){ resBoolean = userClient.updateStrategyStatus(userIds).getData(); } } return resBoolean; } /** * 检验密码策略是否符合要求 * @param strategy */ private void checkPwdStrategy(Strategy strategy){ if(strategy.getRequiredType() > strategy.getCombinationIds().split(",").length){ throw new ServiceException("必填种类不能大于所选择的密码组合方式的个数!"); } if(strategy.getMaxPwdLen() < strategy.getMinPwdLen()){ throw new ServiceException("密码最大长度不能小于最小长度!"); } if(Func.isNotEmpty(strategy.getRequiredType()) && (strategy.getMinPwdLen() < strategy.getRequiredType() || strategy.getMaxPwdLen() < strategy.getRequiredType())){ throw new ServiceException("密码最小长度不能小于必填种类的值!"); } if(strategy.getExpirationTime() <= strategy.getReminderTime()){ throw new ServiceException("过期时间不能小于提醒时间!"); } //判断前端是否未提交,是否默认字段 if(Func.isEmpty(strategy.getIsDefault())){ strategy.setIsDefault(0L); } } /** * 通过主键删除数据 * * @param ids 主键 * @return 是否成功 */ @Override public boolean deleteByIds(List ids) { Strategy strategy = this.getOne(Wrappers.query().lambda() .in(Strategy::getId,ids) .eq(Strategy::getIsDefault, CommonConstant.IS_DEFAULT)); //如果存在默认策略的id,就不能直接删除给出提示 if(!Func.isEmpty(strategy)){ throw new ServiceException("不能删除默认密码策略!"); } boolean tenantTemp = this.removeBatchByIds(ids); return tenantTemp; } /** * 通过租户id以及用户名查询密码策略 * @param tenantId * @param name * @return */ @Override public Strategy queryByNameAndTenantId(String tenantId, String name) { Strategy strategy = this.strategyMapper.queryByNameAndTenantId(tenantId,name); if(!Func.isEmpty(strategy)){ return strategy; } return queryByIsDefault(); } /** * 根据用户id查询密码策略 * @param userId * @return */ @Override public Strategy queryByUserId(Long userId) { Strategy strategy = this.strategyMapper.queryByUserId(userId); if(!Func.isEmpty(strategy)){ return strategy; } return queryByIsDefault(); } }