From 50f3078f4efb3718e921b76567bd33d6c3640a44 Mon Sep 17 00:00:00 2001
From: chenluhua1980 <Chenluhua@qq.com>
Date: 星期三, 21 一月 2026 22:20:31 +0800
Subject: [PATCH] 1.新增“读即已读”逻辑:CServoDlg::AckAlarm(int alarmId)记录已读并刷新角标;弹窗在显示任一告警时自动调用,导航上一条/下一条都会标记已读,工具条数量会同步更新。

---
 SourceCode/Bond/Servo/CMaster.cpp |  154 +++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 143 insertions(+), 11 deletions(-)

diff --git a/SourceCode/Bond/Servo/CMaster.cpp b/SourceCode/Bond/Servo/CMaster.cpp
index d9a0e67..df536fb 100644
--- a/SourceCode/Bond/Servo/CMaster.cpp
+++ b/SourceCode/Bond/Servo/CMaster.cpp
@@ -8,6 +8,9 @@
 #include <fstream>
 #include "SerializeUtil.h"
 #include "CServoUtilsTool.h"
+#include "AlarmManager.h"
+#include "ToolUnits.h"
+#include "Model.h"
 
 
 namespace SERVO {
@@ -72,6 +75,8 @@
 		m_nContinuousWorkingPort = 0;
 		m_nContinuousWorkingSlot = 0;
 		m_pControlJob = nullptr;
+		m_bPauseAlarmRaised = false;
+		m_pModelCtx = nullptr;
 		m_nTestFlag = 0;
 		InitializeCriticalSection(&m_criticalSection);
 	}
@@ -121,6 +126,11 @@
 		m_listener = listener;
 	}
 
