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"))
|