From 25729fa1ae7b630cbd4a9547a5693acd03c09c2a Mon Sep 17 00:00:00 2001
From: shinnosuke <tantao@1hoper.com>
Date: 星期三, 05 八月 2026 14:19:47 +0800
Subject: [PATCH] feat(payment): 添加汇付个人入驻功能并优化商户结算流程
---
talent-card-server/src/main/java/com/talentcard/server/business/merchant/ManualConsumptionService.java | 77 +++++++++++++++++++++++++++++++++++---
1 files changed, 70 insertions(+), 7 deletions(-)
diff --git a/talent-card-server/src/main/java/com/talentcard/server/business/merchant/ManualConsumptionService.java b/talent-card-server/src/main/java/com/talentcard/server/business/merchant/ManualConsumptionService.java
index c2d5c36..d7359f7 100644
--- a/talent-card-server/src/main/java/com/talentcard/server/business/merchant/ManualConsumptionService.java
+++ b/talent-card-server/src/main/java/com/talentcard/server/business/merchant/ManualConsumptionService.java
@@ -5,8 +5,11 @@
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.LinkedHashMap;
+import java.util.ArrayList;
import java.util.List;
import java.util.Map;
+
+import com.alibaba.fastjson.JSON;
import com.talentcard.server.business.BusinessIdGenerator;
import com.talentcard.server.business.DatabaseRows;
@@ -128,6 +131,8 @@
}
private List<Map<String, Object>> rules(Long merchantId, String cardLevel) {
+ List<Map<String, Object>> configured = configuredRules(merchantId, cardLevel);
+ if (!configured.isEmpty()) return configured;
return rows("""
select id, card_level, rule_name, discount_rate, subsidy_enabled
from merchant_store_consume_rule
@@ -144,7 +149,48 @@
}).toList();
}
+ private List<Map<String, Object>> configuredRules(Long merchantId, String cardLevel) {
+ List<Map<String, Object>> merchants = rows("select merchant_rights_config from merchant where id = ? and deleted = 0 limit 1", merchantId);
+ if (merchants.isEmpty()) return List.of();
+ Object raw = merchants.get(0).get("merchantRightsConfig");
+ if (raw == null || string(raw).isBlank()) return List.of();
+ List<Map<String, Object>> configs = new ArrayList<>();
+ try {
+ if (raw instanceof List<?> list) {
+ for (Object item : list) if (item instanceof Map<?, ?> map) {
+ Map<String, Object> value = new LinkedHashMap<>();
+ for (Map.Entry<?, ?> entry : map.entrySet()) value.put(String.valueOf(entry.getKey()), entry.getValue());
+ configs.add(value);
+ }
+ } else {
+ for (Object item : JSON.parseArray(string(raw), Map.class)) if (item instanceof Map<?, ?> map) {
+ Map<String, Object> value = new LinkedHashMap<>();
+ for (Map.Entry<?, ?> entry : map.entrySet()) value.put(String.valueOf(entry.getKey()), entry.getValue());
+ configs.add(value);
+ }
+ }
+ } catch (Exception ignored) {
+ return List.of();
+ }
+ return configs.stream().filter(right -> booleanValue(right.get("enabled")) && booleanValue(right.get("consumeEnabled")) && booleanValue(right.get("storeConsume")) && matchesCardLevel(string(right.get("level")), cardLevel)).map(this::configuredRule).filter(rule -> decimal(rule.get("discountRate")).signum() > 0).toList();
+ }
+
+ private Map<String, Object> configuredRule(Map<String, Object> right) {
+ String level = normalizedCardLevel(string(right.get("level")));
+ Map<String, Object> result = new LinkedHashMap<>();
+ result.put("id", configRuleId(level));
+ result.put("cardLevel", level);
+ result.put("ruleName", string(right.get("tag")).isBlank() ? "到店消费优惠" : right.get("tag"));
+ result.put("name", result.get("ruleName"));
+ result.put("discountRate", configuredDiscountRate(right.get("discount")));
+ result.put("subsidyEnabled", booleanValue(right.get("governmentSubsidy")) ? 1 : 0);
+ result.put("consumeDesc", right.get("consumeDesc"));
+ return result;
+ }
+
private Map<String, Object> rule(Long merchantId, String cardLevel, Long ruleId) {
+ List<Map<String, Object>> configured = configuredRules(merchantId, cardLevel);
+ for (Map<String, Object> candidate : configured) if (String.valueOf(candidate.get("id")).equals(String.valueOf(ruleId))) return candidate;
List<Map<String, Object>> found = rows("""
select id, card_level, rule_name, discount_rate, subsidy_enabled
from merchant_store_consume_rule
@@ -152,18 +198,34 @@
and (valid_end is null or valid_end >= current_date)
limit 1
""", ruleId, merchantId);
- if (found.isEmpty() || !matchesCardLevel(string(found.get(0).get("cardLevel")), cardLevel)) {
- throw new BusinessException(ErrorCode.CONFLICT, "当前人才卡不可使用所选优惠方式");
- }
+ if (found.isEmpty() || !matchesCardLevel(string(found.get(0).get("cardLevel")), cardLevel)) throw new BusinessException(ErrorCode.CONFLICT, "当前人才卡不可使用所选优惠方式");
return found.get(0);
+ }
+
+ private long configRuleId(String level) {
+ return switch (level) { case "EXCELLENT" -> -1L; case "OUTSTANDING" -> -2L; case "ELITE" -> -3L; default -> -9L; };
+ }
+
+ private BigDecimal configuredDiscountRate(Object value) {
+ try {
+ BigDecimal discount = decimal(string(value));
+ return discount.signum() > 0 && discount.compareTo(BigDecimal.TEN) <= 0 ? discount.divide(BigDecimal.TEN, 4, RoundingMode.HALF_UP) : BigDecimal.ZERO;
+ } catch (Exception ignored) {
+ return BigDecimal.ZERO;
+ }
+ }
+
+ private boolean booleanValue(Object value) {
+ if (value instanceof Boolean bool) return bool;
+ if (value instanceof Number number) return number.intValue() != 0;
+ String text = string(value).toLowerCase();
+ return "true".equals(text) || "1".equals(text) || "yes".equals(text);
}
private Map<String, Object> quote(Map<String, Object> rule, BigDecimal inputAmount) {
long originalAmount = inputAmount.movePointRight(2).setScale(0, RoundingMode.HALF_UP).longValueExact();
BigDecimal rate = decimal(rule.get("discountRate"));
- if (rate.signum() <= 0 || rate.compareTo(BigDecimal.ONE) > 0) {
- throw new BusinessException(ErrorCode.CONFLICT, "商户优惠规则配置无效");
- }
+ if (rate.signum() <= 0 || rate.compareTo(BigDecimal.ONE) > 0) throw new BusinessException(ErrorCode.CONFLICT, "商户优惠规则配置无效");
long payAmount = BigDecimal.valueOf(originalAmount).multiply(rate).setScale(0, RoundingMode.HALF_UP).longValueExact();
long discountAmount = originalAmount - payAmount;
long subsidyAmount = number(rule.get("subsidyEnabled")) == 1 ? discountAmount : 0;
@@ -175,7 +237,6 @@
result.put("ruleName", rule.get("ruleName"));
return result;
}
-
private Map<String, Object> merchant(MerchantPrincipal principal) {
List<Map<String, Object>> merchants = rows("""
select merchant_name, address, contact_mobile, longitude, latitude
@@ -208,6 +269,8 @@
select card_level, benefit_text from merchant_card_benefit
where merchant_id = ? and status = 1 order by sort_no desc, id desc
""", merchantId);
+ String configuredDescription = configuredRules(merchantId, cardLevel).stream().map(rule -> string(rule.get("consumeDesc"))).filter(value -> !value.isBlank()).findFirst().orElse("");
+ if (!configuredDescription.isBlank()) return configuredDescription;
return benefits.stream().filter(benefit -> matchesCardLevel(string(benefit.get("cardLevel")), cardLevel))
.map(benefit -> string(benefit.get("benefitText"))).findFirst().orElse("以当前商户到店消费规则为准");
}
--
Gitblit v1.7.1