diff --git a/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java b/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java index 704f24b..34dea0c 100644 --- a/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java +++ b/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java @@ -57,7 +57,7 @@ public class ShiroConfig { private JeecgBaseConfig jeecgBaseConfig; @Autowired(required = false) private RedisProperties redisProperties; - + /** * Filter Chain定义说明 * @@ -143,7 +143,7 @@ public class ShiroConfig { filterChainDefinitionMap.put("/jmreport/**", "anon"); filterChainDefinitionMap.put("/**/*.js.map", "anon"); filterChainDefinitionMap.put("/**/*.css.map", "anon"); - + //拖拽仪表盘设计器排除 filterChainDefinitionMap.put("/drag/view", "anon"); filterChainDefinitionMap.put("/drag/page/queryById", "anon"); @@ -173,6 +173,21 @@ public class ShiroConfig { // 企业微信证书排除 filterChainDefinitionMap.put("/WW_verify*", "anon"); + filterChainDefinitionMap.put("/sys/sysDepart/queryDepartStuTreeSync", "anon"); //申报人部门注册接口排除 + filterChainDefinitionMap.put("/sys/sysDepart/queryTreeStuList", "anon"); //申报人部门注册接口排除 + filterChainDefinitionMap.put("/sys/user/userRegister4Shenbaoren", "anon");//申报人用户注册 + filterChainDefinitionMap.put("/sys/sysDepart/queryDepartTreeSync", "anon");//申报人用户注册 + + + + + + + + + + + // 添加自己的过滤器并且取名为jwt Map filterMap = new HashMap(1); //如果cloudServer为空 则说明是单体 需要加载跨域配置【微服务跨域切换】 @@ -185,6 +200,7 @@ public class ShiroConfig { // 未授权界面返回JSON shiroFilterFactoryBean.setUnauthorizedUrl("/sys/common/403"); shiroFilterFactoryBean.setLoginUrl("/sys/common/403"); + shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; } @@ -273,7 +289,7 @@ public class ShiroConfig { /** * RedisConfig在项目starter项目中 * jeecg-boot-starter-github\jeecg-boot-common\src\main\java\org\jeecg\common\modules\redis\config\RedisConfig.java - * + * * 配置shiro redisManager * 使用的是shiro-redis开源插件 * @@ -295,7 +311,7 @@ public class ShiroConfig { return sentinelManager; } - + // redis 单机支持,在集群为空,或者集群无机器时候使用 add by jzyadmin@163.com if (lettuceConnectionFactory.getClusterConfiguration() == null || lettuceConnectionFactory.getClusterConfiguration().getClusterNodes().isEmpty()) { RedisManager redisManager = new RedisManager(); diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysUserController.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysUserController.java index cbccd1d..e85c29b 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysUserController.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysUserController.java @@ -25,6 +25,7 @@ import org.jeecg.common.system.query.QueryGenerator; import org.jeecg.common.system.util.JwtUtil; import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.util.*; +import org.jeecg.config.JeecgBaseConfig; import org.jeecg.config.mybatis.MybatisPlusSaasConfig; import org.jeecg.modules.base.service.BaseCommonService; import org.jeecg.modules.system.entity.*; @@ -42,11 +43,13 @@ import org.jeecgframework.poi.excel.entity.ImportParams; import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; import org.springframework.web.servlet.ModelAndView; +import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @@ -104,7 +107,10 @@ public class SysUserController { @Autowired private JeecgRedisClient jeecgRedisClient; - + + @Resource + private JeecgBaseConfig jeecgBaseConfig; + /** * 获取租户下用户数据(支持租户隔离) * @param user @@ -241,7 +247,7 @@ public class SysUserController { baseCommonService.addLog("批量删除用户, ids: " +ids ,CommonConstant.LOG_TYPE_2, 3); List userNameList = sysUserService.userIdToUsername(Arrays.asList(ids.split(","))); this.sysUserService.deleteBatchUsers(ids); - + // 用户变更,触发同步工作流 if (!userNameList.isEmpty()) { String joinedString = String.join(",", userNameList); @@ -929,7 +935,7 @@ public class SysUserController { } return result; } - + /** * 查询当前用户的所有部门/当前部门编码 * @return @@ -952,12 +958,12 @@ public class SysUserController { return result; } - + /** * 用户注册接口 - * + * * @param jsonObject * @param user * @return @@ -1020,7 +1026,7 @@ public class SysUserController { if(oConvertUtils.isEmpty(realname)){ realname = username; } - + try { user.setCreateTime(new Date());// 设置创建时间 String salt = oConvertUtils.randomGen(8); @@ -1115,7 +1121,7 @@ public class SysUserController { result.setSuccess(true); return result; } - + /** * 用户更改密码 */ @@ -1167,11 +1173,11 @@ public class SysUserController { return result; } } - + /** * 根据TOKEN获取用户的部分信息(返回的数据是可供表单设计器使用的数据) - * + * * @return */ @GetMapping("/getUserSectionInfoByToken") @@ -1182,7 +1188,7 @@ public class SysUserController { if (oConvertUtils.isEmpty(token)) { username = JwtUtil.getUserNameByToken(request); } else { - username = JwtUtil.getUsername(token); + username = JwtUtil.getUsername(token); } log.debug(" ------ 通过令牌获取部分用户信息,当前用户: " + username); @@ -1203,7 +1209,7 @@ public class SysUserController { return Result.error(500, "查询失败:" + e.getMessage()); } } - + /** * 【APP端接口】获取用户列表 根据用户名和真实名 模糊匹配 * @param keyword @@ -1240,7 +1246,7 @@ public class SysUserController { log.error(e.getMessage(), e); return Result.error(500, "查询失败:" + e.getMessage()); } - + } /** @@ -1281,7 +1287,7 @@ public class SysUserController { if (!userNameList.isEmpty()) { String joinedString = String.join(",", userNameList); } - + } return Result.ok("还原成功"); } @@ -1540,7 +1546,7 @@ public class SysUserController { } return ls; } - + /** * 聊天 创建聊天组件专用 根据用户账号、用户姓名、部门id分页查询 * @param departId 部门id @@ -1812,7 +1818,7 @@ public class SysUserController { Integer tenantId = sysUser.getLoginTenantId(); LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); String userId = loginUser.getId(); - + // 判断 指定的租户ID是不是当前登录用户的租户 LambdaQueryWrapper query = new LambdaQueryWrapper<>(); query.eq(SysUserTenant::getTenantId, tenantId); @@ -1821,7 +1827,7 @@ public class SysUserController { if(null == one){ return result.error500("非租户下的用户,不允许修改!"); } - + // 修改 loginTenantId LambdaQueryWrapper update = new LambdaQueryWrapper() .eq(SysUser::getId, userId); @@ -1829,7 +1835,7 @@ public class SysUserController { updateUser.setLoginTenantId(tenantId); sysUserService.update(updateUser, update); return Result.ok(); - } + } /** * 应用用户导出 @@ -1840,7 +1846,7 @@ public class SysUserController { public ModelAndView exportAppUser(HttpServletRequest request) { return sysUserService.exportAppUser(request); } - + /** * 应用用户导入 * @param request @@ -1850,4 +1856,98 @@ public class SysUserController { public Result importAppUser(HttpServletRequest request, HttpServletResponse response)throws IOException { return sysUserService.importAppUser(request); } + + + /** + * 申报人注册接口 + * @param jsonObject + * @param user + * @return + */ + @PostMapping("/userRegister4Shenbaoren") + public Result userRegister4Shenbaoren(@RequestBody JSONObject jsonObject, SysUser user) { + Result result = new Result(); + String phone = jsonObject.getString("phone"); + String captcha = jsonObject.getString("smscode"); + String departmentid = jsonObject.getString("departmentid"); + String realname = jsonObject.getString("realname"); + String checkKey = jsonObject.getString("checkKey"); + String workon = jsonObject.getString("workno"); + + if(captcha==null){ + result.error500("验证码无效"); + return result; + } + + String lowerCaseCaptcha = captcha.toLowerCase(); + //update-begin-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906 + // 加入密钥作为混淆,避免简单的拼接,被外部利用,用户自定义该密钥即可 + String origin = lowerCaseCaptcha+checkKey+jeecgBaseConfig.getSignatureSecret(); + String realKey = Md5Util.md5Encode(origin, "utf-8"); + //update-end-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906 + Object checkCode = redisUtil.get(realKey); + //当进入登录页时,有一定几率出现验证码错误 #1714 + if(checkCode==null || !checkCode.toString().equals(lowerCaseCaptcha)) { + log.warn("验证码错误,key= {} , Ui checkCode= {}, Redis checkCode = {}", checkKey, lowerCaseCaptcha, checkCode); + result.error500("验证码错误"); + // 改成特殊的code 便于前端判断 + result.setCode(HttpStatus.PRECONDITION_FAILED.value()); + return result; + } + + String username = jsonObject.getString("username"); + //未设置用户名,则用手机号作为用户名 + if(oConvertUtils.isEmpty(username)){ + username = phone; + } + //未设置密码,则随机生成一个密码 + String password = jsonObject.getString("password"); + String email = jsonObject.getString("email"); + SysUser sysUser1 = sysUserService.getUserByName(username); + if (sysUser1 != null) { + result.setMessage("用户名已注册"); + result.setSuccess(false); + return result; + } + SysUser sysUser2 = sysUserService.getUserByPhone(phone); + if (sysUser2 != null) { + result.setMessage("该手机号已注册"); + result.setSuccess(false); + return result; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in("work_no", workon); + List sysUser3 = sysUserService.list(queryWrapper); + if (sysUser3.size()>0) { + result.setMessage("该学号/工号已注册"); + result.setSuccess(false); + return result; + } + + if(oConvertUtils.isEmpty(realname)){ + realname = username; + } + + try { + user.setCreateTime(new Date());// 设置创建时间 + String salt = oConvertUtils.randomGen(8); + String passwordEncode = PasswordUtil.encrypt(username, password, salt); + user.setSalt(salt); + user.setUsername(username); + user.setWorkNo(workon); + user.setRealname(realname); + user.setPassword(passwordEncode); + //user.setEmail(email); + user.setPhone(phone); + user.setStatus(CommonConstant.USER_UNFREEZE); + user.setDelFlag(CommonConstant.DEL_FLAG_0); + user.setActivitiSync(CommonConstant.ACT_SYNC_0); + sysUserService.addUserWithRole(user,"1724327596426760194"); + sysUserService.addUserWithDepart(user,departmentid); + result.success("注册成功"); + } catch (Exception e) { + result.error500("注册失败"); + } + return result; + } } diff --git a/jeecgboot-vue3/src/api/sys/user.ts b/jeecgboot-vue3/src/api/sys/user.ts index 5ed47e3..f08411b 100644 --- a/jeecgboot-vue3/src/api/sys/user.ts +++ b/jeecgboot-vue3/src/api/sys/user.ts @@ -27,6 +27,8 @@ enum Api { getCaptcha = '/sys/sms', //注册接口 registerApi = '/sys/user/register', + // 申报人注册接口 + userRegister4Shenbaoren = '/sys/user/userRegister4Shenbaoren', //校验用户接口 checkOnlyUser = '/sys/user/checkOnlyUser', //SSO登录校验 @@ -114,6 +116,11 @@ export function getCodeInfo(currdatetime) { let url = Api.getInputCode + `/${currdatetime}`; return defHttp.get({ url: url }); } + +export function registerStu(params) { + return defHttp.post({url: Api.userRegister4Shenbaoren, params}, {isReturnNativeResponse: true}); +} + /** * @description: 获取短信验证码 */ diff --git a/jeecgboot-vue3/src/locales/lang/en/sys.ts b/jeecgboot-vue3/src/locales/lang/en/sys.ts index 952d84b..ed5e6d2 100644 --- a/jeecgboot-vue3/src/locales/lang/en/sys.ts +++ b/jeecgboot-vue3/src/locales/lang/en/sys.ts @@ -92,6 +92,8 @@ export default { mobileCorrectPlaceholder: 'Please input correct mobile', policyPlaceholder: 'Register after checking', diffPwd: 'The two passwords are inconsistent', + selectdep: 'Please select dep', + userName: 'Username', password: 'Password', @@ -100,6 +102,10 @@ export default { email: 'Email', smsCode: 'SMS code', mobile: 'Mobile', + realName: 'realname', + workNo: 'workno', + department: 'department', + //重置密码页面英文 authentication:'authentication', diff --git a/jeecgboot-vue3/src/locales/lang/zh-CN/sys.ts b/jeecgboot-vue3/src/locales/lang/zh-CN/sys.ts index b0c1dc6..c155156 100644 --- a/jeecgboot-vue3/src/locales/lang/zh-CN/sys.ts +++ b/jeecgboot-vue3/src/locales/lang/zh-CN/sys.ts @@ -69,12 +69,14 @@ export default { signInTitle: 'Jeecg Boot', signInDesc: '是中国最具影响力的 企业级低代码平台!在线开发,可视化拖拽设计,零代码实现80%的基础功能~', - policy: '我同意敲敲云隐私政策', + policy: '我同意敲敲云隐私政策5', scanSign: `扫码后,即可完成登录`, scanSuccess: `扫码成功,登录中`, loginButton: '登录', registerButton: '注册', + registerButton4danwei: '单位注册', + registerButton4shenbaoren: '申报人注册', rememberMe: '记住我', forgetPassword: '忘记密码?', otherSignIn: '其他登录方式', @@ -92,6 +94,7 @@ export default { mobileCorrectPlaceholder: '请输入正确的手机号码', policyPlaceholder: '勾选后才能注册', diffPwd: '两次输入密码不一致', + selectdep: '请选择所属部门/单位', userName: '账号', password: '密码', @@ -100,6 +103,9 @@ export default { email: '邮箱', smsCode: '短信验证码', mobile: '手机号码', + realName: '姓名', + workNo: '工号', + department: '部门/单位', subTitleText: '{0}秒后返回登录页面', diff --git a/jeecgboot-vue3/src/views/system/loginmini/MiniLogin.vue b/jeecgboot-vue3/src/views/system/loginmini/MiniLogin.vue index 826060a..bd08823 100644 --- a/jeecgboot-vue3/src/views/system/loginmini/MiniLogin.vue +++ b/jeecgboot-vue3/src/views/system/loginmini/MiniLogin.vue @@ -95,7 +95,11 @@ {{ t('sys.login.qrSignInFormTitle') }} @@ -144,7 +148,7 @@ - + @@ -561,7 +565,7 @@ html[data-theme='dark'] { -webkit-text-fill-color: #c9d1d9 !important; box-shadow: inherit !important; } - + .ant-divider-inner-text { font-size: 12px !important; color: @text-color-secondary !important; diff --git a/jeecgboot-vue3/src/views/system/loginmini/MiniRegister.vue b/jeecgboot-vue3/src/views/system/loginmini/MiniRegister.vue index 61a888f..19a0d2e 100644 --- a/jeecgboot-vue3/src/views/system/loginmini/MiniRegister.vue +++ b/jeecgboot-vue3/src/views/system/loginmini/MiniRegister.vue @@ -23,48 +23,93 @@
- - + + +
+
+ +
+ +
+ + + + + + + + +
+ +
+
+ +
+ + +
+
+
- - + +
- 开启 - 关闭 + 开启 + 关闭
- - + +
- 开启 - 关闭 + 开启 + 关闭
- -
-
-
- - {{ t('sys.login.policy') }} -
-
+
+ + + + +
+ +
- +
+
@@ -81,23 +126,22 @@
- - + initForm, + }); + +