员工管理系统

项目需求:

1)服务器负责管理所有员工表单(以数据库形式),其他客户端可通过网络连接服务器来查询员工表单。

2)需要账号密码登陆,其中需要区分管理员账号还是普通用户账号。

3)管理员账号可以查看、修改、添加、删除员工信息,同时具有查询历史记录功能,管理员要负责管理所有的普通用户。

4)普通用户只能查询修改与本人有关的相关信息,其他员工信息不得查看修改。

5)服务器能同时相应多台客户端的请求功能。

服务器流程图:

客户端流程图:

服务器端:

ser.c :

#include <stdio.h>
#include <string.h>
#include <sys/epoll.h>
#include <sys/types.h>         
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include "seropt.h"

#define MAX 1024

#define PRT_ERR(msg) \
    do               \
    {                \
        perror(msg); \
        exit(-1);    \
    }while (0)

msg_t info;

int main(int argc, char const *argv[])
{
    if(argc!=3){    //外部传参个数判断
        fprintf(stderr, "Format Error:%s <ip> <port>\n", argv[0]);
        exit(-1);
    }

    //创建数据库
    //create_db();

    int sfd = socket(AF_INET, SOCK_STREAM, 0);  //创建TCP套接字
    if (sfd < 0)
        PRT_ERR("socket error");

    int reuse = 1;
    if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))<0)  //设置端口快速复用
        PRT_ERR("setsockopt error");

    struct sockaddr_in ser_addr;  //保存服务器地址信息结构体
    struct sockaddr_in cli_addr;  //保存客户端地址信息结构体
    struct sockaddr_in addrs[MAX] = {0};    //用于备份客户端地址信息
    socklen_t addr_len = sizeof(struct sockaddr_in);
    ser_addr.sin_family = AF_INET;                  // 填充服务器地址信息结构体
    ser_addr.sin_addr.s_addr = inet_addr(argv[1]);  //点分十进制字符串转换为ip值
    ser_addr.sin_port = htons(atoi(argv[2]));   //字符串转化为数值,并转化为大端存储

    if(bind(sfd,(struct sockaddr *)&ser_addr,sizeof(ser_addr))<0)   //绑定服务器地址信息
        PRT_ERR("bind error");
    
    if(listen(sfd,5)<0)     //监听客户端连接
        PRT_ERR("listen error");

    int epfd=epoll_create(1);    //创建epoll
    if(epfd<0)
        PRT_ERR("epoll_create error");

    struct epoll_event event;
    struct epoll_event revent[MAX]={0};

    event.data.fd = sfd;
    event.events = EPOLLIN;
    if(epoll_ctl(epfd,EPOLL_CTL_ADD,sfd,&event)<0) //将客户端连接事件加入epoll要监听的成员中
        PRT_ERR("epoll_ctl error");

    int count=0,ret=0;
    int cfd;
    int i;
    char from[24];
    msg_t info;
    while (1){
        count = epoll_wait(epfd, revent, MAX, -1); // epoll开启监听,不需要考虑超时时间
        if(count<0){
            PRT_ERR("epoll_wait error");
        }else{
            for (i = 0; i < count;i++){
                if(revent[i].data.fd==sfd){
                    //客户端发来连接请求
                    cfd=accept(sfd,(struct sockaddr *)&cli_addr,&addr_len);
                    if(cfd<0)
                        PRT_ERR("accept error");
                    printf("%s:%d 连接服务器\n", inet_ntoa(cli_addr.sin_addr), ntohs(cli_addr.sin_port));
                    addrs[cfd] = cli_addr;  //备份客户端信息
                    event.data.fd = cfd;
                    event.events = EPOLLIN;
                    if(epoll_ctl(epfd, EPOLL_CTL_ADD, cfd, &event) < 0)
                        PRT_ERR("epoll_ctl error");
                }else{
                    //客户端发来消息
                    cfd = revent[i].data.fd;
                    ret=recvMsg(cfd, &info,sizeof(info));
                    if(ret<0){
                        PRT_ERR("recv error");
                        exit(-1);
                    }else if(ret==0){
                        //客户端断开连接
                        printf("%s:%d 断开服务器连接\n", inet_ntoa(addrs[cfd].sin_addr),\
                                                         ntohs(addrs[cfd].sin_port));
                        event.data.fd = cfd;
                        event.events = EPOLLIN;
                        if(epoll_ctl(epfd, EPOLL_CTL_DEL, cfd, &event) < 0)   //从监听成员中删除
                            PRT_ERR("epoll_ctl error");
                    }else{
                        bzero(from,sizeof(from));
                        sprintf(from,"%s:%d",inet_ntoa(addrs[cfd].sin_addr),\
                                                ntohs(addrs[cfd].sin_port));
                        switch(info.msgtype){
                            case 'd':
                                deal_login_irq(cfd, &info,sizeof(info));
                                break;
                            case 't':
                                deal_add_req(cfd,&info,sizeof(info),from);
                                break;
                            case 'c':
                                deal_inquire_req(cfd,&info,sizeof(info),from);
                                break;
                            case 's':
                                deal_delte_req(cfd,&info,sizeof(info),from);
                                break;
                            case 'l':
                                deal_inquire_history_req(cfd,&info,sizeof(info),from);
                                break;
                            case 'g':
                                deal_update_req(cfd,&info,sizeof(info),from);
                                break;
                        }
                        memset(&info, 0, sizeof(info));
                    }
                }
            }
        }
    }

    return 0;
}

