11
This commit is contained in:
1 parent
b254ef0783
commit
3effd6f9be
13 files changed
+275
-24
No files matched your search
+5
@@ -34,4 +34,9 @@ public class HardOfflineUserSyncDto {
|
||||
*/
|
||||
@Min(value = 0, message = "离线人员同步快照上界无效")
|
||||
private Long snapshotMaxId;
|
||||
|
||||
/**
|
||||
* 是否同步全租户人员;仅非生产调试使用,生产端点行为与本部门一致。
|
||||
*/
|
||||
private Boolean allTenant;
|
||||
}
|
||||
+49
-24
@@ -27,11 +27,11 @@ import com.bsd.pjcloud.wallet.api.feign.RemoteWalletService;
|
||||
import com.bsd.pjcloud.wallet.api.vo.MchManageVo;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@@ -57,6 +57,7 @@ public class HardApiServiceImpl implements HardApiService {
|
||||
private final RemoteDeptService remoteDeptService;
|
||||
private final HardManagerMapper hardManagerMapper;
|
||||
private final HardManagerService hardManagerService;
|
||||
private final Environment environment;
|
||||
|
||||
@Override
|
||||
public HardAdUserVo getUserById(Long userId, HardTypeEnum type) {
|
||||
@@ -121,12 +122,13 @@ public class HardApiServiceImpl implements HardApiService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 按设备绑定部门树返回脱敏后的离线人员游标快照。
|
||||
* 按设备绑定部门树(或全租户)返回脱敏后的离线人员游标快照。
|
||||
*
|
||||
* <p>部门范围、钱包类型全部由 DEVICE-ID 对应的真实绑定关系解析;姓名只保留
|
||||
* 首字符,其余以星号替代,且不返回手机号和头像。未绑定当前类型钱包、卡号为空
|
||||
* 或钱包已冻结的用户不进入快照;游标始终按部门全部用户主键推进,被过滤用户
|
||||
* 不会造成分页重复。</p>
|
||||
* 或钱包已冻结的用户不进入快照;游标始终按用户主键推进,被过滤用户不会造成
|
||||
* 分页重复。allTenant 仅用于非生产调试的全租户同步,生产环境调用时仍按设备
|
||||
* 绑定部门返回。</p>
|
||||
*/
|
||||
@Override
|
||||
public HardOfflineUserSyncSnapshotVo syncOfflineUserSnapshot(Long hardId, HardOfflineUserSyncDto dto) {
|
||||
@@ -140,27 +142,25 @@ public class HardApiServiceImpl implements HardApiService {
|
||||
? WalletTypeEnum.EAT
|
||||
: WalletTypeEnum.PAY;
|
||||
|
||||
List<Long> deptIds = resolveDepartmentTree(trustedDevice.merchantDeptId());
|
||||
if (deptIds.isEmpty()) {
|
||||
final boolean allTenant = Boolean.TRUE.equals(dto.getAllTenant()) && !isProdProfile();
|
||||
final List<Long> deptIds = allTenant
|
||||
? null
|
||||
: resolveDepartmentTree(trustedDevice.merchantDeptId());
|
||||
if (!allTenant && deptIds.isEmpty()) {
|
||||
throw new RuntimeException("设备绑定部门不存在或已删除");
|
||||
}
|
||||
|
||||
R<List<SysUser>> userResponse = userService.getUserIdListByDeptIdList(deptIds);
|
||||
if (userResponse == null || !userResponse.isOk() || userResponse.getData() == null) {
|
||||
String message = userResponse == null || StrUtil.isBlank(userResponse.getMsg())
|
||||
? "查询部门用户失败"
|
||||
: userResponse.getMsg();
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
List<SysUser> users = userResponse.getData().stream()
|
||||
.filter(user -> user.getUserId() != null && StrUtil.isNotBlank(user.getName()))
|
||||
.sorted(Comparator.comparing(SysUser::getUserId))
|
||||
.toList();
|
||||
|
||||
long normalizedAfterId = dto.getAfterId();
|
||||
Long requestedSnapshotMaxId = dto.getSnapshotMaxId();
|
||||
if (requestedSnapshotMaxId == null) {
|
||||
requestedSnapshotMaxId = users.isEmpty() ? 0L : users.get(users.size() - 1).getUserId();
|
||||
R<Long> maxIdResponse = userService.getOfflineUserMaxId(deptIds);
|
||||
if (maxIdResponse == null || !maxIdResponse.isOk()) {
|
||||
String message = maxIdResponse == null || StrUtil.isBlank(maxIdResponse.getMsg())
|
||||
? "查询离线人员快照上界失败"
|
||||
: maxIdResponse.getMsg();
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
requestedSnapshotMaxId = maxIdResponse.getData() == null ? 0L : maxIdResponse.getData();
|
||||
}
|
||||
final long normalizedSnapshotMaxId = requestedSnapshotMaxId;
|
||||
if (normalizedAfterId > normalizedSnapshotMaxId) {
|
||||
@@ -168,11 +168,8 @@ public class HardApiServiceImpl implements HardApiService {
|
||||
}
|
||||
int normalizedLimit = dto.getLimit() == null ? OFFLINE_USER_SYNC_DEFAULT_LIMIT : dto.getLimit();
|
||||
|
||||
List<SysUser> fetchedPage = users.stream()
|
||||
.filter(user -> user.getUserId() > normalizedAfterId
|
||||
&& user.getUserId() <= normalizedSnapshotMaxId)
|
||||
.limit(normalizedLimit + 1L)
|
||||
.toList();
|
||||
// 多取一条用于判断是否还有下一页;用户过滤发生在钱包聚合之后,不影响游标推进。
|
||||
List<SysUser> fetchedPage = fetchUserCursorPage(deptIds, normalizedAfterId, normalizedLimit + 1);
|
||||
boolean hasMore = fetchedPage.size() > normalizedLimit;
|
||||
List<SysUser> pageUsers = hasMore ? fetchedPage.subList(0, normalizedLimit) : fetchedPage;
|
||||
|
||||
@@ -187,6 +184,34 @@ public class HardApiServiceImpl implements HardApiService {
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从用户服务按主键游标取一页部门范围(空为全租户)内的用户并过滤无效记录。
|
||||
*/
|
||||
private List<SysUser> fetchUserCursorPage(List<Long> deptIds, long afterId, int limit) {
|
||||
R<List<SysUser>> response = userService.getOfflineUserCursor(deptIds, afterId, limit);
|
||||
if (response == null || !response.isOk() || response.getData() == null) {
|
||||
String message = response == null || StrUtil.isBlank(response.getMsg())
|
||||
? "查询部门用户失败"
|
||||
: response.getMsg();
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
return response.getData().stream()
|
||||
.filter(user -> user.getUserId() != null && StrUtil.isNotBlank(user.getName()))
|
||||
.toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前服务是否运行在生产配置;生产环境强制收敛为部门范围同步。
|
||||
*/
|
||||
private boolean isProdProfile() {
|
||||
for (String profile : environment.getActiveProfiles()) {
|
||||
if (StrUtil.containsIgnoreCase(profile, "prod")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将一页部门用户组装为脱敏离线人员记录;食堂归属按部门聚合缓存一次查询。
|
||||
*/
|
||||
|
||||
Reference in new issue
Block a user