feat: include MifaPay orders in admin list
This commit is contained in:
parent
8f888c7041
commit
1d724dadd9
@ -1,17 +1,38 @@
|
||||
package com.red.circle.order.inner.service.impl;
|
||||
|
||||
import com.red.circle.order.infra.database.mongo.order.InAppPurchaseDetailsService;
|
||||
import com.red.circle.order.infra.database.mongo.order.entity.assist.CountUserInAppPurchase;
|
||||
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.dto.inapp.CountUserInAppPurchaseDTO;
|
||||
import com.red.circle.order.inner.model.dto.inapp.InAppPurchaseDetailsDTO;
|
||||
import com.red.circle.order.inner.service.InAppPurchaseDetailsClientService;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
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.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.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.model.cmd.inapp.InAppPurchaseDetailsQryCmd;
|
||||
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.enums.inapp.InAppPurchaseStatus;
|
||||
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.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.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 内购详情.
|
||||
@ -20,32 +41,278 @@ import org.springframework.stereotype.Service;
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class InAppPurchaseDetailsClientServiceImpl implements InAppPurchaseDetailsClientService {
|
||||
|
||||
private final InAppPurchaseDetailsService inAppPurchaseDetailsService;
|
||||
private final InAppPurchaseDetailsInnerConvert inAppPurchaseDetailsInnerConvert;
|
||||
|
||||
@Override
|
||||
public InAppPurchaseDetailsDTO getById(String id) {
|
||||
return inAppPurchaseDetailsInnerConvert.toInAppPurchaseDetailsDTO(
|
||||
inAppPurchaseDetailsService.getById(id)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<InAppPurchaseDetailsDTO> list(InAppPurchaseDetailsQryCmd qryCmd) {
|
||||
return inAppPurchaseDetailsInnerConvert.toListInAppPurchaseDetailsDTO(
|
||||
inAppPurchaseDetailsService.list(
|
||||
inAppPurchaseDetailsInnerConvert.toInAppPurchaseDetailsQuery(qryCmd))
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> statistics(InAppPurchaseDetailsQryCmd qryCmd) {
|
||||
return inAppPurchaseDetailsService.statistics(
|
||||
inAppPurchaseDetailsInnerConvert.toInAppPurchaseDetailsQuery(qryCmd)
|
||||
);
|
||||
}
|
||||
public class InAppPurchaseDetailsClientServiceImpl implements InAppPurchaseDetailsClientService {
|
||||
|
||||
private static final String H5_PLATFORM = "H5";
|
||||
|
||||
private final InAppPurchaseDetailsService inAppPurchaseDetailsService;
|
||||
private final InAppPurchaseDetailsInnerConvert inAppPurchaseDetailsInnerConvert;
|
||||
private final OrderUserPurchasePayService orderUserPurchasePayService;
|
||||
private final OrderUserPurchasePayNoticeService orderUserPurchasePayNoticeService;
|
||||
|
||||
@Override
|
||||
public InAppPurchaseDetailsDTO getById(String id) {
|
||||
InAppPurchaseDetails details = inAppPurchaseDetailsService.getById(id);
|
||||
if (Objects.isNull(details)) {
|
||||
details = getMiFaPayDetails(id);
|
||||
}
|
||||
return inAppPurchaseDetailsInnerConvert.toInAppPurchaseDetailsDTO(
|
||||
details
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<InAppPurchaseDetailsDTO> list(InAppPurchaseDetailsQryCmd qryCmd) {
|
||||
List<InAppPurchaseDetailsDTO> mongoOrders = safeList(
|
||||
inAppPurchaseDetailsInnerConvert.toListInAppPurchaseDetailsDTO(
|
||||
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
|
||||
public Map<String, Object> statistics(InAppPurchaseDetailsQryCmd qryCmd) {
|
||||
Map<String, Object> result = new HashMap<>(inAppPurchaseDetailsService.statistics(
|
||||
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
|
||||
public List<CountUserInAppPurchaseDTO> countUserInAppPurchase(String sysOrigin,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user