#!/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"))