diff --git a/nacos_config/rc-gateway/application.yml b/nacos_config/rc-gateway/application.yml
index 1dbde5bf..1c584efb 100644
--- a/nacos_config/rc-gateway/application.yml
+++ b/nacos_config/rc-gateway/application.yml
@@ -175,6 +175,7 @@ gateway:
- /product/apple/config
- /game/sud/**
- /web/pay/**
+ - /order/web/pay/**
- /external/oss/upload
- /telegram/webhook
- /account/create/getRegion
diff --git a/rc-service/rc-inner-api/order-inner/order-inner-model/src/main/java/com/red/circle/order/inner/model/cmd/SysPayApplicationCommodityCmd.java b/rc-service/rc-inner-api/order-inner/order-inner-model/src/main/java/com/red/circle/order/inner/model/cmd/SysPayApplicationCommodityCmd.java
index 30b8ce3e..3610706b 100644
--- a/rc-service/rc-inner-api/order-inner/order-inner-model/src/main/java/com/red/circle/order/inner/model/cmd/SysPayApplicationCommodityCmd.java
+++ b/rc-service/rc-inner-api/order-inner/order-inner-model/src/main/java/com/red/circle/order/inner/model/cmd/SysPayApplicationCommodityCmd.java
@@ -3,13 +3,14 @@ package com.red.circle.order.inner.model.cmd;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.red.circle.framework.core.dto.CommonCommand;
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-import java.io.Serial;
-import java.math.BigDecimal;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.experimental.Accessors;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import java.io.Serial;
+import java.math.BigDecimal;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
/**
*
@@ -43,11 +44,17 @@ public class SysPayApplicationCommodityCmd extends CommonCommand {
/**
* 开通支付国家.
*/
- @JsonSerialize(using = ToStringSerializer.class)
- private Long payCountryId;
-
- /**
- * 区域ID.
+ @JsonSerialize(using = ToStringSerializer.class)
+ private Long payCountryId;
+
+ /**
+ * 批量创建时的国家列表;表结构仍是一条商品对应一个国家,所以只在新增时拆成多条记录.
+ */
+ @JsonSerialize(contentUsing = ToStringSerializer.class)
+ private List payCountryIds;
+
+ /**
+ * 区域ID.
*/
private String regionId;
diff --git a/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/PayWebApplicationCommodityV2QueryExe.java b/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/PayWebApplicationCommodityV2QueryExe.java
index c5655d38..a3f50b40 100644
--- a/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/PayWebApplicationCommodityV2QueryExe.java
+++ b/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/PayWebApplicationCommodityV2QueryExe.java
@@ -1,12 +1,13 @@
package com.red.circle.order.app.command.pay.web;
-import com.google.api.client.util.Lists;
-import com.google.api.client.util.Maps;
-import com.google.api.client.util.Sets;
-import com.red.circle.common.business.core.amount.PayAmountArithmeticUtils;
-import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
-import com.red.circle.framework.core.asserts.ResponseAssert;
-import com.red.circle.framework.core.response.CommonErrorCode;
+import com.google.api.client.util.Lists;
+import com.google.api.client.util.Maps;
+import com.google.api.client.util.Sets;
+import com.red.circle.common.business.core.amount.PayAmountArithmeticUtils;
+import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
+import com.red.circle.common.business.core.util.CountryCodeAliasUtils;
+import com.red.circle.framework.core.asserts.ResponseAssert;
+import com.red.circle.framework.core.response.CommonErrorCode;
import com.red.circle.order.app.convertor.PayAppConvertor;
import com.red.circle.order.app.dto.clientobject.pay.ApplicationCommodityCardV2CO;
import com.red.circle.order.app.dto.clientobject.pay.PayApplicationCO;
@@ -23,6 +24,8 @@ import com.red.circle.order.infra.database.rds.service.pay.PayApplicationCommodi
import com.red.circle.order.infra.database.rds.service.pay.PayApplicationService;
import com.red.circle.order.infra.database.rds.service.pay.PayChannelService;
import com.red.circle.order.infra.database.rds.service.pay.PayCountryChannelDetailsService;
+import com.red.circle.other.inner.endpoint.sys.SysCountryCodeClient;
+import com.red.circle.other.inner.model.dto.sys.SysCountryCodeDTO;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.num.ArithmeticUtils;
import com.red.circle.tool.core.text.StringUtils;
@@ -54,6 +57,7 @@ public class PayWebApplicationCommodityV2QueryExe {
private final PayCountryAliasResolver payCountryAliasResolver;
private final PayApplicationCommodityService payApplicationCommodityService;
private final PayCountryChannelDetailsService payCountryChannelDetailsService;
+ private final SysCountryCodeClient sysCountryCodeClient;
public ApplicationCommodityCardV2CO execute(PayWebApplicationCommodityCmd cmd) {
@@ -165,7 +169,17 @@ public class PayWebApplicationCommodityV2QueryExe {
}
private PayCountry getPayCountry(PayWebApplicationCommodityCmd cmd) {
- return payCountryAliasResolver.resolveUsablePayCountry(cmd.getPayCountryId());
+ if (Objects.nonNull(cmd.getPayCountryId()) || StringUtils.isBlank(cmd.getCountryCode())) {
+ return payCountryAliasResolver.resolveUsablePayCountry(cmd.getPayCountryId());
+ }
+
+ String normalizedCountryCode = CountryCodeAliasUtils.normalizePaymentCountryCode(
+ cmd.getCountryCode());
+ SysCountryCodeDTO countryCode = ResponseAssert.requiredSuccess(
+ sysCountryCodeClient.getByCode(normalizedCountryCode));
+ ResponseAssert.notNull(CommonErrorCode.NOT_SUPPORTED_REGION, countryCode);
+ // H5 只传用户国家码;这里仅把真实国家转成商品表使用的支付国家ID,是否开放支付国家由 H5 JSON 控制.
+ return payCountryAliasResolver.resolveUsablePayCountryByCountryId(countryCode.getId());
}
private List getPayChannels(List payChannels,
diff --git a/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/PayWebOrderStatusQueryExe.java b/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/PayWebOrderStatusQueryExe.java
index 49d44cb5..5c8e25e6 100644
--- a/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/PayWebOrderStatusQueryExe.java
+++ b/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/PayWebOrderStatusQueryExe.java
@@ -26,8 +26,10 @@ public class PayWebOrderStatusQueryExe {
public PayOrderStatusCO execute(PayOrderStatusCmd cmd) {
OrderUserPurchasePay mysqlOrder = getMysqlOrder(cmd.getOrderId());
ResponseAssert.notNull(OrderErrorCode.NO_PURCHASE_RECORD_FOUND, mysqlOrder);
+ Long expectedUserId = Objects.nonNull(cmd.getReqUserId()) ? cmd.getReqUserId() : cmd.getUserId();
+ // 登录态请求继续使用网关注入的 reqUserId;公开 H5 轮询没有登录态,只允许用下单用户ID校验同一笔订单.
ResponseAssert.isTrue(OrderErrorCode.NO_PURCHASE_RECORD_FOUND,
- Objects.equals(mysqlOrder.getUserId(), cmd.getReqUserId()));
+ Objects.nonNull(expectedUserId) && Objects.equals(mysqlOrder.getUserId(), expectedUserId));
InAppPurchaseStatus status = MiFaPayMysqlOrderSupport
.toInAppPurchaseStatus(mysqlOrder.getPayStatus());
return new PayOrderStatusCO()
diff --git a/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/UserProfileAndCountryQueryExe.java b/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/UserProfileAndCountryQueryExe.java
index 67f799c2..8d6f47d7 100644
--- a/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/UserProfileAndCountryQueryExe.java
+++ b/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/UserProfileAndCountryQueryExe.java
@@ -14,17 +14,15 @@ import com.red.circle.other.inner.endpoint.sys.SysCountryCodeClient;
import com.red.circle.other.inner.model.dto.sys.SysCountryCodeDTO;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.parse.DataTypeUtils;
-import com.red.circle.tool.core.regex.RegexConstant;
-import com.red.circle.tool.core.text.StringUtils;
-import com.red.circle.other.inner.asserts.user.UserErrorCode;
-import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
-import com.red.circle.other.inner.model.dto.user.reigon.RegionRelationDTO;
-import com.red.circle.other.inner.enums.user.RegionRelationGroupEnum;
-import com.red.circle.other.inner.endpoint.user.region.RegionRelationClient;
-import com.red.circle.other.inner.endpoint.user.region.UserRegionClient;
-import com.red.circle.other.inner.endpoint.user.user.UserProfileClient;
+import com.red.circle.tool.core.regex.RegexConstant;
+import com.red.circle.tool.core.text.StringUtils;
+import com.red.circle.other.inner.asserts.user.UserErrorCode;
+import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
+import com.red.circle.other.inner.endpoint.user.region.UserRegionClient;
+import com.red.circle.other.inner.endpoint.user.user.UserProfileClient;
import com.red.circle.wallet.inner.endpoint.freight.FreightGoldClient;
import java.util.AbstractMap;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -47,9 +45,8 @@ public class UserProfileAndCountryQueryExe {
private final PayCountryAliasResolver payCountryAliasResolver;
private final UserProfileClient userProfileClient;
private final SysCountryCodeClient sysCountryCodeClient;
- private final RegionRelationClient regionRelationClient;
-
- public UserProfileAndCountryCO execute(PayWebUserCmd cmd) {
+
+ public UserProfileAndCountryCO execute(PayWebUserCmd cmd) {
UserProfileDTO userProfile = getUserProfile(cmd);
@@ -64,27 +61,17 @@ public class UserProfileAndCountryQueryExe {
.toWebSiteUseProfileCO(userProfile);
webSiteUseProfile.setAccount(userProfile.actualAccount());
- List payCountryList;
-
- String regionId = ResponseAssert.requiredSuccess(
- userRegionClient.getRegionId(userProfile.getId())
- );
-
- if (Objects.equals(cmd.getSysOrigin(), SysOriginPlatformEnum.LIKEI.name())) {
- ResponseAssert.isTrue(CommonErrorCode.NOT_SUPPORTED_REGION, StringUtils.isNotBlank(regionId));
-
- List regionRelationList = getRegionRelationList(userProfile, regionId);
- ResponseAssert.notEmpty(CommonErrorCode.NOT_SUPPORTED_REGION, regionRelationList);
-
- payCountryList = getPayCountryList(regionRelationList);
- ResponseAssert.notEmpty(CommonErrorCode.NOT_SUPPORTED_REGION, payCountryList);
-
- } else {
- payCountryList = payCountryService.listAllShelf();
- }
-
- Map mapCountryCode = getMapCountryCode(payCountryList);
- ResponseAssert.notEmpty(CommonErrorCode.NOT_SUPPORTED_REGION, mapCountryCode);
+ String regionId = ResponseAssert.requiredSuccess(
+ userRegionClient.getRegionId(userProfile.getId())
+ );
+
+ if (Objects.equals(cmd.getSysOrigin(), SysOriginPlatformEnum.LIKEI.name())) {
+ return toLikeiUserCountryResult(userProfile, webSiteUseProfile, regionId);
+ }
+
+ List payCountryList = payCountryService.listAllShelf();
+ Map mapCountryCode = getMapCountryCode(payCountryList);
+ ResponseAssert.notEmpty(CommonErrorCode.NOT_SUPPORTED_REGION, mapCountryCode);
Map compatiblePayCountryMap = getCompatiblePayCountryMap(payCountryList);
return new UserProfileAndCountryCO()
@@ -105,9 +92,48 @@ public class UserProfileAndCountryQueryExe {
}).filter(Objects::nonNull).collect(Collectors.toList()))
.setUserProfile(webSiteUseProfile)
- .setRegionId(regionId);
-
- }
+ .setRegionId(regionId);
+
+ }
+
+ private UserProfileAndCountryCO toLikeiUserCountryResult(UserProfileDTO userProfile,
+ WebSiteUseProfileCO webSiteUseProfile, String regionId) {
+
+ SysCountryCodeDTO countryCode = getUserCountryCode(userProfile);
+ ResponseAssert.notNull(CommonErrorCode.NOT_SUPPORTED_REGION, countryCode);
+
+ PayCountry compatiblePayCountry = payCountryAliasResolver
+ .resolveUsablePayCountryByCountryId(countryCode.getId());
+
+ // LIKEI/Yumi 的支付国家开放由 H5 JSON 控制;这里仅返回用户真实国家,商品接口再按国家码查该国商品.
+ PayCountryCO payCountryCO = new PayCountryCO()
+ .setId(Objects.nonNull(compatiblePayCountry) ? compatiblePayCountry.getId() : null)
+ .setPayCountryId(Objects.nonNull(compatiblePayCountry) ? compatiblePayCountry.getId() : null)
+ .setCountryId(countryCode.getId())
+ .setCurrency(Objects.nonNull(compatiblePayCountry) ? compatiblePayCountry.getCurrency() : null)
+ .setCountry(countryCode);
+
+ return new UserProfileAndCountryCO()
+ .setCountryList(Collections.singletonList(payCountryCO))
+ .setUserProfile(webSiteUseProfile)
+ .setRegionId(regionId);
+ }
+
+ private SysCountryCodeDTO getUserCountryCode(UserProfileDTO userProfile) {
+ if (Objects.nonNull(userProfile.getCountryId())) {
+ return ResponseAssert.requiredSuccess(
+ sysCountryCodeClient.getById(userProfile.getCountryId())
+ );
+ }
+
+ if (StringUtils.isNotBlank(userProfile.getCountryCode())) {
+ return ResponseAssert.requiredSuccess(
+ sysCountryCodeClient.getByCode(userProfile.getCountryCode())
+ );
+ }
+
+ return null;
+ }
private UserProfileDTO getUserProfile(PayWebUserCmd cmd) {
if (StringUtils.isNotBlank(cmd.getAccount()) && StringUtils.isNotBlank(cmd.getSysOrigin())) {
@@ -146,18 +172,4 @@ public class UserProfileAndCountryQueryExe {
(left, right) -> left));
}
- private List getRegionRelationList(UserProfileDTO userProfile,
- String regionId) {
- return ResponseAssert.requiredSuccess(
- regionRelationClient
- .listByRegionId(regionId, userProfile.getOriginSys(),
- RegionRelationGroupEnum.OPEN_PAY_COUNTRY)
- );
- }
-
- private List getPayCountryList(List regionRelationList) {
- return payCountryService
- .listByIds(regionRelationList.stream().map(RegionRelationDTO::getRelationId).collect(
- Collectors.toSet()));
- }
-}
+}
diff --git a/rc-service/rc-service-order/order-client/src/main/java/com/red/circle/order/app/dto/cmd/PayOrderStatusCmd.java b/rc-service/rc-service-order/order-client/src/main/java/com/red/circle/order/app/dto/cmd/PayOrderStatusCmd.java
index 4602efed..0c63c1ec 100644
--- a/rc-service/rc-service-order/order-client/src/main/java/com/red/circle/order/app/dto/cmd/PayOrderStatusCmd.java
+++ b/rc-service/rc-service-order/order-client/src/main/java/com/red/circle/order/app/dto/cmd/PayOrderStatusCmd.java
@@ -23,4 +23,9 @@ public class PayOrderStatusCmd extends AppExtCommand {
*/
@NotBlank(message = "orderId required.")
private String orderId;
+
+ /**
+ * H5公开支付页没有登录态,轮询状态时必须用下单用户ID继续做订单归属校验.
+ */
+ private Long userId;
}
diff --git a/rc-service/rc-service-order/order-client/src/main/java/com/red/circle/order/app/dto/cmd/PayWebApplicationCommodityCmd.java b/rc-service/rc-service-order/order-client/src/main/java/com/red/circle/order/app/dto/cmd/PayWebApplicationCommodityCmd.java
index ea70330e..411e8b34 100644
--- a/rc-service/rc-service-order/order-client/src/main/java/com/red/circle/order/app/dto/cmd/PayWebApplicationCommodityCmd.java
+++ b/rc-service/rc-service-order/order-client/src/main/java/com/red/circle/order/app/dto/cmd/PayWebApplicationCommodityCmd.java
@@ -27,13 +27,18 @@ public class PayWebApplicationCommodityCmd extends AppExtCommand {
@NotNull(message = "applicationId required.")
private Long applicationId;
- /**
- * 国家.
- */
- private Long payCountryId;
-
- /**
- * 金币类型.
+ /**
+ * 国家.
+ */
+ private Long payCountryId;
+
+ /**
+ * 国家编码;H5 先拿用户国家,再用国家码查询商品,避免前端硬编码支付国家ID.
+ */
+ private String countryCode;
+
+ /**
+ * 金币类型.
*/
private PayApplicationCommodityType type;
diff --git a/rc-service/rc-service-order/order-inner-endpoint/src/main/java/com/red/circle/order/inner/service/impl/PayApplicationClientServiceImpl.java b/rc-service/rc-service-order/order-inner-endpoint/src/main/java/com/red/circle/order/inner/service/impl/PayApplicationClientServiceImpl.java
index 327411a2..bd1c7e85 100644
--- a/rc-service/rc-service-order/order-inner-endpoint/src/main/java/com/red/circle/order/inner/service/impl/PayApplicationClientServiceImpl.java
+++ b/rc-service/rc-service-order/order-inner-endpoint/src/main/java/com/red/circle/order/inner/service/impl/PayApplicationClientServiceImpl.java
@@ -1,8 +1,9 @@
package com.red.circle.order.inner.service.impl;
-import com.alibaba.nacos.shaded.com.google.common.collect.Lists;
-import com.red.circle.framework.core.asserts.ResponseAssert;
-import com.red.circle.framework.dto.PageResult;
+import com.alibaba.nacos.shaded.com.google.common.collect.Lists;
+import com.red.circle.framework.core.asserts.ResponseAssert;
+import com.red.circle.framework.core.response.CommonErrorCode;
+import com.red.circle.framework.dto.PageResult;
import com.red.circle.order.infra.database.rds.entity.pay.PayApplication;
import com.red.circle.order.infra.database.rds.entity.pay.PayApplicationCommodity;
import com.red.circle.order.infra.database.rds.service.pay.PayApplicationCommodityService;
@@ -13,16 +14,17 @@ import com.red.circle.order.inner.model.cmd.SysPayApplicationCommodityQryCmd;
import com.red.circle.order.inner.model.dto.SysPayApplicationCommodityDTO;
import com.red.circle.order.inner.model.dto.SysPayApplicationDTO;
import com.red.circle.order.inner.service.PayApplicationClientService;
-import com.red.circle.tool.core.collection.CollectionUtils;
-import com.red.circle.tool.core.text.StringUtils;
-import com.red.circle.other.inner.endpoint.user.region.RegionConfigClient;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.stream.Collectors;
-import lombok.RequiredArgsConstructor;
-import org.springframework.stereotype.Service;
+import com.red.circle.tool.core.collection.CollectionUtils;
+import com.red.circle.tool.core.text.StringUtils;
+import com.red.circle.other.inner.endpoint.user.region.RegionConfigClient;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
/**
* 开通支付应用.
@@ -106,11 +108,31 @@ public class PayApplicationClientServiceImpl implements PayApplicationClientServ
Collectors.toSet())));
}
- @Override
- public void addOrUpdateCommodity(SysPayApplicationCommodityCmd param) {
- payApplicationCommodityService.saveOrUpdate(
- webPayInnerConvertor.toPayApplicationCommodity(param));
- }
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void addOrUpdateCommodity(SysPayApplicationCommodityCmd param) {
+ if (Objects.nonNull(param.getId()) || CollectionUtils.isEmpty(param.getPayCountryIds())) {
+ // 编辑沿用原来的单条更新;批量国家只服务新增,避免一次编辑误伤多个已存在商品.
+ payApplicationCommodityService.saveOrUpdate(
+ webPayInnerConvertor.toPayApplicationCommodity(param));
+ return;
+ }
+
+ List commodities = param.getPayCountryIds().stream()
+ .filter(Objects::nonNull)
+ .distinct()
+ .map(payCountryId -> {
+ PayApplicationCommodity commodity = webPayInnerConvertor.toPayApplicationCommodity(param);
+ // 商品表当前以国家维度存储,新增多选国家时需要拆成多条独立商品记录.
+ commodity.setId(null);
+ commodity.setPayCountryId(payCountryId);
+ return commodity;
+ })
+ .collect(Collectors.toList());
+
+ ResponseAssert.notEmpty(CommonErrorCode.NOT_FOUND_RECORD_INFO, commodities);
+ payApplicationCommodityService.saveBatch(commodities);
+ }
@Override
public void switchShelf(Long id, Boolean shelf) {
diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/team/query/TeamMemberListQryExe.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/team/query/TeamMemberListQryExe.java
index 402a7999..1a67e3a9 100644
--- a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/team/query/TeamMemberListQryExe.java
+++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/team/query/TeamMemberListQryExe.java
@@ -1,5 +1,5 @@
package com.red.circle.other.app.command.team.query;
-
+
import com.google.common.collect.Lists;
import com.red.circle.common.business.dto.cmd.app.AppIdLongCmd;
import com.red.circle.other.app.convertor.user.UserProfileAppConvertor;
@@ -24,10 +24,10 @@ import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;
-
+
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
-
+
/**
* 团队成员列表.
*
@@ -36,58 +36,43 @@ import org.springframework.stereotype.Component;
@Component
@RequiredArgsConstructor
public class TeamMemberListQryExe {
-
+
private final TeamMemberService teamMemberService;
private final UserProfileGateway userProfileGateway;
private final UserProfileAppConvertor userProfileAppConvertor;
private final TeamMemberTargetService teamMemberTargetService;
private final TeamPolicyManagerService teamPolicyManagerService;
private final TeamProfileService teamProfileService;
-
+
public List execute(AppIdLongCmd cmd) {
-
+
List teamMembers = teamMemberService.listTeamMember(cmd.getId(),
3000);
if (CollectionUtils.isEmpty(teamMembers)) {
return Lists.newArrayList();
}
-
+
Set memberUserIds = teamMembers.stream().map(TeamMember::getMemberId)
.collect(Collectors.toSet());
Map userProfileMap = userProfileAppConvertor.toMapUserProfileDTO(
userProfileGateway.mapByUserIds(memberUserIds));
-
+
Map teamMemberTargetMap = teamMemberTargetService.mapMemberBillTarget(
cmd.getId(), memberUserIds, ZonedDateTimeAsiaRiyadhUtils.nowYearMonthToInt());
-
- List teamMemberCOs = teamMembers.stream().map(teamMember -> new TeamMemberCO()
- .setId(teamMember.getMemberId())
- .setUserProfile(userProfileMap.get(teamMember.getMemberId()))
- .setTargetFormat(Optional.ofNullable(teamMemberTargetMap.get(teamMember.getMemberId()))
- .map(target -> NumUtils.formatLong(target.sumAcceptGiftValue()))
- .orElse("0"))
- .setTimeHours(Optional.ofNullable(teamMemberTargetMap.get(teamMember.getMemberId()))
- .map(target -> BigDecimal.valueOf(target.sumAllTargetTime())
- .divide(BigDecimal.valueOf(60), 2, RoundingMode.DOWN)
- .stripTrailingZeros().toPlainString())
- .orElse("0"))
- .setEffectiveDay(Optional.ofNullable(teamMemberTargetMap.get(teamMember.getMemberId()))
- .map(TeamMemberTarget::sumEffectiveDay)
- .orElse(0))
- .setUseDiamonds("0")
- .setSurplusDiamonds("0")
- .setRole(Objects.toString(teamMember.getRole()))
- .setWalletWithdrawal(Objects.isNull(teamMember.getWalletWithdrawal()) || Objects.equals(
- teamMember.getWalletWithdrawal(), Boolean.TRUE))
- .setCreateTime(teamMember.getCreateTime())
- ).collect(Collectors.toList());
+
+ List teamMemberCOs = teamMembers.stream()
+ .map(teamMember -> assembleTeamMemberCO(
+ teamMember,
+ userProfileMap.get(teamMember.getMemberId()),
+ teamMemberTargetMap.get(teamMember.getMemberId())))
+ .collect(Collectors.toList());
return teamMemberCOs;
}
-
+
public TeamMemberCountResultCO executeCount(AppIdLongCmd cmd) {
List teamMembers = teamMemberService.listTeamMember(cmd.getId(),
3000);
-
+
if (CollectionUtils.isEmpty(teamMembers)) {
return new TeamMemberCountResultCO()
.setMemberQuantity(0)
@@ -95,7 +80,7 @@ public class TeamMemberListQryExe {
.setTargetFormatSum("0")
.setTargetSum(0L);
}
-
+
// 获取团队信息和政策管理器
TeamProfile teamProfile = teamProfileService.getById(cmd.getId());
if (teamProfile == null) {
@@ -105,10 +90,10 @@ public class TeamMemberListQryExe {
.setTargetFormatSum("0")
.setTargetSum(0L);
}
-
+
TeamPolicyManager teamPolicyManager = teamPolicyManagerService.getReleaseByRegionAndType(
teamProfile.getSysOrigin(), teamProfile.getRegion());
-
+
if (teamPolicyManager == null || CollectionUtils.isEmpty(teamPolicyManager.getPolicy())) {
return new TeamMemberCountResultCO()
.setMemberQuantity(teamMembers.size())
@@ -116,30 +101,30 @@ public class TeamMemberListQryExe {
.setTargetFormatSum("0")
.setTargetSum(0L);
}
-
+
// 获取团队成员的目标总和
Set memberUserIds = teamMembers.stream().map(TeamMember::getMemberId)
.collect(Collectors.toSet());
-
+
Map teamMemberTargetMap = teamMemberTargetService.mapMemberBillTarget(
cmd.getId(), memberUserIds, ZonedDateTimeAsiaRiyadhUtils.nowYearMonthToInt());
-
+
// 计算目标总和
Long targetSum = teamMemberTargetMap.values().stream()
.filter(Objects::nonNull)
.mapToLong(target -> Optional.ofNullable(target.sumAcceptGiftValue()).orElse(0L))
.sum();
-
+
// 根据团队目标总和匹配对应的TeamPolicy返回对应的挡位
Integer matchedLevel = findMatchedLevel(teamPolicyManager.getPolicy(), targetSum);
-
+
return new TeamMemberCountResultCO()
.setMemberQuantity(teamMembers.size())
.setLevel(matchedLevel)
.setTargetFormatSum(NumUtils.formatLong(targetSum))
.setTargetSum(targetSum);
}
-
+
/**
* 根据目标总和查找匹配的等级.
* 逻辑:从高等级到低等级遍历,找到第一个满足条件的等级
@@ -152,7 +137,7 @@ public class TeamMemberListQryExe {
if (CollectionUtils.isEmpty(policies) || targetSum == null) {
return null;
}
-
+
// 按等级降序排列,从高等级到低等级匹配
return policies.stream()
.sorted((p1, p2) -> Integer.compare(p2.getLevel(), p1.getLevel()))
@@ -161,24 +146,61 @@ public class TeamMemberListQryExe {
.map(TeamPolicy::getLevel)
.orElse(0);
}
-
- public List searchTeamMember(Long reqUserId, String account) {
- TeamMember reqTeamMember = teamMemberService.getByMemberId(reqUserId);
- if (reqTeamMember == null) {
- return Collections.emptyList();
- }
-
- List userProfiles = userProfileGateway.getByAccount(account);
- if (CollectionUtils.isEmpty(userProfiles)) {
- return Collections.emptyList();
- }
- UserProfile userProfile = userProfiles.get(0);
- TeamMember teamMember = teamMemberService.getByMemberId(userProfile.getId());
- if (teamMember == null || !teamMember.getTeamId().equals(reqTeamMember.getTeamId())) {
- return Collections.emptyList();
- }
- return Collections.singletonList(new TeamMemberCO().setUserProfile(userProfileAppConvertor.toUserProfileDTO(userProfile)));
+
+ private TeamMemberCO assembleTeamMemberCO(
+ TeamMember teamMember,
+ UserProfileDTO userProfile,
+ TeamMemberTarget teamMemberTarget) {
+ return new TeamMemberCO()
+ .setId(teamMember.getMemberId())
+ .setUserProfile(userProfile)
+ .setTargetFormat(Optional.ofNullable(teamMemberTarget)
+ .map(target -> NumUtils.formatLong(target.sumAcceptGiftValue()))
+ .orElse("0"))
+ .setTimeHours(Optional.ofNullable(teamMemberTarget)
+ .map(target -> BigDecimal.valueOf(target.sumAllTargetTime())
+ .divide(BigDecimal.valueOf(60), 2, RoundingMode.DOWN)
+ .stripTrailingZeros().toPlainString())
+ .orElse("0"))
+ .setEffectiveDay(Optional.ofNullable(teamMemberTarget)
+ .map(TeamMemberTarget::sumEffectiveDay)
+ .orElse(0))
+ .setUseDiamonds("0")
+ .setSurplusDiamonds("0")
+ .setRole(Objects.toString(teamMember.getRole()))
+ .setWalletWithdrawal(Objects.isNull(teamMember.getWalletWithdrawal()) || Objects.equals(
+ teamMember.getWalletWithdrawal(), Boolean.TRUE))
+ .setCreateTime(teamMember.getCreateTime());
+ }
+
+ public List searchTeamMember(Long reqUserId, String account) {
+ TeamMember reqTeamMember = teamMemberService.getByMemberId(reqUserId);
+ if (reqTeamMember == null) {
+ return Collections.emptyList();
}
-
-
+
+ List userProfiles = userProfileGateway.getByAccount(account);
+ if (CollectionUtils.isEmpty(userProfiles)) {
+ return Collections.emptyList();
+ }
+ UserProfile userProfile = userProfiles.get(0);
+ TeamMember teamMember = teamMemberService.getByMemberId(userProfile.getId());
+ if (teamMember == null || !teamMember.getTeamId().equals(reqTeamMember.getTeamId())) {
+ return Collections.emptyList();
+ }
+
+ TeamMemberTarget teamMemberTarget = teamMemberTargetService
+ .mapMemberBillTarget(
+ reqTeamMember.getTeamId(),
+ Collections.singleton(teamMember.getMemberId()),
+ ZonedDateTimeAsiaRiyadhUtils.nowYearMonthToInt())
+ .get(teamMember.getMemberId());
+
+ return Collections.singletonList(assembleTeamMemberCO(
+ teamMember,
+ userProfileAppConvertor.toUserProfileDTO(userProfile),
+ teamMemberTarget));
+ }
+
+
}
diff --git a/rc-service/rc-service-other/other-application/src/test/java/com/red/circle/other/app/command/team/query/TeamMemberListQryExeTest.java b/rc-service/rc-service-other/other-application/src/test/java/com/red/circle/other/app/command/team/query/TeamMemberListQryExeTest.java
new file mode 100644
index 00000000..cf063919
--- /dev/null
+++ b/rc-service/rc-service-other/other-application/src/test/java/com/red/circle/other/app/command/team/query/TeamMemberListQryExeTest.java
@@ -0,0 +1,88 @@
+package com.red.circle.other.app.command.team.query;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import com.red.circle.other.app.convertor.user.UserProfileAppConvertor;
+import com.red.circle.other.app.dto.clientobject.team.TeamMemberCO;
+import com.red.circle.other.domain.gateway.user.UserProfileGateway;
+import com.red.circle.other.domain.model.user.UserProfile;
+import com.red.circle.other.infra.database.mongo.entity.team.team.TeamMember;
+import com.red.circle.other.infra.database.mongo.entity.team.team.TeamMemberTarget;
+import com.red.circle.other.infra.database.mongo.service.team.team.TeamMemberService;
+import com.red.circle.other.infra.database.mongo.service.team.team.TeamMemberTargetService;
+import com.red.circle.other.infra.database.mongo.service.team.team.TeamPolicyManagerService;
+import com.red.circle.other.infra.database.mongo.service.team.team.TeamProfileService;
+import com.red.circle.other.inner.enums.team.TeamMemberTargetIndex;
+import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import org.junit.jupiter.api.Test;
+
+class TeamMemberListQryExeTest {
+
+ @Test
+ void searchTeamMemberShouldReturnCurrentWorkSummary() {
+ TeamMemberService teamMemberService = mock(TeamMemberService.class);
+ UserProfileGateway userProfileGateway = mock(UserProfileGateway.class);
+ UserProfileAppConvertor userProfileAppConvertor = mock(UserProfileAppConvertor.class);
+ TeamMemberTargetService teamMemberTargetService = mock(TeamMemberTargetService.class);
+ TeamPolicyManagerService teamPolicyManagerService = mock(TeamPolicyManagerService.class);
+ TeamProfileService teamProfileService = mock(TeamProfileService.class);
+ TeamMemberListQryExe exe = new TeamMemberListQryExe(
+ teamMemberService,
+ userProfileGateway,
+ userProfileAppConvertor,
+ teamMemberTargetService,
+ teamPolicyManagerService,
+ teamProfileService
+ );
+
+ Long requesterUserId = 2064760394110529538L;
+ Long targetUserId = 2065155499803865089L;
+ Long teamId = 2064760394110529538L;
+ UserProfile targetProfile = new UserProfile();
+ targetProfile.setId(targetUserId);
+ targetProfile.setAccount("1018375");
+ targetProfile.setUserNickname("misra");
+ UserProfileDTO targetProfileDTO = new UserProfileDTO();
+ TeamMember requesterMember = new TeamMember()
+ .setMemberId(requesterUserId)
+ .setTeamId(teamId);
+ TeamMember targetMember = new TeamMember()
+ .setMemberId(targetUserId)
+ .setTeamId(teamId);
+ TeamMemberTarget target = new TeamMemberTarget()
+ .setUserId(targetUserId)
+ .setTeamId(teamId)
+ .setDailyTargets(List.of(
+ new TeamMemberTargetIndex()
+ .setAcceptGiftValue(425_289L)
+ .setOwnOnlineTime(2L)
+ .setEffectiveDay(1)
+ ));
+
+ when(teamMemberService.getByMemberId(requesterUserId)).thenReturn(requesterMember);
+ when(userProfileGateway.getByAccount("1018375")).thenReturn(List.of(targetProfile));
+ when(teamMemberService.getByMemberId(targetUserId)).thenReturn(targetMember);
+ when(userProfileAppConvertor.toUserProfileDTO(targetProfile)).thenReturn(targetProfileDTO);
+ when(teamMemberTargetService.mapMemberBillTarget(
+ eq(teamId),
+ eq(Collections.singleton(targetUserId)),
+ anyInt())).thenReturn(Map.of(targetUserId, target));
+
+ List result = exe.searchTeamMember(requesterUserId, "1018375");
+
+ assertEquals(1, result.size());
+ assertEquals(targetUserId, result.get(0).getId());
+ assertSame(targetProfileDTO, result.get(0).getUserProfile());
+ assertEquals("425.28K", result.get(0).getTargetFormat());
+ assertEquals("0.03", result.get(0).getTimeHours());
+ assertEquals(1, result.get(0).getEffectiveDay());
+ }
+}