diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/user/impl/UserFreightBalanceRestServiceImpl.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/user/impl/UserFreightBalanceRestServiceImpl.java index 72df16f2..8bc4da71 100644 --- a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/user/impl/UserFreightBalanceRestServiceImpl.java +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/user/impl/UserFreightBalanceRestServiceImpl.java @@ -3,7 +3,6 @@ package com.red.circle.other.app.service.user.impl; import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.red.circle.common.business.dto.cmd.AppExtCommand; import com.red.circle.framework.core.asserts.ResponseAssert; -import com.red.circle.framework.dto.PageQuery; import com.red.circle.framework.dto.PageResult; import com.red.circle.other.app.convertor.UserFreightBalanceConvertor; import com.red.circle.other.app.dto.clientobject.sys.AppCountryCodeCO; @@ -11,10 +10,10 @@ import com.red.circle.other.app.dto.clientobject.sys.CountryCodeCO; import com.red.circle.other.app.dto.clientobject.user.UserFreightBalanceCO; import com.red.circle.other.app.service.sys.AppConfigService; import com.red.circle.other.app.service.user.UserFreightBalanceRestService; -import com.red.circle.other.app.service.user.user.UserRegionService; import com.red.circle.other.domain.gateway.user.UserProfileGateway; -import com.red.circle.other.domain.gateway.user.ability.UserRegionGateway; import com.red.circle.other.domain.model.user.UserProfile; +import com.red.circle.other.infra.database.mongo.entity.user.region.SysRegionConfig; +import com.red.circle.other.infra.database.mongo.service.user.region.SysRegionConfigService; import com.red.circle.other.inner.endpoint.user.user.UserProfileClient; import com.red.circle.other.inner.model.dto.user.UserProfileDTO; import com.red.circle.wallet.inner.endpoint.freight.FreightBalanceClient; @@ -23,7 +22,15 @@ import com.red.circle.wallet.inner.model.cmd.UserFreightBalancePageQryCmd; import com.red.circle.wallet.inner.model.dto.UserFreightBalanceDTO; import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -32,8 +39,7 @@ import org.springframework.stereotype.Service; /** * 用户货运账户服务实现. * - * @author system - * @since 2025-10-21 + * @author tf */ @Slf4j @Service @@ -44,119 +50,123 @@ public class UserFreightBalanceRestServiceImpl implements UserFreightBalanceRest private final UserProfileClient userProfileClient; private final AppConfigService appConfigService; private final UserProfileGateway userProfileGateway; - private final UserRegionGateway userRegionGateway; private final UserFreightBalanceConvertor userFreightBalanceConvertor; + private final SysRegionConfigService regionConfigService; @Override public PageResult pageFreight(UserFreightBalancePageQryCmd cmd, AppExtCommand appExtCommand) { - // 获取请求用户的国家编码 - UserProfile userProfile = userProfileGateway.getByUserId(appExtCommand.getReqUserId()); - String countryCode = userProfile.getCountryCode(); + Long reqUserId = appExtCommand.requiredReqUserId(); + + // 获取当前用户所在区域的国家码集合 + Set regionCountryCodes = resolveReqUserRegionCountryCodes(reqUserId); cmd.setH5Display(true); cmd.setClose(false); - PageQuery pageQuery = cmd.getPageQuery(); + // 保存原始分页参数,全量拉取后内存过滤 + int pageNo = cmd.getPageQuery().getCursor(); + int pageSize = cmd.getPageQuery().getLimit(); + cmd.getPageQuery().setCursor(1); + cmd.getPageQuery().setLimit(500); - // 保存原始分页参数 - int pageNo = pageQuery.getCursor(); - int pageSize = pageQuery.getLimit(); - - pageQuery.setCursor(1); - pageQuery.setLimit(500); PageResult freightPageResult = freightGoldClient.pageFreight(cmd).getBody(); - if (freightPageResult.checkRecordsEmpty()) { return freightPageResult.emptyRecords(); } - - // 根据国家编码过滤数据 - List records = freightPageResult.getRecords().stream() - .filter(dto -> isCountrySupported(userProfile.getId(), dto.getUserId())) - .toList(); - List userProfiles = userProfileGateway.listByUserIds(records.stream().map(UserFreightBalanceDTO::getUserId).collect(Collectors.toSet())); - Set countryCodeSet = userProfiles.stream().map(UserProfile::getCountryCode).collect(Collectors.toSet()); - List filteredRecords = records.stream() - .filter(e -> countryCodeSet.contains(userProfile.getCountryCode())) - .collect(Collectors.toList()); + + // 批量查询 userId → countryCode,按区域过滤 + List allRecords = freightPageResult.getRecords(); + Set allUserIds = allRecords.stream().map(UserFreightBalanceDTO::getUserId).collect(Collectors.toSet()); + Map profileMap = userProfileGateway.mapByUserIds(allUserIds); + + List filteredRecords = allRecords.stream() + .filter(dto -> { + UserProfile profile = profileMap.get(dto.getUserId()); + return profile != null && regionCountryCodes.contains(profile.getCountryCode()); + }) + .collect(Collectors.toList()); if (filteredRecords.isEmpty()) { - return PageResult.newPageResult(20); + return PageResult.newPageResult(pageSize); } - + // 手动分页 int total = filteredRecords.size(); int fromIndex = (pageNo - 1) * pageSize; - int toIndex = Math.min(fromIndex + pageSize, total); - if (fromIndex >= total) { - return PageResult.newPageResult(20); + return PageResult.newPageResult(pageSize); } - - List pagedRecords = filteredRecords.subList(fromIndex, toIndex); - + List pagedRecords = filteredRecords.subList(fromIndex, Math.min(fromIndex + pageSize, total)); + + // 批量查询所需数据 + Set pagedUserIds = pagedRecords.stream().map(UserFreightBalanceDTO::getUserId).collect(Collectors.toSet()); + Map userBaseInfoMap = ResponseAssert.requiredSuccess(userProfileClient.mapByUserIds(pagedUserIds)); + Map transactionCountMap = freightGoldClient.mapTransactionCountByUserIds(pagedUserIds).getBody(); + Map followMap = userProfileGateway.mapIsFollow(reqUserId, pagedUserIds); + + AppCountryCodeCO appCountryCode = appConfigService.getAppCountryCode(); + Map countryFlagMap = buildCountryFlagMap(appCountryCode); + // 构建分页结果 PageResult pagedResult = new PageResult<>(); pagedResult.setRecords(pagedRecords); pagedResult.setTotal((long) total); pagedResult.setCurrent(pageNo); pagedResult.setSize(pageSize); - - if (pagedResult.checkRecordsEmpty()) { - return pagedResult.emptyRecords(); - } - - Set userIds = pagedResult.getRecords().stream() - .map(UserFreightBalanceDTO::getUserId) - .collect(Collectors.toSet()); - - // 查询用户基本信息 - Map userBaseInfoMap = ResponseAssert.requiredSuccess(userProfileClient.mapByUserIds(userIds)); - - Map transactionCountMap = freightGoldClient.mapTransactionCountByUserIds(userIds).getBody(); - AppCountryCodeCO appCountryCode = appConfigService.getAppCountryCode(); - - // 构建国家代码到国旗URL的映射 - Map countryFlagMap = buildCountryFlagMap(appCountryCode); PageResult result = pagedResult.convert(dto -> { UserFreightBalanceCO co = userFreightBalanceConvertor.toUserFreightBalanceCO(dto); co.setBalance(dto.getBalance()); - co.setIsFollow(userProfileGateway.checkFollow(appExtCommand.getReqUserId(), dto.getUserId())); + co.setIsFollow(Boolean.TRUE.equals(followMap.get(dto.getUserId()))); co.setUserBaseInfo(userBaseInfoMap.get(dto.getUserId())); - - // 计算成为代理天数 + if (dto.getCreateTime() != null) { - LocalDateTime createTime = dto.getCreateTime().toLocalDateTime(); - LocalDateTime now = LocalDateTime.now(); - long days = ChronoUnit.DAYS.between(createTime, now); + long days = ChronoUnit.DAYS.between(dto.getCreateTime().toLocalDateTime(), LocalDateTime.now()); co.setBecomeDays((int) days); } - - // 设置交易次数 - co.setTransactionCount( - Optional.ofNullable(transactionCountMap.get(dto.getUserId())).orElse(0L) - ); - - // 匹配并设置国旗URL + + co.setTransactionCount(Optional.ofNullable(transactionCountMap.get(dto.getUserId())).orElse(0L)); co.setNationalFlag(matchNationalFlag(dto.getSupportedCountries(), countryFlagMap)); if (co.getUserBaseInfo() != null) { - UserProfileDTO userBaseInfo = co.getUserBaseInfo(); - co.setOwnNationalFlag(countryFlagMap.get(userBaseInfo.getCountryName())); + co.setOwnNationalFlag(countryFlagMap.get(co.getUserBaseInfo().getCountryName())); } return co; }); - result.setRecords(result.getRecords().stream().sorted(Comparator.comparing(UserFreightBalanceCO::getTransactionCount).reversed()).collect(Collectors.toList())); + result.setRecords(result.getRecords().stream() + .sorted(Comparator.comparing(UserFreightBalanceCO::getTransactionCount).reversed()) + .collect(Collectors.toList())); return result; } /** - * 检查国家是否在支持列表中. + * 获取当前用户所在区域的国家码集合. */ - private boolean isCountrySupported(Long userId, Long dtoUserId) { - return userRegionGateway.checkEqRegion(userId, dtoUserId); + private Set resolveReqUserRegionCountryCodes(Long reqUserId) { + UserProfile userProfile = userProfileGateway.getByUserId(reqUserId); + if (userProfile == null || userProfile.getCountryCode() == null) { + return Set.of(); + } + + // 通过 countryCode 在所有区域配置中找到所属区域 + List allRegions = regionConfigService.listAvailable(userProfile.getOriginSys()); + SysRegionConfig matchedRegion = allRegions.stream() + .filter(r -> StringUtils.isNotBlank(r.getCountryCodes()) + && Arrays.asList(r.getCountryCodes().split(",")).stream() + .map(String::trim) + .anyMatch(c -> c.equalsIgnoreCase(userProfile.getCountryCode()))) + .findFirst() + .orElse(null); + + if (matchedRegion == null || StringUtils.isBlank(matchedRegion.getCountryCodes())) { + return Set.of(userProfile.getCountryCode()); + } + + return Arrays.stream(matchedRegion.getCountryCodes().split(",")) + .map(String::trim) + .filter(StringUtils::isNotBlank) + .collect(Collectors.toSet()); } /** @@ -166,41 +176,25 @@ public class UserFreightBalanceRestServiceImpl implements UserFreightBalanceRest if (appCountryCode == null || appCountryCode.getOpenCountry() == null) { return Map.of(); } - return appCountryCode.getOpenCountry().stream() - .filter(country -> StringUtils.isNotBlank(country.getCountryName()) && StringUtils.isNotBlank(country.getNationalFlag())) - .collect(Collectors.toMap( - CountryCodeCO::getCountryName, - CountryCodeCO::getNationalFlag, - (existing, replacement) -> existing - )); + .filter(c -> StringUtils.isNotBlank(c.getCountryName()) && StringUtils.isNotBlank(c.getNationalFlag())) + .collect(Collectors.toMap(CountryCodeCO::getCountryName, CountryCodeCO::getNationalFlag, (a, b) -> a)); } /** - * 匹配国旗URL. - * - * @param supportedCountries 支持的国家(逗号分隔) - * @param countryFlagMap 国家代码到国旗URL的映射 - * @return 所有匹配的国旗URL(逗号分隔),如果没有匹配则返回空字符串 + * 匹配国旗URL列表. */ private List matchNationalFlag(String supportedCountries, Map countryFlagMap) { if (supportedCountries == null || supportedCountries.isEmpty() || countryFlagMap.isEmpty()) { - return new ArrayList<>(0); + return new ArrayList<>(0); } - - // 分割支持的国家代码 - String[] countries = supportedCountries.split(","); - - // 收集所有匹配到的国旗URL List flagUrls = new ArrayList<>(); - for (String country : countries) { - String countryCode = country.trim(); - if (countryFlagMap.containsKey(countryCode)) { - flagUrls.add(countryFlagMap.get(countryCode)); + for (String country : supportedCountries.split(",")) { + String flag = countryFlagMap.get(country.trim()); + if (flag != null) { + flagUrls.add(flag); } } - return flagUrls; } - } diff --git a/rc-service/rc-service-other/other-domain/src/main/java/com/red/circle/other/domain/gateway/user/UserProfileGateway.java b/rc-service/rc-service-other/other-domain/src/main/java/com/red/circle/other/domain/gateway/user/UserProfileGateway.java index 73b020d4..9f94171a 100644 --- a/rc-service/rc-service-other/other-domain/src/main/java/com/red/circle/other/domain/gateway/user/UserProfileGateway.java +++ b/rc-service/rc-service-other/other-domain/src/main/java/com/red/circle/other/domain/gateway/user/UserProfileGateway.java @@ -186,6 +186,15 @@ public interface UserProfileGateway { */ List getUserNobleAbility(Long userId); + /** + * 批量检测关注关系. + * + * @param userId 用户id + * @param followUserIds 被关注用户id集合 + * @return key=被关注用户id, value=是否关注 + */ + Map mapIsFollow(Long userId, Set followUserIds); + /** * 修改用户签名为空. */ diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/gateway/user/UserProfileGatewayImpl.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/gateway/user/UserProfileGatewayImpl.java index edb6b23c..f29c0c74 100644 --- a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/gateway/user/UserProfileGatewayImpl.java +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/gateway/user/UserProfileGatewayImpl.java @@ -566,6 +566,14 @@ public class UserProfileGatewayImpl implements UserProfileGateway { .orElse(null); } + @Override + public Map mapIsFollow(Long userId, Set followUserIds) { + if (CollectionUtils.isEmpty(followUserIds)) { + return Maps.newHashMap(); + } + return userSubscriptionService.mapIsSubscription(userId, followUserIds); + } + @Override public void updateBatchUserAutographEmpty(Collection ids) { if (CollectionUtils.isEmpty(ids)) {