补足用户切换功能

This commit is contained in:
2026-07-09 16:07:48 +08:00
parent 000d5d3028
commit f7b995ed3a
8 changed files with 504 additions and 163 deletions
@@ -1,12 +1,8 @@
package com.nbport.zgwl.auth;
import com.nbport.zgwl.utils.MockSecurityUserRegistry;
import org.springframework.stereotype.Component;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* 本地模拟 AuthManager。
*
@@ -18,29 +14,13 @@ import java.util.Set;
@Component
public class AuthManager {
/**
* 写死几套本地用户可访问系统。
*
* 约定:
* 1L -> 超管,可同时访问 manage / business
* 2L -> manage 侧管理员
* 3L -> business 侧业务管理员
* 4L -> business 侧普通用户
*/
private static final Map<Long, Set<SysEnum>> USER_SYS_ACCESS = new HashMap<>();
private final MockSecurityUserRegistry mockSecurityUserRegistry;
static {
USER_SYS_ACCESS.put(1L, EnumSet.of(SysEnum.MANAGE, SysEnum.BUSINESS));
USER_SYS_ACCESS.put(2L, EnumSet.of(SysEnum.MANAGE));
USER_SYS_ACCESS.put(3L, EnumSet.of(SysEnum.BUSINESS));
USER_SYS_ACCESS.put(4L, EnumSet.of(SysEnum.BUSINESS));
public AuthManager(MockSecurityUserRegistry mockSecurityUserRegistry) {
this.mockSecurityUserRegistry = mockSecurityUserRegistry;
}
public boolean isUserCanAccessSys(Long userId, SysEnum sysEnum) {
if (userId == null || sysEnum == null) {
return false;
}
Set<SysEnum> accessSet = USER_SYS_ACCESS.get(userId);
return accessSet != null && accessSet.contains(sysEnum);
return mockSecurityUserRegistry.canAccessSystem(userId, sysEnum);
}
}
@@ -2,10 +2,9 @@ package com.nbport.zgwl.auth;
import com.nbport.zgwl.entity.SysUserEntity;
import com.nbport.zgwl.utils.AdminSecurityManage;
import com.nbport.zgwl.utils.MockSecurityUserRegistry;
import org.springframework.stereotype.Component;
import java.util.Set;
/**
* 本地模拟 SecurityManager。
*
@@ -15,18 +14,17 @@ import java.util.Set;
@Component
public class SecurityManager {
private static final Set<Long> SUPER_ADMIN_IDS = Set.of(1L);
private final AdminSecurityManage adminSecurityManage;
private final MockSecurityUserRegistry mockSecurityUserRegistry;
public SecurityManager(AdminSecurityManage adminSecurityManage) {
public SecurityManager(AdminSecurityManage adminSecurityManage,
MockSecurityUserRegistry mockSecurityUserRegistry) {
this.adminSecurityManage = adminSecurityManage;
this.mockSecurityUserRegistry = mockSecurityUserRegistry;
}
public boolean isSuperAdmin() {
SysUserEntity currentUser = adminSecurityManage.getUser();
return currentUser != null
&& currentUser.getId() != null
&& SUPER_ADMIN_IDS.contains(currentUser.getId());
return currentUser != null && mockSecurityUserRegistry.isSuperAdmin(currentUser.getId());
}
}
@@ -131,13 +131,17 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
if (securityManager.isSuperAdmin()) {
return "admin";
}
String scopeByPermission = resolveScopeByDataPermission(currentUser.getDataPermission());
if (scopeByPermission != null) {
return scopeByPermission;
}
if (authManager.isUserCanAccessSys(currentUser.getId(), SysEnum.MANAGE)) {
return "company";
}
if (authManager.isUserCanAccessSys(currentUser.getId(), SysEnum.BUSINESS)) {
return "company";
}
return "personal";
return isAdminUser(currentUser) ? "company" : "personal";
}
/** 查询详情,含日志 */
@@ -0,0 +1,37 @@
package com.nbport.zgwl.controller;
import com.nbport.zgwl.common.R;
import com.nbport.zgwl.utils.AdminSecurityManage;
import com.nbport.zgwl.utils.MockSecurityUserRegistry;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 本地测试用的 mock 用户切换辅助接口。
*
* 仅返回用户列表和当前用户摘要,
* 真正的切换仍由前端通过请求头 X-Mock-User 控制,
* 这样不会引入新的登录态或会话依赖。
*/
@RestController
@RequiredArgsConstructor
@RequestMapping("/mock/security")
public class MockUserSwitchController {
private final AdminSecurityManage adminSecurityManage;
private final MockSecurityUserRegistry mockSecurityUserRegistry;
@GetMapping("/users")
public R<List<MockSecurityUserRegistry.MockUserOptionDto>> listUsers() {
return R.success(mockSecurityUserRegistry.listUserOptions());
}
@GetMapping("/current")
public R<MockSecurityUserRegistry.MockCurrentUserDto> getCurrentUser() {
return R.success(mockSecurityUserRegistry.buildCurrentUserDto(adminSecurityManage.resolveMockUserKey()));
}
}
@@ -1,6 +1,7 @@
package com.nbport.zgwl.manifest.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nbport.zgwl.entity.SysUserEntity;
import com.nbport.zgwl.common.PageResult;
import com.nbport.zgwl.exception.ServiceException;
import com.nbport.zgwl.manifest.dto.ContractTemplateDto;
@@ -12,6 +13,7 @@ import com.nbport.zgwl.manifest.utils.ManifestCodeUtils;
import com.nbport.zgwl.manifest.utils.ManifestJsonUtils;
import com.nbport.zgwl.manifest.utils.ManifestManageConstants;
import com.nbport.zgwl.utils.AdminSecurityManage;
import com.nbport.zgwl.utils.MockSecurityUserRegistry;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -41,6 +43,8 @@ public class ContractTemplateServiceImpl implements ContractTemplateService {
private final AdminSecurityManage adminSecurityManage;
private final MockSecurityUserRegistry mockSecurityUserRegistry;
/**
* 内存中的组织树(扁平化节点列表),懒加载
*/
@@ -94,9 +98,9 @@ public class ContractTemplateServiceImpl implements ContractTemplateService {
LocalDateTime now = LocalDateTime.now();
template.setId(contractTemplateMapper.selectTemplateSeqNextVal());
template.setTemplateCode(ManifestCodeUtils.buildTemplateCode(template.getContractType()));
template.setCreateBy(ManifestManageConstants.DEFAULT_OPERATOR);
template.setCreateBy(resolveOperatorName());
template.setCreatedTime(now);
template.setUpdatedBy(ManifestManageConstants.DEFAULT_OPERATOR);
template.setUpdatedBy(resolveOperatorName());
template.setUpdatedTime(now);
template.setDelFlag(ManifestManageConstants.DEL_FLAG_NORMAL);
saveJsonFields(template);
@@ -125,7 +129,7 @@ public class ContractTemplateServiceImpl implements ContractTemplateService {
template.setTemplateCode(dbTemplate.getTemplateCode());
template.setCreateBy(dbTemplate.getCreateBy());
template.setCreatedTime(dbTemplate.getCreatedTime());
template.setUpdatedBy(ManifestManageConstants.DEFAULT_OPERATOR);
template.setUpdatedBy(resolveOperatorName());
template.setUpdatedTime(LocalDateTime.now());
template.setDelFlag(dbTemplate.getDelFlag());
saveJsonFields(template);
@@ -152,7 +156,7 @@ public class ContractTemplateServiceImpl implements ContractTemplateService {
contractTemplateMapper.updateTemplateStatus(
id,
status,
ManifestManageConstants.DEFAULT_OPERATOR,
resolveOperatorName(),
LocalDateTime.now()
);
return getTemplateDetail(id);
@@ -168,7 +172,7 @@ public class ContractTemplateServiceImpl implements ContractTemplateService {
}
contractTemplateMapper.deleteTemplateById(
id,
ManifestManageConstants.DEFAULT_OPERATOR,
resolveOperatorName(),
LocalDateTime.now(),
ManifestManageConstants.DEL_FLAG_DELETED
);
@@ -195,7 +199,10 @@ public class ContractTemplateServiceImpl implements ContractTemplateService {
* 所以对于用户来说,能看到的模板是「发布范围包含用户所属组织或其任一祖先」的模板。
*/
private List<String> computeVisibleOrgIds() {
String userOrgId = adminSecurityManage.getUser().getSysOrgEntity().getId();
SysUserEntity currentUser = adminSecurityManage.getUser();
String userOrgId = currentUser == null || currentUser.getSysOrgEntity() == null
? null
: currentUser.getSysOrgEntity().getId();
if (userOrgId == null) {
return Collections.emptyList();
}
@@ -216,6 +223,14 @@ public class ContractTemplateServiceImpl implements ContractTemplateService {
}
List<String> result = new ArrayList<>(visible);
if (result.isEmpty()) {
result.add(userOrgId);
MockSecurityUserRegistry.MockUserProfile profile =
mockSecurityUserRegistry.getProfileByUserId(currentUser == null ? null : currentUser.getId());
if (profile != null && "business".equalsIgnoreCase(profile.systemType())) {
result.add("1");
}
}
log.debug("当前用户 orgId={}, 可见组织列表={}", userOrgId, result);
return result;
}
@@ -300,6 +315,11 @@ public class ContractTemplateServiceImpl implements ContractTemplateService {
nodes.add(new OrgNode(73L, "浙港物流西部大区", 1L));
nodes.add(new OrgNode(74L, "宁波港铁路有限公司---重庆/城厢/白银市/西安/宜兴", 73L));
// 业务端 mock 组织,保证切到业务用户时模板发布范围和可见范围能一起联动。
nodes.add(new OrgNode(384L, "江苏远洋新世纪2供应链有限公司", 1L));
nodes.add(new OrgNode(15L, "嘉兴兴港", 1L));
nodes.add(new OrgNode(79L, "货代测试", 1L));
return nodes;
}
@@ -313,6 +333,13 @@ public class ContractTemplateServiceImpl implements ContractTemplateService {
/**
* 内部组织节点
*/
private String resolveOperatorName() {
SysUserEntity currentUser = adminSecurityManage.getUser();
return currentUser == null || currentUser.getUsername() == null || currentUser.getUsername().isBlank()
? ManifestManageConstants.DEFAULT_OPERATOR
: currentUser.getUsername();
}
private static class OrgNode {
private final Long id;
private final String orgName;
@@ -3,6 +3,7 @@ package com.nbport.zgwl.partner.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nbport.zgwl.common.PageResult;
import com.nbport.zgwl.contractlaunch.utils.JsonUtils;
import com.nbport.zgwl.entity.SysUserEntity;
import com.nbport.zgwl.contractpush.dto.PushPayloadDTO;
import com.nbport.zgwl.contractpush.service.DataCollectionPushService;
import com.nbport.zgwl.exception.ServiceException;
@@ -81,9 +82,9 @@ public class PartnerManageServiceImpl implements PartnerManageService {
partner.setSyncTime(null);
partner.setSyncMessage("新增后尚未同步");
partner.setOppositeStatus(PartnerManageConstants.OPPOSITE_STATUS_EFFECTUAL);
partner.setCreateBy(PartnerManageConstants.DEFAULT_OPERATOR);
partner.setCreateBy(resolveOperatorName());
partner.setCreateTime(now);
partner.setUpdateBy(PartnerManageConstants.DEFAULT_OPERATOR);
partner.setUpdateBy(resolveOperatorName());
partner.setUpdateTime(now);
partner.setOrgId(resolveCurrentOrgId());
partner.setIsDeleted(PartnerManageConstants.PARTNER_IS_DELETED_NORMAL);
@@ -117,14 +118,14 @@ public class PartnerManageServiceImpl implements PartnerManageService {
partner.setSyncStatus(PartnerManageConstants.SYNC_STATUS_UNSYNCED);
partner.setSyncTime(null);
partner.setSyncMessage("信息已修改,待重新同步");
partner.setUpdateBy(PartnerManageConstants.DEFAULT_OPERATOR);
partner.setUpdateBy(resolveOperatorName());
partner.setUpdateTime(now);
partner.setOrgId(dbPartner.getOrgId() != null ? dbPartner.getOrgId() : resolveCurrentOrgId());
partner.setIsDeleted(PartnerManageConstants.PARTNER_IS_DELETED_NORMAL);
partnerManageMapper.updatePartner(partner);
partnerManageMapper.markPartnerContactsDeletedByPartnerId(
partner.getCustomerSysid(),
PartnerManageConstants.DEFAULT_OPERATOR,
resolveOperatorName(),
now,
PartnerManageConstants.CONTACT_DEL_FLAG_DELETED);
saveContacts(partner.getCustomerSysid(), partner.getContacts(), now);
@@ -140,12 +141,12 @@ public class PartnerManageServiceImpl implements PartnerManageService {
LocalDateTime now = LocalDateTime.now();
partnerManageMapper.markPartnerContactsDeletedByPartnerIds(
customerSysids,
PartnerManageConstants.DEFAULT_OPERATOR,
resolveOperatorName(),
now,
PartnerManageConstants.CONTACT_DEL_FLAG_DELETED);
partnerManageMapper.deletePartnerByIds(
customerSysids,
PartnerManageConstants.DEFAULT_OPERATOR,
resolveOperatorName(),
now,
PartnerManageConstants.PARTNER_IS_DELETED_DELETED);
}
@@ -218,7 +219,7 @@ public class PartnerManageServiceImpl implements PartnerManageService {
PartnerManageConstants.SYNC_STATUS_SYNCED,
now,
syncMessage,
PartnerManageConstants.DEFAULT_OPERATOR,
resolveOperatorName(),
now);
return selectPartnerById(customerSysid);
@@ -286,7 +287,7 @@ public class PartnerManageServiceImpl implements PartnerManageService {
PartnerManageConstants.SYNC_STATUS_SYNCED,
now,
syncMessage,
PartnerManageConstants.DEFAULT_OPERATOR,
resolveOperatorName(),
now);
successCount++;
}
@@ -338,9 +339,9 @@ public class PartnerManageServiceImpl implements PartnerManageService {
partnerManageMapper.batchInsertPartnerContacts(
contacts,
PartnerManageConstants.DEFAULT_OPERATOR,
resolveOperatorName(),
now,
PartnerManageConstants.DEFAULT_OPERATOR,
resolveOperatorName(),
now,
PartnerManageConstants.CONTACT_DEL_FLAG_NORMAL);
}
@@ -370,10 +371,11 @@ public class PartnerManageServiceImpl implements PartnerManageService {
}
private Long resolveCurrentOrgId() {
if (adminSecurityManage.getUser() == null || adminSecurityManage.getUser().getSysOrgEntity() == null) {
SysUserEntity currentUser = adminSecurityManage.getUser();
if (currentUser == null || currentUser.getSysOrgEntity() == null) {
return null;
}
String orgId = adminSecurityManage.getUser().getSysOrgEntity().getId();
String orgId = currentUser.getSysOrgEntity().getId();
if (!StrUtilHelper.hasText(orgId)) {
return null;
}
@@ -388,6 +390,13 @@ public class PartnerManageServiceImpl implements PartnerManageService {
/**
* 避免为了一个判空再引入新依赖,这里保留一个最小工具。
*/
private String resolveOperatorName() {
SysUserEntity currentUser = adminSecurityManage.getUser();
return currentUser == null || !StrUtilHelper.hasText(currentUser.getUsername())
? PartnerManageConstants.DEFAULT_OPERATOR
: currentUser.getUsername();
}
private static final class StrUtilHelper {
private StrUtilHelper() {
@@ -1,13 +1,10 @@
package com.nbport.zgwl.utils;
import com.nbport.zgwl.entity.SysOrgEntity;
import com.nbport.zgwl.entity.SysUserEntity;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 登录用户获取组件
*
@@ -18,125 +15,25 @@ import java.util.List;
@Component
public class AdminSecurityManage {
private static final String HEADER_MOCK_USER = "X-Mock-User";
private final HttpServletRequest request;
private final MockSecurityUserRegistry mockSecurityUserRegistry;
private final String defaultMockUser;
public AdminSecurityManage(HttpServletRequest request,
MockSecurityUserRegistry mockSecurityUserRegistry,
@Value("${mock.security.current-user:admin}") String defaultMockUser) {
this.request = request;
this.mockSecurityUserRegistry = mockSecurityUserRegistry;
this.defaultMockUser = defaultMockUser;
}
public SysUserEntity getUser() {
String mockUser = request == null ? null : request.getHeader(HEADER_MOCK_USER);
if (mockUser == null || mockUser.isBlank()) {
mockUser = defaultMockUser;
}
if ("manage_admin".equalsIgnoreCase(mockUser)) {
return buildManageAdmin();
}
if ("business_admin".equalsIgnoreCase(mockUser)) {
return buildBusinessAdmin();
}
if ("business_user".equalsIgnoreCase(mockUser)) {
return buildBusinessUser();
}
return buildSuperAdmin();
return mockSecurityUserRegistry.buildUser(resolveMockUserKey());
}
private SysUserEntity buildSuperAdmin() {
return buildUser(
1L,
"admin",
"13800000000",
"admin@test.com",
buildOrg("1", "浙江海港物流集团有限公司X"),
"平台管理部",
1L,
"ALL",
List.of("SUPER_ADMIN", "MANAGE_ADMIN", "BUSINESS_ADMIN")
);
}
private SysUserEntity buildManageAdmin() {
return buildUser(
2L,
"manage_admin",
"13800000001",
"manage_admin@test.com",
buildOrg("1", "浙江海港物流集团有限公司X"),
"财务部",
1L,
"COMPANY",
List.of("MANAGE_ADMIN")
);
}
private SysUserEntity buildBusinessAdmin() {
return buildUser(
3L,
"business_admin",
"13800000002",
"business_admin@test.com",
buildOrg("384", "江苏远洋新世纪2供应链有限公司"),
"业务一部",
1L,
"COMPANY",
List.of("BUSINESS_ADMIN")
);
}
private SysUserEntity buildBusinessUser() {
return buildUser(
4L,
"business_user",
"13800000003",
"business_user@test.com",
buildOrg("384", "江苏远洋新世纪2供应链有限公司"),
"业务一部",
0L,
"SELF",
List.of("BUSINESS_USER")
);
}
private SysUserEntity buildUser(Long id,
String username,
String mobilePhone,
String email,
SysOrgEntity orgEntity,
String deptName,
Long adminFlag,
String dataPermission,
List<String> roleCodes) {
SysUserEntity user = new SysUserEntity();
user.setId(id);
user.setUsername(username);
user.setMobilePhone(mobilePhone);
user.setEmail(email);
user.setSysOrgEntity(orgEntity);
user.setDeptName(deptName);
user.setAdminFlag(adminFlag);
user.setDataPermission(dataPermission);
user.setRoleCodes(roleCodes);
return user;
}
private SysOrgEntity buildOrg(String orgId, String orgName) {
SysOrgEntity orgEntity = new SysOrgEntity();
orgEntity.setId(orgId);
orgEntity.setOrgName(orgName);
orgEntity.setContactPhone("13800000000");
orgEntity.setContactEmail("admin@test.com");
orgEntity.setContactAddress("宁波市北仑区明州路288号");
orgEntity.setRegisteredAddress("宁波市北仑区明州路288号");
orgEntity.setBankName("中国工商银行宁波分行");
orgEntity.setBankAccount("330201000000000001");
orgEntity.setLegalRepresentative("张三");
orgEntity.setCreditCode("91330200MAZGWL0001");
orgEntity.setInvoiceTitleOptions(List.of("浙港物流平台有限公司"));
return orgEntity;
public String resolveMockUserKey() {
String headerValue = request == null ? null : request.getHeader(MockSecurityUserRegistry.HEADER_MOCK_USER);
String candidate = (headerValue == null || headerValue.isBlank()) ? defaultMockUser : headerValue;
return mockSecurityUserRegistry.normalizeUserKey(candidate);
}
}
@@ -0,0 +1,389 @@
package com.nbport.zgwl.utils;
import com.nbport.zgwl.auth.SysEnum;
import com.nbport.zgwl.entity.SysOrgEntity;
import com.nbport.zgwl.entity.SysUserEntity;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
/**
* 本地测试环境的 mock 用户注册表。
*
* 统一管理:
* 1. 前端可切换的测试用户列表
* 2. AdminSecurityManage 返回的当前登录用户
* 3. AuthManager / SecurityManager 需要识别的系统访问能力
*
* 正式环境接入真实登录态后,可整体替换掉这里的实现,
* 不影响业务代码里对 AdminSecurityManage / AuthManager 的调用方式。
*/
@Component
public class MockSecurityUserRegistry {
public static final String HEADER_MOCK_USER = "X-Mock-User";
public static final String DEFAULT_USER_KEY = "admin";
private static final String ROOT_ORG_ID = "1";
private static final String ROOT_ORG_NAME = "浙江海港物流集团有限公司X";
private static final String DEFAULT_ADDRESS = "宁波市北仑区明州路288号";
private static final String DEFAULT_BANK = "中国工商银行宁波分行";
private static final String DEFAULT_BANK_ACCOUNT = "330201000000000001";
private static final String DEFAULT_LEGAL_REPRESENTATIVE = "张三";
private static final String DEFAULT_PHONE = "13800000000";
private static final String DEFAULT_EMAIL_DOMAIN = "@test.com";
private final Map<String, MockUserProfile> profilesByKey;
private final Map<Long, MockUserProfile> profilesByUserId;
public MockSecurityUserRegistry() {
LinkedHashMap<String, MockUserProfile> profiles = new LinkedHashMap<>();
register(profiles, new MockUserProfile(
DEFAULT_USER_KEY,
1L,
"admin",
"平台超管",
"platform",
ROOT_ORG_ID,
ROOT_ORG_NAME,
"平台管理部",
1L,
"ALL",
true,
EnumSet.of(SysEnum.MANAGE, SysEnum.BUSINESS),
List.of("SUPER_ADMIN", "MANAGE_ADMIN", "BUSINESS_ADMIN")
));
register(profiles, new MockUserProfile(
"manage_yongkang",
101L,
"manage_yongkang",
"管理端-永康陆港",
"manage",
"47",
"永康陆港国际物流有限公司",
"永康业务管理部",
1L,
"COMPANY",
false,
EnumSet.of(SysEnum.MANAGE),
List.of("MANAGE_ADMIN")
));
register(profiles, new MockUserProfile(
"manage_zhuji",
102L,
"manage_zhuji",
"管理端-诸暨业务点",
"manage",
"48",
"宁波港国际物流有限公司诸暨业务点",
"诸暨业务管理部",
1L,
"COMPANY",
false,
EnumSet.of(SysEnum.MANAGE),
List.of("MANAGE_ADMIN")
));
register(profiles, new MockUserProfile(
"manage_zhongbei",
103L,
"manage_zhongbei",
"管理端-浙中北大区",
"manage",
"58",
"浙港物流浙中北大区",
"浙中北区域管理部",
1L,
"COMPANY",
false,
EnumSet.of(SysEnum.MANAGE),
List.of("MANAGE_ADMIN")
));
register(profiles, new MockUserProfile(
"manage_jiaxing_branch",
104L,
"manage_jiaxing_branch",
"管理端-嘉兴分公司",
"manage",
"59",
"浙江兴港国际货运代理有限公司嘉兴分公司",
"嘉兴分公司",
1L,
"COMPANY",
false,
EnumSet.of(SysEnum.MANAGE),
List.of("MANAGE_ADMIN")
));
register(profiles, new MockUserProfile(
"manage_shaoxing_branch",
105L,
"manage_shaoxing_branch",
"管理端-绍兴分公司",
"manage",
"60",
"宁波港铁路有限公司绍兴分公司",
"绍兴分公司",
1L,
"COMPANY",
false,
EnumSet.of(SysEnum.MANAGE),
List.of("MANAGE_ADMIN")
));
register(profiles, new MockUserProfile(
"business_jsys",
201L,
"business_jsys",
"业务端-江苏远洋",
"business",
"384",
"江苏远洋新世纪2供应链有限公司",
"业务一部",
1L,
"COMPANY",
false,
EnumSet.of(SysEnum.BUSINESS),
List.of("BUSINESS_ADMIN")
));
register(profiles, new MockUserProfile(
"business_jxxg",
202L,
"business_jxxg",
"业务端-嘉兴兴港",
"business",
"15",
"嘉兴兴港",
"业务二部",
1L,
"COMPANY",
false,
EnumSet.of(SysEnum.BUSINESS),
List.of("BUSINESS_ADMIN")
));
register(profiles, new MockUserProfile(
"business_hdcs",
203L,
"business_hdcs",
"业务端-货代测试",
"business",
"79",
"货代测试",
"测试业务组",
1L,
"COMPANY",
false,
EnumSet.of(SysEnum.BUSINESS),
List.of("BUSINESS_ADMIN")
));
register(profiles, new MockUserProfile(
"business_jsys_user",
204L,
"business_jsys_user",
"业务端-江苏远洋普通用户",
"business",
"384",
"江苏远洋新世纪2供应链有限公司",
"业务一部",
0L,
"SELF",
false,
EnumSet.of(SysEnum.BUSINESS),
List.of("BUSINESS_USER")
));
this.profilesByKey = Collections.unmodifiableMap(profiles);
LinkedHashMap<Long, MockUserProfile> byUserId = new LinkedHashMap<>();
for (MockUserProfile profile : profiles.values()) {
byUserId.put(profile.userId(), profile);
}
this.profilesByUserId = Collections.unmodifiableMap(byUserId);
}
private void register(Map<String, MockUserProfile> profiles, MockUserProfile profile) {
profiles.put(profile.key(), profile);
}
public String normalizeUserKey(String candidate) {
if (candidate == null || candidate.isBlank()) {
return DEFAULT_USER_KEY;
}
String normalized = candidate.trim().toLowerCase(Locale.ROOT);
return profilesByKey.containsKey(normalized) ? normalized : DEFAULT_USER_KEY;
}
public SysUserEntity buildUser(String candidate) {
MockUserProfile profile = profilesByKey.get(normalizeUserKey(candidate));
return toUserEntity(profile);
}
public MockUserProfile getProfile(String candidate) {
return profilesByKey.get(normalizeUserKey(candidate));
}
public MockUserProfile getProfileByUserId(Long userId) {
return userId == null ? null : profilesByUserId.get(userId);
}
public boolean isSuperAdmin(Long userId) {
MockUserProfile profile = getProfileByUserId(userId);
return profile != null && profile.superAdmin();
}
public boolean canAccessSystem(Long userId, SysEnum sysEnum) {
if (userId == null || sysEnum == null) {
return false;
}
MockUserProfile profile = getProfileByUserId(userId);
return profile != null && profile.accessSystems().contains(sysEnum);
}
public List<MockUserOptionDto> listUserOptions() {
List<MockUserOptionDto> options = new ArrayList<>();
for (MockUserProfile profile : profilesByKey.values()) {
options.add(new MockUserOptionDto(
profile.key(),
profile.displayName(),
profile.systemType(),
profile.username(),
profile.userId(),
profile.orgId(),
profile.orgName(),
profile.deptName(),
profile.superAdmin(),
new ArrayList<>(profile.accessSystems()),
profile.dataPermission()
));
}
return options;
}
public MockCurrentUserDto buildCurrentUserDto(String candidate) {
MockUserProfile profile = getProfile(candidate);
return new MockCurrentUserDto(
profile.key(),
profile.displayName(),
profile.systemType(),
profile.username(),
profile.userId(),
profile.orgId(),
profile.orgName(),
profile.deptName(),
profile.superAdmin(),
new ArrayList<>(profile.accessSystems()),
profile.dataPermission()
);
}
private SysUserEntity toUserEntity(MockUserProfile profile) {
SysUserEntity user = new SysUserEntity();
user.setId(profile.userId());
user.setUsername(profile.username());
user.setMobilePhone(buildMobile(profile.userId()));
user.setEmail(profile.username() + DEFAULT_EMAIL_DOMAIN);
user.setSysOrgEntity(buildOrg(profile.orgId(), profile.orgName(), profile.systemType()));
user.setDeptName(profile.deptName());
user.setAdminFlag(profile.adminFlag());
user.setDataPermission(profile.dataPermission());
user.setRoleCodes(new ArrayList<>(profile.roleCodes()));
return user;
}
private SysOrgEntity buildOrg(String orgId, String orgName, String systemType) {
SysOrgEntity orgEntity = new SysOrgEntity();
orgEntity.setId(orgId);
orgEntity.setOrgName(orgName);
orgEntity.setContactPhone(DEFAULT_PHONE);
orgEntity.setContactEmail(buildOrgEmail(orgId, systemType));
orgEntity.setContactAddress(DEFAULT_ADDRESS);
orgEntity.setRegisteredAddress(DEFAULT_ADDRESS);
orgEntity.setBankName(DEFAULT_BANK);
orgEntity.setBankAccount(DEFAULT_BANK_ACCOUNT);
orgEntity.setLegalRepresentative(DEFAULT_LEGAL_REPRESENTATIVE);
orgEntity.setCreditCode(buildCreditCode(orgId, systemType));
orgEntity.setInvoiceTitleOptions(List.of(orgName, ROOT_ORG_NAME));
return orgEntity;
}
private String buildCreditCode(String orgId, String systemType) {
String prefix = "manage".equalsIgnoreCase(systemType) ? "91330200MANAGE" : "91330200BUSIN";
String suffix = String.format(Locale.ROOT, "%04d", parseNumericId(orgId));
return prefix + suffix;
}
private String buildOrgEmail(String orgId, String systemType) {
String prefix = "manage".equalsIgnoreCase(systemType) ? "manage" : "business";
return prefix + "." + orgId + DEFAULT_EMAIL_DOMAIN;
}
private String buildMobile(Long userId) {
long numeric = userId == null ? 0L : userId;
return String.format(Locale.ROOT, "138%08d", numeric % 100000000L);
}
private int parseNumericId(String orgId) {
if (orgId == null) {
return 0;
}
try {
return Integer.parseInt(orgId);
} catch (NumberFormatException ex) {
return 0;
}
}
public record MockUserProfile(
String key,
Long userId,
String username,
String displayName,
String systemType,
String orgId,
String orgName,
String deptName,
Long adminFlag,
String dataPermission,
boolean superAdmin,
Set<SysEnum> accessSystems,
List<String> roleCodes
) {
}
public record MockUserOptionDto(
String key,
String displayName,
String systemType,
String username,
Long userId,
String orgId,
String orgName,
String deptName,
boolean superAdmin,
List<SysEnum> accessSystems,
String dataPermission
) {
}
public record MockCurrentUserDto(
String key,
String displayName,
String systemType,
String username,
Long userId,
String orgId,
String orgName,
String deptName,
boolean superAdmin,
List<SysEnum> accessSystems,
String dataPermission
) {
}
}