diff --git a/src/Controller/Convert.cc b/src/Controller/Convert.cc index f1cf4adb..4263941a 100644 --- a/src/Controller/Convert.cc +++ b/src/Controller/Convert.cc @@ -81,7 +81,7 @@ slint::SharedString firstUnicode(const std::string& str) { EventStruct from(const EventEntity& entity) { boost::algorithm::trim(entity.summary); return { - .id = entity.id, + .id = slint::SharedString(entity.id), .summary = slint::SharedString(entity.summary), .summary_abbr = details::firstUnicode(entity.summary), .description = slint::SharedString(entity.description), diff --git a/src/Controller/Core/AccountManager.cc b/src/Controller/Core/AccountManager.cc index 976847c2..93218924 100644 --- a/src/Controller/Core/AccountManager.cc +++ b/src/Controller/Core/AccountManager.cc @@ -179,19 +179,51 @@ void AccountManager::loadConfig() { setLoginState(false); auto [year, month, day] = evento::account.expire.date; auto [hour, minute, second, _] = evento::account.expire.time; - std::tm t = {year, month, day, hour, minute, second}; + spdlog::info("Loading config with date: {}-{}-{} and time: {}:{}:{}", + year, + month, + day, + hour, + minute, + second); + + if (year < 1900 || month < 1 || month > 12 || day < 1 || day > 31 || hour < 0 || hour > 23 + || minute < 0 || minute > 59 || second < 0 || second > 60) { + spdlog::error("Invalid date or time values"); + return; + } + std::tm t = {}; + t.tm_year = year - 1900; + t.tm_mon = month - 1; + t.tm_mday = day; + t.tm_hour = hour; + t.tm_min = minute; + t.tm_sec = second; + t.tm_isdst = -1; + + time_t time = std::mktime(&t); + if (time == -1) { + spdlog::error("Failed to convert time to time_t"); + return; + } - _expiredTime = std::chrono::system_clock::from_time_t(std::mktime(&t)); + _expiredTime = std::chrono::system_clock::from_time_t(time); _userInfo.linkId = evento::account.userId; } void AccountManager::saveConfig() { auto expire = std::chrono::system_clock::to_time_t(_expiredTime); - auto expireTm = *std::localtime(&expire); - evento::account.expire - = toml::date_time{toml::date{expireTm.tm_year + 1900, expireTm.tm_mon + 1, expireTm.tm_mday}, - toml::time{expireTm.tm_hour, expireTm.tm_min, expireTm.tm_sec}}; - evento::account.userId = _userInfo.linkId; + if (auto expireTm = std::localtime(&expire)) { + evento::account.expire = toml::date_time{toml::date{expireTm->tm_year + 1900, + expireTm->tm_mon + 1, + expireTm->tm_mday}, + toml::time{expireTm->tm_hour, + expireTm->tm_min, + expireTm->tm_sec}}; + evento::account.userId = _userInfo.linkId; + } else { + spdlog::error("Failed to convert time to time_t"); + } } void AccountManager::setKeychainRefreshToken(const std::string& refreshToken) const { diff --git a/src/Controller/View/DetailPage.cc b/src/Controller/View/DetailPage.cc index f3b29e4f..a7bfd149 100644 --- a/src/Controller/View/DetailPage.cc +++ b/src/Controller/View/DetailPage.cc @@ -1,4 +1,3 @@ -#include "app.h" #include #include #include @@ -19,13 +18,14 @@ void DetailPage::onCreate() { self->on_load_feedback([&self = *this]() { self.loadFeedback(); }); self->on_load_event([&self = *this]() { self.loadEvent(); }); self->on_feedback([&self = *this](int rate, slint::SharedString content) { - self.feedbackEvent(self->get_event_model().id, rate, content.data()); + self.feedbackEvent(self->get_event_model().id.data(), rate, content.data()); }); self->on_check_in([&self = *this](slint::SharedString checkInCode) { - self.checkIn(self->get_event_model().id, checkInCode.data()); + self.checkIn(self->get_event_model().id.data(), checkInCode.data()); + }); + self->on_subscribe([&self = *this](bool subscribe) { + self.subscribe(self->get_event_model().id.data(), subscribe); }); - self->on_subscribe( - [&self = *this](bool subscribe) { self.subscribe(self->get_event_model().id, subscribe); }); } void DetailPage::onShow() { @@ -39,7 +39,7 @@ void DetailPage::onShow() { void DetailPage::loadEvent() { auto& self = *this; - executor()->asyncExecute(networkClient()->getEventById(self->get_event_model().id), + executor()->asyncExecute(networkClient()->getEventById(self->get_event_model().id.data()), [&self = *this](Result result) { if (result.isErr()) { self.bridge.getMessageManager() @@ -61,7 +61,7 @@ void DetailPage::loadEvent() { void DetailPage::loadFeedback() { auto& self = *this; self->set_state(PageState::Loading); - executor()->asyncExecute(networkClient()->getUserFeedback(self->get_event_model().id), + executor()->asyncExecute(networkClient()->getUserFeedback(self->get_event_model().id.data()), [&self = *this](Result> result) { if (result.isErr()) { self->set_state(PageState::Error); @@ -75,7 +75,7 @@ void DetailPage::loadFeedback() { }); } -void DetailPage::checkIn(int eventId, std::string checkInCode) { +void DetailPage::checkIn(eventId_t eventId, std::string checkInCode) { auto& self = *this; executor()->asyncExecute( networkClient()->checkInEvent(eventId, checkInCode), [&self = *this](Result result) { @@ -103,9 +103,9 @@ void DetailPage::checkIn(int eventId, std::string checkInCode) { }); } -void DetailPage::subscribe(int eventId, bool subscribe) { +void DetailPage::subscribe(std::string eventId_t, bool subscribe) { auto& self = *this; - executor()->asyncExecute(networkClient()->subscribeEvent(eventId, subscribe), + executor()->asyncExecute(networkClient()->subscribeEvent(eventId_t, subscribe), [&self = *this, subscribe](Result result) { if (result.isErr()) { self.bridge.getMessageManager() @@ -130,10 +130,10 @@ void DetailPage::subscribe(int eventId, bool subscribe) { }); } -void DetailPage::feedbackEvent(int eventId, int rate, std::string content) { +void DetailPage::feedbackEvent(std::string eventId_t, int rate, std::string content) { auto& self = *this; executor() - ->asyncExecute(networkClient()->addUserFeedback(eventId, rate, content), + ->asyncExecute(networkClient()->addUserFeedback(eventId_t, rate, content), [&self = *this, rate, content](Result result) { if (result.isErr()) { self.bridge.getMessageManager().showMessage(result.unwrapErr().what(), diff --git a/src/Controller/View/DetailPage.h b/src/Controller/View/DetailPage.h index 47e116e4..5c2d9785 100644 --- a/src/Controller/View/DetailPage.h +++ b/src/Controller/View/DetailPage.h @@ -17,9 +17,9 @@ class DetailPage : public BasicView, private GlobalAgent { void loadEvent(); void loadFeedback(); - void checkIn(int eventId, std::string checkInCode); - void subscribe(int eventId, bool subscribe); - void feedbackEvent(int eventId, int rate, std::string content); + void checkIn(eventId_t eventId, std::string checkInCode); + void subscribe(eventId_t eventId, bool subscribe); + void feedbackEvent(eventId_t eventId, int rate, std::string content); }; EVENTO_UI_END \ No newline at end of file diff --git a/src/Controller/View/HistoryPage.cc b/src/Controller/View/HistoryPage.cc index ae3e5b7b..dcd001cd 100644 --- a/src/Controller/View/HistoryPage.cc +++ b/src/Controller/View/HistoryPage.cc @@ -19,8 +19,8 @@ void HistoryPage::onCreate() { self->on_load_events( [this](int pageIndex, int size) { loadHistoryEvents(pageIndex + 1, size); }); - self->on_comment([this](int eventId, int rating, slint::SharedString content) { - feedbackEvent(eventId, rating, content.data()); + self->on_comment([this](slint::SharedString eventId, int rating, slint::SharedString content) { + feedbackEvent(eventId.data(), rating, content.data()); }); self->on_navigate_to_detail([this](EventStruct eventStruct) { spdlog::debug("navigate to DetailPage, current event is {}", eventStruct.summary.data()); @@ -79,7 +79,7 @@ Task>> HistoryPage::loadHistoryEventsTas co_return res; } -void HistoryPage::feedbackEvent(int eventId, int rating, std::string content) { +void HistoryPage::feedbackEvent(eventId_t eventId, int rating, std::string content) { auto& self = *this; auto trans = [](const auto& e) { return e.id; }; executor() diff --git a/src/Controller/View/HistoryPage.h b/src/Controller/View/HistoryPage.h index e63a1d64..401d056f 100644 --- a/src/Controller/View/HistoryPage.h +++ b/src/Controller/View/HistoryPage.h @@ -21,7 +21,7 @@ class HistoryPage : public BasicView, private GlobalAgent { Task>> loadHistoryEventsTask(int page, int size); - void feedbackEvent(int eventId, int rating, std::string content); + void feedbackEvent(eventId_t eventId, int rating, std::string content); std::vector eventFeedbacks; }; diff --git a/src/Controller/View/MyEventPage.cc b/src/Controller/View/MyEventPage.cc index cc94aec8..6fb5d425 100644 --- a/src/Controller/View/MyEventPage.cc +++ b/src/Controller/View/MyEventPage.cc @@ -79,7 +79,7 @@ void MyEventPage::refreshUiModel(Result result) { if (evento::settings.noticeBegin) for (auto const& entity : models[(int) EventState::SigningUp]) { auto time = parseIso8601Utc(entity.start.c_str()); - ipc()->showOrUpdateMessage(entity.id, + ipc()->showOrUpdateMessage(entity.id.data(), std::format("活动 {} 还有 15 分钟就要开始了,记得参加哦", entity.summary), std::chrono::system_clock::from_time_t(time) - 15min); @@ -88,14 +88,14 @@ void MyEventPage::refreshUiModel(Result result) { if (evento::settings.noticeEnd) for (auto const& entity : models[(int) EventState::Active]) { auto time = parseIso8601Utc(entity.end.c_str()); - ipc()->showOrUpdateMessage(entity.id, + ipc()->showOrUpdateMessage(entity.id.data(), std::format("活动 {} 结束了,记得反馈哦", entity.summary), std::chrono::system_clock::from_time_t(time)); } for (auto const& entity : models[(int) EventState::Cancelled]) { auto time = parseIso8601Utc(entity.start.c_str()); - ipc()->cancelMessage(entity.id); + ipc()->cancelMessage(entity.id.data()); } self->set_not_started_model(convert::from(models[(int) EventState::SigningUp])); diff --git a/src/Infrastructure/IPC/SocketClient.cc b/src/Infrastructure/IPC/SocketClient.cc index c38910cd..14f5666e 100644 --- a/src/Infrastructure/IPC/SocketClient.cc +++ b/src/Infrastructure/IPC/SocketClient.cc @@ -66,10 +66,10 @@ void SocketClient::exitTray() { spdlog::info("Tray exited with code: {}", exit_code); } -void SocketClient::showOrUpdateMessage(int messageId, +void SocketClient::showOrUpdateMessage(messageId_t messageId, std::string const& message, std::chrono::system_clock::time_point const& time) { - if (messageId == 0) { + if (messageId.empty()) { spdlog::warn("Invalid message id"); return; } @@ -94,8 +94,8 @@ void SocketClient::showOrUpdateMessage(int messageId, AsyncExecutor::Delay | AsyncExecutor::Once); } -void SocketClient::cancelMessage(int messageId) { - if (messageId == 0) { +void SocketClient::cancelMessage(messageId_t messageId) { + if (messageId.empty()) { spdlog::warn("Invalid message id"); return; } diff --git a/src/Infrastructure/IPC/SocketClient.h b/src/Infrastructure/IPC/SocketClient.h index d0c36caf..a6c47f22 100644 --- a/src/Infrastructure/IPC/SocketClient.h +++ b/src/Infrastructure/IPC/SocketClient.h @@ -10,6 +10,7 @@ namespace evento { +using messageId_t = std::string; namespace net = boost::asio; class SocketClient { @@ -20,11 +21,11 @@ class SocketClient { void startTray(); void exitTray(); - void showOrUpdateMessage(int messageId, + void showOrUpdateMessage(messageId_t messageId, std::string const& message, std::chrono::system_clock::time_point const& time); - void cancelMessage(int messageId); + void cancelMessage(messageId_t messageId); void deleteAllMessage(); struct MessageType { @@ -48,7 +49,7 @@ class SocketClient { std::unique_ptr _socket; std::unordered_map> _actions; - std::unordered_map _messageMap; + std::unordered_map _messageMap; }; SocketClient* ipc(); diff --git a/src/Infrastructure/Network/NetworkClient.cc b/src/Infrastructure/Network/NetworkClient.cc index 15524413..1f1a28c2 100644 --- a/src/Infrastructure/Network/NetworkClient.cc +++ b/src/Infrastructure/Network/NetworkClient.cc @@ -167,10 +167,10 @@ Task> NetworkClient::getDepartmentEventList( co_return Ok(entity); } -Task> NetworkClient::getEventById(int eventId) { +Task> NetworkClient::getEventById(eventId_t eventId) { auto result = co_await this->request(http::verb::get, endpoint("/v2/client/event/query", - {{"id", std::to_string(eventId)}}), + {{"id", eventId}}), {}, 0min); if (result.isErr()) @@ -205,7 +205,7 @@ Task> NetworkClient::getEventList( co_return Ok(entity); } -Task> NetworkClient::getAttachment(int eventId) { +Task> NetworkClient::getAttachment(eventId_t eventId) { auto result = co_await this ->request(http::verb::get, endpoint(std::format("/v2/client/event/{}/attachments", @@ -224,7 +224,7 @@ Task> NetworkClient::getAttachment(int eventId) { } Task>> NetworkClient::getUserFeedback( - int eventId, std::chrono::steady_clock::duration cacheTtl) { + eventId_t eventId, std::chrono::steady_clock::duration cacheTtl) { auto result = co_await this ->request(http::verb::get, endpoint(std::format("/v2/client/event/{}/feedback", @@ -249,7 +249,9 @@ Task>> NetworkClient::getUserFeedback( co_return Ok(entity); } -Task> NetworkClient::addUserFeedback(int eventId, int rating, std::string content) { +Task> NetworkClient::addUserFeedback(eventId_t eventId, + int rating, + std::string content) { auto result = co_await this->request( http::verb::post, endpoint(std::format("/v2/client/event/{}/feedback", eventId), @@ -264,7 +266,7 @@ Task> NetworkClient::addUserFeedback(int eventId, int rating, std:: co_return Err(Error(Error::Data, "response data type error")); } -Task> NetworkClient::checkInEvent(int eventId, std::string code) { +Task> NetworkClient::checkInEvent(eventId_t eventId, std::string code) { auto result = co_await this->request( http::verb::post, endpoint(std::format("/v2/client/event/{}/check-in", eventId), {{"code", code}})); @@ -278,7 +280,7 @@ Task> NetworkClient::checkInEvent(int eventId, std::string code) { co_return Err(Error(Error::Data, "response data type error")); } -Task> NetworkClient::subscribeEvent(int eventId, bool subscribe) { +Task> NetworkClient::subscribeEvent(eventId_t eventId, bool subscribe) { std::string subscribeStr = subscribe ? "true" : "false"; auto result = co_await this ->request(http::verb::post, @@ -374,7 +376,7 @@ Task> NetworkClient::getHomeSlide( } Task> NetworkClient::getEventSlide( - int eventId, std::chrono::steady_clock::duration cacheTtl) { + eventId_t eventId, std::chrono::steady_clock::duration cacheTtl) { auto result = co_await this->request(http::verb::get, endpoint( std::format("/v2/client/event/{}/slide", diff --git a/src/Infrastructure/Network/NetworkClient.h b/src/Infrastructure/Network/NetworkClient.h index 166f7e39..4bb20776 100644 --- a/src/Infrastructure/Network/NetworkClient.h +++ b/src/Infrastructure/Network/NetworkClient.h @@ -66,21 +66,21 @@ class NetworkClient { int size = 10, std::chrono::steady_clock::duration cacheTtl = 1min); - Task> getEventById(int eventId); + Task> getEventById(eventId_t eventId); Task> getEventList(std::initializer_list params, std::chrono::steady_clock::duration cacheTtl = 1min); - Task> getAttachment(int eventId); + Task> getAttachment(eventId_t eventId); Task>> getUserFeedback( - int eventId, std::chrono::steady_clock::duration cacheTtl = 1min); + eventId_t eventId, std::chrono::steady_clock::duration cacheTtl = 1min); - Task> addUserFeedback(int eventId, int rating, std::string content); + Task> addUserFeedback(eventId_t eventId, int rating, std::string content); - Task> checkInEvent(int eventId, std::string code); + Task> checkInEvent(eventId_t eventId, std::string code); - Task> subscribeEvent(int eventId, bool subscribe); + Task> subscribeEvent(eventId_t eventId, bool subscribe); Task> subscribeDepartment(std::string larkDepartment, bool subscribe); @@ -95,7 +95,7 @@ class NetworkClient { Task> getHomeSlide(std::chrono::steady_clock::duration cacheTtl = 1min); - Task> getEventSlide(int eventId, + Task> getEventSlide(eventId_t eventId, std::chrono::steady_clock::duration cacheTtl = 1min); Task> getDepartmentList( diff --git a/src/Infrastructure/Network/Response/AttachmentEntity.h b/src/Infrastructure/Network/Response/AttachmentEntity.h index 197d2faa..5f84fd8c 100644 --- a/src/Infrastructure/Network/Response/AttachmentEntity.h +++ b/src/Infrastructure/Network/Response/AttachmentEntity.h @@ -8,7 +8,7 @@ namespace evento { struct AttachmentEntity { int id; - int eventId; + std::string eventId; std::string url; NLOHMANN_DEFINE_TYPE_INTRUSIVE(AttachmentEntity, id, eventId, url); diff --git a/src/Infrastructure/Network/Response/EventEntity.h b/src/Infrastructure/Network/Response/EventEntity.h index 9465487c..1204d0d0 100644 --- a/src/Infrastructure/Network/Response/EventEntity.h +++ b/src/Infrastructure/Network/Response/EventEntity.h @@ -7,8 +7,10 @@ #include namespace evento { +using eventId_t = std::string; + struct EventEntity { - int id; + eventId_t id; mutable std::string summary; std::string description; std::string start; diff --git a/src/Infrastructure/Network/Response/FeedbackEntity.h b/src/Infrastructure/Network/Response/FeedbackEntity.h index 3c48f848..af2b1051 100644 --- a/src/Infrastructure/Network/Response/FeedbackEntity.h +++ b/src/Infrastructure/Network/Response/FeedbackEntity.h @@ -7,11 +7,13 @@ namespace evento { +using eventId_t = std::string; + struct FeedbackEntity { - int id{}; // feedback id - int linkId{}; // which user this feedback belongs to - int eventId{}; // which event this feedback belongs to - int rating{}; // 0 - 5 + int id{}; // feedback id + int linkId{}; // which user this feedback belongs to + eventId_t eventId{}; // which event this feedback belongs to + int rating{}; // 0 - 5 std::optional feedback; NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT( diff --git a/src/Infrastructure/Network/Response/FeedbackEntityV1.h b/src/Infrastructure/Network/Response/FeedbackEntityV1.h index a6e2eed7..be3f52e1 100644 --- a/src/Infrastructure/Network/Response/FeedbackEntityV1.h +++ b/src/Infrastructure/Network/Response/FeedbackEntityV1.h @@ -7,10 +7,12 @@ namespace evento { +using eventId_t = std::string; + struct FeedbackEntityV1 { - int id{}; // feedback id - int eventId{}; // which event this feedback belongs to - int score{}; // 0 - 5 + int id{}; // feedback id + eventId_t eventId{}; // which event this feedback belongs to + int score{}; // 0 - 5 std::optional content; NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(FeedbackEntityV1, id, eventId, score, content); diff --git a/src/Infrastructure/Network/Response/SlideEntity.h b/src/Infrastructure/Network/Response/SlideEntity.h index 84b4646b..6116c538 100644 --- a/src/Infrastructure/Network/Response/SlideEntity.h +++ b/src/Infrastructure/Network/Response/SlideEntity.h @@ -7,9 +7,11 @@ namespace evento { +using eventId_t = std::string; + struct SlideEntity { int id; - int eventId; + eventId_t eventId; std::string url; std::string link; diff --git a/ui/components/event_struct.slint b/ui/components/event_struct.slint index 7e640d8c..101bde4c 100644 --- a/ui/components/event_struct.slint +++ b/ui/components/event_struct.slint @@ -6,7 +6,7 @@ export enum EventState { } export struct EventStruct { - id: int, + id: string, summary: string, summary-abbr: string, description: string, diff --git a/ui/views/page/history.slint b/ui/views/page/history.slint index b5424e5d..503e6906 100644 --- a/ui/views/page/history.slint +++ b/ui/views/page/history.slint @@ -15,7 +15,7 @@ export global HistoryPageBridge { in-out property current-page-index: 0; callback load-events(int, int); callback navigate-to-detail(EventStruct); - callback comment(int, int, string); + callback comment(string, int, string); } component CommentItem { @@ -83,7 +83,7 @@ component HistoryCard inherits Rectangle { in property event; in property feedback; callback event-clicked(EventStruct); - callback comment-clicked(int, int, string); + callback comment-clicked(string, int, string); height: 100px; HorizontalLayout { spacing: 5px;