diff --git a/src/main/java/cn/rosercode/ledgerly/importer/JdBillParser.java b/src/main/java/cn/rosercode/ledgerly/importer/JdBillParser.java index afd08b9..f65d306 100644 --- a/src/main/java/cn/rosercode/ledgerly/importer/JdBillParser.java +++ b/src/main/java/cn/rosercode/ledgerly/importer/JdBillParser.java @@ -14,6 +14,8 @@ import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; @@ -56,8 +58,8 @@ public class JdBillParser implements BillParser { /** CSV 解析格式:逗号分隔并去除字段首尾空白(含制表符) */ private static final CSVFormat CSV_FORMAT = CSVFormat.DEFAULT.builder().setTrim(true).build(); - /** 金额中需要剔除的货币符号与分隔符 */ - private static final String AMOUNT_STRIP_PATTERN = "[¥¥,\\s]"; + /** 金额中提取数值的正则:兼容「230.88(已全额退款)」等带说明、含货币符号与千分位的金额 */ + private static final Pattern AMOUNT_PATTERN = Pattern.compile("[-+]?\\d[\\d,]*(?:\\.\\d+)?"); /** JSON 序列化器,用于生成原始完整数据 */ private final ObjectMapper objectMapper; @@ -163,9 +165,11 @@ public class JdBillParser implements BillParser { String amountStr = get(header, values, COL_AMOUNT); if (StringUtils.hasText(amountStr)) { - try { - row.setAmount(new BigDecimal(amountStr.replaceAll(AMOUNT_STRIP_PATTERN, ""))); - } catch (NumberFormatException e) { + // 金额可能带「(已全额退款)」等说明,仅提取其中的数值部分 + Matcher matcher = AMOUNT_PATTERN.matcher(amountStr); + if (matcher.find()) { + row.setAmount(new BigDecimal(matcher.group().replace(",", ""))); + } else { row.setError("金额格式无法解析:" + amountStr); } }