98 lines
3.3 KiB
Python
98 lines
3.3 KiB
Python
"""物流模块基类,不做具体实现"""
|
||
from enum import Enum
|
||
|
||
class LogisticsType(Enum):
|
||
EXPRESS = '快递'
|
||
LTL = '卡派'
|
||
OCEAN = '海运'
|
||
AIR = '空运'
|
||
class PortType(Enum):
|
||
DEFAULT = '默认'
|
||
WEST = 'west'
|
||
CENTRAL = 'central'
|
||
EAST = 'east'
|
||
SOUTH = 'south'
|
||
NORTH = 'north'
|
||
|
||
# 基础物流费用类
|
||
class BaseLogistics():
|
||
"""基础物流类,强制要求子类定义特定属性"""
|
||
company: str
|
||
currency:str = 'USD' # 货币单位,默认美元
|
||
port: PortType = PortType.DEFAULT
|
||
logistics_type:LogisticsType
|
||
active: bool = True # 是否启用该物流,默认未启用
|
||
def __init__(self):
|
||
# 检查子类是否定义了必要的类变量
|
||
for attr in ['company', 'country_code', 'country']:
|
||
if not getattr(self.__class__, attr, None):
|
||
raise AttributeError(f"Subclass {self.__class__.__name__} is missing required attribute '{attr}'.")
|
||
|
||
def __repr__(self):
|
||
return f"类名:{self.__class__.__name__}, 物流类型:{self.logistics_type.value}"
|
||
|
||
@classmethod
|
||
def get_open_subclasses(cls):
|
||
"""递归获取所有启用状态为 True 的子类"""
|
||
subclasses = set(cls.__subclasses__())
|
||
for subclass in cls.__subclasses__():
|
||
subclasses.update(subclass.get_open_subclasses())
|
||
subclasses = {subclass for subclass in subclasses if subclass.active ==True}
|
||
return subclasses
|
||
@classmethod
|
||
def get_close_subclasses(cls):
|
||
"""获取关闭状态的子类,状态为 False 的子类"""
|
||
subclasses = set(cls.__subclasses__())
|
||
for subclass in cls.__subclasses__():
|
||
subclasses.update(subclass.get_close_subclasses())
|
||
return {subclass for subclass in subclasses if subclass.active == False}
|
||
@classmethod
|
||
def open_logistics(cls):
|
||
"""打开该类"""
|
||
cls.active = True
|
||
@classmethod
|
||
def close_logistics(cls):
|
||
"""关闭该类"""
|
||
cls.active = False
|
||
|
||
|
||
|
||
class TailLogistics(BaseLogistics):
|
||
"""尾端物流类,包含快递和卡派"""
|
||
# 费用结果保存在实例对象中,不需要cal函数返回
|
||
country_code: str
|
||
country: str
|
||
company: str
|
||
currency:str = 'USD' # 货币单位,默认美元
|
||
port: PortType = PortType.DEFAULT
|
||
logistics_type = LogisticsType.EXPRESS # 默认快递
|
||
def __init__(self):
|
||
super().__init__()
|
||
def calculate_fee(self):
|
||
"""计算费用"""
|
||
raise NotImplementedError("Subclasses must implement express fee calculation.")
|
||
|
||
|
||
class HeadLogistics(BaseLogistics):
|
||
"""头程物流类,包含海运和空运"""
|
||
country_code: list[str]
|
||
country: list[str]
|
||
logistics_type = LogisticsType.OCEAN # 默认海运
|
||
currency = 'CNY'
|
||
def __init__(self):
|
||
super().__init__()
|
||
self.head_ratio:float
|
||
|
||
def calculate_fee(self, packages):
|
||
"""计算费用"""
|
||
detail_amount = {
|
||
"volume_weight":0.00,
|
||
"head_per":0.00,
|
||
"head_amount":0.00
|
||
}
|
||
total_weight = sum([package.get_volume_weight(6000) for package in packages])
|
||
detail_amount['volume_weight'] = round(total_weight,2)
|
||
detail_amount['head_per'] = self.head_ratio
|
||
detail_amount["head_amount"] = total_weight * self.head_ratio
|
||
return detail_amount
|