Files
dtm-py-all/UI/viewmodels/system_settings_viewmodel.py

215 lines
7.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
系统设置 ViewModel - 响应式数据管理
"""
from PyQt5.QtCore import QObject, pyqtSignal, pyqtProperty
from models.system_model import SystemModel
import json
class SystemSettingsViewModel(QObject):
"""系统设置的响应式 ViewModel"""
# 信号:数据变化时自动触发
machinesChanged = pyqtSignal()
phasesChanged = pyqtSignal()
usersChanged = pyqtSignal()
currentMachineChanged = pyqtSignal()
plcDataChanged = pyqtSignal()
def __init__(self, parent=None):
super().__init__(parent)
self.model = SystemModel()
# 数据缓存
self._machines = []
self._phases = []
self._users = []
self._current_machine_id = None
self._plc_data = {}
# 删除标记
self.removed_machine_ids = set()
self.removed_phase_ids = set()
self.removed_user_ids = set()
# ============ 机台列表 ============
@pyqtProperty(list, notify=machinesChanged)
def machines(self):
"""机台列表(响应式属性)"""
return self._machines
def loadMachines(self):
"""加载机台数据"""
self._machines = self.model.load_machines()
self.machinesChanged.emit()
def saveMachines(self, machines_data):
"""保存机台数据"""
self.model.save_machines(machines_data, list(self.removed_machine_ids))
self.removed_machine_ids.clear()
self.loadMachines() # 重新加载以刷新
# 如果当前有选中的机台,重新加载 PLC 数据
if self._current_machine_id:
self._loadPlcData()
def deleteMachines(self, machine_ids):
"""删除机台数据"""
if not machine_ids:
return False
delete_records = [{"id": mid} for mid in machine_ids]
success = self.model.delete_machines(delete_records)
if success:
self.loadMachines() # 重新加载以刷新
return success
# ============ 样品阶段列表 ============
@pyqtProperty(list, notify=phasesChanged)
def phases(self):
"""样品阶段列表(响应式属性)"""
return self._phases
def loadPhases(self):
"""加载样品阶段数据"""
self._phases = self.model.load_project_phases()
self.phasesChanged.emit()
def savePhases(self, phases_data):
"""保存样品阶段数据"""
self.model.save_project_phases(phases_data, list(self.removed_phase_ids))
self.removed_phase_ids.clear()
self.loadPhases()
def deletePhases(self, phase_ids):
"""删除样品阶段数据"""
if not phase_ids:
return False
delete_records = [{"id": pid} for pid in phase_ids]
success = self.model.delete_project_phases(delete_records)
if success:
self.loadPhases() # 重新加载以刷新
return success
# ============ 用户列表 ============
@pyqtProperty(list, notify=usersChanged)
def users(self):
"""用户列表(响应式属性)"""
return self._users
def loadUsers(self):
"""加载用户数据"""
self._users = self.model.load_users()
self.usersChanged.emit()
def saveUsers(self, users_data):
"""保存用户数据"""
self.model.save_users(users_data, list(self.removed_user_ids))
self.removed_user_ids.clear()
self.loadUsers()
def deleteUsers(self, user_ids):
"""删除用户数据"""
if not user_ids:
return False
delete_records = [{"id": uid} for uid in user_ids]
success = self.model.delete_users(delete_records)
if success:
self.loadUsers() # 重新加载以刷新
return success
# ============ 当前选中机台 ============
@pyqtProperty(str, notify=currentMachineChanged)
def currentMachineId(self):
"""当前选中的机台 ID响应式属性"""
return self._current_machine_id or ""
def setCurrentMachineId(self, machine_id):
"""设置当前机台 ID自动触发 PLC 数据加载"""
if self._current_machine_id != machine_id:
self._current_machine_id = machine_id
self.currentMachineChanged.emit()
self._loadPlcData() # 自动加载 PLC 数据
# ============ PLC 参数数据 ============
@pyqtProperty('QVariantMap', notify=plcDataChanged)
def plcData(self):
"""当前机台的 PLC 参数(响应式属性)"""
return self._plc_data
def _loadPlcData(self):
"""私有方法:根据当前机台 ID 加载 PLC 数据"""
if not self._current_machine_id:
self._plc_data = {}
self.plcDataChanged.emit()
return
# 从缓存的机台列表中查找
machine = next((m for m in self._machines if m.get("id") == self._current_machine_id), None)
if not machine:
self._plc_data = {}
else:
# 提取 PLC 相关字段
self._plc_data = {
"plcAddress": str(machine.get("plcAddress", "")),
"com": str(machine.get("com", "")),
"testType": str(machine.get("testType", "")),
"baudrate": machine.get("baudrate", {}),
"status1": str(machine.get("status1", "")) in ("1", "true", "enabled"),
"status2": str(machine.get("status2", "")) in ("1", "true", "enabled"),
"status3": str(machine.get("status3", "")) in ("1", "true", "enabled"),
"status4": str(machine.get("status4", "")) in ("1", "true", "enabled"),
"register01": machine.get("register01", {}),
"register02": machine.get("register02", {}),
"register03": machine.get("register03", {}),
"register04": machine.get("register04", {}),
}
# print(f"Loaded PLC data: {self._plc_data}")
self.plcDataChanged.emit() # 触发界面刷新
def savePlcData(self, plc_updates):
"""保存 PLC 参数到当前机台
重要:只传入 PLC 相关字段,不传入机台基本信息;必须包含 SN 字段用于后台更新
"""
if not self._current_machine_id:
return False
# 找到当前机台
machine = next((m for m in self._machines if m.get("id") == self._current_machine_id), None)
if not machine:
return False
# 必须传入 id 和 SN后台通过 SN 更新),以及 PLC 相关字段
update_data = {
"id": self._current_machine_id, # 用于 SQLite 直接访问时的 WHERE 条件
"SN": machine.get("SN"), # 用于 HTTP API 后台更新update_key
}
# 只添加非 None 的 PLC 字段
for key, value in plc_updates.items():
if value is not None:
update_data[key] = value
# 保存到数据库(只更新传入的字段)
self.model.save_machines([update_data])
# 重新加载机台列表和 PLC 数据
self.loadMachines()
self._loadPlcData()
return True
# ============ 初始化加载 ============
def loadAll(self):
"""加载所有数据"""
self.loadMachines()
self.loadPhases()
self.loadUsers()
# 默认选中第一个机台
if self._machines:
self.setCurrentMachineId(self._machines[0].get("id"))