seropt.c :

#include "seropt.h"

//创建数据库
void create_db()
{
    char buf[SIZE];
    char *errmsg = NULL;
    sqlite3 *db = NULL;
    if(sqlite3_open("./staff_sys.db",&db)!=SQLITE_OK){
        printf("sqlite3_open error:%s\n", sqlite3_errmsg(db));
        return ;
    }

    //创建用于保存员工信息的表
    bzero(buf, sizeof(buf));
    sprintf(buf, "create table if not exists userinfo (root char,id int primary key,name char,passwd char,age int,tel char,addr char,work char,time char,level int,salary double)");
    if(sqlite3_exec(db,buf,NULL,NULL,&errmsg)!=SQLITE_OK){
        printf("sqlite3_exec error:%s\n", errmsg);
        return ;
    }

    //创建记录历史信息的表
    bzero(buf, sizeof(buf));
    sprintf(buf, "create table if not exists history (ip char,time char,user char,opertaion char)");
    if(sqlite3_exec(db,buf,NULL,NULL,&errmsg)!=SQLITE_OK){
        printf("sqlite3_exec error:%s\n", errmsg);
        return ;
    }

    //插入默认管理员用户
    bzero(buf, sizeof(buf));
    sprintf(buf, "insert into userinfo values ('root',1000,'admin','admin123',18,'13850816501','华清远见上海中心','系统管理员','2023.02.23',5,10000)");
    if(sqlite3_exec(db,buf,NULL,NULL,&errmsg)!=SQLITE_OK){
        printf("sqlite3_exec error:%s\n", errmsg);
        return ;
    }

    sqlite3_close(db);
}

