From d400f022161ff47f02cd0ea95a5076d0187ecd4d Mon Sep 17 00:00:00 2001
From: chenluhua1980 <Chenluhua@qq.com>
Date: 星期五, 30 一月 2026 15:11:06 +0800
Subject: [PATCH] 1.接上,日志完善;

---
 SourceCode/Bond/Servo/ProcessJob.cpp |  268 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 259 insertions(+), 9 deletions(-)

diff --git a/SourceCode/Bond/Servo/ProcessJob.cpp b/SourceCode/Bond/Servo/ProcessJob.cpp
index 16bfbb0..eb92df5 100644
--- a/SourceCode/Bond/Servo/ProcessJob.cpp
+++ b/SourceCode/Bond/Servo/ProcessJob.cpp
@@ -1,18 +1,35 @@
 #include "stdafx.h"
 #include "ProcessJob.h"
 #include <cctype>
+#include <fstream>
+#include "SerializeUtil.h"
+
 
 namespace SERVO {
     static inline std::string trimCopy(std::string s) {
-        auto notspace = [](int ch) { return !std::isspace(ch); };
-        s.erase(s.begin(), std::find_if(s.begin(), s.end(), notspace));
-        s.erase(std::find_if(s.rbegin(), s.rend(), notspace).base(), s.end());
+        s.erase(s.begin(),
+            std::find_if(s.begin(), s.end(),
+                [](char c) { return !std::isspace(static_cast<unsigned char>(c)); }));
+        s.erase(std::find_if(s.rbegin(), s.rend(),
+            [](char c) { return !std::isspace(static_cast<unsigned char>(c)); }).base(),
+            s.end());
         return s;
+    }
+
+    CProcessJob::CProcessJob()
+    {
+
     }
 
     CProcessJob::CProcessJob(std::string pjId)
         : m_pjId(trimCopy(pjId))
     {
+        clampString(m_pjId, MAX_ID_LEN);
+    }
+
+    void CProcessJob::setId(std::string& id)
+    {
+        m_pjId = trimCopy(id);
         clampString(m_pjId, MAX_ID_LEN);
     }
 
@@ -53,9 +70,14 @@
         m_pauseEvents.erase(std::unique(m_pauseEvents.begin(), m_pauseEvents.end()), m_pauseEvents.end());
     }
 
-    const std::vector<CProcessJob::ValidationIssue>& CProcessJob::issues()
+    const std::vector<CProcessJob::ValidationIssue>& CProcessJob::issues() const
     {
         return m_issues;
+    }
+
+    void CProcessJob::addIssue(uint32_t code, const std::string& msg)
+    {
+        m_issues.push_back({ code, msg });
     }
 
     bool CProcessJob::validate(const IResourceView& rv)
@@ -66,10 +88,6 @@
         auto add = [&](uint32_t code, std::string msg) {
             m_issues.push_back({ code, std::move(msg) });
         };
-
-        if (!rv.isProcessJobsEmpty()) {
-            add(1000, "ProcessJobs Conflict!");
-        }
 
         // —— 基本 / 标识 ——
         if (m_pjId.empty())            add(1001, "PJID empty");
@@ -169,9 +187,11 @@
         return true;
     }
 
-    bool CProcessJob::abort() {
+    bool CProcessJob::abort(std::string reason) {
         if (m_state == PJState::Completed || m_state == PJState::Aborted || m_state == PJState::Failed)
             return false;
+        m_failReason = trimCopy(reason);
+        clampString(m_failReason, 128);
         m_state = PJState::Aborted;
         markEnd();
         return true;
@@ -257,4 +277,234 @@
             m_carriers.emplace_back(std::move(cs));
         }
     }
