Files
TableProcessing/config_loader.py
Aiden_ 5b32208194 xx
2025-10-31 21:24:08 +08:00

211 lines
6.9 KiB
Python

#!/usr/bin/env python3
"""
配置文件加载工具
支持从config.ini读取配置参数
"""
import configparser
import os
from typing import Any, Optional
from dataclasses import dataclass
@dataclass
class ExcelConfig:
"""Excel配置"""
input_file: str
sheet_name: str
data_start_row: int
col_received_amount: int
col_handling_fee: int
col_order_num: int
col_amount: int
col_account_name: int
@dataclass
class OutputConfig:
"""输出配置"""
json_output: str
excel_output: str
validation_report: str
@dataclass
class ProcessingConfig:
"""处理配置"""
amount_tolerance: float
skip_empty_orders: bool
@dataclass
class AccountingConfig:
"""会计配置"""
default_exchange_rate: float
exchange_rate_file: str
account_code_bank: str
account_code_fee: str
account_code_receivable: str
account_name_bank: str
account_name_fee: str
account_name_receivable: str
@dataclass
class LoggingConfig:
"""日志配置"""
log_level: str
log_format: str
log_file: str
class ConfigLoader:
"""配置加载器"""
def __init__(self, config_file: str = 'config.ini'):
"""
初始化配置加载器
参数:
config_file: 配置文件路径
"""
self.config_file = config_file
self.config = configparser.ConfigParser()
if os.path.exists(config_file):
self.config.read(config_file, encoding='utf-8')
else:
raise FileNotFoundError(f"配置文件不存在: {config_file}")
def _get_value(self, section: str, key: str, default: Any = None,
value_type: type = str) -> Any:
"""
获取配置值
参数:
section: 配置节名
key: 配置键名
default: 默认值
value_type: 值类型
返回:
配置值
"""
try:
if value_type == bool:
return self.config.getboolean(section, key)
elif value_type == int:
return self.config.getint(section, key)
elif value_type == float:
return self.config.getfloat(section, key)
else:
return self.config.get(section, key)
except (configparser.NoSectionError, configparser.NoOptionError):
return default
def load_excel_config(self) -> ExcelConfig:
"""加载Excel配置"""
return ExcelConfig(
input_file=self._get_value('Excel', 'input_file', 'data/data.xlsx'),
sheet_name=self._get_value('Excel', 'sheet_name', 'Sheet1'),
data_start_row=self._get_value('Excel', 'data_start_row', 2, int),
col_received_amount=self._get_value('Excel', 'col_received_amount', 6, int),
col_handling_fee=self._get_value('Excel', 'col_handling_fee', 7, int),
col_order_num=self._get_value('Excel', 'col_order_num', 8, int),
col_amount=self._get_value('Excel', 'col_amount', 9, int),
col_account_name=self._get_value('Excel', 'col_account_name', 15, int)
)
def load_output_config(self) -> OutputConfig:
"""加载输出配置"""
return OutputConfig(
json_output=self._get_value('Output', 'json_output', 'res.json'),
excel_output=self._get_value('Output', 'excel_output', 'AccountingEntries.xlsx'),
validation_report=self._get_value('Output', 'validation_report', 'validation_report.txt')
)
def load_processing_config(self) -> ProcessingConfig:
"""加载处理配置"""
return ProcessingConfig(
amount_tolerance=self._get_value('Processing', 'amount_tolerance', 0.01, float),
skip_empty_orders=self._get_value('Processing', 'skip_empty_orders', True, bool)
)
def load_accounting_config(self) -> AccountingConfig:
"""加载会计配置"""
return AccountingConfig(
default_exchange_rate=self._get_value('Accounting', 'default_exchange_rate', 7.1072, float),
exchange_rate_file=self._get_value('Accounting', 'exchange_rate_file', 'exchange_rate.txt'),
account_code_bank=self._get_value('Accounting', 'account_code_bank', '1002.02'),
account_code_fee=self._get_value('Accounting', 'account_code_fee', '5603.03'),
account_code_receivable=self._get_value('Accounting', 'account_code_receivable', '1122'),
account_name_bank=self._get_value('Accounting', 'account_name_bank', '银行存款 - 中行USD'),
account_name_fee=self._get_value('Accounting', 'account_name_fee', '财务费用-手续费'),
account_name_receivable=self._get_value('Accounting', 'account_name_receivable', '应收账款')
)
def load_logging_config(self) -> LoggingConfig:
"""加载日志配置"""
return LoggingConfig(
log_level=self._get_value('Logging', 'log_level', 'INFO'),
log_format=self._get_value('Logging', 'log_format',
'%(asctime)s - %(levelname)s - %(message)s'),
log_file=self._get_value('Logging', 'log_file', 'processing.log')
)
def load_all(self) -> dict:
"""
加载所有配置
返回:
包含所有配置的字典
"""
return {
'excel': self.load_excel_config(),
'output': self.load_output_config(),
'processing': self.load_processing_config(),
'accounting': self.load_accounting_config(),
'logging': self.load_logging_config()
}
def main():
"""测试配置加载"""
try:
loader = ConfigLoader()
configs = loader.load_all()
print("配置加载成功:")
print("-" * 60)
print("\nExcel配置:")
print(f" 输入文件: {configs['excel'].input_file}")
print(f" 工作表: {configs['excel'].sheet_name}")
print(f" 数据起始行: {configs['excel'].data_start_row}")
print("\n输出配置:")
print(f" JSON输出: {configs['output'].json_output}")
print(f" Excel输出: {configs['output'].excel_output}")
print("\n处理配置:")
print(f" 金额容差: {configs['processing'].amount_tolerance}")
print(f" 跳过空订单: {configs['processing'].skip_empty_orders}")
print("\n会计配置:")
print(f" 默认汇率: {configs['accounting'].default_exchange_rate}")
print(f" 银行科目代码: {configs['accounting'].account_code_bank}")
print("\n日志配置:")
print(f" 日志级别: {configs['logging'].log_level}")
print(f" 日志文件: {configs['logging'].log_file}")
except Exception as e:
print(f"配置加载失败: {e}")
if __name__ == '__main__':
main()