LAPTOP-SNT8I5JK\Boounion
2025-09-10 296cead8add8a66a00aa1ea07c19c1039d098c3b
SourceCode/Bond/Servo/CPageGlassList.cpp
@@ -8,6 +8,7 @@
#include "GlassJson.h"
#include "CServoUtilsTool.h"
#include "ToolUnits.h"
#include <optional>
#define PAGE_SIZE                  10
@@ -207,23 +208,29 @@
void CPageGlassList::UpdatePageData()
{
   // 如果为第1页, 取出缓存Glass, 符合条件则显示;
   m_listCtrl.DeleteAllItems();
   UpdateWipData();
   // 查询
   auto& db = GlassLogDb::Instance();
   auto page = db.queryPaged(m_filters, PAGE_SIZE, PAGE_SIZE * (m_nCurPage - 1));
   m_listCtrl.DeleteAllItems();
   for (const auto& r : page.items) {
      int index = m_listCtrl.InsertItem(m_listCtrl.GetItemCount(), std::to_string(r.id).c_str());
      m_listCtrl.SetItemText(index, 1, std::to_string(r.cassetteSeqNo).c_str());
      m_listCtrl.SetItemText(index, 2, std::to_string(r.jobSeqNo).c_str());
      m_listCtrl.SetItemText(index, 3, r.classId.c_str());
      m_listCtrl.SetItemText(index, 4, SERVO::CServoUtilsTool::getMaterialsTypeText((SERVO::MaterialsType)r.materialType).c_str());
      m_listCtrl.SetItemText(index, 5, SERVO::CServoUtilsTool::getGlassStateText((SERVO::GlsState)r.state).c_str());
      m_listCtrl.SetItemText(index, 6, r.tStart.c_str());
      m_listCtrl.SetItemText(index, 7, r.tEnd.c_str());
      m_listCtrl.SetItemText(index, 8, r.buddyId.c_str());
      m_listCtrl.SetItemText(index, 9, SERVO::CServoUtilsTool::getInspResultText((SERVO::InspResult)r.aoiResult).c_str());
      m_listCtrl.SetItemText(index, 10, r.path.c_str());
      m_listCtrl.SetItemText(index, 11, r.params.c_str());
      int index = m_listCtrl.InsertItem(m_listCtrl.GetItemCount(), "");
      m_listCtrl.SetItemText(index, 1, std::to_string(r.id).c_str());
      m_listCtrl.SetItemText(index, 2, std::to_string(r.cassetteSeqNo).c_str());
      m_listCtrl.SetItemText(index, 3, std::to_string(r.jobSeqNo).c_str());
      m_listCtrl.SetItemText(index, 4, r.classId.c_str());
      m_listCtrl.SetItemText(index, 5, SERVO::CServoUtilsTool::getMaterialsTypeText((SERVO::MaterialsType)r.materialType).c_str());
      m_listCtrl.SetItemText(index, 6, SERVO::CServoUtilsTool::getGlassStateText((SERVO::GlsState)r.state).c_str());
      m_listCtrl.SetItemText(index, 7, r.tStart.c_str());
      m_listCtrl.SetItemText(index, 8, r.tEnd.c_str());
      m_listCtrl.SetItemText(index, 9, r.buddyId.c_str());
      m_listCtrl.SetItemText(index, 10, SERVO::CServoUtilsTool::getInspResultText((SERVO::InspResult)r.aoiResult).c_str());
      m_listCtrl.SetItemText(index, 11, r.path.c_str());
      m_listCtrl.SetItemText(index, 12, r.params.c_str());
      m_listCtrl.SetItemColor(index, RGB(0, 0, 0), index % 2 == 0 ? RGB(255, 255, 255) : RGB(235, 235, 235));
      // 测试反序列化
      /*
@@ -237,6 +244,42 @@
   // 上一页 / 下一页
   UpdatePageControls();
}
void CPageGlassList::UpdateWipData()
{
   if (m_nCurPage != 1) return;
   // 取出缓存Glass, 符合条件则显示;
   // 但要删除旧的数据
   std::vector<SERVO::CGlass*> wipGlasses;
   theApp.m_model.m_master.getWipGlasses(wipGlasses);
   std::vector<SERVO::CGlass*> tempGlasses = wipGlasses;
   int count = m_listCtrl.GetItemCount();
   if (count > 0) {
      for (int i = count - 1; i >= 0; i--) {
         SERVO::CGlass* pGlass = (SERVO::CGlass*)m_listCtrl.GetItemData(i);
         if (eraseGlassInVector(pGlass, wipGlasses)
            && GlassMatchesFilters(*pGlass, m_filters)) {
            // 更新
            UpdateWipRow(i, pGlass);
         }
         else {
            // 删除
            m_listCtrl.DeleteItem(i);
         }
      }
   }
   // 剩下的如符号插入
   for (auto* item : wipGlasses) {
      if (GlassMatchesFilters(*item, m_filters)) {
         InsertWipRow(item);
      }
   }
   for (auto* item : tempGlasses) {
      item->release();
   }
}
void CPageGlassList::UpdatePageControls()
@@ -256,6 +299,7 @@
   // TODO:  在此添加额外的初始化
   SetTimer(1, 3000, nullptr);
   SetTimer(2, 2000, nullptr);
   // 下拉框控件
   InitStatusCombo();
@@ -277,6 +321,7 @@
   ListView_SetImageList(m_listCtrl.GetSafeHwnd(), imageList, LVSIL_SMALL);
   CString headers[] = { 
      _T(""),
      _T("id"), 
      _T("Cassette Sequence No"),
      _T("Job Sequence No"),
@@ -290,11 +335,11 @@
      _T("路径"),
      _T("工艺参数") 
   };
   int widths[] = { 80, 80, 80, 100, 120, 120, 120, 120, 200, 200, 200, 200 };
   int widths[] = { 0, 80, 80, 80, 100, 120, 120, 120, 120, 200, 200, 200, 200 };
   for (int i = 0; i < _countof(headers); ++i) {
      strItem.Format(_T("Col_%d_Width"), i);
      widths[i] = GetPrivateProfileInt("GlassListCtrl", strItem, widths[i], strIniFile);
      m_listCtrl.InsertColumn(i, headers[i], LVCFMT_LEFT, widths[i]);
      m_listCtrl.InsertColumn(i, headers[i], i == 0 ? LVCFMT_RIGHT : LVCFMT_LEFT, widths[i]);
   }
   Resize();
@@ -354,6 +399,11 @@
      KillTimer(1);
      InitRxWindow();
   }
   else if (nIDEvent == 2) {
      UpdateWipData();
   }
   CDialogEx::OnTimer(nIDEvent);
}
@@ -464,4 +514,72 @@
      m_nCurPage++;
      UpdatePageData();
   }
}
// 核心:WIP 的 CGlass 是否命中当前 Filters
// useEndTime=true 时用 tEnd 判时间(比如“完成列表”用 t_end),默认按 tStart。
bool CPageGlassList::GlassMatchesFilters(const SERVO::CGlass& g,
   const GlassLogDb::Filters& f,
   bool useEndTime/* = false*/)
{
   // 1) 精确字段
   if (f.classId && g.getID() != *f.classId)      return false;
   if (f.cassetteSeqNo && g.getCassetteSequenceNo() != *f.cassetteSeqNo)return false;
   if (f.jobSeqNo && g.getJobSequenceNo() != *f.jobSeqNo)     return false;
   // 2) 关键字(与 DB 保持一致:class_id / buddy_id / path / params / pretty)
   if (f.keyword) {
      const std::string& kw = *f.keyword;
      if (!(CToolUnits::containsCI(g.getID(), kw)
         || CToolUnits::containsCI(g.getBuddyId(), kw)
         || CToolUnits::containsCI(g.getPathDescription(), kw)
         || CToolUnits::containsCI(g.getParamsDescription(), kw)))
         return false;
   }
   // 3) 时间(与 DB 保持一致:默认按 t_start 过滤;需要可切到 t_end)
   if (f.tStartFrom || f.tStartTo) {
      std::optional<std::chrono::system_clock::time_point> tp = useEndTime ? g.tEnd() : g.tStart();
      // 约定:若没有对应时间戳,则视为不命中(与 DB 相同:NULL 不会命中范围)
      if (!tp) return false;
      if (f.tStartFrom && *tp < *f.tStartFrom) return false;
      if (f.tStartTo && *tp > *f.tStartTo)   return false;
   }
   return true;
}
void CPageGlassList::InsertWipRow(SERVO::CGlass* pGlass)
{
   int index = m_listCtrl.InsertItem(0, "");
   m_listCtrl.SetItemColor(index, RGB(0, 0, 0), RGB(201, 228, 180));
   UpdateWipRow(index, pGlass);
}
void CPageGlassList::UpdateWipRow(unsigned int index, SERVO::CGlass* pGlass)
{
   ASSERT(index < m_listCtrl.GetItemCount());
   m_listCtrl.SetItemData(index, (DWORD_PTR)pGlass);
   m_listCtrl.SetItemText(index, 2, std::to_string(pGlass->getCassetteSequenceNo()).c_str());
   m_listCtrl.SetItemText(index, 3, std::to_string(pGlass->getJobSequenceNo()).c_str());
   m_listCtrl.SetItemText(index, 4, pGlass->getID().c_str());
   m_listCtrl.SetItemText(index, 5, SERVO::CServoUtilsTool::getMaterialsTypeText(pGlass->getType()).c_str());
   m_listCtrl.SetItemText(index, 6, SERVO::CServoUtilsTool::getGlassStateText(pGlass->state()).c_str());
   m_listCtrl.SetItemText(index, 7, CToolUnits::TimePointToLocalString(pGlass->tStart()).c_str());
   m_listCtrl.SetItemText(index, 8, CToolUnits::TimePointToLocalString(pGlass->tEnd()).c_str());
   m_listCtrl.SetItemText(index, 9, pGlass->getBuddyId().c_str());
   m_listCtrl.SetItemText(index, 10, SERVO::CServoUtilsTool::getInspResultText((SERVO::InspResult)pGlass->getAOIInspResult()).c_str());
   m_listCtrl.SetItemText(index, 11, pGlass->getPathDescription().c_str());
   m_listCtrl.SetItemText(index, 12, pGlass->getParamsDescription().c_str());
}
bool CPageGlassList::eraseGlassInVector(SERVO::CGlass* pGlass, std::vector<SERVO::CGlass*>& glasses)
{
   auto iter = std::find(glasses.begin(), glasses.end(), pGlass);
   if (iter != glasses.end()) {
      glasses.erase(iter);
      return true;
   }
   return false;
}