1、新增晨丰科技组织编辑限制、组织编辑管理员信息同步用户、用户管理更新手机号/昵称同步组织管理员信息、修改手机号同步组织管理员信息;2、未排单订单分组分页补充订单类型;3、装配清单顶级部件接口无数据修复;

This commit is contained in:
gaoqr
2026-04-21 15:53:58 +08:00
parent a11ec028fd
commit a8550740d0
8 changed files with 212 additions and 68 deletions
@@ -33,27 +33,40 @@ public class OrderRespVOCopy {
@Schema(description = "订单状态") @Schema(description = "订单状态")
private Integer status; private Integer status;
@Schema(description = "订单类型")
private Integer orderType;
@Schema(description = "自定义单号") @Schema(description = "自定义单号")
private String defineId; private String defineId;
@Schema(description = "客户") @Schema(description = "客户")
private String customer; private String customer;
@Schema(description = "地址") @Schema(description = "地址")
private String address; private String address;
@Schema(description = "订单日期") @Schema(description = "订单日期")
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY, timezone = TIME_ZONE_DEFAULT) @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY, timezone = TIME_ZONE_DEFAULT)
private LocalDateTime orderDate; private LocalDateTime orderDate;
@Schema(description = "交付日期") @Schema(description = "交付日期")
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
private LocalDateTime deliveryDate; private LocalDateTime deliveryDate;
@Schema(description = "更新时间") @Schema(description = "更新时间")
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
private Date updateTime; private Date updateTime;
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
private Date createTime; private Date createTime;
@Schema(description = "片数") @Schema(description = "片数")
private int num; private int num;
@Schema(description = "平方") @Schema(description = "平方")
private BigDecimal area = new BigDecimal("0"); private BigDecimal area = new BigDecimal("0");
@Schema(description = "商品id") @Schema(description = "商品id")
private String goodsId; private String goodsId;
@@ -62,5 +75,4 @@ public class OrderRespVOCopy {
@Schema(description = "子单列表") @Schema(description = "子单列表")
private List<OrderRespVOCopy> child; private List<OrderRespVOCopy> child;
} }
@@ -34,19 +34,27 @@
</select> </select>
<select id="getOrderTopComponentList" resultType="com.cf.imes.module.executor.dal.dataobject.ordercomponent.OrderComponentDO"> <select id="getOrderTopComponentList" resultType="com.cf.imes.module.executor.dal.dataobject.ordercomponent.OrderComponentDO">
select distinct oc.id, oc.name SELECT top.id, top.name
from order_component oc FROM order_component top
join order_item oi on oc.id = oi.comp_id WHERE top.pid = 0
and oi.order_id = oc.order_id
and oi.organ_id = oc.organ_id
where oc.order_id in
<foreach item="orderId" collection="orderIds" open="(" separator="," close=")">
#{orderId}
</foreach>
and oc.pid = 0
<if test="name != null and name != ''"> <if test="name != null and name != ''">
and oc.name like CONCAT('%', #{name}, '%') and oc.name like CONCAT('%', #{name}, '%')
</if> </if>
AND top.order_id in
<foreach item="orderId" collection="orderIds" open="(" separator="," close=")">
#{orderId}
</foreach>
AND EXISTS (
SELECT 1
FROM order_component oc
JOIN order_item oi
ON oi.comp_id = oc.id
AND oi.order_id = oc.order_id
AND oi.organ_id = oc.organ_id
WHERE oc.top_id = top.id
AND oc.order_id = top.order_id
AND oc.organ_id = top.organ_id
);
</select> </select>
<select id="getComponentListOnTopLevel" <select id="getComponentListOnTopLevel"
@@ -14,7 +14,7 @@
<result property="orderDate" column="orderDate"/> <result property="orderDate" column="orderDate"/>
<result property="num" column="num"/> <result property="num" column="num"/>
<result property="area" column="area"/> <result property="area" column="area"/>
<result property="orderType" column="orderType"/>
</resultMap> </resultMap>
@@ -25,6 +25,7 @@
o.plate_num - o.planned_plate_num as num, o.plate_num - o.planned_plate_num as num,
o.area - o.planned_plate_area as area, o.area - o.planned_plate_area as area,
o.parent_id as parentId, o.parent_id as parentId,
o.order_type as orderType,
</if> </if>
<if test="type != null and type == @com.cf.imes.module.executor.enums.OrderPlanQueryTypeEnum@GOODS_GROUP.getType()"> <if test="type != null and type == @com.cf.imes.module.executor.enums.OrderPlanQueryTypeEnum@GOODS_GROUP.getType()">
sum(og.plate_num - og.planned_plate_num) as num, sum(og.plate_num - og.planned_plate_num) as num,
@@ -171,4 +171,13 @@ public interface OrganService {
* @return * @return
*/ */
Map<String, Object> getOrgStatusGroupStatistics(OrgStatusGroupStatisticsReqVO reqVO); Map<String, Object> getOrgStatusGroupStatistics(OrgStatusGroupStatisticsReqVO reqVO);
/**
* 更新组织管理员名字和手机
*
* @param id
* @param contactMobile
* @param contactName
*/
void syncUserToOrgAdmin(Long id, String contactMobile, String contactName);
} }
@@ -18,6 +18,7 @@ import com.cf.imes.framework.common.util.json.JsonUtils;
import com.cf.imes.framework.common.util.object.BeanUtils; import com.cf.imes.framework.common.util.object.BeanUtils;
import com.cf.imes.framework.common.util.pinyin.PinYinUtils; import com.cf.imes.framework.common.util.pinyin.PinYinUtils;
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX; import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.cf.imes.framework.mybatis.core.query.LambdaUpdateWrapperX;
import com.cf.imes.framework.organ.config.OrganProperties; import com.cf.imes.framework.organ.config.OrganProperties;
import com.cf.imes.framework.organ.core.aop.OrganIgnore; import com.cf.imes.framework.organ.core.aop.OrganIgnore;
import com.cf.imes.framework.organ.core.context.OrganContextHolder; import com.cf.imes.framework.organ.core.context.OrganContextHolder;
@@ -65,6 +66,7 @@ import com.cf.imes.module.system.service.permission.PermissionService;
import com.cf.imes.module.system.service.permission.RoleService; import com.cf.imes.module.system.service.permission.RoleService;
import com.cf.imes.module.system.service.user.AdminUserService; import com.cf.imes.module.system.service.user.AdminUserService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
@@ -276,33 +278,47 @@ public class OrganServiceImpl implements OrganService {
// 校验组织域名是否重复 // 校验组织域名是否重复
validTenantWebsiteDuplicate(updateReqVO.getWebsite(), organId); validTenantWebsiteDuplicate(updateReqVO.getWebsite(), organId);
// 校验组织手机号是否重复 // 校验组织手机号是否重复
validContactMobileDuplicate(updateReqVO.getOrgAdminMobile(),organId); String currentOrgAdminMobile = updateReqVO.getOrgAdminMobile();
validContactMobileDuplicate(currentOrgAdminMobile, organId);
// 不允许禁用自身组织
checkCfOrgWhenOperate(organId);
if(!Objects.equals(tenant.getName(), updateReqVO.getName())) { if (!Objects.equals(tenant.getName(), updateReqVO.getName())) {
String pinyinFull = PinYinUtils.convertToPinyin(tenant.getName()); String pinyinFull = PinYinUtils.convertToPinyin(tenant.getName());
if(CharSequenceUtil.isNotBlank(pinyinFull)) { if (CharSequenceUtil.isNotBlank(pinyinFull)) {
pinyinFull = pinyinFull.replace(" ", ""); pinyinFull = pinyinFull.replace(" ", "");
} }
tenant.setPinyinFull(pinyinFull); tenant.setPinyinFull(pinyinFull);
tenant.setPinyinInitial(PinYinUtils.convertFirstChar(tenant.getName())); tenant.setPinyinInitial(PinYinUtils.convertFirstChar(tenant.getName()));
} }
// 如果手机号更新,需要同步更新 token 管理的 token String mobileChange = null;
if(!Objects.equals(tenant.getContactMobile(), updateReqVO.getOrgAdminMobile())){ String nicknameChange = null;
// 手机号更新
String contactMobile = tenant.getContactMobile();
if (ObjectUtil.notEqual(contactMobile, currentOrgAdminMobile)) {
// 同步更新 token 管理的 token
List<TokenConfigDO> tokenConfigDOS = tokenConfigMapper.selectConfigByOrganId(organId); List<TokenConfigDO> tokenConfigDOS = tokenConfigMapper.selectConfigByOrganId(organId);
if(CollUtil.isNotEmpty(tokenConfigDOS)) { if (CollUtil.isNotEmpty(tokenConfigDOS)) {
tokenConfigDOS.forEach(f -> { tokenConfigDOS.forEach(f -> {
f.setAppToken(generateBaseToken(organId, updateReqVO.getOrgAdminMobile(), f.getAppType(), jwtProperties.getSecret())); f.setAppToken(generateBaseToken(organId, currentOrgAdminMobile, f.getAppType(), jwtProperties.getSecret()));
}); });
tokenConfigMapper.updateBatch(tokenConfigDOS); tokenConfigMapper.updateBatch(tokenConfigDOS);
} }
mobileChange = currentOrgAdminMobile;
} }
// 昵称更新
if (ObjectUtil.notEqual(tenant.getContactName(), updateReqVO.getOrgAdminName())) {
nicknameChange = updateReqVO.getOrgAdminName();
}
// 同步到管理员账号
userService.syncOrgAdminToUser(tenant.getContactUserId(), mobileChange, nicknameChange);
// 更新组织 // 更新组织
OrganizationDO updateObj = BeanUtils.toBean(updateReqVO, OrganizationDO.class); OrganizationDO updateObj = BeanUtils.toBean(updateReqVO, OrganizationDO.class);
updateObj.setContactMobile(mobileChange);
updateObj.setContactName(nicknameChange);
organMapper.updateById(updateObj); organMapper.updateById(updateObj);
// 更新产品购买记录 // 更新产品购买记录
@@ -430,7 +446,7 @@ public class OrganServiceImpl implements OrganService {
} }
/** /**
* 检查是否操作当前组织 * 不允许删除自身
*/ */
private void checkCurrentWhenOperate(Long organId) { private void checkCurrentWhenOperate(Long organId) {
if (ObjectUtil.equal(organId, SecurityFrameworkUtils.getUserOrganId())) { if (ObjectUtil.equal(organId, SecurityFrameworkUtils.getUserOrganId())) {
@@ -438,6 +454,15 @@ public class OrganServiceImpl implements OrganService {
} }
} }
/**
* 不允许禁用自身
*/
private void checkCfOrgWhenOperate(Long organId) {
if (ObjectUtil.equal(organId, SecurityFrameworkUtils.CF_ORGANID)) {
throw new ServiceException(ORGAN_USER_OPER_NOT_ALLOW);
}
}
private OrganizationDO validateUpdateTenant(Long id) { private OrganizationDO validateUpdateTenant(Long id) {
OrganizationDO tenant = organMapper.selectById(id); OrganizationDO tenant = organMapper.selectById(id);
if (tenant == null) { if (tenant == null) {
@@ -810,4 +835,16 @@ public class OrganServiceImpl implements OrganService {
return resultMap; return resultMap;
} }
@Override
public void syncUserToOrgAdmin(Long id, String contactMobile, String contactName) {
if (StringUtils.isAllEmpty(contactMobile, contactName)) {
return;
}
organMapper.update(new LambdaUpdateWrapperX<OrganizationDO>()
.setIfPresent(OrganizationDO::getContactMobile, contactMobile)
.setIfPresent(OrganizationDO::getContactName, contactName)
.eq(OrganizationDO::getId, id)
);
}
} }
@@ -300,4 +300,13 @@ public interface AdminUserService {
* @return * @return
*/ */
Map<String, Object> getUserStatusGroupStatistics(OrgStatusGroupStatisticsReqVO reqVO); Map<String, Object> getUserStatusGroupStatistics(OrgStatusGroupStatisticsReqVO reqVO);
/**
* 同步组织管理员账户、姓名
*
* @param userId
* @param contactMobile
* @param contactName
*/
void syncOrgAdminToUser(Long userId, String contactMobile, String contactName);
} }
@@ -19,6 +19,7 @@ import com.cf.imes.framework.common.util.object.BeanUtils;
import com.cf.imes.framework.common.util.pinyin.PinYinUtils; import com.cf.imes.framework.common.util.pinyin.PinYinUtils;
import com.cf.imes.framework.common.util.servlet.ServletUtils; import com.cf.imes.framework.common.util.servlet.ServletUtils;
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX; import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.cf.imes.framework.mybatis.core.query.LambdaUpdateWrapperX;
import com.cf.imes.framework.mybatis.core.query.MPJLambdaWrapperX; import com.cf.imes.framework.mybatis.core.query.MPJLambdaWrapperX;
import com.cf.imes.framework.organ.core.aop.OrganIgnore; import com.cf.imes.framework.organ.core.aop.OrganIgnore;
import com.cf.imes.framework.organ.core.context.OrganContextHolder; import com.cf.imes.framework.organ.core.context.OrganContextHolder;
@@ -37,11 +38,11 @@ import com.cf.imes.module.system.controller.admin.user.vo.profile.UserProfileUpd
import com.cf.imes.module.system.controller.admin.user.vo.user.*; import com.cf.imes.module.system.controller.admin.user.vo.user.*;
import com.cf.imes.module.system.dal.dataobject.dept.DeptDO; import com.cf.imes.module.system.dal.dataobject.dept.DeptDO;
import com.cf.imes.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO; import com.cf.imes.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
import com.cf.imes.module.system.dal.dataobject.organ.OrganizationDO;
import com.cf.imes.module.system.dal.dataobject.permission.UserRoleDO; import com.cf.imes.module.system.dal.dataobject.permission.UserRoleDO;
import com.cf.imes.module.system.dal.dataobject.user.AdminUserDO; import com.cf.imes.module.system.dal.dataobject.user.AdminUserDO;
import com.cf.imes.module.system.dal.dataobject.user.UserStatusGroupStatisticsDO; import com.cf.imes.module.system.dal.dataobject.user.UserStatusGroupStatisticsDO;
import com.cf.imes.module.system.dal.mysql.user.AdminUserMapper; import com.cf.imes.module.system.dal.mysql.user.AdminUserMapper;
import com.cf.imes.module.system.enums.ErrorCodeConstants;
import com.cf.imes.module.system.enums.logger.LoginLogTypeEnum; import com.cf.imes.module.system.enums.logger.LoginLogTypeEnum;
import com.cf.imes.module.system.enums.logger.LoginResultEnum; import com.cf.imes.module.system.enums.logger.LoginResultEnum;
import com.cf.imes.module.system.enums.sms.SmsSceneEnum; import com.cf.imes.module.system.enums.sms.SmsSceneEnum;
@@ -149,12 +150,13 @@ public class AdminUserServiceImpl implements AdminUserService {
organService.handleOrganInfo(organ -> { organService.handleOrganInfo(organ -> {
long count = userMapper.selectCount(new LambdaQueryWrapperX<AdminUserDO>().eq(AdminUserDO::getOrganId, organId)); long count = userMapper.selectCount(new LambdaQueryWrapperX<AdminUserDO>().eq(AdminUserDO::getOrganId, organId));
if (count >= organ.getAccountCount()) { if (count >= organ.getAccountCount()) {
throw new ServiceException(ErrorCodeConstants.USER_COUNT_MAX, organ.getAccountCount()); throw new ServiceException(USER_COUNT_MAX, organ.getAccountCount());
} }
}, organId); }, organId);
// 校验正确性 // 校验正确性
validateUserForCreateOrUpdate(null, createReqVO.getMobile(), createReqVO.getDeptId(), null, organId); validateUserForCreateOrUpdate(null, createReqVO.getMobile(), createReqVO.getDeptId(), null);
// 插入用户 // 插入用户
AdminUserDO user = BeanUtils.toBean(createReqVO, AdminUserDO.class); AdminUserDO user = BeanUtils.toBean(createReqVO, AdminUserDO.class);
// 改造:手机号直接当做用户名 // 改造:手机号直接当做用户名
@@ -173,40 +175,51 @@ public class AdminUserServiceImpl implements AdminUserService {
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void updateUser(UserSaveReqVO updateReqVO) { public void updateUser(UserSaveReqVO updateReqVO) {
Long organId = updateReqVO.getOrganId() == null ? OrganContextHolder.getOrganId() : updateReqVO.getOrganId();
String mobile = updateReqVO.getMobile(); String mobile = updateReqVO.getMobile();
String nickname = updateReqVO.getNickname();
Long userId = updateReqVO.getId(); Long userId = updateReqVO.getId();
// 不允许关闭自身状态 // 不允许关闭自身状态
checkCurrentWhenOperateStatus(userId, updateReqVO.getStatus()); checkCurrentWhenOperateStatus(userId, updateReqVO.getStatus());
// 校验正确性 // 校验正确性
AdminUserDO currUserDO = validateUserForCreateOrUpdate(userId, mobile, updateReqVO.getDeptId(), null, organId); AdminUserDO currUserDO = validateUserForCreateOrUpdate(userId, mobile, updateReqVO.getDeptId(), null);
// 更新用户 // 更新用户
AdminUserDO updateObj = BeanUtils.toBean(updateReqVO, AdminUserDO.class); AdminUserDO updateObj = BeanUtils.toBean(updateReqVO, AdminUserDO.class);
if (!Objects.isNull(nickname)) {
if (!Objects.isNull(updateReqVO.getNickname())) { String pinyinFull = PinYinUtils.convertToPinyin(nickname);
String pinyinFull = PinYinUtils.convertToPinyin(updateReqVO.getNickname());
if (StringUtils.isNotBlank(pinyinFull)) { if (StringUtils.isNotBlank(pinyinFull)) {
pinyinFull = pinyinFull.replace(" ", ""); pinyinFull = pinyinFull.replace(" ", "");
} }
updateObj.setPinyinFull(pinyinFull); updateObj.setPinyinFull(pinyinFull);
updateObj.setPinyinInitial(PinYinUtils.convertFirstChar(updateReqVO.getNickname())); updateObj.setPinyinInitial(PinYinUtils.convertFirstChar(nickname));
} }
Long id = updateObj.getId(); Long id = updateObj.getId();
if (ObjectUtil.isNotNull(id)) { if (ObjectUtil.isNotNull(id)) {
AdminUserDO adminUserDO = userMapper.selectByIdForUpdate(id); AdminUserDO user = userMapper.selectByIdForUpdate(id);
// 当手机号(账号)发生改变时,只允许密码为空的通过(还没有使用验证码来设置过密码) if (ObjectUtil.isNull(user)) {
if (ObjectUtil.isNotNull(adminUserDO) && !StringUtils.equals(adminUserDO.getUsername(), mobile)) { return;
if(StringUtils.isNotEmpty(adminUserDO.getPassword())) {
throw new ServiceException(USER_MOBILE_UPDATE_NOT_ALLOW_ERROR);
} else {
updateObj.setUsername(mobile);
}
} }
String mobileChange = null;
String nicknameChange = null;
// 手机号变更
if (!StringUtils.equals(user.getUsername(), mobile)) {
if (StringUtils.isNotEmpty(user.getPassword())) {
throw new ServiceException(USER_MOBILE_UPDATE_NOT_ALLOW_ERROR);
}
updateObj.setUsername(mobile);
mobileChange = mobile;
}
// 昵称变更
if (!StringUtils.equals(user.getNickname(), nickname)) {
nicknameChange = nickname;
}
// 同步组织的管理员信息
syncUserToOrgAdmin(userId, currUserDO.getOrganId(), mobileChange, nicknameChange);
} }
userMapper.updateById(updateObj); userMapper.updateById(updateObj);
// // 更新岗位
// updateUserPost(updateReqVO, updateObj);
// 如果改变了部门或修改状态为禁用移除用户token // 如果改变了部门或修改状态为禁用移除用户token
if (ObjectUtil.notEqual(currUserDO.getDeptId(), updateReqVO.getDeptId()) || CommonStatusEnum.DISABLE.getStatus().equals(updateReqVO.getStatus())) { if (ObjectUtil.notEqual(currUserDO.getDeptId(), updateReqVO.getDeptId()) || CommonStatusEnum.DISABLE.getStatus().equals(updateReqVO.getStatus())) {
scanAndCompareUserAndDelToken(String.format(OAUTH2_ACCESS_TOKEN, "*"), userId); scanAndCompareUserAndDelToken(String.format(OAUTH2_ACCESS_TOKEN, "*"), userId);
@@ -498,10 +511,10 @@ public class AdminUserServiceImpl implements AdminUserService {
ids.forEach(id -> { ids.forEach(id -> {
AdminUserDO user = userMap.get(id); AdminUserDO user = userMap.get(id);
if (user == null) { if (user == null) {
throw new ServiceException(ErrorCodeConstants.USER_NOT_EXISTS); throw new ServiceException(USER_NOT_EXISTS);
} }
if (!CommonStatusEnum.ENABLE.getStatus().equals(user.getStatus())) { if (!CommonStatusEnum.ENABLE.getStatus().equals(user.getStatus())) {
throw new ServiceException(ErrorCodeConstants.USER_IS_DISABLE, user.getNickname()); throw new ServiceException(USER_IS_DISABLE, user.getNickname());
} }
}); });
} }
@@ -526,7 +539,7 @@ public class AdminUserServiceImpl implements AdminUserService {
return deptIds; return deptIds;
} }
private AdminUserDO validateUserForCreateOrUpdate(Long id, String username, Long deptId, String password, Long organId) { private AdminUserDO validateUserForCreateOrUpdate(Long id, String username, Long deptId, String password) {
// 校验用户的密码是否符合规则 // 校验用户的密码是否符合规则
if (password != null) { if (password != null) {
validatePassword(password); validatePassword(password);
@@ -534,7 +547,7 @@ public class AdminUserServiceImpl implements AdminUserService {
// 校验用户存在 // 校验用户存在
AdminUserDO adminUserDO = validateUserExists(id); AdminUserDO adminUserDO = validateUserExists(id);
// 校验用户名唯一 // 校验用户名唯一
getSelf().validateUsernameUnique(id, username, organId); getSelf().validateUsernameUnique(id, username);
// 组织管理员不归属部门 // 组织管理员不归属部门
if (ObjectUtil.isNotNull(deptId)) { if (ObjectUtil.isNotNull(deptId)) {
// 校验部门处于开启状态 // 校验部门处于开启状态
@@ -548,27 +561,27 @@ public class AdminUserServiceImpl implements AdminUserService {
// 检查密码长度 // 检查密码长度
if (!Pattern.matches(LENGTH_PATTERN, password)) { if (!Pattern.matches(LENGTH_PATTERN, password)) {
throw new ServiceException(ErrorCodeConstants.THE_PASSWORD_LENGTH_MUST_BE_AT_LEAST_8_CHARACTERS); throw new ServiceException(THE_PASSWORD_LENGTH_MUST_BE_AT_LEAST_8_CHARACTERS);
} }
// 检查是否包含大写字母 // 检查是否包含大写字母
if (!Pattern.matches(UPPER_LETTER_PATTERN, password)) { if (!Pattern.matches(UPPER_LETTER_PATTERN, password)) {
throw new ServiceException(ErrorCodeConstants.THE_PASSWORD_LENGTH_MUST_BE_AT_LEAST_8_CHARACTERS); throw new ServiceException(THE_PASSWORD_LENGTH_MUST_BE_AT_LEAST_8_CHARACTERS);
} }
// 检查是否包含小写字母 // 检查是否包含小写字母
if (!Pattern.matches(LOWER_LETTER_PATTERN, password)) { if (!Pattern.matches(LOWER_LETTER_PATTERN, password)) {
throw new ServiceException(ErrorCodeConstants.THE_PASSWORD_LENGTH_MUST_BE_AT_LEAST_8_CHARACTERS); throw new ServiceException(THE_PASSWORD_LENGTH_MUST_BE_AT_LEAST_8_CHARACTERS);
} }
// 检查是否包含数字 // 检查是否包含数字
if (!Pattern.matches(DIGIT_PATTERN, password)) { if (!Pattern.matches(DIGIT_PATTERN, password)) {
throw new ServiceException(ErrorCodeConstants.THE_PASSWORD_LENGTH_MUST_BE_AT_LEAST_8_CHARACTERS); throw new ServiceException(THE_PASSWORD_LENGTH_MUST_BE_AT_LEAST_8_CHARACTERS);
} }
// 检查是否包含特殊字符 // 检查是否包含特殊字符
if (!Pattern.matches(SPECIAL_CHARACTER_PATTERN, password)) { if (!Pattern.matches(SPECIAL_CHARACTER_PATTERN, password)) {
throw new ServiceException(ErrorCodeConstants.THE_PASSWORD_LENGTH_MUST_BE_AT_LEAST_8_CHARACTERS); throw new ServiceException(THE_PASSWORD_LENGTH_MUST_BE_AT_LEAST_8_CHARACTERS);
} }
// 检查是否只包含字母、数字和特殊字符 // 检查是否只包含字母、数字和特殊字符
if (!Pattern.matches(VALID_CHAR_PATTERN, password)) { if (!Pattern.matches(VALID_CHAR_PATTERN, password)) {
throw new ServiceException(ErrorCodeConstants.THE_PASSWORD_LENGTH_MUST_BE_AT_LEAST_8_CHARACTERS); throw new ServiceException(THE_PASSWORD_LENGTH_MUST_BE_AT_LEAST_8_CHARACTERS);
} }
} }
@@ -580,7 +593,7 @@ public class AdminUserServiceImpl implements AdminUserService {
} }
AdminUserDO user = userMapper.selectById(id); AdminUserDO user = userMapper.selectById(id);
if (user == null) { if (user == null) {
throw new ServiceException(ErrorCodeConstants.USER_NOT_EXISTS); throw new ServiceException(USER_NOT_EXISTS);
} }
return user; return user;
} }
@@ -589,14 +602,14 @@ public class AdminUserServiceImpl implements AdminUserService {
private AdminUserDO validateUserNameExists(String userName) { private AdminUserDO validateUserNameExists(String userName) {
AdminUserDO user = userMapper.selectByUsernameUnique(userName); AdminUserDO user = userMapper.selectByUsernameUnique(userName);
if (user == null) { if (user == null) {
throw new ServiceException(ErrorCodeConstants.USER_NOT_EXISTS); throw new ServiceException(USER_NOT_EXISTS);
} }
return user; return user;
} }
@VisibleForTesting @VisibleForTesting
@OrganIgnore @OrganIgnore
void validateUsernameUnique(Long id, String username, Long organId) { void validateUsernameUnique(Long id, String username) {
if (StringUtils.isBlank(username)) { if (StringUtils.isBlank(username)) {
return; return;
} }
@@ -606,10 +619,10 @@ public class AdminUserServiceImpl implements AdminUserService {
} }
// 如果 id 为空,说明不用比较是否为相同 id 的用户 // 如果 id 为空,说明不用比较是否为相同 id 的用户
if (id == null) { if (id == null) {
throw new ServiceException(ErrorCodeConstants.USER_USERNAME_EXISTS); throw new ServiceException(USER_USERNAME_EXISTS);
} }
if (!user.getId().equals(id)) { if (!user.getId().equals(id)) {
throw new ServiceException(ErrorCodeConstants.USER_USERNAME_EXISTS); throw new ServiceException(USER_USERNAME_EXISTS);
} }
} }
@@ -624,10 +637,10 @@ public class AdminUserServiceImpl implements AdminUserService {
} }
// 如果 id 为空,说明不用比较是否为相同 id 的用户 // 如果 id 为空,说明不用比较是否为相同 id 的用户
if (id == null) { if (id == null) {
throw new ServiceException(ErrorCodeConstants.USER_EMAIL_EXISTS); throw new ServiceException(USER_EMAIL_EXISTS);
} }
if (!user.getId().equals(id)) { if (!user.getId().equals(id)) {
throw new ServiceException(ErrorCodeConstants.USER_EMAIL_EXISTS); throw new ServiceException(USER_EMAIL_EXISTS);
} }
} }
@@ -640,10 +653,10 @@ public class AdminUserServiceImpl implements AdminUserService {
} }
// 如果 id 为空,说明不用比较是否为相同 id 的用户 // 如果 id 为空,说明不用比较是否为相同 id 的用户
if (id == null) { if (id == null) {
throw new ServiceException(ErrorCodeConstants.USER_MOBILE_EXISTS); throw new ServiceException(USER_MOBILE_EXISTS);
} }
if (!user.getId().equals(id)) { if (!user.getId().equals(id)) {
throw new ServiceException(ErrorCodeConstants.USER_MOBILE_EXISTS); throw new ServiceException(USER_MOBILE_EXISTS);
} }
return user; return user;
} }
@@ -658,10 +671,10 @@ public class AdminUserServiceImpl implements AdminUserService {
void validateOldPassword(Long id, String oldPassword) { void validateOldPassword(Long id, String oldPassword) {
AdminUserDO user = userMapper.selectById(id); AdminUserDO user = userMapper.selectById(id);
if (user == null) { if (user == null) {
throw new ServiceException(ErrorCodeConstants.USER_NOT_EXISTS); throw new ServiceException(USER_NOT_EXISTS);
} }
if (!isPasswordMatch(oldPassword, user.getPassword())) { if (!isPasswordMatch(oldPassword, user.getPassword())) {
throw new ServiceException(ErrorCodeConstants.USER_PASSWORD_FAILED); throw new ServiceException(USER_PASSWORD_FAILED);
} }
} }
@@ -669,14 +682,14 @@ public class AdminUserServiceImpl implements AdminUserService {
@Transactional(rollbackFor = Exception.class) // 添加事务,异常则回滚所有导入 @Transactional(rollbackFor = Exception.class) // 添加事务,异常则回滚所有导入
public UserImportRespVO importUserList(List<UserImportExcelVO> importUsers, boolean isUpdateSupport, Long organId) { public UserImportRespVO importUserList(List<UserImportExcelVO> importUsers, boolean isUpdateSupport, Long organId) {
if (CollUtil.isEmpty(importUsers)) { if (CollUtil.isEmpty(importUsers)) {
throw new ServiceException(ErrorCodeConstants.USER_IMPORT_LIST_IS_EMPTY); throw new ServiceException(USER_IMPORT_LIST_IS_EMPTY);
} }
UserImportRespVO respVO = UserImportRespVO.builder().createUsernames(new ArrayList<>()) UserImportRespVO respVO = UserImportRespVO.builder().createUsernames(new ArrayList<>())
.updateUsernames(new ArrayList<>()).failureUsernames(new LinkedHashMap<>()).build(); .updateUsernames(new ArrayList<>()).failureUsernames(new LinkedHashMap<>()).build();
importUsers.forEach(importUser -> { importUsers.forEach(importUser -> {
// 校验,判断是否有不符合的原因 // 校验,判断是否有不符合的原因
try { try {
validateUserForCreateOrUpdate(null, null, importUser.getDeptId(), null, organId); validateUserForCreateOrUpdate(null, null, importUser.getDeptId(), null);
} catch (ServiceException ex) { } catch (ServiceException ex) {
respVO.getFailureUsernames().put(importUser.getUsername(), ex.getMessage()); respVO.getFailureUsernames().put(importUser.getUsername(), ex.getMessage());
return; return;
@@ -693,7 +706,7 @@ public class AdminUserServiceImpl implements AdminUserService {
} }
// 如果存在,判断是否允许更新 // 如果存在,判断是否允许更新
if (!isUpdateSupport) { if (!isUpdateSupport) {
respVO.getFailureUsernames().put(importUser.getUsername(), ErrorCodeConstants.USER_USERNAME_EXISTS.getMsg()); respVO.getFailureUsernames().put(importUser.getUsername(), USER_USERNAME_EXISTS.getMsg());
return; return;
} }
AdminUserDO updateUser = BeanUtils.toBean(importUser, AdminUserDO.class); AdminUserDO updateUser = BeanUtils.toBean(importUser, AdminUserDO.class);
@@ -747,9 +760,12 @@ public class AdminUserServiceImpl implements AdminUserService {
AdminUserDO adminUserDO = validateMobileUnique(id, mobile); AdminUserDO adminUserDO = validateMobileUnique(id, mobile);
// 手机号没有改变无需请求 // 手机号没有改变无需请求
if (ObjectUtil.isNotNull(adminUserDO) && ObjectUtil.equal(id, adminUserDO.getId())) { if (ObjectUtil.isNotNull(adminUserDO) && ObjectUtil.equal(id, adminUserDO.getId())) {
throw new ServiceException(ErrorCodeConstants.AUTH_MOBILE_NO_CHANGE); throw new ServiceException(AUTH_MOBILE_NO_CHANGE);
} }
// 同步新手机到组织的管理员信息
syncUserToOrgAdmin(id, adminUserDO.getOrganId(), mobile, null);
// 新手机号入库 -> setUsername // 新手机号入库 -> setUsername
userMapper.update(new LambdaUpdateWrapper<AdminUserDO>() userMapper.update(new LambdaUpdateWrapper<AdminUserDO>()
.set(AdminUserDO::getUsername, mobile) .set(AdminUserDO::getUsername, mobile)
@@ -893,4 +909,56 @@ public class AdminUserServiceImpl implements AdminUserService {
return resultMap; return resultMap;
} }
@Override
public void syncOrgAdminToUser(Long userId, String contactMobile, String contactName) {
if (StringUtils.isAllEmpty(contactMobile, contactName)) {
return;
}
// 获取管理员账户
AdminUserDO adminUserDO = userMapper.selectById(userId);
if (adminUserDO == null) {
throw new ServiceException(USER_NOT_EXISTS);
}
// 校验账号(手机号)重复
AdminUserDO userByName = userMapper.selectOne(AdminUserDO::getUsername, contactMobile);
if (ObjectUtil.isNotNull(userByName) && ObjectUtil.notEqual(userId, userByName.getId())) {
throw new ServiceException(USER_USERNAME_EXISTS);
}
// 同步账号(手机号)和昵称
userMapper.update(new LambdaUpdateWrapperX<AdminUserDO>()
.setIfPresent(AdminUserDO::getUsername, contactMobile)
.setIfPresent(AdminUserDO::getMobile, contactMobile)
.setIfPresent(AdminUserDO::getNickname, contactName)
.eq(AdminUserDO::getId, userId)
);
}
/**
* 更新用户账户(手机号)、昵称到组织管理员信息
*
* @param userId
* @param organId
* @param contactMobile
* @param contactName
*/
private void syncUserToOrgAdmin(Long userId, Long organId, String contactMobile, String contactName) {
// 任一发生变化才更新
if(StringUtils.isAllEmpty(contactMobile, contactName)) {
return;
}
// 查询组织
OrganizationDO organ = organService.getOrgan(organId);
if (ObjectUtil.notEqual(organ.getContactUserId(), userId)) {
// 不是组织管理员,不作操作
return;
}
// 同步到组织
organService.syncUserToOrgAdmin(organ.getId(), contactMobile, contactName);
}
} }
@@ -502,7 +502,7 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest {
userMapper.insert(randomAdminUserDO(o -> o.setUsername(username))); userMapper.insert(randomAdminUserDO(o -> o.setUsername(username)));
// 调用,校验异常 // 调用,校验异常
assertServiceException(() -> userService.validateUsernameUnique(null, username, null), assertServiceException(() -> userService.validateUsernameUnique(null, username),
USER_USERNAME_EXISTS); USER_USERNAME_EXISTS);
} }
@@ -515,7 +515,7 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest {
userMapper.insert(randomAdminUserDO(o -> o.setUsername(username))); userMapper.insert(randomAdminUserDO(o -> o.setUsername(username)));
// 调用,校验异常 // 调用,校验异常
assertServiceException(() -> userService.validateUsernameUnique(id, username, null), assertServiceException(() -> userService.validateUsernameUnique(id, username),
USER_USERNAME_EXISTS); USER_USERNAME_EXISTS);
} }