身份切换

master
lzq 2025-12-17 13:44:19 +08:00
parent 0c56b84a4a
commit 87506c36c3
18 changed files with 313 additions and 13 deletions

View File

@ -4,6 +4,8 @@ public interface ITokenService {
void saveToken(UserDetail userDetail);
void updateToken(UserDetail userDetail);
UserDetail loadUser(String tokenStr);
void removeToken(Token token);

View File

@ -42,9 +42,16 @@ public class UserDetail implements CredentialsContainer, Principal {
* Id
*/
private Long accountId;
private Long tenantId;
/**
*
*/
private Integer clientCode;
/**
*
*/
private Integer client;
private Long tenantId;
private String tenantName;
/**
*

View File

@ -54,7 +54,22 @@ public class SecurityUtil {
SpringUtil.getBean(ITokenService.class).saveToken(userDetail);
}
/**
* TOKEN
*
* @param userDetail
*/
public static UserDetail registrationUser(UserDetail userDetail) {
SpringUtil.getBean(ITokenService.class).updateToken(userDetail);
return userDetail;
}
/**
* TOKEN
*
* @param userDetail
*/
public static UserDetail updateUser(UserDetail userDetail) {
Token token = Token.of(userDetail.getUserId(), userDetail.getAccountId(), userDetail.getAuthWay());
userDetail.setToken(token);
saveToken(userDetail);

View File

@ -13,12 +13,12 @@ import lombok.RequiredArgsConstructor;
public enum IdentityCategory implements DictStr {
PingTai("PingTai", "平台"),
XiaoNa("XiaoNa", "消纳方"),
ChanFei("ChanFei", "产废方"),
YunShu("YunShu", "运输方"),
XiaoNa("XiaoNa", "消纳方"),
CaiGou("CaiGou", "采购方"),
SiJi("SiJi", "司机"),

View File

@ -10,6 +10,7 @@ import com.njzscloud.dispose.cst.customer.pojo.param.AddCustomerParam;
import com.njzscloud.dispose.cst.customer.pojo.param.SearchCustomerParam;
import com.njzscloud.dispose.cst.customer.pojo.result.SearchCustomerResult;
import com.njzscloud.dispose.cst.customer.service.CustomerService;
import com.njzscloud.dispose.sys.auth.pojo.result.MyResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
@ -44,6 +45,18 @@ public class CustomerController {
return R.success(customerService.list(Wrappers.lambdaQuery(CustomerEntity.class).eq(CustomerEntity::getUserId, userId)));
}
/**
*
*
* @param targetCustomerId
*/
@GetMapping("/change_identity")
public R<?> changeIdentity(@RequestParam("targetCustomerId") Long targetCustomerId) {
MyResult myResult = SecurityUtil.loginUser();
myResult = customerService.changeIdentity(targetCustomerId, myResult);
return R.success(myResult);
}
/**
*
*/

View File

@ -9,6 +9,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njzscloud.common.core.ex.Exceptions;
import com.njzscloud.common.mp.support.PageParam;
import com.njzscloud.common.mp.support.PageResult;
import com.njzscloud.common.security.util.SecurityUtil;
import com.njzscloud.dispose.cst.customer.constant.IdentityCategory;
import com.njzscloud.dispose.cst.customer.constant.SettlementWay;
import com.njzscloud.dispose.cst.customer.mapper.CustomerMapper;
@ -18,12 +19,17 @@ import com.njzscloud.dispose.cst.customer.pojo.param.SearchCustomerParam;
import com.njzscloud.dispose.cst.customer.pojo.result.SearchCustomerResult;
import com.njzscloud.dispose.cst.org.pojo.param.AddOrgParam;
import com.njzscloud.dispose.cst.org.service.OrgService;
import com.njzscloud.dispose.sys.auth.pojo.result.IdentityInfo;
import com.njzscloud.dispose.sys.auth.pojo.result.MyResult;
import com.njzscloud.dispose.sys.auth.service.AuthService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
/**
*
@ -33,6 +39,7 @@ import java.util.List;
@RequiredArgsConstructor
public class CustomerService extends ServiceImpl<CustomerMapper, CustomerEntity> implements IService<CustomerEntity> {
private final OrgService orgService;
private final AuthService authService;
/**
*
@ -111,4 +118,20 @@ public class CustomerService extends ServiceImpl<CustomerMapper, CustomerEntity>
.eq(identityCategory != null, "a.identity_category", identityCategory)
));
}
@Transactional(rollbackFor = Exception.class)
public MyResult changeIdentity(Long targetCustomerId, MyResult myResult) {
List<IdentityInfo> identities = myResult.getIdentities();
Assert.notEmpty(identities, () -> Exceptions.exception("无需切换"));
Optional<IdentityInfo> identityInfo = identities.stream().filter(it -> Objects.equals(it.getCustomerId(), targetCustomerId)).findFirst();
Assert.isTrue(identityInfo.isPresent(), () -> Exceptions.exception("目标身份不存在,无法切换"));
Long currentCustomerId = myResult.getCurrentCustomerId();
IdentityInfo currentIdentity = myResult.currentIdentity();
Assert.isTrue(Objects.equals(currentCustomerId, targetCustomerId), () -> Exceptions.exception("已是【{}】身份,无需切换", currentIdentity.getIdentityCategory().getTxt()));
myResult.setCurrentCustomerId(targetCustomerId);
SecurityUtil.updateUser(myResult);
Long userId = myResult.getUserId();
Integer client = myResult.getClient();
return (MyResult) authService.my(userId, client);
}
}

View File

@ -4,6 +4,8 @@ import com.njzscloud.common.core.utils.R;
import com.njzscloud.common.mp.support.PageParam;
import com.njzscloud.common.mp.support.PageResult;
import com.njzscloud.dispose.cst.org.pojo.entity.OrgApplyEntity;
import com.njzscloud.dispose.cst.org.pojo.param.SearchOrgApplyParam;
import com.njzscloud.dispose.cst.org.pojo.result.SearchOrgApplyResult;
import com.njzscloud.dispose.cst.org.service.OrgApplyService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@ -60,7 +62,7 @@ public class OrgApplyController {
*
*/
@GetMapping("/paging")
public R<PageResult<OrgApplyEntity>> paging(PageParam pageParam, OrgApplyEntity orgApplyEntity) {
return R.success(orgApplyService.paging(pageParam, orgApplyEntity));
public R<PageResult<SearchOrgApplyResult>> paging(PageParam pageParam, SearchOrgApplyParam searchOrgApplyParam) {
return R.success(orgApplyService.paging(pageParam, searchOrgApplyParam));
}
}

View File

@ -1,12 +1,18 @@
package com.njzscloud.dispose.cst.org.mapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.njzscloud.dispose.cst.org.pojo.entity.OrgApplyEntity;
import com.njzscloud.dispose.cst.org.pojo.result.SearchOrgApplyResult;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
*
*/
@Mapper
public interface OrgApplyMapper extends BaseMapper<OrgApplyEntity> {
IPage<SearchOrgApplyResult> paging(Page<Object> page, @Param("ew") QueryWrapper<Object> ew);
}

View File

@ -0,0 +1,46 @@
package com.njzscloud.dispose.cst.org.pojo.param;
import com.njzscloud.dispose.cst.customer.constant.IdentityCategory;
import com.njzscloud.dispose.cst.org.constant.ApplyStatus;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.time.LocalDateTime;
/**
*
*/
@Getter
@Setter
@ToString
@Accessors(chain = true)
public class SearchOrgApplyParam {
/**
*
* a.apply_time
*/
private LocalDateTime applyStartTime;
private LocalDateTime applyEndTime;
/**
* ShenQingZhong-->JuJue-->TongYi-->
*/
private ApplyStatus applyStatus;
/**
*
*/
private String customerName;
/**
*
*/
private String customerPhone;
/**
* PingTai-->ChanFei-->QingYun-->XiaoNa-->CaiGou-->
*/
private IdentityCategory identityCategory;
}

View File

@ -0,0 +1,65 @@
package com.njzscloud.dispose.cst.org.pojo.result;
import com.njzscloud.dispose.cst.customer.constant.IdentityCategory;
import com.njzscloud.dispose.cst.org.constant.ApplyStatus;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.time.LocalDateTime;
/**
*
*/
@Getter
@Setter
@ToString
@Accessors(chain = true)
public class SearchOrgApplyResult {
/**
* Id
*/
private Long id;
/**
* Id
*/
private Long customerId;
/**
*
*/
private String customerName;
/**
*
*/
private String customerPhone;
/**
* PingTai-->ChanFei-->QingYun-->XiaoNa-->CaiGou-->
*/
private IdentityCategory identityCategory;
/**
* Id
*/
private Long orgId;
/**
*
*/
private LocalDateTime applyTime;
/**
* ShenQingZhong-->JuJue-->TongYi-->
*/
private ApplyStatus applyStatus;
/**
*
*/
private String cause;
}

View File

@ -1,17 +1,23 @@
package com.njzscloud.dispose.cst.org.service;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njzscloud.common.mp.support.PageParam;
import com.njzscloud.common.mp.support.PageResult;
import com.njzscloud.dispose.cst.customer.constant.IdentityCategory;
import com.njzscloud.dispose.cst.org.constant.ApplyStatus;
import com.njzscloud.dispose.cst.org.mapper.OrgApplyMapper;
import com.njzscloud.dispose.cst.org.pojo.entity.OrgApplyEntity;
import com.njzscloud.dispose.cst.org.pojo.param.SearchOrgApplyParam;
import com.njzscloud.dispose.cst.org.pojo.result.SearchOrgApplyResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
/**
@ -54,7 +60,20 @@ public class OrgApplyService extends ServiceImpl<OrgApplyMapper, OrgApplyEntity>
/**
*
*/
public PageResult<OrgApplyEntity> paging(PageParam pageParam, OrgApplyEntity orgApplyEntity) {
return PageResult.of(this.page(pageParam.toPage(), Wrappers.<OrgApplyEntity>query(orgApplyEntity)));
public PageResult<SearchOrgApplyResult> paging(PageParam pageParam, SearchOrgApplyParam searchOrgApplyParam) {
LocalDateTime applyStartTime = searchOrgApplyParam.getApplyStartTime();
LocalDateTime applyEndTime = searchOrgApplyParam.getApplyEndTime();
ApplyStatus applyStatus = searchOrgApplyParam.getApplyStatus();
String customerName = searchOrgApplyParam.getCustomerName();
String customerPhone = searchOrgApplyParam.getCustomerPhone();
IdentityCategory identityCategory = searchOrgApplyParam.getIdentityCategory();
return PageResult.of(baseMapper.paging(pageParam.toPage(), Wrappers.query()
.ge(applyStartTime != null, "a.apply_time", applyStartTime)
.le(applyStartTime != null, "a.apply_time", applyEndTime)
.eq(applyStatus != null, "a.apply_status", applyStatus)
.eq(identityCategory != null, "b.identity_category", identityCategory)
.eq(StrUtil.isNotBlank(customerName), "b.customer_name", customerName)
.eq(StrUtil.isNotBlank(customerPhone), "b.phone", customerPhone)
));
}
}

View File

@ -1,5 +1,7 @@
package com.njzscloud.dispose.sys.auth.pojo.result;
import cn.hutool.core.lang.Assert;
import com.njzscloud.common.core.ex.Exceptions;
import com.njzscloud.common.security.support.UserDetail;
import com.njzscloud.dispose.sys.user.constant.Gender;
import lombok.Getter;
@ -8,18 +10,38 @@ import lombok.experimental.Accessors;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
@Getter
@Setter
@Accessors(chain = true)
public class MyResult extends UserDetail {
/**
*
*/
private List<MenuResource> menus;
/**
*
*/
private List<EndpointResource> endpoints;
/**
*
*/
private List<IdentityInfo> identities;
/**
*
*/
private List<Map<String, Object>> setting;
/**
* Id
*
*/
private Long currentCustomerId;
/**
*
*/
@ -37,5 +59,11 @@ public class MyResult extends UserDetail {
*/
private String email;
public IdentityInfo currentIdentity() {
Optional<IdentityInfo> identityInfo = identities.stream().filter(it -> Objects.equals(it.getCustomerId(), currentCustomerId)).findFirst();
Assert.isTrue(identityInfo.isPresent(), () -> Exceptions.error("无身份信息"));
// noinspection OptionalGetWithoutIsPresent
return identityInfo.get();
}
}

View File

@ -1,6 +1,7 @@
package com.njzscloud.dispose.sys.auth.service;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@ -37,7 +38,8 @@ public class AuthService implements IAuthService {
@Override
@Transactional(rollbackFor = Exception.class)
public UserDetail selectUser(PasswordLoginForm form) {
return authMapper.selectUser(Wrappers.query().eq("a.username", form.getAccount()).eq("a.deleted", 0));
MyResult myResult = authMapper.selectUser(Wrappers.query().eq("a.username", form.getAccount()).eq("a.deleted", 0));
return my(myResult, form.getClientCode().getVal());
}
@Override
@ -45,14 +47,18 @@ public class AuthService implements IAuthService {
public UserDetail selectUser(WechatMiniLoginForm form) {
String openid = form.getOpenid();
String unionid = form.getUnionid();
return authMapper.selectUser(Wrappers.query().eq("a.wechat_openid", openid)
MyResult myResult = authMapper.selectUser(Wrappers.query().eq("a.wechat_openid", openid)
.eq(StrUtil.isNotBlank(unionid), "a.wechat_unionid", unionid)
.eq("a.deleted", 0));
return my(myResult, form.getClientCode().getVal());
}
@Override
public Set<String> selectRole(Long userId) {
return authMapper.selectRole(userId);
Set<String> roles = authMapper.selectRole(userId);
roles.add(ROLE_AUTHENTICATED);
roles.add(ROLE_ANONYMOUS);
return roles;
}
/**
@ -62,13 +68,27 @@ public class AuthService implements IAuthService {
public UserDetail my(Long userId, Integer client) {
UserDetail userDetail = authMapper.selectUser(Wrappers.query().eq("b.id", userId).eq("a.deleted", 0));
Assert.notNull(userDetail, () -> Exceptions.exception("未查询到用户信息"));
return my(userDetail, client);
}
public UserDetail my(UserDetail userDetail, Integer client) {
if (userDetail == null) return null;
Long userId = userDetail.getUserId();
Assert.notNull(userDetail, () -> Exceptions.exception("未查询到用户信息"));
List<MenuResource> menuResources = authMapper.selectUserMenu(userId, client);
List<EndpointResource> endpointResources = authMapper.selectUserEndpoint(userId);
List<IdentityInfo> identityInfoList = authMapper.selectUserIdentity(userId);
Long currentCustomerId = null;
if (CollUtil.isNotEmpty(identityInfoList)) {
IdentityInfo identityInfo = identityInfoList.getFirst();
currentCustomerId = identityInfo.getCustomerId();
}
Set<String> roles = authMapper.selectRole(userId);
roles.add(ROLE_AUTHENTICATED);
roles.add(ROLE_ANONYMOUS);
return BeanUtil.copyProperties(userDetail, MyResult.class)
.setCurrentCustomerId(currentCustomerId)
.setIdentities(identityInfoList)
.setMenus(menuResources)
.setEndpoints(endpointResources)

View File

@ -51,6 +51,31 @@ public class TokenService implements ITokenService {
}
}
@Override
public void updateToken(UserDetail userDetail) {
try {
writeLock.lock();
Token token = userDetail.getToken();
long userId = token.userId();
String tid = token.tid();
String key = Constants.TOKEN_CACHE_KEY.fill(userId, tid);
TOKEN_CACHE.remove(key);
SysTokenEntity sysTokenEntity = sysTokenMapper.selectOne(Wrappers.<SysTokenEntity>lambdaQuery()
.eq(SysTokenEntity::getUserId, userId)
.eq(SysTokenEntity::getTid, tid));
sysTokenMapper.updateById(new SysTokenEntity()
.setId(sysTokenEntity.getId())
.setUserId(userId)
.setTid(tid)
.setTkey(key)
.setTval(token.toString())
.setUserDetail(Fastjson.toJsonStr(userDetail))
);
} finally {
writeLock.unlock();
}
}
@Override
public UserDetail loadUser(String tokenStr) {
try {

View File

@ -20,6 +20,7 @@ import com.njzscloud.dispose.cst.customer.constant.IdentityCategory;
import com.njzscloud.dispose.cst.customer.pojo.param.AddCustomerParam;
import com.njzscloud.dispose.cst.customer.service.CustomerService;
import com.njzscloud.dispose.cst.org.pojo.param.AddOrgParam;
import com.njzscloud.dispose.sys.auth.service.AuthService;
import com.njzscloud.dispose.sys.role.pojo.entity.RoleEntity;
import com.njzscloud.dispose.sys.role.pojo.result.RoleDetailResult;
import com.njzscloud.dispose.sys.user.constant.Gender;
@ -40,6 +41,8 @@ import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import static com.njzscloud.common.security.contant.Constants.ROLE_ANONYMOUS;
import static com.njzscloud.common.security.contant.Constants.ROLE_AUTHENTICATED;
import static com.njzscloud.dispose.event.SysMittEvent.COERCE_LOGOUT;
/**
@ -136,6 +139,8 @@ public class UserService extends ServiceImpl<UserMapper, UserEntity> implements
return PageResult.of(baseMapper.paging(pageParam.toPage(), ew));
}
AuthService authService;
/**
*
*
@ -175,9 +180,13 @@ public class UserService extends ServiceImpl<UserMapper, UserEntity> implements
customerService.add(BeanUtil.copyProperties(customer, AddCustomerParam.class)
.setAddOrgParam(BeanUtil.copyProperties(org, AddOrgParam.class)));
List<RoleDetailResult> roleDetailResults = userRoleService.listRole(userId);
UserDetail userDetail = baseMapper.selectUser(userId)
Set<String> roles = roleDetailResults.stream().map(RoleDetailResult::getRoleCode).collect(Collectors.toSet());
roles.add(ROLE_AUTHENTICATED);
roles.add(ROLE_ANONYMOUS);
UserDetail userDetail = authService.my(userId, account.getClientCode())
.setAuthWay(userRegisterParam.getAuthWay())
.setRoles(roleDetailResults.stream().map(RoleDetailResult::getRoleCode).collect(Collectors.toSet()));
.setRoles(roles);
return SecurityUtil.registrationUser(userDetail);
}

View File

@ -60,6 +60,6 @@
<select id="detail" resultMap="searchCustomerResultMap">
<include refid="searchCustomer"/>
WHERE a.deleted = 0
AND a.id = ${id}
AND a.id = #{id}
</select>
</mapper>

View File

@ -1,4 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.njzscloud.dispose.cst.org.mapper.OrgApplyMapper">
<select id="paging" resultType="com.njzscloud.dispose.cst.org.pojo.result.SearchOrgApplyResult">
SELECT a.id,
a.customer_id,
a.org_id,
a.apply_time,
a.apply_status,
a.cause,
b.identity_category,
b.customer_name,
b.phone customer_phone
FROM cst_org_apply a
INNER JOIN cst_customer b ON b.id = a.customer_id AND b.deleted = 0
<if test="ew.customSqlSegment != null and ew.customSqlSegment != ''">
${ew.customSqlSegment}
</if>
</select>
</mapper>

View File

@ -30,6 +30,7 @@
SELECT a.role_code
FROM sys_role a
INNER JOIN sys_user_role b ON b.role_id = a.id AND b.user_id = #{userId}
ORDER BY a.id
</select>
<select id="selectUserMenu" resultType="com.njzscloud.dispose.sys.auth.pojo.result.MenuResource">
@ -50,6 +51,7 @@
INNER JOIN sys_user_role b ON b.role_id = a.id AND b.user_id = #{userId})
WHERE a.deleted = 0
AND a.client_code <![CDATA[ & ]]> ${client} != 0
ORDER BY a.tier, a.sort, a.id
</select>
<select id="selectUserEndpoint" resultType="com.njzscloud.dispose.sys.auth.pojo.result.EndpointResource">
@ -64,6 +66,7 @@
AND b.role_id IN (SELECT a.id
FROM sys_role a
INNER JOIN sys_user_role b ON b.role_id = a.id AND b.user_id = #{userId})
ORDER BY a.id
</select>
<select id="selectUserIdentity" resultType="com.njzscloud.dispose.sys.auth.pojo.result.IdentityInfo">
SELECT a.identity_category,
@ -100,6 +103,7 @@
LEFT JOIN cst_org b ON b.id = a.org_id AND b.deleted = 0
WHERE a.deleted = 0
AND a.user_id = #{userId}
ORDER BY a.create_time, a.id
</select>
</mapper>