员工管理系统源码

head.h

#ifndef __HEAD_H__
#define __HEAD_H__
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <fcntl.h>
#include <wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <semaphore.h>
#include <signal.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/msg.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/un.h>
#include <sys/time.h>
#include <sys/select.h>
#include <poll.h>
#include <errno.h>
#include <sqlite3.h>
#include <sys/epoll.h>
#define PRINT_ERR(msg) \
        do{\
        fprintf(stderr,"line:%d ",__LINE__);\
        perror(msg);\
        return -1;\
    } while(0)
#define IF(i) if (argc != i) {\
        printf("input error,try again\n");\
        printf("usage: ./a.out srcfile destfile\n");\
        return -1;\
}
#endif

serverhead.h

#ifndef __SERVREHEAD_H_
#define __SERVERHEAD_H_
#define PORT 8888
#define IP "192.168.100.88"

struct td
{
    int newfd;
    struct sockaddr_in cin_t;
};
typedef struct staff_info
{
    char worknumber[10]; // 员工编号
    char name[10];       // 姓名
    char passwd[10];     // 密码
    char age[5];         // 年龄
    char phone[15];      // 电话
    char addr[40];       // 地址
    char work[20];       // 职位
    char date[30];       // 入职时间
    char level[2];          // 等级
    double salary;       // 工资
} staff_info_t;
typedef struct
{
    int msgtype;            // 请求的消息类型
    char worknumber[20];    // 员工编号
    char level;          // 等级
    char recvmsg[256];  // 通信的消息
    int flags;              // 标志位
    staff_info_t info;      // 员工信息
} MSG;

void *request(void *arg);
sqlite3 *init_sql();
int Users_logoff();
int init_tcpser(char *ip, int port);
int IsuserExist(char *name);
char getusrlevel(char *name);
int Login(int sfd);
int User_isonline(char *name);
int User_online(char *name);
int User_logoff();
int Register(int sfd);
int Delete(int sfd);
int Update(int sfd);
int Query(int sfd);
int do_select(int sfd);
int do_history(char *event);
char *gettime();
int select_history(int sfd);
#endif

cilend.h

#ifndef __CLIENDHEAD_H_
#define __CLIENDHEAD_H_
#define PORT 8888
#define IP "192.168.100.88"

struct td
{
    int newfd;
    struct sockaddr_in cin_t;
};
typedef struct staff_info
{
    char worknumber[10]; // 员工编号
    char name[10];       // 姓名
    char passwd[10];     // 密码
    char age[5];         // 年龄
    char phone[15];      // 电话
    char addr[40];       // 地址
    char work[20];       // 职位
    char date[30];       // 入职时间
    char level[2];          // 等级
    double salary;       // 工资
} staff_info_t;
typedef struct
{
    int msgtype;            // 请求的消息类型
    char worknumber[20];    // 员工编号
    char level;          // 等级
    char recvmsg[256];  // 通信的消息
    int flags;              // 标志位
    staff_info_t info;      // 员工信息
} MSG;

typedef void (*sighandler_t)(int);
void handler(int sig);
int init_tcpcli(char *ip, int port);
int Login_page(int sfd);
int main_page_root(int sfd);
int main_page_ordinary(int sfd);
int Login(int sfd);
int Register(int sfd);
int Delete(int sfd);
int Update(int sfd);
int Query(int sfd);
int dict_select(int sfd);
int select_history(int sfd);
int end(int sfd);
#endif

###tcpser_staff.c

