| 2025-06-05 | LAPTOP-SNT8I5JK\Boounion | ![]() |
| 2025-06-04 | mrDarker | ![]() |
| 2025-06-04 | mrDarker | ![]() |
| 2025-06-03 | mrDarker | ![]() |
| 2025-05-30 | mrDarker | ![]() |
SourceCode/Bond/Servo/CMaster.cpp
@@ -669,7 +669,7 @@ lock(); if (m_listener.onRobotTaskEvent != nullptr) { m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, 0); m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, 1); } delete m_pActiveRobotTask; m_pActiveRobotTask = nullptr; SourceCode/Bond/Servo/CRobotTask.cpp
@@ -8,7 +8,7 @@ { generateId(m_strId); m_state = ROBOT_TASK_STATE::Ready; m_timeCreate = CToolUnits::getTimestamp(); m_timeCreate = CToolUnits::getUnixTimestamp(); m_timeFetchOut = 0; m_timeStored = 0; m_timeFinish = 0; @@ -176,11 +176,11 @@ void CRobotTask::fetchOut() { m_timeFetchOut = CToolUnits::getTimestamp();; m_timeFetchOut = CToolUnits::getUnixTimestamp();; } void CRobotTask::stored() { m_timeStored = CToolUnits::getTimestamp();; m_timeStored = CToolUnits::getUnixTimestamp();; } } SourceCode/Bond/Servo/Common.h
@@ -483,3 +483,8 @@ #define RT_REQUEST_FROM_EAS 4 /* Robot Task Status */ #define ROBOT_EVENT_CREATE 0 // æ°ä»»å¡å建 #define ROBOT_EVENT_FINISH 1 // æ£å¸¸å®æ #define ROBOT_EVENT_ERROR 2 // åºç°é误 #define ROBOT_EVENT_ABORT 3 // äººä¸ºä¸æ¢ SourceCode/Bond/Servo/Model.cpp
@@ -6,6 +6,7 @@ #include "CEqAlarmStep.h" #include "AlarmManager.h" #include "CGlassPool.h" #include "TransferManager.h" CModel::CModel() @@ -171,7 +172,84 @@ notifyPtr(RX_CODE_EQ_DATA_CHANGED, pEquipment); }; masterListener.onRobotTaskEvent = [&](void* pMaster, SERVO::CRobotTask* pTask, int code) { if (pTask == nullptr) { LOGE("<CModel>onRobotTaskEvent: ç©ºä»»å¡æéï¼å¿½ç¥äºä»¶ code=%d", code); return; } // ä»»å¡æè¿°ä¸ ID ç¨äºæ¥å¿ const std::string& strDesc = pTask->getDescription(); const std::string& strClassID = pTask->getId(); // æ¥å¿è¾åºä¸ç¶æå¤ç switch (code) { case ROBOT_EVENT_CREATE: LOGI("<CModel>onRobotTaskEvent: æ°ä»»å¡å建(%s, ClassID=%s).", strDesc.c_str(), strClassID.c_str()); break; case ROBOT_EVENT_FINISH: LOGI("<CModel>onRobotTaskEvent: ä»»å¡å®æ(%s, ClassID=%s).", strDesc.c_str(), strClassID.c_str()); pTask->completed(); break; case ROBOT_EVENT_ERROR: LOGE("<CModel>onRobotTaskEvent: ä»»å¡é误(%s, ClassID=%s).", strDesc.c_str(), strClassID.c_str()); pTask->error(); break; case ROBOT_EVENT_ABORT: LOGE("<CModel>onRobotTaskEvent: ä»»å¡åæ¢(%s, ClassID=%s).", strDesc.c_str(), strClassID.c_str()); pTask->abort(); break; default: LOGE("<CModel>onRobotTaskEvent: æªç¥äºä»¶ code=%d, ä»»å¡=%s", code, strDesc.c_str()); break; } // å®å ¨æ ¼å¼åæ¶é´ auto format_time = [](time_t t) -> std::string { if (t < 0 || t == _I64_MIN || t == _I64_MAX) { return ""; } // ä½¿ç¨ localtime_s ç¡®ä¿çº¿ç¨å®å ¨ tm tmBuf{}; errno_t err = localtime_s(&tmBuf, &t); if (err != 0 || tmBuf.tm_mon < 0 || tmBuf.tm_mon > 11) { return ""; } // æ ¼å¼åæ¶é´å符串 char buf[64] = {}; strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tmBuf); return std::string(buf); }; // æé TransferData æ°æ®ç»æ TransferData data; data.strClassID = strClassID; data.strCreateTime = format_time(pTask->getCreateTime()); data.strPickTime = format_time(pTask->getFetchoutTime()); data.strPlaceTime = format_time(pTask->getStoredTime()); data.strEndTime = format_time(pTask->getFinishTime()); data.strDescription = pTask->getSimpleDescription(); // ç¶ææ å° static const char* STATUS_STR[] = { "Unknown", "Ready", "Running", "Error", "Abort", "Completed" }; auto state = pTask->getState(); int index = static_cast<int>(state); if (index > 0 && index < static_cast<int>(std::size(STATUS_STR))) { data.strStatus = STATUS_STR[index]; } else { data.strStatus = STATUS_STR[0]; } // åå ¥æ°æ®åº int nRecordId = 0; TransferManager::getInstance().addTransferRecord(data, nRecordId); notifyPtr(RX_CODE_EQ_ROBOT_TASK, pTask); LOGI("<CModel>onRobotTaskEvent: ä»»å¡è®°å½å·²ä¿åï¼RecordID=%d", nRecordId); }; m_master.setListener(masterListener); SourceCode/Bond/Servo/PageAlarm.cpp
@@ -39,6 +39,13 @@ CPageAlarm::~CPageAlarm() { if (m_hbrBkgnd != nullptr) { ::DeleteObject(m_hbrBkgnd); } if (m_pObserver != nullptr) { m_pObserver->unsubscribe(); m_pObserver = nullptr; } } void CPageAlarm::InitRxWindow() SourceCode/Bond/Servo/PageTransferLog.cpp
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,495 @@ // PageTransferLog.cpp: å®ç°æä»¶ // #include "stdafx.h" #include "Servo.h" #include "afxdialogex.h" #include "PageTransferLog.h" #include "Common.h" #define PAGE_SIZE 100 #define PAGE_BACKGROUND_COLOR RGB(252, 252, 255) // CPageTransferLog å¯¹è¯æ¡ IMPLEMENT_DYNAMIC(CPageTransferLog, CDialogEx) CPageTransferLog::CPageTransferLog(CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_PAGE_TRANSFER_LOG, pParent) { m_crBkgnd = PAGE_BACKGROUND_COLOR; m_hbrBkgnd = nullptr; m_pObserver = nullptr; m_strStatus = ""; m_strKeyword = ""; m_nCurPage = 0; m_nTotalPages = 0; memset(m_szTimeStart, 0, sizeof(m_szTimeStart)); memset(m_szTimeEnd, 0, sizeof(m_szTimeEnd)); m_szTimeStart[0] = '\0'; m_szTimeEnd[0] = '\0'; } CPageTransferLog::~CPageTransferLog() { if (m_hbrBkgnd != nullptr) { ::DeleteObject(m_hbrBkgnd); } if (m_pObserver != nullptr) { m_pObserver->unsubscribe(); m_pObserver = nullptr; } } void CPageTransferLog::DoDataExchange(CDataExchange* pDX) { DDX_Control(pDX, IDC_DATETIMEPICKER_START, m_dateTimeStart); DDX_Control(pDX, IDC_DATETIMEPICKER_END, m_dateTimeEnd); DDX_Control(pDX, IDC_LIST_ALARM, m_listCtrl); CDialogEx::DoDataExchange(pDX); } void CPageTransferLog::InitRxWindow() { /* code */ // è®¢é æ°æ® IRxWindows* pRxWindows = RX_GetRxWindows(); pRxWindows->enableLog(5); if (m_pObserver == NULL) { m_pObserver = pRxWindows->allocObserver([&](IAny* pAny) -> void { // onNext pAny->addRef(); int code = pAny->getCode(); if (RX_CODE_EQ_ROBOT_TASK == code) { UpdatePageData(); } pAny->release(); }, [&]() -> void { // onComplete }, [&](IThrowable* pThrowable) -> void { // onErrorm pThrowable->printf(); }); theApp.m_model.getObservable()->observeOn(pRxWindows->mainThread())->subscribe(m_pObserver); } } void CPageTransferLog::Resize() { CRect rcClient; GetClientRect(&rcClient); // ===== 常éå®ä¹ ===== const int nLeft = 12; const int nRight = 12; const int nTop = 58; const int nButtonHeight = 28; const int nButtonMarginBottom = 12; const int nSpacing = 8; const int nButtonWidth = 80; const int nLabelWidth = 100; // ===== å页æ§ä»¶å¸å± ===== int yBottom = rcClient.bottom - nButtonMarginBottom - nButtonHeight; int xRight = rcClient.Width() - nRight; CWnd* pBtnNext = GetDlgItem(IDC_BUTTON_NEXT_PAGE); CWnd* pBtnPrev = GetDlgItem(IDC_BUTTON_PREV_PAGE); CWnd* pLabelPage = GetDlgItem(IDC_LABEL_PAGE_NUMBER); if (pBtnNext && pBtnPrev && pLabelPage) { // è·ååé¡µææ¬å®½åº¦ä¼°ç® //CString strLabel; //GetDlgItemText(IDC_LABEL_PAGE_NUMBER, strLabel); //if (strLabel.IsEmpty()) { // strLabel = _T("第 1 / 1 页"); //} //int nCharWidth = 8; //int nLabelWidth = strLabel.GetLength() * nCharWidth + 20; // 设置æé®åæ ç¾ä½ç½® pBtnNext->MoveWindow(xRight - nButtonWidth, yBottom, nButtonWidth, nButtonHeight); xRight -= nButtonWidth + nSpacing; pLabelPage->MoveWindow(xRight - nLabelWidth, yBottom, nLabelWidth, nButtonHeight); xRight -= nLabelWidth + nSpacing; pBtnPrev->MoveWindow(xRight - nButtonWidth, yBottom, nButtonWidth, nButtonHeight); } // ===== è¡¨æ ¼åºåå¸å± ===== if (nullptr != m_listCtrl.m_hWnd) { int listHeight = yBottom - nTop - nSpacing; m_listCtrl.MoveWindow(nLeft, nTop, rcClient.Width() - nLeft - nRight, listHeight); } } void CPageTransferLog::InitStatusCombo() { CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_STATUS_FILTER); if (nullptr != pComboBox) { pComboBox->ResetContent(); pComboBox->AddString(_T("å ¨é¨")); pComboBox->AddString(_T("Ready")); pComboBox->AddString(_T("Running")); pComboBox->AddString(_T("Error")); pComboBox->AddString(_T("Abort")); pComboBox->AddString(_T("Completed")); pComboBox->SetCurSel(0); } } void CPageTransferLog::InitTimeRangeCombo() { CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_DATETIME); if (nullptr != pComboBox) { pComboBox->ResetContent(); pComboBox->AddString(_T("ä¸é")); pComboBox->AddString(_T("ä»å¤©")); pComboBox->AddString(_T("ä¸å¤©å ")); pComboBox->AddString(_T("æ¬æ")); pComboBox->AddString(_T("ä»å¹´")); pComboBox->AddString(_T("èªå®ä¹")); pComboBox->SetCurSel(0); } } void CPageTransferLog::InitDateTimeControls() { if (m_dateTimeStart.m_hWnd == nullptr || m_dateTimeEnd.m_hWnd == nullptr) { return; } // ç¦ç¨åå§ç¶æ m_dateTimeStart.EnableWindow(FALSE); m_dateTimeEnd.EnableWindow(FALSE); // è®¾ç½®æ ¼å¼ï¼æ¾ç¤ºæ¥æ + æ¶é´ //m_dateTimeStart.SetFormat(_T("yyyy/MM/dd HH:mm:ss")); //m_dateTimeEnd.SetFormat(_T("yyyy/MM/dd HH:mm:ss")); // ä¿®æ¹æ ·å¼ä»¥æ¯ææ¶é´æ ¼å¼ //DWORD dwStyleStart = m_dateTimeStart.GetStyle(); //DWORD dwStyleEnd = m_dateTimeEnd.GetStyle(); //m_dateTimeStart.ModifyStyle(0, DTS_TIMEFORMAT | DTS_UPDOWN); //m_dateTimeEnd.ModifyStyle(0, DTS_TIMEFORMAT); } void CPageTransferLog::LoadTransfers() { m_nCurPage = 1; UpdatePageData(); } void CPageTransferLog::UpdatePageData() { TransferData filter; filter.strStatus = m_strStatus; filter.strDescription = m_strKeyword; filter.strCreateTime = m_szTimeStart; filter.strEndTime = m_szTimeEnd; auto vecData = TransferManager::getInstance().getTransfers(filter, m_nCurPage, PAGE_SIZE); FillDataToListCtrl(vecData); int nTotalRecords = TransferManager::getInstance().getFilteredTransferCount(filter); m_nTotalPages = (nTotalRecords + PAGE_SIZE - 1) / PAGE_SIZE; UpdatePageControls(); } void CPageTransferLog::UpdatePageControls() { CString strPage; strPage.Format(_T("第 %d / %d 页"), m_nCurPage, m_nTotalPages); SetDlgItemText(IDC_LABEL_PAGE_NUMBER, strPage); GetDlgItem(IDC_BUTTON_PREV_PAGE)->EnableWindow(m_nCurPage > 1); GetDlgItem(IDC_BUTTON_NEXT_PAGE)->EnableWindow(m_nCurPage < m_nTotalPages); Resize(); } void CPageTransferLog::UpdateDateFilter() { CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_DATETIME); if (nullptr != pComboBox) { int nIndex = pComboBox->GetCurSel(); if (nIndex == 0) { memset(m_szTimeStart, 0, sizeof(m_szTimeStart)); memset(m_szTimeEnd, 0, sizeof(m_szTimeEnd)); m_szTimeStart[0] = '\0'; m_szTimeEnd[0] = '\0'; } else { CTime time = CTime::GetCurrentTime(); if (nIndex == 1) { sprintf_s(m_szTimeStart, 64, "%d-%02d-%02d 00:00:00", time.GetYear(), time.GetMonth(), time.GetDay()); sprintf_s(m_szTimeEnd, 64, "%d-%02d-%02d 23:59:59", time.GetYear(), time.GetMonth(), time.GetDay()); } else if (nIndex == 2) { CTime time2 = time - CTimeSpan(7, 0, 0, 0); sprintf_s(m_szTimeStart, 64, "%d-%02d-%02d 00:00:00", time2.GetYear(), time2.GetMonth(), time2.GetDay()); sprintf_s(m_szTimeEnd, 64, "%d-%02d-%02d 23:59:59", time.GetYear(), time.GetMonth(), time.GetDay()); } else if (nIndex == 3) { sprintf_s(m_szTimeStart, 64, "%d-%02d-01 00:00:00", time.GetYear(), time.GetMonth()); sprintf_s(m_szTimeEnd, 64, "%d-%02d-%02d 23:59:59", time.GetYear(), time.GetMonth(), time.GetDay()); } else if (nIndex == 4) { sprintf_s(m_szTimeStart, 64, "%d-01-01 00:00:00", time.GetYear()); sprintf_s(m_szTimeEnd, 64, "%d-12-31 23:59:59", time.GetYear()); } else if (nIndex == 5) { SYSTEMTIME t1, t2; m_dateTimeStart.GetTime(&t1); m_dateTimeEnd.GetTime(&t2); //sprintf_s(m_szTimeStart, 64, "%d-%02d-%02d %02d:%02d:%02d", t1.wYear, t1.wMonth, t1.wDay, t1.wHour, t1.wMinute, t1.wSecond); //sprintf_s(m_szTimeEnd, 64, "%d-%02d-%02d %02d:%02d:%02d", t2.wYear, t2.wMonth, t2.wDay, t2.wHour, t2.wMinute, t2.wSecond); sprintf_s(m_szTimeStart, 64, "%d-%02d-%02d 00:00:00", t1.wYear, t1.wMonth, t1.wDay); sprintf_s(m_szTimeEnd, 64, "%d-%02d-%02d 23:59:59", t2.wYear, t2.wMonth, t2.wDay); } } } } void CPageTransferLog::FillDataToListCtrl(const std::vector<TransferData>& vecData) { if (m_listCtrl.m_hWnd == nullptr) { return; } m_listCtrl.DeleteAllItems(); for (const auto& item : vecData) { InsertTransferData(item); } } void CPageTransferLog::InsertTransferData(const TransferData& data) { if (m_listCtrl.m_hWnd == nullptr) { return; } int nItem = m_listCtrl.InsertItem(0, _T("")); CString str; str.Format(_T("%d"), data.nRecordId); m_listCtrl.SetItemText(nItem, 1, str); m_listCtrl.SetItemText(nItem, 2, CString(data.strStatus.c_str())); m_listCtrl.SetItemText(nItem, 3, CString(data.strClassID.c_str())); m_listCtrl.SetItemText(nItem, 4, CString(data.strCreateTime.c_str())); m_listCtrl.SetItemText(nItem, 5, CString(data.strPickTime.c_str())); m_listCtrl.SetItemText(nItem, 6, CString(data.strPlaceTime.c_str())); m_listCtrl.SetItemText(nItem, 7, CString(data.strEndTime.c_str())); m_listCtrl.SetItemText(nItem, 8, CString(data.strDescription.c_str())); } BEGIN_MESSAGE_MAP(CPageTransferLog, CDialogEx) ON_WM_CTLCOLOR() ON_WM_DESTROY() ON_WM_SIZE() ON_WM_TIMER() ON_CBN_SELCHANGE(IDC_COMBO_DATETIME, &CPageTransferLog::OnCbnSelchangeComboDatetime) ON_CBN_SELCHANGE(IDC_COMBO_STATUS_FILTER, &CPageTransferLog::OnCbnSelchangeComboStatusFilter) ON_BN_CLICKED(IDC_BUTTON_SEARCH, &CPageTransferLog::OnBnClickedButtonSearch) ON_BN_CLICKED(IDC_BUTTON_EXPORT, &CPageTransferLog::OnBnClickedButtonExport) ON_BN_CLICKED(IDC_BUTTON_PREV_PAGE, &CPageTransferLog::OnBnClickedButtonPrevPage) ON_BN_CLICKED(IDC_BUTTON_NEXT_PAGE, &CPageTransferLog::OnBnClickedButtonNextPage) END_MESSAGE_MAP() // CPageTransferLog æ¶æ¯å¤çç¨åº BOOL CPageTransferLog::OnInitDialog() { CDialogEx::OnInitDialog(); // TODO: 卿¤æ·»å é¢å¤çåå§å SetTimer(1, 3000, nullptr); // ä¸ææ¡æ§ä»¶ InitStatusCombo(); InitTimeRangeCombo(); // æ¥ææ§ä»¶ InitDateTimeControls(); // æ¥è¡¨æ§ä»¶ DWORD dwStyle = m_listCtrl.GetExtendedStyle(); dwStyle |= LVS_EX_FULLROWSELECT; dwStyle |= LVS_EX_GRIDLINES; m_listCtrl.SetExtendedStyle(dwStyle); HIMAGELIST imageList = ImageList_Create(24, 24, ILC_COLOR24, 1, 1); ListView_SetImageList(m_listCtrl.GetSafeHwnd(), imageList, LVSIL_SMALL); CString headers[] = { _T(""), _T("ä»»å¡ID"), _T("ç¶æ"), _T("ClassID"), _T("å建æ¶é´"), _T("åçæ¶é´"), _T("æ¾çæ¶é´"), _T("ç»ææ¶é´"), _T("æè¿°") }; int widths[] = { 0, 80, 80, 100, 120, 120, 120, 120, 200 }; for (int i = 0; i < 9; ++i) { m_listCtrl.InsertColumn(i, headers[i], LVCFMT_LEFT, widths[i]); } m_listCtrl.SetColumnWidth(8, LVSCW_AUTOSIZE_USEHEADER); // 读åºå宽 CString strIniFile, strItem; strIniFile.Format(_T("%s\\configuration.ini"), (LPTSTR)(LPCTSTR)theApp.m_strAppDir); int width[8] = { 0, 80, 180, 80, 80, 100, 80, 180 }; for (int i = 0; i < 8; i++) { strItem.Format(_T("Col_%d_Width"), i); width[i] = GetPrivateProfileInt("TransferListCtrl", strItem, width[i], strIniFile); } // è®¡ç®æ»é¡µæ° int nTotalRecords = TransferManager::getInstance().getTotalTransferCountAll(); m_nTotalPages = (nTotalRecords + PAGE_SIZE - 1) / PAGE_SIZE; m_nCurPage = 1; Resize(); LoadTransfers(); return TRUE; // return TRUE unless you set the focus to a control // å¼å¸¸: OCX 屿§é¡µåºè¿å FALSE } HBRUSH CPageTransferLog::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { if (nCtlColor == CTLCOLOR_STATIC) { pDC->SetBkColor(m_crBkgnd); } if (m_hbrBkgnd == nullptr) { m_hbrBkgnd = CreateSolidBrush(m_crBkgnd); } return m_hbrBkgnd; } void CPageTransferLog::OnDestroy() { CDialogEx::OnDestroy(); if (m_hbrBkgnd != nullptr) { ::DeleteObject(m_hbrBkgnd); m_hbrBkgnd = nullptr; } if (m_pObserver != nullptr) { m_pObserver->unsubscribe(); m_pObserver = nullptr; } // ä¿åå宽 CString strIniFile, strItem, strTemp; strIniFile.Format(_T("%s\\configuration.ini"), (LPTSTR)(LPCTSTR)theApp.m_strAppDir); CHeaderCtrl* pHeader = m_listCtrl.GetHeaderCtrl(); for (int i = 0; i < pHeader->GetItemCount(); i++) { RECT rect; pHeader->GetItemRect(i, &rect); strItem.Format(_T("Col_%d_Width"), i); strTemp.Format(_T("%d"), rect.right - rect.left); WritePrivateProfileString("TransferListCtrl", strItem, strTemp, strIniFile); } } void CPageTransferLog::OnSize(UINT nType, int cx, int cy) { CDialogEx::OnSize(nType, cx, cy); Resize(); } void CPageTransferLog::OnTimer(UINT_PTR nIDEvent) { if (nIDEvent == 1) { KillTimer(1); InitRxWindow(); } CDialogEx::OnTimer(nIDEvent); } void CPageTransferLog::OnCbnSelchangeComboDatetime() { CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_DATETIME); int nIndex = pComboBox->GetCurSel(); int nCount = pComboBox->GetCount(); m_dateTimeStart.EnableWindow(nIndex == nCount - 1); m_dateTimeEnd.EnableWindow(nIndex == nCount - 1); // æ´æ°æ¥æè¿æ»¤å¨å页颿°æ® UpdateDateFilter(); LoadTransfers(); } void CPageTransferLog::OnCbnSelchangeComboStatusFilter() { CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_STATUS_FILTER); int nIndex = pComboBox->GetCurSel(); if (nIndex == 0) { m_strStatus.clear(); } else { CString cstrText; pComboBox->GetLBText(nIndex, cstrText); m_strStatus = CT2A(cstrText); } LoadTransfers(); } void CPageTransferLog::OnBnClickedButtonSearch() { // è·åå ³é®åè¾å ¥æ¡å 容 CString strKeyword; GetDlgItemText(IDC_EDIT_KEYWORD, strKeyword); m_strKeyword = CT2A(strKeyword); // æ´æ°æ¥æè¿æ»¤å¨å页颿°æ® UpdateDateFilter(); LoadTransfers(); } void CPageTransferLog::OnBnClickedButtonExport() { CFileDialog fileDialog(FALSE, _T("csv"), NULL, OFN_HIDEREADONLY, _T("CSV Files (*.csv)|*.csv||")); if (fileDialog.DoModal() != IDOK) { return; } CStdioFile file; if (!file.Open(fileDialog.GetPathName(), CFile::modeCreate | CFile::modeWrite | CFile::typeText)) { AfxMessageBox(_T("å建æä»¶å¤±è´¥ï¼")); return; } CString strHeader = _T("ä»»å¡ID,ç¶æ,ClassID,å建æ¶é´,åçæ¶é´,æ¾çæ¶é´,ç»ææ¶é´,æè¿°\n"); file.WriteString(strHeader); for (int i = 0; i < m_listCtrl.GetItemCount(); ++i) { CString row; for (int j = 1; j <= 8; ++j) { row += m_listCtrl.GetItemText(i, j); if (j != 8) { row += ","; } } row += "\n"; file.WriteString(row); } file.Close(); } void CPageTransferLog::OnBnClickedButtonPrevPage() { if (m_nCurPage > 1) { m_nCurPage--; UpdatePageData(); } } void CPageTransferLog::OnBnClickedButtonNextPage() { if (m_nCurPage < m_nTotalPages) { m_nCurPage++; UpdatePageData(); } } SourceCode/Bond/Servo/PageTransferLog.h
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,70 @@ #pragma once #include "afxdialogex.h" #include "ListCtrlEx.h" #include "TransferManager.h" // CPageTransferLog å¯¹è¯æ¡ class CPageTransferLog : public CDialogEx { DECLARE_DYNAMIC(CPageTransferLog) public: CPageTransferLog(CWnd* pParent = nullptr); // æ åæé 彿° virtual ~CPageTransferLog(); private: COLORREF m_crBkgnd; HBRUSH m_hbrBkgnd; IObserver* m_pObserver; // æç´¢å ³é®å std::string m_strStatus; std::string m_strKeyword; // 页ç int m_nCurPage; int m_nTotalPages; // æ¥æ char m_szTimeStart[64]; char m_szTimeEnd[64]; // æ§ä»¶ CDateTimeCtrl m_dateTimeStart; CDateTimeCtrl m_dateTimeEnd; CListCtrlEx m_listCtrl; void InitRxWindow(); void Resize(); void InitStatusCombo(); void InitTimeRangeCombo(); void InitDateTimeControls(); void LoadTransfers(); void UpdatePageData(); void UpdatePageControls(); void UpdateDateFilter(); void FillDataToListCtrl(const std::vector<TransferData>& vecData); void InsertTransferData(const TransferData& data); // å¯¹è¯æ¡æ°æ® #ifdef AFX_DESIGN_TIME enum { IDD = IDD_PAGE_TRANSFER_LOG }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV æ¯æ virtual BOOL OnInitDialog(); afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor); afx_msg void OnDestroy(); afx_msg void OnSize(UINT nType, int cx, int cy); afx_msg void OnTimer(UINT_PTR nIDEvent); afx_msg void OnCbnSelchangeComboDatetime(); afx_msg void OnCbnSelchangeComboStatusFilter(); afx_msg void OnBnClickedButtonSearch(); afx_msg void OnBnClickedButtonExport(); afx_msg void OnBnClickedButtonPrevPage(); afx_msg void OnBnClickedButtonNextPage(); DECLARE_MESSAGE_MAP() }; SourceCode/Bond/Servo/Servo.rcBinary files differ
SourceCode/Bond/Servo/Servo.vcxproj
@@ -309,6 +309,7 @@ <ClInclude Include="MapPosWnd.h" /> <ClInclude Include="Model.h" /> <ClInclude Include="PageRobotCmd.h" /> <ClInclude Include="PageTransferLog.h" /> <ClInclude Include="PortConfigurationDlg.h" /> <ClInclude Include="ProductionLogManager.h" /> <ClInclude Include="Resource.h" /> @@ -435,6 +436,7 @@ <ClCompile Include="MapPosWnd.cpp" /> <ClCompile Include="Model.cpp" /> <ClCompile Include="PageRobotCmd.cpp" /> <ClCompile Include="PageTransferLog.cpp" /> <ClCompile Include="PortConfigurationDlg.cpp" /> <ClCompile Include="ProductionLogManager.cpp" /> <ClCompile Include="SECSRuntimeManager.cpp" /> SourceCode/Bond/Servo/Servo.vcxproj.filters
@@ -156,6 +156,7 @@ <ClCompile Include="CRobotTask.cpp" /> <ClCompile Include="CSlot.cpp" /> <ClCompile Include="CRobotTaskDlg.cpp" /> <ClCompile Include="PageTransferLog.cpp" /> </ItemGroup> <ItemGroup> <ClInclude Include="AlarmManager.h" /> @@ -317,6 +318,7 @@ <ClInclude Include="CRobotTask.h" /> <ClInclude Include="CSlot.h" /> <ClInclude Include="CRobotTaskDlg.h" /> <ClInclude Include="PageTransferLog.h" /> </ItemGroup> <ItemGroup> <ResourceCompile Include="Servo.rc" /> SourceCode/Bond/Servo/ToolUnits.cpp
@@ -74,11 +74,19 @@ ULONGLONG CToolUnits::getTimestamp() { // è¿åæ¯«ç§æ°ççæ¬ auto now = std::chrono::system_clock::now(); auto ms = std::chrono::time_point_cast<std::chrono::milliseconds>(now); return static_cast<ULONGLONG>(ms.time_since_epoch().count()); } time_t CToolUnits::getUnixTimestamp() { // è¿åç§æ°ççæ¬ auto now = std::chrono::system_clock::now(); return std::chrono::system_clock::to_time_t(now); } void CToolUnits::createDir(const char* pszDir) { if (isDirectory(std::string(pszDir))) { SourceCode/Bond/Servo/ToolUnits.h
@@ -15,6 +15,7 @@ static CString& floatToString1(float value, CString& strOut); static CString& floatToString3(float value, CString& strOut); static ULONGLONG getTimestamp(); static time_t getUnixTimestamp(); static void createDir(const char* pszDir); static BOOL copyTextToClipboard(CWnd* pWnd, const CString& strText); static std::string getCurrentExePath(); SourceCode/Bond/Servo/TransferManager.cpp
@@ -135,21 +135,37 @@ // æå ¥æµè¯æ¬è¿è®°å½ void TransferManager::insertTestTransferRecord() { TransferData data; data.strClassID = "Task-20240529-001"; data.strStatus = "Running"; data.strCreateTime = "2024-05-29 10:30:00"; data.strPickTime = "2024-05-29 10:31:00"; data.strPlaceTime = "2024-05-29 10:32:00"; data.strEndTime = "2024-05-29 10:33:00"; data.strDescription = "æ¬è¿å¨ä½ï¼ä» Port1 åç â Port2 æ¾ç"; if (nullptr != m_pDB) { int nCount = 10000; for (int i = 0; i < nCount; ++i) { TransferData data; data.strClassID = "T-" + std::to_string(1000 + i); data.strStatus = statusToString(static_cast<TransferStatus>(i % 5)); int nRecordId = -1; if (TransferManager::getInstance().addTransferRecord(data, nRecordId)) { std::cout << "æå ¥æåï¼è®°å½ ID = " << nRecordId << std::endl; } else { std::cerr << "æå ¥å¤±è´¥ï¼" << std::endl; std::time_t now = std::time(nullptr) + i * 60; // æ¯æ¡è®°å½é´é1åé std::tm tmCreate = {}, tmPick = {}, tmPlace = {}, tmEnd = {}; localtime_s(&tmCreate, &now); localtime_s(&tmPick, &(now += 60)); localtime_s(&tmPlace, &(now += 60)); localtime_s(&tmEnd, &(now += 60)); char szTime[64]; strftime(szTime, sizeof(szTime), "%Y-%m-%d %H:%M:%S", &tmCreate); data.strCreateTime = szTime; strftime(szTime, sizeof(szTime), "%Y-%m-%d %H:%M:%S", &tmPick); data.strPickTime = szTime; strftime(szTime, sizeof(szTime), "%Y-%m-%d %H:%M:%S", &tmPlace); data.strPlaceTime = szTime; strftime(szTime, sizeof(szTime), "%Y-%m-%d %H:%M:%S", &tmEnd); data.strEndTime = szTime; data.strDescription = "Mock transfer task " + std::to_string(i); int nRecordId = 0; addTransferRecord(data, nRecordId); } std::cout << "[Mock] æåæå ¥ " << nCount << " æ¡æµè¯æ¬è¿è®°å½ã" << std::endl; } } @@ -221,13 +237,13 @@ TransferData data; data.nRecordId = std::stoi(row[0]); data.strClassID = row[1]; data.strStatus = row[2]; data.strClassID = utf8ToAnsi(row[1]); data.strStatus = utf8ToAnsi(row[2]); data.strCreateTime = row[3]; data.strPickTime = row[4]; data.strPlaceTime = row[5]; data.strEndTime = row[6]; data.strDescription = row[7]; data.strDescription = utf8ToAnsi(row[7]); records.push_back(data); } @@ -247,13 +263,13 @@ auto results = m_pDB->fetchResults(oss.str()); if (!results.empty() && results[0].size() == 8) { data.nRecordId = std::stoi(results[0][0]); data.strClassID = results[0][1]; data.strStatus = results[0][2]; data.strClassID = utf8ToAnsi(results[0][1]); data.strStatus = utf8ToAnsi(results[0][2]); data.strCreateTime = results[0][3]; data.strPickTime = results[0][4]; data.strPlaceTime = results[0][5]; data.strEndTime = results[0][6]; data.strDescription = results[0][7]; data.strDescription = utf8ToAnsi(results[0][7]); } return data; } @@ -278,13 +294,13 @@ if (row.size() != 8) continue; TransferData data; data.nRecordId = std::stoi(row[0]); data.strClassID = row[1]; data.strStatus = row[2]; data.strClassID = utf8ToAnsi(row[1]); data.strStatus = utf8ToAnsi(row[2]); data.strCreateTime = row[3]; data.strPickTime = row[4]; data.strPlaceTime = row[5]; data.strEndTime = row[6]; data.strDescription = row[7]; data.strDescription = utf8ToAnsi(row[7]); records.push_back(data); } return records; @@ -299,7 +315,7 @@ std::ostringstream oss; oss << "SELECT record_id, class_id, status, create_time, pick_time, place_time, end_time, description " << "FROM transfers WHERE status = '" << status << "' " << "FROM transfers WHERE status = '" << ansiToUtf8(status) << "' " << "ORDER BY create_time DESC"; auto results = m_pDB->fetchResults(oss.str()); @@ -308,13 +324,13 @@ TransferData data; data.nRecordId = std::stoi(row[0]); data.strClassID = row[1]; data.strStatus = row[2]; data.strClassID = utf8ToAnsi(row[1]); data.strStatus = utf8ToAnsi(row[2]); data.strCreateTime = row[3]; data.strPickTime = row[4]; data.strPlaceTime = row[5]; data.strEndTime = row[6]; data.strDescription = row[7]; data.strDescription = utf8ToAnsi(row[7]); records.push_back(data); } @@ -348,8 +364,8 @@ // return records; //} // è·åç¬¦åæ¡ä»¶çè®°å½æ»æ° int TransferManager::getTotalTransferCount() { // è·åè®°å½æ»æ° int TransferManager::getTotalTransferCountAll() { if (!m_pDB) { return 0; } @@ -370,7 +386,7 @@ } // è·åç¬¦åæ¡ä»¶çè®°å½æ»æ° int TransferManager::getTotalTransferCount(const TransferData& filter) { int TransferManager::getFilteredTransferCount(const TransferData& filter) { if (!m_pDB) { return 0; } @@ -380,12 +396,12 @@ // ç¶æçéï¼å®å ¨å¹é ï¼ if (!filter.strStatus.empty()) { oss << " AND status = '" << filter.strStatus << "'"; oss << " AND status = '" << ansiToUtf8(filter.strStatus) << "'"; } // æè¿°å ³é®å模ç³å¹é if (!filter.strDescription.empty()) { oss << " AND description LIKE '%" << filter.strDescription << "%'"; oss << " AND description LIKE '%" << ansiToUtf8(filter.strDescription) << "%'"; } // æ¶é´èå´çé @@ -422,10 +438,10 @@ // æ¡ä»¶æ¼æ¥ï¼ä¸ getTotalTransferCount ä¿æä¸è´ï¼ if (!filter.strStatus.empty()) { oss << " AND status = '" << filter.strStatus << "'"; oss << " AND status = '" << ansiToUtf8(filter.strStatus) << "'"; } if (!filter.strDescription.empty()) { oss << " AND description LIKE '%" << filter.strDescription << "%'"; oss << " AND description LIKE '%" << ansiToUtf8(filter.strDescription) << "%'"; } if (!filter.strCreateTime.empty()) { oss << " AND create_time >= '" << filter.strCreateTime << "'"; @@ -446,13 +462,13 @@ TransferData data; data.nRecordId = std::stoi(row[0]); data.strClassID = row[1]; data.strStatus = row[2]; data.strClassID = utf8ToAnsi(row[1]); data.strStatus = utf8ToAnsi(row[2]); data.strCreateTime = row[3]; data.strPickTime = row[4]; data.strPlaceTime = row[5]; data.strEndTime = row[6]; data.strDescription = row[7]; data.strDescription = utf8ToAnsi(row[7]); records.push_back(data); } SourceCode/Bond/Servo/TransferManager.h
@@ -109,24 +109,24 @@ //std::vector<TransferData> getTransfers(int startPosition, int count); /** * è·åç¬¦åæ¡ä»¶çè®°å½æ»æ° * è·åè®°å½æ»æ° */ int getTotalTransferCount(); /** * å页è·åç¬¦åæ¡ä»¶çæ¬è¿è®°å½ * @param filter è¿æ»¤æ¡ä»¶ * @param pageNum 页ç * @param pageSize æ¯é¡µè®°å½æ° */ std::vector<TransferData> getTransfers(const TransferData& filter, int pageNum, int pageSize); int getTotalTransferCountAll(); /** * è·åç¬¦åæ¡ä»¶çè®°å½æ»æ° * @param filter è¿æ»¤æ¡ä»¶ * @return ç¬¦åæ¡ä»¶çè®°å½æ»æ° */ int getTotalTransferCount(const TransferData& filter);; int getFilteredTransferCount(const TransferData& filter); /** * å页è·åç¬¦åæ¡ä»¶çæ¬è¿è®°å½ * @param filter è¿æ»¤æ¡ä»¶ * @param pageNum 页ç * @param pageSize æ¯é¡µè®°å½æ° */ std::vector<TransferData> getTransfers(const TransferData& filter, int pageNum, int pageSize); /** * æ¸ çæ©äºæä¸æ¶é´çæ¬è¿è®°å½ SourceCode/Bond/Servo/resource.hBinary files differ