215 lines
7.6 KiB
Python
215 lines
7.6 KiB
Python
#!/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"))
|