#include <head.h>
#include "serverhead.h"
staff_info_t info;
MSG msg;
int const size = sizeof(msg);
//存放日志信息
char event[400];
sqlite3 *db;
int epfd;
//事件的集合
struct epoll_event events[20];
int main(int argc, const char *argv[])
{
    int epct;
    // 初始化数据库
    db = init_sql();
    // 初始化tcp服务器
    int sfd = init_tcpser(IP, PORT);
    // 存储客户端信息
    struct td td_t, td_s[20];
    // 消息结构体大小
    socklen_t addrlen = sizeof(struct sockaddr_in);
    // 使用epoll进行IO多路复用
    struct epoll_event event;
    epfd = epoll_create(1);
    event.events = EPOLLIN;
    event.data.fd = sfd;
    if (epoll_ctl(epfd, EPOLL_CTL_ADD, sfd, &event) < 0)
        PRINT_ERR("epoll_ctl");
    while (1)
    {
        epct = epoll_wait(epfd, events, 20, -1);
        for (int i = 0; i < epct; i++)
        {
            if (events[i].data.fd == sfd)
            { // 如果事件的fd是监听fd,调用accept处理

                td_t.newfd = accept(sfd, (struct sockaddr *)&td_t.cin_t, &addrlen);
                if (td_t.newfd < 0)
                    PRINT_ERR("accept");
                event.events = EPOLLIN;
                event.data.fd = td_t.newfd;
                // 添加clientfd描述符
                epoll_ctl(epfd, EPOLL_CTL_ADD, td_t.newfd, &event);
                printf("[%s:%d] newfd:%d 成功连接\n", inet_ntoa(td_t.cin_t.sin_addr), ntohs(td_t.cin_t.sin_port), td_t.newfd);
                td_s[td_t.newfd].newfd = td_t.newfd;
                td_s[td_t.newfd].cin_t = td_t.cin_t;
            }
            else
            {
                request((void *)&td_s[events[i].data.fd]);
            }
        }
    }
    close(sfd);

    return 0;
}
// 处理请求函数
void *request(void *arg)
{
    struct td *p = (struct td *)arg;
    int newfd = p->newfd;
    struct sockaddr_in cin_t = p->cin_t;
    ssize_t res;
    res = recv(newfd, &msg, size, 0);
    if (res == 0)
    {
        printf("客户端断开,关闭newfd:%d\n", newfd);
        //删除监听的文件描述符
        epoll_ctl(epfd, EPOLL_CTL_DEL, newfd,NULL);
        close(newfd);
        return NULL;
    }
    switch (msg.msgtype)
    {
    case 1:
        printf("[%s:%d] newfd:%d请求注册\n", inet_ntoa(cin_t.sin_addr),
               ntohs(cin_t.sin_port), newfd);
        Register(newfd);
        //导入日志信息
        do_history(event);
        break;
    case 2:
        printf("[%s:%d] newfd:%d请求登录\n", inet_ntoa(cin_t.sin_addr),
               ntohs(cin_t.sin_port), newfd);
        Login(newfd);
        do_history(event);
        break;
    case 3:
        printf("[%s:%d] newfd:%d请求删除员工\n", inet_ntoa(cin_t.sin_addr),
               ntohs(cin_t.sin_port), newfd);
        Delete(newfd);
        do_history(event);
        break;
    case 4:
        printf("[%s:%d] newfd:%d请求修改员工信息\n", inet_ntoa(cin_t.sin_addr),
               ntohs(cin_t.sin_port), newfd);
        Update(newfd);
        do_history(event);
        break;
    case 5:
        printf("[%s:%d] newfd:%d准备下线\n", inet_ntoa(cin_t.sin_addr),
               ntohs(cin_t.sin_port), newfd);
        User_logoff();
        do_history(event);
        break;
    case 6:
        printf("[%s:%d] newfd:%d查询个人信息\n", inet_ntoa(cin_t.sin_addr),
               ntohs(cin_t.sin_port), newfd);
        Query(newfd);
        do_history(event);
        break;
    case 7:
        printf("[%s:%d] newfd:%d查询所有信息\n", inet_ntoa(cin_t.sin_addr),
               ntohs(cin_t.sin_port), newfd);
        Query(newfd);
        do_history(event);
        break;
    case 8:
        printf("[%s:%d] newfd:%d查看日志信息\n", inet_ntoa(cin_t.sin_addr),
               ntohs(cin_t.sin_port), newfd);
        select_history(newfd);
        do_history(event);
        break;
    default:
        break;
    }
}
// 初始化数据库
sqlite3 *init_sql()
{
    if (sqlite3_open("sql.db", &db) != SQLITE_OK)
    {
        fprintf(stderr, "line:%d sqlite3_open:%s\n", __LINE__, sqlite3_errmsg(db));
        return NULL;
    }
    //添加日志表
    char sql[256] = "create table if not exists history (time char,worknumber char,event char);";
    char *errmsg = NULL;
    if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
    {
        fprintf(stderr, "line:%d sqlite3_exec:%s\n", __LINE__, errmsg);
        return NULL;
    }
    //添加用户表
    strcpy(sql, "create table if not exists usr (worknumber char primary key,password char,name char,age char,phone char,addr char,work char,time char,level char,salary double,flag char);");
    if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
    {
        fprintf(stderr, "line:%d sqlite3_exec:%s\n", __LINE__, errmsg);
        return NULL;
    }
    // 将所有用户置于下线状态
    Users_logoff();
    printf("数据库初始化完毕\n");
    return db;
}
// 添加管理员将所有用户置于下线状态
int Users_logoff()
{
    char sql[128];
    // 将所有用户flag置零
    char *errmsg = NULL;
    sprintf(sql, "UPDATE usr SET flag='0';");
    if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
    {
        fprintf(stderr, "line:%d sqlite3_exec:%s\n", __LINE__, errmsg);
        return -1;
    }
    // 检查是否已有管理员
    sprintf(sql, "select * from usr where worknumber='%s';", "00");
    char **pres;
    int row, column;
    if (sqlite3_get_table(db, sql, &pres, &row, &column, &errmsg) != SQLITE_OK)
    {
        fprintf(stderr, "line:%d sqlite3_get_table:%s\n", __LINE__, errmsg);
        return -1;
    }
    sqlite3_free_table(pres);
    if (row == 0)
    {
        // 添加一名管理员
        char time[30];
        strcpy(time, gettime());
        time[10] = '\0';
        sprintf(sql, "INSERT INTO usr VALUES (\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%-10s\",\"%s\",%f,\"%s\");", "00", "123456", "zt", "21", "19856602562", "hqyj", "CEO", time, "0", 12000.00, "0");
        if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
        {
            fprintf(stderr, "line:%d sqlite3_get_table:%s\n", __LINE__, errmsg);
            return -1;
        }
        printf("添加管理员成功\n");
    }
    return 0;
}
// 判断用户是否存在
int IsuserExist(char *name)
{
    char sql[128];
    char *errmsg = NULL;
    sprintf(sql, "select * from usr where worknumber='%s';", name);
    char **pres;
    int row, column;
    if (sqlite3_get_table(db, sql, &pres, &row, &column, &errmsg) != SQLITE_OK)
    {
        fprintf(stderr, "line:%d sqlite3_get_table:%s\n", __LINE__, errmsg);
        return -1;
    }
    sqlite3_free_table(pres);
    // row=0,即没有查询结果,不存在用户
    return (row != 0) ? 1 : 0;
}
// 获取用户等级
char getusrlevel(char *name)
{
    char sql[128];
    char *errmsg = NULL;
    sprintf(sql, "select level from usr where worknumber='%s';", name);
    char **pres;
    int row, column;
    if (sqlite3_get_table(db, sql, &pres, &row, &column, &errmsg) != SQLITE_OK)
    {
        fprintf(stderr, "line:%d sqlite3_get_table:%s\n", __LINE__, errmsg);
        return 0;
    }
    sqlite3_free_table(pres);
    return *pres[1];
}
// 初始化tcp服务器
int init_tcpser(char *ip, int port)
{
    // 创建流式套接字
    int sfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sfd < 0)
        PRINT_ERR("socket");
    // 允许端口快速重用
    int reuse = 1;
    if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
        PRINT_ERR("setsockopt");
    // 填充地址信息的结构体,将IP和端口号绑定到套接字上
    struct sockaddr_in sin_t;
    sin_t.sin_family = AF_INET;
    sin_t.sin_port = htons(port);
    sin_t.sin_addr.s_addr = inet_addr(ip);
    // 绑定服务器的ip和端口
    if (bind(sfd, (struct sockaddr *)&sin_t, sizeof(sin_t)) < 0)
        PRINT_ERR("bind");
    // 将套接字设置为监听状态
    if (listen(sfd, 128) < 0)
        PRINT_ERR("listen");
    printf("服务器初始化完成\n");
    return sfd;
}
// 客户端登录
int Login(int sfd)
{
    printf("工号:%s 密码:%s\n", msg.info.worknumber, msg.info.passwd);
    char sql[128];
    char *errmsg = NULL;
    sprintf(sql, "select * from usr where worknumber='%s';", msg.info.worknumber);
    char **pres;
    int row, column;
    if (sqlite3_get_table(db, sql, &pres, &row, &column, &errmsg) != SQLITE_OK)
    {
        fprintf(stderr, "line:%d sqlite3_get_table:%s\n", __LINE__, errmsg);
        return -1;
    }
    // row=0,即没有查询结果,不存在用户
    if (row == 0)
    {
        strcpy(event, "登录失败,不存在该用户");
        // 不存在该用户发送0
        printf("不存在该用户\n");
        msg.flags = -2;
        if (send(sfd, &msg, size, 0) < 0)
            PRINT_ERR("send");
    }
    // 判断密码是否相同
    else if (strcmp(pres[12], msg.info.passwd) == 0)
    {
        // 判断用户是否在线
        if (User_isonline(msg.info.worknumber) == 1)
        { // 用户已在线发送3
            msg.flags = -4;
            strcpy(event, "登录失败,用户已在线");
            if (send(sfd, &msg, size, 0) < 0)
                PRINT_ERR("send");
            return -1;
        }
        // 将用户flag置1
        User_online(msg.info.worknumber);
        //获取用户等级
        msg.level=getusrlevel(msg.info.worknumber);
        strcpy(msg.worknumber,msg.info.worknumber);
        strcpy(event, "登录成功");
        printf("登录成功\n");
        // 登录成功发送1
        msg.flags = 1;
        if (send(sfd, &msg, size, 0) < 0)
            PRINT_ERR("send");
    }
    else
    {
        // 密码不对发送2
        strcpy(event, "登录失败,密码不正确");
        printf("密码不正确\n");
        msg.flags = -3;
        if (send(sfd, &msg, sizeof(msg), 0) < 0)
            PRINT_ERR("send");
    }
    sqlite3_free_table(pres);
    return 0;
}
// 判断用户是否在线,在线为1,反之为0
int User_isonline(char *name)
{
    char sql[128];
    sprintf(sql, "select flag from usr where worknumber='%s';", name);
    char *errmsg = NULL;
    char **pres;
    int row, column;
    if (sqlite3_get_table(db, sql, &pres, &row, &column, &errmsg) != SQLITE_OK)
    {
        fprintf(stderr, "line:%d sqlite3_get_table:%s\n", __LINE__, errmsg);
        return -1;
    }
    // 判断flag是否为1
    if (strcmp(pres[1], "1") == 0)
    {
        sqlite3_free_table(pres);
        return 1;
    }
    else
    {
        sqlite3_free_table(pres);
        return 0;
    }
}
// 用户上线,将flag置1
int User_online(char *worknumber)
{
    char sql[128];
    sprintf(sql, "UPDATE usr SET flag='1' WHERE worknumber='%s';", worknumber);
    char *errmsg = NULL;
    if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
    {
        fprintf(stderr, "line:%d sqlite3_exec:%s\n", __LINE__, errmsg);
        return -1;
    }
    return 0;
}
// 用户下线,将flag置0
int User_logoff()
{
    char sql[128];
    sprintf(sql, "UPDATE usr SET flag='0' WHERE worknumber='%s';", msg.worknumber);
    char *errmsg = NULL;
    if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
    {
        fprintf(stderr, "line:%d sqlite3_exec:%s\n", __LINE__, errmsg);
        return -1;
    }
    strcpy(event, "用户下线");
    printf("工号:%s 退出登录!\n", msg.worknumber);
    return 0;
}
// 添加用户
int Register(int sfd)
{
    printf("工号:%s 密码:%s\n", msg.info.worknumber, msg.info.passwd);
    char sql[256];
    char *errmsg = NULL;
    // 导入用户表,默认flag为0
    sprintf(sql, "INSERT INTO usr VALUES (\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",%f,\"%s\");", msg.info.worknumber, msg.info.name, msg.info.passwd,
            msg.info.age, msg.info.phone, msg.info.addr, msg.info.work, msg.info.date, msg.info.level, msg.info.salary, "0");
    if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
    {
        printf("注册失败,已有该用户\n");
        sprintf(event, "注册用户:%s 失败,已有该用户", msg.info.worknumber);
        msg.flags = -2;
        // 注册失败向客户端发送0
        if (send(sfd, &msg, size, 0) < 0)
            PRINT_ERR("send");
        return -1;
    }
    printf("注册成功\n");
    sprintf(event, "注册用户:%s 成功", msg.info.worknumber);
    msg.flags = 1;
    // 注册成功向客户端发送1
    if (send(sfd, &msg, size, 0) < 0)
        PRINT_ERR("send");
    return 0;
}
// 删除用户
int Delete(int sfd)
{
    printf("工号:%s\n", msg.info.worknumber);
    if (IsuserExist(msg.info.worknumber) == 0)
    {
        msg.flags = -2;
        printf("没有该用户\n");
        sprintf(event, "删除用户:%s 失败,没有该用户", msg.info.worknumber);
        // 没有该用户向客户端发送-1
        if (send(sfd, &msg, size, 0) < 0)
            PRINT_ERR("send");
        return -1;
    }
    char sql[128];
    char *errmsg = NULL;
    // 导入用户表,默认flag为0
    sprintf(sql, "delete from usr where worknumber='%s';", msg.info.worknumber);
    if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
    {
        printf("删除失败\n");
        sprintf(event, "删除用户:%s 失败", msg.info.worknumber);
        msg.flags = -1;
        // 删除失败失败向客户端发送0
        if (send(sfd, &msg, size, 0) < 0)
            PRINT_ERR("send");
        return -1;
    }
    printf("删除成功\n");
    sprintf(event, "删除用户:%s 成功", msg.info.worknumber);
    msg.flags = 1;
    // 删除成功向客户端发送1
    if (send(sfd, &msg, size, 0) < 0)
        PRINT_ERR("send");
    return 0;
}
// 修改用户信息
int Update(int sfd)
{
    printf("工号:%s\n", msg.info.worknumber);
    if (IsuserExist(msg.info.worknumber) == 0)
    {
        msg.flags = -2;
        printf("没有该用户\n");
        sprintf(event, "修改用户:%s 的信息失败,没有该用户", msg.info.worknumber);
        // 没有该用户向客户端发送-1
        if (send(sfd, &msg, size, 0) < 0)
            PRINT_ERR("send");
        return -1;
    }
    char sql[512];
    char *errmsg = NULL;
    // 导入用户表,默认flag为0
    sprintf(sql, "UPDATE usr SET '%s'='%s' WHERE worknumber='%s';", msg.recvmsg, msg.info.addr, msg.info.worknumber);
    if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
    {
        printf("修改失败\n");
        sprintf(event, "修改用户:%s 的信息失败", msg.info.worknumber);
        msg.flags = -1;
        // 修改失败向客户端发送0
        if (send(sfd, &msg, size, 0) < 0)
            PRINT_ERR("send");
        return -1;
    }
    printf("修改成功\n");
    sprintf(event, "将用户:%s的%s修改为%s", msg.info.worknumber, msg.recvmsg, msg.info.addr);
    msg.flags = 1;
    // 修改成功向客户端发送1
    if (send(sfd, &msg, size, 0) < 0)
        PRINT_ERR("send");
    return 0;
}
// 查询用户信息
int Query(int sfd)
{
    char sql[128];
    if (msg.msgtype == 6)
    {
        printf("工号:%s\n", msg.info.worknumber);
        if (IsuserExist(msg.info.worknumber) == 0)
        {
            // 没有该用户向客户端发送-2
            msg.flags = -2;
            printf("没有该用户\n");
            sprintf(event, "查询用户:%s 的信息失败,没有该用户", msg.info.worknumber);
            if (send(sfd, &msg, size, 0) < 0)
                PRINT_ERR("send");
            return -1;
        }
        sprintf(event, "查询用户:%s 的信息成功", msg.info.worknumber);
        sprintf(sql, "select * from usr where worknumber='%s';", msg.info.worknumber);
    }
    else
    {
        sprintf(sql, "select * from usr;");
        sprintf(event, "查询所有用户的信息成功");
    }
    char **pres;
    char *errmsg = NULL;
    int row, column;
    if (sqlite3_get_table(db, sql, &pres, &row, &column, &errmsg) != SQLITE_OK)
    {
        fprintf(stderr, "line:%d sqlite3_get_table:%s\n", __LINE__, errmsg);
        return -1;
    }
    if (row == 0)
    { // 没有查询到发送-1
        sprintf(event, "查询用户信息失败");
        msg.flags = -1;
        if (send(sfd, &msg, size, 0) < 0)
            PRINT_ERR("send");
        return 0;
    }
    // 有数据发送1;
    msg.flags = 1;
    if (send(sfd, &msg, size, 0) < 0)
        PRINT_ERR("send");
    for (int i = column; i + 1 < (row + 1) * column; i += 11)
    { // 循环发送
        sprintf(msg.recvmsg, "║%-6s║%-10s║%-6s║%-6s║%-13s║%-6s║%-6s║%-10s║%-6s║%-10s║%-8s║\n", pres[i], pres[i + 1],
                pres[i + 2], pres[i + 3], pres[i + 4], pres[i + 5], pres[i + 6], pres[i + 7], pres[i + 8], pres[i + 9], pres[i + 10]);
        if (send(sfd, &msg, size, 0) < 0)
            PRINT_ERR("send");
    }
    // 发送完,发送2表示发送完毕
    msg.flags = 2;
    if (send(sfd, &msg, size, 0) < 0)
        PRINT_ERR("send");
    msg.flags = 0;
    sqlite3_free_table(pres);
    return 0;
}
// 将信息导入历史记录
int do_history(char *event)
{
    char sql[256] = "";
    char *errmsg = NULL;
    char *times = gettime();
    sprintf(sql, "INSERT INTO history VALUES ('%s','%s','%s');", gettime(), msg.worknumber, event);
    if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
    {
        fprintf(stderr, "line:%d sqlite3_exec:%s\n", __LINE__, errmsg);
        return -1;
    }
    return 0;
}
// 获取当前时间
char *gettime()
{
    time_t ts;
    struct tm *tm;
    char *times = (char *)malloc(50);
    ts = time(NULL);
    tm = localtime(&ts);
    sprintf(times, "%d-%02d-%02d %02d:%02d:%02d", tm->tm_year + 1900,
            tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
    return times;
}
// 客户端查询日志信息
int select_history(int sfd)
{
    char sql[128];
    sprintf(sql, "select * from history;");
    char **pres;
    char *errmsg = NULL;
    int row, column;
    if (sqlite3_get_table(db, sql, &pres, &row, &column, &errmsg) != SQLITE_OK)
    {
        fprintf(stderr, "line:%d sqlite3_get_table:%s\n", __LINE__, errmsg);
        return -1;
    }
    if (row == 0)
    { // 没有查询到发送0
        if (send(sfd, &msg, size, 0) < 0)
            PRINT_ERR("send");
        msg.flags = 0;
        return 0;
    }
    //有数据发送1
    msg.flags = 1;
    if (send(sfd, &msg, size, 0) < 0)
        PRINT_ERR("send");
    for (int i = column; i + 1 < (row + 1) * column; i += 3)
    {
        sprintf(msg.recvmsg, "║%-20s║%-5s║%-s\n", pres[i], pres[i + 1], pres[i + 2]);
        if (send(sfd, &msg, size, 0) < 0)
            PRINT_ERR("send");
    }
    // 发送完,再次发送2表示发送完毕
    sprintf(event, "查看日志信息");
    msg.flags = 2;
    if (send(sfd, &msg, size, 0) < 0)
        PRINT_ERR("send");
    sqlite3_free_table(pres);
    return 0;
}

tcpcli_staff.c

#include <head.h>
#include "cliendhead.h"
staff_info_t info;
MSG msg;
int const size = sizeof(msg);
int sfd;
int main(int argc, const char *argv[])
{
    // 初始化tcp客户端
    sfd = init_tcpcli(IP, PORT);
    // 捕获ctrl+c信号
    signal(2, handler);
LD: // 登录页面
    if (Login_page(sfd) == -1)
    { // 返回值为-1,说明用户选择退出
        goto END;
    }
    int a;
    // 先判断用户等级是否为管理员
    if (msg.level == '0')
    { // 主页面
        a = main_page_root(sfd);
    }
    else
    {
        a = main_page_ordinary(sfd);
    }
    if (a == -1)
    { // 返回值为-1,说明用户选择退出
        goto END;
    }
    else if (a == 1)
    { // 返回值为1,说明用户选择返回,返回前先下线账号
        end(sfd);
        // 返回上一级退出当前账号,将用户名清空
        bzero(&msg, size);
        goto LD;
    }
END:
    handler(1);
    return 0;
}
// 捕捉信号后的处理函数(退出函数)
void handler(int sig)
{
    // 判断用户是否已登录,还未登录不用发送离线消息
    if (strlen(msg.worknumber) != 0)
        end(sfd);
    close(sfd);
    printf("\n谢谢使用\n");
    exit(0);
}
// 初始化客户端
int init_tcpcli(char *ip, int port)
{
    // 创建流式套接字
    int sfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sfd < 0)
        PRINT_ERR("socket");
    struct sockaddr_in sin_t;
    sin_t.sin_family = AF_INET;
    sin_t.sin_port = htons(port);
    sin_t.sin_addr.s_addr = inet_addr(ip);
    if (connect(sfd, (struct sockaddr *)&sin_t, sizeof(sin_t)) < 0)
        PRINT_ERR("connect");
    printf("成功连接服务器[%s:%d]\n", inet_ntoa(sin_t.sin_addr), ntohs(sin_t.sin_port));
    return sfd;
}
// 登录页面
int Login_page(int sfd)
{
    char c;
    while (1)
    {
        system("clear");
        printf("\033[2J\033[?25l"); // 清屏和隐藏光标
        printf("\033[47m");         // 设置背景色
        printf("\033[34m");         // 设置前景色
        printf("\033[1m");          // 字体加粗
        printf("\n");
        printf("╔══════════════════════════════════════════╗\n");
        printf("║              员 工 管 理 系 统           ║\n");
        printf("╟══════════════════════════════════════════╢\n");
        printf("║                  1.登录                  ║\n");
        printf("║                                          ║\n");
        printf("║                  2.退出                  ║\n");
        printf("║                                          ║\n");
        printf("╚══════════════════════════════════════════╝\n");
        printf("\033[0m"); // 恢复颜色
        printf("\n");
        printf("\033[31m"); // 设置前景色
        printf("请输入>>>");
        c = getchar();
        while (getchar() != 10)
            ;
        switch (c)
        {
        case '1':
            c = Login(sfd);
            break;
        case '2':
            return -1;
        default:
            printf("请输入正确的选项\n");
            break;
        }
        if (c == 1)
        {
            printf("输入任意字符跳转>>>");
            while (getchar() != 10)
                ;
            break;
        }
        printf("输入任意字符清屏>>>");
        while (getchar() != 10)
            ;
    }
    return c;
}
// 主页面(root用户)
int main_page_root(int sfd)
{
    while (1)
    {
        system("clear");
        printf("\033[47m"); // 设置背景色
        printf("\033[34m"); // 设置前景色
        printf("\033[1m");  // 字体加粗
        printf("\n");
        printf("╔══════════════════════════════════════════╗\n");
        printf("║              员 工 管 理 系 统           ║\n");
        printf("╟══════════════════════════════════════════╢\n");
        printf("║       1.添加员工         2.删除员工      ║\n");
        printf("║       3.修改信息         4.查询个人信息  ║\n");
        printf("║       5.查询所有信息     6.查看日志      ║\n");
        printf("║       7.切换账号         8.退出系统      ║\n");
        printf("╚══════════════════════════════════════════╝");
        printf("\033[0m"); // 恢复颜色
        printf("\n\n");
        printf("\033[31m"); // 设置前景色
        printf("请输入>>>");
        char c = getchar();
        while (getchar() != 10)
            ;
        switch (c)
        {
        case '1':
            Register(sfd);
            break;
        case '2':
            Delete(sfd);
            break;
        case '3':;
            Update(sfd);
            break;
        case '4':
            msg.msgtype = 6;
            Query(sfd);
            break;
        case '5':;
            msg.msgtype = 7;
            Query(sfd);
            break;
        case '6':
            select_history(sfd);
            break;
        case '7':;
            return 1;
            break;
        case '8':
            return -1;
            break;
        default:
            printf("请输入正确的选项\n");
            break;
        }
        printf("输入任意字符清屏>>>");
        while (getchar() != 10)
            ;
    }
    return 0;
}
// 主页面(普通用户)
int main_page_ordinary(int sfd)
{
    while (1)
    {
        system("clear");
        printf("\033[47m"); // 设置背景色
        printf("\033[34m"); // 设置前景色
        printf("\033[1m");  // 字体加粗
        printf("\n");
        printf("╔══════════════════════════════════════════╗\n");
        printf("║              员 工 管 理 系 统           ║\n");
        printf("╟══════════════════════════════════════════╢\n");
        printf("║       1.修改信息         2.查询个人信息  ║\n");
        printf("║       3.切换账号         4.退出系统      ║\n");
        printf("╚══════════════════════════════════════════╝");
        printf("\033[0m"); // 恢复颜色
        printf("\n\n");
        printf("\033[31m"); // 设置前景色
        printf("请输入>>>");
        char c = getchar();
        while (getchar() != 10)
            ;
        switch (c)
        {
        case '1':;
            Update(sfd);
            break;
        case '2':
            msg.msgtype = 6;
            Query(sfd);
            break;
        case '3':
            return 1;
            break;
        case '4':
            return -1;
            break;
        default:
            printf("请输入正确的选项\n");
            break;
        }
        printf("输入任意字符清屏>>>");
        while (getchar() != 10)
            ;
    }
    return 0;
}
// 修改
int Update(int sfd)
{
    if (msg.level == '0')
    {
        printf("请输入要修改的工人工号>>>");
        scanf("%s", msg.info.worknumber);
        getchar();
    ANEW1:
        system("clear");
        printf("\033[47m"); // 设置背景色
        printf("\033[34m"); // 设置前景色
        printf("\033[1m");  // 字体加粗
        printf("\n");
        printf("╔══════════════════════════════════════════╗\n");
        printf("║                   选项                   ║\n");
        printf("╟══════════════════════════════════════════╢\n");
        printf("║       1.员工编号         2.员工姓名      ║\n");
        printf("║       3.员工密码         4.员工年龄      ║\n");
        printf("║       5.员工电话         6.员工地址      ║\n");
        printf("║       7.员工职位         8.入职时间      ║\n");
        printf("║       9.员工等级         10.员工工资     ║\n");
        printf("╚══════════════════════════════════════════╝");
        printf("\033[0m"); // 恢复颜色
        printf("\n\n");
        printf("\033[31m"); // 设置前景色
        printf("请输入>>>");
        scanf("%d", &msg.flags);
        getchar();
        switch (msg.flags)
        {
        case 1:
            strcpy(msg.recvmsg, "worknumber");
            break;
        case 2:
            strcpy(msg.recvmsg, "name");
            break;
        case 3:
            strcpy(msg.recvmsg, "password");
            break;
        case 4:
            strcpy(msg.recvmsg, "age");
            break;
        case 5:
            strcpy(msg.recvmsg, "phone");
            break;
        case 6:
            strcpy(msg.recvmsg, "addr");
            break;
        case 7:
            strcpy(msg.recvmsg, "work");
            break;
        case 8:
            strcpy(msg.recvmsg, "time");
            break;
        case 9:
            strcpy(msg.recvmsg, "lever");
            break;
        case 10:
            strcpy(msg.recvmsg, "salary");
            break;
        default:
            printf("请重新输入!\n");
            printf("输入任意字符清屏>>>");
            while (getchar() != 10)
                ;
            goto ANEW1;
        }
    }
    else
    {
        strcpy(msg.info.worknumber, msg.worknumber);
    ANEW2:
        system("clear");
        printf("\033[47m"); // 设置背景色
        printf("\033[34m"); // 设置前景色
        printf("\033[1m");  // 字体加粗
        printf("\n");
        printf("╔══════════════════════════════════════════╗\n");
        printf("║                   选项                   ║\n");
        printf("╟══════════════════════════════════════════╢\n");
        printf("║       1.员工姓名         2.员工密码      ║\n");
        printf("║       3.员工电话         4.员工地址      ║\n");
        printf("╚══════════════════════════════════════════╝");
        printf("\033[0m"); // 恢复颜色
        printf("\n\n");
        printf("\033[31m"); // 设置前景色
        printf("请输入>>>");
        scanf("%d", &msg.flags);
        getchar();
        switch (msg.flags)
        {
        case 1:
            strcpy(msg.recvmsg, "name");
            break;
        case 2:
            strcpy(msg.recvmsg, "password");
            break;
        case 3:
            strcpy(msg.recvmsg, "phone");
            break;
        case 4:
            strcpy(msg.recvmsg, "addr");
            break;
        default:
            printf("请重新输入!\n");
            printf("输入任意字符清屏>>>");
            while (getchar() != 10)
                ;
            goto ANEW2;
        }
    }
    printf("请输入修改后的值>>>");
    scanf("%s", msg.info.addr);
    msg.msgtype = 4;
    while (getchar() != 10)
        ;
    if (send(sfd, &msg, size, 0) < 0)
        PRINT_ERR("send");
    if (recv(sfd, &msg, size, 0) < 0)
        PRINT_ERR("recv");
    if (msg.flags == 1)
    {
        printf("修改成功\n");
        return 1;
    }
    else if (msg.flags == -1)
        printf("修改失败\n");
    else if (msg.flags == -2)
        printf("没有该用户\n");
    return 0;
}
// 删除
int Delete(int sfd)
{
    printf("请输入要删除的员工工号>>>");
    scanf("%s", msg.info.worknumber);
    msg.msgtype = 3;
    while (getchar() != 10)
        ;
    if (send(sfd, &msg, size, 0) < 0)
        PRINT_ERR("send");
    if (recv(sfd, &msg, size, 0) < 0)
        PRINT_ERR("recv");
    if (msg.flags == 1)
    {
        printf("删除成功\n");
        return 1;
    }
    else if (msg.flags == -1)
        printf("删除失败\n");
    else if (msg.flags == -2)
        printf("没有该用户\n");
    return 0;
}
// 查询
int Query(int sfd)
{
    if (msg.level == '0')
    {
        if (msg.msgtype == 6)
        {
            printf("请输入要查询的员工工号>>>");
            scanf("%s", msg.info.worknumber);
            while (getchar() != 10)
                ;
        }
    }else
    {
        msg.msgtype == 6;
        strcpy(msg.info.worknumber,msg.worknumber);
    }
    
    if (send(sfd, &msg, size, 0) < 0)
        PRINT_ERR("send");
    if (recv(sfd, &msg, size, 0) < 0)
        PRINT_ERR("recv");
    if (msg.flags == 1)
    {
        system("clear");
        printf("查询成功\n");
        printf("\033[47m"); // 设置背景色
        printf("\033[34m"); // 设置前景色
        printf("\033[1m");  // 字体加粗
        printf("\n");
        printf("╔═════════════════════════════════════════════════════════════════════════════════════════════════╗\n");
        printf("║%-6s  ║%-10s  ║%-6s  ║%-6s  ║%-13s   ║%-6s  ║%-6s  ║%-10s  ║%-6s  ║%-10s  ║%-8s║\n", "工号", "密码", "姓名", "年龄", "手机号", "地址", "职位", "入职时间", "等级", "工资", "是否在线");
        printf("╟═════════════════════════════════════════════════════════════════════════════════════════════════╢\n");
        while (1)
        {
            if (recv(sfd, &msg, size, 0) < 0)
                PRINT_ERR("recv");
            if (msg.flags == 2)
                break;
            printf("%s", msg.recvmsg);
        }
        printf("╚═════════════════════════════════════════════════════════════════════════════════════════════════╝");
        printf("\033[0m"); // 恢复颜色
        printf("\n\n");
        printf("\033[31m"); // 设置前景色
        return 1;
    }
    else if (msg.flags == -1)
        printf("查询失败\n");
    else if (msg.flags == -2)
        printf("没有该用户\n");
    return 0;
}
// 查看日志
int select_history(int sfd)
{
    msg.msgtype = 8;
    if (send(sfd, &msg, size, 0) < 0)
        PRINT_ERR("send");
    if (recv(sfd, &msg, size, 0) < 0)
        PRINT_ERR("recv");
    if (msg.flags == 1)
    {
        system("clear");
        printf("查询成功\n");
        printf("╔══════════════════════════════════════════════════\n");
        printf("║%-22s║%-7s║%-38s\n", "时间", "用户", "事件");
        printf("╟══════════════════════════════════════════════════\n");
        while (1)
        {
            if (recv(sfd, &msg, size, 0) < 0)
                PRINT_ERR("recv");
            if (msg.flags == 2)
                break;
            printf("%s", msg.recvmsg);
        }
        printf("╚══════════════════════════════════════════════════");
        printf("\n");
        return 1;
    }
    else if (msg.flags == -1)
        printf("查询失败\n");

    return 0;
}
// 登录
int Login(int sfd)
{
    printf("(账号和密码用空格隔开)\n");
    printf("请输入账号和密码>>>");
    scanf("%s %s", msg.info.worknumber, msg.info.passwd);
    while (getchar() != 10)
        ;
    msg.msgtype = 2;
    if (send(sfd, &msg, size, 0) < 0)
        PRINT_ERR("send");
    if (recv(sfd, &msg, size, 0) < 0)
        PRINT_ERR("recv");
    if (msg.flags == 1)
    {
        printf("登录成功\n");
        // 登录成功将次客户端与工号绑定
        strcpy(msg.worknumber, msg.info.worknumber);
        return 1;
    }
    else if (msg.flags == -2)
        printf("不存在该用户\n");
    else if (msg.flags == -3)
        printf("密码不正确\n");
    else if (msg.flags == -4)
        printf("账号已在别处登录\n");
    return 0;
}
// 注册
int Register(int sfd)
{
    printf("请输入要注册的员工编号、姓名、密码、年龄、电话、地址、职位、入职时间、等级、工资 \n");
    scanf("%s %s %s %s %s %s %s %s %s %lf", msg.info.worknumber, msg.info.name, msg.info.passwd,
          msg.info.age, msg.info.phone, msg.info.addr, msg.info.work, msg.info.date, msg.info.level, &msg.info.salary);
    msg.msgtype = 1;
    while (getchar() != 10)
        ;
    if (send(sfd, &msg, size, 0) < 0)
        PRINT_ERR("send");
    if (recv(sfd, &msg, size, 0) < 0)
        PRINT_ERR("recv");
    if (msg.flags == 1)
        printf("注册成功\n");
    else
        printf("注册失败,已存在该用户\n");
    return 0;
}
// 下线
int end(int sfd)
{
    msg.msgtype = 5;
    // 封装数据包,5代表该用户下线
    if (send(sfd, &msg, size, 0) < 0)
        PRINT_ERR("send");
    printf("\033[0m"); // 恢复颜色
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值