+	void CMaster::setModelCtx(CModel* pModel)
+	{
+		m_pModelCtx = pModel;
+	}
+
 	CRobotTask* CMaster::getActiveRobotTask()
 	{
 		return m_pActiveRobotTask;
@@ -128,11 +138,18 @@
 
 	int CMaster::init()
 	{
+		const ULONGLONG boot_master_begin = GetTickCount64();
 		LOGI("<Master>姝e湪鍒濆鍖�...");
+		LOGI("[BOOT][MASTER] init begin");
 
 
 		// 	cclink
-		if (m_cclink.Connect(CC_LINK_IE_CONTROL_CHANNEL(1)) != 0) {
+		const ULONGLONG boot_cclink_begin = GetTickCount64();
+		const int cc_ret = m_cclink.Connect(CC_LINK_IE_CONTROL_CHANNEL(1));
+		LOGI("[BOOT][MASTER] CC-Link connect ret=%d, cost=%llu ms",
+			cc_ret,
+			(unsigned long long)(GetTickCount64() - boot_cclink_begin));
+		if (cc_ret != 0) {
 			LOGE("杩炴帴CC-Link澶辫触.");
 		}
 		else {
@@ -221,11 +238,21 @@
 
 
 		// 璇荤紦瀛樻暟鎹�
+		const ULONGLONG boot_cache_begin = GetTickCount64();
+		const ULONGLONG boot_read_begin = GetTickCount64();
 		readCache();
+		LOGI("[BOOT][MASTER] readCache finished, cost=%llu ms", (unsigned long long)(GetTickCount64() - boot_read_begin));
+
+		const ULONGLONG boot_state_begin = GetTickCount64();
 		loadState();
+		LOGI("[BOOT][MASTER] loadState finished, cost=%llu ms", (unsigned long long)(GetTickCount64() - boot_state_begin));
 		if (m_listener.onControlJobChanged) {
-			m_listener.onControlJobChanged(this);
+			notifyControlJobChanged();
 		}
+
+		LOGI("[BOOT][MASTER] cache/state loaded, cost=%llu ms (since init %llu ms)",
+			(unsigned long long)(GetTickCount64() - boot_cache_begin),
+			(unsigned long long)(GetTickCount64() - boot_master_begin));
 
 
 		// 瀹氭椂鍣�
@@ -248,6 +275,8 @@
 
 
 		LOGI("<Master>鍒濆鍖栧畬鎴�.");
+		LOGI("[BOOT][MASTER] init finished, total cost=%llu ms",
+			(unsigned long long)(GetTickCount64() - boot_master_begin));
 		return 0;
 	}
 
@@ -879,6 +908,33 @@
 						m_pActiveRobotTask->place();
 					}
 					unlock(); // 绛夊綋鍓嶄换鍔″畬鎴愭垨涓鍚庣户缁�
+					continue;
+				}
+
+				// 5.5) 鏆傚仠鐘舵�佹鏌ワ細鑻� CJ 鎴栧湪鍒� PJ 澶勪簬 Paused锛屾殏缂撹皟搴︽柊鐨勬惉閫�
+				bool pausedByEvent = false;
+				if (m_pControlJob != nullptr && m_pControlJob->state() == CJState::Paused) {
+					pausedByEvent = true;
+				}
+				for (auto pj : m_inProcesJobs) {
+					if (pj != nullptr && pj->state() == PJState::Paused) {
+						pausedByEvent = true;
+						break;
+					}
+				}
+				if (!pausedByEvent && m_bPauseAlarmRaised) {
+					if (m_pModelCtx != nullptr) {
+						m_pModelCtx->clearSoftAlarm(ALID_SOFTWARE_PAUSE_EVENT, 0, 0);
+					}
+					else {
+						AlarmManager& alarmManager = AlarmManager::getInstance();
+						alarmManager.clearAlarmByAttributes(ALID_SOFTWARE_PAUSE_EVENT, 0, 0, CToolUnits::getCurrentTimeString());
+					}
+					m_bPauseAlarmRaised = false;
+				}
+				if (pausedByEvent) {
+					LOGI("<Master>璋冨害鏆傚仠锛欳ontrolJob/ProcessJob 澶勪簬 Paused 鐘舵�侊紙鍙兘鐢� PauseEvent 瑙﹀彂锛�");
+					unlock();
 					continue;
 				}
 
@@ -1638,6 +1694,14 @@
 			}
 		};
 		listener.onSVDataReport = [&](void* pEquipment, void* pData) {
+			const bool allowSvLog =
+				(m_state == MASTERSTATE::RUNNING ||
+					m_state == MASTERSTATE::RUNNING_CONTINUOUS_TRANSFER ||
+					m_state == MASTERSTATE::RUNNING_BATCH ||
+					m_state == MASTERSTATE::STARTING);
+			if (!allowSvLog) {
+				return;
+			}
 			CSVData* pSVData = (CSVData*)pData;
 			auto rawData = pSVData->getSVRawData();
 			std::vector<CParam> params;
@@ -2859,7 +2923,7 @@
 
 		this->saveState();
 		if (m_listener.onControlJobChanged) {
-			m_listener.onControlJobChanged(this);
+			notifyControlJobChanged();
 		}
 
 		return (int)m_processJobs.size();
@@ -2919,7 +2983,7 @@
 		m_pControlJob->setPJs(temps);
 		this->saveState();
 		if (m_listener.onControlJobChanged) {
-			m_listener.onControlJobChanged(this);
+			notifyControlJobChanged();
 		}
 
 
@@ -2977,15 +3041,83 @@
 		return m_allowedCeids.find(ceid) != m_allowedCeids.end();
 	}
 
