Commit 077f62f4 authored by fulixin's avatar fulixin

Merge branch 'V20240319三方平台登录改造' into V20240805

parents 798456ab f50c2397
package com.dsk.web.controller.system; package com.dsk.web.controller.system;
import cn.dev33.satoken.annotation.SaCheckLogin; import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaIgnore; import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.stp.StpUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.RegexPool;
import cn.hutool.core.lang.RegexPool; import cn.hutool.core.map.MapUtil;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.RandomUtil; import com.dsk.common.constant.Constants;
import cn.hutool.core.util.ReUtil; import com.dsk.common.constant.GlobalConstants;
import com.dsk.common.constant.Constants; import com.dsk.common.core.domain.R;
import com.dsk.common.constant.GlobalConstants; import com.dsk.common.core.domain.model.*;
import com.dsk.common.core.domain.R; import com.dsk.common.helper.LoginHelper;
import com.dsk.common.exception.ServiceException; import com.dsk.common.utils.redis.RedisUtils;
import com.dsk.common.tenant.helper.TenantHelper; import com.dsk.jsk.util.IpUtil;
import com.dsk.common.utils.StringUtils; import com.dsk.system.domain.SysMenu;
import com.dsk.common.utils.redis.RedisUtils; import com.dsk.system.domain.SysUser;
import com.dsk.jsk.util.IpUtil; import com.dsk.system.domain.vo.LoginVo;
import com.dsk.system.domain.SysMenu; import com.dsk.system.domain.vo.RouterVo;
import com.dsk.system.domain.SysUser; import com.dsk.system.domain.vo.SysTenantVo;
import com.dsk.common.core.domain.model.EmailLoginBody; import com.dsk.system.service.ISysMenuService;
import com.dsk.common.core.domain.model.LoginBody; import com.dsk.system.service.ISysUserService;
import com.dsk.common.core.domain.model.LoginUser; import com.dsk.system.service.SysLoginService;
import com.dsk.common.core.domain.model.SmsLoginBody; import lombok.RequiredArgsConstructor;
import com.dsk.common.helper.LoginHelper; import org.springframework.validation.annotation.Validated;
import com.dsk.system.domain.vo.LoginVo; import org.springframework.web.bind.annotation.GetMapping;
import com.dsk.system.domain.vo.RouterVo; import org.springframework.web.bind.annotation.PostMapping;
import com.dsk.system.domain.vo.SysTenantVo; import org.springframework.web.bind.annotation.RequestBody;
import com.dsk.system.service.ISysMenuService; import org.springframework.web.bind.annotation.RestController;
import com.dsk.system.service.ISysUserService;
import com.dsk.system.service.SysLoginService; import javax.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor; import javax.validation.constraints.NotBlank;
import org.dromara.sms4j.api.SmsBlend; import java.util.ArrayList;
import org.dromara.sms4j.api.entity.SmsResponse; import java.util.HashMap;
import org.dromara.sms4j.core.factory.SmsFactory; import java.util.List;
import org.dromara.sms4j.provider.enumerate.SupplierType; import java.util.Map;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; /**
* 登录验证
import javax.servlet.ServletRequest; *
import javax.servlet.http.HttpServletRequest; * @author Lion Li
import javax.validation.constraints.NotBlank; */
import java.time.Duration; @Validated
import java.util.*; @RequiredArgsConstructor
@RestController
/** public class SysLoginController {
* 登录验证
* private final SysLoginService loginService;
* @author Lion Li private final ISysMenuService menuService;
*/ private final ISysUserService userService;
@Validated
@RequiredArgsConstructor /**
@RestController * 登录方法
public class SysLoginController { *
* @param loginBody 登录信息
private final SysLoginService loginService; * @return 结果
private final ISysMenuService menuService; */
private final ISysUserService userService; @SaIgnore
@PostMapping("/login")
/** public R<LoginVo> login(@Validated @RequestBody LoginBody loginBody, HttpServletRequest request) {
* 登录方法 // Map<String, Object> ajax = new HashMap<>();
* // 生成令牌
* @param loginBody 登录信息 // LoginVo loginVo = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
* @return 结果 // loginBody.getUuid());
*/ // ajax.put(Constants.TOKEN, token);
@SaIgnore // return R.ok(ajax);
@PostMapping("/login") String ipAddr = IpUtil.getIpAddr(request);
public R<LoginVo> login(@Validated @RequestBody LoginBody loginBody, HttpServletRequest request) { LoginVo loginVo = loginService.passwordLogin(loginBody, ipAddr);
// Map<String, Object> ajax = new HashMap<>(); return R.ok(loginVo);
// 生成令牌 }
// LoginVo loginVo = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
// loginBody.getUuid()); /**
// ajax.put(Constants.TOKEN, token); * 三方平台跳转登录方法
// return R.ok(ajax); *
String ipAddr = IpUtil.getIpAddr(request); * @param tpLoginBody 登录信息
LoginVo loginVo = loginService.passwordLogin(loginBody, ipAddr); * @return 结果
return R.ok(loginVo); */
} @SaIgnore
@PostMapping("/thirdPlatformLogin")
public R<LoginVo> thirdPlatformLogin(@Validated @RequestBody ThirdPlatformLoginBody tpLoginBody, HttpServletRequest request) {
// /** String ipAddr = IpUtil.getIpAddr(request);
// * 发送短信验证码 return R.ok(loginService.thirdPlatformLogin(tpLoginBody, ipAddr));
// * }
// * @param phones 电话号
// * @param templateId 模板ID
// */ // /**
// @SaIgnore // * 发送短信验证码
// @GetMapping("/send/sms/code") // *
// public R<Object> sendAliyun(String phones, String templateId) { // * @param phones 电话号
// LinkedHashMap<String, String> map = new LinkedHashMap<>(1); // * @param templateId 模板ID
// map.put("code", RandomUtil.randomNumbers(4)); // */
// SmsBlend smsBlend = SmsFactory.createSmsBlend(SupplierType.ALIBABA); // @SaIgnore
// SmsResponse smsResponse = smsBlend.sendMessage(phones, templateId, map); // @GetMapping("/send/sms/code")
// return R.ok(smsResponse); // public R<Object> sendAliyun(String phones, String templateId) {
// } // LinkedHashMap<String, String> map = new LinkedHashMap<>(1);
// map.put("code", RandomUtil.randomNumbers(4));
/** // SmsBlend smsBlend = SmsFactory.createSmsBlend(SupplierType.ALIBABA);
* 短信登录 // SmsResponse smsResponse = smsBlend.sendMessage(phones, templateId, map);
* // return R.ok(smsResponse);
* @param smsLoginBody 登录信息 // }
* @return 结果
*/ /**
@SaIgnore * 短信登录
@PostMapping("/smsLogin") *
public R<LoginVo> smsLogin(@Validated @RequestBody SmsLoginBody smsLoginBody) { * @param smsLoginBody 登录信息
// 生成令牌 * @return 结果
LoginVo loginVo = loginService.smsLogin(smsLoginBody.getPhonenumber(), smsLoginBody.getSmsCode()); */
return R.ok(loginVo); @SaIgnore
} @PostMapping("/smsLogin")
public R<LoginVo> smsLogin(@Validated @RequestBody SmsLoginBody smsLoginBody) {
// 生成令牌
/** LoginVo loginVo = loginService.smsLogin(smsLoginBody.getPhonenumber(), smsLoginBody.getSmsCode());
* 动态切换租户 return R.ok(loginVo);
*/ }
@SaCheckLogin
@PostMapping("/switch/tenant")
public R<LoginVo> switchTenant(String tenantId) { /**
LoginVo loginVo = loginService.switchTenant(tenantId); * 动态切换租户
return R.ok(loginVo); */
} @SaCheckLogin
@PostMapping("/switch/tenant")
public R<LoginVo> switchTenant(String tenantId) {
/** LoginVo loginVo = loginService.switchTenant(tenantId);
* 用户租户列表:根据用户账号获取用户绑定的租户列表 return R.ok(loginVo);
* }
* @return 结果
*/
@SaCheckLogin /**
@PostMapping("/user/tenants") * 用户租户列表:根据用户账号获取用户绑定的租户列表
public R<List<SysTenantVo>> userTenants() { *
LoginUser loginUser = LoginHelper.getLoginUser(); * @return 结果
List<SysTenantVo> tenantList = loginService.tenantListByAccount(loginUser.getUserPhone()); */
return R.ok(tenantList); @SaCheckLogin
} @PostMapping("/user/tenants")
public R<List<SysTenantVo>> userTenants() {
LoginUser loginUser = LoginHelper.getLoginUser();
/** List<SysTenantVo> tenantList = loginService.tenantListByAccount(loginUser.getUserPhone());
* 用户租户列表:根据用户账号获取用户绑定的租户列表 return R.ok(tenantList);
* }
* @return 结果
*/
@SaIgnore /**
@PostMapping("/user/tenant/list") * 用户租户列表:根据用户账号获取用户绑定的租户列表
public R<List<SysTenantVo>> userTenantList(String phone) { *
if (!ReUtil.isMatch(RegexPool.MOBILE, phone)) { * @return 结果
return R.ok(new ArrayList<>()); */
} @SaIgnore
List<SysTenantVo> tenantList = loginService.tenantListByAccount(phone); @PostMapping("/user/tenant/list")
if (CollectionUtil.isNotEmpty(tenantList)) { public R<List<SysTenantVo>> userTenantList(String phone) {
for (SysTenantVo sysTenantVo : tenantList) { if (!ReUtil.isMatch(RegexPool.MOBILE, phone)) {
sysTenantVo.setCompanyName(""); return R.ok(new ArrayList<>());
} }
} List<SysTenantVo> tenantList = loginService.tenantListByAccount(phone);
return R.ok(tenantList); if (CollectionUtil.isNotEmpty(tenantList)) {
} for (SysTenantVo sysTenantVo : tenantList) {
sysTenantVo.setCompanyName("");
/** }
* 获取当前用户默认租户 }
* return R.ok(tenantList);
* @return }
*/
@SaCheckLogin /**
@PostMapping("/user/default/tenant") * 获取当前用户默认租户
public R<Map> userDefaultTenant() { *
LoginUser loginUser = LoginHelper.getLoginUser(); * @return
Assert.notNull(loginUser, "用户信息不存在!"); */
String defaultTenantKey = GlobalConstants.PHONE_DEFAULT_TENANT + loginUser.getUserPhone(); @SaCheckLogin
String defaultTenant = RedisUtils.getCacheObject(defaultTenantKey); @PostMapping("/user/default/tenant")
return R.ok(MapUtil.of("tenantId", defaultTenant)); public R<Map> userDefaultTenant() {
} LoginUser loginUser = LoginHelper.getLoginUser();
Assert.notNull(loginUser, "用户信息不存在!");
String defaultTenantKey = GlobalConstants.PHONE_DEFAULT_TENANT + loginUser.getUserPhone();
/** String defaultTenant = RedisUtils.getCacheObject(defaultTenantKey);
* 获取当前用户默认租户 return R.ok(MapUtil.of("tenantId", defaultTenant));
* }
* @return
*/
@SaIgnore /**
@PostMapping("/user/default/tenant/phone") * 获取当前用户默认租户
public R<Map> userDefaultTenant(String phone) { *
// LoginUser loginUser = LoginHelper.getLoginUser(); * @return
// Assert.notNull(loginUser,"用户信息不存在!"); */
String defaultTenantKey = GlobalConstants.PHONE_DEFAULT_TENANT + phone; @SaIgnore
String defaultTenant = RedisUtils.getCacheObject(defaultTenantKey); @PostMapping("/user/default/tenant/phone")
return R.ok(MapUtil.of("tenantId", defaultTenant)); public R<Map> userDefaultTenant(String phone) {
} // LoginUser loginUser = LoginHelper.getLoginUser();
// Assert.notNull(loginUser,"用户信息不存在!");
/** String defaultTenantKey = GlobalConstants.PHONE_DEFAULT_TENANT + phone;
* 邮件登录 String defaultTenant = RedisUtils.getCacheObject(defaultTenantKey);
* return R.ok(MapUtil.of("tenantId", defaultTenant));
* @param body 登录信息 }
* @return 结果
*/ /**
@PostMapping("/emailLogin") * 邮件登录
public R<Map<String, Object>> emailLogin(@Validated @RequestBody EmailLoginBody body) { *
Map<String, Object> ajax = new HashMap<>(); * @param body 登录信息
// 生成令牌 * @return 结果
String token = loginService.emailLogin(body.getEmail(), body.getEmailCode()); */
ajax.put(Constants.TOKEN, token); @PostMapping("/emailLogin")
return R.ok(ajax); public R<Map<String, Object>> emailLogin(@Validated @RequestBody EmailLoginBody body) {
} Map<String, Object> ajax = new HashMap<>();
// 生成令牌
/** String token = loginService.emailLogin(body.getEmail(), body.getEmailCode());
* 小程序登录(示例) ajax.put(Constants.TOKEN, token);
* return R.ok(ajax);
* @param xcxCode 小程序code }
* @return 结果
*/ /**
@SaIgnore * 小程序登录(示例)
@PostMapping("/xcxLogin") *
public R<Map<String, Object>> xcxLogin(@NotBlank(message = "{xcx.code.not.blank}") String xcxCode) { * @param xcxCode 小程序code
Map<String, Object> ajax = new HashMap<>(); * @return 结果
// 生成令牌 */
String token = loginService.xcxLogin(xcxCode); @SaIgnore
ajax.put(Constants.TOKEN, token); @PostMapping("/xcxLogin")
return R.ok(ajax); public R<Map<String, Object>> xcxLogin(@NotBlank(message = "{xcx.code.not.blank}") String xcxCode) {
} Map<String, Object> ajax = new HashMap<>();
// 生成令牌
/** String token = loginService.xcxLogin(xcxCode);
* 退出登录 ajax.put(Constants.TOKEN, token);
*/ return R.ok(ajax);
@SaIgnore }
@PostMapping("/logout")
public R<Void> logout() { /**
loginService.logout(); * 退出登录
return R.ok("退出成功"); */
} @SaIgnore
@PostMapping("/logout")
/** public R<Void> logout() {
* 获取用户信息 loginService.logout();
* return R.ok("退出成功");
* @return 用户信息 }
*/
@GetMapping("getInfo") /**
public R<Map<String, Object>> getInfo(HttpServletRequest request) { * 获取用户信息
LoginUser loginUser = LoginHelper.getLoginUser(); *
//校验当前发请求的IP与登录账号的IP是否相同 * @return 用户信息
// String loginUserIpaddr = loginUser.getIpaddr(); */
// if (StringUtils.isNotBlank(loginUserIpaddr) && !Objects.equals(IpUtil.getIpAddr(request), loginUserIpaddr)) { @GetMapping("getInfo")
// throw new ServiceException("该账号已在其他地方登录,请求失败!", 401); public R<Map<String, Object>> getInfo(HttpServletRequest request) {
// } LoginUser loginUser = LoginHelper.getLoginUser();
SysUser user = userService.selectUserById(loginUser.getUserId()); //校验当前发请求的IP与登录账号的IP是否相同
Map<String, Object> ajax = new HashMap<>(); // String loginUserIpaddr = loginUser.getIpaddr();
ajax.put("user", user); // if (StringUtils.isNotBlank(loginUserIpaddr) && !Objects.equals(IpUtil.getIpAddr(request), loginUserIpaddr)) {
ajax.put("roles", loginUser.getRolePermission()); // throw new ServiceException("该账号已在其他地方登录,请求失败!", 401);
ajax.put("permissions", loginUser.getMenuPermission()); // }
return R.ok(ajax); SysUser user = userService.selectUserById(loginUser.getUserId());
} Map<String, Object> ajax = new HashMap<>();
ajax.put("user", user);
/** ajax.put("roles", loginUser.getRolePermission());
* 获取路由信息 ajax.put("permissions", loginUser.getMenuPermission());
* ajax.put("isThirdPlatformLogin", LoginHelper.getLoginUser().getIsThirdPlatformLogin());
* @return 路由信息 return R.ok(ajax);
*/ }
@GetMapping("getRouters")
public R<List<RouterVo>> getRouters() { /**
Long userId = LoginHelper.getUserId(); * 获取路由信息
List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId); *
return R.ok(menuService.buildMenus(menus)); * @return 路由信息
} */
} @GetMapping("getRouters")
public R<List<RouterVo>> getRouters() {
Long userId = LoginHelper.getUserId();
List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId);
return R.ok(menuService.buildMenus(menus));
}
}
...@@ -52,9 +52,16 @@ spring: ...@@ -52,9 +52,16 @@ spring:
# url: jdbc:mysql://192.168.0.79:3306/dsk_operate_sys?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 # url: jdbc:mysql://192.168.0.79:3306/dsk_operate_sys?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
# username: dev # username: dev
# password: 8AXjjCHZ666! # password: 8AXjjCHZ666!
url: jdbc:mysql://rds-szh.dsk.com/dos?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 # url: jdbc:mysql://rds-szh.dsk.com/dos?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: dsk_api_szh # username: dsk_api_szh
password: j1nxbVPF0QS*B57C # password: j1nxbVPF0QS*B57C
# 二十局线上数据库
url: jdbc:mysql://123.60.218.188:3306/dsk_operate_online?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: dev
password: encPHwi8dbKeL!6X
# 从库数据源 # 从库数据源
# slave: # slave:
# lazy: true # lazy: true
...@@ -104,13 +111,29 @@ spring: ...@@ -104,13 +111,29 @@ spring:
--- # redis 单机配置(单机与集群只能开启一个另一个需要注释掉) --- # redis 单机配置(单机与集群只能开启一个另一个需要注释掉)
spring: spring:
redis: redis:
host: redis-szh.dsk.com # host: redis-szh.dsk.com
# # 端口,默认为6379
# port: 6379
# # 数据库索引
# database: 13
# # 密码
# password: Xi8$r*@d7zn5FaP2
# # 密码(如没有密码请注释掉)
# # password:
# # 连接超时时间
# timeout: 10s
# # 是否开启ssl
# ssl: false
# 二十局redis测试链接
host: 123.60.218.188
# 端口,默认为6379 # 端口,默认为6379
port: 6379 port: 6379
# 数据库索引 # 数据库索引
database: 13 database: 13
# 密码 # 密码
password: Xi8$r*@d7zn5FaP2 password: zfTFIJjaN#6xB64r
# 密码(如没有密码请注释掉) # 密码(如没有密码请注释掉)
# password: # password:
# 连接超时时间 # 连接超时时间
...@@ -190,4 +213,4 @@ sms: ...@@ -190,4 +213,4 @@ sms:
territory: ap-guangzhou territory: ap-guangzhou
dsk: dsk:
exportBackUrl: https://szhapi.jiansheku.com/export/backUrl exportBackUrl: https://szhapi.jiansheku.com/export/backUrl
\ No newline at end of file
...@@ -49,9 +49,16 @@ spring: ...@@ -49,9 +49,16 @@ spring:
driverClassName: com.mysql.cj.jdbc.Driver driverClassName: com.mysql.cj.jdbc.Driver
# jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562 # jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562
# rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题) # rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题)
url: jdbc:mysql://120.46.64.239:3306/dsk_operate?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 # url: jdbc:mysql://120.46.64.239:3306/dsk_operate?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: dskdev # username: dskdev
password: encPHwi8dbKeL8ZX # password: encPHwi8dbKeL8ZX
# 二十局数据库配置
url: jdbc:mysql://123.60.218.188:3306/dsk_operate?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: dev
password: encPHwi8dbKeL!6X
# 从库数据源 # 从库数据源
# slave: # slave:
# lazy: true # lazy: true
...@@ -101,13 +108,28 @@ spring: ...@@ -101,13 +108,28 @@ spring:
--- # redis 单机配置(单机与集群只能开启一个另一个需要注释掉) --- # redis 单机配置(单机与集群只能开启一个另一个需要注释掉)
spring: spring:
redis: redis:
host: 120.46.64.239 # host: 120.46.64.239
# # 端口,默认为6379
# port: 6379
# # 数据库索引
# database: 13
# # 密码
# password: zfTFIJjaN#6xB83r
# # 密码(如没有密码请注释掉)
# # password:
# # 连接超时时间
# timeout: 10s
# # 是否开启ssl
# ssl: false
# 二十局redis测试链接
host: 123.60.218.188
# 端口,默认为6379 # 端口,默认为6379
port: 6379 port: 6379
# 数据库索引 # 数据库索引
database: 13 database: 14
# 密码 # 密码
password: zfTFIJjaN#6xB83r password: zfTFIJjaN#6xB64r
# 密码(如没有密码请注释掉) # 密码(如没有密码请注释掉)
# password: # password:
# 连接超时时间 # 连接超时时间
...@@ -115,6 +137,9 @@ spring: ...@@ -115,6 +137,9 @@ spring:
# 是否开启ssl # 是否开启ssl
ssl: false ssl: false
redisson: redisson:
# redis key前缀 # redis key前缀
keyPrefix: keyPrefix:
...@@ -193,4 +218,4 @@ sa-token: ...@@ -193,4 +218,4 @@ sa-token:
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
is-concurrent: true is-concurrent: true
# 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
is-share: true is-share: true
\ No newline at end of file
...@@ -29,7 +29,9 @@ captcha: ...@@ -29,7 +29,9 @@ captcha:
# 开发环境配置 # 开发环境配置
server: server:
# 服务器的HTTP端口,默认为8080 # 服务器的HTTP端口,默认为8080
port: 9098 # port: 9098
# 二十局线上端口9097
port: 9097
servlet: servlet:
# 应用的访问路径 # 应用的访问路径
context-path: / context-path: /
...@@ -142,12 +144,14 @@ security: ...@@ -142,12 +144,14 @@ security:
# actuator 监控配置 # actuator 监控配置
- /api/** - /api/**
- /actuator/** - /actuator/**
# - /**
# 多租户配置 # 多租户配置
tenant: tenant:
# 是否开启 # 是否开启
enable: true enable: true
# enable: false
# 排除表 # 排除表
excludes: excludes:
- sys_menu - sys_menu
......
...@@ -113,6 +113,11 @@ public class LoginUser implements Serializable { ...@@ -113,6 +113,11 @@ public class LoginUser implements Serializable {
*/ */
private Long roleId; private Long roleId;
/**
* 是否三方登录
*/
private Boolean isThirdPlatformLogin;
/** /**
* 获取登录id * 获取登录id
*/ */
......
package com.dsk.common.core.domain.model;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
* 三方平台用户登录对象
*
* @author sxk
*/
@Data
public class ThirdPlatformLoginBody {
/**
* 三方平台跳转本系统所需秘钥
*/
@NotBlank(message = "桑芳平台登录秘钥不能为空")
private String thirdPlatformKey;
}
...@@ -43,4 +43,283 @@ public class IndexController { ...@@ -43,4 +43,283 @@ public class IndexController {
public AjaxResult bidRank(@RequestBody JSONObject object) { public AjaxResult bidRank(@RequestBody JSONObject object) {
return enterpriseService.bidRank(object); return enterpriseService.bidRank(object);
} }
/**
*
*
* 总金额、总面积统计--刘杰那边的接口
* @param object
* @return {@link AjaxResult }
* @throws Exception
*/
@PostMapping(value = "/statisticsOfAmountAndArea")
public AjaxResult statisticsOfAmountAndArea(@RequestBody JSONObject object) {
return enterpriseService.statisticsOfAmountAndArea(object);
}
/**
*
*
* 基础维度统计--刘杰那边的接口
* /nationzj/landMarket/commonStatis
* @param object
* @return {@link AjaxResult }
* @throws Exception
*/
@PostMapping(value = "/jcwdtj")
public AjaxResult jcwdtj(@RequestBody JSONObject object) {
return enterpriseService.jcwdtj(object);
}
/**
*
*
* 前十企业统计--刘杰那边的接口
* /nationzj/landMarket/companyStatis
* @param object
* @return {@link AjaxResult }
* @throws Exception
*/
@PostMapping(value = "/topten")
public AjaxResult topten(@RequestBody JSONObject object) {
return enterpriseService.topten(object);
}
/**
*
*
* 商机-拟建查询-总金额统计--刘杰那边的接口
* /nationzj/landMarket/companyStatis
* @param object
* @return {@link AjaxResult }
* @throws Exception
*/
@PostMapping(value = "/njzjetj")
public AjaxResult njzjetj(@RequestBody JSONObject object) {
return enterpriseService.njzjetj(object);
}
/**
*
*
* 商机-拟建查询-基础维度统计--刘杰那边的接口
* /nationzj/landMarket/companyStatis
* @param object
* @return {@link AjaxResult }
* @throws Exception
*/
@PostMapping(value = "/njjcwdtj")
public AjaxResult njjcwdtj(@RequestBody JSONObject object) {
return enterpriseService.njjcwdtj(object);
}
/**
*
*
* 商机-拟建查询-前十企业统计--刘杰那边的接口
* /nationzj/landMarket/companyStatis
* @param object
* @return {@link AjaxResult }
* @throws Exception
*/
@PostMapping(value = "/njtopten")
public AjaxResult njtopten(@RequestBody JSONObject object) {
return enterpriseService.njtopten(object);
}
/**
*
*
* 商机-招标公告-总金额统计--刘杰那边的接口
* /nationzj/landMarket/companyStatis
* @param object
* @return {@link AjaxResult }
* @throws Exception
*/
@PostMapping(value = "/zbggzjetj")
public AjaxResult zbggzjetj(@RequestBody JSONObject object) {
return enterpriseService.zbggzjetj(object);
}
/**
*
*
* 商机-招标公告-基础维度统计--刘杰那边的接口
* /nationzj/landMarket/companyStatis
* @param object
* @return {@link AjaxResult }
* @throws Exception
*/
@PostMapping(value = "/zbggjcwdtj")
public AjaxResult zbggjcwdtj(@RequestBody JSONObject object) {
return enterpriseService.zbggjcwdtj(object);
}
/**
*
*
* 商机-招标公告-前十企业统计--刘杰那边的接口
* /nationzj/landMarket/companyStatis
* @param object
* @return {@link AjaxResult }
* @throws Exception
*/
@PostMapping(value = "/zbggtopten")
public AjaxResult zbggtopten(@RequestBody JSONObject object) {
return enterpriseService.zbggtopten(object);
}
/**
*
*
* 招标计划查询-总金额统计--刘杰那边的接口
* /nationzj/landMarket/companyStatis
* @param object
* @return {@link AjaxResult }
* @throws Exception
*/
@PostMapping(value = "/zbjhcxzjetj")
public AjaxResult zbjhcxzjetj(@RequestBody JSONObject object) {
return enterpriseService.zbjhcxzjetj(object);
}
/**
*
*
* 招标计划查询-基础维度统计--刘杰那边的接口
* /nationzj/landMarket/companyStatis
* @param object
* @return {@link AjaxResult }
* @throws Exception
*/
@PostMapping(value = "/zbjhcxjcwdtj")
public AjaxResult zbjhcxjcwdtj(@RequestBody JSONObject object) {
return enterpriseService.zbjhcxjcwdtj(object);
}
/**
*
*
* 招标计划查询-前十企业统计--刘杰那边的接口
* /nationzj/landMarket/companyStatis
* @param object
* @return {@link AjaxResult }
* @throws Exception
*/
@PostMapping(value = "/zbjhcxtopten")
public AjaxResult zbjhcxtopten(@RequestBody JSONObject object) {
return enterpriseService.zbjhcxtopten(object);
}
/**
*
*
* 重点项目清单查询-总金额统计--刘杰那边的接口
* /nationzj/landMarket/companyStatis
* @param object
* @return {@link AjaxResult }
* @throws Exception
*/
@PostMapping(value = "/zdxmqdzjetj")
public AjaxResult zdxmqdzjetj(@RequestBody JSONObject object) {
return enterpriseService.zdxmqdzjetj(object);
}
/**
*
*
* 重点项目清单查询-基础统计--刘杰那边的接口
* /nationzj/landMarket/companyStatis
* @param object
* @return {@link AjaxResult }
* @throws Exception
*/
@PostMapping(value = "/zdxmqdjctj")
public AjaxResult zdxmqdjctj(@RequestBody JSONObject object) {
return enterpriseService.zdxmqdjctj(object);
}
/**
*
*
* 重点项目清单查询-前十企业--刘杰那边的接口
* /nationzj/landMarket/companyStatis
* @param object
* @return {@link AjaxResult }
* @throws Exception
*/
@PostMapping(value = "/zdxmqdtopten")
public AjaxResult zdxmqdtopten(@RequestBody JSONObject object) {
return enterpriseService.zdxmqdtopten(object);
}
/**
*
*
* 专项债项目-总金额统计--刘杰那边的接口
* /nationzj/landMarket/companyStatis
* @param object
* @return {@link AjaxResult }
* @throws Exception
*/
@PostMapping(value = "/zxzxmzjetj")
public AjaxResult zxzxmzjetj(@RequestBody JSONObject object) {
return enterpriseService.zxzxmzjetj(object);
}
/**
*
*
* 专项债项目-基础统计--刘杰那边的接口
* /nationzj/landMarket/companyStatis
* @param object
* @return {@link AjaxResult }
* @throws Exception
*/
@PostMapping(value = "/zxzxmjctj")
public AjaxResult zxzxmjctj(@RequestBody JSONObject object) {
return enterpriseService.zxzxmjctj(object);
}
/**
*
*
* 专项债项目查询-企业统计--刘杰那边的接口
* /nationzj/landMarket/companyStatis
* @param object
* @return {@link AjaxResult }
* @throws Exception
*/
@PostMapping(value = "/zxzxmqytj")
public AjaxResult zxzxmqytj(@RequestBody JSONObject object) {
return enterpriseService.zxzxmqytj(object);
}
} }
...@@ -33,6 +33,278 @@ public class IndexService { ...@@ -33,6 +33,278 @@ public class IndexService {
@Autowired @Autowired
private DskOpenApiUtil dskOpenApiUtil; private DskOpenApiUtil dskOpenApiUtil;
public AjaxResult zxzxmqytj(JSONObject object) {
JSONObject page = object.getJSONObject("page");
if(ObjectUtil.isEmpty(page)){
return AjaxResult.error("page对象不能为空");
}
Integer pageIndex = page.getInt("page"),pageSize = page.getInt("limit");
if(ObjectUtil.isEmpty(pageIndex) || ObjectUtil.isEmpty(pageSize)){
return AjaxResult.error("page、limit都不能为空");
}
Map<String, Object> map = dskOpenApiUtil.requestBody("/nationzj/bondProject/companyStatis", object);
return BeanUtil.toBean(map, AjaxResult.class);
}
public AjaxResult zxzxmjctj(JSONObject object) {
JSONObject page = object.getJSONObject("page");
if(ObjectUtil.isEmpty(page)){
return AjaxResult.error("page对象不能为空");
}
Integer pageIndex = page.getInt("page"),pageSize = page.getInt("limit");
if(ObjectUtil.isEmpty(pageIndex) || ObjectUtil.isEmpty(pageSize)){
return AjaxResult.error("page、limit都不能为空");
}
Map<String, Object> map = dskOpenApiUtil.requestBody("/nationzj/bondProject/commonStatis", object);
return BeanUtil.toBean(map, AjaxResult.class);
}
public AjaxResult zxzxmzjetj(JSONObject object) {
JSONObject page = object.getJSONObject("page");
if(ObjectUtil.isEmpty(page)){
return AjaxResult.error("page对象不能为空");
}
Integer pageIndex = page.getInt("page"),pageSize = page.getInt("limit");
if(ObjectUtil.isEmpty(pageIndex) || ObjectUtil.isEmpty(pageSize)){
return AjaxResult.error("page、limit都不能为空");
}
Map<String, Object> map = dskOpenApiUtil.requestBody("/nationzj/bondProject/sumStatis", object);
return BeanUtil.toBean(map, AjaxResult.class);
}
public AjaxResult zdxmqdtopten(JSONObject object) {
JSONObject page = object.getJSONObject("page");
if(ObjectUtil.isEmpty(page)){
return AjaxResult.error("page对象不能为空");
}
Integer pageIndex = page.getInt("page"),pageSize = page.getInt("limit");
if(ObjectUtil.isEmpty(pageIndex) || ObjectUtil.isEmpty(pageSize)){
return AjaxResult.error("page、limit都不能为空");
}
Map<String, Object> map = dskOpenApiUtil.requestBody("/nationzj/bondProject/importantCompanyStatis", object);
return BeanUtil.toBean(map, AjaxResult.class);
}
public AjaxResult zdxmqdjctj(JSONObject object) {
JSONObject page = object.getJSONObject("page");
if(ObjectUtil.isEmpty(page)){
return AjaxResult.error("page对象不能为空");
}
Integer pageIndex = page.getInt("page"),pageSize = page.getInt("limit");
if(ObjectUtil.isEmpty(pageIndex) || ObjectUtil.isEmpty(pageSize)){
return AjaxResult.error("page、limit都不能为空");
}
Map<String, Object> map = dskOpenApiUtil.requestBody("/nationzj/bondProject/importantCommonStatis", object);
return BeanUtil.toBean(map, AjaxResult.class);
}
public AjaxResult zdxmqdzjetj(JSONObject object) {
JSONObject page = object.getJSONObject("page");
if(ObjectUtil.isEmpty(page)){
return AjaxResult.error("page对象不能为空");
}
Integer pageIndex = page.getInt("page"),pageSize = page.getInt("limit");
if(ObjectUtil.isEmpty(pageIndex) || ObjectUtil.isEmpty(pageSize)){
return AjaxResult.error("page、limit都不能为空");
}
Map<String, Object> map = dskOpenApiUtil.requestBody("/nationzj/bondProject/importantSumStatis", object);
return BeanUtil.toBean(map, AjaxResult.class);
}
public AjaxResult zbjhcxtopten(JSONObject object) {
JSONObject page = object.getJSONObject("page");
if(ObjectUtil.isEmpty(page)){
return AjaxResult.error("page对象不能为空");
}
Integer pageIndex = page.getInt("page"),pageSize = page.getInt("limit");
if(ObjectUtil.isEmpty(pageIndex) || ObjectUtil.isEmpty(pageSize)){
return AjaxResult.error("page、limit都不能为空");
}
Map<String, Object> map = dskOpenApiUtil.requestBody("/nationzj/jskBidPlan/companyStatis", object);
return BeanUtil.toBean(map, AjaxResult.class);
}
public AjaxResult zbjhcxjcwdtj(JSONObject object) {
JSONObject page = object.getJSONObject("page");
if(ObjectUtil.isEmpty(page)){
return AjaxResult.error("page对象不能为空");
}
Integer pageIndex = page.getInt("page"),pageSize = page.getInt("limit");
if(ObjectUtil.isEmpty(pageIndex) || ObjectUtil.isEmpty(pageSize)){
return AjaxResult.error("page、limit都不能为空");
}
Map<String, Object> map = dskOpenApiUtil.requestBody("/nationzj/jskBidPlan/commonStatis", object);
return BeanUtil.toBean(map, AjaxResult.class);
}
public AjaxResult zbjhcxzjetj(JSONObject object) {
JSONObject page = object.getJSONObject("page");
if(ObjectUtil.isEmpty(page)){
return AjaxResult.error("page对象不能为空");
}
Integer pageIndex = page.getInt("page"),pageSize = page.getInt("limit");
if(ObjectUtil.isEmpty(pageIndex) || ObjectUtil.isEmpty(pageSize)){
return AjaxResult.error("page、limit都不能为空");
}
Map<String, Object> map = dskOpenApiUtil.requestBody("/nationzj/jskBidPlan/sumStatis", object);
return BeanUtil.toBean(map, AjaxResult.class);
}
public AjaxResult zbggtopten(JSONObject object) {
JSONObject page = object.getJSONObject("page");
if(ObjectUtil.isEmpty(page)){
return AjaxResult.error("page对象不能为空");
}
Integer pageIndex = page.getInt("page"),pageSize = page.getInt("limit");
if(ObjectUtil.isEmpty(pageIndex) || ObjectUtil.isEmpty(pageSize)){
return AjaxResult.error("page、limit都不能为空");
}
Map<String, Object> map = dskOpenApiUtil.requestBody("/nationzj/jskBid/companyStatis", object);
return BeanUtil.toBean(map, AjaxResult.class);
}
public AjaxResult zbggjcwdtj(JSONObject object) {
JSONObject page = object.getJSONObject("page");
if(ObjectUtil.isEmpty(page)){
return AjaxResult.error("page对象不能为空");
}
Integer pageIndex = page.getInt("page"),pageSize = page.getInt("limit");
if(ObjectUtil.isEmpty(pageIndex) || ObjectUtil.isEmpty(pageSize)){
return AjaxResult.error("page、limit都不能为空");
}
Map<String, Object> map = dskOpenApiUtil.requestBody("/nationzj/jskBid/commonStatis", object);
return BeanUtil.toBean(map, AjaxResult.class);
}
public AjaxResult zbggzjetj(JSONObject object) {
JSONObject page = object.getJSONObject("page");
if(ObjectUtil.isEmpty(page)){
return AjaxResult.error("page对象不能为空");
}
Integer pageIndex = page.getInt("page"),pageSize = page.getInt("limit");
if(ObjectUtil.isEmpty(pageIndex) || ObjectUtil.isEmpty(pageSize)){
return AjaxResult.error("page、limit都不能为空");
}
Map<String, Object> map = dskOpenApiUtil.requestBody("/nationzj/jskBid/sumStatis", object);
return BeanUtil.toBean(map, AjaxResult.class);
}
public AjaxResult njtopten(JSONObject object) {
JSONObject page = object.getJSONObject("page");
if(ObjectUtil.isEmpty(page)){
return AjaxResult.error("page对象不能为空");
}
Integer pageIndex = page.getInt("page"),pageSize = page.getInt("limit");
if(ObjectUtil.isEmpty(pageIndex) || ObjectUtil.isEmpty(pageSize)){
return AjaxResult.error("page、limit都不能为空");
}
Map<String, Object> map = dskOpenApiUtil.requestBody("/nationzj/establishment/companyStatis", object);
return BeanUtil.toBean(map, AjaxResult.class);
}
public AjaxResult njjcwdtj(JSONObject object) {
JSONObject page = object.getJSONObject("page");
if(ObjectUtil.isEmpty(page)){
return AjaxResult.error("page对象不能为空");
}
Integer pageIndex = page.getInt("page"),pageSize = page.getInt("limit");
if(ObjectUtil.isEmpty(pageIndex) || ObjectUtil.isEmpty(pageSize)){
return AjaxResult.error("page、limit都不能为空");
}
Map<String, Object> map = dskOpenApiUtil.requestBody("/nationzj/establishment/commonStatis", object);
return BeanUtil.toBean(map, AjaxResult.class);
}
public AjaxResult njzjetj(JSONObject object) {
JSONObject page = object.getJSONObject("page");
if(ObjectUtil.isEmpty(page)){
return AjaxResult.error("page对象不能为空");
}
Integer pageIndex = page.getInt("page"),pageSize = page.getInt("limit");
if(ObjectUtil.isEmpty(pageIndex) || ObjectUtil.isEmpty(pageSize)){
return AjaxResult.error("page、limit都不能为空");
}
Map<String, Object> map = dskOpenApiUtil.requestBody("/nationzj/establishment/sumStatis", object);
return BeanUtil.toBean(map, AjaxResult.class);
}
public AjaxResult topten(JSONObject object) {
JSONObject page = object.getJSONObject("page");
if(ObjectUtil.isEmpty(page)){
return AjaxResult.error("page对象不能为空");
}
Integer pageIndex = page.getInt("page"),pageSize = page.getInt("limit");
if(ObjectUtil.isEmpty(pageIndex) || ObjectUtil.isEmpty(pageSize)){
return AjaxResult.error("page、limit都不能为空");
}
Map<String, Object> map = dskOpenApiUtil.requestBody("/nationzj/landMarket/companyStatis", object);
return BeanUtil.toBean(map, AjaxResult.class);
}
public AjaxResult jcwdtj(JSONObject object) {
JSONObject page = object.getJSONObject("page");
if(ObjectUtil.isEmpty(page)){
return AjaxResult.error("page对象不能为空");
}
Integer pageIndex = page.getInt("page"),pageSize = page.getInt("limit");
if(ObjectUtil.isEmpty(pageIndex) || ObjectUtil.isEmpty(pageSize)){
return AjaxResult.error("page、limit都不能为空");
}
Map<String, Object> map = dskOpenApiUtil.requestBody("/nationzj/landMarket/commonStatis", object);
return BeanUtil.toBean(map, AjaxResult.class);
}
public AjaxResult statisticsOfAmountAndArea(JSONObject object) {
JSONObject page = object.getJSONObject("page");
if(ObjectUtil.isEmpty(page)){
return AjaxResult.error("page对象不能为空");
}
Integer pageIndex = page.getInt("page"),pageSize = page.getInt("limit");
if(ObjectUtil.isEmpty(pageIndex) || ObjectUtil.isEmpty(pageSize)){
return AjaxResult.error("page、limit都不能为空");
}
Map<String, Object> map = dskOpenApiUtil.requestBody("/nationzj/landMarket/sumStatis", object);
return BeanUtil.toBean(map, AjaxResult.class);
}
public AjaxResult bigWinningBidsPage(JSONObject object) { public AjaxResult bigWinningBidsPage(JSONObject object) {
JSONArray recentlyBidQueryDtoList = object.getJSONArray("recentlyBidQueryDto"); JSONArray recentlyBidQueryDtoList = object.getJSONArray("recentlyBidQueryDto");
Map<String, Object> objectMap = new HashMap<>(); Map<String, Object> objectMap = new HashMap<>();
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {
"dev": "vue-cli-service serve", "dev": "vue-cli-service serve",
"devmac": "export NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve",
"build:prod": "vue-cli-service build", "build:prod": "vue-cli-service build",
"build:test": "vue-cli-service build --mode test", "build:test": "vue-cli-service build --mode test",
"build:stage": "vue-cli-service build --mode staging", "build:stage": "vue-cli-service build --mode staging",
......
import request from '@/utils/request' import request from '@/utils/request';
// 登录方法 // 登录方法
export function login(username, password, code, uuid) { export function login(username, password, code, uuid) {
...@@ -7,7 +7,7 @@ export function login(username, password, code, uuid) { ...@@ -7,7 +7,7 @@ export function login(username, password, code, uuid) {
password, password,
code, code,
uuid uuid
} };
return request({ return request({
url: '/login', url: '/login',
headers: { headers: {
...@@ -15,7 +15,7 @@ export function login(username, password, code, uuid) { ...@@ -15,7 +15,7 @@ export function login(username, password, code, uuid) {
}, },
method: 'post', method: 'post',
data: data data: data
}) });
} }
// 注册方法 // 注册方法
...@@ -27,7 +27,7 @@ export function register(data) { ...@@ -27,7 +27,7 @@ export function register(data) {
}, },
method: 'post', method: 'post',
data: data data: data
}) });
} }
// 获取用户详细信息 // 获取用户详细信息
...@@ -35,7 +35,7 @@ export function getInfo() { ...@@ -35,7 +35,7 @@ export function getInfo() {
return request({ return request({
url: '/getInfo', url: '/getInfo',
method: 'get' method: 'get'
}) });
} }
// 退出方法 // 退出方法
...@@ -43,7 +43,7 @@ export function logout() { ...@@ -43,7 +43,7 @@ export function logout() {
return request({ return request({
url: '/logout', url: '/logout',
method: 'post' method: 'post'
}) });
} }
// 获取验证码 // 获取验证码
...@@ -55,7 +55,7 @@ export function getCodeImg() { ...@@ -55,7 +55,7 @@ export function getCodeImg() {
}, },
method: 'get', method: 'get',
timeout: 20000 timeout: 20000
}) });
} }
//获取租户企业列表 //获取租户企业列表
...@@ -63,7 +63,7 @@ export function getTenants() { ...@@ -63,7 +63,7 @@ export function getTenants() {
return request({ return request({
url: '/user/tenants', url: '/user/tenants',
method: 'post', method: 'post',
}) });
} }
// 获取默认租户 // 获取默认租户
...@@ -71,15 +71,15 @@ export function defaultTenantid() { ...@@ -71,15 +71,15 @@ export function defaultTenantid() {
return request({ return request({
url: '/user/default/tenant', url: '/user/default/tenant',
method: 'post', method: 'post',
}) });
} }
// 切换租户 // 切换租户
export function changeTenants(data) { export function changeTenants(data) {
return request({ return request({
url: '/switch/tenant?tenantId='+data, url: '/switch/tenant?tenantId=' + data,
method: 'post', method: 'post',
}) });
} }
//发送短信验证码(删除组织使用) //发送短信验证码(删除组织使用)
...@@ -87,7 +87,7 @@ export function captchaSms() { ...@@ -87,7 +87,7 @@ export function captchaSms() {
return request({ return request({
url: '/getTempSmsCode', url: '/getTempSmsCode',
method: 'get', method: 'get',
}) });
} }
//验证短信验证码(删除组织使用) //验证短信验证码(删除组织使用)
...@@ -95,8 +95,8 @@ export function checkSmsCode(data) { ...@@ -95,8 +95,8 @@ export function checkSmsCode(data) {
return request({ return request({
url: '/checkSmsCode', url: '/checkSmsCode',
method: 'POST', method: 'POST',
params:data params: data
}) });
} }
//根据用户账号获取用户绑定的租户列表 //根据用户账号获取用户绑定的租户列表
...@@ -104,8 +104,8 @@ export function userTenantList(data) { ...@@ -104,8 +104,8 @@ export function userTenantList(data) {
return request({ return request({
url: '/user/tenant/list', url: '/user/tenant/list',
method: 'POST', method: 'POST',
params:data params: data
}) });
} }
//登录获取验证码 //登录获取验证码
...@@ -113,17 +113,29 @@ export function logincaptchaSms(data) { ...@@ -113,17 +113,29 @@ export function logincaptchaSms(data) {
return request({ return request({
url: '/captchaSms', url: '/captchaSms',
method: 'get', method: 'get',
params:data params: data
}) });
} }
//短信登录 //短信登录
export function smsLogin(data) { export function smsLogin(data) {
return request({ return request({
url: '/smsLogin', url: '/smsLogin',
method: 'post', method: 'post',
data:data data: data
}) });
} }
/**
* 第三方植入系统
* @param {string} thirdPlatformKey
* @returns
*/
export const thirdPlatformLoginApi = (thirdPlatformKey) => request({
method: "post",
url: "/thirdPlatformLogin",
data: {
thirdPlatformKey
}
})
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<div class="left-menu" :style="{width: scrollerWidth}"> <div class="left-menu" :style="{width: scrollerWidth}">
<tags-view /> <tags-view />
</div> </div>
<div ref="rightMenu" class="flex-box right-menu"> <div ref="rightMenu" class="flex-box right-menu" v-if="!isThirdPlatformLogin">
<!-- <div class="menu-bells"><img src="@/assets/images/message.png"><i /></div>--> <!-- <div class="menu-bells"><img src="@/assets/images/message.png"><i /></div>-->
<!-- <i class="menu-line" />--> <!-- <i class="menu-line" />-->
<el-dropdown class="avatar-container" trigger="hover" ref="mydrodown" :hide-on-click="false" placement="bottom-start"> <el-dropdown class="avatar-container" trigger="hover" ref="mydrodown" :hide-on-click="false" placement="bottom-start">
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
<script> <script>
import store from "@/store"; import store from "@/store";
import { mapGetters } from 'vuex' import { mapGetters, mapState } from 'vuex'
import elementResizeDetectorMaker from "element-resize-detector" import elementResizeDetectorMaker from "element-resize-detector"
import TagsView from './TagsView' import TagsView from './TagsView'
import { getTenants ,changeTenants} from "@/api/login"; import { getTenants ,changeTenants} from "@/api/login";
...@@ -63,7 +63,10 @@ export default { ...@@ -63,7 +63,10 @@ export default {
'sidebar', 'sidebar',
'avatar', 'avatar',
'name' 'name'
]) ]),
...mapState({
isThirdPlatformLogin : state => state.user.isThirdPlatformLogin
})
}, },
watch: { watch: {
offsetWidth(newValue, oldValue){ offsetWidth(newValue, oldValue){
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<logo v-if="showLogo" :collapse="isCollapse" /> <logo v-if="showLogo" :collapse="isCollapse" />
<el-scrollbar :class="settings.sideTheme" wrap-class="scrollbar-wrapper"> <el-scrollbar :class="settings.sideTheme" wrap-class="scrollbar-wrapper">
<el-menu :default-active="activeMenu" :collapse="isCollapse" :background-color="variables.menuBg" :text-color="variables.menuText" <el-menu :default-active="activeMenu" :collapse="isCollapse" :background-color="variables.menuBg" :text-color="variables.menuText"
:unique-opened="true" :active-text-color="settings.theme" :collapse-transition="false" mode="vertical"> :unique-opened="true" :active-text-color="settings.theme" :collapse-transition="false" mode="vertical" class="left-top-level-menu">
<sidebar-item v-for="(route, index) in hidechildren" :key="route.path + index" :is-collapse="isCollapse" :active-menu="activeMenu" <sidebar-item v-for="(route, index) in hidechildren" :key="route.path + index" :is-collapse="isCollapse" :active-menu="activeMenu"
:item="route" :base-path="route.path" :class="route.fixed&&route.fixed.isFixed?'sideFoot':''" :item="route" :base-path="route.path" :class="route.fixed&&route.fixed.isFixed?'sideFoot':''"
:style="route.fixed&&route.fixed.isFixed?{'bottom': route.fixed.number*50+'px'}: bottomMenu&&index==routes.length-bottomMenu-2?{'padding-bottom': bottomMenu*50+'px'}:''" /> :style="route.fixed&&route.fixed.isFixed?{'bottom': route.fixed.number*50+'px'}: bottomMenu&&index==routes.length-bottomMenu-2?{'padding-bottom': bottomMenu*50+'px'}:''" />
...@@ -91,3 +91,10 @@ export default { ...@@ -91,3 +91,10 @@ export default {
}, },
}; };
</script> </script>
<style lang="scss" scoped>
.left-top-level-menu {
padding: 20px 0px;
box-sizing: border-box;
}
</style>
...@@ -3,14 +3,17 @@ import store from './store'; ...@@ -3,14 +3,17 @@ import store from './store';
import { Message } from 'element-ui'; import { Message } from 'element-ui';
import NProgress from 'nprogress'; import NProgress from 'nprogress';
import 'nprogress/nprogress.css'; import 'nprogress/nprogress.css';
import { getToken } from '@/utils/auth'; import { getToken, getThirdPlatform } from '@/utils/auth';
import { isRelogin } from '@/utils/request'; import { isRelogin } from '@/utils/request';
NProgress.configure({ showSpinner: false }); NProgress.configure({ showSpinner: false });
const whiteList = ['/login', '/register']; const whiteList = ['/login', "/404", "/401"];
router.beforeEach((to, from, next) => { router.beforeEach((to, from, next) => {
// 默认跳转路径 本系统跳转首页,第三方跳转宏观市场
const platFormKey = getThirdPlatform();
let defaultRedirectPath = platFormKey ? "/macro/nationalEconomies" : "/";
NProgress.start(); NProgress.start();
if (getToken()) { if (getToken()) {
// tab页签title // tab页签title
...@@ -20,10 +23,10 @@ router.beforeEach((to, from, next) => { ...@@ -20,10 +23,10 @@ router.beforeEach((to, from, next) => {
to.meta.title && store.dispatch('settings/setTitle', to.meta.title); to.meta.title && store.dispatch('settings/setTitle', to.meta.title);
/* has token*/ /* has token*/
if (to.path === '/login') { if (to.path === '/login') {
next({ path: '/' }); next({ path: defaultRedirectPath });
NProgress.done(); NProgress.done();
} else { } else {
if (store.getters.roles.length === 0) { if (!store.state?.user?.userId && !store.state?.user?.roles?.length) {
isRelogin.show = true; isRelogin.show = true;
// 判断当前用户是否已拉取完user_info信息 // 判断当前用户是否已拉取完user_info信息
store.dispatch('GetInfo').then(() => { store.dispatch('GetInfo').then(() => {
...@@ -34,24 +37,52 @@ router.beforeEach((to, from, next) => { ...@@ -34,24 +37,52 @@ router.beforeEach((to, from, next) => {
next({ ...to, replace: true }); // hack方法 确保addRoutes已完成 next({ ...to, replace: true }); // hack方法 确保addRoutes已完成
}); });
}).catch(err => { }).catch(err => {
store.dispatch('LogOut').then(() => { if (platFormKey) {
Message.error(err); store.dispatch('FedLogOut').then(() => {
sessionStorage.removeItem('views'); next({
next({ path: '/' }); path: "/401",
}); query: {
isSecretFreeLogin: true
}
});
});
} else {
store.dispatch('LogOut').then(() => {
Message.error(err);
sessionStorage.removeItem('views');
next({ path: '/' });
});
}
}); });
} else { } else {
next(); next();
} }
} }
} else { } else {
// 没有token
if (whiteList.indexOf(to.path) !== -1) { if (whiteList.indexOf(to.path) !== -1) {
// 在免登录白名单,直接进入 // 在免登录白名单,直接进入
next(); next();
} else { } else {
next(`/login?redirect=${to.fullPath}`); // 否则全部重定向到登录页 // 非白名单 没有token 判断是否有app key 属于第三方平台
NProgress.done(); // 第三方平台 获取到 platFormKey 直接通过key 登录
if (platFormKey) {
store.dispatch("secretFreeLogin", platFormKey).then((res) => {
next({
path: defaultRedirectPath
});
}).catch(err => {
// appkey 登陆失败 跳转到401
next({
path: "/401",
query: {
isSecretFreeLogin: true
}
});
});
} else {
next(`/login?redirect=${to.fullPath}`); // 否则全部重定向到登录页
NProgress.done();
}
} }
} }
}); });
......
...@@ -47,11 +47,11 @@ export const constantRoutes = [ ...@@ -47,11 +47,11 @@ export const constantRoutes = [
component: () => import('@/views/login'), component: () => import('@/views/login'),
hidden: true hidden: true
}, },
{ // {
path: '/register', // path: '/register',
component: () => import('@/views/register'), // component: () => import('@/views/register'),
hidden: true // hidden: true
}, // },
{ {
path: '/404', path: '/404',
component: () => import('@/views/error/404'), component: () => import('@/views/error/404'),
...@@ -62,33 +62,20 @@ export const constantRoutes = [ ...@@ -62,33 +62,20 @@ export const constantRoutes = [
component: () => import('@/views/error/401'), component: () => import('@/views/error/401'),
hidden: true hidden: true
}, },
{ // {
path: '', // path: '/macro',
component: Layout, // component: Layout,
redirect: 'index', // hidden: true,
children: [ // // redirect: 'urban',
{ // children: [
path: 'index', // {
component: () => import('@/views/index'), // path: 'urban',
name: 'Index', // component: () => import('@/views/macro/urban'),
meta: { title: '首页', icon: 'index', noCache: true } // name: 'Urban',
} // meta: { title: '城投平台', icon: 'macro' }
] // }
}, // ]
{ // },
path: '',
component: Layout,
hidden: true,
redirect: 'urban',
children: [
{
path: '/macro/urban',
component: () => import('@/views/macro/urban'),
name: 'Urban',
meta: { title: '城投平台', icon: 'macro' }
}
]
},
// { // {
// path: '', // path: '',
// component: Layout, // component: Layout,
...@@ -103,20 +90,6 @@ export const constantRoutes = [ ...@@ -103,20 +90,6 @@ export const constantRoutes = [
// } // }
// ] // ]
// }, // },
{
path: '',
component: Layout,
hidden: true,
redirect: 'urban',
children: [
{
path: '/macro/urban',
component: () => import('@/views/macro/urban'),
name: 'Urban',
meta: { title: '城投平台', icon: 'macro' }
}
]
},
{ {
path: '/user', path: '/user',
component: Layout, component: Layout,
...@@ -127,7 +100,7 @@ export const constantRoutes = [ ...@@ -127,7 +100,7 @@ export const constantRoutes = [
path: 'profile', path: 'profile',
component: () => import('@/views/system/user/profile/index'), component: () => import('@/views/system/user/profile/index'),
name: 'Profile', name: 'Profile',
meta: { title: '个人中心', icon: 'user',noCache: true } meta: { title: '个人中心', icon: 'user', noCache: true }
} }
] ]
}, },
...@@ -161,26 +134,26 @@ export const constantRoutes = [ ...@@ -161,26 +134,26 @@ export const constantRoutes = [
] ]
}, },
{ {
path: '', path: '/JumpPage.html',
component: Layout, component: Layout,
hidden: true, hidden: true,
redirect: 'noredirect', redirect: '/JumpPage.html',
children: [ children: [
{ {
path: '/JumpPage.html', path: '',
component: () => import('@/views/detail'), component: () => import('@/views/detail'),
} }
] ]
}, },
//乙方-企业详情 //乙方-企业详情
{ {
path: '/company', path: '/company/:id',
component: Layout, component: Layout,
hidden: true, hidden: true,
redirect: 'noredirect', redirect: '',
children: [ children: [
{ {
path: '/company/:id', path: '',
component: () => import('@/views/detail'), component: () => import('@/views/detail'),
name: 'Company', name: 'Company',
meta: { title: '企业详情' } meta: { title: '企业详情' }
...@@ -189,104 +162,104 @@ export const constantRoutes = [ ...@@ -189,104 +162,104 @@ export const constantRoutes = [
}, },
//企业详情-业绩 //企业详情-业绩
{ {
path: '', path: '/company/:id/performance',
component: Layout, component: Layout,
hidden: true, hidden: true,
redirect: 'noredirect', redirect: '',
children: [ children: [
{ {
path: '/company/:id/performance', path: '',
component: () => import('@/views/detail'), component: () => import('@/views/detail'),
} }
] ]
}, },
//企业详情-人员 //企业详情-人员
{ {
path: '', path: '/company/:id/personnel',
component: Layout, component: Layout,
hidden: true, hidden: true,
redirect: 'noredirect', redirect: '',
children: [ children: [
{ {
path: '/company/:id/personnel', path: '',
component: () => import('@/views/detail'), component: () => import('@/views/detail'),
} }
] ]
}, },
//企业详情-经营信息 //企业详情-经营信息
{ {
path: '', path: '/company/:id/business',
component: Layout, component: Layout,
hidden: true, hidden: true,
redirect: 'noredirect', redirect: '',
children: [ children: [
{ {
path: '/company/:id/business', path: '',
component: () => import('@/views/detail'), component: () => import('@/views/detail'),
} }
] ]
}, },
//企业详情-良好行为 //企业详情-良好行为
{ {
path: '', path: '/company/:id/behavior',
component: Layout, component: Layout,
hidden: true, hidden: true,
redirect: 'noredirect', redirect: '',
children: [ children: [
{ {
path: '/company/:id/behavior', path: '',
component: () => import('@/views/detail'), component: () => import('@/views/detail'),
} }
] ]
}, },
//企业详情-信用评价 //企业详情-信用评价
{ {
path: '', path: '/company/:id/evaluation',
component: Layout, component: Layout,
hidden: true, hidden: true,
redirect: 'noredirect', redirect: '',
children: [ children: [
{ {
path: '/company/:id/evaluation', path: '',
component: () => import('@/views/detail'), component: () => import('@/views/detail'),
} }
] ]
}, },
//企业详情-信用行为 //企业详情-信用行为
{ {
path: '', path: '/company/:id/credit',
component: Layout, component: Layout,
hidden: true, hidden: true,
redirect: 'noredirect', redirect: '',
children: [ children: [
{ {
path: '/company/:id/credit', path: '',
component: () => import('@/views/detail'), component: () => import('@/views/detail'),
} }
] ]
}, },
//企业详情-股权 //企业详情-股权
{ {
path: '', path: '/company/:id/lt',
component: Layout, component: Layout,
hidden: true, hidden: true,
redirect: 'noredirect', redirect: '',
children: [ children: [
{ {
path: '/company/:id/lt', path: '',
component: () => import('@/views/detail'), component: () => import('@/views/detail'),
} }
] ]
}, },
//人员详情 //人员详情
{ {
path: '/personnel', path: '/personnel/:id.html',
component: Layout, component: Layout,
hidden: true, hidden: true,
redirect: 'noredirect', redirect: '',
children: [ children: [
{ {
path: '/personnel/:id.html', path: '',
component: () => import('@/views/detail'), component: () => import('@/views/detail'),
name: 'Personnel', name: 'Personnel',
meta: { title: '人员详情' } meta: { title: '人员详情' }
...@@ -309,13 +282,13 @@ export const constantRoutes = [ ...@@ -309,13 +282,13 @@ export const constantRoutes = [
}, },
//公招市场详情 //公招市场详情
{ {
path: '/gzsc', path: '/gzsc/:id',
component: Layout, component: Layout,
hidden: true, hidden: true,
redirect: 'noredirect', redirect: '',
children: [ children: [
{ {
path: '/gzsc/:id', path: '',
component: () => import('@/views/detail'), component: () => import('@/views/detail'),
name: 'detail-gzsc', name: 'detail-gzsc',
meta: { title: "公招市场详情" } meta: { title: "公招市场详情" }
...@@ -324,221 +297,221 @@ export const constantRoutes = [ ...@@ -324,221 +297,221 @@ export const constantRoutes = [
}, },
//中标业绩详情 //中标业绩详情
{ {
path: '', path: '/performance/zb/:id.html',
component: Layout, component: Layout,
hidden: true, hidden: true,
redirect: 'noredirect', redirect: '',
children: [ children: [
{ {
path: '/performance/zb/:id.html', path: '',
component: () => import('@/views/detail'), component: () => import('@/views/detail'),
} }
] ]
}, },
//荣誉详情 //荣誉详情
{ {
path: '', path: '/honor/:id.html',
component: Layout, component: Layout,
hidden: true, hidden: true,
redirect: 'noredirect', redirect: '',
children: [ children: [
{ {
path: '/honor/:id.html', path: '',
component: () => import('@/views/detail'), component: () => import('@/views/detail'),
} }
] ]
}, },
//标讯Pro-招标公告 //标讯Pro-招标公告
{ {
path: '', path: '/bxpro/:id.html',
component: Layout, component: Layout,
hidden: true, hidden: true,
redirect: 'noredirect', redirect: '',
children: [ children: [
{ {
path: '/bxpro/:id.html', path: '',
component: () => import('@/views/detail'), component: () => import('@/views/detail'),
} }
] ]
}, },
//中标候选人 //中标候选人
{ {
path: '', path: '/zbpro/:id.html',
component: Layout, component: Layout,
hidden: true, hidden: true,
redirect: 'noredirect', redirect: '',
children: [ children: [
{ {
path: '/zbpro/:id.html', path: '',
component: () => import('@/views/detail'), component: () => import('@/views/detail'),
} }
] ]
}, },
//开标记录 //开标记录
{ {
path: '', path: '/biz/tbjl/:id.html',
component: Layout, component: Layout,
hidden: true, hidden: true,
redirect: 'noredirect', redirect: '',
children: [ children: [
{ {
path: '/biz/tbjl/:id.html', path: '',
component: () => import('@/views/detail'), component: () => import('@/views/detail'),
} }
] ]
}, },
//一体化详情 //一体化详情
{ {
path: '', path: '/performance/sjyth/:id.html',
component: Layout, component: Layout,
hidden: true, hidden: true,
redirect: 'noredirect', redirect: '',
children: [ children: [
{ {
path: '/performance/sjyth/:id.html', path: '',
component: () => import('@/views/detail'), component: () => import('@/views/detail'),
} }
] ]
}, },
//一体化详情 //一体化详情
{ {
path: '', path: '/performance/yth/:id.html',
component: Layout, component: Layout,
hidden: true, hidden: true,
redirect: 'noredirect', redirect: '',
children: [ children: [
{ {
path: '/performance/yth/:id.html', path: '',
component: () => import('@/views/detail'), component: () => import('@/views/detail'),
} }
] ]
}, },
//四库详情 //四库详情
{ {
path: '', path: '/performance/sky/:id.html',
component: Layout, component: Layout,
hidden: true, hidden: true,
redirect: 'noredirect', redirect: '',
children: [ children: [
{ {
path: '/performance/sky/:id.html', path: '',
component: () => import('@/views/detail'), component: () => import('@/views/detail'),
} }
] ]
}, },
//公路系统详情 //公路系统详情
{ {
path: '', path: '/performance/glxt/:id.html',
component: Layout, component: Layout,
hidden: true, hidden: true,
redirect: 'noredirect', redirect: '',
children: [ children: [
{ {
path: '/performance/glxt/:id.html', path: '',
component: () => import('@/views/detail'), component: () => import('@/views/detail'),
} }
] ]
}, },
//公路系统详情 //公路系统详情
{ {
path: '', path: '/performance/xmzt/:id.html',
component: Layout, component: Layout,
hidden: true, hidden: true,
redirect: 'noredirect', redirect: '',
children: [ children: [
{ {
path: '/performance/xmzt/:id.html', path: '',
component: () => import('@/views/detail'), component: () => import('@/views/detail'),
} }
] ]
}, },
//水利详情 //水利详情
{ {
path: '', path: '/performance/slyj/:id.html',
component: Layout, component: Layout,
hidden: true, hidden: true,
redirect: 'noredirect', redirect: '',
children: [ children: [
{ {
path: '/performance/slyj/:id.html', path: '',
component: () => import('@/views/detail'), component: () => import('@/views/detail'),
} }
] ]
}, },
//江西住建云详情 //江西住建云详情
{ {
path: '', path: '/performance/jxzjy/:id.html',
component: Layout, component: Layout,
hidden: true, hidden: true,
redirect: 'noredirect', redirect: '',
children: [ children: [
{ {
path: '/performance/jxzjy/:id.html', path: '',
component: () => import('@/views/detail'), component: () => import('@/views/detail'),
} }
] ]
}, },
//北京业绩详情 //北京业绩详情
{ {
path: '', path: '/performance/bj/:id.html',
component: Layout, component: Layout,
hidden: true, hidden: true,
redirect: 'noredirect', redirect: '',
children: [ children: [
{ {
path: '/performance/bj/:id.html', path: '',
component: () => import('@/views/detail'), component: () => import('@/views/detail'),
} }
] ]
}, },
//云南业绩详情 //云南业绩详情
{ {
path: '', path: '/performance/yn/:id.html',
component: Layout, component: Layout,
hidden: true, hidden: true,
redirect: 'noredirect', redirect: '',
children: [ children: [
{ {
path: '/performance/yn/:id.html', path: '',
component: () => import('@/views/detail'), component: () => import('@/views/detail'),
} }
] ]
}, },
//商机-标讯详情 //商机-标讯详情
{ {
path: '', path: '/biz/bx/:id.html',
component: Layout, component: Layout,
hidden: true, hidden: true,
redirect: 'noredirect', redirect: '',
children: [ children: [
{ {
path: '/biz/bx/:id.html', path: '',
component: () => import('@/views/detail'), component: () => import('@/views/detail'),
} }
] ]
}, },
//商机-土地交易详情 //商机-土地交易详情
{ {
path: '', path: '/biz/tdjy/:id.html',
component: Layout, component: Layout,
hidden: true, hidden: true,
redirect: 'noredirect', redirect: '',
children: [ children: [
{ {
path: '/biz/tdjy/:id.html', path: '',
component: () => import('@/views/detail'), component: () => import('@/views/detail'),
} }
] ]
}, },
//商机-拟建项目详情 //商机-拟建项目详情
{ {
path: '', path: '/biz/njxm/:id.html',
component: Layout, component: Layout,
hidden: true, hidden: true,
redirect: 'noredirect', redirect: '',
children: [ children: [
{ {
path: '/biz/njxm/:id.html', path: '',
component: () => import('@/views/detail'), component: () => import('@/views/detail'),
} }
] ]
...@@ -815,6 +788,31 @@ export const dynamicRoutes = [ ...@@ -815,6 +788,31 @@ export const dynamicRoutes = [
} }
]; ];
/**
* 第三方登录首页
*/
export const isThirdPlatformRoutes = [
{
path: '',
component: Layout,
redirect: 'index',
children: [
{
path: 'index',
component: () => import('@/views/index'),
name: 'Index',
meta: { title: '首页', icon: 'index', noCache: true }
}
]
},
{
path: '',
component: Layout,
redirect: '/macro/nationalEconomies',
hidden: true
}
];
// 防止连续点击多次路由报错 // 防止连续点击多次路由报错
let routerPush = Router.prototype.push; let routerPush = Router.prototype.push;
let routerReplace = Router.prototype.replace; let routerReplace = Router.prototype.replace;
......
import auth from '@/plugins/auth'; import auth from '@/plugins/auth';
import router, { constantRoutes, dynamicRoutes } from '@/router'; import router, { constantRoutes, dynamicRoutes, isThirdPlatformRoutes } from '@/router';
import { getRouters } from '@/api/menu'; import { getRouters } from '@/api/menu';
import Layout from '@/layout/index'; import Layout from '@/layout/index';
import ParentView from '@/components/ParentView'; import ParentView from '@/components/ParentView';
...@@ -19,7 +19,7 @@ const permission = { ...@@ -19,7 +19,7 @@ const permission = {
state.routes = constantRoutes.concat(routes); state.routes = constantRoutes.concat(routes);
}, },
SET_DEFAULT_ROUTES: (state, routes) => { SET_DEFAULT_ROUTES: (state, routes) => {
state.defaultRoutes = constantRoutes.concat(routes); state.defaultRoutes = routes;
}, },
SET_TOPBAR_ROUTES: (state, routes) => { SET_TOPBAR_ROUTES: (state, routes) => {
state.topbarRouters = routes; state.topbarRouters = routes;
...@@ -30,21 +30,24 @@ const permission = { ...@@ -30,21 +30,24 @@ const permission = {
}, },
actions: { actions: {
// 生成路由 // 生成路由
GenerateRoutes({ commit }) { GenerateRoutes({ commit, rootState }) {
return new Promise(resolve => { return new Promise(resolve => {
// 向后端请求路由数据 // 向后端请求路由数据
getRouters().then(res => { getRouters().then(res => {
const isThirdPlatformLogin = rootState.user.isThirdPlatformLogin;
let _array = isThirdPlatformLogin ? [isThirdPlatformRoutes[1]] : [isThirdPlatformRoutes[0]];
const sdata = JSON.parse(JSON.stringify(res.data)); const sdata = JSON.parse(JSON.stringify(res.data));
const rdata = JSON.parse(JSON.stringify(res.data)); const rdata = JSON.parse(JSON.stringify(res.data));
const sidebarRoutes = filterAsyncRouter(sdata); const sidebarRoutes = filterAsyncRouter(sdata);
const rewriteRoutes = filterAsyncRouter(rdata, false, true); const rewriteRoutes = filterAsyncRouter(rdata, false, true);
const asyncRoutes = filterDynamicRoutes(dynamicRoutes); const asyncRoutes = filterDynamicRoutes(dynamicRoutes);
rewriteRoutes.unshift(..._array);
rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true }); rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true });
router.addRoutes(asyncRoutes); router.addRoutes(asyncRoutes);
commit('SET_ROUTES', rewriteRoutes); commit('SET_ROUTES', rewriteRoutes);
commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes)); commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(_array).concat(sidebarRoutes));
commit('SET_DEFAULT_ROUTES', sidebarRoutes); commit('SET_DEFAULT_ROUTES', constantRoutes.concat(_array).concat(sidebarRoutes));
commit('SET_TOPBAR_ROUTES', sidebarRoutes); commit('SET_TOPBAR_ROUTES', constantRoutes.concat(_array).concat(sidebarRoutes));
resolve(rewriteRoutes); resolve(rewriteRoutes);
}); });
}); });
......
import { login, logout, getInfo } from '@/api/login'; import { login, logout, getInfo, thirdPlatformLoginApi } from '@/api/login';
import { getToken, setToken, removeToken, setTenantid } from '@/utils/auth'; import { getToken, setToken, removeToken, setTenantid, removeThirdPlatform } from '@/utils/auth';
const user = { const user = {
state: { state: {
...@@ -10,6 +10,7 @@ const user = { ...@@ -10,6 +10,7 @@ const user = {
permissions: [], permissions: [],
userId: '', userId: '',
phonenumber: '', phonenumber: '',
isThirdPlatformLogin: false
}, },
mutations: { mutations: {
...@@ -33,6 +34,9 @@ const user = { ...@@ -33,6 +34,9 @@ const user = {
}, },
SET_USERPHONE: (state, phonenumber) => { SET_USERPHONE: (state, phonenumber) => {
state.phonenumber = phonenumber; state.phonenumber = phonenumber;
},
SET_IS_THIRD_PLATFORM: (state, isThirdPlatformLogin) => {
state.isThirdPlatformLogin = isThirdPlatformLogin ? true : false;
} }
}, },
...@@ -71,6 +75,7 @@ const user = { ...@@ -71,6 +75,7 @@ const user = {
commit('SET_AVATAR', avatar); commit('SET_AVATAR', avatar);
commit('SET_USERID', user.userId); commit('SET_USERID', user.userId);
commit('SET_USERPHONE', user.phonenumber); commit('SET_USERPHONE', user.phonenumber);
commit("SET_IS_THIRD_PLATFORM", res.data.isThirdPlatformLogin);
resolve(res); resolve(res);
}).catch(error => { }).catch(error => {
reject(error); reject(error);
...@@ -97,10 +102,33 @@ const user = { ...@@ -97,10 +102,33 @@ const user = {
FedLogOut({ commit }) { FedLogOut({ commit }) {
return new Promise(resolve => { return new Promise(resolve => {
commit('SET_TOKEN', ''); commit('SET_TOKEN', '');
commit('SET_USERID', "");
commit('SET_ROLES', []);
removeToken(); removeToken();
resolve(); resolve();
}); });
},
// 免密登录 通过appkey登录
async secretFreeLogin({ commit, state }, payload) {
try {
if (!payload) throw new Error("缺少platFormKey");
const tokenInfo = await thirdPlatformLoginApi(payload);
console.log(tokenInfo);
if (tokenInfo.code == 200) {
setToken(tokenInfo.data.token);
commit('SET_TOKEN', tokenInfo.data.token);
setTenantid(tokenInfo.data.tenantId);
return true;
} else {
throw new Error("appkey登录失败");
}
} catch (error) {
throw error;
}
} }
} }
}; };
......
import Cookies from 'js-cookie'; import Cookies from 'js-cookie';
import { getUrlSearchQuery } from '@/utils';
const TokenKey = 'Admin-Token'; const TokenKey = 'Admin-Token';
const Tenantid = 'Tenantid'; const Tenantid = 'Tenantid';
...@@ -30,3 +31,41 @@ export function setBiAuth(token) { ...@@ -30,3 +31,41 @@ export function setBiAuth(token) {
sessionStorage.setItem("DSK_SYSTEM_AUTH_TOKEN", token); sessionStorage.setItem("DSK_SYSTEM_AUTH_TOKEN", token);
return true; return true;
} }
/**
* 获取第三方app key
* @returns
*/
export function getThirdPlatform() {
const platForm = sessionStorage.getItem("PLAT_FORM");
if (platForm) return platForm;
// sessiongStorage 未获取到appkey 寻找url上的参数
const { platFormKey } = getUrlSearchQuery();
if (platFormKey) {
return setThirdPlatform(platFormKey) ? platFormKey : "";
} else {
return "";
};
}
/**
* 储存第三方app key
* @param {*} appkey
* @returns
*/
export function setThirdPlatform(appkey) {
try {
if (!appkey) throw new Error("");
sessionStorage.setItem("PLAT_FORM", appkey);
return true;
} catch (error) {
return false;
}
}
/**
* 移除第三方app key
*/
export function removeThirdPlatform() {
sessionStorage.removeItem("PLAT_FORM");
}
<template> <template>
<div class="errPage-container"> <div class="errPage-container">
<el-button icon="arrow-left" class="pan-back-btn" @click="back"> <el-button icon="arrow-left" class="pan-back-btn" @click="isSecretFreeLogin === false ? back() : aginLogin()">
返回 {{isSecretFreeLogin === false ? "返回" : "重新登录"}}
</el-button> </el-button>
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
...@@ -9,8 +9,8 @@ ...@@ -9,8 +9,8 @@
401错误! 401错误!
</h1> </h1>
<h2>您没有访问权限!</h2> <h2>您没有访问权限!</h2>
<h6>对不起,您没有访问权限,请不要进行非法操作!您可以返回主页面</h6> <h6>对不起,您没有访问权限,请不要进行非法操作!{{isSecretFreeLogin === true ? "您可以尝试使用appkey重新登录系统" : "您可以返回主界面"}}</h6>
<ul class="list-unstyled"> <ul class="list-unstyled" v-if="isSecretFreeLogin === false">
<li class="link-type"> <li class="link-type">
<router-link to="/"> <router-link to="/">
回首页 回首页
...@@ -26,21 +26,46 @@ ...@@ -26,21 +26,46 @@
</template> </template>
<script> <script>
import errGif from '@/assets/images/401/401.gif' import errGif from '@/assets/images/401/401.gif';
import { getThirdPlatform } from "@/utils/auth";
export default { export default {
name: 'Page401', name: 'Page401',
data() { data() {
return { return {
errGif: errGif + '?' + +new Date() errGif: errGif + '?' + +new Date(),
isSecretFreeLogin: null
};
},
created() {
const { isSecretFreeLogin } = this.$route.query;
try {
this.isSecretFreeLogin = JSON.parse(isSecretFreeLogin);
} catch (error) {
} }
}, },
methods: { methods: {
back() { back() {
if (this.$route.query.noGoBack) { if (this.$route.query.noGoBack) {
this.$router.push({ path: '/' }) this.$router.push({ path: '/' });
} else {
this.$router.go(-1);
}
},
aginLogin() {
const platFormKey = getThirdPlatform();
if (platFormKey) {
this.$router.replace({
path: "/",
query: {
platFormKey
}
});
} else { } else {
this.$router.go(-1) this.$router.replace({
path: "/login"
});
} }
} }
} }
...@@ -48,41 +73,44 @@ export default { ...@@ -48,41 +73,44 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.errPage-container { .errPage-container {
width: 800px; width: 800px;
max-width: 100%; max-width: 100%;
margin: 100px auto; margin: 100px auto;
.pan-back-btn { .pan-back-btn {
background: #008489; background: #008489;
color: #fff; color: #fff;
border: none!important; border: none !important;
} }
.pan-gif { .pan-gif {
margin: 0 auto; margin: 0 auto;
display: block; display: block;
} }
.pan-img { .pan-img {
display: block; display: block;
margin: 0 auto; margin: 0 auto;
width: 100%; width: 100%;
} }
.text-jumbo { .text-jumbo {
font-size: 60px; font-size: 60px;
font-weight: 700; font-weight: 700;
color: #484848; color: #484848;
}
.list-unstyled {
font-size: 14px;
li {
padding-bottom: 5px;
} }
.list-unstyled { a {
font-size: 14px; color: #008489;
li { text-decoration: none;
padding-bottom: 5px; &:hover {
} text-decoration: underline;
a {
color: #008489;
text-decoration: none;
&:hover {
text-decoration: underline;
}
} }
} }
} }
h6 {
line-height: 22px;
}
}
</style> </style>
package com.dsk.system.domain; package com.dsk.system.domain;
import com.baomidou.mybatisplus.annotation.*; import com.baomidou.mybatisplus.annotation.*;
import com.dsk.common.annotation.Sensitive; import com.dsk.common.annotation.Sensitive;
import com.dsk.common.constant.UserConstants; import com.dsk.common.constant.UserConstants;
import com.dsk.common.enums.SensitiveStrategy; import com.dsk.common.enums.SensitiveStrategy;
import com.dsk.common.tenant.core.TenantEntity; import com.dsk.common.tenant.core.TenantEntity;
import com.dsk.common.xss.Xss; import com.dsk.common.xss.Xss;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import javax.validation.constraints.Email; import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size; import javax.validation.constraints.Size;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
/** /**
* 用户对象 sys_user * 用户对象 sys_user
* *
* @author Lion Li * @author Lion Li
*/ */
@Data @Data
@NoArgsConstructor @NoArgsConstructor
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@TableName("sys_user") @TableName("sys_user")
public class SysUser extends TenantEntity { public class SysUser extends TenantEntity {
/** /**
* 用户ID * 用户ID
*/ */
@TableId(value = "user_id") @TableId(value = "user_id")
private Long userId; private Long userId;
/** /**
* 部门ID * 三方平台跳转本系统所需秘钥
*/ */
private Long deptId; private String thirdPlatformKey;
/** /**
* 用户账号 * 部门ID
*/ */
@Xss(message = "用户账号不能包含脚本字符") private Long deptId;
@NotBlank(message = "用户账号不能为空")
@Size(min = 0, max = 30, message = "用户账号长度不能超过{max}个字符") /**
private String userName; * 用户账号
*/
/** @Xss(message = "用户账号不能包含脚本字符")
* 用户昵称 @NotBlank(message = "用户账号不能为空")
*/ @Size(min = 0, max = 30, message = "用户账号长度不能超过{max}个字符")
@Xss(message = "用户昵称不能包含脚本字符") private String userName;
@NotBlank(message = "用户昵称不能为空")
@Size(min = 0, max = 30, message = "用户昵称长度不能超过{max}个字符") /**
private String nickName; * 用户昵称
*/
/** @Xss(message = "用户昵称不能包含脚本字符")
* 用户类型(sys_user系统用户) @NotBlank(message = "用户昵称不能为空")
*/ @Size(min = 0, max = 30, message = "用户昵称长度不能超过{max}个字符")
private String userType; private String nickName;
/** /**
* 用户邮箱 * 用户类型(sys_user系统用户)
*/ */
@Sensitive(strategy = SensitiveStrategy.EMAIL) private String userType;
@Email(message = "邮箱格式不正确")
@Size(min = 0, max = 50, message = "邮箱长度不能超过{max}个字符") /**
private String email; * 用户邮箱
*/
/** @Sensitive(strategy = SensitiveStrategy.EMAIL)
* 手机号码 @Email(message = "邮箱格式不正确")
*/ @Size(min = 0, max = 50, message = "邮箱长度不能超过{max}个字符")
@Sensitive(strategy = SensitiveStrategy.PHONE) private String email;
private String phonenumber;
/**
/** * 手机号码
* 用户性别 */
*/ @Sensitive(strategy = SensitiveStrategy.PHONE)
private String sex; private String phonenumber;
/** /**
* 用户头像 * 用户性别
*/ */
private String avatar; private String sex;
/** /**
* 密码 * 用户头像
*/ */
@TableField( private String avatar;
insertStrategy = FieldStrategy.NOT_EMPTY,
updateStrategy = FieldStrategy.NOT_EMPTY, /**
whereStrategy = FieldStrategy.NOT_EMPTY * 密码
) */
private String password; @TableField(
insertStrategy = FieldStrategy.NOT_EMPTY,
@JsonIgnore updateStrategy = FieldStrategy.NOT_EMPTY,
@JsonProperty whereStrategy = FieldStrategy.NOT_EMPTY
public String getPassword() { )
return password; private String password;
}
@JsonIgnore
/** @JsonProperty
* 帐号状态(0正常 1停用) public String getPassword() {
*/ return password;
private String status; }
/** /**
* 删除标志(0代表存在 2代表删除) * 帐号状态(0正常 1停用)
*/ */
@TableLogic private String status;
private String delFlag;
/**
/** * 删除标志(0代表存在 2代表删除)
* 最后登录IP */
*/ @TableLogic
private String loginIp; private String delFlag;
/** /**
* 最后登录时间 * 最后登录IP
*/ */
private Date loginDate; private String loginIp;
/** /**
* 备注 * 最后登录时间
*/ */
private String remark; private Date loginDate;
/** /**
* 创建时间 * 备注
*/ */
private Date createTime; private String remark;
/** /**
* 部门对象 * 创建时间
*/ */
@TableField(exist = false) private Date createTime;
private SysDept dept;
/**
/** * 部门对象
* 角色对象 */
*/ @TableField(exist = false)
@TableField(exist = false) private SysDept dept;
private List<SysRole> roles;
/**
/** * 角色对象
* 角色组 */
*/ @TableField(exist = false)
@TableField(exist = false) private List<SysRole> roles;
private Long[] roleIds;
/**
/** * 角色组
* 岗位组 */
*/ @TableField(exist = false)
@TableField(exist = false) private Long[] roleIds;
private Long[] postIds;
/**
/** * 岗位组
* 数据权限 当前角色ID */
*/ @TableField(exist = false)
@TableField(exist = false) private Long[] postIds;
private Long roleId;
/**
* 数据权限 当前角色ID
public SysUser(Long userId) { */
this.userId = userId; @TableField(exist = false)
} private Long roleId;
public boolean isAdmin() {
return UserConstants.ADMIN_ID.equals(this.userId); public SysUser(Long userId) {
} this.userId = userId;
}
public boolean isSuperAdmin() {
return UserConstants.SUPER_ADMIN_ID.equals(this.userId); public boolean isAdmin() {
} return UserConstants.ADMIN_ID.equals(this.userId);
}
}
public boolean isSuperAdmin() {
return UserConstants.SUPER_ADMIN_ID.equals(this.userId);
}
}
package com.dsk.system.service; package com.dsk.system.service;
import cn.dev33.satoken.exception.NotLoginException; import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.secure.BCrypt; import cn.dev33.satoken.secure.BCrypt;
import cn.dev33.satoken.secure.SaBase64Util; import cn.dev33.satoken.secure.SaBase64Util;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.RegexPool; import cn.hutool.core.lang.RegexPool;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReUtil; import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.dsk.common.constant.Constants;
import com.dsk.common.constant.CacheConstants; import com.dsk.common.constant.GlobalConstants;
import com.dsk.common.constant.Constants; import com.dsk.common.constant.TenantConstants;
import com.dsk.common.constant.GlobalConstants; import com.dsk.common.core.domain.dto.RoleDTO;
import com.dsk.common.constant.TenantConstants; import com.dsk.common.core.domain.event.LogininforEvent;
import com.dsk.common.core.domain.dto.RoleDTO; import com.dsk.common.core.domain.model.LoginBody;
import com.dsk.common.core.domain.event.LogininforEvent; import com.dsk.common.core.domain.model.LoginUser;
import com.dsk.common.core.domain.model.LoginBody; import com.dsk.common.core.domain.model.ThirdPlatformLoginBody;
import com.dsk.common.core.domain.model.LoginUser; import com.dsk.common.core.domain.model.XcxLoginUser;
import com.dsk.common.core.domain.model.XcxLoginUser; import com.dsk.common.enums.DeviceType;
import com.dsk.common.enums.DeviceType; import com.dsk.common.enums.LoginType;
import com.dsk.common.enums.LoginType; import com.dsk.common.enums.TenantStatus;
import com.dsk.common.enums.TenantStatus; import com.dsk.common.enums.UserStatus;
import com.dsk.common.enums.UserStatus; import com.dsk.common.exception.user.CaptchaException;
import com.dsk.common.exception.user.CaptchaException; import com.dsk.common.exception.user.CaptchaExpireException;
import com.dsk.common.exception.user.CaptchaExpireException; import com.dsk.common.exception.user.UserException;
import com.dsk.common.exception.user.UserException; import com.dsk.common.helper.LoginHelper;
import com.dsk.common.helper.LoginHelper; import com.dsk.common.tenant.exception.TenantException;
import com.dsk.common.tenant.exception.TenantException; import com.dsk.common.tenant.helper.TenantHelper;
import com.dsk.common.tenant.helper.TenantBroker; import com.dsk.common.utils.DateUtils;
import com.dsk.common.tenant.helper.TenantHelper; import com.dsk.common.utils.MessageUtils;
import com.dsk.common.utils.DateUtils; import com.dsk.common.utils.ServletUtils;
import com.dsk.common.utils.MessageUtils; import com.dsk.common.utils.StringUtils;
import com.dsk.common.utils.ServletUtils; import com.dsk.common.utils.redis.RedisUtils;
import com.dsk.common.utils.StringUtils; import com.dsk.common.utils.spring.SpringUtils;
import com.dsk.common.utils.redis.RedisUtils; import com.dsk.system.domain.SysUser;
import com.dsk.common.utils.spring.SpringUtils; import com.dsk.system.domain.vo.LoginVo;
import com.dsk.system.domain.SysTenant; import com.dsk.system.domain.vo.SysTenantVo;
import com.dsk.system.domain.SysUser; import com.dsk.system.mapper.SysUserMapper;
import com.dsk.system.domain.vo.LoginVo; import lombok.RequiredArgsConstructor;
import com.dsk.system.domain.vo.SysTenantVo; import lombok.extern.slf4j.Slf4j;
import com.dsk.system.mapper.SysTenantMapper; import org.springframework.beans.factory.annotation.Value;
import com.dsk.system.mapper.SysUserMapper; import org.springframework.stereotype.Service;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import java.time.Duration;
import org.springframework.beans.factory.annotation.Value; import java.util.Date;
import org.springframework.stereotype.Service; import java.util.List;
import java.util.function.Supplier;
import java.time.Duration;
import java.util.Date; /**
import java.util.List; * 登录校验方法
import java.util.function.Supplier; *
* @author Lion Li
/** */
* 登录校验方法 @RequiredArgsConstructor
* @Slf4j
* @author Lion Li @Service
*/ public class SysLoginService {
@RequiredArgsConstructor
@Slf4j private final SysUserMapper userMapper;
@Service private final ISysConfigService configService;
public class SysLoginService { private final SysPermissionService permissionService;
private final ISysTenantService sysTenantService;
private final SysUserMapper userMapper;
private final ISysConfigService configService; @Value("${captcha.enable}")
private final SysPermissionService permissionService; private boolean captchaEnabled;
private final ISysTenantService sysTenantService;
@Value("${user.password.maxRetryCount}")
@Value("${captcha.enable}") private Integer maxRetryCount;
private boolean captchaEnabled;
@Value("${user.password.lockTime}")
@Value("${user.password.maxRetryCount}") private Integer lockTime;
private Integer maxRetryCount;
/**
@Value("${user.password.lockTime}") * 登录验证
private Integer lockTime; *
* @param loginBody 唯一标识
/** * @param ipAddr IP地址
* 登录验证 * @return 结果
* */
* @param loginBody 唯一标识 public LoginVo passwordLogin(LoginBody loginBody, String ipAddr) {
* @param ipAddr IP地址 String tenantId = loginBody.getTenantId();
* @return 结果 String username = loginBody.getUsername();
*/ String password = SaBase64Util.decode(loginBody.getPassword());
public LoginVo passwordLogin(LoginBody loginBody, String ipAddr) { String code = loginBody.getCode();
String tenantId = loginBody.getTenantId(); String uuid = loginBody.getUuid();
String username = loginBody.getUsername(); // 验证码开关
String password = SaBase64Util.decode(loginBody.getPassword()); if (captchaEnabled) {
String code = loginBody.getCode(); validateCaptcha(username, code, uuid);
String uuid = loginBody.getUuid(); }
// 验证码开关
if (captchaEnabled) { if (ReUtil.isMatch(RegexPool.MOBILE, username)) {
validateCaptcha(username, code, uuid); String defaultTenantId = RedisUtils.getCacheObject(GlobalConstants.PHONE_DEFAULT_TENANT + username);
} log.info("登录用户:{} 获取缓存默认租户:" + tenantId, username);
if (StrUtil.isEmpty(tenantId) && StrUtil.isNotBlank(defaultTenantId)) {
if (ReUtil.isMatch(RegexPool.MOBILE, username)) { defaultTenantId = checkDefaultTenant(defaultTenantId, username);
String defaultTenantId = RedisUtils.getCacheObject(GlobalConstants.PHONE_DEFAULT_TENANT + username); tenantId = defaultTenantId;
log.info("登录用户:{} 获取缓存默认租户:" + tenantId, username); }
if (StrUtil.isEmpty(tenantId) && StrUtil.isNotBlank(defaultTenantId)) { }
defaultTenantId = checkDefaultTenant(defaultTenantId, username);
tenantId = defaultTenantId; //查询手机号绑定的所有用户
} if (StrUtil.isEmpty(tenantId)) {
} List<SysUser> sysUsers = queryListByPhone(username);
if (CollectionUtil.isEmpty(sysUsers)) {
//查询手机号绑定的所有用户 log.info("登录用户:{} 不存在.", username);
if (StrUtil.isEmpty(tenantId)) { throw new UserException("user.not.exists", username);
List<SysUser> sysUsers = queryListByPhone(username); } else if (sysUsers.size() > 1) {
if (CollectionUtil.isEmpty(sysUsers)) { //处理存在多个用户的情况,取一个最新租户
log.info("登录用户:{} 不存在.", username); SysUser sysUser = sysUsers.get(0);
throw new UserException("user.not.exists", username); if (ObjectUtil.isEmpty(sysUser)) {
} else if (sysUsers.size() > 1) { log.info("登录用户:{} 不存在.", username);
//处理存在多个用户的情况,取一个最新租户 throw new UserException("user.not.exists", username);
SysUser sysUser = sysUsers.get(0); }
if (ObjectUtil.isEmpty(sysUser)) { tenantId = sysUser.getTenantId();
log.info("登录用户:{} 不存在.", username); } else {
throw new UserException("user.not.exists", username); SysUser sysUser = sysUsers.get(0);
} tenantId = sysUser.getTenantId();
tenantId = sysUser.getTenantId(); }
} else { }
SysUser sysUser = sysUsers.get(0);
tenantId = sysUser.getTenantId(); // 校验租户
} if (tenantId != null) {
} checkTenant(tenantId);
}
// 校验租户 if (tenantId == null || "".equals(tenantId)) {
if (tenantId != null) { tenantId = TenantConstants.DEFAULT_TENANT_ID;
checkTenant(tenantId); }
} TenantHelper.setTenantId(tenantId);
if (tenantId == null || "".equals(tenantId)) { // 框架登录不限制从什么表查询 只要最终构建出 LoginUser 即可
tenantId = TenantConstants.DEFAULT_TENANT_ID; // SysUser user = loadUserByUsername(username);
} // return TenantBroker.applyAs(tenantId, (id -> {
TenantHelper.setTenantId(tenantId);
// 框架登录不限制从什么表查询 只要最终构建出 LoginUser 即可 // 框架登录不限制从什么表查询 只要最终构建出 LoginUser 即可
// SysUser user = loadUserByUsername(username); SysUser user = loadUserByUsername(username);
// return TenantBroker.applyAs(tenantId, (id -> { checkLogin(LoginType.PASSWORD, username, () -> !BCrypt.checkpw(password, user.getPassword()));
// 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了
// 框架登录不限制从什么表查询 只要最终构建出 LoginUser 即可 LoginUser loginUser = buildLoginUser(user);
SysUser user = loadUserByUsername(username); // 生成token
checkLogin(LoginType.PASSWORD, username, () -> !BCrypt.checkpw(password, user.getPassword())); loginUser.setIpaddr(ipAddr);
// 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了 LoginHelper.loginByDevice(loginUser, DeviceType.PC);
LoginUser loginUser = buildLoginUser(user);
// 生成token recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
loginUser.setIpaddr(ipAddr); recordLoginInfo(user.getUserId(), username);
LoginHelper.loginByDevice(loginUser, DeviceType.PC);
// RedisUtils.setCacheObject(GlobalConstants.PHONE_DEFAULT_TENANT + username, TenantHelper.getTenantId(), Duration.ofDays(30));
recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
recordLoginInfo(user.getUserId(), username); LoginVo loginVo = new LoginVo();
loginVo.setTenantId(TenantHelper.getTenantId());
// RedisUtils.setCacheObject(GlobalConstants.PHONE_DEFAULT_TENANT + username, TenantHelper.getTenantId(), Duration.ofDays(30)); loginVo.setAccessToken(StpUtil.getTokenValue());
loginVo.setExpireIn(StpUtil.getTokenTimeout());
LoginVo loginVo = new LoginVo(); return loginVo;
loginVo.setTenantId(TenantHelper.getTenantId()); // }));
loginVo.setAccessToken(StpUtil.getTokenValue()); // return StpUtil.getTokenValue();
loginVo.setExpireIn(StpUtil.getTokenTimeout()); }
return loginVo;
// })); /**
// return StpUtil.getTokenValue(); * 三方平台跳转登录方法
} *
* @param tpLoginBody 登录信息
* @return 结果
/** */
* 登录验证 public LoginVo thirdPlatformLogin(ThirdPlatformLoginBody tpLoginBody, String ipAddr) {
* return TenantHelper.ignore(() -> {
* @param username 用户名 SysUser sysUser = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
* @param password 密码 .eq(SysUser::getThirdPlatformKey, tpLoginBody.getThirdPlatformKey()));
* @param code 验证码
* @param uuid 唯一标识 String tenantId = sysUser.getTenantId();
* @return 结果 String username = sysUser.getUserName();
*/ String password = sysUser.getPassword();
public String login(String username, String password, String code, String uuid) {
boolean captchaEnabled = configService.selectCaptchaEnabled(); if (ReUtil.isMatch(RegexPool.MOBILE, username)) {
// 验证码开关 String defaultTenantId = RedisUtils.getCacheObject(GlobalConstants.PHONE_DEFAULT_TENANT + username);
if (captchaEnabled) { log.info("登录用户:{} 获取缓存默认租户:" + tenantId, username);
validateCaptcha(username, code, uuid); if (StrUtil.isEmpty(tenantId) && StrUtil.isNotBlank(defaultTenantId)) {
} defaultTenantId = checkDefaultTenant(defaultTenantId, username);
// 框架登录不限制从什么表查询 只要最终构建出 LoginUser 即可 tenantId = defaultTenantId;
SysUser user = loadUserByUsername(username); }
checkLogin(LoginType.PASSWORD, username, () -> !BCrypt.checkpw(password, user.getPassword())); }
// 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了
LoginUser loginUser = buildLoginUser(user); //查询手机号绑定的所有用户
// 生成token if (StrUtil.isEmpty(tenantId)) {
LoginHelper.loginByDevice(loginUser, DeviceType.PC); List<SysUser> sysUsers = queryListByPhone(username);
if (CollectionUtil.isEmpty(sysUsers)) {
recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")); log.info("登录用户:{} 不存在.", username);
recordLoginInfo(user.getUserId(), username); throw new UserException("user.not.exists", username);
return StpUtil.getTokenValue(); } else if (sysUsers.size() > 1) {
} //处理存在多个用户的情况,取一个最新租户
SysUser sysUser1 = sysUsers.get(0);
public LoginVo smsLogin(String username, String smsCode) { if (ObjectUtil.isEmpty(sysUser)) {
String tenantId = null; log.info("登录用户:{} 不存在.", username);
if (ReUtil.isMatch(RegexPool.MOBILE, username)) { throw new UserException("user.not.exists", username);
String defaultTenantId = RedisUtils.getCacheObject(GlobalConstants.PHONE_DEFAULT_TENANT + username); }
log.info("登录用户:{} 获取缓存默认租户:" + tenantId, username); tenantId = sysUser1.getTenantId();
if (StrUtil.isNotBlank(defaultTenantId)) { } else {
defaultTenantId = checkDefaultTenant(defaultTenantId, username); SysUser sysUser2 = sysUsers.get(0);
tenantId = defaultTenantId; tenantId = sysUser2.getTenantId();
} }
} }
//查询手机号绑定的所有用户 // 校验租户
if (StrUtil.isEmpty(tenantId)) { if (tenantId != null) {
List<SysUser> sysUsers = queryListByPhone(username); checkTenant(tenantId);
if (CollectionUtil.isEmpty(sysUsers)) { }
log.info("登录用户:{} 不存在.", username); if (tenantId == null || "".equals(tenantId)) {
throw new UserException("user.not.exists", username); tenantId = TenantConstants.DEFAULT_TENANT_ID;
} else if (sysUsers.size() > 1) { }
//处理存在多个用户的情况,取一个最新租户 TenantHelper.setTenantId(tenantId);
SysUser sysUser = sysUsers.get(0);
if (ObjectUtil.isEmpty(sysUser)) { // 框架登录不限制从什么表查询 只要最终构建出 LoginUser 即可
log.info("登录用户:{} 不存在.", username); SysUser user = loadUserByUsername(username);
throw new UserException("user.not.exists", username); //checkLogin(LoginType.PASSWORD, username, () -> !BCrypt.checkpw(password, user.getPassword()));
} // 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了
tenantId = sysUser.getTenantId(); LoginUser loginUser = buildLoginUser(user);
} else { // 生成token
SysUser sysUser = sysUsers.get(0); loginUser.setIpaddr(ipAddr);
tenantId = sysUser.getTenantId(); loginUser.setIsThirdPlatformLogin(true);
} LoginHelper.loginByDevice(loginUser, DeviceType.PC);
}
recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
// 校验租户 recordLoginInfo(user.getUserId(), username);
if (tenantId != null) {
checkTenant(tenantId); LoginVo loginVo = new LoginVo();
} loginVo.setTenantId(TenantHelper.getTenantId());
if (tenantId == null || "".equals(tenantId)) { loginVo.setAccessToken(StpUtil.getTokenValue());
tenantId = TenantConstants.DEFAULT_TENANT_ID; loginVo.setExpireIn(StpUtil.getTokenTimeout());
} return loginVo;
TenantHelper.setTenantId(tenantId); });
// 框架登录不限制从什么表查询 只要最终构建出 LoginUser 即可 }
// SysUser user = loadUserByUsername(username);
// return TenantBroker.applyAs(tenantId, (id -> { /**
* 登录验证
// 框架登录不限制从什么表查询 只要最终构建出 LoginUser 即可 *
SysUser user = loadUserByUsername(username); * @param username 用户名
checkLogin(LoginType.SMS, username, () -> !validateSmsCode(username, smsCode)); * @param password 密码
// 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了 * @param code 验证码
LoginUser loginUser = buildLoginUser(user); * @param uuid 唯一标识
// 生成token * @return 结果
LoginHelper.loginByDevice(loginUser, DeviceType.PC); */
public String login(String username, String password, String code, String uuid) {
recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")); boolean captchaEnabled = configService.selectCaptchaEnabled();
recordLoginInfo(user.getUserId(), username); // 验证码开关
if (captchaEnabled) {
LoginVo loginVo = new LoginVo(); validateCaptcha(username, code, uuid);
loginVo.setTenantId(TenantHelper.getTenantId()); }
loginVo.setAccessToken(StpUtil.getTokenValue()); // 框架登录不限制从什么表查询 只要最终构建出 LoginUser 即可
loginVo.setExpireIn(StpUtil.getTokenTimeout()); SysUser user = loadUserByUsername(username);
return loginVo; checkLogin(LoginType.PASSWORD, username, () -> !BCrypt.checkpw(password, user.getPassword()));
} // 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了
LoginUser loginUser = buildLoginUser(user);
public String emailLogin(String email, String emailCode) { // 生成token
// 通过手邮箱查找用户 LoginHelper.loginByDevice(loginUser, DeviceType.PC);
SysUser user = loadUserByEmail(email);
recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
checkLogin(LoginType.EMAIL, user.getUserName(), () -> !validateEmailCode(email, emailCode)); recordLoginInfo(user.getUserId(), username);
// 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了 return StpUtil.getTokenValue();
LoginUser loginUser = buildLoginUser(user); }
// 生成token
LoginHelper.loginByDevice(loginUser, DeviceType.APP); public LoginVo smsLogin(String username, String smsCode) {
String tenantId = null;
recordLogininfor(user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")); if (ReUtil.isMatch(RegexPool.MOBILE, username)) {
recordLoginInfo(user.getUserId(), user.getUserName()); String defaultTenantId = RedisUtils.getCacheObject(GlobalConstants.PHONE_DEFAULT_TENANT + username);
return StpUtil.getTokenValue(); log.info("登录用户:{} 获取缓存默认租户:" + tenantId, username);
} if (StrUtil.isNotBlank(defaultTenantId)) {
defaultTenantId = checkDefaultTenant(defaultTenantId, username);
public String xcxLogin(String xcxCode) { tenantId = defaultTenantId;
// xcxCode 为 小程序调用 wx.login 授权后获取 }
// todo 以下自行实现 }
// 校验 appid + appsrcret + xcxCode 调用登录凭证校验接口 获取 session_key 与 openid
String openid = ""; //查询手机号绑定的所有用户
if (StrUtil.isEmpty(tenantId)) {
// 框架登录不限制从什么表查询 只要最终构建出 LoginUser 即可 List<SysUser> sysUsers = queryListByPhone(username);
SysUser user = loadUserByOpenid(openid); if (CollectionUtil.isEmpty(sysUsers)) {
log.info("登录用户:{} 不存在.", username);
// 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了 throw new UserException("user.not.exists", username);
XcxLoginUser loginUser = new XcxLoginUser(); } else if (sysUsers.size() > 1) {
loginUser.setUserId(user.getUserId()); //处理存在多个用户的情况,取一个最新租户
loginUser.setUsername(user.getUserName()); SysUser sysUser = sysUsers.get(0);
loginUser.setUserType(user.getUserType()); if (ObjectUtil.isEmpty(sysUser)) {
loginUser.setOpenid(openid); log.info("登录用户:{} 不存在.", username);
// 生成token throw new UserException("user.not.exists", username);
LoginHelper.loginByDevice(loginUser, DeviceType.XCX); }
tenantId = sysUser.getTenantId();
recordLogininfor(user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")); } else {
recordLoginInfo(user.getUserId(), user.getUserName()); SysUser sysUser = sysUsers.get(0);
return StpUtil.getTokenValue(); tenantId = sysUser.getTenantId();
} }
}
/**
* 退出登录 // 校验租户
*/ if (tenantId != null) {
public void logout() { checkTenant(tenantId);
try { }
LoginUser loginUser = LoginHelper.getLoginUser(); if (tenantId == null || "".equals(tenantId)) {
if (TenantHelper.isEnable() && LoginHelper.isSuperAdmin()) { tenantId = TenantConstants.DEFAULT_TENANT_ID;
// 超级管理员 登出清除动态租户 }
TenantHelper.clearDynamic(); TenantHelper.setTenantId(tenantId);
} // 框架登录不限制从什么表查询 只要最终构建出 LoginUser 即可
recordLogininfor(loginUser.getUsername(), Constants.LOGOUT, MessageUtils.message("user.logout.success")); // SysUser user = loadUserByUsername(username);
} catch (NotLoginException ignored) { // return TenantBroker.applyAs(tenantId, (id -> {
} finally {
try { // 框架登录不限制从什么表查询 只要最终构建出 LoginUser 即可
StpUtil.logout(); SysUser user = loadUserByUsername(username);
} catch (NotLoginException ignored) { checkLogin(LoginType.SMS, username, () -> !validateSmsCode(username, smsCode));
} // 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了
} LoginUser loginUser = buildLoginUser(user);
} // 生成token
LoginHelper.loginByDevice(loginUser, DeviceType.PC);
/**
* 记录登录信息 recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
* recordLoginInfo(user.getUserId(), username);
* @param username 用户名
* @param status 状态 LoginVo loginVo = new LoginVo();
* @param message 消息内容 loginVo.setTenantId(TenantHelper.getTenantId());
*/ loginVo.setAccessToken(StpUtil.getTokenValue());
private void recordLogininfor(String username, String status, String message) { loginVo.setExpireIn(StpUtil.getTokenTimeout());
LogininforEvent logininforEvent = new LogininforEvent(); return loginVo;
logininforEvent.setUsername(username); }
logininforEvent.setStatus(status);
logininforEvent.setMessage(message); public String emailLogin(String email, String emailCode) {
logininforEvent.setRequest(ServletUtils.getRequest()); // 通过手邮箱查找用户
SpringUtils.context().publishEvent(logininforEvent); SysUser user = loadUserByEmail(email);
}
checkLogin(LoginType.EMAIL, user.getUserName(), () -> !validateEmailCode(email, emailCode));
/** // 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了
* 校验短信验证码 LoginUser loginUser = buildLoginUser(user);
*/ // 生成token
private boolean validateSmsCode(String phonenumber, String smsCode) { LoginHelper.loginByDevice(loginUser, DeviceType.APP);
String code = RedisUtils.getCacheObject(GlobalConstants.CAPTCHA_CODE_KEY + phonenumber);
if (StringUtils.isBlank(code)) { recordLogininfor(user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
recordLogininfor(phonenumber, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")); recordLoginInfo(user.getUserId(), user.getUserName());
throw new CaptchaExpireException(); return StpUtil.getTokenValue();
} }
return code.equals(smsCode);
} public String xcxLogin(String xcxCode) {
// xcxCode 为 小程序调用 wx.login 授权后获取
/** // todo 以下自行实现
* 校验邮箱验证码 // 校验 appid + appsrcret + xcxCode 调用登录凭证校验接口 获取 session_key 与 openid
*/ String openid = "";
private boolean validateEmailCode(String email, String emailCode) {
String code = RedisUtils.getCacheObject(GlobalConstants.CAPTCHA_CODE_KEY + email); // 框架登录不限制从什么表查询 只要最终构建出 LoginUser 即可
if (StringUtils.isBlank(code)) { SysUser user = loadUserByOpenid(openid);
recordLogininfor(email, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"));
throw new CaptchaExpireException(); // 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了
} XcxLoginUser loginUser = new XcxLoginUser();
return code.equals(emailCode); loginUser.setUserId(user.getUserId());
} loginUser.setUsername(user.getUserName());
loginUser.setUserType(user.getUserType());
/** loginUser.setOpenid(openid);
* 校验验证码 // 生成token
* LoginHelper.loginByDevice(loginUser, DeviceType.XCX);
* @param username 用户名
* @param code 验证码 recordLogininfor(user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
* @param uuid 唯一标识 recordLoginInfo(user.getUserId(), user.getUserName());
*/ return StpUtil.getTokenValue();
public void validateCaptcha(String username, String code, String uuid) { }
String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + StringUtils.defaultString(uuid, "");
String captcha = RedisUtils.getCacheObject(verifyKey); /**
RedisUtils.deleteObject(verifyKey); * 退出登录
if (captcha == null) { */
recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")); public void logout() {
throw new CaptchaExpireException(); try {
} LoginUser loginUser = LoginHelper.getLoginUser();
if (!code.equalsIgnoreCase(captcha)) { if (TenantHelper.isEnable() && LoginHelper.isSuperAdmin()) {
recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")); // 超级管理员 登出清除动态租户
throw new CaptchaException(); TenantHelper.clearDynamic();
} }
} recordLogininfor(loginUser.getUsername(), Constants.LOGOUT, MessageUtils.message("user.logout.success"));
} catch (NotLoginException ignored) {
private SysUser loadUserByUsername(String username) { } finally {
SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>() try {
.select(SysUser::getUserName, SysUser::getStatus) StpUtil.logout();
.eq(SysUser::getUserName, username) } catch (NotLoginException ignored) {
.or().eq(SysUser::getPhonenumber, username)); }
if (ObjectUtil.isNull(user)) { }
log.info("登录用户:{} 不存在.", username); }
throw new UserException("user.not.exists", username);
} else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) { /**
log.info("登录用户:{} 已被停用.", username); * 记录登录信息
throw new UserException("user.blocked", username); *
} * @param username 用户名
return userMapper.selectUserByUserName(user.getUserName()); * @param status 状态
} * @param message 消息内容
*/
private SysUser loadUserByPhonenumber(String phonenumber) { private void recordLogininfor(String username, String status, String message) {
SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>() LogininforEvent logininforEvent = new LogininforEvent();
.select(SysUser::getPhonenumber, SysUser::getStatus) logininforEvent.setUsername(username);
.eq(SysUser::getPhonenumber, phonenumber)); logininforEvent.setStatus(status);
if (ObjectUtil.isNull(user)) { logininforEvent.setMessage(message);
log.info("登录用户:{} 不存在.", phonenumber); logininforEvent.setRequest(ServletUtils.getRequest());
throw new UserException("user.not.exists", phonenumber); SpringUtils.context().publishEvent(logininforEvent);
} else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) { }
log.info("登录用户:{} 已被停用.", phonenumber);
throw new UserException("user.blocked", phonenumber); /**
} * 校验短信验证码
return userMapper.selectUserByPhonenumber(phonenumber); */
} private boolean validateSmsCode(String phonenumber, String smsCode) {
String code = RedisUtils.getCacheObject(GlobalConstants.CAPTCHA_CODE_KEY + phonenumber);
private SysUser loadUserByEmail(String email) { if (StringUtils.isBlank(code)) {
SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>() recordLogininfor(phonenumber, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"));
.select(SysUser::getPhonenumber, SysUser::getStatus) throw new CaptchaExpireException();
.eq(SysUser::getEmail, email)); }
if (ObjectUtil.isNull(user)) { return code.equals(smsCode);
log.info("登录用户:{} 不存在.", email); }
throw new UserException("user.not.exists", email);
} else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) { /**
log.info("登录用户:{} 已被停用.", email); * 校验邮箱验证码
throw new UserException("user.blocked", email); */
} private boolean validateEmailCode(String email, String emailCode) {
return userMapper.selectUserByEmail(email); String code = RedisUtils.getCacheObject(GlobalConstants.CAPTCHA_CODE_KEY + email);
} if (StringUtils.isBlank(code)) {
recordLogininfor(email, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"));
private SysUser loadUserByOpenid(String openid) { throw new CaptchaExpireException();
// 使用 openid 查询绑定用户 如未绑定用户 则根据业务自行处理 例如 创建默认用户 }
// todo 自行实现 userService.selectUserByOpenid(openid); return code.equals(emailCode);
SysUser user = new SysUser(); }
if (ObjectUtil.isNull(user)) {
log.info("登录用户:{} 不存在.", openid); /**
// todo 用户不存在 业务逻辑自行实现 * 校验验证码
} else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) { *
log.info("登录用户:{} 已被停用.", openid); * @param username 用户名
// todo 用户已被停用 业务逻辑自行实现 * @param code 验证码
} * @param uuid 唯一标识
return user; */
} public void validateCaptcha(String username, String code, String uuid) {
String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + StringUtils.defaultString(uuid, "");
/** String captcha = RedisUtils.getCacheObject(verifyKey);
* 构建登录用户 RedisUtils.deleteObject(verifyKey);
*/ if (captcha == null) {
public LoginUser buildLoginUser(SysUser user) { recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"));
LoginUser loginUser = new LoginUser(); throw new CaptchaExpireException();
loginUser.setTenantId(user.getTenantId()); }
loginUser.setUserId(user.getUserId()); if (!code.equalsIgnoreCase(captcha)) {
loginUser.setDeptId(user.getDeptId()); recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error"));
loginUser.setUsername(user.getUserName()); throw new CaptchaException();
loginUser.setNickname(user.getNickName()); }
loginUser.setUserType(user.getUserType()); }
loginUser.setUserPhone(user.getPhonenumber());
loginUser.setMenuPermission(permissionService.getMenuPermission(user.getUserId())); private SysUser loadUserByUsername(String username) {
loginUser.setRolePermission(permissionService.getRolePermission(user.getUserId())); SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
loginUser.setDeptName(ObjectUtil.isNull(user.getDept()) ? "" : user.getDept().getDeptName()); .select(SysUser::getUserName, SysUser::getStatus)
List<RoleDTO> roles = BeanUtil.copyToList(user.getRoles(), RoleDTO.class); .eq(SysUser::getUserName, username)
loginUser.setRoles(roles); .or().eq(SysUser::getPhonenumber, username));
return loginUser; if (ObjectUtil.isNull(user)) {
} log.info("登录用户:{} 不存在.", username);
throw new UserException("user.not.exists", username);
} else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
/** log.info("登录用户:{} 已被停用.", username);
* 记录登录信息 throw new UserException("user.blocked", username);
* }
* @param userId 用户ID return userMapper.selectUserByUserName(user.getUserName());
*/ }
public void recordLoginInfo(Long userId, String username) {
SysUser sysUser = new SysUser(); private SysUser loadUserByPhonenumber(String phonenumber) {
sysUser.setUserId(userId); SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
sysUser.setLoginIp(ServletUtils.getClientIP()); .select(SysUser::getPhonenumber, SysUser::getStatus)
sysUser.setLoginDate(DateUtils.getNowDate()); .eq(SysUser::getPhonenumber, phonenumber));
sysUser.setUpdateBy(username); if (ObjectUtil.isNull(user)) {
userMapper.updateById(sysUser); log.info("登录用户:{} 不存在.", phonenumber);
} throw new UserException("user.not.exists", phonenumber);
} else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
/** log.info("登录用户:{} 已被停用.", phonenumber);
* 登录校验 throw new UserException("user.blocked", phonenumber);
*/ }
private void checkLogin(LoginType loginType, String username, Supplier<Boolean> supplier) { return userMapper.selectUserByPhonenumber(phonenumber);
String errorKey = GlobalConstants.PWD_ERR_CNT_KEY + username; }
String loginFail = Constants.LOGIN_FAIL;
private SysUser loadUserByEmail(String email) {
// 获取用户登录错误次数,默认为0 (可自定义限制策略 例如: key + username + ip) SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
int errorNumber = ObjectUtil.defaultIfNull(RedisUtils.getCacheObject(errorKey), 0); .select(SysUser::getPhonenumber, SysUser::getStatus)
// 锁定时间内登录 则踢出 .eq(SysUser::getEmail, email));
if (errorNumber >= maxRetryCount) { if (ObjectUtil.isNull(user)) {
recordLogininfor(username, loginFail, MessageUtils.message(loginType.getRetryLimitExceed(), maxRetryCount, lockTime)); log.info("登录用户:{} 不存在.", email);
throw new UserException(loginType.getRetryLimitExceed(), maxRetryCount, lockTime); throw new UserException("user.not.exists", email);
} } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
log.info("登录用户:{} 已被停用.", email);
if (supplier.get()) { throw new UserException("user.blocked", email);
// 错误次数递增 }
errorNumber++; return userMapper.selectUserByEmail(email);
RedisUtils.setCacheObject(errorKey, errorNumber, Duration.ofMinutes(lockTime)); }
// 达到规定错误次数 则锁定登录
if (errorNumber >= maxRetryCount) { private SysUser loadUserByOpenid(String openid) {
recordLogininfor(username, loginFail, MessageUtils.message(loginType.getRetryLimitExceed(), maxRetryCount, lockTime)); // 使用 openid 查询绑定用户 如未绑定用户 则根据业务自行处理 例如 创建默认用户
throw new UserException(loginType.getRetryLimitExceed(), maxRetryCount, lockTime); // todo 自行实现 userService.selectUserByOpenid(openid);
} else { SysUser user = new SysUser();
// 未达到规定错误次数 if (ObjectUtil.isNull(user)) {
recordLogininfor(username, loginFail, MessageUtils.message(loginType.getRetryLimitCount(), errorNumber)); log.info("登录用户:{} 不存在.", openid);
throw new UserException(loginType.getRetryLimitCount(), errorNumber); // todo 用户不存在 业务逻辑自行实现
} } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
} log.info("登录用户:{} 已被停用.", openid);
// todo 用户已被停用 业务逻辑自行实现
// 登录成功 清空错误次数 }
RedisUtils.deleteObject(errorKey); return user;
} }
public void checkTenant(String tenantId) { /**
if (!TenantHelper.isEnable()) { * 构建登录用户
return; */
} public LoginUser buildLoginUser(SysUser user) {
if (TenantConstants.DEFAULT_TENANT_ID.equals(tenantId)) { LoginUser loginUser = new LoginUser();
return; loginUser.setTenantId(user.getTenantId());
} loginUser.setUserId(user.getUserId());
SysTenantVo tenant = sysTenantService.queryByTenantId(tenantId); loginUser.setDeptId(user.getDeptId());
if (ObjectUtil.isNull(tenant)) { loginUser.setUsername(user.getUserName());
log.info("登录企业:{} 不存在.", tenantId); loginUser.setNickname(user.getNickName());
throw new TenantException("company.not.exists"); loginUser.setUserType(user.getUserType());
} else if (TenantStatus.DISABLE.getCode().equals(tenant.getStatus())) { loginUser.setUserPhone(user.getPhonenumber());
log.info("登录企业:{} 已被停用.", tenant.getCompanyName()); loginUser.setMenuPermission(permissionService.getMenuPermission(user.getUserId()));
throw new TenantException("company.blocked"); loginUser.setRolePermission(permissionService.getRolePermission(user.getUserId()));
} else if (ObjectUtil.isNotNull(tenant.getExpireTime()) loginUser.setDeptName(ObjectUtil.isNull(user.getDept()) ? "" : user.getDept().getDeptName());
&& new Date().after(tenant.getExpireTime())) { List<RoleDTO> roles = BeanUtil.copyToList(user.getRoles(), RoleDTO.class);
log.info("登录企业:{} 已超过有效期.", tenant.getCompanyName()); loginUser.setRoles(roles);
throw new TenantException("company.expired"); return loginUser;
} }
}
/**
public String checkDefaultTenant(String tenantId, String phoneNumber) { * 记录登录信息
if (!TenantHelper.isEnable()) { *
return null; * @param userId 用户ID
} */
if (TenantConstants.DEFAULT_TENANT_ID.equals(tenantId)) { public void recordLoginInfo(Long userId, String username) {
return null; SysUser sysUser = new SysUser();
} sysUser.setUserId(userId);
SysTenantVo tenant = sysTenantService.queryByTenantId(tenantId); sysUser.setLoginIp(ServletUtils.getClientIP());
if (ObjectUtil.isNull(tenant)) { sysUser.setLoginDate(DateUtils.getNowDate());
log.info("登录企业:{} 不存在.", tenantId); sysUser.setUpdateBy(username);
RedisUtils.deleteObject(GlobalConstants.PHONE_DEFAULT_TENANT + phoneNumber); userMapper.updateById(sysUser);
return null; }
} else if (TenantStatus.DISABLE.getCode().equals(tenant.getStatus())) {
log.info("登录企业:{} 已被停用.", tenant.getCompanyName()); /**
RedisUtils.deleteObject(GlobalConstants.PHONE_DEFAULT_TENANT + phoneNumber); * 登录校验
return null; */
} else if (ObjectUtil.isNotNull(tenant.getExpireTime()) private void checkLogin(LoginType loginType, String username, Supplier<Boolean> supplier) {
&& new Date().after(tenant.getExpireTime())) { String errorKey = GlobalConstants.PWD_ERR_CNT_KEY + username;
log.info("登录企业:{} 已超过有效期.", tenant.getCompanyName()); String loginFail = Constants.LOGIN_FAIL;
RedisUtils.deleteObject(GlobalConstants.PHONE_DEFAULT_TENANT + phoneNumber);
return null; // 获取用户登录错误次数,默认为0 (可自定义限制策略 例如: key + username + ip)
} int errorNumber = ObjectUtil.defaultIfNull(RedisUtils.getCacheObject(errorKey), 0);
return tenantId; // 锁定时间内登录 则踢出
} if (errorNumber >= maxRetryCount) {
recordLogininfor(username, loginFail, MessageUtils.message(loginType.getRetryLimitExceed(), maxRetryCount, lockTime));
throw new UserException(loginType.getRetryLimitExceed(), maxRetryCount, lockTime);
public List<SysTenantVo> tenantListByAccount(String username) { }
return TenantHelper.ignore(() -> sysTenantService.selectTenantList(username));
} if (supplier.get()) {
// 错误次数递增
// public List<SysTenantVo> selectTenantList(String username){ errorNumber++;
// RedisUtils.setCacheObject(errorKey, errorNumber, Duration.ofMinutes(lockTime));
// } // 达到规定错误次数 则锁定登录
if (errorNumber >= maxRetryCount) {
recordLogininfor(username, loginFail, MessageUtils.message(loginType.getRetryLimitExceed(), maxRetryCount, lockTime));
public List<SysUser> queryListByPhone(String username) { throw new UserException(loginType.getRetryLimitExceed(), maxRetryCount, lockTime);
return TenantHelper.ignore(() -> { } else {
List<SysUser> sysUsers = null; // 未达到规定错误次数
if (ReUtil.isMatch(RegexPool.MOBILE, username)) { recordLogininfor(username, loginFail, MessageUtils.message(loginType.getRetryLimitCount(), errorNumber));
throw new UserException(loginType.getRetryLimitCount(), errorNumber);
LambdaQueryWrapper<SysUser> lqw = new LambdaQueryWrapper<SysUser>() }
.select(SysUser::getUserName, SysUser::getStatus, SysUser::getTenantId, SysUser::getDelFlag) }
.eq(SysUser::getPhonenumber, username)
.orderByDesc(SysUser::getUserId); // 登录成功 清空错误次数
// sysUsers = userMapper.selectUserByTenantPhone(username); RedisUtils.deleteObject(errorKey);
sysUsers = userMapper.selectList(lqw); }
} else {
LambdaQueryWrapper<SysUser> lqw = new LambdaQueryWrapper<SysUser>() public void checkTenant(String tenantId) {
.select(SysUser::getUserName, SysUser::getStatus, SysUser::getTenantId) if (!TenantHelper.isEnable()) {
.eq(SysUser::getUserName, username) return;
.orderByDesc(SysUser::getUserId); }
// sysUsers = userMapper.selectUserByTenantUsername(username); if (TenantConstants.DEFAULT_TENANT_ID.equals(tenantId)) {
sysUsers = userMapper.selectList(lqw); return;
} }
return sysUsers; SysTenantVo tenant = sysTenantService.queryByTenantId(tenantId);
}); if (ObjectUtil.isNull(tenant)) {
} log.info("登录企业:{} 不存在.", tenantId);
throw new TenantException("company.not.exists");
} else if (TenantStatus.DISABLE.getCode().equals(tenant.getStatus())) {
public LoginVo switchTenant(String tenantId) { log.info("登录企业:{} 已被停用.", tenant.getCompanyName());
throw new TenantException("company.blocked");
//获取当前登录信息 } else if (ObjectUtil.isNotNull(tenant.getExpireTime())
Long userId = LoginHelper.getUserId(); && new Date().after(tenant.getExpireTime())) {
Assert.notNull(userId, "企业切换失败!"); log.info("登录企业:{} 已超过有效期.", tenant.getCompanyName());
// 如果 切换租户和当前登录租户一致,仅保存默认租户 throw new TenantException("company.expired");
LoginUser loginUserVo = LoginHelper.getLoginUser(); }
if (tenantId.equals(loginUserVo.getTenantId())) { }
//保存当前账号的默认租户
String defaultTenantKey = GlobalConstants.PHONE_DEFAULT_TENANT + loginUserVo.getUserPhone();
RedisUtils.setCacheObject(defaultTenantKey, tenantId, Duration.ofDays(90)); public String checkDefaultTenant(String tenantId, String phoneNumber) {
LoginVo loginVo = new LoginVo(); if (!TenantHelper.isEnable()) {
loginVo.setTenantId(TenantHelper.getTenantId()); return null;
loginVo.setAccessToken(StpUtil.getTokenValue()); }
loginVo.setExpireIn(StpUtil.getTokenTimeout()); if (TenantConstants.DEFAULT_TENANT_ID.equals(tenantId)) {
return loginVo; return null;
} }
SysTenantVo tenant = sysTenantService.queryByTenantId(tenantId);
SysUser sysUser = TenantHelper.ignore(() -> { if (ObjectUtil.isNull(tenant)) {
return userMapper.selectUserById(userId); log.info("登录企业:{} 不存在.", tenantId);
}); RedisUtils.deleteObject(GlobalConstants.PHONE_DEFAULT_TENANT + phoneNumber);
Assert.notNull(sysUser, "用户信息为空,企业切换失败!"); return null;
if (StrUtil.isEmpty(sysUser.getPhonenumber())) { } else if (TenantStatus.DISABLE.getCode().equals(tenant.getStatus())) {
Assert.notNull(sysUser, "用户手机号为空,企业切换失败!"); log.info("登录企业:{} 已被停用.", tenant.getCompanyName());
} RedisUtils.deleteObject(GlobalConstants.PHONE_DEFAULT_TENANT + phoneNumber);
//退出登录 return null;
StpUtil.logout(); } else if (ObjectUtil.isNotNull(tenant.getExpireTime())
String tokenValue = StpUtil.getTokenValueByLoginId(userId); && new Date().after(tenant.getExpireTime())) {
StpUtil.logoutByTokenValue(tokenValue); log.info("登录企业:{} 已超过有效期.", tenant.getCompanyName());
StpUtil.kickoutByTokenValue(tokenValue); RedisUtils.deleteObject(GlobalConstants.PHONE_DEFAULT_TENANT + phoneNumber);
// RedisUtils.deleteKeys("*"+tokenValue+"*"); return null;
}
return tenantId;
//重新登录 }
TenantHelper.setTenantId(tenantId);
String username = sysUser.getPhonenumber();
SysUser user = loadUserByUsername(sysUser.getPhonenumber()); public List<SysTenantVo> tenantListByAccount(String username) {
// 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了 return TenantHelper.ignore(() -> sysTenantService.selectTenantList(username));
LoginUser loginUser = buildLoginUser(user); }
// 生成token
LoginHelper.loginByDevice(loginUser, DeviceType.PC); // public List<SysTenantVo> selectTenantList(String username){
//
// }
log.info("当前租户由" + sysUser.getTenantId() + "切换为" + tenantId);
//保存当前账号的默认租户
String defaultTenantKey = GlobalConstants.PHONE_DEFAULT_TENANT + loginUser.getUserPhone(); public List<SysUser> queryListByPhone(String username) {
RedisUtils.setCacheObject(defaultTenantKey, tenantId, Duration.ofDays(90)); return TenantHelper.ignore(() -> {
recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")); List<SysUser> sysUsers = null;
recordLoginInfo(user.getUserId(), username); if (ReUtil.isMatch(RegexPool.MOBILE, username)) {
LoginVo loginVo = new LoginVo(); LambdaQueryWrapper<SysUser> lqw = new LambdaQueryWrapper<SysUser>()
loginVo.setTenantId(TenantHelper.getTenantId()); .select(SysUser::getUserName, SysUser::getStatus, SysUser::getTenantId, SysUser::getDelFlag)
loginVo.setAccessToken(StpUtil.getTokenValue()); .eq(SysUser::getPhonenumber, username)
loginVo.setExpireIn(StpUtil.getTokenTimeout()); .orderByDesc(SysUser::getUserId);
return loginVo; // sysUsers = userMapper.selectUserByTenantPhone(username);
} sysUsers = userMapper.selectList(lqw);
} } else {
LambdaQueryWrapper<SysUser> lqw = new LambdaQueryWrapper<SysUser>()
.select(SysUser::getUserName, SysUser::getStatus, SysUser::getTenantId)
.eq(SysUser::getUserName, username)
.orderByDesc(SysUser::getUserId);
// sysUsers = userMapper.selectUserByTenantUsername(username);
sysUsers = userMapper.selectList(lqw);
}
return sysUsers;
});
}
public LoginVo switchTenant(String tenantId) {
//获取当前登录信息
Long userId = LoginHelper.getUserId();
Assert.notNull(userId, "企业切换失败!");
// 如果 切换租户和当前登录租户一致,仅保存默认租户
LoginUser loginUserVo = LoginHelper.getLoginUser();
if (tenantId.equals(loginUserVo.getTenantId())) {
//保存当前账号的默认租户
String defaultTenantKey = GlobalConstants.PHONE_DEFAULT_TENANT + loginUserVo.getUserPhone();
RedisUtils.setCacheObject(defaultTenantKey, tenantId, Duration.ofDays(90));
LoginVo loginVo = new LoginVo();
loginVo.setTenantId(TenantHelper.getTenantId());
loginVo.setAccessToken(StpUtil.getTokenValue());
loginVo.setExpireIn(StpUtil.getTokenTimeout());
return loginVo;
}
SysUser sysUser = TenantHelper.ignore(() -> {
return userMapper.selectUserById(userId);
});
Assert.notNull(sysUser, "用户信息为空,企业切换失败!");
if (StrUtil.isEmpty(sysUser.getPhonenumber())) {
Assert.notNull(sysUser, "用户手机号为空,企业切换失败!");
}
//退出登录
StpUtil.logout();
String tokenValue = StpUtil.getTokenValueByLoginId(userId);
StpUtil.logoutByTokenValue(tokenValue);
StpUtil.kickoutByTokenValue(tokenValue);
// RedisUtils.deleteKeys("*"+tokenValue+"*");
//重新登录
TenantHelper.setTenantId(tenantId);
String username = sysUser.getPhonenumber();
SysUser user = loadUserByUsername(sysUser.getPhonenumber());
// 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了
LoginUser loginUser = buildLoginUser(user);
// 生成token
LoginHelper.loginByDevice(loginUser, DeviceType.PC);
log.info("当前租户由" + sysUser.getTenantId() + "切换为" + tenantId);
//保存当前账号的默认租户
String defaultTenantKey = GlobalConstants.PHONE_DEFAULT_TENANT + loginUser.getUserPhone();
RedisUtils.setCacheObject(defaultTenantKey, tenantId, Duration.ofDays(90));
recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
recordLoginInfo(user.getUserId(), username);
LoginVo loginVo = new LoginVo();
loginVo.setTenantId(TenantHelper.getTenantId());
loginVo.setAccessToken(StpUtil.getTokenValue());
loginVo.setExpireIn(StpUtil.getTokenTimeout());
return loginVo;
}
}
package com.dsk.system.service.impl; package com.dsk.system.service.impl;
import cn.dev33.satoken.secure.BCrypt; import cn.dev33.satoken.secure.BCrypt;
import cn.dev33.satoken.session.SaSession; import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.session.TokenSign; import cn.dev33.satoken.session.TokenSign;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dsk.common.constant.CacheNames; import com.dsk.common.constant.CacheNames;
import com.dsk.common.constant.Constants; import com.dsk.common.constant.Constants;
import com.dsk.common.constant.TenantConstants; import com.dsk.common.constant.TenantConstants;
import com.dsk.common.constant.UserConstants; import com.dsk.common.constant.UserConstants;
import com.dsk.common.core.domain.PageQuery; import com.dsk.common.core.domain.PageQuery;
import com.dsk.common.core.domain.entity.SysDictData; import com.dsk.common.core.domain.entity.SysDictData;
import com.dsk.common.core.domain.entity.SysDictType; import com.dsk.common.core.domain.entity.SysDictType;
import com.dsk.common.core.page.TableDataInfo; import com.dsk.common.core.page.TableDataInfo;
import com.dsk.common.enums.UserStatus; import com.dsk.common.enums.UserStatus;
import com.dsk.common.exception.ServiceException; import com.dsk.common.exception.ServiceException;
import com.dsk.common.utils.PasswordUtils; import com.dsk.common.utils.DingTalkUtil;
import com.dsk.common.utils.StringUtils; import com.dsk.common.utils.PasswordUtils;
import com.dsk.common.utils.redis.RedisUtils; import com.dsk.common.utils.StringUtils;
import com.dsk.system.domain.*; import com.dsk.common.utils.redis.RedisUtils;
import com.dsk.system.domain.bo.SysTenantAdminBo; import com.dsk.system.domain.*;
import com.dsk.system.domain.bo.SysTenantBo; import com.dsk.system.domain.bo.SysTenantAdminBo;
import com.dsk.system.domain.vo.SysTenantVo; import com.dsk.system.domain.bo.SysTenantBo;
import com.dsk.system.mapper.*; import com.dsk.system.domain.vo.SysTenantVo;
import com.dsk.system.service.ISysTenantService; import com.dsk.system.mapper.*;
import lombok.RequiredArgsConstructor; import com.dsk.system.service.ISysTenantService;
import lombok.extern.slf4j.Slf4j; import lombok.RequiredArgsConstructor;
import org.dromara.sms4j.api.SmsBlend; import lombok.extern.slf4j.Slf4j;
import org.dromara.sms4j.api.entity.SmsResponse; import org.dromara.sms4j.api.SmsBlend;
import org.dromara.sms4j.core.factory.SmsFactory; import org.dromara.sms4j.api.entity.SmsResponse;
import org.dromara.sms4j.provider.enumerate.SupplierType; import org.dromara.sms4j.core.factory.SmsFactory;
import org.springframework.cache.annotation.CacheEvict; import org.dromara.sms4j.provider.enumerate.SupplierType;
import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service; import org.springframework.cache.annotation.Cacheable;
import org.springframework.transaction.annotation.Transactional; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.*;
/**
* 企业Service业务层处理 /**
* * 企业Service业务层处理
* @author sxk *
* @date 2023.08.22 * @author sxk
*/ * @date 2023.08.22
@RequiredArgsConstructor */
@Service @RequiredArgsConstructor
@Slf4j @Service
public class ISysTenantServiceImpl implements ISysTenantService { @Slf4j
public class ISysTenantServiceImpl implements ISysTenantService {
private final SysTenantMapper baseMapper;
private final SysTenantPackageMapper tenantPackageMapper; private final SysTenantMapper baseMapper;
private final SysRoleMapper roleMapper; private final SysTenantPackageMapper tenantPackageMapper;
private final SysRoleMenuMapper roleMenuMapper; private final SysRoleMapper roleMapper;
private final SysDeptMapper deptMapper; private final SysRoleMenuMapper roleMenuMapper;
private final SysRoleDeptMapper roleDeptMapper; private final SysDeptMapper deptMapper;
private final SysUserMapper userMapper; private final SysRoleDeptMapper roleDeptMapper;
private final SysUserRoleMapper userRoleMapper; private final SysUserMapper userMapper;
private final SysDictTypeMapper dictTypeMapper; private final SysUserRoleMapper userRoleMapper;
private final SysDictDataMapper dictDataMapper; private final SysDictTypeMapper dictTypeMapper;
private final SysConfigMapper configMapper; private final SysDictDataMapper dictDataMapper;
private final SysConfigMapper configMapper;
/**
* 查询租户列表 /**
*/ * 查询租户列表
@Override */
public TableDataInfo<SysTenantVo> queryPageList(SysTenantBo bo, PageQuery pageQuery) { @Override
LambdaQueryWrapper<SysTenant> lqw = buildQueryWrapper(bo); public TableDataInfo<SysTenantVo> queryPageList(SysTenantBo bo, PageQuery pageQuery) {
pageQuery.setIsAsc("desc"); LambdaQueryWrapper<SysTenant> lqw = buildQueryWrapper(bo);
pageQuery.setOrderByColumn("createTime"); pageQuery.setIsAsc("desc");
Page<SysTenantVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); pageQuery.setOrderByColumn("createTime");
for (SysTenantVo sysTenantVo : result.getRecords()) { Page<SysTenantVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
SysTenantPackage sysTenantPackage = tenantPackageMapper.selectById(sysTenantVo.getPackageId()); for (SysTenantVo sysTenantVo : result.getRecords()) {
sysTenantVo.setPackageName(sysTenantPackage.getPackageName()); SysTenantPackage sysTenantPackage = tenantPackageMapper.selectById(sysTenantVo.getPackageId());
} sysTenantVo.setPackageName(sysTenantPackage.getPackageName());
return TableDataInfo.build(result); }
} return TableDataInfo.build(result);
}
/**
* 禁用所有已过期租户 /**
*/ * 禁用所有已过期租户
@Override */
public void handleExpiredTenant() { @Override
Date now = new Date(); public void handleExpiredTenant() {
//查询所有已过期租户 Date now = new Date();
List<SysTenant> tenantList = baseMapper.selectList(new LambdaQueryWrapper<SysTenant>() //查询所有已过期租户
.eq(SysTenant::getStatus, TenantConstants.NORMAL) List<SysTenant> tenantList = baseMapper.selectList(new LambdaQueryWrapper<SysTenant>()
.gt(SysTenant::getStartTime, now) .eq(SysTenant::getStatus, TenantConstants.NORMAL)
.or() .gt(SysTenant::getStartTime, now)
.lt(SysTenant::getExpireTime, now)); .or()
//批量禁用已过期租户 .lt(SysTenant::getExpireTime, now));
if (!tenantList.isEmpty()) { //批量禁用已过期租户
tenantList.forEach(sysTenant -> sysTenant.setStatus(TenantConstants.DISABLE)); if (!tenantList.isEmpty()) {
baseMapper.updateBatchById(tenantList); tenantList.forEach(sysTenant -> sysTenant.setStatus(TenantConstants.DISABLE));
} baseMapper.updateBatchById(tenantList);
} }
}
// /**
// * 查询租户列表 // /**
// */ // * 查询租户列表
// @Override // */
// public List<SysTenantVo> queryList(SysTenantBo bo) { // @Override
// LambdaQueryWrapper<SysTenant> lqw = buildQueryWrapper(bo); // public List<SysTenantVo> queryList(SysTenantBo bo) {
// return baseMapper.selectVoList(lqw); // LambdaQueryWrapper<SysTenant> lqw = buildQueryWrapper(bo);
// } // return baseMapper.selectVoList(lqw);
// }
/**
* 基于租户ID查询租户 /**
*/ * 基于租户ID查询租户
@Cacheable(cacheNames = CacheNames.SYS_TENANT, key = "#tenantId") */
@Override @Cacheable(cacheNames = CacheNames.SYS_TENANT, key = "#tenantId")
public SysTenantVo queryByTenantId(String tenantId) { @Override
return baseMapper.selectVoOne(new LambdaQueryWrapper<SysTenant>().eq(SysTenant::getTenantId, tenantId)); public SysTenantVo queryByTenantId(String tenantId) {
} return baseMapper.selectVoOne(new LambdaQueryWrapper<SysTenant>().eq(SysTenant::getTenantId, tenantId));
}
@Override
public List<SysTenantVo> selectTenantList(String username) { @Override
return baseMapper.selectTenantList(username); public List<SysTenantVo> selectTenantList(String username) {
} return baseMapper.selectTenantList(username);
}
private LambdaQueryWrapper<SysTenant> buildQueryWrapper(SysTenantBo bo) {
LambdaQueryWrapper<SysTenant> lqw = Wrappers.lambdaQuery(); private LambdaQueryWrapper<SysTenant> buildQueryWrapper(SysTenantBo bo) {
lqw.eq(StringUtils.isNotBlank(bo.getTenantId()), SysTenant::getTenantId, bo.getTenantId()); LambdaQueryWrapper<SysTenant> lqw = Wrappers.lambdaQuery();
lqw.like(StringUtils.isNotBlank(bo.getContactUserName()), SysTenant::getContactUserName, bo.getContactUserName()); lqw.eq(StringUtils.isNotBlank(bo.getTenantId()), SysTenant::getTenantId, bo.getTenantId());
lqw.eq(StringUtils.isNotBlank(bo.getContactPhone()), SysTenant::getContactPhone, bo.getContactPhone()); lqw.like(StringUtils.isNotBlank(bo.getContactUserName()), SysTenant::getContactUserName, bo.getContactUserName());
lqw.like(StringUtils.isNotBlank(bo.getCompanyName()), SysTenant::getCompanyName, bo.getCompanyName()); lqw.eq(StringUtils.isNotBlank(bo.getContactPhone()), SysTenant::getContactPhone, bo.getContactPhone());
lqw.eq(StringUtils.isNotBlank(bo.getLicenseNumber()), SysTenant::getLicenseNumber, bo.getLicenseNumber()); lqw.like(StringUtils.isNotBlank(bo.getCompanyName()), SysTenant::getCompanyName, bo.getCompanyName());
lqw.eq(StringUtils.isNotBlank(bo.getAddress()), SysTenant::getAddress, bo.getAddress()); lqw.eq(StringUtils.isNotBlank(bo.getLicenseNumber()), SysTenant::getLicenseNumber, bo.getLicenseNumber());
lqw.eq(StringUtils.isNotBlank(bo.getIntro()), SysTenant::getIntro, bo.getIntro()); lqw.eq(StringUtils.isNotBlank(bo.getAddress()), SysTenant::getAddress, bo.getAddress());
lqw.like(StringUtils.isNotBlank(bo.getDomain()), SysTenant::getDomain, bo.getDomain()); lqw.eq(StringUtils.isNotBlank(bo.getIntro()), SysTenant::getIntro, bo.getIntro());
lqw.eq(bo.getPackageId() != null, SysTenant::getPackageId, bo.getPackageId()); lqw.like(StringUtils.isNotBlank(bo.getDomain()), SysTenant::getDomain, bo.getDomain());
lqw.eq(bo.getExpireTime() != null, SysTenant::getExpireTime, bo.getExpireTime()); lqw.eq(bo.getPackageId() != null, SysTenant::getPackageId, bo.getPackageId());
lqw.eq(bo.getAccountCount() != null, SysTenant::getAccountCount, bo.getAccountCount()); lqw.eq(bo.getExpireTime() != null, SysTenant::getExpireTime, bo.getExpireTime());
lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysTenant::getStatus, bo.getStatus()); lqw.eq(bo.getAccountCount() != null, SysTenant::getAccountCount, bo.getAccountCount());
return lqw; lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysTenant::getStatus, bo.getStatus());
} return lqw;
}
/**
* 查询租户 /**
*/ * 查询租户
@Override */
public SysTenantVo queryById(Long id) { @Override
return baseMapper.selectVoById(id); public SysTenantVo queryById(Long id) {
} return baseMapper.selectVoById(id);
}
/**
* 校验企业名称是否唯一 /**
*/ * 校验企业名称是否唯一
@Override */
public boolean checkCompanyNameUnique(SysTenantBo bo) { @Override
boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysTenant>() public boolean checkCompanyNameUnique(SysTenantBo bo) {
.eq(SysTenant::getCompanyName, bo.getCompanyName()) boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysTenant>()
.ne(ObjectUtil.isNotNull(bo.getTenantId()), SysTenant::getTenantId, bo.getTenantId())); .eq(SysTenant::getCompanyName, bo.getCompanyName())
return !exist; .ne(ObjectUtil.isNotNull(bo.getTenantId()), SysTenant::getTenantId, bo.getTenantId()));
} return !exist;
}
/**
* 新增租户 /**
*/ * 新增租户
@Override */
@Transactional(rollbackFor = Exception.class) @Override
public Boolean insertByBo(SysTenantBo bo) { @Transactional(rollbackFor = Exception.class)
SysTenant add = BeanUtil.toBean(bo, SysTenant.class); public Boolean insertByBo(SysTenantBo bo) {
SysTenant add = BeanUtil.toBean(bo, SysTenant.class);
// 获取所有租户编号
List<String> tenantIds = baseMapper.selectObjs( // 获取所有租户编号
new LambdaQueryWrapper<SysTenant>().select(SysTenant::getTenantId), Convert::toStr); List<String> tenantIds = baseMapper.selectObjs(
String tenantId = generateTenantId(tenantIds); new LambdaQueryWrapper<SysTenant>().select(SysTenant::getTenantId), Convert::toStr);
add.setTenantId(tenantId); String tenantId = generateTenantId(tenantIds);
boolean flag = baseMapper.insert(add) > 0; add.setTenantId(tenantId);
if (!flag) {
throw new ServiceException("创建租户失败"); boolean flag = baseMapper.insert(add) > 0;
} if (!flag) {
bo.setId(add.getId()); throw new ServiceException("创建租户失败");
}
// 根据套餐创建角色 bo.setId(add.getId());
Long roleId = createTenantRole(tenantId, bo.getPackageId(),
TenantConstants.TENANT_SUPER_ADMIN_ROLE_NAME, // 根据套餐创建角色
TenantConstants.TENANT_SUPER_ADMIN_ROLE_KEY); Long roleId = createTenantRole(tenantId, bo.getPackageId(),
TenantConstants.TENANT_SUPER_ADMIN_ROLE_NAME,
// 创建部门: 公司名是部门名称 TenantConstants.TENANT_SUPER_ADMIN_ROLE_KEY);
SysDept dept = new SysDept();
dept.setTenantId(tenantId); // 创建部门: 公司名是部门名称
dept.setDeptName(bo.getCompanyName()); SysDept dept = new SysDept();
dept.setParentId(Constants.TOP_PARENT_ID); dept.setTenantId(tenantId);
dept.setAncestors(Constants.TOP_PARENT_ID.toString()); dept.setDeptName(bo.getCompanyName());
deptMapper.insert(dept); dept.setParentId(Constants.TOP_PARENT_ID);
Long deptId = dept.getDeptId(); dept.setAncestors(Constants.TOP_PARENT_ID.toString());
deptMapper.insert(dept);
// 角色和部门关联表 Long deptId = dept.getDeptId();
SysRoleDept roleDept = new SysRoleDept();
roleDept.setRoleId(roleId); // 角色和部门关联表
roleDept.setDeptId(deptId); SysRoleDept roleDept = new SysRoleDept();
roleDeptMapper.insert(roleDept); roleDept.setRoleId(roleId);
roleDept.setDeptId(deptId);
// 创建系统用户 roleDeptMapper.insert(roleDept);
SysUser user = new SysUser();
user.setTenantId(tenantId); // 创建系统用户
user.setPhonenumber(bo.getContactPhone()); SysUser user = new SysUser();
//默认新增用户名为手机号 user.setTenantId(tenantId);
user.setUserName(bo.getContactPhone()); String thirdPlatformKey = UUID.randomUUID().toString();
user.setNickName(bo.getContactUserName()); user.setThirdPlatformKey(thirdPlatformKey);
//生成8位随机密码 user.setPhonenumber(bo.getContactPhone());
String password = PasswordUtils.generatePwd(8); //默认新增用户名为手机号
user.setPassword(BCrypt.hashpw(password)); user.setUserName(bo.getContactPhone());
user.setDeptId(deptId); user.setNickName(bo.getContactUserName());
user.setCreateTime(new DateTime()); //生成8位随机密码
userMapper.insert(user); String password = PasswordUtils.generatePwd(8);
//新增系统用户后,默认当前用户为部门的负责人 user.setPassword(BCrypt.hashpw(password));
SysDept sd = new SysDept(); user.setDeptId(deptId);
sd.setLeader(String.valueOf(user.getUserId())); user.setCreateTime(new DateTime());
sd.setDeptId(deptId); userMapper.insert(user);
deptMapper.updateById(sd); //新增系统用户后,默认当前用户为部门的负责人
SysDept sd = new SysDept();
// 用户和角色关联表 sd.setLeader(String.valueOf(user.getUserId()));
SysUserRole userRole = new SysUserRole(); sd.setDeptId(deptId);
userRole.setUserId(user.getUserId()); deptMapper.updateById(sd);
userRole.setRoleId(roleId);
userRoleMapper.insert(userRole); // 用户和角色关联表
SysUserRole userRole = new SysUserRole();
String defaultTenantId = TenantConstants.DEFAULT_TENANT_ID; userRole.setUserId(user.getUserId());
List<SysDictType> dictTypeList = dictTypeMapper.selectList( userRole.setRoleId(roleId);
new LambdaQueryWrapper<SysDictType>().eq(SysDictType::getTenantId, defaultTenantId)); userRoleMapper.insert(userRole);
List<SysDictData> dictDataList = dictDataMapper.selectList(
new LambdaQueryWrapper<SysDictData>().eq(SysDictData::getTenantId, defaultTenantId)); String defaultTenantId = TenantConstants.DEFAULT_TENANT_ID;
for (SysDictType dictType : dictTypeList) { List<SysDictType> dictTypeList = dictTypeMapper.selectList(
dictType.setDictId(null); new LambdaQueryWrapper<SysDictType>().eq(SysDictType::getTenantId, defaultTenantId));
dictType.setTenantId(tenantId); List<SysDictData> dictDataList = dictDataMapper.selectList(
} new LambdaQueryWrapper<SysDictData>().eq(SysDictData::getTenantId, defaultTenantId));
for (SysDictData dictData : dictDataList) { for (SysDictType dictType : dictTypeList) {
dictData.setDictCode(null); dictType.setDictId(null);
dictData.setTenantId(tenantId); dictType.setTenantId(tenantId);
} }
dictTypeMapper.insertBatch(dictTypeList); for (SysDictData dictData : dictDataList) {
dictDataMapper.insertBatch(dictDataList); dictData.setDictCode(null);
dictData.setTenantId(tenantId);
List<SysConfig> sysConfigList = configMapper.selectList( }
new LambdaQueryWrapper<SysConfig>() dictTypeMapper.insertBatch(dictTypeList);
.eq(SysConfig::getTenantId, defaultTenantId) dictDataMapper.insertBatch(dictDataList);
.eq(SysConfig::getConfigType, "Y"));
for (SysConfig config : sysConfigList) { List<SysConfig> sysConfigList = configMapper.selectList(
config.setConfigId(null); new LambdaQueryWrapper<SysConfig>()
config.setTenantId(tenantId); .eq(SysConfig::getTenantId, defaultTenantId)
} .eq(SysConfig::getConfigType, "Y"));
configMapper.insertBatch(sysConfigList); for (SysConfig config : sysConfigList) {
config.setConfigId(null);
////此处暂用钉钉机器人模拟发送短信 config.setTenantId(tenantId);
//String content = "【短信通知】:" }
// + bo.getContactUserName() configMapper.insertBatch(sysConfigList);
// + ",您好,您已经成功开通数字化经营管理系统,请使用手机号码登录,初始密码为"
// + password //此处暂用钉钉机器人模拟发送短信
// + "。友情提示:为了您的账号安全,请勿泄露密码。"; String content = "【短信通知】:"
//DingTalkUtil.sendDingTalkMsg(content); + bo.getContactUserName()
+ ",您好,您已经成功开通数字化经营管理系统,请使用手机号码登录,初始密码为"
//租户新增成功,发送短信通知租户 + password
LinkedHashMap<String, String> map = new LinkedHashMap<>(1); + ",三方平台登录秘钥为"
map.put("company", bo.getContactUserName()); + thirdPlatformKey
map.put("pwd", password); + "。友情提示:为了您的账号安全,请勿泄露密码。";
SmsBlend smsBlend = SmsFactory.createSmsBlend(SupplierType.ALIBABA); DingTalkUtil.sendDingTalkMsg(content);
SmsResponse smsResponse = smsBlend.sendMessage(bo.getContactPhone(), "SMS_463175230", map);
if (!"OK".equals(smsResponse.getCode())) { //租户新增成功,发送短信通知租户
log.error("新增租户通知短信发送异常 => {}", smsResponse); LinkedHashMap<String, String> map = new LinkedHashMap<>(1);
} map.put("company", bo.getContactUserName());
return true; map.put("pwd", password);
} SmsBlend smsBlend = SmsFactory.createSmsBlend(SupplierType.ALIBABA);
SmsResponse smsResponse = smsBlend.sendMessage(bo.getContactPhone(), "SMS_463175230", map);
/** if (!"OK".equals(smsResponse.getCode())) {
* 新增企业普通管理员账号 log.error("新增租户通知短信发送异常 => {}", smsResponse);
* }
* @param tenantAdminBo 用户信息 return true;
* @return 结果 }
*/
@Override /**
@Transactional(rollbackFor = Exception.class) * 新增企业普通管理员账号
public Boolean addTenantAdmin(SysTenantAdminBo tenantAdminBo) { *
String tenantId = tenantAdminBo.getTenantId(); * @param tenantAdminBo 用户信息
* @return 结果
//获取部门ID */
Long deptId = deptMapper.selectOne(new LambdaQueryWrapper<SysDept>() @Override
.eq(SysDept::getTenantId, tenantId)).getDeptId(); @Transactional(rollbackFor = Exception.class)
public Boolean addTenantAdmin(SysTenantAdminBo tenantAdminBo) {
SysRole sysRole = roleMapper.selectOne(new LambdaQueryWrapper<SysRole>() String tenantId = tenantAdminBo.getTenantId();
.eq(SysRole::getStatus, UserConstants.ROLE_NORMAL)
.eq(SysRole::getDelFlag, UserConstants.ROLE_NORMAL) //获取部门ID
.eq(SysRole::getTenantId, tenantId) Long deptId = deptMapper.selectOne(new LambdaQueryWrapper<SysDept>()
.eq(SysRole::getRoleKey, TenantConstants.TENANT_ADMIN_ROLE_KEY)); .eq(SysDept::getTenantId, tenantId)).getDeptId();
Long roleId = null; SysRole sysRole = roleMapper.selectOne(new LambdaQueryWrapper<SysRole>()
//校验当前企业是否已存在普通管理员角色 .eq(SysRole::getStatus, UserConstants.ROLE_NORMAL)
if (ObjectUtil.isNull(sysRole)) { .eq(SysRole::getDelFlag, UserConstants.ROLE_NORMAL)
//不存在,则根据套餐创建角色 .eq(SysRole::getTenantId, tenantId)
roleId = createTenantRole(tenantId, tenantAdminBo.getPackageId(), .eq(SysRole::getRoleKey, TenantConstants.TENANT_ADMIN_ROLE_KEY));
TenantConstants.TENANT_ADMIN_ROLE_NAME,
TenantConstants.TENANT_ADMIN_ROLE_KEY); Long roleId = null;
//校验当前企业是否已存在普通管理员角色
// 角色和部门关联表 if (ObjectUtil.isNull(sysRole)) {
SysRoleDept roleDept = new SysRoleDept(); //不存在,则根据套餐创建角色
roleDept.setRoleId(roleId); roleId = createTenantRole(tenantId, tenantAdminBo.getPackageId(),
roleDept.setDeptId(deptId); TenantConstants.TENANT_ADMIN_ROLE_NAME,
roleDeptMapper.insert(roleDept); TenantConstants.TENANT_ADMIN_ROLE_KEY);
} else {
roleId = sysRole.getRoleId(); // 角色和部门关联表
} SysRoleDept roleDept = new SysRoleDept();
roleDept.setRoleId(roleId);
// 创建系统用户 roleDept.setDeptId(deptId);
SysUser user = new SysUser(); roleDeptMapper.insert(roleDept);
user.setTenantId(tenantId); } else {
user.setPhonenumber(tenantAdminBo.getPhonenumber()); roleId = sysRole.getRoleId();
//默认新增用户名为手机号 }
user.setUserName(tenantAdminBo.getPhonenumber());
user.setNickName(tenantAdminBo.getNickName()); // 创建系统用户
//生成8位随机密码 SysUser user = new SysUser();
String password = PasswordUtils.generatePwd(8); user.setTenantId(tenantId);
user.setPassword(BCrypt.hashpw(password)); user.setPhonenumber(tenantAdminBo.getPhonenumber());
user.setDeptId(deptId); //默认新增用户名为手机号
user.setCreateTime(new DateTime()); user.setUserName(tenantAdminBo.getPhonenumber());
userMapper.insert(user); user.setNickName(tenantAdminBo.getNickName());
//生成8位随机密码
// 用户和角色关联表 String password = PasswordUtils.generatePwd(8);
SysUserRole userRole = new SysUserRole(); user.setPassword(BCrypt.hashpw(password));
userRole.setUserId(user.getUserId()); user.setDeptId(deptId);
userRole.setRoleId(roleId); user.setCreateTime(new DateTime());
userRoleMapper.insert(userRole); userMapper.insert(user);
List<SysConfig> sysConfigList = configMapper.selectList( // 用户和角色关联表
new LambdaQueryWrapper<SysConfig>() SysUserRole userRole = new SysUserRole();
.eq(SysConfig::getTenantId, TenantConstants.DEFAULT_TENANT_ID) userRole.setUserId(user.getUserId());
.eq(SysConfig::getConfigType, "Y")); userRole.setRoleId(roleId);
for (SysConfig config : sysConfigList) { userRoleMapper.insert(userRole);
config.setConfigId(null);
config.setTenantId(tenantId); List<SysConfig> sysConfigList = configMapper.selectList(
} new LambdaQueryWrapper<SysConfig>()
configMapper.insertBatch(sysConfigList); .eq(SysConfig::getTenantId, TenantConstants.DEFAULT_TENANT_ID)
.eq(SysConfig::getConfigType, "Y"));
//管理员新增成功,发送短信通知用户 for (SysConfig config : sysConfigList) {
LinkedHashMap<String, String> map = new LinkedHashMap<>(1); config.setConfigId(null);
map.put("company", tenantAdminBo.getNickName()); config.setTenantId(tenantId);
map.put("pwd", password); }
SmsBlend smsBlend = SmsFactory.createSmsBlend(SupplierType.ALIBABA); configMapper.insertBatch(sysConfigList);
SmsResponse smsResponse = smsBlend.sendMessage(tenantAdminBo.getPhonenumber(), "SMS_463175230", map);
if (!"OK".equals(smsResponse.getCode())) { //管理员新增成功,发送短信通知用户
log.error("新增租户通知短信发送异常 => {}", smsResponse); LinkedHashMap<String, String> map = new LinkedHashMap<>(1);
} map.put("company", tenantAdminBo.getNickName());
return true; map.put("pwd", password);
} SmsBlend smsBlend = SmsFactory.createSmsBlend(SupplierType.ALIBABA);
SmsResponse smsResponse = smsBlend.sendMessage(tenantAdminBo.getPhonenumber(), "SMS_463175230", map);
/** if (!"OK".equals(smsResponse.getCode())) {
* 生成租户id log.error("新增租户通知短信发送异常 => {}", smsResponse);
* }
* @param tenantIds 已有租户id列表 return true;
* @return 租户id }
*/
private String generateTenantId(List<String> tenantIds) { /**
// 随机生成6位 * 生成租户id
String numbers = RandomUtil.randomNumbers(6); *
// 判断是否存在,如果存在则重新生成 * @param tenantIds 已有租户id列表
if (tenantIds.contains(numbers)) { * @return 租户id
generateTenantId(tenantIds); */
} private String generateTenantId(List<String> tenantIds) {
return numbers; // 随机生成6位
} String numbers = RandomUtil.randomNumbers(6);
// 判断是否存在,如果存在则重新生成
/** if (tenantIds.contains(numbers)) {
* 根据租户菜单创建租户角色 generateTenantId(tenantIds);
* }
* @param tenantId 租户编号 return numbers;
* @param packageId 租户套餐id }
* @return 角色id
*/ /**
private Long createTenantRole(String tenantId, Long packageId, String roleName, String roleKey) { * 根据租户菜单创建租户角色
// 获取租户套餐 *
SysTenantPackage tenantPackage = tenantPackageMapper.selectById(packageId); * @param tenantId 租户编号
if (ObjectUtil.isNull(tenantPackage)) { * @param packageId 租户套餐id
throw new ServiceException("套餐不存在"); * @return 角色id
} */
// 获取套餐菜单id private Long createTenantRole(String tenantId, Long packageId, String roleName, String roleKey) {
List<Long> menuIds = StringUtils.splitTo(tenantPackage.getMenuIds(), Convert::toLong); // 获取租户套餐
SysTenantPackage tenantPackage = tenantPackageMapper.selectById(packageId);
// 创建角色 if (ObjectUtil.isNull(tenantPackage)) {
SysRole role = new SysRole(); throw new ServiceException("套餐不存在");
role.setTenantId(tenantId); }
role.setRoleName(roleName); // 获取套餐菜单id
role.setRoleKey(roleKey); List<Long> menuIds = StringUtils.splitTo(tenantPackage.getMenuIds(), Convert::toLong);
role.setRoleSort(1);
role.setStatus(TenantConstants.NORMAL); // 创建角色
roleMapper.insert(role); SysRole role = new SysRole();
Long roleId = role.getRoleId(); role.setTenantId(tenantId);
role.setRoleName(roleName);
// 创建角色菜单 role.setRoleKey(roleKey);
List<SysRoleMenu> roleMenus = new ArrayList<>(menuIds.size()); role.setRoleSort(1);
menuIds.forEach(menuId -> { role.setStatus(TenantConstants.NORMAL);
SysRoleMenu roleMenu = new SysRoleMenu(); roleMapper.insert(role);
roleMenu.setRoleId(roleId); Long roleId = role.getRoleId();
roleMenu.setMenuId(menuId);
roleMenus.add(roleMenu); // 创建角色菜单
}); List<SysRoleMenu> roleMenus = new ArrayList<>(menuIds.size());
roleMenuMapper.insertBatch(roleMenus); menuIds.forEach(menuId -> {
SysRoleMenu roleMenu = new SysRoleMenu();
return roleId; roleMenu.setRoleId(roleId);
} roleMenu.setMenuId(menuId);
roleMenus.add(roleMenu);
/** });
* 校验租户是否允许操作 roleMenuMapper.insertBatch(roleMenus);
*
* @param tenantId 租户ID return roleId;
*/ }
@Override
public void checkTenantAllowed(String tenantId) { /**
if (ObjectUtil.isNotNull(tenantId) && TenantConstants.DEFAULT_TENANT_ID.equals(tenantId)) { * 校验租户是否允许操作
throw new ServiceException("不允许操作管理租户"); *
} * @param tenantId 租户ID
} */
@Override
/** public void checkTenantAllowed(String tenantId) {
* 修改租户 if (ObjectUtil.isNotNull(tenantId) && TenantConstants.DEFAULT_TENANT_ID.equals(tenantId)) {
*/ throw new ServiceException("不允许操作管理租户");
@Override }
@CacheEvict(cacheNames = CacheNames.SYS_TENANT, key = "#bo.tenantId") }
public Boolean updateByBo(SysTenantBo bo) {
SysTenant tenant = BeanUtil.toBean(bo, SysTenant.class); /**
if (TenantConstants.DISABLE.equals(bo.getStatus())) { * 修改租户
tenant.setExpireTime(new DateTime()); */
} @Override
tenant.setTenantId(null); @CacheEvict(cacheNames = CacheNames.SYS_TENANT, key = "#bo.tenantId")
return baseMapper.updateById(tenant) > 0; public Boolean updateByBo(SysTenantBo bo) {
} SysTenant tenant = BeanUtil.toBean(bo, SysTenant.class);
if (TenantConstants.DISABLE.equals(bo.getStatus())) {
// /** tenant.setExpireTime(new DateTime());
// * 修改租户状态 }
// * tenant.setTenantId(null);
// * @param bo 租户信息 return baseMapper.updateById(tenant) > 0;
// * @return 结果 }
// */
// @Override // /**
// @CacheEvict(cacheNames = CacheNames.SYS_TENANT, key = "#bo.tenantId") // * 修改租户状态
// public int updateTenantStatus(SysTenantBo bo) { // *
// SysTenant tenant = MapStructUtils.convert(bo, SysTenant.class); // * @param bo 租户信息
// return baseMapper.updateById(tenant); // * @return 结果
// } // */
// @Override
/** // @CacheEvict(cacheNames = CacheNames.SYS_TENANT, key = "#bo.tenantId")
* 校验并批量删除租户信息 // public int updateTenantStatus(SysTenantBo bo) {
*/ // SysTenant tenant = MapStructUtils.convert(bo, SysTenant.class);
@Override // return baseMapper.updateById(tenant);
@CacheEvict(cacheNames = CacheNames.SYS_TENANT, allEntries = true) // }
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) { /**
// 做一些业务上的校验,判断是否需要校验 * 校验并批量删除租户信息
if (ids.contains(TenantConstants.SUPER_ADMIN_ID)) { */
throw new ServiceException("超管租户不能删除"); @Override
} @CacheEvict(cacheNames = CacheNames.SYS_TENANT, allEntries = true)
} public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
return baseMapper.deleteBatchIds(ids) > 0; if (isValid) {
} // 做一些业务上的校验,判断是否需要校验
if (ids.contains(TenantConstants.SUPER_ADMIN_ID)) {
@Override throw new ServiceException("超管租户不能删除");
@Transactional(rollbackFor = Exception.class) }
public Boolean syncTenantPackage(String tenantId, Long packageId) { }
SysTenantPackage tenantPackage = tenantPackageMapper.selectById(packageId); return baseMapper.deleteBatchIds(ids) > 0;
List<SysRole> roles = roleMapper.selectList( }
new LambdaQueryWrapper<SysRole>().eq(SysRole::getTenantId, tenantId));
List<Long> roleIds = new ArrayList<>(roles.size() - 1); @Override
List<Long> menuIds = StringUtils.splitTo(tenantPackage.getMenuIds(), Convert::toLong); @Transactional(rollbackFor = Exception.class)
roles.forEach(item -> { public Boolean syncTenantPackage(String tenantId, Long packageId) {
if (TenantConstants.TENANT_SUPER_ADMIN_ROLE_KEY.equals(item.getRoleKey())) { SysTenantPackage tenantPackage = tenantPackageMapper.selectById(packageId);
List<SysRoleMenu> roleMenus = new ArrayList<>(menuIds.size()); List<SysRole> roles = roleMapper.selectList(
menuIds.forEach(menuId -> { new LambdaQueryWrapper<SysRole>().eq(SysRole::getTenantId, tenantId));
SysRoleMenu roleMenu = new SysRoleMenu(); List<Long> roleIds = new ArrayList<>(roles.size() - 1);
roleMenu.setRoleId(item.getRoleId()); List<Long> menuIds = StringUtils.splitTo(tenantPackage.getMenuIds(), Convert::toLong);
roleMenu.setMenuId(menuId); roles.forEach(item -> {
roleMenus.add(roleMenu); if (TenantConstants.TENANT_SUPER_ADMIN_ROLE_KEY.equals(item.getRoleKey())) {
}); List<SysRoleMenu> roleMenus = new ArrayList<>(menuIds.size());
roleMenuMapper.delete(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getRoleId, item.getRoleId())); menuIds.forEach(menuId -> {
roleMenuMapper.insertBatch(roleMenus); SysRoleMenu roleMenu = new SysRoleMenu();
} else { roleMenu.setRoleId(item.getRoleId());
roleIds.add(item.getRoleId()); roleMenu.setMenuId(menuId);
} roleMenus.add(roleMenu);
}); });
if (!roleIds.isEmpty()) { roleMenuMapper.delete(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getRoleId, item.getRoleId()));
roleMenuMapper.delete( roleMenuMapper.insertBatch(roleMenus);
new LambdaQueryWrapper<SysRoleMenu>().in(SysRoleMenu::getRoleId, roleIds).notIn(!menuIds.isEmpty(), SysRoleMenu::getMenuId, menuIds)); } else {
} roleIds.add(item.getRoleId());
try { }
//清除企业用户登录信息 });
List<SysUser> tenantUsers = userMapper.selectList(Wrappers.<SysUser>lambdaQuery() if (!roleIds.isEmpty()) {
.eq(SysUser::getTenantId, tenantId).eq(SysUser::getStatus, UserStatus.OK.getCode())); roleMenuMapper.delete(
if (!CollectionUtils.isEmpty(tenantUsers)) { new LambdaQueryWrapper<SysRoleMenu>().in(SysRoleMenu::getRoleId, roleIds).notIn(!menuIds.isEmpty(), SysRoleMenu::getMenuId, menuIds));
for (SysUser tenantUser : tenantUsers) { }
String key = "global:Authorization:login:session:00:" + tenantUser.getUserId(); try {
if (RedisUtils.hasKey(key)) { //清除企业用户登录信息
SaSession session = RedisUtils.getCacheObject(key); List<SysUser> tenantUsers = userMapper.selectList(Wrappers.<SysUser>lambdaQuery()
List<TokenSign> tokenSignList = session.getTokenSignList(); .eq(SysUser::getTenantId, tenantId).eq(SysUser::getStatus, UserStatus.OK.getCode()));
tokenSignList.forEach(sign -> StpUtil.kickoutByTokenValue(sign.getValue())); if (!CollectionUtils.isEmpty(tenantUsers)) {
} for (SysUser tenantUser : tenantUsers) {
} String key = "global:Authorization:login:session:00:" + tenantUser.getUserId();
} if (RedisUtils.hasKey(key)) {
} catch (Exception e) { SaSession session = RedisUtils.getCacheObject(key);
log.error("清除企业用户登录信息操作失败!error={}", e.getMessage()); List<TokenSign> tokenSignList = session.getTokenSignList();
} tokenSignList.forEach(sign -> StpUtil.kickoutByTokenValue(sign.getValue()));
}
return true; }
} }
} catch (Exception e) {
log.error("清除企业用户登录信息操作失败!error={}", e.getMessage());
} }
return true;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment