order 和 console
This commit is contained in:
parent
1826aa10ab
commit
c39dac772a
@ -3,11 +3,13 @@ package com.red.circle.order.inner.endpoint.api;
|
||||
|
||||
import com.red.circle.framework.dto.PageResult;
|
||||
import com.red.circle.framework.dto.ResultResponse;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryAddCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryChannelCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryChannelDetailsCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryQryCmd;
|
||||
import com.red.circle.order.inner.model.dto.PayCountryDTO;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryAddCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryChannelCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryChannelDetailsCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryCurrencyRateSyncCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryQryCmd;
|
||||
import com.red.circle.order.inner.model.dto.PayCountryCurrencyRateSyncDTO;
|
||||
import com.red.circle.order.inner.model.dto.PayCountryDTO;
|
||||
import com.red.circle.order.inner.model.dto.SysPayCountryChannelDTO;
|
||||
import com.red.circle.order.inner.model.dto.SysPayCountryChannelDetailsDTO;
|
||||
import java.math.BigDecimal;
|
||||
@ -85,10 +87,14 @@ public interface PayCountryClientApi {
|
||||
@GetMapping("/updateSort")
|
||||
ResultResponse<Void> updateSort(@RequestParam("id") Long id, @RequestParam("sort") Integer sort);
|
||||
|
||||
@GetMapping("/shelf")
|
||||
ResultResponse<Void> shelf(@RequestParam("id") Long id, @RequestParam("shelf") Boolean shelf);
|
||||
|
||||
@GetMapping("/listPayCountryByRegionId")
|
||||
ResultResponse<List<PayCountryDTO>> listPayCountryByRegionId(
|
||||
@RequestParam("regionId") String regionId);
|
||||
}
|
||||
@GetMapping("/shelf")
|
||||
ResultResponse<Void> shelf(@RequestParam("id") Long id, @RequestParam("shelf") Boolean shelf);
|
||||
|
||||
@PostMapping("/syncCurrencyRates")
|
||||
ResultResponse<PayCountryCurrencyRateSyncDTO> syncCurrencyRates(
|
||||
@RequestBody SysPayCountryCurrencyRateSyncCmd cmd);
|
||||
|
||||
@GetMapping("/listPayCountryByRegionId")
|
||||
ResultResponse<List<PayCountryDTO>> listPayCountryByRegionId(
|
||||
@RequestParam("regionId") String regionId);
|
||||
}
|
||||
|
||||
@ -0,0 +1,33 @@
|
||||
package com.red.circle.order.inner.model.cmd;
|
||||
|
||||
import com.red.circle.framework.core.dto.CommonCommand;
|
||||
import jakarta.validation.constraints.DecimalMax;
|
||||
import jakarta.validation.constraints.DecimalMin;
|
||||
import jakarta.validation.constraints.Digits;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.math.BigDecimal;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 支付国家货币汇率同步命令.
|
||||
*
|
||||
* @author system
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Accessors(chain = true)
|
||||
public class SysPayCountryCurrencyRateSyncCmd extends CommonCommand {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 上浮比例,5 表示在实时汇率基础上增加 5%.
|
||||
*/
|
||||
@NotNull
|
||||
@DecimalMin("0")
|
||||
@DecimalMax("100")
|
||||
@Digits(integer = 3, fraction = 4)
|
||||
private BigDecimal markupPercent;
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
package com.red.circle.order.inner.model.dto;
|
||||
|
||||
import com.red.circle.framework.dto.DTO;
|
||||
import java.io.Serial;
|
||||
import java.util.List;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 支付国家货币汇率同步结果.
|
||||
*
|
||||
* @author system
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Accessors(chain = true)
|
||||
public class PayCountryCurrencyRateSyncDTO extends DTO {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 参与同步的支付国家数量.
|
||||
*/
|
||||
private Integer totalCount;
|
||||
|
||||
/**
|
||||
* 已更新的支付国家数量.
|
||||
*/
|
||||
private Integer updatedCount;
|
||||
|
||||
/**
|
||||
* 跳过的支付国家数量.
|
||||
*/
|
||||
private Integer skippedCount;
|
||||
|
||||
/**
|
||||
* 汇率来源.
|
||||
*/
|
||||
private String sourceName;
|
||||
|
||||
/**
|
||||
* 被跳过的国家说明.
|
||||
*/
|
||||
private List<String> skippedCountries;
|
||||
}
|
||||
@ -4,10 +4,12 @@ package com.red.circle.console.adapter.app.sys.pay;
|
||||
import com.red.circle.console.app.service.app.sys.pay.SysPayCountryService;
|
||||
import com.red.circle.console.infra.annotations.OpsOperationReqLog;
|
||||
import com.red.circle.framework.dto.PageResult;
|
||||
import com.red.circle.framework.web.controller.BaseController;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryAddCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryQryCmd;
|
||||
import com.red.circle.order.inner.model.dto.PayCountryDTO;
|
||||
import com.red.circle.framework.web.controller.BaseController;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryAddCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryCurrencyRateSyncCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryQryCmd;
|
||||
import com.red.circle.order.inner.model.dto.PayCountryCurrencyRateSyncDTO;
|
||||
import com.red.circle.order.inner.model.dto.PayCountryDTO;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@ -111,10 +113,19 @@ public class SysPayOpenCountryController extends BaseController {
|
||||
*/
|
||||
@OpsOperationReqLog("修改国家上下架")
|
||||
@GetMapping("/shelf")
|
||||
public void shelf(@RequestParam Long id,
|
||||
@RequestParam Boolean shelf) {
|
||||
sysPayCountryService.shelf(id, shelf);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
public void shelf(@RequestParam Long id,
|
||||
@RequestParam Boolean shelf) {
|
||||
sysPayCountryService.shelf(id, shelf);
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步全球支付国家货币和实时汇率.
|
||||
*/
|
||||
@OpsOperationReqLog("同步全球支付国家货币汇率")
|
||||
@PostMapping("/sync-currency-rates")
|
||||
public PayCountryCurrencyRateSyncDTO syncCurrencyRates(
|
||||
@RequestBody @Validated SysPayCountryCurrencyRateSyncCmd cmd) {
|
||||
return sysPayCountryService.syncCurrencyRates(cmd);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -2,10 +2,12 @@ package com.red.circle.console.app.service.app.sys.pay;
|
||||
|
||||
import com.red.circle.framework.core.asserts.ResponseAssert;
|
||||
import com.red.circle.framework.dto.PageResult;
|
||||
import com.red.circle.order.inner.endpoint.PayCountryClient;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryAddCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryQryCmd;
|
||||
import com.red.circle.order.inner.model.dto.PayCountryDTO;
|
||||
import com.red.circle.order.inner.endpoint.PayCountryClient;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryAddCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryCurrencyRateSyncCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryQryCmd;
|
||||
import com.red.circle.order.inner.model.dto.PayCountryCurrencyRateSyncDTO;
|
||||
import com.red.circle.order.inner.model.dto.PayCountryDTO;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -64,14 +66,19 @@ public class SysPayCountryServiceImpl implements SysPayCountryService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shelf(Long id, Boolean shelf) {
|
||||
ResponseAssert.requiredSuccess(payCountryClient.shelf(id, shelf));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Long, PayCountryDTO> mapCountryByIds(Set<Long> ids) {
|
||||
return ResponseAssert.requiredSuccess(payCountryClient.mapCountryByIds(ids));
|
||||
}
|
||||
public void shelf(Long id, Boolean shelf) {
|
||||
ResponseAssert.requiredSuccess(payCountryClient.shelf(id, shelf));
|
||||
}
|
||||
|
||||
@Override
|
||||
public PayCountryCurrencyRateSyncDTO syncCurrencyRates(SysPayCountryCurrencyRateSyncCmd cmd) {
|
||||
return ResponseAssert.requiredSuccess(payCountryClient.syncCurrencyRates(cmd));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Long, PayCountryDTO> mapCountryByIds(Set<Long> ids) {
|
||||
return ResponseAssert.requiredSuccess(payCountryClient.mapCountryByIds(ids));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PayCountryDTO> listPayCountryByRegionId(String regionId) {
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
package com.red.circle.console.app.service.app.sys.pay;
|
||||
|
||||
import com.red.circle.framework.dto.PageResult;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryAddCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryQryCmd;
|
||||
import com.red.circle.order.inner.model.dto.PayCountryDTO;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryAddCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryCurrencyRateSyncCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryQryCmd;
|
||||
import com.red.circle.order.inner.model.dto.PayCountryCurrencyRateSyncDTO;
|
||||
import com.red.circle.order.inner.model.dto.PayCountryDTO;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -57,12 +59,17 @@ public interface SysPayCountryService {
|
||||
/**
|
||||
* 修改国家上下架状态.
|
||||
*/
|
||||
void shelf(Long id, Boolean shelf);
|
||||
|
||||
/**
|
||||
* 根据id集合获得.
|
||||
*/
|
||||
Map<Long, PayCountryDTO> mapCountryByIds(Set<Long> ids);
|
||||
void shelf(Long id, Boolean shelf);
|
||||
|
||||
/**
|
||||
* 同步支付国家默认货币和实时美元汇率.
|
||||
*/
|
||||
PayCountryCurrencyRateSyncDTO syncCurrencyRates(SysPayCountryCurrencyRateSyncCmd cmd);
|
||||
|
||||
/**
|
||||
* 根据id集合获得.
|
||||
*/
|
||||
Map<Long, PayCountryDTO> mapCountryByIds(Set<Long> ids);
|
||||
|
||||
/**
|
||||
* 根据区域id集合获得支持支付的国家.
|
||||
|
||||
@ -18,13 +18,18 @@ import com.red.circle.order.infra.database.rds.service.order.OrderUserPurchasePa
|
||||
import com.red.circle.order.inner.model.enums.inapp.InAppPurchaseStatus;
|
||||
import com.red.circle.tool.core.date.TimestampUtils;
|
||||
import com.red.circle.tool.core.http.RcHttpClient;
|
||||
import com.red.circle.tool.core.json.JacksonUtils;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.red.circle.tool.core.json.JacksonUtils;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @author pengliang on 2022/11/2
|
||||
@ -120,10 +125,31 @@ public class PayPlaceAnOrderService {
|
||||
* @param targetCurrency 目标币种(如CNY)
|
||||
* @return 汇率值
|
||||
*/
|
||||
public BigDecimal getRealTimeExchangeRate(String baseCurrency, String targetCurrency) {
|
||||
try {
|
||||
QuoteQueryParam param = new QuoteQueryParam();
|
||||
QuoteQueryParam.QuoteQueryData data = new QuoteQueryParam.QuoteQueryData();
|
||||
public BigDecimal getRealTimeExchangeRate(String baseCurrency, String targetCurrency) {
|
||||
return getRealTimeExchangeRates(baseCurrency, List.of(targetCurrency)).get(targetCurrency);
|
||||
}
|
||||
|
||||
public Map<String, BigDecimal> getRealTimeExchangeRates(String baseCurrency,
|
||||
Collection<String> targetCurrencies) {
|
||||
Map<String, BigDecimal> result = new HashMap<>();
|
||||
Optional.ofNullable(targetCurrencies).orElseGet(List::of).stream()
|
||||
.filter(Objects::nonNull)
|
||||
.map(String::trim)
|
||||
.filter(currency -> !currency.isEmpty())
|
||||
.distinct()
|
||||
.forEach(targetCurrency -> {
|
||||
BigDecimal rate = queryRealTimeExchangeRate(baseCurrency, targetCurrency);
|
||||
if (Objects.nonNull(rate)) {
|
||||
result.put(targetCurrency, rate);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
private BigDecimal queryRealTimeExchangeRate(String baseCurrency, String targetCurrency) {
|
||||
try {
|
||||
QuoteQueryParam param = new QuoteQueryParam();
|
||||
QuoteQueryParam.QuoteQueryData data = new QuoteQueryParam.QuoteQueryData();
|
||||
|
||||
// 币种对格式:基础币种+目标币种,如USDCNY
|
||||
String ccyPair = baseCurrency + targetCurrency;
|
||||
@ -163,10 +189,10 @@ public class PayPlaceAnOrderService {
|
||||
return null;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Error occurred while querying real-time exchange rate from {} to {}",
|
||||
baseCurrency, targetCurrency, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
log.error("Error occurred while querying real-time exchange rate from {} to {}",
|
||||
baseCurrency, targetCurrency, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -41,9 +41,11 @@ public interface PayCountryService extends BaseService<PayCountry> {
|
||||
|
||||
PageResult<PayCountry> pageOpenPayCountry(SysPayCountryQryCmd query);
|
||||
|
||||
List<PayCountry> listOpenPayCountry(Set<Long> ids);
|
||||
|
||||
void delOpenPayCountry(List<Long> ids);
|
||||
List<PayCountry> listOpenPayCountry(Set<Long> ids);
|
||||
|
||||
List<PayCountry> listAllOpenPayCountry();
|
||||
|
||||
void delOpenPayCountry(List<Long> ids);
|
||||
|
||||
void updateUsdExchangeRate(Long id, BigDecimal rate);
|
||||
|
||||
@ -51,5 +53,7 @@ public interface PayCountryService extends BaseService<PayCountry> {
|
||||
|
||||
void updateSort(Long id, Integer sort);
|
||||
|
||||
void shelf(Long id, Boolean shelf);
|
||||
}
|
||||
void shelf(Long id, Boolean shelf);
|
||||
|
||||
boolean updateCurrencyRates(List<PayCountry> countries);
|
||||
}
|
||||
|
||||
@ -15,8 +15,9 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import org.springframework.stereotype.Service;
|
||||
import java.util.stream.Collectors;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@ -96,14 +97,21 @@ public class PayCountryServiceImpl extends BaseServiceImpl<PayCountryDAO, PayCou
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PayCountry> listOpenPayCountry(Set<Long> ids) {
|
||||
return query()
|
||||
.in(CollectionUtils.isNotEmpty(ids), PayCountry::getId, ids)
|
||||
.eq(PayCountry::getShelf, Boolean.TRUE)
|
||||
.orderByDesc(PayCountry::getId)
|
||||
.list();
|
||||
}
|
||||
|
||||
public List<PayCountry> listOpenPayCountry(Set<Long> ids) {
|
||||
return query()
|
||||
.in(CollectionUtils.isNotEmpty(ids), PayCountry::getId, ids)
|
||||
.eq(PayCountry::getShelf, Boolean.TRUE)
|
||||
.orderByDesc(PayCountry::getId)
|
||||
.list();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PayCountry> listAllOpenPayCountry() {
|
||||
return query()
|
||||
.orderByDesc(PayCountry::getId)
|
||||
.list();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delOpenPayCountry(List<Long> ids) {
|
||||
delete()
|
||||
@ -139,12 +147,21 @@ public class PayCountryServiceImpl extends BaseServiceImpl<PayCountryDAO, PayCou
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shelf(Long id, Boolean shelf) {
|
||||
update()
|
||||
.set(PayCountry::getShelf, shelf)
|
||||
.set(PayCountry::getUpdateTime, TimestampUtils.now())
|
||||
.eq(PayCountry::getId, id)
|
||||
.execute();
|
||||
}
|
||||
|
||||
}
|
||||
public void shelf(Long id, Boolean shelf) {
|
||||
update()
|
||||
.set(PayCountry::getShelf, shelf)
|
||||
.set(PayCountry::getUpdateTime, TimestampUtils.now())
|
||||
.eq(PayCountry::getId, id)
|
||||
.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean updateCurrencyRates(List<PayCountry> countries) {
|
||||
if (CollectionUtils.isEmpty(countries)) {
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
return updateBatchById(countries);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -3,11 +3,13 @@ package com.red.circle.order.inner.endpoint;
|
||||
import com.red.circle.framework.dto.PageResult;
|
||||
import com.red.circle.framework.dto.ResultResponse;
|
||||
import com.red.circle.order.inner.endpoint.api.PayCountryClientApi;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryAddCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryChannelCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryChannelDetailsCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryQryCmd;
|
||||
import com.red.circle.order.inner.model.dto.PayCountryDTO;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryAddCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryChannelCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryChannelDetailsCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryCurrencyRateSyncCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryQryCmd;
|
||||
import com.red.circle.order.inner.model.dto.PayCountryCurrencyRateSyncDTO;
|
||||
import com.red.circle.order.inner.model.dto.PayCountryDTO;
|
||||
import com.red.circle.order.inner.model.dto.SysPayCountryChannelDTO;
|
||||
import com.red.circle.order.inner.model.dto.SysPayCountryChannelDetailsDTO;
|
||||
import com.red.circle.order.inner.service.PayCountryClientService;
|
||||
@ -133,14 +135,20 @@ public class PayCountryClientEndpoint implements PayCountryClientApi {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultResponse<Void> shelf(Long id, Boolean shelf) {
|
||||
payCountryClientService.shelf(id, shelf);
|
||||
return ResultResponse.success();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultResponse<List<PayCountryDTO>> listPayCountryByRegionId(String regionId) {
|
||||
return ResultResponse.success(payCountryClientService.listPayCountryByRegionId(regionId));
|
||||
}
|
||||
public ResultResponse<Void> shelf(Long id, Boolean shelf) {
|
||||
payCountryClientService.shelf(id, shelf);
|
||||
return ResultResponse.success();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultResponse<PayCountryCurrencyRateSyncDTO> syncCurrencyRates(
|
||||
SysPayCountryCurrencyRateSyncCmd cmd) {
|
||||
return ResultResponse.success(payCountryClientService.syncCurrencyRates(cmd));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultResponse<List<PayCountryDTO>> listPayCountryByRegionId(String regionId) {
|
||||
return ResultResponse.success(payCountryClientService.listPayCountryByRegionId(regionId));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,11 +1,13 @@
|
||||
package com.red.circle.order.inner.service;
|
||||
|
||||
import com.red.circle.framework.dto.PageResult;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryAddCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryChannelCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryChannelDetailsCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryQryCmd;
|
||||
import com.red.circle.order.inner.model.dto.PayCountryDTO;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryAddCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryChannelCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryChannelDetailsCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryCurrencyRateSyncCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryQryCmd;
|
||||
import com.red.circle.order.inner.model.dto.PayCountryCurrencyRateSyncDTO;
|
||||
import com.red.circle.order.inner.model.dto.PayCountryDTO;
|
||||
import com.red.circle.order.inner.model.dto.SysPayCountryChannelDTO;
|
||||
import com.red.circle.order.inner.model.dto.SysPayCountryChannelDetailsDTO;
|
||||
import java.math.BigDecimal;
|
||||
@ -55,7 +57,9 @@ public interface PayCountryClientService {
|
||||
|
||||
void updateSort(Long id, Integer sort);
|
||||
|
||||
void shelf(Long id, Boolean shelf);
|
||||
|
||||
List<PayCountryDTO> listPayCountryByRegionId(String regionId);
|
||||
}
|
||||
void shelf(Long id, Boolean shelf);
|
||||
|
||||
PayCountryCurrencyRateSyncDTO syncCurrencyRates(SysPayCountryCurrencyRateSyncCmd cmd);
|
||||
|
||||
List<PayCountryDTO> listPayCountryByRegionId(String regionId);
|
||||
}
|
||||
|
||||
@ -1,38 +1,48 @@
|
||||
package com.red.circle.order.inner.service.impl;
|
||||
|
||||
import com.alibaba.nacos.shaded.com.google.common.collect.Lists;
|
||||
import com.google.api.client.util.Maps;
|
||||
import com.red.circle.framework.core.asserts.ResponseAssert;
|
||||
import com.red.circle.framework.dto.PageResult;
|
||||
import com.red.circle.framework.mybatis.constant.PageConstant;
|
||||
import com.red.circle.order.infra.database.rds.entity.pay.PayCountry;
|
||||
import com.red.circle.order.infra.database.rds.entity.pay.PayCountryChannel;
|
||||
import com.red.circle.order.infra.database.rds.entity.pay.PayCountryChannelDetails;
|
||||
import com.alibaba.nacos.shaded.com.google.common.collect.Lists;
|
||||
import com.google.api.client.util.Maps;
|
||||
import com.red.circle.framework.core.response.CommonErrorCode;
|
||||
import com.red.circle.framework.core.asserts.ResponseAssert;
|
||||
import com.red.circle.framework.dto.PageResult;
|
||||
import com.red.circle.framework.mybatis.constant.PageConstant;
|
||||
import com.red.circle.order.app.command.pay.web.strategy.PayPlaceAnOrderService;
|
||||
import com.red.circle.order.infra.database.rds.entity.pay.PayCountry;
|
||||
import com.red.circle.order.infra.database.rds.entity.pay.PayCountryChannel;
|
||||
import com.red.circle.order.infra.database.rds.entity.pay.PayCountryChannelDetails;
|
||||
import com.red.circle.order.infra.database.rds.service.pay.PayCountryChannelDetailsService;
|
||||
import com.red.circle.order.infra.database.rds.service.pay.PayCountryChannelService;
|
||||
import com.red.circle.order.infra.database.rds.service.pay.PayCountryService;
|
||||
import com.red.circle.order.inner.convertor.WebPayInnerConvertor;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryAddCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryChannelCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryChannelDetailsCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryQryCmd;
|
||||
import com.red.circle.order.inner.model.dto.PayCountryDTO;
|
||||
import com.red.circle.order.inner.model.dto.SysPayCountryChannelDTO;
|
||||
import com.red.circle.order.inner.model.dto.SysPayCountryChannelDetailsDTO;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryAddCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryChannelCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryChannelDetailsCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryCurrencyRateSyncCmd;
|
||||
import com.red.circle.order.inner.model.cmd.SysPayCountryQryCmd;
|
||||
import com.red.circle.order.inner.model.dto.PayCountryCurrencyRateSyncDTO;
|
||||
import com.red.circle.order.inner.model.dto.PayCountryDTO;
|
||||
import com.red.circle.order.inner.model.dto.SysPayCountryChannelDTO;
|
||||
import com.red.circle.order.inner.model.dto.SysPayCountryChannelDetailsDTO;
|
||||
import com.red.circle.order.inner.service.PayCountryClientService;
|
||||
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.date.TimestampUtils;
|
||||
import com.red.circle.tool.core.text.StringUtils;
|
||||
import com.red.circle.other.inner.enums.user.RegionRelationGroupEnum;
|
||||
import com.red.circle.other.inner.endpoint.user.region.RegionRelationClient;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import com.red.circle.other.inner.enums.user.RegionRelationGroupEnum;
|
||||
import com.red.circle.other.inner.endpoint.user.region.RegionRelationClient;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Currency;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@ -42,16 +52,22 @@ import org.springframework.stereotype.Service;
|
||||
* @author pengliang on 2023/11/3
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class PayCountryClientServiceImpl implements PayCountryClientService {
|
||||
|
||||
private final PayCountryService payCountryService;
|
||||
private final SysCountryCodeClient countryCodeClient;
|
||||
private final WebPayInnerConvertor webPayInnerConvertor;
|
||||
private final RegionRelationClient regionRelationClient;
|
||||
private final SysCountryCodeClient sysCountryCodeClient;
|
||||
private final PayCountryChannelService payCountryChannelService;
|
||||
private final PayCountryChannelDetailsService payCountryChannelDetailsService;
|
||||
@RequiredArgsConstructor
|
||||
public class PayCountryClientServiceImpl implements PayCountryClientService {
|
||||
|
||||
private static final String BASE_CURRENCY = "USD";
|
||||
private static final String SOURCE_NAME = "ISO4217/PayerMax";
|
||||
private static final BigDecimal HUNDRED = BigDecimal.valueOf(100);
|
||||
private static final int RATE_SCALE = 8;
|
||||
|
||||
private final PayCountryService payCountryService;
|
||||
private final SysCountryCodeClient countryCodeClient;
|
||||
private final WebPayInnerConvertor webPayInnerConvertor;
|
||||
private final RegionRelationClient regionRelationClient;
|
||||
private final SysCountryCodeClient sysCountryCodeClient;
|
||||
private final PayCountryChannelService payCountryChannelService;
|
||||
private final PayCountryChannelDetailsService payCountryChannelDetailsService;
|
||||
private final PayPlaceAnOrderService payPlaceAnOrderService;
|
||||
|
||||
|
||||
@Override
|
||||
@ -257,13 +273,112 @@ public class PayCountryClientServiceImpl implements PayCountryClientService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shelf(Long id, Boolean shelf) {
|
||||
payCountryService.shelf(id, shelf);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<PayCountryDTO> listPayCountryByRegionId(String regionId) {
|
||||
public void shelf(Long id, Boolean shelf) {
|
||||
payCountryService.shelf(id, shelf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PayCountryCurrencyRateSyncDTO syncCurrencyRates(SysPayCountryCurrencyRateSyncCmd cmd) {
|
||||
BigDecimal markupPercent = Optional.ofNullable(cmd)
|
||||
.map(SysPayCountryCurrencyRateSyncCmd::getMarkupPercent)
|
||||
.orElse(BigDecimal.ZERO);
|
||||
BigDecimal markupMultiplier = BigDecimal.ONE.add(
|
||||
markupPercent.divide(HUNDRED, RATE_SCALE, RoundingMode.HALF_UP));
|
||||
List<PayCountry> payCountries = payCountryService.listAllOpenPayCountry();
|
||||
if (CollectionUtils.isEmpty(payCountries)) {
|
||||
return new PayCountryCurrencyRateSyncDTO()
|
||||
.setTotalCount(0)
|
||||
.setUpdatedCount(0)
|
||||
.setSkippedCount(0)
|
||||
.setSourceName(SOURCE_NAME)
|
||||
.setSkippedCountries(Lists.newArrayList());
|
||||
}
|
||||
|
||||
Map<Long, SysCountryCodeDTO> countryMap = ResponseAssert.requiredSuccess(
|
||||
sysCountryCodeClient.mapByIdes(payCountries.stream()
|
||||
.map(PayCountry::getCountryId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet())));
|
||||
Map<Long, String> currencyMap = Maps.newHashMap();
|
||||
List<String> skippedCountries = new ArrayList<>();
|
||||
Set<String> targetCurrencies = payCountries.stream()
|
||||
.map(payCountry -> {
|
||||
SysCountryCodeDTO country = countryMap.get(payCountry.getCountryId());
|
||||
String currency = resolveCountryCurrency(country);
|
||||
if (StringUtils.isBlank(currency)) {
|
||||
skippedCountries.add(formatSkippedCountry(payCountry, country, "未找到国家默认货币"));
|
||||
return null;
|
||||
}
|
||||
currencyMap.put(payCountry.getId(), currency);
|
||||
return currency;
|
||||
})
|
||||
.filter(StringUtils::isNotBlank)
|
||||
.filter(currency -> !Objects.equals(BASE_CURRENCY, currency))
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
Map<String, BigDecimal> rateMap = Maps.newHashMap();
|
||||
rateMap.put(BASE_CURRENCY, BigDecimal.ONE);
|
||||
rateMap.putAll(payPlaceAnOrderService.getRealTimeExchangeRates(BASE_CURRENCY, targetCurrencies));
|
||||
|
||||
List<PayCountry> updates = payCountries.stream()
|
||||
.map(payCountry -> buildSyncUpdate(payCountry, countryMap.get(payCountry.getCountryId()),
|
||||
currencyMap.get(payCountry.getId()), rateMap, markupMultiplier, skippedCountries))
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
ResponseAssert.isTrue(CommonErrorCode.OPERATING_FAILURE,
|
||||
payCountryService.updateCurrencyRates(updates));
|
||||
|
||||
return new PayCountryCurrencyRateSyncDTO()
|
||||
.setTotalCount(payCountries.size())
|
||||
.setUpdatedCount(updates.size())
|
||||
.setSkippedCount(skippedCountries.size())
|
||||
.setSourceName(SOURCE_NAME)
|
||||
.setSkippedCountries(skippedCountries);
|
||||
}
|
||||
|
||||
private PayCountry buildSyncUpdate(PayCountry payCountry, SysCountryCodeDTO country,
|
||||
String currency, Map<String, BigDecimal> rateMap, BigDecimal markupMultiplier,
|
||||
List<String> skippedCountries) {
|
||||
if (StringUtils.isBlank(currency)) {
|
||||
return null;
|
||||
}
|
||||
BigDecimal rate = rateMap.get(currency);
|
||||
if (Objects.isNull(rate) || rate.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
skippedCountries.add(formatSkippedCountry(payCountry, country, "未获取到实时汇率"));
|
||||
return null;
|
||||
}
|
||||
payCountry.setCurrency(currency);
|
||||
payCountry.setUsdExchangeRate(rate.multiply(markupMultiplier).setScale(RATE_SCALE,
|
||||
RoundingMode.HALF_UP));
|
||||
payCountry.setUpdateTime(TimestampUtils.now());
|
||||
return payCountry;
|
||||
}
|
||||
|
||||
private String resolveCountryCurrency(SysCountryCodeDTO country) {
|
||||
if (Objects.isNull(country) || StringUtils.isBlank(country.getAlphaTwo())) {
|
||||
return "";
|
||||
}
|
||||
try {
|
||||
Locale locale = new Locale.Builder()
|
||||
.setRegion(country.getAlphaTwo().trim().toUpperCase(Locale.ROOT))
|
||||
.build();
|
||||
return Currency.getInstance(locale).getCurrencyCode();
|
||||
} catch (IllegalArgumentException | MissingResourceException e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private String formatSkippedCountry(PayCountry payCountry, SysCountryCodeDTO country,
|
||||
String reason) {
|
||||
String countryName = Optional.ofNullable(country)
|
||||
.map(item -> StringUtils.isNotBlank(item.getAliasName()) ? item.getAliasName()
|
||||
: item.getAlphaTwo())
|
||||
.orElse(Objects.toString(payCountry.getCountryId(), "-"));
|
||||
return countryName + "(" + payCountry.getId() + "): " + reason;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PayCountryDTO> listPayCountryByRegionId(String regionId) {
|
||||
|
||||
Set<Long> relationIds = ResponseAssert.requiredSuccess(regionRelationClient
|
||||
.getRelationIdsByRegionId(regionId, RegionRelationGroupEnum.OPEN_PAY_COUNTRY.name()));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user