init: 项目初始提交 - NeoZQYY Monorepo 完整代码
This commit is contained in:
604
gui/widgets/pipeline_selector.py
Normal file
604
gui/widgets/pipeline_selector.py
Normal file
@@ -0,0 +1,604 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""管道选择组件:统一的 ETL 管道配置界面。"""
|
||||
|
||||
from typing import Dict, List, Optional, Tuple
|
||||
|
||||
from PySide6.QtWidgets import (
|
||||
QWidget, QVBoxLayout, QHBoxLayout, QGroupBox,
|
||||
QRadioButton, QButtonGroup, QLabel, QSpinBox,
|
||||
QDateTimeEdit, QComboBox, QCheckBox, QPushButton,
|
||||
QScrollArea, QFrame
|
||||
)
|
||||
from PySide6.QtCore import Signal, Qt, QDateTime
|
||||
|
||||
from ..models.task_registry import (
|
||||
TaskRegistry, TaskDefinition, BusinessDomain, DOMAIN_LABELS,
|
||||
task_registry, get_fact_ods_task_codes, get_dimension_ods_task_codes
|
||||
)
|
||||
|
||||
|
||||
# 管道选项定义:(id, 显示名称, 包含的层)
|
||||
PIPELINE_OPTIONS: List[Tuple[str, str, List[str]]] = [
|
||||
("api_ods", "API → ODS", ["ODS"]),
|
||||
("api_ods_dwd", "API → ODS → DWD", ["ODS", "DWD"]),
|
||||
("api_full", "API → ODS → DWD → DWS汇总 → DWS指数", ["ODS", "DWD", "DWS", "INDEX"]),
|
||||
("ods_dwd", "ODS → DWD", ["DWD"]),
|
||||
("dwd_dws", "DWD → DWS汇总", ["DWS"]),
|
||||
("dwd_dws_index", "DWD → DWS汇总 → DWS指数", ["DWS", "INDEX"]),
|
||||
("dwd_index", "DWD → DWS指数", ["INDEX"]),
|
||||
]
|
||||
|
||||
# 数据处理模式
|
||||
PROCESSING_MODES: List[Tuple[str, str, str]] = [
|
||||
("increment_only", "仅增量", "仅执行增量数据处理,不进行校验"),
|
||||
("verify_only", "校验并修复", "跳过增量处理,直接校验数据一致性并自动补齐缺失/不一致数据"),
|
||||
("increment_verify", "增量 + 校验并修复", "先执行增量处理,再校验并修复缺失/不一致数据"),
|
||||
]
|
||||
|
||||
# 校验模式附加选项
|
||||
VERIFY_MODE_OPTIONS = {
|
||||
"fetch_before_verify": "校验前先从 API 获取数据",
|
||||
"skip_ods_when_fetch_before_verify": "跳过 ODS 校验(仅在校验前获取时)",
|
||||
"ods_use_local_json": "ODS 校验使用本地 JSON(不请求 API)",
|
||||
}
|
||||
|
||||
# 时间窗口模式
|
||||
WINDOW_MODES: List[Tuple[str, str]] = [
|
||||
("lookback", "回溯 + 冗余"),
|
||||
("custom", "自定义时间范围"),
|
||||
]
|
||||
|
||||
# 时间窗口切分选项
|
||||
WINDOW_SPLIT_OPTIONS: List[Tuple[str, str]] = [
|
||||
("none", "不切分"),
|
||||
("day", "按天"),
|
||||
]
|
||||
|
||||
# 时间窗口切分天数(按天时生效)
|
||||
WINDOW_SPLIT_DAY_OPTIONS: List[Tuple[int, str]] = [
|
||||
(1, "1 天"),
|
||||
(10, "10 天"),
|
||||
(30, "30 天"),
|
||||
]
|
||||
|
||||
|
||||
def get_pipeline_layers(pipeline_id: str) -> List[str]:
|
||||
"""获取管道包含的层"""
|
||||
for pid, _, layers in PIPELINE_OPTIONS:
|
||||
if pid == pipeline_id:
|
||||
return layers
|
||||
return []
|
||||
|
||||
|
||||
def get_pipeline_display_name(pipeline_id: str) -> str:
|
||||
"""获取管道显示名称"""
|
||||
for pid, name, _ in PIPELINE_OPTIONS:
|
||||
if pid == pipeline_id:
|
||||
return name
|
||||
return pipeline_id
|
||||
|
||||
|
||||
class PipelineSelectorWidget(QWidget):
|
||||
"""管道选择组件"""
|
||||
|
||||
# 信号
|
||||
pipeline_changed = Signal(str) # 管道ID
|
||||
processing_mode_changed = Signal(str) # 处理模式
|
||||
window_mode_changed = Signal(str) # 时间窗口模式
|
||||
config_changed = Signal() # 任意配置变化
|
||||
|
||||
def __init__(self, parent: Optional[QWidget] = None):
|
||||
super().__init__(parent)
|
||||
|
||||
# 当前选择
|
||||
self._pipeline_id = "api_ods_dwd"
|
||||
self._processing_mode = "increment_only"
|
||||
self._window_mode = "lookback"
|
||||
self._fetch_before_verify = False
|
||||
self._skip_ods_when_fetch_before_verify = True
|
||||
self._ods_use_local_json = True
|
||||
|
||||
self._init_ui()
|
||||
self._connect_signals()
|
||||
|
||||
def _init_ui(self):
|
||||
"""初始化界面"""
|
||||
layout = QVBoxLayout(self)
|
||||
layout.setContentsMargins(0, 0, 0, 0)
|
||||
layout.setSpacing(12)
|
||||
|
||||
# 1. 管道选择
|
||||
pipeline_group = self._create_pipeline_group()
|
||||
layout.addWidget(pipeline_group)
|
||||
|
||||
# 2. 数据处理模式
|
||||
processing_group = self._create_processing_mode_group()
|
||||
layout.addWidget(processing_group)
|
||||
|
||||
# 3. 时间窗口配置
|
||||
window_group = self._create_window_group()
|
||||
layout.addWidget(window_group)
|
||||
|
||||
layout.addStretch()
|
||||
|
||||
def _create_pipeline_group(self) -> QGroupBox:
|
||||
"""创建管道选择分组"""
|
||||
group = QGroupBox("管道选择 (Pipeline)")
|
||||
layout = QVBoxLayout(group)
|
||||
layout.setSpacing(4)
|
||||
|
||||
self._pipeline_button_group = QButtonGroup(self)
|
||||
|
||||
for i, (pid, name, layers) in enumerate(PIPELINE_OPTIONS):
|
||||
radio = QRadioButton(name)
|
||||
radio.setProperty("pipeline_id", pid)
|
||||
radio.setToolTip(f"包含层: {' → '.join(layers)}")
|
||||
|
||||
if pid == self._pipeline_id:
|
||||
radio.setChecked(True)
|
||||
|
||||
self._pipeline_button_group.addButton(radio, i)
|
||||
layout.addWidget(radio)
|
||||
|
||||
return group
|
||||
|
||||
def _create_processing_mode_group(self) -> QGroupBox:
|
||||
"""创建数据处理模式分组"""
|
||||
group = QGroupBox("数据处理模式")
|
||||
layout = QVBoxLayout(group)
|
||||
layout.setSpacing(4)
|
||||
|
||||
self._processing_button_group = QButtonGroup(self)
|
||||
|
||||
for i, (mode_id, name, tooltip) in enumerate(PROCESSING_MODES):
|
||||
radio = QRadioButton(name)
|
||||
radio.setProperty("mode_id", mode_id)
|
||||
radio.setToolTip(tooltip)
|
||||
|
||||
if mode_id == self._processing_mode:
|
||||
radio.setChecked(True)
|
||||
|
||||
self._processing_button_group.addButton(radio, i)
|
||||
layout.addWidget(radio)
|
||||
|
||||
# 校验模式附加选项:校验前从 API 获取数据
|
||||
option_layout = QHBoxLayout()
|
||||
option_layout.setContentsMargins(20, 4, 0, 0) # 缩进以表示从属关系
|
||||
|
||||
self._fetch_before_verify_checkbox = QCheckBox(
|
||||
VERIFY_MODE_OPTIONS["fetch_before_verify"]
|
||||
)
|
||||
self._fetch_before_verify_checkbox.setToolTip(
|
||||
"勾选后,在执行校验前会先从 API 获取最新数据到 ODS 层。\n"
|
||||
"适用于需要同时获取新数据并校验修复的场景。"
|
||||
)
|
||||
self._fetch_before_verify_checkbox.setChecked(self._fetch_before_verify)
|
||||
# 默认禁用,仅在 verify_only 模式下启用
|
||||
self._fetch_before_verify_checkbox.setEnabled(
|
||||
self._processing_mode == "verify_only"
|
||||
)
|
||||
option_layout.addWidget(self._fetch_before_verify_checkbox)
|
||||
option_layout.addStretch()
|
||||
layout.addLayout(option_layout)
|
||||
|
||||
# 仅在 fetch_before_verify 时生效的附加选项
|
||||
skip_ods_layout = QHBoxLayout()
|
||||
skip_ods_layout.setContentsMargins(40, 2, 0, 0)
|
||||
self._skip_ods_when_fetch_before_verify_checkbox = QCheckBox(
|
||||
VERIFY_MODE_OPTIONS["skip_ods_when_fetch_before_verify"]
|
||||
)
|
||||
self._skip_ods_when_fetch_before_verify_checkbox.setToolTip(
|
||||
"勾选后,在校验前先抓取数据的场景下跳过 ODS 校验。\n"
|
||||
"适用于仅关心 ODS 入库统计或避免重复校验的场景。"
|
||||
)
|
||||
self._skip_ods_when_fetch_before_verify_checkbox.setChecked(
|
||||
self._skip_ods_when_fetch_before_verify
|
||||
)
|
||||
skip_ods_layout.addWidget(self._skip_ods_when_fetch_before_verify_checkbox)
|
||||
skip_ods_layout.addStretch()
|
||||
layout.addLayout(skip_ods_layout)
|
||||
|
||||
local_json_layout = QHBoxLayout()
|
||||
local_json_layout.setContentsMargins(40, 2, 0, 0)
|
||||
self._ods_use_local_json_checkbox = QCheckBox(
|
||||
VERIFY_MODE_OPTIONS["ods_use_local_json"]
|
||||
)
|
||||
self._ods_use_local_json_checkbox.setToolTip(
|
||||
"勾选后,ODS 校验将完全基于落盘 JSON 进行,不再请求 API。\n"
|
||||
"需要先执行“校验前先从 API 获取数据”以生成 JSON。"
|
||||
)
|
||||
self._ods_use_local_json_checkbox.setChecked(self._ods_use_local_json)
|
||||
local_json_layout.addWidget(self._ods_use_local_json_checkbox)
|
||||
local_json_layout.addStretch()
|
||||
layout.addLayout(local_json_layout)
|
||||
|
||||
self._update_verify_option_states()
|
||||
|
||||
return group
|
||||
|
||||
def _create_window_group(self) -> QGroupBox:
|
||||
"""创建时间窗口配置分组"""
|
||||
group = QGroupBox("时间窗口")
|
||||
layout = QVBoxLayout(group)
|
||||
layout.setSpacing(8)
|
||||
|
||||
# 时间窗口模式选择
|
||||
self._window_button_group = QButtonGroup(self)
|
||||
|
||||
# 回溯模式
|
||||
lookback_layout = QHBoxLayout()
|
||||
self._lookback_radio = QRadioButton("回溯 + 冗余:")
|
||||
self._lookback_radio.setProperty("mode_id", "lookback")
|
||||
self._lookback_radio.setChecked(True)
|
||||
self._window_button_group.addButton(self._lookback_radio, 0)
|
||||
lookback_layout.addWidget(self._lookback_radio)
|
||||
|
||||
self._lookback_hours_spin = QSpinBox()
|
||||
self._lookback_hours_spin.setRange(1, 720)
|
||||
self._lookback_hours_spin.setValue(24)
|
||||
self._lookback_hours_spin.setSuffix(" 小时")
|
||||
self._lookback_hours_spin.setToolTip("回溯时间长度")
|
||||
self._lookback_hours_spin.setFixedWidth(100)
|
||||
lookback_layout.addWidget(self._lookback_hours_spin)
|
||||
|
||||
lookback_layout.addWidget(QLabel("冗余:"))
|
||||
|
||||
self._overlap_seconds_spin = QSpinBox()
|
||||
self._overlap_seconds_spin.setRange(0, 7200)
|
||||
self._overlap_seconds_spin.setValue(600)
|
||||
self._overlap_seconds_spin.setSuffix(" 秒")
|
||||
self._overlap_seconds_spin.setToolTip("时间窗口前后的重叠冗余")
|
||||
self._overlap_seconds_spin.setFixedWidth(100)
|
||||
lookback_layout.addWidget(self._overlap_seconds_spin)
|
||||
|
||||
lookback_layout.addStretch()
|
||||
layout.addLayout(lookback_layout)
|
||||
|
||||
# 自定义模式
|
||||
custom_layout = QHBoxLayout()
|
||||
self._custom_radio = QRadioButton("自定义:")
|
||||
self._custom_radio.setProperty("mode_id", "custom")
|
||||
self._window_button_group.addButton(self._custom_radio, 1)
|
||||
custom_layout.addWidget(self._custom_radio)
|
||||
|
||||
self._start_datetime = QDateTimeEdit()
|
||||
self._start_datetime.setCalendarPopup(True)
|
||||
self._start_datetime.setDisplayFormat("yyyy-MM-dd HH:mm:ss")
|
||||
self._start_datetime.setDateTime(QDateTime.currentDateTime().addDays(-1))
|
||||
self._start_datetime.setFixedWidth(160)
|
||||
self._start_datetime.setEnabled(False)
|
||||
custom_layout.addWidget(self._start_datetime)
|
||||
|
||||
custom_layout.addWidget(QLabel("至"))
|
||||
|
||||
self._end_datetime = QDateTimeEdit()
|
||||
self._end_datetime.setCalendarPopup(True)
|
||||
self._end_datetime.setDisplayFormat("yyyy-MM-dd HH:mm:ss")
|
||||
self._end_datetime.setDateTime(QDateTime.currentDateTime())
|
||||
self._end_datetime.setFixedWidth(160)
|
||||
self._end_datetime.setEnabled(False)
|
||||
custom_layout.addWidget(self._end_datetime)
|
||||
|
||||
custom_layout.addStretch()
|
||||
layout.addLayout(custom_layout)
|
||||
|
||||
# 时间窗口切分
|
||||
split_layout = QHBoxLayout()
|
||||
split_layout.addWidget(QLabel("时间窗口切分:"))
|
||||
|
||||
self._split_combo = QComboBox()
|
||||
for split_id, split_name in WINDOW_SPLIT_OPTIONS:
|
||||
self._split_combo.addItem(split_name, split_id)
|
||||
default_split_index = self._split_combo.findData("day")
|
||||
if default_split_index >= 0:
|
||||
self._split_combo.setCurrentIndex(default_split_index)
|
||||
self._split_combo.setFixedWidth(100)
|
||||
split_layout.addWidget(self._split_combo)
|
||||
|
||||
split_layout.addWidget(QLabel("切分天数:"))
|
||||
self._split_days_combo = QComboBox()
|
||||
for days, label in WINDOW_SPLIT_DAY_OPTIONS:
|
||||
self._split_days_combo.addItem(label, days)
|
||||
default_days_index = self._split_days_combo.findData(10)
|
||||
if default_days_index >= 0:
|
||||
self._split_days_combo.setCurrentIndex(default_days_index)
|
||||
self._split_days_combo.setFixedWidth(90)
|
||||
split_layout.addWidget(self._split_days_combo)
|
||||
|
||||
split_layout.addStretch()
|
||||
layout.addLayout(split_layout)
|
||||
|
||||
self._update_split_days_state()
|
||||
|
||||
return group
|
||||
|
||||
def _connect_signals(self):
|
||||
"""连接信号"""
|
||||
# 管道选择变化
|
||||
self._pipeline_button_group.buttonClicked.connect(self._on_pipeline_changed)
|
||||
|
||||
# 处理模式变化
|
||||
self._processing_button_group.buttonClicked.connect(self._on_processing_mode_changed)
|
||||
|
||||
# 时间窗口模式变化
|
||||
self._window_button_group.buttonClicked.connect(self._on_window_mode_changed)
|
||||
|
||||
# 其他配置变化
|
||||
self._lookback_hours_spin.valueChanged.connect(self._emit_config_changed)
|
||||
self._overlap_seconds_spin.valueChanged.connect(self._emit_config_changed)
|
||||
self._start_datetime.dateTimeChanged.connect(self._emit_config_changed)
|
||||
self._end_datetime.dateTimeChanged.connect(self._emit_config_changed)
|
||||
self._split_combo.currentIndexChanged.connect(self._on_split_changed)
|
||||
self._split_days_combo.currentIndexChanged.connect(self._emit_config_changed)
|
||||
|
||||
# 校验模式附加选项变化
|
||||
self._fetch_before_verify_checkbox.stateChanged.connect(self._on_fetch_before_verify_changed)
|
||||
self._skip_ods_when_fetch_before_verify_checkbox.stateChanged.connect(
|
||||
self._on_skip_ods_when_fetch_before_verify_changed
|
||||
)
|
||||
self._ods_use_local_json_checkbox.stateChanged.connect(
|
||||
self._on_ods_use_local_json_changed
|
||||
)
|
||||
|
||||
def _on_pipeline_changed(self, button: QRadioButton):
|
||||
"""管道选择变化"""
|
||||
pipeline_id = button.property("pipeline_id")
|
||||
if pipeline_id and pipeline_id != self._pipeline_id:
|
||||
self._pipeline_id = pipeline_id
|
||||
self.pipeline_changed.emit(pipeline_id)
|
||||
self.config_changed.emit()
|
||||
|
||||
def _on_processing_mode_changed(self, button: QRadioButton):
|
||||
"""处理模式变化"""
|
||||
mode_id = button.property("mode_id")
|
||||
if mode_id and mode_id != self._processing_mode:
|
||||
self._processing_mode = mode_id
|
||||
|
||||
# 更新 "校验前获取数据" 选项的启用状态
|
||||
# 仅在 verify_only 模式下可用
|
||||
is_verify_only = mode_id == "verify_only"
|
||||
self._fetch_before_verify_checkbox.setEnabled(is_verify_only)
|
||||
if not is_verify_only:
|
||||
# 非 verify_only 模式时,自动取消勾选
|
||||
self._fetch_before_verify_checkbox.setChecked(False)
|
||||
|
||||
self._update_verify_option_states()
|
||||
|
||||
self.processing_mode_changed.emit(mode_id)
|
||||
self.config_changed.emit()
|
||||
|
||||
def _on_fetch_before_verify_changed(self, state: int):
|
||||
"""校验前获取数据选项变化"""
|
||||
from PySide6.QtCore import Qt
|
||||
self._fetch_before_verify = state == Qt.Checked.value
|
||||
self._update_verify_option_states()
|
||||
self.config_changed.emit()
|
||||
|
||||
def _on_skip_ods_when_fetch_before_verify_changed(self, state: int):
|
||||
"""跳过 ODS 校验选项变化"""
|
||||
from PySide6.QtCore import Qt
|
||||
self._skip_ods_when_fetch_before_verify = state == Qt.Checked.value
|
||||
self.config_changed.emit()
|
||||
|
||||
def _on_ods_use_local_json_changed(self, state: int):
|
||||
"""ODS 校验使用本地 JSON 选项变化"""
|
||||
from PySide6.QtCore import Qt
|
||||
self._ods_use_local_json = state == Qt.Checked.value
|
||||
self.config_changed.emit()
|
||||
|
||||
def _update_verify_option_states(self):
|
||||
"""更新校验附加选项的启用状态"""
|
||||
enable_suboptions = self._processing_mode == "verify_only" and self._fetch_before_verify
|
||||
self._skip_ods_when_fetch_before_verify_checkbox.setEnabled(enable_suboptions)
|
||||
self._ods_use_local_json_checkbox.setEnabled(enable_suboptions)
|
||||
|
||||
def _on_window_mode_changed(self, button: QRadioButton):
|
||||
"""时间窗口模式变化"""
|
||||
mode_id = button.property("mode_id")
|
||||
if mode_id and mode_id != self._window_mode:
|
||||
self._window_mode = mode_id
|
||||
|
||||
# 更新控件启用状态
|
||||
is_lookback = mode_id == "lookback"
|
||||
self._lookback_hours_spin.setEnabled(is_lookback)
|
||||
self._overlap_seconds_spin.setEnabled(is_lookback)
|
||||
self._start_datetime.setEnabled(not is_lookback)
|
||||
self._end_datetime.setEnabled(not is_lookback)
|
||||
|
||||
self.window_mode_changed.emit(mode_id)
|
||||
self.config_changed.emit()
|
||||
|
||||
def _on_split_changed(self):
|
||||
"""时间窗口切分方式变化"""
|
||||
self._update_split_days_state()
|
||||
self.config_changed.emit()
|
||||
|
||||
def _update_split_days_state(self):
|
||||
"""按天切分才允许选择天数"""
|
||||
is_day_split = self.get_window_split() == "day"
|
||||
self._split_days_combo.setEnabled(is_day_split)
|
||||
|
||||
def _emit_config_changed(self):
|
||||
"""发出配置变化信号"""
|
||||
self.config_changed.emit()
|
||||
|
||||
# === 公共接口 ===
|
||||
|
||||
def get_pipeline_id(self) -> str:
|
||||
"""获取当前管道ID"""
|
||||
return self._pipeline_id
|
||||
|
||||
def set_pipeline_id(self, pipeline_id: str):
|
||||
"""设置管道ID"""
|
||||
for button in self._pipeline_button_group.buttons():
|
||||
if button.property("pipeline_id") == pipeline_id:
|
||||
button.setChecked(True)
|
||||
self._pipeline_id = pipeline_id
|
||||
break
|
||||
|
||||
def get_pipeline_layers(self) -> List[str]:
|
||||
"""获取当前管道包含的层"""
|
||||
return get_pipeline_layers(self._pipeline_id)
|
||||
|
||||
def get_processing_mode(self) -> str:
|
||||
"""获取数据处理模式"""
|
||||
return self._processing_mode
|
||||
|
||||
def set_processing_mode(self, mode: str):
|
||||
"""设置数据处理模式"""
|
||||
for button in self._processing_button_group.buttons():
|
||||
if button.property("mode_id") == mode:
|
||||
button.setChecked(True)
|
||||
self._processing_mode = mode
|
||||
# 更新复选框启用状态
|
||||
is_verify_only = mode == "verify_only"
|
||||
self._fetch_before_verify_checkbox.setEnabled(is_verify_only)
|
||||
if not is_verify_only:
|
||||
self._fetch_before_verify_checkbox.setChecked(False)
|
||||
self._update_verify_option_states()
|
||||
break
|
||||
|
||||
def get_fetch_before_verify(self) -> bool:
|
||||
"""获取是否在校验前从 API 获取数据"""
|
||||
return self._fetch_before_verify
|
||||
|
||||
def set_fetch_before_verify(self, enabled: bool):
|
||||
"""设置是否在校验前从 API 获取数据"""
|
||||
self._fetch_before_verify = enabled
|
||||
self._fetch_before_verify_checkbox.setChecked(enabled)
|
||||
self._update_verify_option_states()
|
||||
|
||||
def get_skip_ods_when_fetch_before_verify(self) -> bool:
|
||||
"""获取是否跳过 ODS 校验(仅校验前获取时生效)"""
|
||||
return self._skip_ods_when_fetch_before_verify
|
||||
|
||||
def set_skip_ods_when_fetch_before_verify(self, enabled: bool):
|
||||
"""设置是否跳过 ODS 校验(仅校验前获取时生效)"""
|
||||
self._skip_ods_when_fetch_before_verify = enabled
|
||||
self._skip_ods_when_fetch_before_verify_checkbox.setChecked(enabled)
|
||||
self._update_verify_option_states()
|
||||
|
||||
def get_ods_use_local_json(self) -> bool:
|
||||
"""获取是否使用本地 JSON 进行 ODS 校验"""
|
||||
return self._ods_use_local_json
|
||||
|
||||
def set_ods_use_local_json(self, enabled: bool):
|
||||
"""设置是否使用本地 JSON 进行 ODS 校验"""
|
||||
self._ods_use_local_json = enabled
|
||||
self._ods_use_local_json_checkbox.setChecked(enabled)
|
||||
self._update_verify_option_states()
|
||||
|
||||
def get_window_mode(self) -> str:
|
||||
"""获取时间窗口模式"""
|
||||
return self._window_mode
|
||||
|
||||
def set_window_mode(self, mode: str):
|
||||
"""设置时间窗口模式"""
|
||||
for button in self._window_button_group.buttons():
|
||||
if button.property("mode_id") == mode:
|
||||
button.setChecked(True)
|
||||
self._on_window_mode_changed(button)
|
||||
break
|
||||
|
||||
def get_lookback_hours(self) -> int:
|
||||
"""获取回溯小时数"""
|
||||
return self._lookback_hours_spin.value()
|
||||
|
||||
def set_lookback_hours(self, hours: int):
|
||||
"""设置回溯小时数"""
|
||||
self._lookback_hours_spin.setValue(hours)
|
||||
|
||||
def get_overlap_seconds(self) -> int:
|
||||
"""获取冗余秒数"""
|
||||
return self._overlap_seconds_spin.value()
|
||||
|
||||
def set_overlap_seconds(self, seconds: int):
|
||||
"""设置冗余秒数"""
|
||||
self._overlap_seconds_spin.setValue(seconds)
|
||||
|
||||
def get_window_start(self) -> str:
|
||||
"""获取开始时间(ISO格式)"""
|
||||
return self._start_datetime.dateTime().toString("yyyy-MM-dd HH:mm:ss")
|
||||
|
||||
def set_window_start(self, dt_str: str):
|
||||
"""设置开始时间"""
|
||||
dt = QDateTime.fromString(dt_str, "yyyy-MM-dd HH:mm:ss")
|
||||
if dt.isValid():
|
||||
self._start_datetime.setDateTime(dt)
|
||||
|
||||
def get_window_end(self) -> str:
|
||||
"""获取结束时间(ISO格式)"""
|
||||
return self._end_datetime.dateTime().toString("yyyy-MM-dd HH:mm:ss")
|
||||
|
||||
def set_window_end(self, dt_str: str):
|
||||
"""设置结束时间"""
|
||||
dt = QDateTime.fromString(dt_str, "yyyy-MM-dd HH:mm:ss")
|
||||
if dt.isValid():
|
||||
self._end_datetime.setDateTime(dt)
|
||||
|
||||
def get_window_split(self) -> str:
|
||||
"""获取窗口切分模式"""
|
||||
return self._split_combo.currentData()
|
||||
|
||||
def get_window_split_days(self) -> int:
|
||||
"""获取按天切分天数"""
|
||||
return int(self._split_days_combo.currentData())
|
||||
|
||||
def set_window_split(self, split: str):
|
||||
"""设置窗口切分模式"""
|
||||
index = self._split_combo.findData(split)
|
||||
if index >= 0:
|
||||
self._split_combo.setCurrentIndex(index)
|
||||
self._update_split_days_state()
|
||||
|
||||
def set_window_split_days(self, days: int):
|
||||
"""设置按天切分天数"""
|
||||
index = self._split_days_combo.findData(days)
|
||||
if index >= 0:
|
||||
self._split_days_combo.setCurrentIndex(index)
|
||||
|
||||
def get_config(self) -> dict:
|
||||
"""获取完整配置字典"""
|
||||
split_unit = self.get_window_split()
|
||||
split_days = self.get_window_split_days()
|
||||
return {
|
||||
"pipeline": self._pipeline_id,
|
||||
"processing_mode": self._processing_mode,
|
||||
"fetch_before_verify": self._fetch_before_verify,
|
||||
"skip_ods_when_fetch_before_verify": self._skip_ods_when_fetch_before_verify,
|
||||
"ods_use_local_json": self._ods_use_local_json,
|
||||
"window_mode": self._window_mode,
|
||||
"lookback_hours": self.get_lookback_hours(),
|
||||
"overlap_seconds": self.get_overlap_seconds(),
|
||||
"window_start": self.get_window_start(),
|
||||
"window_end": self.get_window_end(),
|
||||
"window_split": split_unit,
|
||||
"window_split_days": split_days,
|
||||
}
|
||||
|
||||
def set_config(self, config: dict):
|
||||
"""从配置字典恢复设置"""
|
||||
if "pipeline" in config:
|
||||
self.set_pipeline_id(config["pipeline"])
|
||||
if "processing_mode" in config:
|
||||
self.set_processing_mode(config["processing_mode"])
|
||||
if "fetch_before_verify" in config:
|
||||
self.set_fetch_before_verify(config["fetch_before_verify"])
|
||||
if "skip_ods_when_fetch_before_verify" in config:
|
||||
self.set_skip_ods_when_fetch_before_verify(config["skip_ods_when_fetch_before_verify"])
|
||||
if "ods_use_local_json" in config:
|
||||
self.set_ods_use_local_json(config["ods_use_local_json"])
|
||||
if "window_mode" in config:
|
||||
self.set_window_mode(config["window_mode"])
|
||||
if "lookback_hours" in config:
|
||||
self.set_lookback_hours(config["lookback_hours"])
|
||||
if "overlap_seconds" in config:
|
||||
self.set_overlap_seconds(config["overlap_seconds"])
|
||||
if "window_start" in config:
|
||||
self.set_window_start(config["window_start"])
|
||||
if "window_end" in config:
|
||||
self.set_window_end(config["window_end"])
|
||||
if "window_split" in config:
|
||||
self.set_window_split(config["window_split"])
|
||||
if "window_split_days" in config and config["window_split_days"]:
|
||||
self.set_window_split_days(config["window_split_days"])
|
||||
Reference in New Issue
Block a user