refactor: countryRegion 统一中文归一化; label-ocr 改用 countryRegion; destinationCountry 还原 ISO2

This commit is contained in:
yeuimu
2026-08-02 16:07:24 +00:00
parent 7ed1893b83
commit c5efa457d1
3 changed files with 33 additions and 50 deletions
+7 -7
View File
@@ -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
View File
@@ -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
View File
@@ -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,