diff --git a/CMakeLists.txt b/CMakeLists.txt index db8b442..1852c76 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,5 +15,7 @@ add_executable(o sqlite3.c login.c ui.c - include/ui.h) + signin.c + include/ui.h + ) target_link_libraries(o "${LIBRARY_PATH}/${LIBRARY_NAME}") \ No newline at end of file diff --git a/include/function.h b/include/function.h index 49a7c76..e2ac257 100644 --- a/include/function.h +++ b/include/function.h @@ -9,7 +9,9 @@ #ifndef FUNCTION_H #define FUNCTION_H -int Login(); +void Login(char *username,char*password,int *recall,char *errmsg); + +void Signin(const char *username,const char*password,int *recall,char *errmsg); void myexit(); #endif //FUNCTION_H diff --git a/login.c b/login.c index e69de29..15b7a5b 100644 --- a/login.c +++ b/login.c @@ -0,0 +1,56 @@ +#include +#include +#include "./include/function.h" +#include "./include/ui.h" +void Login(char *username,char*password,int *recall,char *errmsg){ + sqlite3 *db; + int rc; + + // 打开数据库 + rc = sqlite3_open("./data/msg.db", &db); + if (rc) { + strcpy(errmsg,"Error:database error."); + *recall=-1; + return; + } + + // SQL 查询语句:查找用户及其密码 + const char *sql = "SELECT user, password FROM users WHERE user = ?;"; + + sqlite3_stmt *stmt; + + // 编译 SQL 语句 + rc = sqlite3_prepare_v2(db, sql, -1, &stmt, 0); + if (rc != SQLITE_OK) { + strcpy(errmsg,"Error:database error."); + *recall=-1; + sqlite3_close(db); + return; + } + + // 绑定查询参数 + sqlite3_bind_text(stmt, 1, username, -1, SQLITE_STATIC); + + rc = sqlite3_step(stmt); + if (rc == SQLITE_ROW) { + // 查找到用户,获取密码 + const char *db_password = (const char *)sqlite3_column_text(stmt, 1); + + // 如果密码匹配 + if (db_password && strcmp(db_password, password) == 0) { + *recall=0; + } else { + strcpy(errmsg,"Incorrect username or password."); + *recall=-1; + } + } else { + strcpy(errmsg,"Incorrect username or password."); + *recall=-1; + } + // 绑定查询参数 + // 清理资源 + sqlite3_finalize(stmt); + sqlite3_close(db); + + return; +} diff --git a/signin.c b/signin.c new file mode 100644 index 0000000..108e4c3 --- /dev/null +++ b/signin.c @@ -0,0 +1,63 @@ +// +// Created by zhang on 2024/12/29. +// +#include +#include +#include "./include/function.h" +#include "./include/sqlite3.h" + +void Signin(const char *username,const char*password,int *recall,char *errmsg){ + sqlite3 *db; + char *errMsg = 0; + int rc; + // 打开数据库,如果数据库文件不存在则创建它 + rc = sqlite3_open("./data/msg.db", &db); + if (rc) { + strcpy(errmsg,"Error:database error."); + *recall=-1; + return; + } + const char *sql_create_table = + "CREATE TABLE IF NOT EXISTS users " + "(" + "id INTEGER PRIMARY KEY AUTOINCREMENT, " + "user TEXT UNIQUE," + "password TEXT" + ");"; + + // 执行 SQL 语句 + rc = sqlite3_exec(db, sql_create_table, 0, 0, &errMsg); + if (rc != SQLITE_OK) { + strcpy(errmsg,"Error:database error."); + sqlite3_free(errMsg); + sqlite3_close(db); + *recall=-1;return; + } + const char *sql_insert="INSERT INTO users (user, password) VALUES (?, ?);"; + sqlite3_stmt *insert; + rc = sqlite3_prepare_v2(db, sql_insert, -1, &insert, 0); + if (rc != SQLITE_OK) { + strcpy(errmsg,"Error:database error."); + *recall=-1; + sqlite3_close(db); + return; + } + + // 将第一个参数 (name) 绑定到 SQL 语句中的第一个 "?" + sqlite3_bind_text(insert, 1, username, -1, SQLITE_STATIC); + + // 将第二个参数 (email) 绑定到 SQL 语句中的第二个 "?" + sqlite3_bind_text(insert, 2, password, -1, SQLITE_STATIC); + + rc = sqlite3_exec(db,insert,0,0,&errMsg); + if (rc != SQLITE_OK) { + strcpy(errmsg,errMsg); + sqlite3_free(errMsg); + sqlite3_finalize(insert); + sqlite3_close(db); + *recall=-1;return; + } + sqlite3_close(db); + *recall=0; + return; +} \ No newline at end of file diff --git a/ui.c b/ui.c index d632b3d..1171fdd 100644 --- a/ui.c +++ b/ui.c @@ -13,30 +13,31 @@ #define WIN_HEIGHT 15 #define WIN_WIDTH 40 -struct bottom{ - int x,y; - int width,height; +struct bottom { + int x, y; + int width, height; char *test[30]; int private; }; -void draw_bottom(WINDOW *win,struct bottom *bot){ - mvwprintw(win,bot->y,bot->x,"%s",bot->test); +void draw_bottom(WINDOW *win, struct bottom *bot) { + mvwprintw(win, bot->y, bot->x, "%s", bot->test); } -struct bottom *creat_bottom(WINDOW *win,int x,int y,int width,int height,char *test[]) { - struct bottom *bot=malloc(sizeof(struct bottom)); - bot->y=x; - bot->x=y; - bot->width=width; - bot->height=height; - strcpy(bot->test,test); +struct bottom *creat_bottom(WINDOW *win, int x, int y, int width, int height, char *test[]) { + struct bottom *bot = malloc(sizeof(struct bottom)); + bot->y = x; + bot->x = y; + bot->width = width; + bot->height = height; + strcpy(bot->test, test); //mvwprintw(win,x,y,"%s",test); return bot; } -bool click_bottom(MEVENT event,struct bottom bottom,int sx,int sy){ - return event.x-sx>= bottom.x && event.x-sx < bottom.x + bottom.width && event.y-sy >= bottom.y && event.y-sy < bottom.y + bottom.height; +bool click_bottom(MEVENT event, struct bottom bottom, int sx, int sy) { + return event.x - sx >= bottom.x && event.x - sx < bottom.x + bottom.width && event.y - sy >= bottom.y && + event.y - sy < bottom.y + bottom.height; } int Welcome_ui() { @@ -53,32 +54,41 @@ int Welcome_ui() { int start_y = (LINES - WIN_HEIGHT) / 2; int start_x = (COLS - WIN_WIDTH) / 2; WINDOW *welcome_win = newwin(WIN_HEIGHT, WIN_WIDTH, start_y, start_x); - keypad(welcome_win,TRUE); - wborder(welcome_win, '|', '|', '-','-','+', '+', '+', '+'); + keypad(welcome_win, TRUE); + wborder(welcome_win, '|', '|', '-', '-', '+', '+', '+', '+'); // 标题 mvwprintw(welcome_win, 1, 1, "Welcome to math calculate system!"); - struct bottom *login= creat_bottom(welcome_win,4,1,5,1,"Login"); - draw_bottom(welcome_win,login); - struct bottom *signin= creat_bottom(welcome_win,8,1,6,1,"Signin"); - draw_bottom(welcome_win,signin); - struct bottom *exit= creat_bottom(welcome_win,12,1,4,1,"Exit"); - draw_bottom(welcome_win,exit); + struct bottom *login = creat_bottom(welcome_win, 4, 1, 5, 1, "Login"); + draw_bottom(welcome_win, login); + struct bottom *signin = creat_bottom(welcome_win, 8, 1, 6, 1, "Signin"); + draw_bottom(welcome_win, signin); + struct bottom *exit = creat_bottom(welcome_win, 12, 1, 4, 1, "Exit"); + draw_bottom(welcome_win, exit); wrefresh(welcome_win); - while(1){ - int rc=wgetch(welcome_win); - if(rc==KEY_MOUSE){ - if(nc_getmouse(&event)==OK){ + while (1) { + int rc = wgetch(welcome_win); + if (rc == KEY_MOUSE) { + if (nc_getmouse(&event) == OK) { //mvwprintw(welcome_win, 3, 1, "Mouse at (%d, %d), button %d", event.x-start_x, event.y-start_y, event.bstate); - if(click_bottom(event,*login,start_x,start_y)){ - free(login);free(signin);free(exit);endwin(); + if (click_bottom(event, *login, start_x, start_y)) { + free(login); + free(signin); + free(exit); + endwin(); return 2; } - if(click_bottom(event,*signin,start_x,start_y)){ - free(login);free(signin);free(exit);endwin(); + if (click_bottom(event, *signin, start_x, start_y)) { + free(login); + free(signin); + free(exit); + endwin(); return 3; } - if(click_bottom(event,*exit,start_x,start_y)){ - free(login);free(signin);free(exit);endwin(); + if (click_bottom(event, *exit, start_x, start_y)) { + free(login); + free(signin); + free(exit); + endwin(); return 0; } } @@ -86,7 +96,9 @@ int Welcome_ui() { } } -void draw_login_window(WINDOW *win,struct bottom *login,struct bottom *signin,struct bottom *user,struct bottom *psword,struct bottom *exit) { +void +draw_login_window(WINDOW *win, struct bottom *login, struct bottom *signin, struct bottom *user, struct bottom *psword, + struct bottom *exit) { // 清空窗口并绘制边框 wclear(win); box(win, 0, 0); @@ -100,214 +112,212 @@ void draw_login_window(WINDOW *win,struct bottom *login,struct bottom *signin,st // 密码输入框 mvwprintw(win, 6, 4, "Password:"); //绘制剩余内容 - draw_bottom(win,login); - draw_bottom(win,signin); - draw_bottom(win,exit); - draw_bottom(win,user); - draw_bottom(win,psword); + draw_bottom(win, login); + draw_bottom(win, signin); + draw_bottom(win, exit); + draw_bottom(win, user); + draw_bottom(win, psword); wrefresh(win); // 刷新窗口 } -void get_input(WINDOW *win, int y, int x, char *buffer, int max_len,struct bottom *bot,int sx,int sy) { +void +draw_signin_window(WINDOW *win, struct bottom *signin, struct bottom *user, struct bottom *psword, + struct bottom *exit) { + // 清空窗口并绘制边框 + wclear(win); + box(win, 0, 0); + + // 标题 + mvwprintw(win, 1, (WIN_WIDTH - 10) / 2, "Signin"); + + // 用户名输入框 + mvwprintw(win, 3, 4, "Username:"); + + // 密码输入框 + mvwprintw(win, 6, 4, "Password:"); + //绘制剩余内容 + draw_bottom(win, signin); + draw_bottom(win, exit); + draw_bottom(win, user); + draw_bottom(win, psword); + wrefresh(win); // 刷新窗口 +} + +void get_input(WINDOW *win, int y, int x, char *buffer, int max_len, struct bottom *bot, int sx, int sy) { MEVENT event; int ch, pos = 0; - char *test=bot->test; - while(postest; + while (pos < max_len && buffer[pos] != '\0')pos++; while (1) { - ch= wgetch(win); + ch = wgetch(win); if (ch == KEY_BACKSPACE || ch == 8) { // 处理退格键 if (pos > 0) { pos--; - buffer[pos]='\0'; - test[pos+1]='_'; - draw_bottom(win,bot); + buffer[pos] = '\0'; + test[pos + 1] = '_'; + draw_bottom(win, bot); wrefresh(win); } } else if (pos < max_len - 1 && ch >= 32 && ch <= 126) { // 可打印字符 buffer[pos++] = ch; - if(bot->private==0)test[pos]=ch; - else test[pos]='*'; - draw_bottom(win,bot); + if (bot->private == 0)test[pos] = ch; + else test[pos] = '*'; + draw_bottom(win, bot); wrefresh(win); - } - else if(ch== KEY_MOUSE){ - if(nc_getmouse(&event)==OK){ - if(!click_bottom(event,*bot,sx,sy)){ + } else if (ch == KEY_MOUSE) { + if (nc_getmouse(&event) == OK) { + if (!click_bottom(event, *bot, sx, sy)) { return; } } } } } -int Login_ui(){ + +int Login_ui() { MEVENT event; + char *errmsg[30]; + memset(errmsg, 0, 30); int start_y = (LINES - WIN_HEIGHT) / 2; int start_x = (COLS - WIN_WIDTH) / 2; WINDOW *login_win = newwin(WIN_HEIGHT, WIN_WIDTH, start_y, start_x); - keypad(login_win,TRUE); + keypad(login_win, TRUE); char *username[15]; //储存用户名 memset(username, 0, 15); // 清空缓冲区 char *password[15]; //储存密码 memset(password, 0, 15); // 清空缓冲区 - struct bottom *login= creat_bottom(login_win,10,4,5,1,"Login"); - struct bottom *signin= creat_bottom(login_win,10,14,5,1,"Signin"); - struct bottom *exit= creat_bottom(login_win,10,25,5,1,"Exit"); - struct bottom *users= creat_bottom(login_win,4,4,16,1,"[______________]"); - struct bottom *psword= creat_bottom(login_win,7,4,16,1,"[______________]"); - psword->private=1;users->private=0; - while(1){ - draw_login_window(login_win,login,signin,users,psword,exit); - int rc=wgetch(login_win); - if(rc==KEY_MOUSE){ - if(nc_getmouse(&event)==OK){ + struct bottom *login = creat_bottom(login_win, 10, 4, 5, 1, "Login"); + struct bottom *signin = creat_bottom(login_win, 10, 14, 5, 1, "Signin"); + struct bottom *exit = creat_bottom(login_win, 10, 25, 5, 1, "Exit"); + struct bottom *users = creat_bottom(login_win, 4, 4, 16, 1, "[______________]"); + struct bottom *psword = creat_bottom(login_win, 7, 4, 16, 1, "[______________]"); + psword->private = 1; + users->private = 0; + int willdraw = 1; + while (1) { + if (willdraw)draw_login_window(login_win, login, signin, users, psword, exit); + int rc = wgetch(login_win); + if (rc == KEY_MOUSE) { + if (nc_getmouse(&event) == OK) { //mvwprintw(welcome_win, 3, 1, "Mouse at (%d, %d), button %d", event.x-start_x, event.y-start_y, event.bstate); - if(click_bottom(event,*login,start_x,start_y)){ - free(login);free(signin);free(exit);free(users);free(psword);endwin(); - } - if(click_bottom(event,*signin,start_x,start_y)){ - free(login);free(signin);free(exit);free(users);free(psword);endwin(); - return 3; - } - if(click_bottom(event,*exit,start_x,start_y)){ - free(login);free(signin);free(exit);free(users);free(psword);endwin(); - return 1; - } - if(click_bottom(event,*users,start_x,start_y)){ - get_input(login_win, 4, 6, username, 15,users,start_x,start_y); - continue; - } - if(click_bottom(event,*psword,start_x,start_y)){ - get_input(login_win, 7, 6, password, 15,psword,start_x,start_y); - continue; + if (willdraw) + if (click_bottom(event, *login, start_x, start_y)) { + int recall; + Login(username, password, &recall, errmsg); + if (recall != 0) { + wclear(login_win); + mvwprintw(login_win, 5, 5, "%s", errmsg); + exit->x=5;exit->y=8; + draw_bottom(login_win, exit); + wrefresh(login_win); + willdraw=0; + continue; + } + } + if (willdraw) + if (click_bottom(event, *signin, start_x, start_y)) { + free(login); + free(signin); + free(exit); + free(users); + free(psword); + endwin(); + return 3; + } + if (click_bottom(event, *exit, start_x, start_y)) { + free(login); + free(signin); + free(exit); + free(users); + free(psword); + endwin(); + return willdraw==1?1:2; } + if (willdraw) + if (click_bottom(event, *users, start_x, start_y)) { + get_input(login_win, 4, 6, username, 15, users, start_x, start_y); + continue; + } + if (willdraw) + if (click_bottom(event, *psword, start_x, start_y)) { + get_input(login_win, 7, 6, password, 15, psword, start_x, start_y); + continue; + } } } } } -int Signin_ui(){ - -} - - - - - - - - -//void draw_button(WINDOW *win, int x, int y, const char *label, bool is_active) { -// if (is_active) { -// wattron(win, A_REVERSE); // 激活按钮时反显 -// } -// mvwprintw(win, y, x + (BUTTON_WIDTH - strlen(label)) / 2, "%s", label); -// if (is_active) { -// wattroff(win, A_REVERSE); // 反显结束 -// } -// box(win, 0, 0); // 画按钮的边框 -// wrefresh(win); -//} - -//void draw_login_window() { -// // 绘制登录窗口 -// clear(); -// box(stdscr, 0, 0); -// -// // 标题 -// mvprintw(2, 20, "Login Window"); -// -// // 用户名 -// mvprintw(USERNAME_Y, USERNAME_X - 10, "Username: "); -// mvprintw(PASSWORD_Y, PASSWORD_X - 10, "Password: "); -// -// // 输入框 -// mvprintw(USERNAME_Y, USERNAME_X, "____________________________"); -// mvprintw(PASSWORD_Y, PASSWORD_X, "____________________________"); -// -// // 按钮 -// mvprintw(LOGIN_BTN_Y, LOGIN_BTN_X, "[ Login ]"); -// mvprintw(REGISTER_BTN_Y, REGISTER_BTN_X, "[ Register ]"); -// -// refresh(); -//} - -//void handle_mouse_click(MEVENT event) { -// // 处理鼠标点击事件 -// if (event.bstate & BUTTON1_CLICKED) { -// // 判断是否点击了登录按钮 -// if (event.x >= LOGIN_BTN_X && event.x <= LOGIN_BTN_X + 9 && -// event.y == LOGIN_BTN_Y) { -// printw("\nLogin button clicked!\n"); -// refresh(); -// } -// // 判断是否点击了注册按钮 -// else if (event.x >= REGISTER_BTN_X && event.x <= REGISTER_BTN_X + 11 && -// event.y == REGISTER_BTN_Y) { -// printw("\nRegister button clicked!\n"); -// refresh(); -// } -// } -//} - -void clear_input_area(int x, int y, int len) { - // 清除输入框区域 - for (int i = 0; i < len; i++) { - mvaddch(y, x + i, ' '); +int Signin_ui() { + MEVENT event; + char *errmsg[100]; + memset(errmsg, 0, 30); + int start_y = (LINES - WIN_HEIGHT) / 2; + int start_x = (COLS - WIN_WIDTH) / 2; + WINDOW *signin_win = newwin(WIN_HEIGHT, WIN_WIDTH, start_y, start_x); + keypad(signin_win, TRUE); + char *username[15]; //储存用户名 + memset(username, 0, 15); // 清空缓冲区 + char *password[15]; //储存密码 + memset(password, 0, 15); // 清空缓冲区 + struct bottom *signin = creat_bottom(signin_win, 10, 4, 5, 1, "Signin"); + struct bottom *exit = creat_bottom(signin_win, 10, 25, 5, 1, "Exit"); + struct bottom *users = creat_bottom(signin_win, 4, 4, 16, 1, "[______________]"); + struct bottom *psword = creat_bottom(signin_win, 7, 4, 16, 1, "[______________]"); + psword->private = 0; + users->private = 0; + int willdraw = 1; + while (1) { + if (willdraw)draw_signin_window(signin_win, signin, users, psword, exit); + int rc = wgetch(signin_win); + if (rc == KEY_MOUSE) { + if (nc_getmouse(&event) == OK) { + //mvwprintw(welcome_win, 3, 1, "Mouse at (%d, %d), button %d", event.x-start_x, event.y-start_y, event.bstate); + if (willdraw) + if (click_bottom(event, *signin, start_x, start_y)) { + int recall; + Signin(username,password,&recall,errmsg); + if (recall != 0) { + wclear(signin_win); + mvwprintw(signin_win, 5, 5, "%s", errmsg); + exit->x=5;exit->y=8; + draw_bottom(signin_win, exit); + wrefresh(signin_win); + willdraw=0; + continue; + } + else{ + wclear(signin_win); + mvwprintw(signin_win, 5, 5, "Accepted"); + exit->x=5;exit->y=8; + draw_bottom(signin_win, exit); + wrefresh(signin_win); + willdraw=0; + continue; + } + } + if (click_bottom(event, *exit, start_x, start_y)) { + free(signin); + free(exit); + free(users); + free(psword); + endwin(); + return willdraw==1?1:3; + } + if (willdraw) + if (click_bottom(event, *users, start_x, start_y)) { + get_input(signin_win, 4, 6, username, 15, users, start_x, start_y); + continue; + } + if (willdraw) + if (click_bottom(event, *psword, start_x, start_y)) { + get_input(signin_win, 7, 6, password, 15, psword, start_x, start_y); + continue; + } + } + } } } -//void Login_ui() { -// initscr(); // 初始化屏幕 -// cbreak(); // 禁用行缓冲 -// noecho(); // 不显示输入的字符 -// keypad(stdscr, TRUE); // 启用键盘功能(例如箭头键) -// mousemask(ALL_MOUSE_EVENTS, NULL); // 启用所有鼠标事件 -// curs_set(0); // 隐藏光标 -// -// draw_login_window(); // 绘制登录窗口 -// -// char username[MAX_INPUT_LEN + 1] = ""; -// char password[MAX_INPUT_LEN + 1] = ""; -// int ch; -// MEVENT event; -// -// while (1) { -// ch = getch(); // 获取输入 -// -// if (ch == KEY_MOUSE) { // 检查是否是鼠标事件 -// if (nc_getmouse(&event) == OK) { -// handle_mouse_click(event); // 处理鼠标点击事件 -// } -// } -// -// // 处理键盘输入(用户输入用户名和密码) -// if (ch == 10) { // 回车键 -// printw("\n登录成功!\n"); -// break; -// } -// -// // 如果是在用户名或密码框中输入 -// if (ch == KEY_BACKSPACE || ch == 127) { // 退格键 -// // 删除输入框中的最后一个字符 -// if (strlen(username) > 0) { -// username[strlen(username) - 1] = '\0'; -// clear_input_area(USERNAME_X, USERNAME_Y, MAX_INPUT_LEN); -// mvprintw(USERNAME_Y, USERNAME_X, "%s", username); -// } -// } else if (isprint(ch)) { // 只接受可打印的字符 -// if (strlen(username) < MAX_INPUT_LEN) { -// username[strlen(username)] = ch; -// username[strlen(username) + 1] = '\0'; -// mvprintw(USERNAME_Y, USERNAME_X, "%s", username); -// } -// } -// -// refresh(); -// } -// -// endwin(); // 结束 ncurses 模式 -// return; -//} -// 用于绘制按钮的函数