//插入一条历史操作信息
int insert_history_info(char *from,char *who,char *what)
{
    time_t sec = 0;
    char buf[SIZE];
    char date[32]={0};
    char *errmsg = NULL;
    sqlite3 *db = NULL;
    struct tm *tm;
    if(sqlite3_open("./staff_sys.db",&db)!=SQLITE_OK){
        printf("sqlite3_open error:%s\n", sqlite3_errmsg(db));
        return -1;
    }

    time(&sec);
    tm = localtime(&sec);
    sprintf(date,"%04d-%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);

    //插入操作信息
    bzero(buf, sizeof(buf));
    sprintf(buf, "insert into history values ('%s','%s','%s','%s')",\
            from,date,who,what);
    if(sqlite3_exec(db,buf,NULL,NULL,&errmsg)!=SQLITE_OK){
        printf("sqlite3_exec error:%s\n", errmsg);
        return -1;
    }

    sqlite3_close(db);
    return 0;
}

//插入新员工数据
int insert_info(msg_t *info)
{
    char buf[SIZE];
    char *errmsg = NULL;
    sqlite3 *db = NULL;
    if(sqlite3_open("./staff_sys.db",&db)!=SQLITE_OK){
        printf("sqlite3_open error:%s\n", sqlite3_errmsg(db));
        return -1;
    }

    //插入员工信息
    bzero(buf, sizeof(buf));
    if(!info->root){
        sprintf(buf, "insert into userinfo values ('root',%d,'%s','%s',%d,'%s','%s','%s','%s',%d,%lf)",\
                info->staff.id,info->staff.name,info->staff.passwd,info->staff.age,info->staff.tel,\
                info->staff.addr,info->staff.work,info->staff.time,info->staff.level,info->staff.salary);
    }else{
        sprintf(buf, "insert into userinfo values ('consumer',%d,'%s','%s',%d,'%s','%s','%s','%s',%d,%lf)",\
                info->staff.id,info->staff.name,info->staff.passwd,info->staff.age,info->staff.tel,\
                info->staff.addr,info->staff.work,info->staff.time,info->staff.level,info->staff.salary);
    }
    if(sqlite3_exec(db,buf,NULL,NULL,&errmsg)!=SQLITE_OK){
        printf("sqlite3_exec error:%s\n", errmsg);
        return -1;
    }

    sqlite3_close(db);
    return 0;
}

//删除员工信息
int delete_info(msg_t *info)
{
    char buf[SIZE];
    char *errmsg = NULL;
    sqlite3 *db = NULL;
    if(sqlite3_open("./staff_sys.db",&db)!=SQLITE_OK){
        printf("sqlite3_open error:%s\n", sqlite3_errmsg(db));
        return -1;
    }

    //删除员工信息
    bzero(buf, sizeof(buf));
    sprintf(buf, "delete from userinfo where id='%d' and name = '%s'",\
                                        info->staff.id,info->staff.name);
    if(sqlite3_exec(db,buf,NULL,NULL,&errmsg)!=SQLITE_OK){
        printf("sqlite3_exec error:%s\n", errmsg);
        return -1;
    }

    sqlite3_close(db);
    return 0;
}

//查询用户信息
int inquire_info(int fd,msg_t *info,int flag,int size)
{
    char buf[SIZE];
    char *errmsg = NULL;
    sqlite3 *db = NULL;
    char **restr=NULL;
    int row=0;
    int column=0;
    int temp=-1;
    if(sqlite3_open("./staff_sys.db",&db)!=SQLITE_OK){
        printf("sqlite3_open error:%s\n", sqlite3_errmsg(db));
        return -1;
    }

    switch(flag){
        case 0:
            bzero(buf, sizeof(buf));
            sprintf(buf,"select * from userinfo");
            if(sqlite3_get_table(db,buf,&restr,&row,&column,&errmsg)!=SQLITE_OK){
                printf("sqlite3_get_table error:%s\n", sqlite3_errmsg(db));
                return -1;
            }
            if(row>=1){
                for(int i=0;i<column*(row+1);i++){
                    strcpy(info->str, restr[i]);
                    sendMsg(fd,info,size);
                }
                temp = info->usertype;
                info->usertype = -1;
                sendMsg(fd,info,size);
                info->usertype = temp;
            }else{
                info->usertype = -2;
                sendMsg(fd,info,size);
            }
            break;
        case 2:
        case 1:
            bzero(buf, sizeof(buf));
            sprintf(buf,"select * from userinfo where name='%s'",info->staff.name);
            if(sqlite3_get_table(db,buf,&restr,&row,&column,&errmsg)!=SQLITE_OK){
                printf("sqlite3_get_table error:%s\n", sqlite3_errmsg(db));
                return -1;
            }
            if(row>=1){
                for(int i=0;i<column*(row+1);i++){
                    strcpy(info->str, restr[i]);
                    sendMsg(fd,info,size);
                }
                temp = info->usertype;
                info->usertype = -1;
                sendMsg(fd,info,size);
                info->usertype = temp;
            }else{
                info->usertype = -2;
                sendMsg(fd,info,size);
            }
            break;
    }

    sqlite3_free_table(restr);
    sqlite3_close(db);
    return 0;
}

//查询历史记录
int inquire_history_info(int fd,msg_t *info,int size)
{
    char buf[SIZE];
    char *errmsg = NULL;
    sqlite3 *db = NULL;
    char **restr=NULL;
    int row=0;
    int column=0;
    int temp=-1;

    if(sqlite3_open("./staff_sys.db",&db)!=SQLITE_OK){
        printf("sqlite3_open error:%s\n", sqlite3_errmsg(db));
        return -1;
    }

    bzero(buf, sizeof(buf));
    sprintf(buf,"select * from history");
    if(sqlite3_get_table(db,buf,&restr,&row,&column,&errmsg)!=SQLITE_OK){
        printf("sqlite3_get_table error:%s\n", sqlite3_errmsg(db));
        return -1;
    }
    if(row>=1){
        for(int i=0;i<column*(row+1);i++){
            strcpy(info->str, restr[i]);
            sendMsg(fd,info,size);
        }
        temp = info->usertype;
        info->usertype = -1;
        sendMsg(fd,info,size);
        info->usertype = temp;
    }else{
        info->usertype = -2;
        sendMsg(fd,info,size);
    }

    sqlite3_free_table(restr);
    sqlite3_close(db);
    return 0;
}

//修改员工信息
int update_info(int id,char *text,char *str,int value)
{
    char buf[SIZE];
    char *errmsg = NULL;
    sqlite3 *db = NULL;

    if(sqlite3_open("./staff_sys.db",&db)!=SQLITE_OK){
        printf("sqlite3_open error:%s\n", sqlite3_errmsg(db));
        return -1;
    }

    bzero(buf, sizeof(buf));
    if(str!=NULL){
        sprintf(buf, "update userinfo set '%s' = '%s' where id = '%d'",text,str,id);
        if(sqlite3_exec(db,buf,NULL,NULL,&errmsg)!=SQLITE_OK){
            printf("sqlite3_exec error:%s\n", errmsg);
            return -1;
        }
    }else{
        if(strcmp(text,"salary")==0)
            sprintf(buf, "update userinfo set '%s' = '%lf' where id = '%d'",text,(double)value,id);
        else
            sprintf(buf, "update userinfo set '%s' = '%d' where id = '%d'",text,value,id);
        if(sqlite3_exec(db,buf,NULL,NULL,&errmsg)!=SQLITE_OK){
            printf("sqlite3_exec error:%s\n", errmsg);
            return -1;
        }
    }

    sqlite3_close(db);
    return 0;
}

//处理登录请求
int deal_login_irq(int fd,msg_t *info,int size)
{
    char buf[SIZE];
    char *errmsg = NULL;
    sqlite3 *db = NULL;
    char **restr=NULL;
    int row=0;
    int column=0;

    if(sqlite3_open("./staff_sys.db",&db)!=SQLITE_OK){
        printf("sqlite3_open error:%s\n", sqlite3_errmsg(db));
        return -1;
    }

    bzero(buf, sizeof(buf));
    sprintf(buf,"select * from userinfo where name=\"%s\"",info->staff.name);
    if(sqlite3_get_table(db,buf,&restr,&row,&column,&errmsg)!=SQLITE_OK){
        printf("sqlite3_get_table error:%s\n", sqlite3_errmsg(db));
        return -1;
    }

    if(row==0){
        sprintf(info->str, "用户名不存在");
    }else{
        for (int i = 1; i <= row;i++){
            if(strcmp(restr[i*column+3],info->staff.passwd)==0){
                if(!info->usertype){
                    if(strcmp(restr[i*column],"root")==0){
                        strcpy(info->str, "login success");
                    }else{
                        sprintf(info->str, "用户%s非管理员", restr[i * column + 3]);
                    }
                }else{
                    if(strcmp(restr[i*column],"consumer")==0){
                        info->staff.id = atoi(restr[i*column+1]);
                        strcpy(info->str, "login success");
                    }else{
                        sprintf(info->str, "用户%s为管理员", restr[i * column + 3]);
                    }
                }
            }else{
                strcpy(info->str, "密码错误");
            }
        }
    }
    sendMsg(fd, info, size);
    sqlite3_free_table(restr);
    sqlite3_close(db);
    return 0;
}

//处理添加新员工请求
int deal_add_req(int fd,msg_t *info,int size,char *from)
{
    char buf[BUFSIZE];
    if(insert_info(info)<0){
        strcpy(info->str, "add failed");
    }else{
        strcpy(info->str, "add success");
        bzero(buf, sizeof(buf));
        sprintf(buf, "管理员添加了员工%s的信息", info->staff.name);
        insert_history_info(from,"管理员", buf);
    }
    sendMsg(fd, info, size);
    return 0;
}

//处理查询用户信息请求
int deal_inquire_req(int fd,msg_t *info,int size,char *from)
{
    char buf[BUFSIZE];
    bzero(buf, sizeof(buf));
    inquire_info(fd, info, info->usertype, size);
    switch(info->usertype){
        case 0:
            insert_history_info(from,"管理员","管理员查询了所有员工信息");
            break;
        case 1:
            sprintf(buf, "管理员查询了员工%s的信息", info->staff.name);
            insert_history_info(from,"管理员", buf);
            break;
        case 2:
            sprintf(buf, "员工%s进行信息查询", info->staff.name);
            insert_history_info(from,info->staff.name, buf);
            break;
    }
    return 0;
}

//处理删除员工信息请求
int deal_delte_req(int fd, msg_t *info, int size,char *from)
{
    char buf[BUFSIZE];
    if(delete_info(info)<0){
        strcpy(info->str, "delete failed");
    }else{
        strcpy(info->str, "delete success");
        bzero(buf, sizeof(buf));
        sprintf(buf, "管理员删除了工号为%d的员工信息", info->staff.id);
        insert_history_info(from,"管理员", buf);
    }
    sendMsg(fd, info, size);
    return 0;
}

//处理查询历史记录信息请求
int deal_inquire_history_req(int fd, msg_t *info, int size,char *from)
{
    insert_history_info(from,"管理员","管理员查询了历史记录信息");
    inquire_history_info(fd, info, size);
    return 0;
}

//处理修改信息请求
int deal_update_req(int fd,msg_t *info,int size,char *from)
{
    char buf[SIZE];
    char what[BUFSIZE];
    char who[NAMELEN];
    char uname[NAMELEN];
    char *errmsg = NULL;
    sqlite3 *db = NULL;
    char **restr=NULL;
    int row=0;
    int column=0;
    int flag = 0;

    if(sqlite3_open("./staff_sys.db",&db)!=SQLITE_OK){
        printf("sqlite3_open error:%s\n", sqlite3_errmsg(db));
        return -1;
    }

    bzero(buf, sizeof(buf));
    bzero(uname, sizeof(uname));
    bzero(what, sizeof(what));
    bzero(who, sizeof(who));

    sprintf(buf, "select * from userinfo where id = '%d'", info->staff.id);
    if(sqlite3_get_table(db,buf,&restr,&row,&column,&errmsg)!=SQLITE_OK){
                printf("sqlite3_get_table error:%s\n", sqlite3_errmsg(db));
                return -1;
    }
    if(row<1){
        strcpy(info->str,"用户名不存在");
        sendMsg(fd,info,size);
        sqlite3_free_table(restr);
        sqlite3_close(db);
        return -1;
    }else{
        strcpy(uname, restr[column + 2]);
    }

    sqlite3_free_table(restr);
    sqlite3_close(db);

    if(strcmp(info->str,"root")==0){
        flag = 1;
        strcpy(who, "管理员");
    }else{
        strcpy(who, uname);
    }

    switch(info->usertype){
        case 1:
            update_info(info->staff.id,"name",info->staff.name,0);
            if(flag)
                sprintf(what,"管理员修改了%s的名字信息",uname);
            else
                sprintf(what, "员工%s修改了名字信息", uname);
            break;
        case 2:
            update_info(info->staff.id,"age",NULL,info->staff.age);
            if(flag)
                sprintf(what,"管理员修改了%s的年龄信息",uname);
            else
                sprintf(what, "员工%s修改了年龄信息", uname);
            break;
        case 3:
            update_info(info->staff.id,"addr",info->staff.addr,0);
            if(flag)
                sprintf(what,"管理员修改了%s的地址信息",uname);
            else
                sprintf(what, "员工%s修改了地址信息", uname);
            break;
        case 4:
            update_info(info->staff.id,"tel",info->staff.tel,0);
            if(flag)
                sprintf(what,"管理员修改了%s的电话信息",uname);
            else
                sprintf(what, "员工%s修改了电话信息", uname);
            break;
        case 5:
            update_info(info->staff.id,"work",info->staff.work,0);
            sprintf(what,"管理员修改了%s的职位信息",uname);
            break;
        case 6:
            update_info(info->staff.id,"salary",NULL,info->staff.salary);
            sprintf(what,"管理员修改了%s的薪资信息",uname);
            break;
        case 7:
            update_info(info->staff.id,"time",info->staff.time,0);
            sprintf(what,"管理员修改了%s的入职时间信息",uname);
            break;
        case 8:
            update_info(info->staff.id,"level",NULL,info->staff.level);
            sprintf(what,"管理员修改了%s的评级信息",uname);
            break;
        case 9:
            update_info(info->staff.id,"passwd",info->staff.passwd,0);
            if(flag)
                sprintf(what,"管理员修改了%s的密码信息",uname);
            else
                sprintf(what, "员工%s修改了密码信息", uname);
            break;
    }
    insert_history_info(from,who,what);
    strcpy(info->str,"update success");
    sendMsg(fd,info,size);
}

客户端:

cli.c :

#include <stdio.h>
#include <string.h>
#include <sys/epoll.h>
#include <sys/types.h>         
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include "cliopt.h"

#define PRT_ERR(msg) \
    do               \
    {                \
        perror(msg); \
        exit(-1);    \
    }while (0)

int main(int argc, char const *argv[])
{
    if(argc!=3){    //外部传参个数判断
        fprintf(stderr, "Format Error:%s <ip> <port>\n", argv[0]);
        exit(-1);
    }

    int cfd = socket(AF_INET, SOCK_STREAM, 0);  //创建TCP套接字
    if (cfd < 0)
        PRT_ERR("socket error");

    struct sockaddr_in ser_addr;  //保存服务器地址信息结构体
    ser_addr.sin_family = AF_INET;  //填充服务器地址信息结构体
    ser_addr.sin_addr.s_addr = inet_addr(argv[1]);  //点分十进制字符串转换为ip值
    ser_addr.sin_port = htons(atoi(argv[2]));   //字符串转化为数值,并转化为大端存储

    if(connect(cfd,(struct sockaddr *)&ser_addr,sizeof(ser_addr))<0)    //连接服务器
        PRT_ERR("connect error");

    int ret = 0;
    int which;
    char name[NAMELEN]={0};
    int id=-1;
    while (1){
        select_interface();
        wait_input_int(&which);
        switch(which){
            case 1:
                ret=send_login_req(cfd, 0,NULL,0);
                if(ret){
                    root_interface(cfd);
                }
                break;
            case 2:
                ret=send_login_req(cfd, 1,name,&id);
                if(ret){
                    user_interface(cfd,name,id);
                }
                break;
            case 3:
                exit(0);
                break;
            default:
                printf("选择有误,请重试!\n");
                break;
        }
    }

    return 0;
}

cliopt.c :

#include "cliopt.h"

//定义消息
msg_t info;

//界面打印
void select_interface()
{
    puts("***************************************************");
    puts("********1.管理员登录   2.员工登录   3.退出*********");
    puts("***************************************************");
    printf("请输入>>>");
    fflush(stdout);
}

void inquire_interface(int cfd)
{
    int which;
    while(1){
        puts("***************************************************");
        puts("********1.按名字查询   2.查询所有   3.退出*********");
        puts("***************************************************");
        printf("请输入>>>");
        fflush(stdout);
        wait_input_int(&which);
        switch(which){
            case 1:
                send_inquire_req(cfd, 0, NULL);
                break;
            case 2:
                send_inquire_req(cfd, 1, NULL);
                break;
            case 3:
                return;
            default:
                printf("选择有误,请重试!\n");
                break;
        }
    }
}

void root_interface(int cfd)
{
    int which;
    while(1){
        puts("********************************************************************");
        puts("***1.查询  2.修改  3.添加用户  4.删除用户  5.查询历史记录  6.退出***");
        puts("********************************************************************");
        printf("请输入>>>");
        fflush(stdout);
        wait_input_int(&which);
        switch(which){
            case 1:
                inquire_interface(cfd);
                break;
            case 2:
                root_update_interface(cfd);
                break;
            case 3:
                send_add_req(cfd,0);
                break;
            case 4:
                send_delete_req(cfd,0);
                break;
            case 5:
                sned_inquire_history_req(cfd);
                break;
            case 6:
                return ;
            default:
                printf("选择有误,请重试!\n");
                break;
        }
    }
}

void user_interface(int cfd,char *name,int id)
{
    int which;
    while(1){
        puts("*************************************************");
        puts("************1.查询   2.修改   3.退出*************");
        puts("*************************************************");
        printf("请输入>>>");
        fflush(stdout);
        wait_input_int(&which);
        switch(which){
            case 1:
                send_inquire_req(cfd, 0, name);
                break;
            case 2:
                user_update_interface(cfd, id);
                break;
            case 3:
                return;
            default:
                printf("选择有误,请重试!\n");
                break;
        }
    }
}

void root_update_interface(int cfd)
{
    int which;
    int id = -1;
    printf("请输入要修改信息的员工工号>>>");
    fflush(stdout);
    wait_input_int(&id);
    while(1){
        puts("********************请输入要修改的选项***************************");
        puts("************1.姓名   2.年龄   3.常住地址   4.电话****************");
        puts("************5.职位   6.工资   7.入职年月   8.评级****************");
        puts("************9.密码   10.退出                    *****************");
        puts("*****************************************************************");
        printf("请输入>>>");
        fflush(stdout);
        wait_input_int(&which);
        if(which<1 && which>10){
            printf("选择有误,请重试!\n");
            continue;
        }
        send_update_req(cfd,id,which,0);
        break;
    }
}

void user_update_interface(int cfd,int id)
{
    int which;
    while(1){
        puts("********************请输入要修改的选项***************************");
        puts("************1.姓名   2.年龄   3.常住地址   4.电话****************");
        puts("************5.密码   6.退出                    ******************");
        puts("*****************************************************************");
        printf("请输入>>>");
        fflush(stdout);
        wait_input_int(&which);
        if(which<1 && which>6){
            printf("选择有误,请重试!\n");
            continue;
        }else if(which==5 || which==6){
            which += 4;
        }
        send_update_req(cfd, id, which,1);
        break;
    }
}

//操作方法
void wait_input_int(int *value)
{
    int ret;
    while (1){
        ret=scanf("%d",value);
        if(ret!=1){
            printf("输入有误,请重试!\n");
            printf("请输入>>>");
            while(getchar()!='\n');
        }else{
            break;
        }
    }
    while(getchar()!='\n');
}

void wait_input_double(double *value)
{
    int ret;
    while (1){
        ret=scanf("%lf",value);
        if(ret!=1){
            printf("输入有误,请重试!\n");
            printf("请输入>>>");
            while(getchar()!='\n');
        }else{
            break;
        }
    }
    while(getchar()!='\n');
}

void wait_input_str(char *str,int len)
{
    fgets(str, len, stdin);
    str[strlen(str) - 1] = '\0';
}

//发送登录请求
int send_login_req(int cfd,int flag,char *name,int *id) //flag=0,表示管理员请求登录,name用于保留员工用户名
{
    int ret = 0;
    memset(&info, 0, sizeof(info));
    puts("********管理员/用户登录********");
    printf("请输入用户名>>>");
    fflush(stdout);
    wait_input_str(info.staff.name,sizeof(info.staff.name));
    printf("请输入密码>>>");
    fflush(stdout);
    wait_input_str(info.staff.passwd,sizeof(info.staff.passwd));

    info.msgtype = 'd'; //登录信息标识
    info.usertype = flag;
    ret=sendMsg(cfd, &info, sizeof(info));
    if(ret!=sizeof(info)){
        printf("发送登录请求失败\n");
        return -1;
    }
    if(recvMsg(cfd,&info,sizeof(info))==0){
        printf("断开连接\n");
        exit(-1);
    }

    if(strcmp(info.str,"login success")==0){
        if(name!=NULL){
            strcpy(name, info.staff.name);
            *id = info.staff.id;
        }
        printf("登录成功\n");
        return 1;
    }else{
        printf("登录失败,%s,请重试!\n", info.str);
        return 0;
    }
}

//发送添加请求
int send_add_req(int cfd,int flag) //flag=0,表示管理员
{
    int ret = 0;
    memset(&info, 0, sizeof(info));
    printf("请输入工号>>>");
    fflush(stdout);
    wait_input_int(&info.staff.id);
    printf("请输入用户名>>>");
    fflush(stdout);
    wait_input_str(info.staff.name,sizeof(info.staff.name));
    printf("请输入密码>>>");
    fflush(stdout);
    wait_input_str(info.staff.passwd,sizeof(info.staff.passwd));
    printf("请输入年龄>>>");
    fflush(stdout);
    wait_input_int(&info.staff.age);
    printf("请输入联系电话>>>");
    fflush(stdout);
    wait_input_str(info.staff.tel,sizeof(info.staff.tel));
    printf("请输入常住地址>>>");
    fflush(stdout);
    wait_input_str(info.staff.addr,sizeof(info.staff.addr));
    printf("请输入员工职位>>>");
    fflush(stdout);
    wait_input_str(info.staff.work,sizeof(info.staff.work));
    printf("请输入员工入职时间>>>");
    fflush(stdout);
    wait_input_str(info.staff.time,sizeof(info.staff.time));
    printf("请输入职位级别(1-5)>>>");
    fflush(stdout);
    wait_input_int(&info.staff.level);
    printf("请输入员工月薪>>>");
    fflush(stdout);
    wait_input_double(&info.staff.salary);
    printf("是否赋予管理员权限(yes:0 no:1)>>>");
    fflush(stdout);
    wait_input_int(&info.root);
    
    info.msgtype = 't'; //添加信息标识
    info.usertype = flag;
    ret=sendMsg(cfd, &info, sizeof(info));
    if(ret!=sizeof(info)){
        printf("发送添加请求失败\n");
        return -1;
    }
    if(recvMsg(cfd,&info,sizeof(info))==0){
        printf("断开连接\n");
        exit(-1);
    }

    if(strcmp(info.str,"add success")==0){
        printf("添加成功\n");
        return 1;
    }else{
        printf("添加失败,请重试!\n");
        return 0;
    }
}

//发送查询请求
int send_inquire_req(int cfd,int flag,char *name)  //flag为1表示查询所有用户信息,为0表示查询单个用户信息
{
    int ret=0;
    int i;
    memset(&info, 0, sizeof(info));
    info.msgtype = 'c'; //添加信息标识
    info.usertype=0;    //查询所有信息
    if(!flag){
        if(name==NULL){
            printf("请输入要查询的用户名>>>");
            fflush(stdout);
            wait_input_str(info.staff.name,sizeof(info.staff.name));
            info.usertype=1;    //查询指定用户信息
        }else{
            strcpy(info.staff.name, name);
            info.usertype = 2;  //员工查询
        }
    }

    ret=sendMsg(cfd, &info, sizeof(info));
    if(ret!=sizeof(info)){
        printf("发送添加请求失败\n");
        return -1;
    }

    i=0;
    while(1){
        if(recvMsg(cfd,&info,sizeof(info))==0){
            printf("断开连接\n");
            exit(-1);
        }
        if(info.usertype==-1){
            printf("查询完毕\n");
            break;
        }else if(info.usertype==-2){
            printf("查询失败,请重试!\n");
            break;
        }
        i++;
        printf("%s",info.str);
        if(i%11==0)
            putchar('\n');
        else
            putchar('\t');
    }
    return 0;
}

//发送删除用户请求
int send_delete_req(int cfd, int flag)  //flag=0,表示管理员
{
    int ret = 0;
    memset(&info, 0, sizeof(info));
    memset(&info, 0, sizeof(info));
    printf("请输入要删除员工信息的工号>>>");
    fflush(stdout);
    wait_input_int(&info.staff.id);
    printf("请输入要删除员工信息的用户名>>>");
    fflush(stdout);
    wait_input_str(info.staff.name,sizeof(info.staff.name));

    info.msgtype = 's'; //添加信息标识
    info.usertype = flag;
    ret=sendMsg(cfd, &info, sizeof(info));
    if(ret!=sizeof(info)){
        printf("发送删除请求失败\n");
        return -1;
    }
    if(recvMsg(cfd,&info,sizeof(info))==0){
        printf("断开连接\n");
        exit(-1);
    }

    if(strcmp(info.str,"delete success")==0){
        printf("删除成功\n");
        return 1;
    }else{
        printf("删除失败,请重试!\n");
        return 0;
    }

    return 0;
}

//发送查询历史记录请求
int sned_inquire_history_req(int cfd)
{
    int ret=0;
    int i;
    memset(&info, 0, sizeof(info));
    info.msgtype = 'l'; //查询历史记录信息标识

    ret=sendMsg(cfd, &info, sizeof(info));
    if(ret!=sizeof(info)){
        printf("发送添加请求失败\n");
        return -1;
    }

    i=0;
    while(1){
        if(recvMsg(cfd,&info,sizeof(info))==0){
            printf("断开连接\n");
            exit(-1);
        }
        if(info.usertype==-1){
            printf("查询完毕\n");
            break;
        }else if(info.usertype==-2){
            printf("查询失败,请重试!\n");
            break;
        }
        i++;
        printf("%s",info.str);
        if(i%4==0)
            putchar('\n');
        else
            putchar('\t');
    }
    return 0;
}

//发送修改信息请求
int send_update_req(int cfd,int id,int which,int flag)
{
    int ret=0;
    int i;
    memset(&info, 0, sizeof(info));
    info.msgtype = 'g'; //修改信息标识
    info.staff.id = id;
    info.usertype = which;
    if(!flag)
        strcpy(info.str, "root");
    else
        strcpy(info.str, "consumer");

    switch(which){
        case 1:
            printf("请输入新的用户名>>>");
            fflush(stdout);
            wait_input_str(info.staff.name,sizeof(info.staff.name));
            break;
        case 2:
            printf("请输入新的年龄>>>");
            fflush(stdout);
            wait_input_int(&info.staff.age);
            break;
        case 3:
            printf("请输入新的常住地址>>>");
            fflush(stdout);
            wait_input_str(info.staff.addr,sizeof(info.staff.addr));
            break;
        case 4:
            printf("请输入新的电话号码>>>");
            fflush(stdout);
            wait_input_str(info.staff.tel,sizeof(info.staff.tel));
            break;
        case 5:
            printf("请输入新的职位>>>");
            fflush(stdout);
            wait_input_str(info.staff.work,sizeof(info.staff.work));
            break;
        case 6:
            printf("请输入新的月薪>>>");
            fflush(stdout);
            wait_input_double(&info.staff.salary);
            break;
        case 7:
            printf("请输入新的入职年月>>>");
            fflush(stdout);
            wait_input_str(info.staff.time,sizeof(info.staff.time));
            break;
        case 8:
            printf("请输入新的评级>>>");
            fflush(stdout);
            wait_input_int(&info.staff.level);
            break;
        case 9:
            printf("请输入新的密码>>>");
            fflush(stdout);
            wait_input_str(info.staff.passwd,sizeof(info.staff.passwd));
            break;
        case 10:
            memset(&info,0,sizeof(info));
            return 0;
    }

    ret=sendMsg(cfd, &info, sizeof(info));
    if(ret!=sizeof(info)){
        printf("发送修改请求失败\n");
        return -1;
    }

    if(recvMsg(cfd,&info,sizeof(info))==0){
        printf("断开连接\n");
        exit(-1);
    }

    if(strcmp(info.str,"update success")==0){
        printf("修改成功\n");
        return 1;
    }else{
        printf("修改失败,%s,请重试!\n",info.str);
        return 0;
    }

    return 0;
}

共用 头文件和功能函数:

common.h :

#ifndef __COMMON_H__
#define __COMMON_H__

#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <sys/epoll.h>
#include <sys/types.h>         
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>

#define NAMELEN     24
#define PASSWDLEN   16
#define TELLEN      16
#define ADDRLEN     32
#define WORKLEN     32
#define TIMELEN     16
#define BUFSIZE     64

#pragma pack(1) 
//用于保存员工信息的结构体
typedef struct staff_info {
    int id;
    char name[NAMELEN];
    char passwd[PASSWDLEN];
    int age;
    char tel[TELLEN];
    char addr[ADDRLEN];
    char work[WORKLEN];
    char time[TIMELEN];
    int level;
    double salary;
}staff_t;

//用于服务器与客户端通信的消息结构体
typedef struct {
    int msgtype;
    int usertype;
    int root;
    char str[BUFSIZE];
    staff_t staff;
} msg_t;

#pragma pack()


//减少TCP的粘包问题
int sendMsg(int fd, msg_t *msg, int size);

int recvMsg(int fd, msg_t *msg, int size);

#endif

common.c :

#include "common.h"

//发送指定大小数据
int sendMsg(int fd, msg_t *msg, int size)
{
    char *buf=(char *)msg;
    int count=size;
    int len=0;
    while(count>0){
        len=send(fd,buf,count,0);
        if(len<0){
            return -1;
        }
        buf+=len;
        count-=len;
    }
    return size;
}

//接受指定大小数据
int recvMsg(int fd, msg_t *msg, int size)
{
    char *buf=(char *)msg;
    int count=size;
    int len=0;
    while(count>0){
        len=recv(fd,buf,count,0);
        if(len<0){
            return -1;
        }else if(0==len){
            return 0;
        }
        buf+=len;
        count-=len;
    }
    return size;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值