Compare commits

...

2 Commits

Author SHA1 Message Date
xiaocp2009
f5339d6237 Merge remote-tracking branch 'origin/main' into main 2025-08-15 11:01:41 +08:00
xiaocp2009
5ae10027cd 1、用户注册V1
2、修复营销编号校验bug
3、其他优化
2025-08-15 11:00:00 +08:00
21 changed files with 327 additions and 31 deletions

View File

@ -1,5 +1,11 @@
export const REG_USER_NAME = /^[\u4E00-\u9FA5a-zA-Z0-9_-]{4,16}$/;
export const REG_NICK_NAME = /^[\u4e00-\u9fa5]{2,8}$/;
export const ID_CARD_NO = /^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/;
export const MKT_NO = /[A-Za-z0-9]{6}/;
/** Phone reg */
export const REG_PHONE =
/^[1](([3][0-9])|([4][01456789])|([5][012356789])|([6][2567])|([7][0-8])|([8][0-9])|([9][012356789]))[0-9]{8}$/;

View File

@ -1,7 +1,7 @@
import { ref, toValue } from 'vue';
import type { ComputedRef, Ref } from 'vue';
import type { FormInst } from 'naive-ui';
import { REG_CODE_SIX, REG_EMAIL, REG_PHONE, REG_PWD, REG_USER_NAME } from '@/constants/reg';
import {ID_CARD_NO, MKT_NO, REG_CODE_SIX, REG_EMAIL, REG_NICK_NAME, REG_PHONE, REG_PWD, REG_USER_NAME} from '@/constants/reg';
import { $t } from '@/locales';
export function useFormRules() {
@ -11,6 +11,21 @@ export function useFormRules() {
message: $t('form.userName.invalid'),
trigger: ['change', 'blur']
},
nickName: {
pattern: REG_NICK_NAME,
message: $t('form.nickName.invalid'),
trigger: ['change', 'blur']
},
idCard: {
pattern: ID_CARD_NO,
message: $t('form.idCard.invalid'),
trigger: ['change', 'blur']
},
mktNo: {
pattern: MKT_NO,
message: $t('form.mktNo.invalid'),
trigger: ['change', 'blur']
},
phone: {
pattern: REG_PHONE,
message: $t('form.phone.invalid'),
@ -35,6 +50,9 @@ export function useFormRules() {
const formRules = {
userName: [createRequiredRule($t('form.userName.required')), patternRules.userName],
nickName: [createRequiredRule($t('form.nickName.required')), patternRules.nickName],
idCard: [createRequiredRule($t('form.idCard.required')), patternRules.idCard],
mktNo: [createRequiredRule($t('form.mktNo.required')), patternRules.mktNo],
phone: [createRequiredRule($t('form.phone.required')), patternRules.phone],
pwd: [createRequiredRule($t('form.pwd.required')), patternRules.pwd],
code: [createRequiredRule($t('form.code.required')), patternRules.code],

View File

@ -1174,9 +1174,21 @@ const local: App.I18n.Schema = {
form: {
required: 'Cannot be empty',
userName: {
required: 'Please enter login name',
invalid: 'Login name format is incorrect'
},
nickName: {
required: 'Please enter user name',
invalid: 'User name format is incorrect'
},
idCard: {
required: 'Please enter id card no',
invalid: 'Id card no format is incorrect'
},
mktNo: {
required: 'Please enter mkt no',
invalid: 'Mkt no format is incorrect'
},
phone: {
required: 'Please enter phone number',
invalid: 'Phone number format is incorrect'

View File

@ -340,7 +340,7 @@ const local: App.I18n.Schema = {
common: {
loginOrRegister: '登录 / 注册',
register: '注册',
userNamePlaceholder: '请输入用户名',
userNamePlaceholder: '请输入登录用户名',
phonePlaceholder: '请输入手机号',
codePlaceholder: '请输入验证码',
passwordPlaceholder: '请输入密码',
@ -1182,8 +1182,20 @@ const local: App.I18n.Schema = {
form: {
required: '不能为空',
userName: {
required: '请输入用户名',
invalid: '用户名格式不正确'
required: '请输入登录名',
invalid: '登录名格式不正确'
},
nickName: {
required: '请输入姓名',
invalid: '姓名必须为2-8位中文'
},
idCard: {
required: '请输入身份证号码',
invalid: '身份证号码格式不正确'
},
mktNo: {
required: '请输入营销编号',
invalid: '营销编号格式不正确'
},
phone: {
required: '请输入手机号',

View File

@ -83,6 +83,17 @@ export function fetchGetDeptTree() {
});
}
/** 获取部门树列表 */
export function fetchGetRegDeptTree(tenantId: string) {
return request<Api.Common.CommonTreeRecord>({
url: '/system/user/regDeptTree',
method: 'get',
params: {
tenantId
}
});
}
/** 重置用户密码 */
export function fetchResetUserPassword(userId: CommonType.IdType, password: string) {
return request<boolean>({

View File

@ -126,7 +126,7 @@ declare namespace Api {
/** register form */
interface RegisterForm extends LoginForm {
/** 用户名 */
/** 登录名 */
username?: string;
/** 密码 */
password?: string;
@ -134,6 +134,17 @@ declare namespace Api {
confirmPassword?: string;
/** 用户类型 */
userType?: string;
/** 姓名 */
nickName: '',
/** 身份证号 */
idCard: '',
/*用户种类(0-营销 1-其他)*/
userCategory: '1',//注意跟字典保持一致
/** 营销编号 */
mktNo: '',
/** 部门编号 */
deptId: null,
}
/** login token data */

View File

@ -179,12 +179,12 @@ async function handleSocialLogin(type: Api.System.SocialSource) {
</NSpace>
</NForm>
<NDivider>
<!-- <div class="color-#858585">{{ $t('page.login.pwdLogin.otherAccountLogin') }}</div>-->
<!-- <NDivider>
&lt;!&ndash; <div class="color-#858585">{{ $t('page.login.pwdLogin.otherAccountLogin') }}</div>&ndash;&gt;
评估是否增加注册功能
</NDivider>
</NDivider>-->
<!-- <div class="w-full flex-y-center gap-16px">
<NButton class="flex-1" @click="handleSocialLogin('gitee')">
@ -201,12 +201,12 @@ async function handleSocialLogin(type: Api.System.SocialSource) {
</NButton>
</div>-->
<!-- <div class="mt-32px w-full text-center text-18px text-#858585">
<div class="mt-32px w-full text-center text-18px text-#858585">
您还没有账户
<NA type="primary" class="text-18px" @click="toggleLoginModule('register')">
{{ $t('page.login.common.register') }}
</NA>
</div>-->
</div>
</div>
</template>

View File

@ -6,6 +6,8 @@ import { fetchCaptchaCode, fetchRegister, fetchTenantList } from '@/service/api'
import { useRouterPush } from '@/hooks/common/router';
import { useFormRules, useNaiveForm } from '@/hooks/common/form';
import { $t } from '@/locales';
import { fetchGetRegDeptTree} from "@/service/api/system";
import {useDict} from "@/hooks/business/dict";
defineOptions({
name: 'Register'
@ -15,19 +17,29 @@ const { toggleLoginModule } = useRouterPush();
const { formRef, validate } = useNaiveForm();
const { loading: codeLoading, startLoading: startCodeLoading, endLoading: endCodeLoading } = useLoading();
const { loading: registerLoading, startLoading: startRegisterLoading, endLoading: endRegisterLoading } = useLoading();
const { loading: deptLoading, startLoading: startDeptLoading, endLoading: endDeptLoading } = useLoading();
const { loading: treeLoading, startLoading: startTreeLoading, endLoading: endTreeLoading } = useLoading();
const codeUrl = ref<string>();
const captchaEnabled = ref<boolean>(false);
const tenantEnabled = ref<boolean>(false);
const tenantOption = ref<SelectOption[]>([]);
const deptData = ref<Api.Common.CommonTreeRecord>([]);
const {options: mpsUserCategory} = useDict('mps_user_category');
const model: Api.Auth.RegisterForm = reactive({
tenantId: '000000',
/*tenantId: '000000',*/
tenantId: '069291',//
username: '',
nickName: '',
idCard: '',
userCategory: '1',//
mktNo: '',
code: '',
password: '',
confirmPassword: '',
userType: 'sys_user'
userType: 'sys_user',
deptId: null,
});
type RuleKey = Extract<keyof Api.Auth.RegisterForm, 'username' | 'password' | 'confirmPassword' | 'code' | 'tenantId'>;
@ -38,12 +50,26 @@ const rules = computed<Record<RuleKey, App.Global.FormRule[]>>(() => {
return {
tenantId: tenantEnabled.value ? formRules.tenantId : [],
username: [...formRules.userName, { required: true }],
nickName: [...formRules.nickName, { required: true }],
idCard: [...formRules.idCard, { required: true }],
mktNo: [...formRules.mktNo, { required: true }],
password: [...formRules.pwd, { required: true }],
confirmPassword: createConfirmPwdRule(model.password!),
code: captchaEnabled.value ? [createRequiredRule($t('form.code.required'))] : []
};
});
async function getTreeData() {
startTreeLoading();
const { data: tree, error } = await fetchGetRegDeptTree(model.tenantId);
if (!error) {
deptData.value = tree;
}
endTreeLoading();
}
getTreeData();
async function handleSubmit() {
try {
await validate();
@ -56,7 +82,18 @@ async function handleSubmit() {
uuid: model.uuid,
grantType: 'password',
userType: model.userType,
clientId: import.meta.env.VITE_APP_CLIENT_ID
clientId: import.meta.env.VITE_APP_CLIENT_ID,
/** 姓名 */
nickName: model.nickName,
/** 身份证号 */
idCard: model.idCard,
/*用户种类(0-营销 1-其他)*/
userCategory: model.userCategory,//
/** 营销编号 */
mktNo: model.mktNo,
/** 部门编号 */
deptId: model.deptId,
});
if (error) {
handleFetchCaptchaCode();
@ -111,16 +148,60 @@ handleFetchCaptchaCode();
:model="model"
:rules="rules"
size="large"
:show-label="false"
:show-label="true"
label-placement="left"
:label-width="100"
@keyup.enter="() => !registerLoading && handleSubmit()"
>
<NFormItem v-if="tenantEnabled" path="tenantId">
<!-- 法人部门 -->
<NFormItem label="所属法人" v-if="tenantEnabled" path="tenantId">
<NSelect v-model:value="model.tenantId" :options="tenantOption" :enabled="tenantEnabled" />
</NFormItem>
<NFormItem path="username">
<NFormItem required :label="$t('page.system.user.deptName')" path="deptId">
<NTreeSelect
v-model:value="model.deptId"
:loading="deptLoading"
clearable
:options="deptData as []"
label-field="label"
key-field="id"
:default-expanded-keys="deptData?.length ? [deptData[0].id] : []"
:placeholder="$t('page.system.user.form.deptId.required')"
:default-value="deptData?.length ? [deptData[0].id] : null"
/>
</NFormItem>
<!-- 营销 -->
<NFormItem required label="用户类别" path="userCategory">
<NSelect
v-model:value="model.userCategory"
placeholder="请选择用户类别"
:options="mpsUserCategory"
filterable
/>
</NFormItem>
<NFormItem v-if="model.userCategory === '0'" label="营销编号" path="mktNo" required>
<NInput v-model:value="model.mktNo" :placeholder="$t('page.system.user.form.mktNo.required')" />
</NFormItem>
<!-- 真实用户信息 -->
<NFormItem required label="姓名" path="nickName">
<NInput v-model:value="model.nickName" :placeholder="$t('form.nickName.required')" />
</NFormItem>
<NFormItem required label="身份证号" path="idCard">
<NInput v-model:value="model.idCard" :placeholder="$t('form.idCard.required')" />
</NFormItem>
<!-- 登录用户信息 -->
<NFormItem required label="登录名" path="username">
<NInput v-model:value="model.username" :placeholder="$t('page.login.common.userNamePlaceholder')" />
</NFormItem>
<NFormItem path="password">
<NFormItem required label="登陆密码" path="password">
<NInput
v-model:value="model.password"
type="password"
@ -128,7 +209,7 @@ handleFetchCaptchaCode();
:placeholder="$t('page.login.common.passwordPlaceholder')"
/>
</NFormItem>
<NFormItem path="confirmPassword">
<NFormItem required label="登录密码" path="confirmPassword">
<NInput
v-model:value="model.confirmPassword"
type="password"
@ -136,7 +217,7 @@ handleFetchCaptchaCode();
:placeholder="$t('page.login.common.confirmPasswordPlaceholder')"
/>
</NFormItem>
<NFormItem v-if="captchaEnabled" path="code">
<NFormItem required label="验证码" v-if="captchaEnabled" path="code">
<div class="w-full flex-y-center gap-16px">
<NInput v-model:value="model.code" :placeholder="$t('page.login.common.codePlaceholder')" />
<NSpin :show="codeLoading" :size="28" class="h-52px">

View File

@ -29,12 +29,10 @@ import org.dromara.common.sse.dto.SseMessageDto;
import org.dromara.common.sse.utils.SseMessageUtils;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.system.domain.bo.SysTenantBo;
import org.dromara.system.domain.bo.SysUserBo;
import org.dromara.system.domain.vo.SysClientVo;
import org.dromara.system.domain.vo.SysTenantVo;
import org.dromara.system.service.ISysClientService;
import org.dromara.system.service.ISysConfigService;
import org.dromara.system.service.ISysSocialService;
import org.dromara.system.service.ISysTenantService;
import org.dromara.system.service.*;
import org.dromara.web.domain.vo.LoginTenantVo;
import org.dromara.web.domain.vo.LoginVo;
import org.dromara.web.domain.vo.TenantListVo;
@ -72,6 +70,7 @@ public class AuthController {
private final ISysSocialService socialUserService;
private final ISysClientService clientService;
private final ScheduledExecutorService scheduledExecutorService;
private final ISysUserService userService;
/**
@ -189,6 +188,28 @@ public class AuthController {
if (!configService.selectRegisterEnabled(user.getTenantId())) {
return R.fail("当前系统没有开启注册功能!");
}
if(user.getUserCategory().equals("0")){//注意与字典保持一致
if(StringUtils.isBlank(user.getMktNo())){
return R.fail("营销人员营销编号不能为空");
}
if(user.getMktNo().length() != 9){
return R.fail("营销编号错误");
}
}
SysUserBo sysUser = new SysUserBo();
sysUser.setUserName(user.getUsername());
sysUser.setIdCard(user.getIdCard());
sysUser.setMktNo(user.getMktNo());
if (!userService.checkUserNameUnique(sysUser)) {
return R.fail("注册用户'" + user.getUsername() + "'失败,登录账号已存在");
}else if (StringUtils.isNotEmpty(user.getIdCard()) && !userService.checkIdCardUnique(sysUser)) {
return R.fail("注册用户'" + user.getUsername() + "'失败,身份证号已存在");
}else if (StringUtils.isNotEmpty(user.getMktNo()) && !userService.checkMktNoUnique(sysUser)) {
return R.fail("注册用户'" + user.getUsername() + "'失败,营销编号已存在");
}
registerService.register(user);
return R.ok();
}

View File

@ -54,10 +54,16 @@ public class SysRegisterService {
}
SysUserBo sysUser = new SysUserBo();
sysUser.setUserName(username);
sysUser.setNickName(username);
sysUser.setNickName(registerBody.getNickName());
sysUser.setPassword(BCrypt.hashpw(password));
sysUser.setUserType(userType);
sysUser.setMktNo(registerBody.getMktNo());
sysUser.setDeptId(registerBody.getDeptId());//TODO 部分树按业务需求精简即可,目前是查询出所有供用户选择
sysUser.setIdCard(registerBody.getIdCard());
sysUser.setUserCategory(registerBody.getUserCategory());
sysUser.setRoleIds(new Long[]{1942042655333339137L});//TODO 需要确定注册用户的角色,角色只能固定不能用用户自己选择
boolean exist = TenantHelper.dynamic(tenantId, () -> {
return userMapper.exists(new LambdaQueryWrapper<SysUser>()
.eq(SysUser::getUserName, sysUser.getUserName()));

View File

@ -111,6 +111,7 @@ sa-token:
# security配置
security:
# 排除路径
# 开启注册,需要放开部分字典授权
excludes:
- /*.html
- /**/*.html
@ -121,6 +122,8 @@ security:
- /*/api-docs
- /*/api-docs/**
- /warm-flow-ui/config
- /system/dict/data/type/mps_user_category
- /system/user/regDeptTree
# 多租户配置
tenant:

View File

@ -1,8 +1,10 @@
package org.dromara.common.core.domain.model;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.core.xss.Xss;
import org.hibernate.validator.constraints.Length;
/**
@ -15,9 +17,10 @@ import org.hibernate.validator.constraints.Length;
public class RegisterBody extends LoginBody {
/**
* 用户
* 登录
*/
@NotBlank(message = "{user.username.not.blank}")
@Xss(message = "用户账号不能包含脚本字符")
@Length(min = 2, max = 30, message = "{user.username.length.valid}")
private String username;
@ -30,4 +33,21 @@ public class RegisterBody extends LoginBody {
private String userType;
/**
* 姓名
*/
@Xss(message = "用户姓名不能包含脚本字符")
@NotBlank(message = "用户姓名不能为空")
private String nickName;
@NotBlank(message = "身份证号不允许为空")
private String idCard;
private String mktNo;
private Long deptId;
@NotBlank(message = "用户类别不允许为空")
private String userCategory;
}

View File

@ -180,6 +180,15 @@ public class SysUserController extends BaseController {
return R.fail("新增用户'" + user.getUserName() + "'失败,营销编号已存在");
}
if(user.getUserCategory().equals("0")){//注意与字典保持一致
if(StringUtils.isBlank(user.getMktNo())){
return R.fail("营销人员营销编号不能为空");
}
if(user.getMktNo().length() != 6){
return R.fail("营销编号错误");
}
}
// 不再校验手机号和邮箱
/*else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
return R.fail("修改用户'" + user.getUserName() + "'失败,手机号码已存在");
@ -207,6 +216,7 @@ public class SysUserController extends BaseController {
userService.checkUserAllowed(user.getUserId());
userService.checkUserDataScope(user.getUserId());
deptService.checkDeptDataScope(user.getDeptId());
if (!userService.checkUserNameUnique(user)) {
return R.fail("修改用户'" + user.getUserName() + "'失败,登录账号已存在");
}
@ -216,6 +226,15 @@ public class SysUserController extends BaseController {
return R.fail("修改用户'" + user.getUserName() + "'失败,营销编号已存在");
}
if(user.getUserCategory().equals("0")){//注意与字典保持一致
if(StringUtils.isBlank(user.getMktNo())){
return R.fail("营销人员营销编号不能为空");
}
if(user.getMktNo().length() != 9){
return R.fail("营销编号错误");
}
}
// 不再校验手机号和邮箱
/*else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
return R.fail("修改用户'" + user.getUserName() + "'失败,手机号码已存在");
@ -320,6 +339,18 @@ public class SysUserController extends BaseController {
return R.ok(deptService.selectDeptTreeList(dept));
}
/**
* 注册时获取部门树列表
*
* 之所以单独抽出来是为了区分权限及数据范围@PathVariable("source") String source
* 需求确定后,可以通过bo添加过滤条件,暂时还是查询全部
*/
@GetMapping("/regDeptTree")
public R<List<Tree<Long>>> regDeptTree(String tenantId) {
System.out.println(tenantId);
return R.ok(deptService.selectRegDeptTreeList(tenantId));
}
/**
* 获取部门下的所有用户信息
*/

View File

@ -78,4 +78,6 @@ public class SysDeptBo extends BaseEntity {
*/
private Long belongDeptId;
private String tenantId;
}

View File

@ -64,8 +64,6 @@ public class SysUserBo extends BaseEntity {
/**
* 营销编号
*/
@NotBlank(message = "营销编号不能为空")
@Size(min = 9, max = 9, message = "营销编号长度必须为9位")
private String mktNo;
/**

View File

@ -33,6 +33,10 @@ public interface SysDeptMapper extends BaseMapperPlus<SysDept, SysDeptVo> {
return this.selectVoList(queryWrapper);
}
default List<SysDeptVo> selectRegDeptList(Wrapper<SysDept> queryWrapper) {
return this.selectVoList(queryWrapper);
}
/**
* 分页查询部门管理数据
*

View File

@ -44,6 +44,8 @@ public interface SysRoleMapper extends BaseMapperPlus<SysRole, SysRoleVo> {
})
List<SysRoleVo> selectRoleList(@Param(Constants.WRAPPER) Wrapper<SysRole> queryWrapper);
List<SysRoleVo> selectRegRoleList(@Param(Constants.WRAPPER) Wrapper<SysRole> queryWrapper);
/**
* 根据角色ID查询角色信息
*

View File

@ -40,6 +40,8 @@ public interface ISysDeptService {
*/
List<Tree<Long>> selectDeptTreeList(SysDeptBo dept);
List<Tree<Long>> selectRegDeptTreeList(String tenantId);
/**
* 构建前端所需要下拉树结构
*

View File

@ -92,12 +92,21 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService {
return buildDeptTreeSelect(depts);
}
public List<Tree<Long>> selectRegDeptTreeList(String tenantId) {
SysDeptBo bo = new SysDeptBo();
bo.setTenantId(tenantId);
LambdaQueryWrapper<SysDept> lqw = buildQueryWrapper(bo);
List<SysDeptVo> depts = baseMapper.selectRegDeptList(lqw);
return buildDeptTreeSelect(depts);
}
private LambdaQueryWrapper<SysDept> buildQueryWrapper(SysDeptBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<SysDept> lqw = Wrappers.lambdaQuery();
lqw.eq(SysDept::getDelFlag, SystemConstants.NORMAL);
lqw.eq(ObjectUtil.isNotNull(bo.getDeptId()), SysDept::getDeptId, bo.getDeptId());
lqw.eq(ObjectUtil.isNotNull(bo.getParentId()), SysDept::getParentId, bo.getParentId());
lqw.eq(ObjectUtil.isNotNull(bo.getTenantId()), SysDept::getTenantId, bo.getTenantId());
lqw.like(StringUtils.isNotBlank(bo.getDeptName()), SysDept::getDeptName, bo.getDeptName());
lqw.like(StringUtils.isNotBlank(bo.getDeptCategory()), SysDept::getDeptCategory, bo.getDeptCategory());
lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysDept::getStatus, bo.getStatus());

View File

@ -353,13 +353,12 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
@Override
@Transactional(rollbackFor = Exception.class)
public int insertUser(SysUserBo user) {
System.out.println("user2:" + JSONUtil.toJsonStr(user));
SysUser sysUser = MapstructUtils.convert(user, SysUser.class);
System.out.println("user3:" + JSONUtil.toJsonStr(sysUser));
// 新增用户信息
int rows = baseMapper.insert(sysUser);
user.setUserId(sysUser.getUserId());
System.out.println("user4:" + JSONUtil.toJsonStr(user));
// 新增用户岗位关联
insertUserPost(user, false);
// 新增用户与角色管理
@ -374,12 +373,24 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
* @return 结果
*/
@Override
@Transactional(rollbackFor = Exception.class)
public boolean registerUser(SysUserBo user, String tenantId) {
user.setCreateBy(0L);
user.setUpdateBy(0L);
SysUser sysUser = MapstructUtils.convert(user, SysUser.class);
sysUser.setTenantId(tenantId);
return baseMapper.insert(sysUser) > 0;
//return baseMapper.insert(sysUser) > 0;
// 新增用户信息
int rows = baseMapper.insert(sysUser);
user.setUserId(sysUser.getUserId());
// 新增用户岗位关联
//insertUserPost(user, false);
// 新增用户与角色管理
insertRegUserRole(user, false);
return rows >0;
}
/**
@ -490,6 +501,10 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
this.insertUserRole(user.getUserId(), user.getRoleIds(), clear);
}
private void insertRegUserRole(SysUserBo user, boolean clear) {
this.insertRegUserRole(user.getUserId(), user.getRoleIds(), clear);
}
/**
* 新增用户岗位信息
*
@ -548,6 +563,33 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
}
}
private void insertRegUserRole(Long userId, Long[] roleIds, boolean clear) {
if (ArrayUtil.isNotEmpty(roleIds)) {
List<Long> roleList = new ArrayList<>(List.of(roleIds));
if (!LoginHelper.isSuperAdmin(userId)) {
roleList.remove(SystemConstants.SUPER_ADMIN_ID);
}
// 判断是否具有此角色的操作权限
List<SysRoleVo> roles = roleMapper.selectRegRoleList(
new QueryWrapper<SysRole>().in("r.role_id", roleList));
if (CollUtil.isEmpty(roles)) {
throw new ServiceException("没有权限访问角色的数据");
}
if (clear) {
// 删除用户与角色关联
userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, userId));
}
// 新增用户与角色管理
List<SysUserRole> list = StreamUtils.toList(roleList, roleId -> {
SysUserRole ur = new SysUserRole();
ur.setUserId(userId);
ur.setRoleId(roleId);
return ur;
});
userRoleMapper.insertBatch(list);
}
}
/**
* 通过用户ID删除用户
*

View File

@ -35,6 +35,11 @@
${ew.getCustomSqlSegment}
</select>
<select id="selectRegRoleList" resultMap="SysRoleResult">
<include refid="selectRoleVo"/>
${ew.getCustomSqlSegment}
</select>
<select id="selectRolePermissionByUserId" parameterType="Long" resultMap="SysRoleResult">
<include refid="selectRoleVo"/>
WHERE r.del_flag = '0' and sur.user_id = #{userId}