+
+    bool CProcessJob::setCarrierSlotsAndContexts(std::string carrierId, std::vector<uint8_t> slots, std::vector<void*> contexts)
+    {
+        for (auto& c : m_carriers) {
+            if (c.carrierId.compare(carrierId) == 0) {
+                c.slots = std::move(slots);
+                c.contexts = std::move(contexts);
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    bool CProcessJob::setCarrierContexts(std::string carrierId, std::vector<void*> contexts)
+    {
+        for (auto& c : m_carriers) {
+            if (c.carrierId.compare(carrierId) == 0) {
+                c.contexts = std::move(contexts);
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    // --------- 核心:serialize/deserialize ---------
+    void CProcessJob::serialize(std::ostream& os) const {
+        // 头
+        write_pod(os, PJ_FILE_MAGIC);
+        write_pod(os, PJ_FILE_VERSION);
+
+        // 基本
+        write_string(os, m_pjId);
+        write_string(os, m_parentCjId);
+
+        // 配方
+        uint8_t recipeType = static_cast<uint8_t>(m_recipeMethod);
+        write_pod(os, recipeType);
+        write_string(os, m_recipeSpec);
+
+        // 物料(多 Carrier & Slot)
+        {
+            uint32_t n = static_cast<uint32_t>(m_carriers.size());
+            write_pod(os, n);
+            for (const auto& cs : m_carriers) {
+                write_string(os, cs.carrierId);
+                write_vec<uint8_t>(os, cs.slots);
+            }
+        }
+
+        // 参数
+        {
+            uint32_t n = static_cast<uint32_t>(m_params.size());
+            write_pod(os, n);
+            for (const auto& p : m_params) {
+                write_string(os, p.name);
+                write_string(os, p.value);
+            }
+        }
+
+        // 暂停事件
+        write_vec<uint32_t>(os, m_pauseEvents);
+
+        // 启动策略 & 状态
+        uint8_t startPolicy = static_cast<uint8_t>(m_startPolicy);
+        uint8_t st = static_cast<uint8_t>(m_state);
+        write_pod(os, startPolicy);
+        write_pod(os, st);
+
+        // 失败原因
+        write_string(os, m_failReason);
+
+        // 时间戳
+        write_opt_time(os, m_tQueued);
+        write_opt_time(os, m_tStart);
+        write_opt_time(os, m_tEnd);
+    }
+
+    bool CProcessJob::deserialize(std::istream& is, CProcessJob& out, std::string* err) {
+        auto fail = [&](const char* msg) { if (err) *err = msg; return false; };
+
+        uint32_t magic = 0; if (!read_pod(is, magic)) return fail("read magic failed");
+        if (magic != PJ_FILE_MAGIC) return fail("bad magic");
+
+        uint16_t ver = 0; if (!read_pod(is, ver)) return fail("read version failed");
+        if (ver != PJ_FILE_VERSION) return fail("unsupported version");
+
+        // 基本
+        if (!read_string(is, out.m_pjId))        return fail("read pjId");
+        if (!read_string(is, out.m_parentCjId))  return fail("read parentCjId");
+
+        // 配方
+        uint8_t recipeType = 0; if (!read_pod(is, recipeType)) return fail("read recipeType");
+        out.m_recipeMethod = static_cast<RecipeMethod>(recipeType);
+        if (!read_string(is, out.m_recipeSpec)) return fail("read recipeSpec");
+
+        // 物料
+        {
+            uint32_t n = 0; if (!read_pod(is, n)) return fail("read carriers count");
+            out.m_carriers.clear(); out.m_carriers.reserve(n);
+            for (uint32_t i = 0; i < n; ++i) {
+                CarrierSlotInfo cs;
+                if (!read_string(is, cs.carrierId)) return fail("read carrierId");
+                if (!read_vec<uint8_t>(is, cs.slots)) return fail("read slots");
+                out.m_carriers.emplace_back(std::move(cs));
+            }
+        }
+
+        // 参数
+        {
+            uint32_t n = 0; if (!read_pod(is, n)) return fail("read params count");
+            out.m_params.clear(); out.m_params.reserve(n);
+            for (uint32_t i = 0; i < n; ++i) {
+                PJParam p;
+                if (!read_string(is, p.name))  return fail("read param name");
+                if (!read_string(is, p.value)) return fail("read param value");
+                out.m_params.emplace_back(std::move(p));
+            }
+        }
+
+        // 暂停事件
+        if (!read_vec<uint32_t>(is, out.m_pauseEvents)) return fail("read pauseEvents");
+
+        // 启动策略 & 状态
+        uint8_t startPolicy = 0, st = 0;
+        if (!read_pod(is, startPolicy)) return fail("read startPolicy");
+        if (!read_pod(is, st))          return fail("read state");
+        out.m_startPolicy = static_cast<StartPolicy>(startPolicy);
+        out.m_state = static_cast<PJState>(st);
+
+        // 失败原因
+        if (!read_string(is, out.m_failReason)) return fail("read failReason");
+
+        // 时间戳
+        if (!read_opt_time(is, out.m_tQueued)) return fail("read tQueued");
+        if (!read_opt_time(is, out.m_tStart))  return fail("read tStart");
+        if (!read_opt_time(is, out.m_tEnd))    return fail("read tEnd");
+
+        return true;
+    }
+
+    std::string CProcessJob::getStateText()
+    {
+        switch (m_state)
+        {
+        case SERVO::PJState::NoState:
+            return "NoState";
+            break;
+        case SERVO::PJState::Queued:
+            return "Queued";
+            break;
+        case SERVO::PJState::SettingUp:
+            return "SettingUp";
+            break;
+        case SERVO::PJState::InProcess:
+            return "InProcess";
+            break;
+        case SERVO::PJState::Paused:
+            return "Paused";
+            break;
+        case SERVO::PJState::Aborting:
+            return "Aborting";
+            break;
+        case SERVO::PJState::Completed:
+            return "Completed";
+            break;
+        case SERVO::PJState::Aborted:
+            return "Aborted";
+            break;
+        case SERVO::PJState::Failed:
+            return "Failed";
+            break;
+        default:
+            break;
+        }
+
+        return "";
+    }
+
+    CarrierSlotInfo* CProcessJob::getCarrier(const  std::string& strId)
+    {
+        for (auto& item : m_carriers) {
+            if (item.carrierId.compare(strId) == 0) {
+                return &item;
+            }
+        }
+
+        return nullptr;
+    }
+
+    void CProcessJob::setLotId(std::string strLotId)
+    {
+        m_strLotId = strLotId;
+    }
+
+    std::string& CProcessJob::getLotId()
+    {
+        return m_strLotId;
+    }
+
+    void CProcessJob::setProductId(std::string strProductId)
+    {
+        m_strProductId = strProductId;
+    }
+
+    std::string& CProcessJob::getProductId()
+    {
+        return m_strProductId;
+    }
+
+    void CProcessJob::setOperationId(std::string strOperationId)
+    {
+        m_strOperationId = strOperationId;
+    }
+
+    std::string& CProcessJob::getOperationId()
+    {
+        return m_strOperationId;
+    }
+
+    void CProcessJob::setPjWarp(PJWarp pjWarp)
+    {
+        m_pjWarp = pjWarp;
+    }
+
+    PJWarp& CProcessJob::getPjWarp()
+    {
+        return m_pjWarp;
+    }
 }

--
Gitblit v1.9.3