+	bool CMaster::raiseSoftAlarm(int alarmId,
+		const std::string& desc,
+		int level/* = -1*/,
+		int deviceId/* = 0*/,
+		int unitId/* = 0*/,
+		const char* deviceName/* = "Software"*/,
+		const char* unitName/* = "App"*/)
+	{
+		AlarmManager& alarmManager = AlarmManager::getInstance();
+		const AlarmInfo* info = alarmManager.getAlarmInfoByID(alarmId);
+
+		int severity = level;
+		if (severity < 0 && info != nullptr) {
+			severity = info->nAlarmLevel;
+		}
+		if (severity < 0) severity = 0; // fallback
+
+		std::string descText = desc;
+		if (descText.empty() && info != nullptr) {
+			descText = !info->strDescription.empty() ? info->strDescription : info->strAlarmText;
+		}
+		if (descText.empty()) {
+			descText = CToolUnits::formatString("Alarm %d", alarmId);
+		}
+
+		AlarmData alarmData;
+		alarmData.nId = alarmId;
+		alarmData.nSeverityLevel = severity;
+		alarmData.nDeviceId = deviceId;
+		alarmData.nUnitId = unitId;
+		alarmData.strDeviceName = deviceName;
+		alarmData.strUnitName = unitName;
+		alarmData.strStartTime = CToolUnits::timeToString2(CToolUnits::getTimestamp());
+		alarmData.strEndTime = "";
+		alarmData.strDescription = descText;
+
+		int nAlarmEventId = 0;
+		return alarmManager.addAlarm(alarmData, nAlarmEventId);
+	}
+
 	void CMaster::handleCollectionEvent(uint32_t ceid)
 	{
 		// 閬嶅巻褰撳墠 PJ锛屽懡涓� pauseEvents 鏃跺彲鍦ㄦ鎵╁睍鏆傚仠鍔ㄤ綔
+		bool pausedAny = false;
 		for (auto pj : m_processJobs) {
 			if (pj == nullptr) continue;
 			const auto& pauseList = pj->pauseEvents();
 			if (std::find(pauseList.begin(), pauseList.end(), ceid) != pauseList.end()) {
 				LOGW("<Master>PauseEvent hit: CEID=%u, PJ=%s, state=%d", ceid, pj->id().c_str(), (int)pj->state());
-				// TODO: 琛旀帴鍏蜂綋鏆傚仠绛栫暐锛堝鏆傚仠 PJ/CJ銆佸仠姝㈣皟搴�/鎼�侊級锛屾澶勪粎鐣欐々浣�
+				if (pj->pause()) {
+					LOGI("<Master>PJ paused by CEID=%u", ceid);
+					pausedAny = true;
+				}
+				if (m_pControlJob != nullptr && m_pControlJob->state() == CJState::Executing) {
+					if (m_pControlJob->pause()) {
+						LOGI("<Master>ControlJob paused by CEID=%u", ceid);
+						pausedAny = true;
+					}
+				}
+			}
+		}
+		if (pausedAny && m_listener.onControlJobChanged) {
+			// 閫氱煡搴旂敤灞傚埛鏂� UI/鎸夐挳鐘舵��
+			notifyControlJobChanged();
+		}
+		if (pausedAny && !m_bPauseAlarmRaised) {
+			std::string desc = CToolUnits::formatString("<PauseEvent CEID=%u>", ceid);
+			bool raised = false;
+			if (m_pModelCtx != nullptr) {
+				raised = m_pModelCtx->raiseSoftAlarm(ALID_SOFTWARE_PAUSE_EVENT, desc);
+			}
+			else {
+				raised = raiseSoftAlarm(ALID_SOFTWARE_PAUSE_EVENT, desc);
+			}
+			if (raised) {
+				LOGI("<Master>PauseEvent soft alarm raised, CEID=%u", ceid);
+				m_bPauseAlarmRaised = true;
 			}
 		}
 	}
@@ -3287,7 +3419,7 @@
 
 		saveState();
 		if (m_listener.onControlJobChanged) {
-			m_listener.onControlJobChanged(this);
+			notifyControlJobChanged();
 		}
 
 		return true;
@@ -3324,7 +3456,7 @@
 
 		saveState();
 		if (m_listener.onControlJobChanged) {
-			m_listener.onControlJobChanged(this);
+			notifyControlJobChanged();
 		}
 
 		return true;
@@ -3475,14 +3607,14 @@
 			auto& dataTypes = CServoUtilsTool::getEqDataTypes();
 			auto& bonderTypes = dataTypes[MID_Bonder1];
 			for (size_t i = 0; i < bonderTypes.size(); ++i) {
-				m_pCollector->buffersSetChannelName(MID_Bonder1, i + 1, bonderTypes[i].c_str());
-				m_pCollector->buffersSetChannelName(MID_Bonder2, i + 1, bonderTypes[i].c_str());
+				m_pCollector->buffersSetChannelName(MID_Bonder1, (UINT)i + 1, bonderTypes[(UINT)i].c_str());
+				m_pCollector->buffersSetChannelName(MID_Bonder2, (UINT)i + 1, bonderTypes[(UINT)i].c_str());
 			}
 
 			auto& vacuumbakeTypes = dataTypes[MID_VacuumBakeA];
 			for (size_t i = 0; i < vacuumbakeTypes.size(); ++i) {
-				m_pCollector->buffersSetChannelName(MID_VacuumBakeA, i + 1, vacuumbakeTypes[i].c_str());
-				m_pCollector->buffersSetChannelName(MID_VacuumBakeB, i + 1, vacuumbakeTypes[i].c_str());
+				m_pCollector->buffersSetChannelName(MID_VacuumBakeA, (UINT)i + 1, vacuumbakeTypes[(UINT)i].c_str());
+				m_pCollector->buffersSetChannelName(MID_VacuumBakeB, (UINT)i + 1, vacuumbakeTypes[(UINT)i].c_str());
 			}
 
 			auto& coolingTypes = dataTypes[MID_BakeCoolingA];

--
Gitblit v1.9.3