Files
billai/analyzer/clean_bill.py
2026-01-08 23:42:01 +08:00

112 lines
3.5 KiB
Python

#!/usr/bin/env python3
"""
账单清理统一入口
自动识别微信或支付宝账单,调用对应的清理逻辑
用法: python clean_bill.py <输入文件> [输出文件] [日期筛选选项]
示例:
python clean_bill.py 账单.csv --year 2026
python clean_bill.py 账单.csv --year 2026 --month 1
python clean_bill.py 账单.csv --start 2026-01-01 --end 2026-01-15
"""
import sys
import io
from pathlib import Path
# 解决 Windows 控制台编码问题
if sys.stdout.encoding != 'utf-8':
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
if sys.stderr.encoding != 'utf-8':
sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8', errors='replace')
from cleaners.base import create_arg_parser, compute_date_range
from cleaners import AlipayCleaner, WechatCleaner
def detect_bill_type(filepath: str) -> str | None:
"""
检测账单类型
Returns:
'alipay' | 'wechat' | None
"""
try:
with open(filepath, "r", encoding="utf-8") as f:
for _ in range(20):
line = f.readline()
if not line:
break
# 支付宝特征:表头包含"交易分类"和"对方账号"
if "交易分类" in line and "对方账号" in line:
return "alipay"
# 微信特征:表头包含"交易类型"和"金额(元)"
if "交易类型" in line and "金额(元)" in line:
return "wechat"
# 数据行特征
if line.startswith("202"):
if "" in line:
return "wechat"
if "@" in line:
return "alipay"
except Exception as e:
print(f"读取文件失败: {e}", file=sys.stderr)
return None
return None
def main():
parser = create_arg_parser("账单清理统一入口 - 自动识别微信/支付宝账单")
parser.add_argument(
"--type", "-t",
choices=["alipay", "wechat", "auto"],
default="auto",
help="手动指定账单类型(默认自动检测)"
)
args = parser.parse_args()
input_file = args.input_file
# 检查文件是否存在
if not Path(input_file).exists():
print(f"❌ 错误:文件不存在 - {input_file}", file=sys.stderr)
sys.exit(1)
# 检测账单类型
if args.type == "auto":
bill_type = detect_bill_type(input_file)
if bill_type is None:
print("❌ 无法识别账单类型,请使用 --type 参数手动指定", file=sys.stderr)
print(" 支持: --type alipay (支付宝) 或 --type wechat (微信)", file=sys.stderr)
sys.exit(1)
else:
bill_type = args.type
# 显示检测结果
type_names = {"alipay": "支付宝", "wechat": "微信"}
print(f"📋 检测到账单类型: {type_names[bill_type]}")
print()
# 计算日期范围
start_date, end_date = compute_date_range(args)
# 获取输出格式
output_format = getattr(args, 'format', 'csv')
# 创建对应的清理器
if bill_type == "alipay":
cleaner = AlipayCleaner(args.input_file, args.output_file, output_format)
else:
cleaner = WechatCleaner(args.input_file, args.output_file, output_format)
cleaner.set_date_range(start_date, end_date)
cleaner.clean()
if __name__ == "__main__":
main()