670 lines
23 KiB
Python
670 lines
23 KiB
Python
# -*- coding: utf-8 -*-
|
||
# AI_CHANGELOG [2026-02-13] 移除 DWS_RECALL_INDEX/DWS_INTIMACY_INDEX 任务定义
|
||
"""任务注册表:定义所有可用任务及其业务域分组。
|
||
|
||
从后端 ods_tasks 动态获取任务定义,并按业务域分组,供 UI 使用。
|
||
"""
|
||
|
||
from dataclasses import dataclass, field
|
||
from enum import Enum
|
||
from typing import Dict, List, Optional, Sequence, Tuple
|
||
|
||
# 尝试从后端导入 ODS 任务定义
|
||
try:
|
||
from tasks.ods.ods_tasks import ENABLED_ODS_CODES, ODS_TASK_SPECS
|
||
_HAS_BACKEND = True
|
||
except ImportError:
|
||
_HAS_BACKEND = False
|
||
ENABLED_ODS_CODES = set()
|
||
ODS_TASK_SPECS = ()
|
||
|
||
|
||
class BusinessDomain(Enum):
|
||
"""业务域枚举"""
|
||
MEMBER = "member" # 会员
|
||
SETTLEMENT = "settlement" # 结算/支付
|
||
ASSISTANT = "assistant" # 助教
|
||
GOODS = "goods" # 商品/销售
|
||
TABLE = "table" # 台桌
|
||
PROMOTION = "promotion" # 团购/优惠券
|
||
INVENTORY = "inventory" # 库存
|
||
SCHEMA = "schema" # Schema 初始化
|
||
DWD = "dwd" # DWD 装载
|
||
DWS = "dws" # DWS 汇总
|
||
INDEX = "index" # 指数计算
|
||
QUALITY = "quality" # 质量检查
|
||
OTHER = "other" # 其他
|
||
|
||
|
||
# 业务域显示名称
|
||
DOMAIN_LABELS: Dict[BusinessDomain, str] = {
|
||
BusinessDomain.MEMBER: "会员",
|
||
BusinessDomain.SETTLEMENT: "结算/支付",
|
||
BusinessDomain.ASSISTANT: "助教",
|
||
BusinessDomain.GOODS: "商品/销售",
|
||
BusinessDomain.TABLE: "台桌",
|
||
BusinessDomain.PROMOTION: "团购/优惠券",
|
||
BusinessDomain.INVENTORY: "库存",
|
||
BusinessDomain.SCHEMA: "Schema 初始化",
|
||
BusinessDomain.DWD: "DWD 装载",
|
||
BusinessDomain.DWS: "DWS 汇总",
|
||
BusinessDomain.INDEX: "指数计算",
|
||
BusinessDomain.QUALITY: "质量检查",
|
||
BusinessDomain.OTHER: "其他",
|
||
}
|
||
|
||
|
||
@dataclass
|
||
class TaskDefinition:
|
||
"""任务定义"""
|
||
code: str # 任务编码
|
||
name: str # 显示名称
|
||
description: str # 描述
|
||
domain: BusinessDomain # 业务域
|
||
requires_window: bool = True # 是否需要时间窗口
|
||
is_ods: bool = False # 是否为 ODS 任务
|
||
is_dimension: bool = False # 是否为维度类任务(校验时区分)
|
||
default_enabled: bool = True # 默认是否选中
|
||
|
||
|
||
# ODS 任务到业务域的映射
|
||
ODS_DOMAIN_MAP: Dict[str, BusinessDomain] = {
|
||
# 会员相关
|
||
"ODS_MEMBER": BusinessDomain.MEMBER,
|
||
"ODS_MEMBER_CARD": BusinessDomain.MEMBER,
|
||
"ODS_MEMBER_BALANCE": BusinessDomain.MEMBER,
|
||
# 结算/支付相关
|
||
"ODS_PAYMENT": BusinessDomain.SETTLEMENT,
|
||
"ODS_REFUND": BusinessDomain.SETTLEMENT,
|
||
"ODS_SETTLEMENT_RECORDS": BusinessDomain.SETTLEMENT,
|
||
"ODS_RECHARGE_SETTLE": BusinessDomain.SETTLEMENT,
|
||
"ODS_SETTLEMENT_TICKET": BusinessDomain.SETTLEMENT,
|
||
# 助教相关
|
||
"ODS_ASSISTANT_ACCOUNT": BusinessDomain.ASSISTANT,
|
||
"ODS_ASSISTANT_LEDGER": BusinessDomain.ASSISTANT,
|
||
"ODS_ASSISTANT_ABOLISH": BusinessDomain.ASSISTANT,
|
||
# 商品/销售相关
|
||
"ODS_TENANT_GOODS": BusinessDomain.GOODS,
|
||
"ODS_STORE_GOODS": BusinessDomain.GOODS,
|
||
"ODS_STORE_GOODS_SALES": BusinessDomain.GOODS,
|
||
"ODS_GOODS_CATEGORY": BusinessDomain.GOODS,
|
||
# 台桌相关
|
||
"ODS_TABLES": BusinessDomain.TABLE,
|
||
"ODS_TABLE_USE": BusinessDomain.TABLE,
|
||
"ODS_TABLE_FEE_DISCOUNT": BusinessDomain.TABLE,
|
||
# 团购/优惠券相关
|
||
"ODS_GROUP_PACKAGE": BusinessDomain.PROMOTION,
|
||
"ODS_GROUP_BUY_REDEMPTION": BusinessDomain.PROMOTION,
|
||
"ODS_PLATFORM_COUPON": BusinessDomain.PROMOTION,
|
||
# 库存相关
|
||
"ODS_INVENTORY_STOCK": BusinessDomain.INVENTORY,
|
||
"ODS_INVENTORY_CHANGE": BusinessDomain.INVENTORY,
|
||
}
|
||
|
||
# ODS 任务显示名称(中文)
|
||
ODS_DISPLAY_NAMES: Dict[str, str] = {
|
||
"ODS_MEMBER": "会员档案",
|
||
"ODS_MEMBER_CARD": "会员储值卡",
|
||
"ODS_MEMBER_BALANCE": "会员余额变动",
|
||
"ODS_PAYMENT": "支付流水",
|
||
"ODS_REFUND": "退款流水",
|
||
"ODS_SETTLEMENT_RECORDS": "结账记录",
|
||
"ODS_RECHARGE_SETTLE": "充值结算",
|
||
"ODS_SETTLEMENT_TICKET": "结账小票",
|
||
"ODS_ASSISTANT_ACCOUNT": "助教账号",
|
||
"ODS_ASSISTANT_LEDGER": "助教流水",
|
||
"ODS_ASSISTANT_ABOLISH": "助教作废",
|
||
"ODS_TENANT_GOODS": "租户商品",
|
||
"ODS_STORE_GOODS": "门店商品",
|
||
"ODS_STORE_GOODS_SALES": "商品销售流水",
|
||
"ODS_GOODS_CATEGORY": "商品分类",
|
||
"ODS_TABLES": "台桌维表",
|
||
"ODS_TABLE_USE": "台费计费流水",
|
||
"ODS_TABLE_FEE_DISCOUNT": "台费折扣调账",
|
||
"ODS_GROUP_PACKAGE": "团购套餐",
|
||
"ODS_GROUP_BUY_REDEMPTION": "团购核销",
|
||
"ODS_PLATFORM_COUPON": "平台券核销",
|
||
"ODS_INVENTORY_STOCK": "库存汇总",
|
||
"ODS_INVENTORY_CHANGE": "库存变化",
|
||
}
|
||
|
||
# 维度类 ODS 任务(校验时通常单独处理)
|
||
DIMENSION_ODS_CODES = {
|
||
"ODS_MEMBER",
|
||
"ODS_MEMBER_CARD",
|
||
"ODS_ASSISTANT_ACCOUNT",
|
||
"ODS_TENANT_GOODS",
|
||
"ODS_STORE_GOODS",
|
||
"ODS_GOODS_CATEGORY",
|
||
"ODS_TABLES",
|
||
"ODS_GROUP_PACKAGE",
|
||
}
|
||
|
||
# 事实类 ODS 任务(需要时间窗口)
|
||
FACT_ODS_CODES = {
|
||
"ODS_MEMBER_BALANCE",
|
||
"ODS_PAYMENT",
|
||
"ODS_REFUND",
|
||
"ODS_SETTLEMENT_RECORDS",
|
||
"ODS_RECHARGE_SETTLE",
|
||
"ODS_SETTLEMENT_TICKET",
|
||
"ODS_ASSISTANT_LEDGER",
|
||
"ODS_ASSISTANT_ABOLISH",
|
||
"ODS_STORE_GOODS_SALES",
|
||
"ODS_TABLE_USE",
|
||
"ODS_TABLE_FEE_DISCOUNT",
|
||
"ODS_GROUP_BUY_REDEMPTION",
|
||
"ODS_PLATFORM_COUPON",
|
||
"ODS_INVENTORY_CHANGE",
|
||
}
|
||
|
||
# ======================== DWD 表定义 ========================
|
||
|
||
@dataclass
|
||
class DwdTableDefinition:
|
||
"""DWD 表定义(用于 GUI 表级选择)"""
|
||
code: str # 表编码(不含 schema,如 dim_member)
|
||
name: str # 中文显示名称
|
||
description: str # 描述
|
||
domain: BusinessDomain # 业务域
|
||
is_dimension: bool = False # 是否维度表
|
||
tables: List[str] = field(default_factory=list) # 完整表名列表(含 _ex)
|
||
|
||
|
||
# DWD 表定义列表(按业务域分组)
|
||
DWD_TABLE_DEFINITIONS: List[DwdTableDefinition] = [
|
||
# ---- 会员 ----
|
||
DwdTableDefinition(
|
||
"dim_member", "会员维度", "会员基本信息维度表",
|
||
BusinessDomain.MEMBER, True,
|
||
["billiards_dwd.dim_member", "billiards_dwd.dim_member_ex"],
|
||
),
|
||
DwdTableDefinition(
|
||
"dim_member_card_account", "会员储值卡", "会员储值卡账户维度表",
|
||
BusinessDomain.MEMBER, True,
|
||
["billiards_dwd.dim_member_card_account", "billiards_dwd.dim_member_card_account_ex"],
|
||
),
|
||
DwdTableDefinition(
|
||
"dwd_member_balance_change", "余额变动", "会员余额变动事实表",
|
||
BusinessDomain.MEMBER, False,
|
||
["billiards_dwd.dwd_member_balance_change", "billiards_dwd.dwd_member_balance_change_ex"],
|
||
),
|
||
# ---- 结算/支付 ----
|
||
DwdTableDefinition(
|
||
"dwd_settlement_head", "结账记录", "结账/结算事实表",
|
||
BusinessDomain.SETTLEMENT, False,
|
||
["billiards_dwd.dwd_settlement_head", "billiards_dwd.dwd_settlement_head_ex"],
|
||
),
|
||
DwdTableDefinition(
|
||
"dwd_payment", "支付流水", "支付明细事实表",
|
||
BusinessDomain.SETTLEMENT, False,
|
||
["billiards_dwd.dwd_payment"],
|
||
),
|
||
DwdTableDefinition(
|
||
"dwd_refund", "退款流水", "退款明细事实表",
|
||
BusinessDomain.SETTLEMENT, False,
|
||
["billiards_dwd.dwd_refund", "billiards_dwd.dwd_refund_ex"],
|
||
),
|
||
DwdTableDefinition(
|
||
"dwd_recharge_order", "充值订单", "充值结算事实表",
|
||
BusinessDomain.SETTLEMENT, False,
|
||
["billiards_dwd.dwd_recharge_order", "billiards_dwd.dwd_recharge_order_ex"],
|
||
),
|
||
# ---- 助教 ----
|
||
DwdTableDefinition(
|
||
"dim_assistant", "助教维度", "助教基本信息维度表",
|
||
BusinessDomain.ASSISTANT, True,
|
||
["billiards_dwd.dim_assistant", "billiards_dwd.dim_assistant_ex"],
|
||
),
|
||
DwdTableDefinition(
|
||
"dwd_assistant_service_log", "助教服务流水", "助教服务计费事实表",
|
||
BusinessDomain.ASSISTANT, False,
|
||
["billiards_dwd.dwd_assistant_service_log", "billiards_dwd.dwd_assistant_service_log_ex"],
|
||
),
|
||
DwdTableDefinition(
|
||
"dwd_assistant_trash_event", "助教作废", "助教作废事件事实表",
|
||
BusinessDomain.ASSISTANT, False,
|
||
["billiards_dwd.dwd_assistant_trash_event", "billiards_dwd.dwd_assistant_trash_event_ex"],
|
||
),
|
||
# ---- 商品/销售 ----
|
||
DwdTableDefinition(
|
||
"dim_tenant_goods", "租户商品", "租户商品维度表",
|
||
BusinessDomain.GOODS, True,
|
||
["billiards_dwd.dim_tenant_goods", "billiards_dwd.dim_tenant_goods_ex"],
|
||
),
|
||
DwdTableDefinition(
|
||
"dim_store_goods", "门店商品", "门店商品维度表",
|
||
BusinessDomain.GOODS, True,
|
||
["billiards_dwd.dim_store_goods", "billiards_dwd.dim_store_goods_ex"],
|
||
),
|
||
DwdTableDefinition(
|
||
"dim_goods_category", "商品分类", "商品分类维度表",
|
||
BusinessDomain.GOODS, True,
|
||
["billiards_dwd.dim_goods_category"],
|
||
),
|
||
DwdTableDefinition(
|
||
"dwd_store_goods_sale", "商品销售", "商品销售事实表",
|
||
BusinessDomain.GOODS, False,
|
||
["billiards_dwd.dwd_store_goods_sale", "billiards_dwd.dwd_store_goods_sale_ex"],
|
||
),
|
||
# ---- 台桌 ----
|
||
DwdTableDefinition(
|
||
"dim_site", "门店维度", "门店基本信息维度表",
|
||
BusinessDomain.TABLE, True,
|
||
["billiards_dwd.dim_site", "billiards_dwd.dim_site_ex"],
|
||
),
|
||
DwdTableDefinition(
|
||
"dim_table", "台桌维度", "台桌基本信息维度表",
|
||
BusinessDomain.TABLE, True,
|
||
["billiards_dwd.dim_table", "billiards_dwd.dim_table_ex"],
|
||
),
|
||
DwdTableDefinition(
|
||
"dwd_table_fee_log", "台费流水", "台费计费事实表",
|
||
BusinessDomain.TABLE, False,
|
||
["billiards_dwd.dwd_table_fee_log", "billiards_dwd.dwd_table_fee_log_ex"],
|
||
),
|
||
DwdTableDefinition(
|
||
"dwd_table_fee_adjust", "台费折扣调账", "台费折扣调账事实表",
|
||
BusinessDomain.TABLE, False,
|
||
["billiards_dwd.dwd_table_fee_adjust", "billiards_dwd.dwd_table_fee_adjust_ex"],
|
||
),
|
||
# ---- 团购/优惠券 ----
|
||
DwdTableDefinition(
|
||
"dim_groupbuy_package", "团购套餐", "团购套餐维度表",
|
||
BusinessDomain.PROMOTION, True,
|
||
["billiards_dwd.dim_groupbuy_package", "billiards_dwd.dim_groupbuy_package_ex"],
|
||
),
|
||
DwdTableDefinition(
|
||
"dwd_groupbuy_redemption", "团购核销", "团购核销事实表",
|
||
BusinessDomain.PROMOTION, False,
|
||
["billiards_dwd.dwd_groupbuy_redemption", "billiards_dwd.dwd_groupbuy_redemption_ex"],
|
||
),
|
||
DwdTableDefinition(
|
||
"dwd_platform_coupon_redemption", "平台券核销", "平台券核销事实表",
|
||
BusinessDomain.PROMOTION, False,
|
||
["billiards_dwd.dwd_platform_coupon_redemption", "billiards_dwd.dwd_platform_coupon_redemption_ex"],
|
||
),
|
||
]
|
||
|
||
# DWD 表按业务域显示顺序
|
||
DWD_TABLE_DOMAIN_ORDER: List[BusinessDomain] = [
|
||
BusinessDomain.MEMBER,
|
||
BusinessDomain.SETTLEMENT,
|
||
BusinessDomain.ASSISTANT,
|
||
BusinessDomain.GOODS,
|
||
BusinessDomain.TABLE,
|
||
BusinessDomain.PROMOTION,
|
||
]
|
||
|
||
|
||
def get_dwd_tables_grouped() -> Dict[BusinessDomain, List[DwdTableDefinition]]:
|
||
"""获取按业务域分组的 DWD 表定义"""
|
||
grouped: Dict[BusinessDomain, List[DwdTableDefinition]] = {}
|
||
for tbl in DWD_TABLE_DEFINITIONS:
|
||
grouped.setdefault(tbl.domain, []).append(tbl)
|
||
return grouped
|
||
|
||
|
||
def get_all_dwd_table_codes() -> List[str]:
|
||
"""获取所有 DWD 表编码"""
|
||
return [t.code for t in DWD_TABLE_DEFINITIONS]
|
||
|
||
|
||
def resolve_dwd_table_names(codes: Sequence[str]) -> List[str]:
|
||
"""将 DWD 表编码解析为完整表名列表(含 _ex)"""
|
||
code_set = {c.lower() for c in codes}
|
||
result: List[str] = []
|
||
for tbl in DWD_TABLE_DEFINITIONS:
|
||
if tbl.code.lower() in code_set:
|
||
result.extend(tbl.tables)
|
||
return result
|
||
|
||
|
||
# 非 ODS 任务定义
|
||
NON_ODS_TASKS: List[TaskDefinition] = [
|
||
# DWD 装载(保留为单一调度任务,表级选择通过 DWD_ONLY_TABLES 环境变量控制)
|
||
TaskDefinition(
|
||
code="DWD_LOAD_FROM_ODS",
|
||
name="ODS→DWD 装载",
|
||
description="从 ODS 增量装载到 DWD",
|
||
domain=BusinessDomain.DWD,
|
||
requires_window=True,
|
||
),
|
||
TaskDefinition(
|
||
code="DWD_QUALITY_CHECK",
|
||
name="DWD 质量检查",
|
||
description="执行 DWD 数据质量检查",
|
||
domain=BusinessDomain.QUALITY,
|
||
requires_window=False,
|
||
),
|
||
TaskDefinition(
|
||
code="DWS_BUILD_ORDER_SUMMARY",
|
||
name="构建订单汇总",
|
||
description="重算 DWS 订单汇总表",
|
||
domain=BusinessDomain.DWS,
|
||
requires_window=False,
|
||
),
|
||
# DWS 汇总任务
|
||
TaskDefinition(
|
||
code="DWS_ASSISTANT_DAILY",
|
||
name="助教日度明细",
|
||
description="汇总助教日度服务、时长与收入指标",
|
||
domain=BusinessDomain.DWS,
|
||
requires_window=True,
|
||
),
|
||
TaskDefinition(
|
||
code="DWS_ASSISTANT_MONTHLY",
|
||
name="助教月度汇总",
|
||
description="汇总助教月度绩效与服务指标",
|
||
domain=BusinessDomain.DWS,
|
||
requires_window=True,
|
||
),
|
||
TaskDefinition(
|
||
code="DWS_ASSISTANT_CUSTOMER",
|
||
name="助教客户统计",
|
||
description="统计助教与客户的服务关系与滚动窗口指标",
|
||
domain=BusinessDomain.DWS,
|
||
requires_window=True,
|
||
),
|
||
TaskDefinition(
|
||
code="DWS_ASSISTANT_SALARY",
|
||
name="助教工资计算",
|
||
description="计算助教月度工资与奖金明细",
|
||
domain=BusinessDomain.DWS,
|
||
requires_window=True,
|
||
default_enabled=False,
|
||
),
|
||
TaskDefinition(
|
||
code="DWS_ASSISTANT_FINANCE",
|
||
name="助教财务分析",
|
||
description="汇总助教日度财务分析指标",
|
||
domain=BusinessDomain.DWS,
|
||
requires_window=True,
|
||
),
|
||
TaskDefinition(
|
||
code="DWS_MEMBER_CONSUMPTION",
|
||
name="会员消费汇总",
|
||
description="汇总会员消费行为与滚动窗口指标",
|
||
domain=BusinessDomain.DWS,
|
||
requires_window=True,
|
||
),
|
||
TaskDefinition(
|
||
code="DWS_MEMBER_VISIT",
|
||
name="会员来店明细",
|
||
description="记录会员来店消费明细与服务列表",
|
||
domain=BusinessDomain.DWS,
|
||
requires_window=True,
|
||
),
|
||
TaskDefinition(
|
||
code="DWS_FINANCE_DAILY",
|
||
name="财务日度汇总",
|
||
description="汇总当日财务发生额、优惠与现金流",
|
||
domain=BusinessDomain.DWS,
|
||
requires_window=True,
|
||
),
|
||
TaskDefinition(
|
||
code="DWS_FINANCE_RECHARGE",
|
||
name="财务充值统计",
|
||
description="统计充值笔数、金额与卡余额",
|
||
domain=BusinessDomain.DWS,
|
||
requires_window=True,
|
||
),
|
||
TaskDefinition(
|
||
code="DWS_FINANCE_INCOME_STRUCTURE",
|
||
name="财务收入结构",
|
||
description="统计收入结构分布",
|
||
domain=BusinessDomain.DWS,
|
||
requires_window=True,
|
||
),
|
||
TaskDefinition(
|
||
code="DWS_FINANCE_DISCOUNT_DETAIL",
|
||
name="优惠明细分析",
|
||
description="拆分优惠构成与占比",
|
||
domain=BusinessDomain.DWS,
|
||
requires_window=True,
|
||
),
|
||
TaskDefinition(
|
||
code="DWS_MV_REFRESH_FINANCE_DAILY",
|
||
name="物化刷新-财务日汇总",
|
||
description="刷新财务日汇总物化视图(L1-L4)",
|
||
domain=BusinessDomain.DWS,
|
||
requires_window=False,
|
||
default_enabled=False,
|
||
),
|
||
TaskDefinition(
|
||
code="DWS_MV_REFRESH_ASSISTANT_DAILY",
|
||
name="物化刷新-助教日明细",
|
||
description="刷新助教日明细物化视图(L1-L4)",
|
||
domain=BusinessDomain.DWS,
|
||
requires_window=False,
|
||
default_enabled=False,
|
||
),
|
||
TaskDefinition(
|
||
code="DWS_RETENTION_CLEANUP",
|
||
name="时间分层清理",
|
||
description="按配置清理历史 DWS 数据",
|
||
domain=BusinessDomain.DWS,
|
||
requires_window=True,
|
||
default_enabled=False,
|
||
),
|
||
# DWS 指数计算
|
||
TaskDefinition(
|
||
code="DWS_WINBACK_INDEX",
|
||
name="老客挽回指数(WBI)",
|
||
description="计算老客挽回优先级,基于个人周期超期、降频、价值与充值压力",
|
||
domain=BusinessDomain.INDEX,
|
||
requires_window=False,
|
||
),
|
||
TaskDefinition(
|
||
code="DWS_NEWCONV_INDEX",
|
||
name="新客转化指数(NCI)",
|
||
description="计算新客二访/三访转化紧迫度与价值",
|
||
domain=BusinessDomain.INDEX,
|
||
requires_window=False,
|
||
),
|
||
TaskDefinition(
|
||
code="DWS_RELATION_INDEX",
|
||
name="关系指数(RS/OS/MS/ML)",
|
||
description="单任务计算关系强度、归属份额、升温动量、付费关联",
|
||
domain=BusinessDomain.INDEX,
|
||
requires_window=False,
|
||
),
|
||
TaskDefinition(
|
||
code="DWS_ML_MANUAL_IMPORT",
|
||
name="ML人工台账导入",
|
||
description="导入人工台账并按日/30天批次覆盖写入 ML 归因明细",
|
||
domain=BusinessDomain.INDEX,
|
||
requires_window=False,
|
||
default_enabled=False,
|
||
),
|
||
# Schema 初始化
|
||
TaskDefinition(
|
||
code="INIT_ODS_SCHEMA",
|
||
name="初始化 ODS Schema",
|
||
description="创建/重建 ODS 表结构",
|
||
domain=BusinessDomain.SCHEMA,
|
||
requires_window=False,
|
||
default_enabled=False,
|
||
),
|
||
TaskDefinition(
|
||
code="INIT_DWD_SCHEMA",
|
||
name="初始化 DWD Schema",
|
||
description="创建/重建 DWD 表结构",
|
||
domain=BusinessDomain.SCHEMA,
|
||
requires_window=False,
|
||
default_enabled=False,
|
||
),
|
||
TaskDefinition(
|
||
code="INIT_DWS_SCHEMA",
|
||
name="初始化 DWS Schema",
|
||
description="创建/重建 DWS 表结构",
|
||
domain=BusinessDomain.SCHEMA,
|
||
requires_window=False,
|
||
default_enabled=False,
|
||
),
|
||
TaskDefinition(
|
||
code="SEED_DWS_CONFIG",
|
||
name="初始化 DWS 配置",
|
||
description="写入 DWS 配置表基础数据",
|
||
domain=BusinessDomain.SCHEMA,
|
||
requires_window=False,
|
||
default_enabled=False,
|
||
),
|
||
# 其他
|
||
TaskDefinition(
|
||
code="MANUAL_INGEST",
|
||
name="手工数据灌入",
|
||
description="从本地 JSON 回放入库",
|
||
domain=BusinessDomain.OTHER,
|
||
requires_window=False,
|
||
default_enabled=False,
|
||
),
|
||
TaskDefinition(
|
||
code="ODS_JSON_ARCHIVE",
|
||
name="ODS JSON 归档",
|
||
description="在线抓取 ODS 接口数据并落盘 JSON",
|
||
domain=BusinessDomain.OTHER,
|
||
requires_window=True,
|
||
default_enabled=False,
|
||
),
|
||
TaskDefinition(
|
||
code="CHECK_CUTOFF",
|
||
name="检查 Cutoff",
|
||
description="查看各表数据截止时间",
|
||
domain=BusinessDomain.QUALITY,
|
||
requires_window=False,
|
||
),
|
||
TaskDefinition(
|
||
code="DATA_INTEGRITY_CHECK",
|
||
name="数据完整性检查",
|
||
description="检查 ODS/DWD 数据完整性",
|
||
domain=BusinessDomain.QUALITY,
|
||
requires_window=True,
|
||
),
|
||
]
|
||
|
||
|
||
def _build_ods_task_definition(code: str) -> TaskDefinition:
|
||
"""根据 ODS 任务编码构建任务定义"""
|
||
domain = ODS_DOMAIN_MAP.get(code, BusinessDomain.OTHER)
|
||
name = ODS_DISPLAY_NAMES.get(code, code)
|
||
is_dimension = code in DIMENSION_ODS_CODES
|
||
|
||
# 从后端获取描述(如果可用)
|
||
description = f"抓取{name}到 ODS"
|
||
if _HAS_BACKEND:
|
||
for spec in ODS_TASK_SPECS:
|
||
if spec.code == code:
|
||
# 尝试解码描述(可能是乱码)
|
||
desc = spec.description
|
||
if desc and not any(ord(c) > 0x4e00 for c in desc[:10] if desc):
|
||
description = f"抓取{name}到 ODS"
|
||
break
|
||
|
||
return TaskDefinition(
|
||
code=code,
|
||
name=name,
|
||
description=description,
|
||
domain=domain,
|
||
requires_window=code not in DIMENSION_ODS_CODES,
|
||
is_ods=True,
|
||
is_dimension=is_dimension,
|
||
)
|
||
|
||
|
||
class TaskRegistry:
|
||
"""任务注册表:管理所有可用任务"""
|
||
|
||
_instance: Optional["TaskRegistry"] = None
|
||
|
||
def __new__(cls):
|
||
if cls._instance is None:
|
||
cls._instance = super().__new__(cls)
|
||
cls._instance._initialized = False
|
||
return cls._instance
|
||
|
||
def __init__(self):
|
||
if self._initialized:
|
||
return
|
||
self._initialized = True
|
||
self._tasks: Dict[str, TaskDefinition] = {}
|
||
self._load_tasks()
|
||
|
||
def _load_tasks(self):
|
||
"""加载所有任务定义"""
|
||
# 加载 ODS 任务
|
||
ods_codes = ENABLED_ODS_CODES if _HAS_BACKEND else set(ODS_DOMAIN_MAP.keys())
|
||
for code in ods_codes:
|
||
self._tasks[code] = _build_ods_task_definition(code)
|
||
|
||
# 加载非 ODS 任务
|
||
for task_def in NON_ODS_TASKS:
|
||
self._tasks[task_def.code] = task_def
|
||
|
||
def get_task(self, code: str) -> Optional[TaskDefinition]:
|
||
"""获取任务定义"""
|
||
return self._tasks.get(code)
|
||
|
||
def get_all_tasks(self) -> List[TaskDefinition]:
|
||
"""获取所有任务"""
|
||
return list(self._tasks.values())
|
||
|
||
def get_ods_tasks(self) -> List[TaskDefinition]:
|
||
"""获取所有 ODS 任务"""
|
||
return [t for t in self._tasks.values() if t.is_ods]
|
||
|
||
def get_fact_ods_tasks(self) -> List[TaskDefinition]:
|
||
"""获取事实类 ODS 任务(需要时间窗口)"""
|
||
return [t for t in self._tasks.values() if t.is_ods and not t.is_dimension]
|
||
|
||
def get_dimension_ods_tasks(self) -> List[TaskDefinition]:
|
||
"""获取维度类 ODS 任务"""
|
||
return [t for t in self._tasks.values() if t.is_ods and t.is_dimension]
|
||
|
||
def get_tasks_by_domain(self, domain: BusinessDomain) -> List[TaskDefinition]:
|
||
"""按业务域获取任务"""
|
||
return [t for t in self._tasks.values() if t.domain == domain]
|
||
|
||
def get_ods_tasks_grouped(self) -> Dict[BusinessDomain, List[TaskDefinition]]:
|
||
"""获取按业务域分组的 ODS 任务"""
|
||
grouped: Dict[BusinessDomain, List[TaskDefinition]] = {}
|
||
for task in self.get_ods_tasks():
|
||
if task.domain not in grouped:
|
||
grouped[task.domain] = []
|
||
grouped[task.domain].append(task)
|
||
return grouped
|
||
|
||
def get_non_ods_tasks(self) -> List[TaskDefinition]:
|
||
"""获取非 ODS 任务"""
|
||
return [t for t in self._tasks.values() if not t.is_ods]
|
||
|
||
|
||
# 全局注册表实例
|
||
task_registry = TaskRegistry()
|
||
|
||
|
||
# 便捷函数
|
||
def get_ods_task_codes() -> List[str]:
|
||
"""获取所有 ODS 任务编码"""
|
||
return [t.code for t in task_registry.get_ods_tasks()]
|
||
|
||
|
||
def get_fact_ods_task_codes() -> List[str]:
|
||
"""获取事实类 ODS 任务编码"""
|
||
return [t.code for t in task_registry.get_fact_ods_tasks()]
|
||
|
||
|
||
def get_dimension_ods_task_codes() -> List[str]:
|
||
"""获取维度类 ODS 任务编码"""
|
||
return [t.code for t in task_registry.get_dimension_ods_tasks()]
|
||
|
||
|
||
def get_all_task_tuples() -> List[Tuple[str, str, str]]:
|
||
"""获取所有任务的 (code, name, description) 元组列表"""
|
||
return [(t.code, t.name, t.description) for t in task_registry.get_all_tasks()]
|
||
|
||
|
||
def get_ods_tasks_for_ui() -> List[Tuple[str, str, BusinessDomain]]:
|
||
"""获取 ODS 任务列表供 UI 使用:(code, display_name, domain)"""
|
||
return [(t.code, t.name, t.domain) for t in task_registry.get_ods_tasks()]
|