diff --git a/code/analysis.cpp b/code/analysis.cpp new file mode 100644 index 0000000000000000000000000000000000000000..853c96a91ac67d6888cfef76ad64be438aeeed85 --- /dev/null +++ b/code/analysis.cpp @@ -0,0 +1,236 @@ +#include "analysis.h" + +extern employee_list employee_List; // 员工信息链表头指针 +__declspec(selectany) records *all; // 总销售记录头指针 + +double totalSalesMoney = 0; // 当月总销售额 +double totalEmployeeSalary = 0; // 当月待发工资总额 +double totalPurchasePrice = 0; // 已经卖出去的商品的总进价 + +/********************************************************* + * sortingRuleOfEmployees -- 员工的排序规则: + * 将员工按当月销售额进行排序, + * 当销售额相同时按照姓名字典序进行排序 + * 参数:a,b:代表员工的销售额信息:pair<姓名, 当月销售额> + * 返回值:a应排在b前面时,返回true;否则返回false + *********************************************************/ +bool sortingRuleOfEmployees(pair a, pair b) +{ + if(!(fabs(a.second - b.second) < 1e-6)) // 销售额不同时 + return a.second > b.second; // 按当月销售额进行排序 + return a.first < b.first; // 否则按照姓名字典序排序 +} + + +/********************************************************************** + * sortingRuleOfGoods -- 商品的排序规则: + * 将商品按当月销量进行排序, + * 当销售额相同时按照商品名字典序进行排序 + * 参数:a,b:代表商品的销售信息:pair<商品id, 销售信息> + * 其中商品id(pair::first)等于销售信息中的商品id(pair::second.id_Number) + * 返回值:a应排在b前面时,返回true;否则返回false + **********************************************************************/ +bool sortingRuleOfGoods(pair a, pair b) +{ + if(a.second.count != b.second.count) // 销量不同时 + return a.second.count > b.second.count; // 按当月销量进行排序 + return strcmp(a.second.name, b.second.name) < 0; // 否则按照商品名字典序排序 +} + +/********************************************************* + * countSalespersonWinner -- 统计并输出销售冠军, + * 同时完成当月总销售额、 + * 已经卖出去的商品的总进价两个数值的计算 + * 参数:current_date:当前日期 + * 返回值:无 + *********************************************************/ +void countSalespersonWinner(date current_date) +{ + map emp_map; // 员工姓名到该员工当月销售额的映射 + for(employee_list p = employee_List->next; p != NULL; p = p->next) + { + emp_map[p->name] = 0; // 把每个员工当月销售额先初始化为0 + } + for(sales_Records p = all->next; p != NULL; p = p->next) + { + // 遍历总销售记录,统计每个员工当月销售额 + // 下面的if判断条件是为了筛选出当月的销售记录进行统计 + if(p->year == current_date.year && p->mon == current_date.month) + { + emp_map[p->people] += p->price; // 修改该员工当月销售额 + totalSalesMoney += p->price; // 修改当月总销售额 + goods *n = searchGoods(p->id, commodity_head); + totalPurchasePrice += p->count * n->buy_Price; // 修改已经卖出去的商品的总进价 + } + } + vector> emp_v; // 临时存储员工的销售额信息:pair<姓名, 当月销售额> + for(auto p : emp_map) + { + emp_v.push_back(p); + } + printf("销售冠军:\n"); + if(emp_v.size() == 0) // 当月无销售记录,无法统计销售冠军 + { + printf("暂无\n"); + } + else + { + sort(emp_v.begin(), emp_v.end(), sortingRuleOfEmployees); + char salespersonName[15]; + if(emp_v.size() >= 1 && !(fabs(emp_v[0].second) < 1e-6)) + { + strcpy(salespersonName, emp_v[0].first.c_str()); + printf("第一名:%s(%d) 当月销售额:%.2lf元\n", salespersonName, + employee_findName(employee_List, salespersonName)->id, emp_v[0].second); + if(emp_v.size() >= 2 && !(fabs(emp_v[1].second) < 1e-6)) + { + strcpy(salespersonName, emp_v[1].first.c_str()); + printf("第二名:%s(%d) 当月销售额:%.2lf元\n", salespersonName, + employee_findName(employee_List, salespersonName)->id, emp_v[1].second); + if(emp_v.size() >= 3 && !(fabs(emp_v[2].second) < 1e-6)) + { + strcpy(salespersonName, emp_v[2].first.c_str()); + printf("第三名:%s(%d) 当月销售额:%.2lf元\n", salespersonName, + employee_findName(employee_List, salespersonName)->id, emp_v[2].second); + } + else + { + printf("第三名:暂无\n"); + } + } + else + { + printf("第二名:暂无\n"); + } + } + else + { + printf("第一名:暂无\n"); + } + } + putchar('\n'); + return; +} + +/********************************************************* + * countSalespersonWinner -- 统计并输出销量之星 + * 参数:current_date:当前日期 + * 返回值:无 + *********************************************************/ +void countGoodsWinner(date current_date) +{ + map goods_map; // 商品id到该商品销售信息的映射 + for(commodity p = commodity_head->next; p != NULL; p = p->next) + { + goods_map[p->id_Number] = soldGoods(); // 初始化商品信息 + strcpy(goods_map[p->id_Number].id_Number, p->id_Number); // 商品id + strcpy(goods_map[p->id_Number].name, p->goods_Name); // 商品名 + goods_map[p->id_Number].count = 0; // 销量 + goods_map[p->id_Number].price = p->sell_Price; // 售出价格(单价,用于计算销售额) + } + for(sales_Records p = all->next; p != NULL; p = p->next) + { + // 遍历总销售记录,统计每个商品当月销量 + // 下面的if判断条件是为了筛选出当月的销售记录进行统计 + if(p->year == current_date.year && p->mon == current_date.month) + { + goods_map[p->id].count += p->count; + } + } + vector> goods_v; // 临时存储商品的销售信息:pair<商品id, 销售信息> + for(auto p : goods_map) + { + goods_v.push_back(p); + } + printf("销量之星:\n"); + if(goods_v.size() == 0) // 当月无销售记录,无法统计销量之星 + { + printf("暂无\n"); + } + else + { + sort(goods_v.begin(), goods_v.end(), sortingRuleOfGoods); + if(goods_v.size() >= 1 && goods_v[0].second.count != 0) + { + printf("第一名:%s(%s) 当月销量:%d 销售额:%.2lf元\n", goods_v[0].second.name, + goods_v[0].second.id_Number, goods_v[0].second.count, + goods_v[0].second.price * goods_v[0].second.count); + if(goods_v.size() >= 2 && goods_v[1].second.count != 0) + { + printf("第二名:%s(%s) 当月销量:%d 销售额:%.2lf元\n", goods_v[1].second.name, + goods_v[1].second.id_Number, goods_v[1].second.count, + goods_v[1].second.price * goods_v[1].second.count); + if(goods_v.size() >= 3 && goods_v[2].second.count != 0) + { + printf("第三名:%s(%s) 当月销量:%d 销售额:%.2lf元\n", goods_v[2].second.name, + goods_v[2].second.id_Number, goods_v[2].second.count, + goods_v[2].second.price * goods_v[2].second.count); + } + else + { + printf("第三名:暂无\n"); + } + } + else + { + printf("第二名:暂无\n"); + } + } + else + { + printf("第一名:暂无\n"); + } + } + putchar('\n'); + return; +} + +/********************************************************* + * data_overview -- 统计当月待发工资总额 + * 参数:无 + * 返回值:无 + *********************************************************/ +void countTotalEmployeeSalary() +{ + for(employee_list p = employee_List->next; p != NULL; p = p->next) + { + totalEmployeeSalary += p->salary; + } + return; +} + +/********************************************************* + * data_overview -- 数据速览,对当月的数据进行统计, + * 并输出相关数据 + * 参数:无 + * 返回值:无 + *********************************************************/ +void data_overview() +{ + time_t now; + struct tm *ptm; + time(&now); // 获取当前时间戳(1970-1-1以来经过的秒数) + ptm = localtime(&now); // 将时间戳转换为本地时间 + date current_date(1900 + ptm->tm_year, 1 + ptm->tm_mon, ptm->tm_mday); // 当前日期 + printf(" * * * * * 数 据 速 览 * * * * *\n\n", current_date.year, current_date.month); + printf("计算周期:%04d年%d月\n", current_date.year, current_date.month); + printf("数据截止至:%04d年%d月%d日\n\n", current_date.year, current_date.month, current_date.day); + totalSalesMoney = 0; // 初始化当月总销售额为0 + totalEmployeeSalary = 0; // 初始化当月待发工资总额为0 + totalPurchasePrice = 0; // 初始化已经卖出去的商品的总进价为0 + + // 统计并输出销售冠军,同时计算当月总销售额、已经卖出去的商品的总进价 + countSalespersonWinner(current_date); + // 统计并输出销量之星 + countGoodsWinner(current_date); + // 统计当月待发工资总额 + countTotalEmployeeSalary(); + + printf("本月总销售额:%.2lf元\n\n", totalSalesMoney); + printf("本月待发工资总额:%.2lf元\n\n", totalEmployeeSalary); + printf("盈亏:%.2lf元\n", totalSalesMoney - totalPurchasePrice - totalEmployeeSalary); + printf("(盈亏=总销售额-卖出商品的总进价-员工工资)\n\n"); + + system("pause"); + return; +} diff --git a/code/analysis.h b/code/analysis.h new file mode 100644 index 0000000000000000000000000000000000000000..6d95df8695634800d81d40fe6e5c6c29e080ad2e --- /dev/null +++ b/code/analysis.h @@ -0,0 +1,37 @@ +#ifndef __ANALYSIS_H__ +#define __ANALYSIS_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "date.h" +#include "employee.h" +#include "purchase.h" +#include "sell.h" +#include "sellFun.h" +using namespace std; + +// 员工的排序规则:将员工按当月销售额从高到低进行排序 +bool sortingRuleOfEmployees(pair a, pair b); + +// 商品的排序规则:将商品按当月销量从高到低进行排序 +bool sortingRuleOfGoods(pair a, pair b); + +// 统计并输出销售冠军,同时计算当月总销售额、已经卖出去的商品的总进价 +void countSalespersonWinner(date current_date); + +// 统计并输出销量之星 +void countGoodsWinner(date current_date); + +// 统计当月待发工资总额 +void countTotalEmployeeSalary(); + +// 数据速览,对当月的数据进行统计,并输出相关数据 +void data_overview(); + +#endif // !__ANALYSIS_H__ diff --git a/code/employee.cpp b/code/employee.cpp index 0c39479b7260c42e6f86c1bae41fddffdf9bcc36..1ee7a7951bfb2cec7bbe86fb906d8882fae66eb3 100644 --- a/code/employee.cpp +++ b/code/employee.cpp @@ -1,13 +1,12 @@ #include #include #include -#include #include #include "employee.h" using namespace std; __declspec(selectany) sales_Records all;//总销售记录头指针 -employee_list employee_List = employee_makeEmpty(); +employee_list employee_List = employee_makeEmpty(); // 员工信息链表 employee::employee() { @@ -26,12 +25,15 @@ employee::employee() next = NULL; } + // 员工信息管理菜单 +// 无参数 +// 无返回值 void employee_meau() { employee_list p; bool flag; - int num; + int num; //操作数 while(true) { system("cls"); @@ -48,32 +50,84 @@ void employee_meau() system("cls"); switch(num) { - case 0:return; - case 1: + case 0: + { + flag = employee_printIntoFile1(employee_List); + return; //退出系统 + } + case 1: //添加员工信息 { int n; printf("1--从文件读取 2--手动添加\n请选择:"); scanf("%d", &n); fflush(stdin); - if(n == 1) + if(n == 1) //文件读取 { employee_inputFromFile(employee_List); } + else if(n == 2) + { + employee *s = new employee; //新增信息节点 + char str[30]; + int s1; + printf("员工姓名:\n"); + scanf("%s", str); + strcpy(s->name, str); + printf("员工工号:\n"); + scanf("%d", &s1); + s->id = s1; + printf("员工性别:\n"); + scanf("%s", str); + strcpy(s->sex, str); + printf("员工电话:\n"); + scanf("%s", str); + printf("基本工资:\n"); + scanf("%d", &s1); + s->basic_salary = s1; + strcpy(s->phone, str); + printf("所在部门:\n"); + scanf("%s", str); + strcpy(s->department, str); + printf("职务:\n"); + scanf("%s", str); + strcpy(s->job, str); + s->absentDays = 0; + s->salary = 0; + employee_List = employee_addNode(employee_List, s); //插入到链表中 + } else { - employee_List = employee_addNode(employee_List); + printf("输入错误!\n"); + break; } + flag = employee_printIntoFile1(employee_List); + system("pause"); break; } - case 2: + case 2: //查找员工信息 { - employee_find(employee_List); + if(employee_List->next == NULL) //判断系统内是否存在员工信息 + { + printf("系统内暂无员工信息!\n"); + system("pause"); + break; + } + employee_find(employee_List); // 查找函数 system("pause"); break; } - case 3: + case 3: //删除员工信息 { - flag = employee_deleteNode(employee_List); + if(employee_List->next == NULL) + { + printf("系统内暂无员工信息!\n"); + system("pause"); + break; + } + int id; //待删除员工工号 + printf("请输入工号:"); + scanf("%d", &id); + flag = employee_deleteNode(employee_List, id); //调用删除信息函数 if(flag == true) { printf("删除成功。\n"); @@ -82,74 +136,110 @@ void employee_meau() { printf("未找到相关信息,请重试。\n"); } + flag = employee_printIntoFile1(employee_List); system("pause"); break; } - case 4: + case 4: //统计员工工资 { - if(employee_countSalary(employee_List, all) == 1) + if(employee_List->next == NULL) { - employee_printIntoFile(employee_List); + printf("系统内暂无员工信息!\n"); + system("pause"); + break; + } + char input; + bool flag; + flag = employee_countSalary(employee_List, all); //统计函数 + bool flag2 = employee_printIntoFile1(employee_List); + printf("是否将员工信息输出到文件?(y/n)"); + fflush(stdin); + scanf("%c", &input); + if(input == 'y') + { + bool f = employee_printIntoFile(employee_List); + } + else + { + break; } break; } - case 5: + case 5: //考勤管理 { - bool flag1 = employee_modifyAbsentDays(employee_List); + if(employee_List->next == NULL) + { + printf("系统内暂无员工信息!\n"); + system("pause"); + break; + } + bool flag1 = employee_modifyAbsentDays(employee_List); // 修改函数 if(flag1 == true) { printf("修改成功!\n"); + flag = employee_printIntoFile1(employee_List); } else { printf("未找到相关信息,请重试。\n"); } system("pause"); + break; + } + default: //输出错误 + { + printf("输入错误!\n"); + system("pause"); } } } - return; + employee_deleteLinkList(employee_List); } // 创建并返回一个空的带头结点的双向链表 +// 无参数 +// 返回链表头结点 employee_list employee_makeEmpty() { - employee_list head = new employee; + employee_list head = new employee; //头结点定义并分配空间 + head->next = NULL; return head; } // 查找功能 1--ID查找 2--姓名查找 +// 参数:员工信息链表头结点 +// 返回值:无 void employee_find(employee_list head) { - int id; + int id; //待查找工号 int num; printf("1--ID查找 2--姓名查找\n"); employee_list p; - char name[30]; - scanf("%d", &num); + char name[30]; //待查找姓名 + scanf("%d", &num); // 查找类型 if(num == 1) { printf("请输入工号:\n"); scanf("%d", &id); - p = employee_findId(head, id); + p = employee_findId(head, id); //ID查找 } else if(num == 2) { printf("请输入姓名:\n"); scanf("%s", name); - p = employee_findName(head, name); + p = employee_findName(head, name); // 姓名查找 } else { printf("输入错误!\n"); return; } - if(p != NULL) + if(p != NULL) //存在则输出相应的信息 { printf("姓名:%s\n工号:%d\n性别:%s\n电话:%s\n基本工资:%d\n缺勤天数:%d\n部门:%s\n职务:%s\n", p->name, p->id, p->sex, p->phone, p->basic_salary, p->absentDays, p->department, p->job); } - else + else //不存在输出提示信息 { printf("未找到相关信息,请重试。\n"); } @@ -157,103 +247,95 @@ void employee_find(employee_list head) } // 工号的精确查找,返回表中id的位置,若找不到则返回NULL +// 参数:1.员工信息链表头结点 2.待查找工号 +// 返回:对应节点 employee_list employee_findId(employee_list listHead, int value) { employee_list p = listHead; - while(p != NULL) + while(p != NULL) //遍历链表 { if(p->id == value) + { break; + } p = p->next; } - return p; + return p; //返回对应节点 } // 姓名的精确查找,返回表中name的位置,若找不到则返回NULL +// 参数:1.员工信息链表头结点 2.待查找姓名 +// 返回值:对应节点 employee_list employee_findName(employee_list listHead, char value[]) { employee_list p = listHead; - while(p != NULL) + while(p != NULL) //遍历链表 { if(strcmp(p->name, value) == 0) + { break; + } p = p->next; } return p; } // 在position指向的结点之后插入一个结点,返回true。如果position指向非法位置,返回false -bool employee_insertNode(employee_list position) +// 参数:1.待插入位置 2.节点 +// 返回值:true/false +bool employee_insertNode(employee_list position, employee *s) { + if(s == NULL) //判断信息节点是否为空 + { + printf("添加信息失败!\n"); + return false; + } if(position == NULL) // position指向非法位置 { + printf("添加信息失败!\n"); return false; } - employee *s = new employee; - char str[30]; - int s1; - printf("员工姓名:\n"); - scanf("%s", str); - strcpy(s->name, str); - printf("员工工号:\n"); - scanf("%d", &s1); - s->id = s1; - printf("员工性别:\n"); - scanf("%s", str); - strcpy(s->sex, str); - printf("员工电话:\n"); - scanf("%s", str); - printf("基本工资:\n"); - scanf("%d", &s1); - s->basic_salary = s1; - strcpy(s->phone, str); - printf("所在部门:\n"); - scanf("%s", str); - strcpy(s->department, str); - printf("职务:\n"); - scanf("%s", str); - strcpy(s->job, str); - s->absentDays = 0; - s->salary = 0; s->next = position->next; // 修改新增结点后继指针 position->next = s; // 修改position的后继指针 if(s->next != NULL) // s不是链表尾节点 s->next->pre = s; // 修改新增结点下一结点的前驱指针 s->pre = position; // 修改新增结点前驱指针 printf("添加信息成功。\n"); - //system("pause"); return true; } // 使用头插法,在链表头部新增一个结点,返回新增结点的指针 -employee_list employee_addNode(employee_list listHead) +// 参数:1.待插入位置 2.节点 +// 返回值:链表头结点 +employee_list employee_addNode(employee_list listHead, employee *s) { - employee_insertNode(listHead); + bool flag = employee_insertNode(listHead, s); //调用插入函数 return listHead; } // 将position指向的元素删除并返回true。若position指向非法位置,返回false -bool employee_deleteNode(employee_list listHead) +// 参数:1.员工信息链表 2.工号 +// 返回值:true/False +bool employee_deleteNode(employee_list listHead, int id) { - int id; - printf("请输入工号:"); - scanf("%d", &id); employee_list p = listHead, q = listHead->next; - while(q != NULL) + while(q != NULL) //遍历链表 { if(q->id == id) { p->next = q->next; - delete q; + delete q; // 找到了,删除该节点 return true; } p = p->next; q = q->next; } - return false; + return false; //没找到 } // 从文件读入已有信息 +// 参数:链表头结点 +// 返回值:true/false bool employee_inputFromFile(employee_list listHead) { FILE *fp = fopen("employee_info.txt", "r"); @@ -268,11 +350,10 @@ bool employee_inputFromFile(employee_list listHead) while(!feof(fp)) { employee_list s = (employee *)malloc(sizeof(employee)); - fscanf(fp, "%d %s %s %s %d %d %s %s", + fscanf(fp, "%d %s %s %s %d %lf %d %s %s", //读入信息 &s->id, s->name, s->sex, s->phone, - &s->basic_salary, &s->absentDays, + &s->basic_salary, &s->salary, &s->absentDays, s->department, s->job); - s->salary = 0; s->old_price = 0; s->next = listHead->next; listHead->next = s; @@ -287,38 +368,62 @@ bool employee_inputFromFile(employee_list listHead) printf("未能成功读取数据,请检查文件是否为空。\n"); } fclose(fp); - system("pause"); return true; } -// 计算并打印员工工资 -int employee_countSalary(employee_list listHead, sales_Records re) +int employee_inputFromFile1(employee_list listHead) { - employee_list p = listHead->next; - if(p == NULL) + FILE *fp = fopen("employee_info1.txt", "r"); + if(fp == NULL) // 未打开成功 { - puts("\n当前系统中暂无记录,请输入信息后再尝试保存\n"); + puts("无法打开指定的文件,请重试。"); system("pause"); - return 0; + return false; + } + char temp[500]; // 假定一条数据的最大长度为500个字符 + int cnt = 0; // 记录读入数据条数 + while(!feof(fp)) + { + employee_list s = new employee; + fscanf(fp, "%d %s %s %s %d %lf %d %s %s\n", + &s->id, s->name, s->sex, s->phone, + &s->basic_salary, &s->salary, &s->absentDays, + s->department, s->job); + s->old_price = 0; + if(s->id != 0) + { + s->next = listHead->next; + listHead->next = s; + cnt++; + } } + fclose(fp); + return cnt; +} + +// 计算并打印员工工资 +// 参数:员工信息链表 销售记录 +// 返回值:true/false +bool employee_countSalary(employee_list listHead, sales_Records re) +{ + employee_list p = listHead->next; sales_Records q = NULL; - char input; bool flag; - printf("%-15s %-4s %-4s %-12s %-8s %-8s %-8s %-20s %s\n", + printf("%-15s %-4s %-4s %-12s %-8s %-8s %-8s %-20s %s\n", //输出提示信息 "姓名", "工号", "性别", "电话", "基本工资", "工资", "缺勤天数", "部门", "职务"); - while(p != NULL) + while(p != NULL) //遍历员工信息链表 { - if(re != NULL) + if(re != NULL) //销售记录链表不为空 { q = re->next; } double price = 0; - p->salary = p->basic_salary; + p->salary = p->basic_salary; //初始化员工工资 if(p->absentDays > 0) { p->salary -= p->absentDays * 50.0; // 计算缺勤天数应该扣的钱 } - while(q != NULL) + while(q != NULL) //遍历销售记录 { if(strcmp(p->name, q->people) == 0) { @@ -326,76 +431,101 @@ int employee_countSalary(employee_list listHead, sales_Records re) } q = q->next; } - if(price > 0) + if(price >= 0) { p->salary += (price - p->old_price) * 0.05; // 提成销售额的5% p->old_price += price; } - printf("%-15s %-4d %-4s %-12s %-8d %-8.2lf %-8d %-20s %s\n", + printf("%-15s %-4d %-4s %-12s %-8d %-8.2lf %-8d %-20s %s\n", //输出信息 p->name, p->id, p->sex, p->phone, p->basic_salary, p->salary, p->absentDays, p->department, p->job); p = p->next; } - printf("是否将员工信息输出到文件?(y/n)"); - fflush(stdin); - scanf("%c", &input); - if(input == 'y') - { - return 1; - } - else - { - return 0; - } + return true; } // 将员工信息输出到文件 -void employee_printIntoFile(employee_list listHead) +// 参数:员工信息链表 +bool employee_printIntoFile(employee_list listHead) { employee_list p = listHead->next; - if(p == NULL) - { - puts("\n当前系统中暂无记录,请输入信息后再尝试保存\n"); - system("pause"); - return; - } - FILE *fp = fopen("employ.txt", "w"); + FILE *fp = fopen("employ.txt", "w"); //打开文件 if(fp == NULL) { puts("无法打开指定文件。"); system("pause"); - return; + return false; } int num = 0; - while(p != NULL) + while(p != NULL) //将员工信息输出到文件 { fprintf(fp, "姓名:%s\n工号:%d\n性别:%s\n电话:%s\n基本工资:%d\n工资:%.2lf\n缺勤天数:%d\n部门:%s\n职务:%s\n\n", p->name, p->id, p->sex, p->phone, p->basic_salary, p->salary, p->absentDays, p->department, p->job); p = p->next; num++; } - printf("成功保存%d条数据到employ.txt中。\n", num); + printf("成功保存%d条数据到employ.txt中。\n", num); //提示信息 fclose(fp); system("pause"); + return true; } -// 员工考勤管理 +bool employee_printIntoFile1(employee_list listHead) +{ + employee_list p = listHead->next; + FILE *fp = fopen("employee_info1.txt", "w"); //打开文件 + if(fp == NULL) + { + puts("无法打开指定文件。"); + system("pause"); + return false; + } + int num = 0; + while(p != NULL) //将员工信息输出到文件 + { + fprintf(fp, "%d %s %s %s %d %.2lf %d %s %s\n", + p->id, p->name, p->sex, p->phone, p->basic_salary, p->salary, p->absentDays, p->department, p->job); + p = p->next; + num++; + } + printf("成功保存%d条数据到employ_info1.txt中。\n", num); //提示信息 + fclose(fp); + return true; +} + + +//员工考勤管理 +//参数:员工信息链表头结点 +//返回值:true/false bool employee_modifyAbsentDays(employee_list listHead) { int id, day; puts("请输入工号:"); scanf("%d", &id); - employee_list p = employee_findId(listHead, id); + employee_list p = employee_findId(listHead, id); //查找对应员工,返回相应节点 if(p == NULL) { return false; } else { - printf("员工姓名:%s\n工号:%d\n当前缺勤天数:%d\n", + printf("员工姓名:%s\n工号:%d\n当前缺勤天数:%d\n", //输出修改前信息 p->name, p->id, p->absentDays); printf("请输入修改后缺勤天数:"); scanf("%d", &day); - p->absentDays = day; + p->absentDays = day; //修改缺勤天数 return true; } -} \ No newline at end of file +} + +// 释放链表所占空间(释放全部结点) +void employee_deleteLinkList(employee_list listHead) +{ + employee_list p = listHead; + while(p->next != NULL) // 依次释放链表结点所占空间 + { + p = p->next; + delete p->pre; + } + delete p; + return; +} diff --git a/code/employee.h b/code/employee.h index 7cc304ac2db164bab7001a9da3daeb1259c89b1d..af295d1367df3254bce94ac8ad1ebd8b199b98b2 100644 --- a/code/employee.h +++ b/code/employee.h @@ -26,6 +26,8 @@ typedef employee *employee_list; typedef records *sales_Records; // employee_list 就相当于 employee* +extern employee_list employee_List; + // 创建并返回一个空的带头结点的双向链表 employee_list employee_makeEmpty(); @@ -36,13 +38,13 @@ employee_list employee_findId(employee_list listHead, int value); employee_list employee_findName(employee_list listHead, char value[]); // 在position指向的结点之后插入一个结点,返回true。如果position指向非法位置,返回false -bool employee_insertNode(employee_list position); +bool employee_insertNode(employee_list position, employee *s); // 将position指向的元素删除并返回true。若position指向非法位置,返回false -bool employee_deleteNode(employee_list position); +bool employee_deleteNode(employee_list position, int id); // 使用头插法,在链表头部新增一个结点,返回新增结点的指针 -employee_list employee_addNode(employee_list listHead); +employee_list employee_addNode(employee_list listHead, employee *s); // 释放链表所占空间(释放全部结点) void employee_deleteLinkList(employee_list listHead); @@ -50,11 +52,15 @@ void employee_deleteLinkList(employee_list listHead); // 从文件读入已有信息 bool employee_inputFromFile(employee_list listHead); +int employee_inputFromFile1(employee_list listHead); + // 计算并打印员工工资 -int employee_countSalary(employee_list listHead, sales_Records re); +bool employee_countSalary(employee_list listHead, sales_Records re); // 将员工信息输出到文件 -void employee_printIntoFile(employee_list listHead); +bool employee_printIntoFile(employee_list listHead); + +bool employee_printIntoFile1(employee_list listHead); // 查找功能 1--ID查找 2--姓名查找 void employee_find(employee_list head); @@ -64,5 +70,4 @@ void employee_meau(); // 员工考勤管理 bool employee_modifyAbsentDays(employee_list listHead); - #endif diff --git a/code/employee_info.txt b/code/employee_info.txt index 3589bedb441deaab0bab180419820b902ba2ee2d..08cc6c07cfef56de7b47a2a15219f548fb9d85be 100644 --- a/code/employee_info.txt +++ b/code/employee_info.txt @@ -1,5 +1,5 @@ -101 zhangsan M 13122220000 3000 5 SalesDepartment salesperson -102 lisi M 13255555555 3500 1 SalesDepartment salesperson -103 wangwu F 13333333333 3200 2 Division assistant -104 xiaohong M 13255888855 4500 0 SalesDepartment salesperson -105 xiaoming F 13333330000 2200 0 Division assistant \ No newline at end of file +111 xiaohua M 13122112200 3600 3600 5 SalesDepartment salesperson +112 lihua F 13256665555 3500 3500 1 SalesDepartment salesperson +113 wuyong F 13338889933 3200 3200 2 Division assistant +114 xiaodong M 13255655855 4700 4700 0 SalesDepartment salesperson +115 daming F 13303230000 2400 2400 0 Division assistant \ No newline at end of file diff --git a/code/employee_info1.txt b/code/employee_info1.txt new file mode 100644 index 0000000000000000000000000000000000000000..92d35ff1487cc721bdd19ba2b9ca05a7de5f944e --- /dev/null +++ b/code/employee_info1.txt @@ -0,0 +1,5 @@ +125 xiaoming F 13333330000 2200 2200.00 0 Division assistant +124 xiaohong M 13255888855 4500 4500.00 0 SalesDepartment salesperson +123 wangwu F 13333333333 3200 3100.00 2 Division assistant +122 lisi M 13255555555 3500 3450.00 1 SalesDepartment salesperson +121 zhangsan M 13122220000 3000 2750.00 5 SalesDepartment salesperson diff --git a/code/main.cpp b/code/main.cpp index 69287216f060f8a2f5b82efd541e99e0185297ea..efa5b1d255079baf0ab5eb5d5708de4d103f1556 100644 --- a/code/main.cpp +++ b/code/main.cpp @@ -5,6 +5,7 @@ #include "purchase.h" #include "sellFun.h" #include "repo.h" +#include "analysis.h" #define __GUI__ // 有此宏定义时使用图形界面,没有时使用控制台界面 @@ -12,8 +13,22 @@ int main() { + // 初始化供应商信息和进货信息 InitList_suppliers(suppliers_head, suppliers_tail); InitList_commodity(commodity_head, commodity_tail); + Fadd_suppliers(suppliers_head, suppliers_tail); + Fadd_commodity(commodity_head, commodity_tail, suppliers_head, suppliers_tail); + + // 初始化总销售记录(历史销售记录) + initAllRecordList(); + + // 初始化员工信息 + int employee_flag = employee_inputFromFile1(employee_List); + if(employee_flag == 0) + { + employee_List->next = NULL; + } + int choice; // choice 接收由用户输入的指令代码 system("color fc"); while(true) @@ -25,7 +40,8 @@ int main() puts(" 2 - 进货管理"); puts(" 3 - 销售管理"); puts(" 4 - 库存管理"); - puts("\n 0 - 退出系统\n"); + puts("\n 5 - 数据速览"); + puts(" 0 - 退出系统\n"); printf("请选择:"); scanf("%d", &choice); getchar(); switch(choice) @@ -58,8 +74,16 @@ int main() repo_main(); break; } + case 5: // 数据速览 + { + system("cls"); + system("title 超市管理系统 - 数据速览"); + data_overview(); + break; + } case 0: // 退出系统 { + modifyRemainNumber(); // 退出系统前修改库存信息文件 return 0; } default: @@ -84,12 +108,13 @@ enum CHOICE_CODE // PURCHASE_MODULE, // 进货管理 SELL_MODULE, // 销售管理 REPO_MODULE, // 库存管理 + ANALYSIS_MODULE, // 数据速览 EXIT_MODULE, // 退出系统 OTHER // 其它 }; CHOICE_CODE choice_code = OTHER; // 代表图形主界面选择了哪一个模块进入 -// 以下五个为响应函数,代表点击按钮时系统要执行的操作 +// 以下六个为响应函数,代表点击按钮时系统要执行的操作 px_void OnButtonClick_employeeModule(PX_Object *pObject, PX_Object_Event e, px_void *ptr) { choice_code = EMPLOYEE_MODULE; @@ -110,6 +135,11 @@ px_void OnButtonClick_repoModule(PX_Object *pObject, PX_Object_Event e, px_void choice_code = REPO_MODULE; } +px_void OnButtonClick_analysisModule(PX_Object *pObject, PX_Object_Event e, px_void *ptr) +{ + choice_code = ANALYSIS_MODULE; +} + px_void OnButtonClick_exitModule(PX_Object *pObject, PX_Object_Event e, px_void *ptr) { choice_code = EXIT_MODULE; @@ -128,73 +158,92 @@ void GUI_Init() px_texture employee_logo; // 定义"员工管理"模块logo对应的纹理结构 PX_LoadTextureFromFile(PX_GetMP(), &employee_logo, (px_char *)".\\image\\employee.bmp"); // 从文件加载一个图片放在纹理中 - PX_TextureRender(PX_GetSurface(), &employee_logo, 145, 160, + PX_TextureRender(PX_GetSurface(), &employee_logo, 145, 150, PX_TEXTURERENDER_REFPOINT_LEFTTOP, PX_NULL); // 绘制纹理 px_texture purchase_logo; // 定义"进货管理"模块logo对应的纹理结构 PX_LoadTextureFromFile(PX_GetMP(), &purchase_logo, (px_char *)".\\image\\purchase.bmp"); // 从文件加载一个图片放在纹理中 - PX_TextureRender(PX_GetSurface(), &purchase_logo, 545, 160, + PX_TextureRender(PX_GetSurface(), &purchase_logo, 545, 150, PX_TEXTURERENDER_REFPOINT_LEFTTOP, PX_NULL); // 绘制纹理 px_texture sell_logo; // 定义"销售管理"模块logo对应的纹理结构 PX_LoadTextureFromFile(PX_GetMP(), &sell_logo, (px_char *)".\\image\\sell.bmp"); // 从文件加载一个图片放在纹理中 - PX_TextureRender(PX_GetSurface(), &sell_logo, 145, 350, + PX_TextureRender(PX_GetSurface(), &sell_logo, 145, 340, PX_TEXTURERENDER_REFPOINT_LEFTTOP, PX_NULL); // 绘制纹理 px_texture repo_logo; // 定义"库存管理"模块logo对应的纹理结构 PX_LoadTextureFromFile(PX_GetMP(), &repo_logo, (px_char *)".\\image\\repo.bmp"); // 从文件加载一个图片放在纹理中 - PX_TextureRender(PX_GetSurface(), &repo_logo, 545, 350, + PX_TextureRender(PX_GetSurface(), &repo_logo, 545, 340, PX_TEXTURERENDER_REFPOINT_LEFTTOP, PX_NULL); // 绘制纹理 // 绘制按钮 PX_Object *Button_employee; // 定义"员工管理"按钮对象 Button_employee = PX_Object_PushButtonCreate(PX_GetMP(), PX_GetUiRoot(), - 160, 280, 80, 32, "员工管理", PX_COLOR(255, 0, 0, 0)); // 创建按钮 + 160, 270, 80, 32, "员工管理", PX_COLOR(255, 0, 0, 0)); // 创建按钮 PX_ObjectRegisterEvent(Button_employee, PX_OBJECT_EVENT_EXECUTE, OnButtonClick_employeeModule, PX_NULL); // 绑定响应函数 PX_Object *Button_purchase; // 定义"进货管理"按钮对象 Button_purchase = PX_Object_PushButtonCreate(PX_GetMP(), PX_GetUiRoot(), - 560, 280, 80, 32, "进货管理", PX_COLOR(255, 0, 0, 0)); // 创建按钮 + 560, 270, 80, 32, "进货管理", PX_COLOR(255, 0, 0, 0)); // 创建按钮 PX_ObjectRegisterEvent(Button_purchase, PX_OBJECT_EVENT_EXECUTE, OnButtonClick_purchaseModule, PX_NULL); // 绑定响应函数 PX_Object *Button_sell; // 定义"销售管理"按钮对象 Button_sell = PX_Object_PushButtonCreate(PX_GetMP(), PX_GetUiRoot(), - 160, 470, 80, 32, "销售管理", PX_COLOR(255, 0, 0, 0)); // 创建按钮 + 160, 460, 80, 32, "销售管理", PX_COLOR(255, 0, 0, 0)); // 创建按钮 PX_ObjectRegisterEvent(Button_sell, PX_OBJECT_EVENT_EXECUTE, OnButtonClick_sellModule, PX_NULL); // 绑定响应函数 PX_Object *Button_repo; // 定义"库存管理"按钮对象 Button_repo = PX_Object_PushButtonCreate(PX_GetMP(), PX_GetUiRoot(), - 560, 470, 80, 32, "库存管理", PX_COLOR(255, 0, 0, 0)); // 创建按钮 + 560, 460, 80, 32, "库存管理", PX_COLOR(255, 0, 0, 0)); // 创建按钮 PX_ObjectRegisterEvent(Button_repo, PX_OBJECT_EVENT_EXECUTE, OnButtonClick_repoModule, PX_NULL); // 绑定响应函数 + PX_Object *Button_analysis; // 定义"数据速览"按钮对象 + Button_analysis = PX_Object_PushButtonCreate(PX_GetMP(), PX_GetUiRoot(), + 270, 535, 80, 32, "数据速览", PX_COLOR(255, 0, 0, 0)); // 创建按钮 + PX_ObjectRegisterEvent(Button_analysis, PX_OBJECT_EVENT_EXECUTE, + OnButtonClick_analysisModule, PX_NULL); // 绑定响应函数 + PX_Object *Button_exit; // 定义"退出系统"按钮对象 Button_exit = PX_Object_PushButtonCreate(PX_GetMP(), PX_GetUiRoot(), - 360, 535, 80, 32, "退出系统", PX_COLOR(255, 0, 0, 0)); // 创建按钮 + 450, 535, 80, 32, "退出系统", PX_COLOR(255, 0, 0, 0)); // 创建按钮 PX_ObjectRegisterEvent(Button_exit, PX_OBJECT_EVENT_EXECUTE, OnButtonClick_exitModule, PX_NULL); // 绑定响应函数 } int main() { + // 初始化供应商信息和进货信息 InitList_suppliers(suppliers_head, suppliers_tail); InitList_commodity(commodity_head, commodity_tail); - system("title 销售管理系统"); + Fadd_suppliers(suppliers_head, suppliers_tail); + Fadd_commodity(commodity_head, commodity_tail, suppliers_head, suppliers_tail); + + // 初始化总销售记录(历史销售记录) + initAllRecordList(); + + // 初始化员工信息 + int employee_flag = employee_inputFromFile1(employee_List); + if(employee_flag == 0) + { + employee_List->next = NULL; + } + + system("title 超市管理系统"); system("color fc"); HWND HWND_console = GetForegroundWindow(); // 控制台窗口句柄 - PX_Initialize("销售管理系统:主界面", 800, 600); + PX_Initialize("超市管理系统:主界面", 800, 600); GUI_Init(); HWND HWND_GUI = GetForegroundWindow(); // 图形界面窗口句柄 ShowWindow(HWND_console, SW_MINIMIZE); while(true) { - //GUI_Init(); while(PX_Loop()) { break; @@ -245,10 +294,22 @@ int main() ShowWindow(HWND_GUI, SW_RESTORE); break; } + case ANALYSIS_MODULE: // 数据速览 + { + ShowWindow(HWND_GUI, SW_MINIMIZE); + ShowWindow(HWND_console, SW_RESTORE); + system("cls"); + system("title 超市管理系统 - 数据速览"); + data_overview(); + ShowWindow(HWND_console, SW_MINIMIZE); + ShowWindow(HWND_GUI, SW_RESTORE); + break; + } case EXIT_MODULE: // 退出系统 { ShowWindow(HWND_GUI, SW_MINIMIZE); ShowWindow(HWND_console, SW_RESTORE); + modifyRemainNumber(); // 退出系统前修改库存信息文件 system("cls"); printf("已退出超市管理系统。\n\n欢迎下次使用!\n"); return 0; diff --git a/code/repo.cpp b/code/repo.cpp index aa31aea5a6abcaeee8d1ed4100fbad19768b58ae..35c6c2758d82e89162a35dedc2b99cb568fa0383 100644 --- a/code/repo.cpp +++ b/code/repo.cpp @@ -1,4 +1,5 @@ #include "repo.h" +#include "purchase.h" /************************************************************ * repo_printGoodsInfo -- 输出p所指向的商品信息 @@ -362,4 +363,37 @@ void repo_main() default:puts("输入错误!"); system("pause"); break; } -} \ No newline at end of file +} + + +/********************************************************* + * modifyRemainNumber -- 在退出系统前,修改库存信息文件, + * 把变动后的剩余库存值写入文件 + * 参数:无 + * 返回值:无 + *********************************************************/ +void modifyRemainNumber() +{ + FILE *fp; + commodity p = commodity_head->next; + purchase s; + fp = fopen("commodity1.txt", "w"); + if(fp == NULL) + { + printf("库存商品信息文件 commodity1.txt 打开失败!"); + exit(0); + } + while(p != NULL) + { + ListHandle_purchase(suppliers_head, s, p->id_Number); + fprintf(fp, "%s %s %d %d %d %s %s %d %lf %lf %d %d %d %d %s%c", + p->id_Number, p->goods_Name, p->purchase_Date.year, p->purchase_Date.month, p->purchase_Date.day, + s->source, s->channel, p->remain_Number, + p->buy_Price, p->sell_Price, p->produce_Date.year, p->produce_Date.month, p->produce_Date.day, + p->quality_Date, p->place, + (p->next != NULL) ? '\n' : ' ' // 最后一行数据的末尾有一个空格 + ); + p = p->next; + } + fclose(fp); +} diff --git a/code/repo.h b/code/repo.h index 6102c26e478d6e3c444a2d0879b291273edb1e69..ae92741f5bf775aa694f7dc1ecb54d8a3a543caf 100644 --- a/code/repo.h +++ b/code/repo.h @@ -31,4 +31,7 @@ bool repo_goodsOverdueWarning(goods *listHead); // 库存管理主函数 void repo_main(); +// 在退出系统前,修改库存信息文件,把变动后的剩余库存值写入文件 +void modifyRemainNumber(); + #endif