feat: 添加线索引擎、NLQ、场景检测、前端界面等核心功能模块
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
"""R11 适配器:渠道佣金与代理商套利。
|
||||
|
||||
源明细:SrcTerminalBinding
|
||||
映射到:Entity(IMEI, MSISDN) + 关系(BOUND_DEVICE) + MetricEvent
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import uuid
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.datahub.graph_repo import add_relationship, upsert_entity
|
||||
from app.datahub.models import MetricEvent
|
||||
from app.datahub.ontology import EntityType, RelationshipType
|
||||
from app.datahub.staging import SrcTerminalBinding
|
||||
from app.ingest.base import BaseAdapter, IngestResult
|
||||
from app.ingest.registry import register_adapter
|
||||
|
||||
|
||||
@register_adapter
|
||||
class TerminalBindingAdapter(BaseAdapter):
|
||||
"""SrcTerminalBinding → Entity(IMEI, MSISDN) + BOUND_DEVICE + MetricEvent。"""
|
||||
|
||||
source_system = "BSS"
|
||||
staging_table = "src_terminal_binding"
|
||||
|
||||
def ingest(
|
||||
self,
|
||||
session: Session,
|
||||
data_version_id: uuid.UUID | None = None,
|
||||
batch_size: int = 1000,
|
||||
) -> IngestResult:
|
||||
result = IngestResult()
|
||||
query = session.query(SrcTerminalBinding)
|
||||
if data_version_id:
|
||||
query = query.filter(SrcTerminalBinding.data_version_id == data_version_id)
|
||||
rows = query.limit(batch_size).all()
|
||||
|
||||
for row in rows:
|
||||
try:
|
||||
# IMEI 实体
|
||||
imei_entity = upsert_entity(
|
||||
session,
|
||||
entity_type=EntityType.IMEI,
|
||||
business_key=row.imei,
|
||||
display_name=row.brand_model or row.imei,
|
||||
attributes={
|
||||
"brand_model": row.brand_model,
|
||||
"region": row.region,
|
||||
},
|
||||
data_version_id=data_version_id,
|
||||
)
|
||||
result.entities.append(imei_entity)
|
||||
|
||||
# MSISDN 实体
|
||||
msisdn_entity = upsert_entity(
|
||||
session,
|
||||
entity_type=EntityType.MSISDN,
|
||||
business_key=row.msisdn,
|
||||
display_name=row.msisdn,
|
||||
attributes={"region": row.region},
|
||||
data_version_id=data_version_id,
|
||||
)
|
||||
result.entities.append(msisdn_entity)
|
||||
|
||||
# 绑定关系
|
||||
rel = add_relationship(
|
||||
session, RelationshipType.BOUND_DEVICE, msisdn_entity, imei_entity,
|
||||
attributes={
|
||||
"activate_time": str(row.activate_time) if row.activate_time else None,
|
||||
"subsidy_amount": row.subsidy_amount,
|
||||
},
|
||||
data_version_id=data_version_id,
|
||||
)
|
||||
result.relationships.append(rel)
|
||||
|
||||
# 终端激活/补贴事件
|
||||
if row.activate_time:
|
||||
event = MetricEvent(
|
||||
event_time=row.activate_time,
|
||||
subject_type="imei",
|
||||
subject_key=row.imei,
|
||||
metric_name="terminal_activate",
|
||||
metric_value=row.subsidy_amount + row.commission_amount,
|
||||
attributes={
|
||||
"msisdn": row.msisdn,
|
||||
"subsidy_amount": row.subsidy_amount,
|
||||
"commission_amount": row.commission_amount,
|
||||
"online_days": row.online_days,
|
||||
"post_activate_traffic_mb": row.post_activate_traffic_mb,
|
||||
"cross_province_flag": row.cross_province_flag,
|
||||
},
|
||||
data_version_id=data_version_id,
|
||||
)
|
||||
session.add(event)
|
||||
result.metric_events.append(event)
|
||||
|
||||
result.row_count += 1
|
||||
except Exception:
|
||||
result.error_count += 1
|
||||
|
||||
return result
|
||||
Reference in New Issue
Block a user