diff --git a/rc-common-business/common-business-mq/business-mq-model/src/main/java/com/red/circle/mq/business/model/event/pay/BuySuccessEvent.java b/rc-common-business/common-business-mq/business-mq-model/src/main/java/com/red/circle/mq/business/model/event/pay/BuySuccessEvent.java index 9d70bed0..3cde35d7 100644 --- a/rc-common-business/common-business-mq/business-mq-model/src/main/java/com/red/circle/mq/business/model/event/pay/BuySuccessEvent.java +++ b/rc-common-business/common-business-mq/business-mq-model/src/main/java/com/red/circle/mq/business/model/event/pay/BuySuccessEvent.java @@ -56,9 +56,13 @@ public class BuySuccessEvent implements Serializable { */ String payPlatform; - /** - * 来源. - */ + /** + * 本次充值请求的App版本. + */ + String appVersion; + /** + * 来源. + */ String origin; /** diff --git a/rc-common-business/common-business-mq/business-mq-model/src/main/java/com/red/circle/mq/business/model/event/pay/RechargeSuccessEvent.java b/rc-common-business/common-business-mq/business-mq-model/src/main/java/com/red/circle/mq/business/model/event/pay/RechargeSuccessEvent.java index c81e22b2..6b1aa063 100644 --- a/rc-common-business/common-business-mq/business-mq-model/src/main/java/com/red/circle/mq/business/model/event/pay/RechargeSuccessEvent.java +++ b/rc-common-business/common-business-mq/business-mq-model/src/main/java/com/red/circle/mq/business/model/event/pay/RechargeSuccessEvent.java @@ -29,6 +29,7 @@ public class RechargeSuccessEvent implements Serializable { private String currency; private String payPlatform; private String paymentMethod; + private String appVersion; private String sourceOrderId; private String orderId; private String occurredAt; diff --git a/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/app/execute/AppInAppPurchaseCmdExe.java b/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/app/execute/AppInAppPurchaseCmdExe.java index a5afca82..b7ce4aca 100644 --- a/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/app/execute/AppInAppPurchaseCmdExe.java +++ b/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/app/execute/AppInAppPurchaseCmdExe.java @@ -109,6 +109,7 @@ public class AppInAppPurchaseCmdExe { .setSysOrigin(history.getSysOrigin()) .setPlatform(history.getPlatform()) .setPayPlatform(history.getPayPlatform()) + .setAppVersion(reqAppVersion(cmd)) .setOrigin(appCommodity.getProductConfigProductId()) .setOriginName(appCommodity.getOriginDescription()) .setExpireDateMs(history.getExpiresDateMs()) @@ -168,7 +169,12 @@ public class AppInAppPurchaseCmdExe { return MonthlyRechargeType.UNDEFINED; } - private void saveFriendshipRecord(AppCommodity appCommodity) { + private String reqAppVersion(AbstractPurchaseCmd cmd) { + return Objects.nonNull(cmd.getReqAppIntel()) + ? Objects.toString(cmd.getReqAppIntel().getVersion(), "") + : ""; + } + private void saveFriendshipRecord(AppCommodity appCommodity) { PurchaseHistory purchaseHistory = appCommodity.getPurchaseHistory(); orderPurchaseFriendshipRecordService.save( new OrderPurchaseFriendshipRecord() diff --git a/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/PayWebPlaceAnOrderCmdExe.java b/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/PayWebPlaceAnOrderCmdExe.java index c76ba76f..234aa18f 100644 --- a/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/PayWebPlaceAnOrderCmdExe.java +++ b/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/PayWebPlaceAnOrderCmdExe.java @@ -119,11 +119,12 @@ public class PayWebPlaceAnOrderCmdExe { + "&appId=" + application.getId() + "&appStatus=0" + "&appType=" + commodity.getType()); - details.setCancelRedirectUrl(details.getRechargeUrl()); - details.setNewVersion(cmd.getNewVersion()); - details.setRequestIp(IpUtils.getIpAddr()); - - // 记录充值金额 + details.setCancelRedirectUrl(details.getRechargeUrl()); + details.setNewVersion(cmd.getNewVersion()); + details.setAppVersion(cmd.getAppVersion()); + details.setRequestIp(IpUtils.getIpAddr()); + + // 记录充值金额 rechargeRecord(details); return details; } diff --git a/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/strategy/PayPlaceAnOrderDetailsV2.java b/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/strategy/PayPlaceAnOrderDetailsV2.java index 00ff3e75..4a38e8b7 100644 --- a/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/strategy/PayPlaceAnOrderDetailsV2.java +++ b/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/strategy/PayPlaceAnOrderDetailsV2.java @@ -115,9 +115,13 @@ public class PayPlaceAnOrderDetailsV2 implements Serializable { */ private Boolean newVersion; - /** - * 请求ip信息. - */ + /** + * 本次充值请求的App版本. + */ + private String appVersion; + /** + * 请求ip信息. + */ private String requestIp; public String getFactoryChannel() { @@ -156,6 +160,7 @@ public class PayPlaceAnOrderDetailsV2 implements Serializable { .put("countryCode", this.getCountryCode()) .put("amount", this.getAmount().toString()) .put("currency", this.getCurrency()) + .put("appVersion", Objects.toString(this.getAppVersion(), "")) .build(); } diff --git a/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/strategy/PayPlaceAnOrderService.java b/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/strategy/PayPlaceAnOrderService.java index 37935343..10d25a64 100644 --- a/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/strategy/PayPlaceAnOrderService.java +++ b/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/command/pay/web/strategy/PayPlaceAnOrderService.java @@ -1,7 +1,6 @@ package com.red.circle.order.app.command.pay.web.strategy; -import com.google.api.client.util.Maps; -import com.red.circle.component.pay.paymax.PayMaxUtils; +import com.red.circle.component.pay.paymax.PayMaxUtils; import com.red.circle.framework.core.request.RequestClientEnum; import com.red.circle.framework.web.props.EnvProperties; import com.red.circle.order.app.common.MiFaPayMysqlOrderSupport; @@ -104,9 +103,9 @@ public class PayPlaceAnOrderService { .setNoticeData(response.extra()) .setCreateTime(TimestampUtils.now()) )) - .setMetadata(Maps.newHashMap()) - .setVersion(0) - ); + .setMetadata(param.createMetadata()) + .setVersion(0) + ); return response; } diff --git a/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/common/MiFaPayMysqlOrderSupport.java b/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/common/MiFaPayMysqlOrderSupport.java index 0f3c16bd..76f8262a 100644 --- a/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/common/MiFaPayMysqlOrderSupport.java +++ b/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/common/MiFaPayMysqlOrderSupport.java @@ -15,7 +15,9 @@ import java.math.BigDecimal; import java.math.RoundingMode; import java.sql.Timestamp; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; /** @@ -61,6 +63,7 @@ public final class MiFaPayMysqlOrderSupport { .setFactoryCode(param.getFactoryCode()) .setFactoryOrderId(Objects.toString(response.getTradeNo(), "")) .setReferenceId(Objects.toString(param.getApplicationId(), "")) + .setAppVersion(Objects.toString(param.getAppVersion(), "")) .setReceiptType(Objects.toString(param.getReceiptType(), InAppPurchaseReceiptType.PAYMENT.name())) .setPaymentChannel(Objects.toString(param.getChannelCode(), "")) @@ -121,7 +124,8 @@ public final class MiFaPayMysqlOrderSupport { .setReason(order.getReason()) .setCreateTime(order.getCreateTime()) .setUpdateTime(order.getUpdateTime()) - .setCreateUser(order.getCreateUser()); + .setCreateUser(order.getCreateUser()) + .setMetadata(metadata(order)); } public static InAppPurchaseStatus toInAppPurchaseStatus(String payStatus) { @@ -162,6 +166,14 @@ public final class MiFaPayMysqlOrderSupport { return InAppPurchaseReceiptType.PAYMENT; } + private static Map metadata(OrderUserPurchasePay order) { + Map metadata = new HashMap<>(); + if (StringUtils.isNotBlank(order.getAppVersion())) { + metadata.put("appVersion", order.getAppVersion()); + } + return metadata; + } + private static BigDecimal defaultDecimal(BigDecimal value) { return value != null ? value : BigDecimal.ZERO; } diff --git a/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/common/task/RechargeSuccessEventPublisher.java b/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/common/task/RechargeSuccessEventPublisher.java index 264b8758..e9fa7959 100644 --- a/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/common/task/RechargeSuccessEventPublisher.java +++ b/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/common/task/RechargeSuccessEventPublisher.java @@ -65,10 +65,12 @@ public class RechargeSuccessEventPublisher { payload.put("candyQuantity", event.getCandyQuantity()); payload.put("platform", event.getPlatform()); payload.put("payPlatform", event.getPayPlatform()); + payload.put("appVersion", event.getAppVersion()); String sourceOrderId = String.valueOf(purchaseHistoryId); String payPlatform = normalizePayPlatform(defaultIfBlank(event.getPayPlatform(), event.getPlatform())); String paymentMethod = classifyPaymentMethod(payPlatform); + String appVersion = defaultIfBlank(event.getAppVersion(), ""); publish(new RechargeSuccessEvent() .setEventId("RECHARGE_SUCCESS:" + paymentMethod + ":" + sourceOrderId) .setSysOrigin(event.getSysOrigin()) @@ -78,6 +80,7 @@ public class RechargeSuccessEventPublisher { .setCurrency("USD") .setPayPlatform(payPlatform) .setPaymentMethod(paymentMethod) + .setAppVersion(appVersion) .setSourceOrderId(sourceOrderId) .setOrderId(sourceOrderId) .setOccurredAt(toInstantString(event.getBuyDateTime())) @@ -110,6 +113,8 @@ public class RechargeSuccessEventPublisher { payload.put("platform", Objects.nonNull(order.getFactory()) ? order.getFactory().getPlatform() : null); payload.put("productCode", product.getCode()); payload.put("productContent", product.getContent()); + String appVersion = appVersionFromMetadata(order); + payload.put("appVersion", appVersion); publish(new RechargeSuccessEvent() .setEventId("RECHARGE_SUCCESS:" + paymentMethod + ":" + payPlatform + ":" + order.getId()) @@ -120,6 +125,7 @@ public class RechargeSuccessEventPublisher { .setCurrency(defaultIfBlank(order.getCurrency(), "USD")) .setPayPlatform(payPlatform) .setPaymentMethod(paymentMethod) + .setAppVersion(appVersion) .setSourceOrderId(order.getId()) .setOrderId(defaultIfBlank(order.getOrderId(), order.getId())) .setOccurredAt(firstTime(order.getPurchaseDateMs(), order.getUpdateTime(), order.getCreateTime())) @@ -165,6 +171,13 @@ public class RechargeSuccessEventPublisher { return THIRD_PARTY; } + private String appVersionFromMetadata(InAppPurchaseDetails order) { + if (Objects.isNull(order) || Objects.isNull(order.getMetadata())) { + return ""; + } + return defaultIfBlank(order.getMetadata().get("appVersion"), ""); + } + private Long toCents(BigDecimal amount) { if (Objects.isNull(amount) || amount.compareTo(BigDecimal.ZERO) <= 0) { return null; diff --git a/rc-service/rc-service-order/order-client/src/main/java/com/red/circle/order/app/dto/cmd/PayPlaceAnOrderCmd.java b/rc-service/rc-service-order/order-client/src/main/java/com/red/circle/order/app/dto/cmd/PayPlaceAnOrderCmd.java index 3aacbe65..8c8766b4 100644 --- a/rc-service/rc-service-order/order-client/src/main/java/com/red/circle/order/app/dto/cmd/PayPlaceAnOrderCmd.java +++ b/rc-service/rc-service-order/order-client/src/main/java/com/red/circle/order/app/dto/cmd/PayPlaceAnOrderCmd.java @@ -64,9 +64,13 @@ public class PayPlaceAnOrderCmd implements Serializable { */ private Boolean newVersion; - /** - * 请求ip信息. - */ + /** + * 本次充值请求的App版本. + */ + private String appVersion; + /** + * 请求ip信息. + */ private String requestIp; } diff --git a/rc-service/rc-service-order/order-infrastructure/src/main/java/com/red/circle/order/infra/database/rds/entity/order/OrderUserPurchasePay.java b/rc-service/rc-service-order/order-infrastructure/src/main/java/com/red/circle/order/infra/database/rds/entity/order/OrderUserPurchasePay.java index 11b16e74..58af85b2 100644 --- a/rc-service/rc-service-order/order-infrastructure/src/main/java/com/red/circle/order/infra/database/rds/entity/order/OrderUserPurchasePay.java +++ b/rc-service/rc-service-order/order-infrastructure/src/main/java/com/red/circle/order/infra/database/rds/entity/order/OrderUserPurchasePay.java @@ -45,6 +45,9 @@ public class OrderUserPurchasePay implements Serializable { @TableField("reference_id") private String referenceId; + @TableField("app_version") + private String appVersion; + @TableField("receipt_type") private String receiptType; diff --git a/rc-service/rc-service-order/order-inner-endpoint/src/main/java/com/red/circle/order/inner/service/impl/InAppPurchaseDetailsClientServiceImpl.java b/rc-service/rc-service-order/order-inner-endpoint/src/main/java/com/red/circle/order/inner/service/impl/InAppPurchaseDetailsClientServiceImpl.java index a21b1e26..ddae2b28 100644 --- a/rc-service/rc-service-order/order-inner-endpoint/src/main/java/com/red/circle/order/inner/service/impl/InAppPurchaseDetailsClientServiceImpl.java +++ b/rc-service/rc-service-order/order-inner-endpoint/src/main/java/com/red/circle/order/inner/service/impl/InAppPurchaseDetailsClientServiceImpl.java @@ -190,6 +190,7 @@ public class InAppPurchaseDetailsClientServiceImpl implements InAppPurchaseDetai putMetadata(metadata, "payCountryId", order.getPayCountryId()); putMetadata(metadata, "countryId", order.getCountryId()); putMetadata(metadata, "reason", order.getReason()); + putMetadata(metadata, "appVersion", order.getAppVersion()); return metadata; } diff --git a/rc-service/rc-service-other/other-inner-endpoint/src/main/java/com/red/circle/other/app/inner/service/material/props/impl/PropsActivityRewardGroupClientServiceImpl.java b/rc-service/rc-service-other/other-inner-endpoint/src/main/java/com/red/circle/other/app/inner/service/material/props/impl/PropsActivityRewardGroupClientServiceImpl.java index a1c1143c..fd8f73de 100644 --- a/rc-service/rc-service-other/other-inner-endpoint/src/main/java/com/red/circle/other/app/inner/service/material/props/impl/PropsActivityRewardGroupClientServiceImpl.java +++ b/rc-service/rc-service-other/other-inner-endpoint/src/main/java/com/red/circle/other/app/inner/service/material/props/impl/PropsActivityRewardGroupClientServiceImpl.java @@ -294,13 +294,18 @@ public class PropsActivityRewardGroupClientServiceImpl implements if (Objects.equals(config.getType(), PropsActivityRewardEnum.PROPS.name()) || Objects.equals(config.getType(), PropsActivityRewardEnum.PROP_COUPON.name())) { PropsSourceRecord sourceRecord = sourceRecordMap .get(Long.valueOf(config.getContent())); - if (Objects.nonNull(sourceRecord)) { - propsActivity.setCover(sourceRecord.getCover()); - propsActivity.setSourceUrl(sourceRecord.getSourceUrl()); - propsActivity.setAmount(sourceRecord.getAmount()); - propsActivity.setName(sourceRecord.getName()); - } - } + if (Objects.nonNull(sourceRecord)) { + if (Objects.equals(config.getType(), PropsActivityRewardEnum.PROPS.name()) + && StringUtils.isNotBlank(sourceRecord.getType())) { + propsActivity.setType(sourceRecord.getType()); + propsActivity.setDetailType(sourceRecord.getType()); + } + propsActivity.setCover(sourceRecord.getCover()); + propsActivity.setSourceUrl(sourceRecord.getSourceUrl()); + propsActivity.setAmount(sourceRecord.getAmount()); + propsActivity.setName(sourceRecord.getName()); + } + } if (Objects.equals(config.getType(), PropsActivityRewardEnum.FRAGMENTS.name())) { PropsSourceRecord sourceRecord = fragmentsSourceMap @@ -432,6 +437,8 @@ public class PropsActivityRewardGroupClientServiceImpl implements private void setVipConfig(PropsActivityRewardConfig config, PropsActivityRewardConfigInfoDTO propsActivity, VipLevelConfig vipConfig, Map vipCoverMap) { + propsActivity.setType(VipActivityRewardCommon.VIP_DETAIL_TYPE); + propsActivity.setDetailType(VipActivityRewardCommon.VIP_DETAIL_TYPE); propsActivity.setCover(resolveVipCover(vipConfig, vipCoverMap)); propsActivity.setSourceUrl(resolveVipSourceUrl(vipConfig, vipCoverMap)); propsActivity.setAmount(BigDecimal.valueOf(Objects.requireNonNullElse( diff --git a/sql/20260525_mifapay_order_app_version.sql b/sql/20260525_mifapay_order_app_version.sql new file mode 100644 index 00000000..715fa715 --- /dev/null +++ b/sql/20260525_mifapay_order_app_version.sql @@ -0,0 +1,16 @@ +SET @table_schema = DATABASE(); + +SET @ddl = IF( + EXISTS( + SELECT 1 + FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = @table_schema + AND TABLE_NAME = 'order_user_purchase_pay' + AND COLUMN_NAME = 'app_version' + ), + 'SELECT 1', + "ALTER TABLE `order_user_purchase_pay` ADD COLUMN `app_version` varchar(32) NOT NULL DEFAULT '' COMMENT '本次充值请求的App版本' AFTER `reference_id`" +); +PREPARE stmt FROM @ddl; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; diff --git a/sql/20260525_region_broadcast_menu.sql b/sql/20260525_region_broadcast_menu.sql new file mode 100644 index 00000000..9cca4f79 --- /dev/null +++ b/sql/20260525_region_broadcast_menu.sql @@ -0,0 +1,75 @@ +SET NAMES utf8mb4; + +SET @operate_manager_id := ( + SELECT id + FROM sys_menu + WHERE alias = 'OperateManager' + LIMIT 1 +); + +INSERT INTO sys_menu ( + id, + parent_id, + menu_name, + path, + menu_type, + icon, + create_user, + update_user, + sort, + status, + router, + alias +) +SELECT + menu_id.next_id, + @operate_manager_id, + '区域飘屏', + 'operate/region-broadcast', + 2, + 'lucide:radio-tower', + '0', + '0', + 18, + 0, + 'region-broadcast', + 'OperateRegionBroadcast' +FROM ( + SELECT COALESCE(MAX(id), 1700000000) + 1 AS next_id + FROM sys_menu +) AS menu_id +WHERE @operate_manager_id IS NOT NULL + AND NOT EXISTS ( + SELECT 1 FROM sys_menu WHERE alias = 'OperateRegionBroadcast' + ); + +UPDATE sys_menu +SET + parent_id = @operate_manager_id, + menu_name = '区域飘屏', + path = 'operate/region-broadcast', + menu_type = 2, + icon = 'lucide:radio-tower', + update_user = '0', + sort = 18, + status = 0, + router = 'region-broadcast' +WHERE alias = 'OperateRegionBroadcast' + AND @operate_manager_id IS NOT NULL; + +INSERT INTO sys_role_menu (role_id, menu_id) +SELECT DISTINCT + role_menu.role_id, + target_menu.id +FROM sys_role_menu AS role_menu +JOIN sys_menu AS source_menu + ON source_menu.id = role_menu.menu_id + AND source_menu.alias = 'OperateManager' +JOIN sys_menu AS target_menu + ON target_menu.alias = 'OperateRegionBroadcast' +WHERE NOT EXISTS ( + SELECT 1 + FROM sys_role_menu AS existing_role_menu + WHERE existing_role_menu.role_id = role_menu.role_id + AND existing_role_menu.menu_id = target_menu.id +);