refactor: countryRegion 统一中文归一化; label-ocr 改用 countryRegion; destinationCountry 还原 ISO2
This commit is contained in:
+7
-7
@@ -115,16 +115,16 @@ def process_all(pending: list) -> dict[str, int]:
|
|||||||
|
|
||||||
@flow(name="label-ocr", log_prints=True)
|
@flow(name="label-ocr", log_prints=True)
|
||||||
def label_ocr(
|
def label_ocr(
|
||||||
destination_countries: list[str] | None = None,
|
country_regions: list[str] | None = None,
|
||||||
courier_source: str | None = None,
|
courier_source: str | None = None,
|
||||||
days: int = 7,
|
days: int = 7,
|
||||||
) -> dict:
|
) -> dict:
|
||||||
"""面单 OCR enrichment。默认处理英国(GB)+美国(US),近 7 天下单的订单。
|
"""面单 OCR enrichment。默认处理英国+美国,近 7 天下单的订单。
|
||||||
|
|
||||||
手动跑其他国家: label_ocr(destination_countries=['德国'])
|
手动跑其他国家: label_ocr(country_regions=['德国'])
|
||||||
"""
|
"""
|
||||||
if destination_countries is None:
|
if country_regions is None:
|
||||||
destination_countries = ['英国', '美国']
|
country_regions = ['英国', '美国']
|
||||||
if _has_running_peer():
|
if _has_running_peer():
|
||||||
print("已有 label-ocr 在运行,跳过本次")
|
print("已有 label-ocr 在运行,跳过本次")
|
||||||
return {"skipped": True}
|
return {"skipped": True}
|
||||||
@@ -133,11 +133,11 @@ def label_ocr(
|
|||||||
print(f"OCR 状态(开始): {before}")
|
print(f"OCR 状态(开始): {before}")
|
||||||
|
|
||||||
pending = db.get_ocr_pending(
|
pending = db.get_ocr_pending(
|
||||||
destination_countries=destination_countries,
|
country_regions=country_regions,
|
||||||
courier_source=courier_source,
|
courier_source=courier_source,
|
||||||
days=days,
|
days=days,
|
||||||
)
|
)
|
||||||
scope = f" [{'/'.join(destination_countries)}{f' {courier_source}' if courier_source else ''}]"
|
scope = f" [{'/'.join(country_regions)}{f' {courier_source}' if courier_source else ''}]"
|
||||||
print(f"待 OCR: {len(pending)} 单{scope} (RIIN+SDS, 近{days}天)")
|
print(f"待 OCR: {len(pending)} 单{scope} (RIIN+SDS, 近{days}天)")
|
||||||
if not pending:
|
if not pending:
|
||||||
emit_sync_summary(f"面单 OCR{scope}", build_stats_rows("ALL", {}, [
|
emit_sync_summary(f"面单 OCR{scope}", build_stats_rows("ALL", {}, [
|
||||||
|
|||||||
+7
-7
@@ -102,25 +102,25 @@ class SyncDB:
|
|||||||
|
|
||||||
def get_ocr_pending(
|
def get_ocr_pending(
|
||||||
self, limit: int = 0,
|
self, limit: int = 0,
|
||||||
destination_countries: list[str] | None = None,
|
country_regions: list[str] | None = None,
|
||||||
courier_source: str | None = None,
|
courier_source: str | None = None,
|
||||||
days: int = 0,
|
days: int = 0,
|
||||||
) -> list[tuple[str, datetime, str, str | None]]:
|
) -> list[tuple[str, datetime, str, str | None]]:
|
||||||
"""查待 OCR 订单(所有系统):(orderNo, createdAt, labelPdfUrl, destinationCountry)。
|
"""查待 OCR 订单(所有系统):(orderNo, createdAt, labelPdfUrl, countryRegion)。
|
||||||
|
|
||||||
条件:有 labelPdfUrl、ocrLayout 未处理(Null)。
|
条件:有 labelPdfUrl、ocrLayout 未处理(Null)。
|
||||||
limit=0 表示不限。可选按 destinationCountries / courierSource 筛选。
|
limit=0 表示不限。可选按 countryRegions / courierSource 筛选。
|
||||||
days>0 时只取近 N 天下单的订单。
|
days>0 时只取近 N 天下单的订单。
|
||||||
"""
|
"""
|
||||||
sql = (
|
sql = (
|
||||||
'SELECT "orderNo","createdAt","labelPdfUrl","destinationCountry" '
|
'SELECT "orderNo","createdAt","labelPdfUrl","countryRegion" '
|
||||||
'FROM "Orders" '
|
'FROM "Orders" '
|
||||||
'WHERE "labelPdfUrl" IS NOT NULL AND "ocrLayout" IS NULL'
|
'WHERE "labelPdfUrl" IS NOT NULL AND "ocrLayout" IS NULL'
|
||||||
)
|
)
|
||||||
params: list = []
|
params: list = []
|
||||||
if destination_countries:
|
if country_regions:
|
||||||
sql += ' AND "destinationCountry"=ANY(%s)'
|
sql += ' AND "countryRegion"=ANY(%s)'
|
||||||
params.append(destination_countries)
|
params.append(country_regions)
|
||||||
if courier_source:
|
if courier_source:
|
||||||
sql += ' AND "courierSource"=%s'
|
sql += ' AND "courierSource"=%s'
|
||||||
params.append(courier_source)
|
params.append(courier_source)
|
||||||
|
|||||||
+19
-36
@@ -79,7 +79,7 @@ def _from_epoch_ms(value: Any) -> datetime | None:
|
|||||||
# ---------- 国家/地区归一 ----------
|
# ---------- 国家/地区归一 ----------
|
||||||
|
|
||||||
_US_ALIASES = {"US", "UNITED STATES", "USA", "ESTADOS UNIDOS", "美国加州发货仓"}
|
_US_ALIASES = {"US", "UNITED STATES", "USA", "ESTADOS UNIDOS", "美国加州发货仓"}
|
||||||
_MX_ALIASES = {"MX", "MEXICO", "MÉXICO", "MEX", "ME", "MÉXICO"}
|
_MX_ALIASES = {"MX", "MEXICO", "MÉXICO", "MEX", "ME"}
|
||||||
_CA_ALIASES = {"加拿大工厂", "CA"}
|
_CA_ALIASES = {"加拿大工厂", "CA"}
|
||||||
_PL_ALIASES = {"欧州波兰发货仓", "欧洲波兰法兰克福发货仓"}
|
_PL_ALIASES = {"欧州波兰发货仓", "欧洲波兰法兰克福发货仓"}
|
||||||
_WAREHOUSE_MAP = {
|
_WAREHOUSE_MAP = {
|
||||||
@@ -102,6 +102,7 @@ _ISO2_CN: dict[str, str] = {
|
|||||||
"NO": "挪威", "IS": "冰岛", "TR": "土耳其", "AE": "阿联酋", "IL": "以色列",
|
"NO": "挪威", "IS": "冰岛", "TR": "土耳其", "AE": "阿联酋", "IL": "以色列",
|
||||||
"NZ": "新西兰", "SG": "新加坡", "MY": "马来西亚", "TH": "泰国", "PH": "菲律宾",
|
"NZ": "新西兰", "SG": "新加坡", "MY": "马来西亚", "TH": "泰国", "PH": "菲律宾",
|
||||||
"ID": "印度尼西亚", "VN": "越南", "IN": "印度", "RU": "俄罗斯", "UA": "乌克兰",
|
"ID": "印度尼西亚", "VN": "越南", "IN": "印度", "RU": "俄罗斯", "UA": "乌克兰",
|
||||||
|
"RS": "塞尔维亚",
|
||||||
}
|
}
|
||||||
|
|
||||||
_EN_CN: dict[str, str] = {
|
_EN_CN: dict[str, str] = {
|
||||||
@@ -110,7 +111,12 @@ _EN_CN: dict[str, str] = {
|
|||||||
"SPAIN": "西班牙", "BRAZIL": "巴西", "ITALY": "意大利", "CANADA": "加拿大",
|
"SPAIN": "西班牙", "BRAZIL": "巴西", "ITALY": "意大利", "CANADA": "加拿大",
|
||||||
"FRANCE": "法国", "POLAND": "波兰", "NETHERLANDS": "荷兰", "AUSTRALIA": "澳大利亚",
|
"FRANCE": "法国", "POLAND": "波兰", "NETHERLANDS": "荷兰", "AUSTRALIA": "澳大利亚",
|
||||||
"CROATIA": "克罗地亚", "CZECH REPUBLIC": "捷克", "ESTADOS UNIDOS": "美国",
|
"CROATIA": "克罗地亚", "CZECH REPUBLIC": "捷克", "ESTADOS UNIDOS": "美国",
|
||||||
"SLOVAKIA (SLOVAK REPUBLIC)": "斯洛伐克", "AUSTRALIA": "澳大利亚",
|
"SLOVAKIA (SLOVAK REPUBLIC)": "斯洛伐克", "ROMANIA": "罗马尼亚",
|
||||||
|
"HUNGARY": "匈牙利", "BELGIUM": "比利时", "SWEDEN": "瑞典", "DENMARK": "丹麦",
|
||||||
|
"FINLAND": "芬兰", "IRELAND": "爱尔兰", "PORTUGAL": "葡萄牙", "AUSTRIA": "奥地利",
|
||||||
|
"GREECE": "希腊", "LUXEMBOURG": "卢森堡", "BULGARIA": "保加利亚",
|
||||||
|
"ESTONIA": "爱沙尼亚", "LATVIA": "拉脱维亚", "LITHUANIA": "立陶宛",
|
||||||
|
"SLOVENIA": "斯洛文尼亚",
|
||||||
}
|
}
|
||||||
|
|
||||||
_CN_NORMALIZE: dict[str, str] = {
|
_CN_NORMALIZE: dict[str, str] = {
|
||||||
@@ -118,8 +124,10 @@ _CN_NORMALIZE: dict[str, str] = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def normalize_destination_country(raw: str | None) -> str | None:
|
def normalize_country_region(raw: str | None, factory_name: str | None = None) -> str | None:
|
||||||
"""将 destinationCountry 归一为中文国名。"""
|
"""将国家/地区原始值统一归一为中文国名。"""
|
||||||
|
if factory_name == "广州印美达":
|
||||||
|
return "中国"
|
||||||
if not raw:
|
if not raw:
|
||||||
return None
|
return None
|
||||||
trimmed = raw.strip()
|
trimmed = raw.strip()
|
||||||
@@ -134,42 +142,17 @@ def normalize_destination_country(raw: str | None) -> str | None:
|
|||||||
if trimmed in _CN_NORMALIZE:
|
if trimmed in _CN_NORMALIZE:
|
||||||
return _CN_NORMALIZE[trimmed]
|
return _CN_NORMALIZE[trimmed]
|
||||||
upper = trimmed.upper()
|
upper = trimmed.upper()
|
||||||
if upper in _ISO2_CN:
|
|
||||||
return _ISO2_CN[upper]
|
|
||||||
if upper in _EN_CN:
|
|
||||||
return _EN_CN[upper]
|
|
||||||
return trimmed
|
|
||||||
_EXCLUDED_COUNTRIES = {
|
|
||||||
"Croatia", "Czech Republic", "丹麦", "保加利亚", "克罗地亚", "卢森堡", "奥地利", "希腊",
|
|
||||||
"拉脱维亚", "捷克", "斯洛伐克", "斯洛文尼亚", "比利时", "法国", "爱尔兰", "爱沙尼亚",
|
|
||||||
"瑞典", "瑞士", "立陶宛", "罗马尼亚", "芬兰", "荷兰", "Denmark", "Austria", "Greece",
|
|
||||||
"Latvia", "Slovakia", "Slovenia", "Belgium", "France", "Ireland", "Estonia", "Sweden",
|
|
||||||
"Switzerland", "Lithuania", "Romania", "Finland", "Netherlands", "Luxembourg", "Bulgaria",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def normalize_country_region(raw: str | None, factory_name: str | None = None) -> str | None:
|
|
||||||
if factory_name == "广州印美达":
|
|
||||||
return "中国"
|
|
||||||
if not raw:
|
|
||||||
return None
|
|
||||||
trimmed = raw.strip()
|
|
||||||
if trimmed in _EXCLUDED_COUNTRIES:
|
|
||||||
return None
|
|
||||||
upper = trimmed.upper()
|
|
||||||
if upper in _US_ALIASES:
|
if upper in _US_ALIASES:
|
||||||
return "美国"
|
return "美国"
|
||||||
if upper in _MX_ALIASES:
|
if upper in _MX_ALIASES:
|
||||||
return "墨西哥"
|
return "墨西哥"
|
||||||
if upper in _CA_ALIASES:
|
if upper in _CA_ALIASES:
|
||||||
return "加拿大"
|
return "加拿大"
|
||||||
if trimmed in _PL_ALIASES:
|
if upper in _ISO2_CN:
|
||||||
return "波兰"
|
return _ISO2_CN[upper]
|
||||||
if trimmed in _WAREHOUSE_MAP:
|
if upper in _EN_CN:
|
||||||
return _WAREHOUSE_MAP[trimmed]
|
return _EN_CN[upper]
|
||||||
if raw in _DIRECT_MAP:
|
return trimmed
|
||||||
return _DIRECT_MAP[raw]
|
|
||||||
return raw
|
|
||||||
|
|
||||||
|
|
||||||
# ---------- 统一写入模型 ----------
|
# ---------- 统一写入模型 ----------
|
||||||
@@ -239,7 +222,7 @@ def map_riin_order(raw: Any) -> OrderUpsertInput:
|
|||||||
completedAt=completed_at,
|
completedAt=completed_at,
|
||||||
shipDeadline=ship_deadline,
|
shipDeadline=ship_deadline,
|
||||||
consigneeName=raw.consignee_name,
|
consigneeName=raw.consignee_name,
|
||||||
destinationCountry=normalize_destination_country(raw.receiver_country),
|
destinationCountry=raw.receiver_country,
|
||||||
stateProvince=raw.receiver_province,
|
stateProvince=raw.receiver_province,
|
||||||
city=raw.receiver_city,
|
city=raw.receiver_city,
|
||||||
addressLine1=raw.address,
|
addressLine1=raw.address,
|
||||||
@@ -339,7 +322,7 @@ def map_sds_order(raw: Any, channel_type_map: dict[int, str | None], pre_courier
|
|||||||
completedAt=completed_at,
|
completedAt=completed_at,
|
||||||
shipDeadline=ship_deadline,
|
shipDeadline=ship_deadline,
|
||||||
consigneeName=addr.consignee if addr else None,
|
consigneeName=addr.consignee if addr else None,
|
||||||
destinationCountry=normalize_destination_country(addr.country) if addr else None,
|
destinationCountry=addr.country if addr else None,
|
||||||
stateProvince=addr.province if addr else None,
|
stateProvince=addr.province if addr else None,
|
||||||
city=addr.city if addr else None,
|
city=addr.city if addr else None,
|
||||||
addressLine1=addr.address_detail1 if addr else None,
|
addressLine1=addr.address_detail1 if addr else None,
|
||||||
|
|||||||
Reference in New Issue
Block a user