commit 23537c3ae93bc15d929f664a40f6434cc6a51c06 Author: GoldBro233 Date: Tue Apr 15 18:38:03 2025 +0800 Init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a4fb4fb --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +build/ +.cache/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..c9549e5 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.31) +project (course_design) +set (CMAKE_CXX_STANDARD 17) +find_package(SQLite3 REQUIRED) + +add_executable(coursedesign main.cpp userAuth.cpp userAuth.h data.cpp data.h tools.cpp tools.h render_ui.cpp render_ui.h) +target_link_libraries(coursedesign PRIVATE SQLite::SQLite3) \ No newline at end of file diff --git a/Course-Design.code-workspace b/Course-Design.code-workspace new file mode 100644 index 0000000..a17b72e --- /dev/null +++ b/Course-Design.code-workspace @@ -0,0 +1,11 @@ +{ + "folders": [ + // 将载入到工作区的文件夹列表 + { + "path": "." + } + ], + "settings": { + // 工作区设置 + } +} \ No newline at end of file diff --git a/data.cpp b/data.cpp new file mode 100644 index 0000000..6e4daa4 --- /dev/null +++ b/data.cpp @@ -0,0 +1,192 @@ +#include "data.h" +#include "tools.h" +#include + +const char *CREATE_PA_TABLE = "CREATE TABLE IF NOT EXISTS pa_table (" + "id INTEGER PRIMARY KEY AUTOINCREMENT," + "car_id TEXT NOT NULL," + "in_pa_time DATETIME," + "out_pa_time DATETIME," + "define_in_pa INTEGER);"; +const char *REGISTER_PA_CAR = + "INSERT INTO pa_table (car_id, in_pa_time, " + "out_pa_time, define_in_pa) VALUES (?1, ?2, ?3, ?4);"; +const char *SELECT_PA_CAR = + "SELECT id, car_id, in_pa_time, out_pa_time, define_in_pa FROM pa_table " + "WHERE define_in_pa = 0 " + "ORDER BY id DESC;"; +const char *SELECT_PA_LEFTCAR = + "SELECT id, car_id, in_pa_time, out_pa_time, define_in_pa FROM pa_table " + "WHERE define_in_pa = 1 " + "ORDER BY id DESC;"; + +const char *UPDATE_PA_CAR = + "UPDATE pa_table SET out_pa_time = ?1, define_in_pa = ?3 WHERE id = ?2"; +const char *DELETE_PA_CAR = "DELETE FROM pa_table WHERE id = ?1;"; + +void init_pa_data(sqlite3 *db) { + char *err_msg = nullptr; + + int rc = sqlite3_exec(db, CREATE_PA_TABLE, nullptr, nullptr, &err_msg); + if (rc != SQLITE_OK) { + std::cerr << "创建表失败: " << err_msg << std::endl; + sqlite3_free(err_msg); + exit(1); + }; +}; + +void register_pa_car(sqlite3 *db, const string &car_id) { + sqlite3_stmt *stmt; + + int rc = sqlite3_prepare_v2(db, REGISTER_PA_CAR, -1, &stmt, nullptr); + + if (rc != SQLITE_OK) { + std::cerr << "准备语句失败: " << sqlite3_errmsg(db) << std::endl; + exit(1); + } + + int define_in_pa = 0; + string in_pa_time = get_utc8_time(); + string NAtime = "N/A"; + + sqlite3_bind_text(stmt, 1, car_id.c_str(), -1, SQLITE_STATIC); + sqlite3_bind_text(stmt, 2, in_pa_time.c_str(), -1, SQLITE_STATIC); + sqlite3_bind_text(stmt, 3, NAtime.c_str(), -1, SQLITE_STATIC); + sqlite3_bind_int(stmt, 4, define_in_pa); + + rc = sqlite3_step(stmt); + if (rc != SQLITE_DONE) { + std::cerr << "执行失败" << sqlite3_errmsg(db) << std::endl; + exit(1); + } + + sqlite3_finalize(stmt); +}; + +vector get_pa_cars(sqlite3 *db) { + vector results; + sqlite3_stmt *stmt; + + int rc = sqlite3_prepare_v2(db, SELECT_PA_CAR, -1, &stmt, nullptr); + if (rc != SQLITE_OK) { + std::cerr << "准备查询失败: " << sqlite3_errmsg(db) << std::endl; + exit(1); + } + + while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) { + PAStruct record; + record.id = sqlite3_column_int(stmt, 0); + + const unsigned char *text1 = sqlite3_column_text(stmt, 1); + record.car_id = std::string(reinterpret_cast(text1)); + + const unsigned char *time1 = sqlite3_column_text(stmt, 2); + record.in_pa_time = time1 ? reinterpret_cast(time1) : "N/A"; + + const unsigned char *time2 = sqlite3_column_text(stmt, 3); + record.out_pa_time = time2 ? reinterpret_cast(time2) : "N/A"; + + record.define_in_pa = sqlite3_column_int(stmt, 4); + + results.push_back(record); + } + + if (rc != SQLITE_DONE) { + std::cerr << "查询错误失败: " << sqlite3_errmsg(db) << std::endl; + } + + sqlite3_finalize(stmt); + return results; +} + +vector get_pa_leftcars(sqlite3 *db) { + vector results; + sqlite3_stmt *stmt; + + int rc = sqlite3_prepare_v2(db, SELECT_PA_LEFTCAR, -1, &stmt, nullptr); + if (rc != SQLITE_OK) { + std::cerr << "准备查询失败: " << sqlite3_errmsg(db) << std::endl; + exit(1); + } + + while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) { + PAStruct record; + record.id = sqlite3_column_int(stmt, 0); + + const unsigned char *text1 = sqlite3_column_text(stmt, 1); + record.car_id = std::string(reinterpret_cast(text1)); + + const unsigned char *time1 = sqlite3_column_text(stmt, 2); + record.in_pa_time = time1 ? reinterpret_cast(time1) : "N/A"; + + const unsigned char *time2 = sqlite3_column_text(stmt, 3); + record.out_pa_time = time2 ? reinterpret_cast(time2) : "N/A"; + + record.define_in_pa = sqlite3_column_int(stmt, 4); + + results.push_back(record); + } + + if (rc != SQLITE_DONE) { + std::cerr << "查询错误失败: " << sqlite3_errmsg(db) << std::endl; + } + + sqlite3_finalize(stmt); + return results; +} + +bool car_leave_func(sqlite3 *db, int id) { + sqlite3_stmt *stmt; + int define_in_pa = 1; + std::string outtime = get_utc8_time(); + + int rc = sqlite3_prepare_v2(db, UPDATE_PA_CAR, -1, &stmt, nullptr); + if (rc != SQLITE_OK) { + std::cerr << "准备更新语句失败: " << sqlite3_errmsg(db) << std::endl; + return false; + } + + sqlite3_bind_text(stmt, 1, outtime.c_str(), -1, SQLITE_STATIC); + sqlite3_bind_int(stmt, 3, define_in_pa); + sqlite3_bind_int(stmt, 2, id); + + rc = sqlite3_step(stmt); + sqlite3_finalize(stmt); + + if (rc != SQLITE_DONE) { + std::cerr << "更新执行失败: " << sqlite3_errmsg(db) << std::endl; + return false; + } + + return true; +} + +bool delete_pa_car(sqlite3 *db, int id) { + sqlite3_stmt *stmt = nullptr; + + int rc = sqlite3_prepare_v2(db, DELETE_PA_CAR, -1, &stmt, nullptr); + if (rc != SQLITE_OK) { + std::cerr << "准备删除语句失败: " << sqlite3_errmsg(db) << std::endl; + return false; + } + + rc = sqlite3_bind_int(stmt, 1, id); + + if (rc != SQLITE_OK) { + std::cerr << "绑定参数失败: " << sqlite3_errmsg(db) << std::endl; + sqlite3_finalize(stmt); + return false; + } + + rc = sqlite3_step(stmt); + const bool success = (rc == SQLITE_DONE); + const char *errorMsg = sqlite3_errmsg(db); + + sqlite3_finalize(stmt); + + if (!success) { + std::cerr << "删除执行失败: " << errorMsg << std::endl; + return false; + } + return true; +}; \ No newline at end of file diff --git a/data.h b/data.h new file mode 100644 index 0000000..9a85ec7 --- /dev/null +++ b/data.h @@ -0,0 +1,24 @@ +#ifndef COURSE_DESIGN_DATA_H_ +#define COURSE_DESIGN_DATA_H_ + +#include "tools.h" +#include + +using namespace std; + +struct PAStruct { + int id; + string car_id; + string in_pa_time; + string out_pa_time; + int define_in_pa; +}; + +void init_pa_data(sqlite3 *db); +void register_pa_car(sqlite3 *db, const string &car_id); +vector get_pa_cars(sqlite3 *db); +vector get_pa_leftcars(sqlite3 *db); +bool car_leave_func(sqlite3 *db, int id); +bool delete_pa_car(sqlite3 *db, int id); + +#endif \ No newline at end of file diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..e671e4e --- /dev/null +++ b/main.cpp @@ -0,0 +1,87 @@ +#include "data.h" +#include "render_ui.h" +#include "stdlib.h" +#include "tools.h" +#include "userAuth.h" +#include +#include + +using namespace std; + +const char *DB_NAME = "user_data.db"; + +sqlite3 *create_connection() { + sqlite3 *db; + int rc = sqlite3_open(DB_NAME, &db); + if (rc != SQLITE_OK) { + std::cerr << "无法打开数据库:" << sqlite3_errmsg(db) << std::endl; + exit(1); + } + return db; +} + +int main() { + sqlite3 *db = create_connection(); + init_pa_data(db); + init_user_data(db); + string login_username; + string login_password; + bool user_authorized = false; + + cout << "请输入用户名登录: "; + cin >> login_username; + cout << "请输入对应的密码: "; + cin >> login_password; + cout << endl; + + user_authorized = login_user(db, login_username, login_password); + + if (user_authorized) { + cout << "登录成功!" << endl; + } else { + cout << "登录失败! " << endl; + return 1; + } + + while (user_authorized) { + system("clear"); + switch (show_main_menu()) { + case 1: + system("clear"); + handle_add_pa_record(db); + break; + case 2: + system("clear"); + handle_leave_car(db); + break; + case 3: + system("clear"); + handle_show_pa_records(db); + break; + case 4: + system("clear"); + handle_show_pa_leftcar_records(db); + break; + case 5: + system("clear"); + handle_add_user_record(db); + break; + case 6: + system("clear"); + handle_show_user_records(db); + break; + case 7: + system("clear"); + handle_update_userpassword_record(db); + break; + case 8: + system("clear"); + handle_delete_user_record(db); + break; + case 9: + sqlite3_close(db); + std::cout << "退出应用" << std::endl; + return 0; + } + } +} \ No newline at end of file diff --git a/render_ui.cpp b/render_ui.cpp new file mode 100644 index 0000000..b59c4a6 --- /dev/null +++ b/render_ui.cpp @@ -0,0 +1,223 @@ +#include "render_ui.h" +#include "data.h" +#include "userAuth.h" +#include + +int show_main_menu() { + int choice = 0; + + std::cout << endl + << "[=== 主菜单 ===]" << std::endl + << "1. 车辆进场" << std::endl + << "2. 车辆离场" << std::endl + << "3. 查看在场车辆" << std::endl + << "4. 查看离场车辆" << std::endl + << "5. 添加用户" << std::endl + << "6. 查看已有用户" << std::endl + << "7. 修改用户密码" << std::endl + << "8. 删除用户" << std::endl + << "9. 退出" << std::endl + << "请输入选项: "; + + while (!(std::cin >> choice) || choice < 1 || choice > 9) { + std::cin.clear(); + std::cin.ignore(std::numeric_limits::max(), '\n'); + std::cout << "请重新输入。" << std::endl; + } + std::cin.ignore(); + return choice; +} + +void display_user_records(const std::vector &records) { + if (records.empty()) { + std::cout << "数据库中没有存储记录。" << std::endl; + return; + } + + std::cout << "[====== 用户记录 ======]" << std::endl; + for (const auto &record : records) { + std::cout << "ID: " << record.id << std::endl + << "用户名称: " << record.username << std::endl + << "用户密码: " << record.userpassword << std::endl + << "创建时间: " << record.created_time << std::endl + << "[------------------------]" << std::endl; + } +} + +void handle_show_user_records(sqlite3 *db) { + auto records = get_user_inputs(db); + display_user_records(records); +} + +void display_pa_records(const std::vector &records) { + if (records.empty()) { + std::cout << "数据库中没有存储记录。" << std::endl; + return; + } + + std::cout << "[====== 车辆记录记录 ======]" << std::endl; + for (const auto &record : records) { + std::cout << "ID: " << record.id << std::endl + << "车牌号: " << record.car_id << std::endl + << "进场时间: " << record.in_pa_time << std::endl + << "离场时间: " << record.out_pa_time << std::endl + << "[------------------------]" <> target_id)) { + std::cin.clear(); + std::cin.ignore(std::numeric_limits::max(), '\n'); + std::cout << "无效的ID输入" << std::endl; + return; + } + std::cin.ignore(); + + auto it = std::find_if( + records.begin(), records.end(), + [target_id](const UserStruct &u) { return u.id == target_id; }); + + if (it == records.end()) { + std::cout << "未能找到ID为 " << target_id << " 的记录" << std::endl; + return; + } + + std::string new_content1; + std::cout << "原用户名 " << it->username << std::endl; + std::cout << "新用户名(直接回车取消) "; + std::getline(std::cin, new_content1); + + std::string new_content2; + std::cout << "原用户密码 " << it->userpassword << std::endl; + std::cout << "新用户密码(直接回车取消) "; + std::getline(std::cin, new_content2); + + if (new_content1.empty()) { + new_content1 = it->username; + } + if (new_content2.empty()) { + new_content2 = it->userpassword; + } + + if (update_user(db, target_id, new_content1, new_content2)) { + std::cout << "更新成功!" << std::endl; + } + else { + std::cout << "更新失败!" << std::endl; + } +} + +void handle_delete_user_record(sqlite3 *db) { + auto records = get_user_inputs(db); + display_user_records(records); + + if (records.empty()) + return; + + std::cout << "请输入要删除的记录ID(或输入exit取消): " << std::endl; + std::string input; + std::getline(std::cin, input); + + // 处理取消操作 + if (input == "exit" || input == "EXIT") { + std::cout << "已取消删除操作" << std::endl; + return; + } + + try { + int target_id = std::stoi(input); + auto it = std::find_if( + records.begin(), records.end(), + [target_id](const UserStruct &u) { return u.id == target_id; }); + + if (it == records.end()) { + std::cout << "未找到ID为 " << target_id << " 的记录" << std::endl; + return; + } + + // 确认删除 + std::cout << "确认删除以下记录吗? " << std::endl + << "ID: " << it->id << std::endl + << "用户名: " << it->username << std::endl + << "输入 y 确认,其他取消: "; + std::string confirm; + std::getline(std::cin, confirm); + + if (confirm == "y" || confirm == "Y") { + if (delete_user(db, target_id)) { + std::cout << "记录删除成功! " << std::endl; + } else { + std::cout << "记录删除失败! " << std::endl; + } + } else { + std::cout << "已取消删除操作。 " << std::endl; + } + } catch (const std::invalid_argument &) { + std::cout << "无效的ID输入! " << std::endl; + } catch (const std::out_of_range &) { + std::cout << "ID超出有效范围! " << std::endl; + } +} + +void handle_leave_car (sqlite3* db) { + auto records = get_pa_cars(db); + display_pa_records(records); + + int choice; + std::cout << "请输入要离场的车辆:" ; + std::cin >> choice; + + if (car_leave_func(db, choice)) { + std::cout << "车辆离场! " < +#include +#include +#include +#include + +int show_main_menu(); + +void display_user_records(const std::vector &records); +void handle_show_user_records(sqlite3 *db); +void display_pa_records(const std::vector &records); +void handle_show_pa_records(sqlite3 *db); +void handle_show_pa_leftcar_records(sqlite3 *db); + + void handle_add_pa_record(sqlite3 *db); +void handle_add_user_record(sqlite3 *db); +void handle_leave_car(sqlite3 *db); + +void handle_update_userpassword_record(sqlite3 *db); +void handle_delete_user_record(sqlite3 *db); +#endif \ No newline at end of file diff --git a/tools.cpp b/tools.cpp new file mode 100644 index 0000000..cdee9e7 --- /dev/null +++ b/tools.cpp @@ -0,0 +1,13 @@ +#include "tools.h" + +std::string get_utc8_time() { + auto now = std::chrono::system_clock::now(); + std::time_t now_time = std::chrono::system_clock::to_time_t(now); + + now_time += 8 * 3600; + + std::tm *tm = std::gmtime(&now_time); + std::stringstream ss; + ss << std::put_time(tm, "%Y-%m-%d %H:%M:%S"); + return ss.str(); +} \ No newline at end of file diff --git a/tools.h b/tools.h new file mode 100644 index 0000000..a365e8a --- /dev/null +++ b/tools.h @@ -0,0 +1,13 @@ +#ifndef COURSE_DESIGN_TOOLS_H_ +#define COURSE_DESIGN_TOOLS_H_ + +#include "chrono" +#include "iostream" +#include "sqlite3.h" +#include "string" +#include "iomanip" +#include "vector" + +std::string get_utc8_time(); + +#endif \ No newline at end of file diff --git a/userAuth.cpp b/userAuth.cpp new file mode 100644 index 0000000..045442c --- /dev/null +++ b/userAuth.cpp @@ -0,0 +1,172 @@ +#include "userAuth.h" +#include "tools.h" + +const char *CREATE_USER_TABLE = "CREATE TABLE IF NOT EXISTS user_data (" + "id INTEGER PRIMARY KEY AUTOINCREMENT," + "username TEXT NOT NULL," + "userpassword TEXT NOT NULL," + "created_time DATETIME)"; + +const char *REGISTER_USER = "INSERT INTO user_data (username, userpassword, " + "created_time) VALUES (?1, ?2, ?3);"; + +const char *LOGIN_USER = + "SELECT 1 FROM user_data WHERE username = ? AND userpassword = ?;"; + +const char *SELECT_USER = + "SELECT id, username, userpassword, created_time FROM user_data " + "ORDER BY id DESC;"; + +const char *UPDATE_USER = + "UPDATE user_data SET username = ?1, userpassword = ?3 WHERE id = ?2"; + +const char *DELETE_USER = "DELETE FROM user_data WHERE id = ?1;"; + +void init_user_data(sqlite3 *db) { + char *err_msg = nullptr; + + int rc = sqlite3_exec(db, CREATE_USER_TABLE, nullptr, nullptr, &err_msg); + if (rc != SQLITE_OK) { + std::cerr << "创建表失败: " << err_msg << std::endl; + sqlite3_free(err_msg); + exit(1); + }; +}; + +void register_user(sqlite3 *db, const string &username, + const string &userpassword) { + sqlite3_stmt *stmt; + + int rc = sqlite3_prepare_v2(db, REGISTER_USER, -1, &stmt, nullptr); + + if (rc != SQLITE_OK) { + std::cerr << "准备语句失败: " << sqlite3_errmsg(db) << std::endl; + exit(1); + } + + sqlite3_bind_text(stmt, 1, username.c_str(), -1, SQLITE_STATIC); + sqlite3_bind_text(stmt, 2, userpassword.c_str(), -1, SQLITE_STATIC); + + string timestamp = get_utc8_time(); + sqlite3_bind_text(stmt, 3, timestamp.c_str(), -1, SQLITE_STATIC); + + rc = sqlite3_step(stmt); + if (rc != SQLITE_DONE) { + std::cerr << "执行失败" << sqlite3_errmsg(db) << std::endl; + exit(1); + } + + sqlite3_finalize(stmt); +}; + +bool login_user(sqlite3 *db, const std::string &username, + const std::string &password) { + sqlite3_stmt *stmt; + bool authResult = false; + + if (sqlite3_prepare_v2(db, LOGIN_USER, -1, &stmt, nullptr) != SQLITE_OK) { + std::cerr << "准备语句失败: " << sqlite3_errmsg(db) << std::endl; + sqlite3_close(db); + return false; + } + + sqlite3_bind_text(stmt, 1, username.c_str(), -1, SQLITE_STATIC); + sqlite3_bind_text(stmt, 2, password.c_str(), -1, SQLITE_STATIC); + + // 执行查询 + if (sqlite3_step(stmt) == SQLITE_ROW) { + authResult = true; // 找到匹配记录 + } + + sqlite3_finalize(stmt); + return authResult; +} + +vector get_user_inputs(sqlite3 *db) { + vector results; + sqlite3_stmt *stmt; + + int rc = sqlite3_prepare_v2(db, SELECT_USER, -1, &stmt, nullptr); + if (rc != SQLITE_OK) { + std::cerr << "准备查询失败: " << sqlite3_errmsg(db) << std::endl; + exit(1); + } + + while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) { + UserStruct record; + record.id = sqlite3_column_int(stmt, 0); + + const unsigned char *text1 = sqlite3_column_text(stmt, 1); + record.username = std::string(reinterpret_cast(text1)); + + const unsigned char *text2 = sqlite3_column_text(stmt, 2); + record.userpassword = std::string(reinterpret_cast(text2)); + + const unsigned char *time = sqlite3_column_text(stmt, 3); + record.created_time = time ? reinterpret_cast(time) : "N/A"; + + results.push_back(record); + } + + if (rc != SQLITE_DONE) { + std::cerr << "查询错误失败: " << sqlite3_errmsg(db) << std::endl; + } + + sqlite3_finalize(stmt); + return results; +} + +bool update_user(sqlite3 *db, int id, const string &new_username, + const string &new_password) { + sqlite3_stmt *stmt; + + int rc = sqlite3_prepare_v2(db, UPDATE_USER, -1, &stmt, nullptr); + if (rc != SQLITE_OK) { + std::cerr << "准备更新语句失败: " << sqlite3_errmsg(db) << std::endl; + return false; + } + + sqlite3_bind_text(stmt, 1, new_username.c_str(), -1, SQLITE_STATIC); + sqlite3_bind_text(stmt, 3, new_password.c_str(), -1, SQLITE_STATIC); + sqlite3_bind_int(stmt, 2, id); + + rc = sqlite3_step(stmt); + sqlite3_finalize(stmt); + + if (rc != SQLITE_DONE) { + std::cerr << "更新执行失败: " << sqlite3_errmsg(db) << std::endl; + return false; + } + + return true; +} + +bool delete_user(sqlite3 *db, int id) { + sqlite3_stmt *stmt = nullptr; + + int rc = sqlite3_prepare_v2(db, DELETE_USER, -1, &stmt, nullptr); + if (rc != SQLITE_OK) { + std::cerr << "准备删除语句失败: " << sqlite3_errmsg(db) << std::endl; + return false; + } + + rc = sqlite3_bind_int(stmt, 1, id); + + if (rc != SQLITE_OK) { + std::cerr << "绑定参数失败: " << sqlite3_errmsg(db) << std::endl; + sqlite3_finalize(stmt); + return false; + } + + rc = sqlite3_step(stmt); + const bool success = (rc == SQLITE_DONE); + const char *errorMsg = sqlite3_errmsg(db); + + sqlite3_finalize(stmt); + + if (!success) { + std::cerr << "删除执行失败: " << errorMsg << std::endl; + return false; + } + return true; +}; diff --git a/userAuth.h b/userAuth.h new file mode 100644 index 0000000..c85b802 --- /dev/null +++ b/userAuth.h @@ -0,0 +1,28 @@ +#ifndef COURSE_DESIGN_USERAUTH_H_ +#define COURSE_DESIGN_USERAUTH_H_ + +#include "sqlite3.h" +#include "tools.h" + +using namespace std; + +struct UserStruct { + int id; + string username; + string userpassword; + string created_time; +}; + +void init_user_data(sqlite3 *db); + +void register_user(sqlite3 *db, const string &username, + const string &userpassword); +bool login_user(sqlite3 *db, const std::string &username, + const std::string &password); +bool update_user(sqlite3 *db, int id, const string &new_username, + const string &new_password); +vector get_user_inputs(sqlite3 *db); + +bool delete_user(sqlite3 *db, int id); + +#endif \ No newline at end of file