feat: 京东账单专属分类映射配置

This commit is contained in:
CHE LIANG ZHAO
2026-01-26 14:12:05 +08:00
parent 9e146c5ef0
commit 279eceaa95
3 changed files with 147 additions and 7 deletions

View File

@@ -4,6 +4,9 @@
import csv
import re
from decimal import Decimal
from pathlib import Path
import yaml
from .base import (
BaseCleaner, parse_amount, format_amount,
@@ -12,6 +15,54 @@ from .base import (
from category import infer_category
# 加载京东专属分类配置
JD_CONFIG_FILE = Path(__file__).parent.parent / "config" / "category_jd.yaml"
def load_jd_config():
"""加载京东分类配置"""
with open(JD_CONFIG_FILE, "r", encoding="utf-8") as f:
return yaml.safe_load(f)
_jd_config = load_jd_config()
def infer_jd_category(merchant: str, product: str, original_category: str) -> tuple[str, bool]:
"""
根据京东账单的商户名称、商品说明和原分类推断统一分类
Args:
merchant: 商户名称(如"京东外卖""京东平台商户"
product: 交易说明/商品说明
original_category: 京东原始分类(如"食品酒饮""数码电器"
Returns:
(分类名称, 是否确定) - 如果无法确定分类,第二个值为 False
"""
# 1. 先检查商户名称直接映射(如"京东外卖" -> "餐饮美食"
merchant_mapping = _jd_config.get("商户映射", {})
for merchant_key, category in merchant_mapping.items():
if merchant_key in merchant:
return category, True
# 2. 尝试直接映射京东原分类
category_mapping = _jd_config.get("分类映射", {})
# 处理多分类情况(如"食品酒饮 其他网购"
original_cats = original_category.split() if original_category else []
for orig_cat in original_cats:
mapped = category_mapping.get(orig_cat)
if mapped: # 非空映射
return mapped, True
# 3. 使用通用分类推断(已包含京东平台商户关键词)
category, is_certain = infer_category(merchant, product, "支出")
if is_certain:
return category, True
# 4. 返回默认分类
return _jd_config.get("默认分类", "其他支出"), False
# 与支付宝/微信对齐的表头(包含"复核等级"字段)
ALIGNED_HEADER = [
"交易时间", "交易分类", "交易对方", "对方账号", "商品说明",
@@ -242,13 +293,8 @@ class JDCleaner(BaseCleaner):
merchant_order_no = row[9] if len(row) > 9 else ""
final_remark = remark if remark else (row[10] if len(row) > 10 else "/")
# 使用推断分类(京东原始分类相对准确,但仍可优化)
category, is_certain = infer_category(merchant, product, income_expense)
# 如果推断失败但原分类非空,使用原分类
if not is_certain and original_category and original_category not in ["其他", ""]:
category = original_category
is_certain = True # 信任京东原分类
# 使用京东专属分类推断
category, is_certain = infer_jd_category(merchant, product, original_category)
# 复核等级: 空=无需复核, HIGH=无法判断
review_mark = "" if is_certain else "HIGH"