feat: include MifaPay orders in admin list
This commit is contained in:
parent
8f888c7041
commit
1d724dadd9
@ -1,15 +1,36 @@
|
|||||||
package com.red.circle.order.inner.service.impl;
|
package com.red.circle.order.inner.service.impl;
|
||||||
|
|
||||||
|
import com.red.circle.framework.mybatis.constant.PageConstant;
|
||||||
|
import com.red.circle.order.app.common.MiFaPayMysqlOrderSupport;
|
||||||
import com.red.circle.order.infra.database.mongo.order.InAppPurchaseDetailsService;
|
import com.red.circle.order.infra.database.mongo.order.InAppPurchaseDetailsService;
|
||||||
|
import com.red.circle.order.infra.database.mongo.order.entity.InAppPurchaseDetails;
|
||||||
import com.red.circle.order.infra.database.mongo.order.entity.assist.CountUserInAppPurchase;
|
import com.red.circle.order.infra.database.mongo.order.entity.assist.CountUserInAppPurchase;
|
||||||
|
import com.red.circle.order.infra.database.mongo.order.entity.assist.InAppPurchaseEventNotice;
|
||||||
|
import com.red.circle.order.infra.database.rds.entity.order.OrderUserPurchasePay;
|
||||||
|
import com.red.circle.order.infra.database.rds.entity.order.OrderUserPurchasePayNotice;
|
||||||
|
import com.red.circle.order.infra.database.rds.service.order.OrderUserPurchasePayNoticeService;
|
||||||
|
import com.red.circle.order.infra.database.rds.service.order.OrderUserPurchasePayService;
|
||||||
import com.red.circle.order.inner.convertor.InAppPurchaseDetailsInnerConvert;
|
import com.red.circle.order.inner.convertor.InAppPurchaseDetailsInnerConvert;
|
||||||
import com.red.circle.order.inner.model.cmd.inapp.InAppPurchaseDetailsQryCmd;
|
import com.red.circle.order.inner.model.cmd.inapp.InAppPurchaseDetailsQryCmd;
|
||||||
import com.red.circle.order.inner.model.dto.inapp.CountUserInAppPurchaseDTO;
|
import com.red.circle.order.inner.model.dto.inapp.CountUserInAppPurchaseDTO;
|
||||||
import com.red.circle.order.inner.model.dto.inapp.InAppPurchaseDetailsDTO;
|
import com.red.circle.order.inner.model.dto.inapp.InAppPurchaseDetailsDTO;
|
||||||
|
import com.red.circle.order.inner.model.enums.inapp.InAppPurchaseStatus;
|
||||||
import com.red.circle.order.inner.service.InAppPurchaseDetailsClientService;
|
import com.red.circle.order.inner.service.InAppPurchaseDetailsClientService;
|
||||||
|
import com.red.circle.tool.core.text.StringUtils;
|
||||||
|
import com.red.circle.tool.core.json.JacksonUtils;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.RoundingMode;
|
||||||
|
import java.sql.Timestamp;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@ -22,29 +43,275 @@ import org.springframework.stereotype.Service;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class InAppPurchaseDetailsClientServiceImpl implements InAppPurchaseDetailsClientService {
|
public class InAppPurchaseDetailsClientServiceImpl implements InAppPurchaseDetailsClientService {
|
||||||
|
|
||||||
|
private static final String H5_PLATFORM = "H5";
|
||||||
|
|
||||||
private final InAppPurchaseDetailsService inAppPurchaseDetailsService;
|
private final InAppPurchaseDetailsService inAppPurchaseDetailsService;
|
||||||
private final InAppPurchaseDetailsInnerConvert inAppPurchaseDetailsInnerConvert;
|
private final InAppPurchaseDetailsInnerConvert inAppPurchaseDetailsInnerConvert;
|
||||||
|
private final OrderUserPurchasePayService orderUserPurchasePayService;
|
||||||
|
private final OrderUserPurchasePayNoticeService orderUserPurchasePayNoticeService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InAppPurchaseDetailsDTO getById(String id) {
|
public InAppPurchaseDetailsDTO getById(String id) {
|
||||||
|
InAppPurchaseDetails details = inAppPurchaseDetailsService.getById(id);
|
||||||
|
if (Objects.isNull(details)) {
|
||||||
|
details = getMiFaPayDetails(id);
|
||||||
|
}
|
||||||
return inAppPurchaseDetailsInnerConvert.toInAppPurchaseDetailsDTO(
|
return inAppPurchaseDetailsInnerConvert.toInAppPurchaseDetailsDTO(
|
||||||
inAppPurchaseDetailsService.getById(id)
|
details
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<InAppPurchaseDetailsDTO> list(InAppPurchaseDetailsQryCmd qryCmd) {
|
public List<InAppPurchaseDetailsDTO> list(InAppPurchaseDetailsQryCmd qryCmd) {
|
||||||
return inAppPurchaseDetailsInnerConvert.toListInAppPurchaseDetailsDTO(
|
List<InAppPurchaseDetailsDTO> mongoOrders = safeList(
|
||||||
inAppPurchaseDetailsService.list(
|
inAppPurchaseDetailsInnerConvert.toListInAppPurchaseDetailsDTO(
|
||||||
inAppPurchaseDetailsInnerConvert.toInAppPurchaseDetailsQuery(qryCmd))
|
inAppPurchaseDetailsService.list(
|
||||||
);
|
inAppPurchaseDetailsInnerConvert.toInAppPurchaseDetailsQuery(qryCmd))
|
||||||
|
));
|
||||||
|
List<InAppPurchaseDetailsDTO> miFaPayOrders = listMiFaPayOrders(qryCmd, true).stream()
|
||||||
|
.map(order -> inAppPurchaseDetailsInnerConvert.toInAppPurchaseDetailsDTO(
|
||||||
|
toMiFaPayDetails(order, false)))
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
return mergePage(mongoOrders, miFaPayOrders, normalizeLimit(qryCmd.getLimit()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> statistics(InAppPurchaseDetailsQryCmd qryCmd) {
|
public Map<String, Object> statistics(InAppPurchaseDetailsQryCmd qryCmd) {
|
||||||
return inAppPurchaseDetailsService.statistics(
|
Map<String, Object> result = new HashMap<>(inAppPurchaseDetailsService.statistics(
|
||||||
inAppPurchaseDetailsInnerConvert.toInAppPurchaseDetailsQuery(qryCmd)
|
inAppPurchaseDetailsInnerConvert.toInAppPurchaseDetailsQuery(qryCmd)
|
||||||
);
|
));
|
||||||
|
|
||||||
|
List<OrderUserPurchasePay> miFaPayOrders = listMiFaPayOrders(qryCmd, false);
|
||||||
|
if (miFaPayOrders.isEmpty()) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
long totalOrderCount = longValue(result.get("totalOrderCount")) + miFaPayOrders.size();
|
||||||
|
BigDecimal totalAmount = decimalValue(result.get("totalAmount"))
|
||||||
|
.add(sum(miFaPayOrders, OrderUserPurchasePay::getPaymentAmount));
|
||||||
|
BigDecimal totalAmountUsd = decimalValue(result.get("totalAmountUsd"))
|
||||||
|
.add(sum(miFaPayOrders, OrderUserPurchasePay::getComputeUsdAmount));
|
||||||
|
|
||||||
|
result.put("totalOrderCount", totalOrderCount);
|
||||||
|
result.put("totalAmount", totalAmount);
|
||||||
|
result.put("totalAmountUsd", totalAmountUsd);
|
||||||
|
result.put("averageOrderAmount", average(totalAmount, totalOrderCount));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private InAppPurchaseDetails getMiFaPayDetails(String id) {
|
||||||
|
Long mysqlOrderId = MiFaPayMysqlOrderSupport.parseOrderId(id);
|
||||||
|
if (Objects.isNull(mysqlOrderId)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
OrderUserPurchasePay order = orderUserPurchasePayService.getById(mysqlOrderId);
|
||||||
|
if (Objects.isNull(order) || !MiFaPayMysqlOrderSupport.isMiFaPay(order.getFactoryCode())) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return toMiFaPayDetails(order, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<OrderUserPurchasePay> listMiFaPayOrders(InAppPurchaseDetailsQryCmd qryCmd,
|
||||||
|
boolean pageable) {
|
||||||
|
if (!shouldIncludeMiFaPay(qryCmd)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
Long id = parseFilterId(qryCmd.getId());
|
||||||
|
if (StringUtils.isNotBlank(qryCmd.getId()) && Objects.isNull(id)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
Long lastId = parseFilterId(qryCmd.getLastId());
|
||||||
|
if (pageable && StringUtils.isNotBlank(qryCmd.getLastId()) && Objects.isNull(lastId)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
String payStatus = toMiFaPayStatus(qryCmd.getStatus());
|
||||||
|
if (Objects.nonNull(qryCmd.getStatus()) && Objects.isNull(payStatus)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> sysOrigins = parseSysOrigins(qryCmd.getSysOrigins());
|
||||||
|
var query = orderUserPurchasePayService.query()
|
||||||
|
.eq(OrderUserPurchasePay::getFactoryCode, MiFaPayMysqlOrderSupport.FACTORY_CODE)
|
||||||
|
.eq(Objects.nonNull(id), OrderUserPurchasePay::getId, id)
|
||||||
|
.eq(Objects.nonNull(qryCmd.getReceiptType()), OrderUserPurchasePay::getReceiptType,
|
||||||
|
Objects.nonNull(qryCmd.getReceiptType()) ? qryCmd.getReceiptType().name() : null)
|
||||||
|
.eq(StringUtils.isNotBlank(qryCmd.getTrackId()), OrderUserPurchasePay::getReferenceId,
|
||||||
|
qryCmd.getTrackId())
|
||||||
|
.in(!sysOrigins.isEmpty(), OrderUserPurchasePay::getSysOrigin, sysOrigins)
|
||||||
|
.eq(Objects.nonNull(qryCmd.getAcceptUserId()), OrderUserPurchasePay::getUserId,
|
||||||
|
qryCmd.getAcceptUserId())
|
||||||
|
.eq(StringUtils.isNotBlank(qryCmd.getOrderId()), OrderUserPurchasePay::getFactoryOrderId,
|
||||||
|
qryCmd.getOrderId())
|
||||||
|
.eq(StringUtils.isNotBlank(qryCmd.getEnv()), OrderUserPurchasePay::getEvn,
|
||||||
|
qryCmd.getEnv())
|
||||||
|
.eq(StringUtils.isNotBlank(qryCmd.getCountryCode()), OrderUserPurchasePay::getCountryCode,
|
||||||
|
qryCmd.getCountryCode())
|
||||||
|
.eq(Objects.nonNull(payStatus), OrderUserPurchasePay::getPayStatus, payStatus)
|
||||||
|
.ge(Objects.nonNull(qryCmd.getStartTime()), OrderUserPurchasePay::getCreateTime,
|
||||||
|
toTimestamp(qryCmd.getStartTime()))
|
||||||
|
.le(Objects.nonNull(qryCmd.getEndTime()), OrderUserPurchasePay::getCreateTime,
|
||||||
|
toTimestamp(qryCmd.getEndTime()))
|
||||||
|
.lt(pageable && Objects.nonNull(lastId), OrderUserPurchasePay::getId, lastId)
|
||||||
|
.orderByDesc(OrderUserPurchasePay::getId);
|
||||||
|
|
||||||
|
if (pageable) {
|
||||||
|
query.last("LIMIT " + normalizeLimit(qryCmd.getLimit()));
|
||||||
|
}
|
||||||
|
return query.list();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean shouldIncludeMiFaPay(InAppPurchaseDetailsQryCmd qryCmd) {
|
||||||
|
if (StringUtils.isNotBlank(qryCmd.getFactoryPlatform())
|
||||||
|
&& !Objects.equals(H5_PLATFORM, qryCmd.getFactoryPlatform())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return StringUtils.isBlank(qryCmd.getSubscribeId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private InAppPurchaseDetails toMiFaPayDetails(OrderUserPurchasePay order, boolean withNotices) {
|
||||||
|
InAppPurchaseDetails details = MiFaPayMysqlOrderSupport.toInAppPurchaseDetails(order)
|
||||||
|
.setMetadata(miFaPayMetadata(order))
|
||||||
|
.setPayNotices(withNotices ? miFaPayNotices(order.getId()) : Collections.emptyList())
|
||||||
|
.setVersion(0);
|
||||||
|
return details;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, String> miFaPayMetadata(OrderUserPurchasePay order) {
|
||||||
|
Map<String, String> metadata = new HashMap<>();
|
||||||
|
putMetadata(metadata, "payStatus", order.getPayStatus());
|
||||||
|
putMetadata(metadata, "refundStatus", order.getRefundStatus());
|
||||||
|
putMetadata(metadata, "paymentChannel", order.getPaymentChannel());
|
||||||
|
putMetadata(metadata, "factoryChannel", order.getFactoryChannel());
|
||||||
|
putMetadata(metadata, "payCountryId", order.getPayCountryId());
|
||||||
|
putMetadata(metadata, "countryId", order.getCountryId());
|
||||||
|
putMetadata(metadata, "reason", order.getReason());
|
||||||
|
return metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void putMetadata(Map<String, String> metadata, String key, Object value) {
|
||||||
|
if (Objects.nonNull(value) && StringUtils.isNotBlank(Objects.toString(value, ""))) {
|
||||||
|
metadata.put(key, Objects.toString(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<InAppPurchaseEventNotice> miFaPayNotices(Long purchasePayId) {
|
||||||
|
if (Objects.isNull(purchasePayId)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
return orderUserPurchasePayNoticeService.query()
|
||||||
|
.eq(OrderUserPurchasePayNotice::getPurchasePayId, purchasePayId)
|
||||||
|
.orderByAsc(OrderUserPurchasePayNotice::getId)
|
||||||
|
.list()
|
||||||
|
.stream()
|
||||||
|
.map(notice -> new InAppPurchaseEventNotice()
|
||||||
|
.setEventId(notice.getEventId())
|
||||||
|
.setNoticeType(notice.getNoticeType())
|
||||||
|
.setNoticeData(parseNoticeData(notice.getNoticeData()))
|
||||||
|
.setCreateTime(notice.getCreateTime()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object parseNoticeData(String noticeData) {
|
||||||
|
if (StringUtils.isBlank(noticeData)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return JacksonUtils.readValue(noticeData, Object.class);
|
||||||
|
} catch (Exception ignore) {
|
||||||
|
return noticeData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<InAppPurchaseDetailsDTO> mergePage(List<InAppPurchaseDetailsDTO> first,
|
||||||
|
List<InAppPurchaseDetailsDTO> second, int limit) {
|
||||||
|
List<InAppPurchaseDetailsDTO> result = new ArrayList<>();
|
||||||
|
result.addAll(first);
|
||||||
|
result.addAll(second);
|
||||||
|
return result.stream()
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.sorted(Comparator.comparing(InAppPurchaseDetailsDTO::getId,
|
||||||
|
this::compareIdDesc))
|
||||||
|
.limit(limit)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
private int compareIdDesc(String left, String right) {
|
||||||
|
Long leftId = parseFilterId(left);
|
||||||
|
Long rightId = parseFilterId(right);
|
||||||
|
if (Objects.nonNull(leftId) && Objects.nonNull(rightId)) {
|
||||||
|
return rightId.compareTo(leftId);
|
||||||
|
}
|
||||||
|
return Objects.toString(right, "").compareTo(Objects.toString(left, ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<InAppPurchaseDetailsDTO> safeList(List<InAppPurchaseDetailsDTO> list) {
|
||||||
|
return Objects.isNull(list) ? Collections.emptyList() : list;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> parseSysOrigins(String sysOrigins) {
|
||||||
|
if (StringUtils.isBlank(sysOrigins)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
return Arrays.stream(sysOrigins.split(","))
|
||||||
|
.map(String::trim)
|
||||||
|
.filter(StringUtils::isNotBlank)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Long parseFilterId(String id) {
|
||||||
|
return MiFaPayMysqlOrderSupport.parseOrderId(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String toMiFaPayStatus(InAppPurchaseStatus status) {
|
||||||
|
if (Objects.isNull(status)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (Objects.equals(InAppPurchaseStatus.CREATE, status)) {
|
||||||
|
return MiFaPayMysqlOrderSupport.PAY_STATUS_PREPAYMENT;
|
||||||
|
}
|
||||||
|
if (Objects.equals(InAppPurchaseStatus.SUCCESS, status)) {
|
||||||
|
return MiFaPayMysqlOrderSupport.PAY_STATUS_SUCCESSFUL;
|
||||||
|
}
|
||||||
|
if (Objects.equals(InAppPurchaseStatus.FAIL, status)) {
|
||||||
|
return MiFaPayMysqlOrderSupport.PAY_STATUS_FAIL;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Timestamp toTimestamp(Long value) {
|
||||||
|
return Objects.isNull(value) ? null : new Timestamp(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int normalizeLimit(Integer limit) {
|
||||||
|
return Objects.isNull(limit) || limit <= 0 ? PageConstant.DEFAULT_LIMIT_SIZE : limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
private long longValue(Object value) {
|
||||||
|
return Objects.isNull(value) ? 0L : Long.parseLong(Objects.toString(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal decimalValue(Object value) {
|
||||||
|
return Objects.isNull(value) ? BigDecimal.ZERO : new BigDecimal(Objects.toString(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal sum(List<OrderUserPurchasePay> orders,
|
||||||
|
java.util.function.Function<OrderUserPurchasePay, BigDecimal> mapper) {
|
||||||
|
return orders.stream()
|
||||||
|
.map(mapper)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal average(BigDecimal amount, long count) {
|
||||||
|
if (count <= 0) {
|
||||||
|
return BigDecimal.ZERO;
|
||||||
|
}
|
||||||
|
return amount.divide(BigDecimal.valueOf(count), 8, RoundingMode.HALF_UP).stripTrailingZeros();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user