diff --git a/code/date.cpp b/code/date.cpp index 0ebd7f3d526834f21cc3ad65bff6b125c78bfb04..9c5213156392a7ec23894d2acfa5ffab2bc89317 100644 --- a/code/date.cpp +++ b/code/date.cpp @@ -1,7 +1,9 @@ #include "date.h" +// 无参构造函数 date::date() :year(0), month(0), day(0) {} +// 带参构造函数 date::date(int y, int m, int d) : year(y), month(m), day(d) {} @@ -9,13 +11,12 @@ date::date(int y, int m, int d) : date::date(const date &_date) : year(_date.year), month(_date.month), day(_date.day) {} -// 重载大于号,判断日期a是否大于日期b -/*********************************************** - * addDate -- 返回日期a + 天数b的结果 - * 参数:d:日期结构体(年月日) - * days:要加的天数 - * 返回值:计算结果,类型为日期(年月日) - ***********************************************/ +/**************************************************** + * operator> -- 重载大于号,判断日期a是否大于日期b + * 参数:a,b:都是日期结构体(年月日) + * 返回值:若日期a大于日期b,返回true + * 否则返回false + ****************************************************/ bool operator>(const date &a, const date &b) { if(a.year != b.year) @@ -26,7 +27,7 @@ bool operator>(const date &a, const date &b) } /*********************************************** - * addDate -- 返回日期a + 天数b的结果 + * addDay -- 返回日期a + 天数b的结果 * 参数:d:日期结构体(年月日) * days:要加的天数 * 返回值:计算结果,类型为日期(年月日) diff --git a/code/employee.cpp b/code/employee.cpp index 0fc8626cada063836c546048591db71029d5ca14..ba9fd83140c9201521d5a82097c9c0ea5dfb1101 100644 --- a/code/employee.cpp +++ b/code/employee.cpp @@ -1,7 +1,13 @@ #include #include #include +#include +#include #include "employee.h" +using namespace std; + +__declspec(selectany) sales_Records all;//总销售记录头指针 +employee_list employee_List = employee_makeEmpty(); employee::employee() { @@ -12,12 +18,99 @@ employee::employee() memset(phone, 0, sizeof(phone)); basic_salary = 0; absentDays = 0; + salary = 0; + old_price = 0; memset(department, 0, sizeof(department)); memset(job, 0, sizeof(job)); pre = NULL; next = NULL; } +// 员工信息管理菜单 +void employee_meau() +{ + employee_list p; + bool flag; + int num; + while(true) + { + system("cls"); + printf("欢迎使用员工信息管理!\n"); + printf("*******请输入要执行的功能:*******\n"); + printf("****** 1----增加员工信息 *********\n"); + printf("****** 2----查找员工信息 *********\n"); + printf("****** 3----删除员工信息 *********\n"); + printf("****** 4----统计员工工资 *********\n"); + printf("****** 5----员工考勤管理 *********\n"); + printf("********* 0----退出系统 **********\n"); + scanf("%d", &num); getchar(); + fflush(stdin); + system("cls"); + switch(num) + { + case 0:return; + case 1: + { + int n; + printf("1--从文件读取 2--手动添加\n请选择:"); + scanf("%d", &n); + fflush(stdin); + if(n == 1) + { + employee_inputFromFile(employee_List); + } + else + { + employee_List = employee_addNode(employee_List); + } + break; + } + case 2: + { + employee_find(employee_List); + system("pause"); + break; + } + case 3: + { + flag = employee_deleteNode(employee_List); + if(flag == true) + { + printf("删除成功。\n"); + } + else + { + printf("未找到相关信息,请重试。\n"); + } + system("pause"); + break; + } + case 4: + { + if(employee_countSalary(employee_List, all) == 1) + { + employee_printIntoFile(employee_List); + } + break; + } + case 5: + { + bool flag1 = employee_modifyAbsentDays(employee_List); + if(flag1 == true) + { + printf("修改成功!\n"); + } + else + { + printf("未找到相关信息,请重试。\n"); + } + system("pause"); + } + } + } + return; +} + // 创建并返回一个空的带头结点的双向链表 employee_list employee_makeEmpty() { @@ -25,10 +118,48 @@ employee_list employee_makeEmpty() return head; } +// 查找功能 1--ID查找 2--姓名查找 +void employee_find(employee_list head) +{ + int id; + int num; + printf("1--ID查找 2--姓名查找\n"); + employee_list p; + char name[30]; + scanf("%d", &num); + if(num == 1) + { + printf("请输入工号:\n"); + scanf("%d", &id); + p = employee_findId(head, id); + } + else if(num == 2) + { + printf("请输入姓名:\n"); + scanf("%s", name); + p = employee_findName(head, name); + } + else + { + printf("输入错误!\n"); + return; + } + 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 + { + printf("未找到相关信息,请重试。\n"); + } + return; +} + // 工号的精确查找,返回表中id的位置,若找不到则返回NULL employee_list employee_findId(employee_list listHead, int value) { - employee_list p = listHead->next; + employee_list p = listHead; while(p != NULL) { if(p->id == value) @@ -41,7 +172,7 @@ employee_list employee_findId(employee_list listHead, int value) // 姓名的精确查找,返回表中name的位置,若找不到则返回NULL employee_list employee_findName(employee_list listHead, char value[]) { - employee_list p = listHead->next; + employee_list p = listHead; while(p != NULL) { if(strcmp(p->name, value) == 0) @@ -59,34 +190,38 @@ bool employee_insertNode(employee_list position) 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; // 修改新增结点前驱指针 - - // 在这个函数里没有给新增的结点赋值 - // 请在调用完该函数之后,给新增结点的每一项挨个赋值 - // 新增结点的指针就是“该函数的参数->next” - - return true; -} - -// 将position指向的元素删除并返回true。若position指向非法位置,返回false -bool employee_deleteNode(employee_list position) -{ - // 第一,如果position指向非法位置(如NULL),此时返回false - // 第二,不能直接删除头结点,如需删除空链表请使用deleteLinkList函数 - if(position == NULL || position->pre == NULL) - { - return false; - } - position->pre->next = position->next; // 断开position与前一个的联系 - if(position->next != NULL) // position不是链表尾节点 - position->next->pre = position->pre; // 断开position与后一个的联系 - delete position; - position = NULL; - + printf("添加信息成功。\n"); + //system("pause"); return true; } @@ -94,30 +229,34 @@ bool employee_deleteNode(employee_list position) employee_list employee_addNode(employee_list listHead) { employee_insertNode(listHead); - return listHead->next; + return listHead; } -// 释放链表所占空间(释放全部结点) -void employee_deleteLinkList(employee_list listHead) +// 将position指向的元素删除并返回true。若position指向非法位置,返回false +bool employee_deleteNode(employee_list listHead) { - employee *p = listHead; - while(p->next != NULL) // 依次释放链表结点所占空间 + int id; + printf("请输入工号:"); + scanf("%d", &id); + employee_list p = listHead, q = listHead->next; + while(q != NULL) { + if(q->id == id) + { + p->next = q->next; + delete q; + return true; + } p = p->next; - delete p->pre; + q = q->next; } - delete p; - return; + return false; } // 从文件读入已有信息 bool employee_inputFromFile(employee_list listHead) { - puts("请输入文件名或文件的地址,以回车结束。注意:地址中的'\\'应写作\"\\\\\"。"); - char fileName[200]; // 文件名或地址 - scanf("%[^\n]", fileName); - fflush(stdin); - FILE *fp = fopen(fileName, "r"); + FILE *fp = fopen("employee_info.txt", "r"); if(fp == NULL) // 未打开成功 { puts("无法打开指定的文件,请重试。"); @@ -126,24 +265,128 @@ bool employee_inputFromFile(employee_list listHead) } char temp[500]; // 假定一条数据的最大长度为500个字符 int cnt = 0; // 记录读入数据条数 - while(fgets(temp, 500, fp) != NULL) + while(!feof(fp)) { - employee *s = employee_addNode(listHead); - sscanf(temp, "%d\t%s\t%s\t%s\t%d\t%d\t%s\t%s", + employee_list s = (employee *)malloc(sizeof(employee)); + fscanf(fp, "%d %s %s %s %d %d %s %s", &s->id, s->name, s->sex, s->phone, &s->basic_salary, &s->absentDays, s->department, s->job); + s->salary = 0; + s->old_price = 0; + s->next = listHead->next; + listHead->next = s; cnt++; } if(cnt != 0) { - printf("成功读入 %d 条数据。", cnt); + printf("成功读入 %d 条数据。\n", cnt); } else { - printf("未能成功读取数据,请检查文件 %s 是否为空。\n", fileName); + printf("未能成功读取数据,请检查文件是否为空。\n"); } fclose(fp); system("pause"); return true; +} + +// 计算并打印员工工资 +int employee_countSalary(employee_list listHead, sales_Records re) +{ + employee_list p = listHead->next; + sales_Records q; + char input; + bool flag; + printf("%-15s %-4s %-4s %-12s %-8s %-8s %-8s %-20s %s\n", + "姓名", "工号", "性别", "电话", "基本工资", "工资", "缺勤天数", "部门", "职务"); + while(p != NULL) + { + q = re->next; + double price = 0; + p->salary = p->basic_salary; + if(p->absentDays > 0) + { + p->salary -= p->absentDays * 50.0; // 计算缺勤天数应该扣的钱 + } + while(q != NULL) + { + if(strcmp(p->name, q->people) == 0) + { + price += q->price; + } + q = q->next; + } + 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", + 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; + } +} + +// 将员工信息输出到文件 +void 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"); + if(fp == NULL) + { + puts("无法打开指定文件。"); + system("pause"); + return; + } + int num = 0; + 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); + fclose(fp); + system("pause"); +} + +// 员工考勤管理 +bool employee_modifyAbsentDays(employee_list listHead) +{ + int id, day; + puts("请输入工号:"); + scanf("%d", &id); + employee_list p = employee_findId(listHead, id); + if(p == NULL) + { + return false; + } + else + { + printf("员工姓名:%s\n工号:%d\n当前缺勤天数:%d\n", + p->name, p->id, p->absentDays); + printf("请输入修改后缺勤天数:"); + scanf("%d", &day); + p->absentDays = day; + return true; + } } \ No newline at end of file diff --git a/code/employee.h b/code/employee.h index 4cab13f33cdfdaf2c29c9d75368d600266086195..7cc304ac2db164bab7001a9da3daeb1259c89b1d 100644 --- a/code/employee.h +++ b/code/employee.h @@ -3,22 +3,27 @@ // 标准头文件结构 +#include "sell.h" + // 员工信息结点的数据结构(双向链表) struct employee { int id; // 工号 - char name[10]; // 姓名 + char name[15]; // 姓名 char sex[5]; // 性别 char phone[15]; // 电话 int basic_salary; // 基本工资 + double salary; //工资 + double old_price; // 历史销售额 int absentDays; // 缺勤的天数 - char department[30]; // 部门 - char job[30]; // 职务 + char department[20]; // 部门 + char job[20]; // 职务 struct employee *pre; // 前趋指针 struct employee *next; // 后继指针 employee(); // 构造函数,用于新建结点时初始化内容 }; typedef employee *employee_list; +typedef records *sales_Records; // employee_list 就相当于 employee* // 创建并返回一个空的带头结点的双向链表 @@ -45,4 +50,19 @@ void employee_deleteLinkList(employee_list listHead); // 从文件读入已有信息 bool employee_inputFromFile(employee_list listHead); +// 计算并打印员工工资 +int employee_countSalary(employee_list listHead, sales_Records re); + +// 将员工信息输出到文件 +void employee_printIntoFile(employee_list listHead); + +// 查找功能 1--ID查找 2--姓名查找 +void employee_find(employee_list head); + +// 员工管理模块菜单 +void employee_meau(); + +// 员工考勤管理 +bool employee_modifyAbsentDays(employee_list listHead); + #endif diff --git a/code/employee_info.txt b/code/employee_info.txt new file mode 100644 index 0000000000000000000000000000000000000000..3589bedb441deaab0bab180419820b902ba2ee2d --- /dev/null +++ b/code/employee_info.txt @@ -0,0 +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 diff --git a/code/main.cpp b/code/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ecaba54555bb3036311294115a987af28310f62d --- /dev/null +++ b/code/main.cpp @@ -0,0 +1,78 @@ +#include +#include +#include +#include "employee.h" +#include "purchase.h" +#include "sellFun.h" +#include "repo.h" + +#ifndef __GUI__ // 用控制台(黑框)实现系统主界面 + +int main() +{ + InitList_suppliers(suppliers_head, suppliers_tail); + InitList_commodity(commodity_head, commodity_tail); + int choice; // choice 接收由用户输入的指令代码 + system("color fc"); + while(true) + { + system("cls"); // 清屏 + system("title 超市管理系统"); // 更改窗口标题 + puts(" * * * * * 超 市 管 理 系 统 * * * * *\n"); + puts(" 1 - 员工管理"); + puts(" 2 - 进货管理"); + puts(" 3 - 销售管理"); + puts(" 4 - 库存管理"); + puts("\n 0 - 退出系统\n"); + printf("请选择:"); + scanf("%d", &choice); getchar(); + switch(choice) + { + case 1: // 员工管理 + { + system("cls"); + system("title 超市管理系统 - 员工管理"); + employee_meau(); + break; + } + case 2: // 进货管理 + { + system("cls"); + system("title 超市管理系统 - 进货管理"); + Main_interface(commodity_head, commodity_tail, suppliers_head, suppliers_tail); + break; + } + case 3: // 销售管理 + { + system("cls"); + system("title 超市管理系统 - 销售管理"); + sellmain(); + break; + } + case 4: // 库存管理 + { + system("cls"); + system("title 超市管理系统 - 库存管理"); + repo_main(); + break; + } + case 0: // 退出系统 + { + return 0; + } + default: + { + puts("输入错误,请重新输入。"); + system("pause"); + break; + } + } + } + return 0; +} + +#else // 用图形用户界面(GUI)实现系统主界面 + + + +#endif // !__GUI__ diff --git a/code/repo.cpp b/code/repo.cpp index 9cf68bd81ec5a7146308c1af1bc3739ee9e54c69..aa31aea5a6abcaeee8d1ed4100fbad19768b58ae 100644 --- a/code/repo.cpp +++ b/code/repo.cpp @@ -1,7 +1,365 @@ -#include #include "repo.h" -// 查询商品信息结构体中是否有剩余货 +/************************************************************ + * repo_printGoodsInfo -- 输出p所指向的商品信息 + * 参数:fp:文件指针,为stdout时表示输出到标准输出,即屏幕 + * p:指向某个库存商品的指针 + * 返回值:无 + ************************************************************/ +void repo_printGoodsInfo(FILE *fp, goods *p) +{ + fprintf(fp, "%-20s %-20s %8.2lf %8.2lf %04d-%02d-%02d %6d %04d-%02d-%02d %8d %s\n", + p->id_Number, // 商品编号 + p->goods_Name, // 商品名 + p->buy_Price, // 商品进价 + p->sell_Price, // 商品售价 + p->produce_Date.year, p->produce_Date.month, p->produce_Date.day, // 生产日期 + p->quality_Date, // 保质期 + p->purchase_Date.year, p->purchase_Date.month, p->purchase_Date.day, // 进货日期 + p->remain_Number, // 剩余数量 + p->place // 库存位置 + ); + return; +} -// 卖出货后减去相应数量 +/**************************************************** + * repo_showRepoInfo -- 库存查询 + * 参数:listHead:库存商品链表的头指针 + * 返回值:查询成功,返回true + * 查询失败,返回false + ****************************************************/ +bool repo_showRepoInfo(goods *listHead) +{ + system("title 库存管理 - 库存查询"); + if(listHead->next == NULL) // 库存为空 + { + printf("库存为空!\n"); // 输出提示信息 + system("pause"); + return false; + } + int count = 0; // 库存信息的条数 + goods *p = listHead->next; + while(p != NULL) + { + if(count == 0) // 如果是第一条信息 + { + // 输出列标题 + printf("%-20s %-20s %-8s %-8s %-10s %-6s %-10s %-8s %s\n", + "商品编号", "商品名", "商品进价", "商品售价", "生产日期", "保质期", "进货日期", "剩余数量", "库存位置"); + } + repo_printGoodsInfo(stdout, p); // 输出商品信息 + count++; + p = p->next; + } + if(count != 0) + { + printf("\n库存信息共 %d 条。\n", count); // 输出条数 + printf("是否将库存信息输出到文件?如果需要输出,请键入yes,键入其它字符返回主菜单:"); + char choice[5]; + scanf("%s", choice); + fflush(stdin); + if(strcmp(choice, "yes") == 0) + { + // 输出到文件 + int fcount = 0; + FILE *fp = fopen("Repo Info.txt", "w"); + p = listHead->next; + while(p != NULL) + { + if(fcount == 0) // 如果是第一条预警信息 + { + // 输出列标题 + fprintf(fp, "%-20s %-20s %-8s %-8s %-10s %-6s %-10s %-8s %s\n", + "商品编号", "商品名", "商品进价", "商品售价", "生产日期", "保质期", "进货日期", "剩余数量", "库存位置"); + } + repo_printGoodsInfo(fp, p); // 输出商品信息 + fcount++; + p = p->next; + } + fclose(fp); + printf("库存信息已写入 Repo Info.txt\n"); + } + } + system("pause"); + return true; +} +/**************************************************** + * repo_goodsTooMuchWarning -- 查询库存积压预警 + * 参数:listHead:库存商品链表的头指针 + * 返回值:查询成功,返回true + * 查询失败,返回false + ****************************************************/ +bool repo_goodsTooMuchWarning(goods *listHead) +{ + system("title 库存管理 - 库存积压预警"); + if(listHead->next == NULL) // 库存为空 + { + printf("库存为空!\n"); // 输出提示信息 + system("pause"); + return false; + } + printf("请输入积压时长预警值(库存积压时长大于此天数时将会发出预警):\n\n"); + printf(">>> "); + int warningValue = 0; // 积压时长预警值 + int count = 0; // 预警的条数 + while(scanf("%d", &warningValue) != 1 || warningValue <= 0) + { + // 输入不是数字或小于等于0,视为输入非法 + printf("输入错误,请重新输入:"); + } + fflush(stdin); + goods *p = listHead->next; + 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); + // 创建变量current_date,记录今天的日期 + + while(p != NULL) + { + // 库存积压时长大于预警值,即当前日期 > 进货日期 + 积压时长预警天数 + if(current_date > addDay(p->purchase_Date, warningValue)) + { + if(count == 0) // 如果是第一条预警信息 + { + // 输出列标题 + printf("%-20s %-20s %-8s %-8s %-10s %-6s %-10s %-8s %s\n", + "商品编号", "商品名", "商品进价", "商品售价", "生产日期", "保质期", "进货日期", "剩余数量", "库存位置"); + } + repo_printGoodsInfo(stdout, p); // 输出商品信息 + count++; + } + p = p->next; + } + if(count != 0) + { + printf("\n共 %d 条预警。\n", count); // 输出预警的条数 + printf("是否将预警信息输出到文件?如果需要输出,请键入yes,键入其它字符返回主菜单:"); + char choice[5]; + scanf("%s", choice); + fflush(stdin); + if(strcmp(choice, "yes") == 0) + { + // 输出到文件 + int fcount = 0; + FILE *fp = fopen("Goods Too Much - Warning.txt", "w"); + p = listHead->next; + while(p != NULL) + { + // 库存积压时长大于预警值,即当前日期 > 进货日期 + 积压时长预警天数 + if(current_date > addDay(p->purchase_Date, warningValue)) + { + if(fcount == 0) // 如果是第一条预警信息 + { + // 输出列标题 + fprintf(fp, "%-20s %-20s %-8s %-8s %-10s %-6s %-10s %-8s %s\n", + "商品编号", "商品名", "商品进价", "商品售价", "生产日期", "保质期", "进货日期", "剩余数量", "库存位置"); + } + repo_printGoodsInfo(fp, p); // 输出商品信息 + fcount++; + } + p = p->next; + } + fclose(fp); + printf("库存积压预警信息已写入 Goods Too Much - Warning.txt\n"); + } + } + else + { + printf("没有积压超过 %d 天的货物。\n", warningValue); // 输出提示信息 + } + system("pause"); + return true; +} + +/**************************************************** + * repo_goodsTooLittleWarning -- 查询缺货断货预警 + * 参数:listHead:库存商品链表的头指针 + * 返回值:查询成功,返回true + * 查询失败,返回false + ****************************************************/ +bool repo_goodsTooLittleWarning(goods *listHead) +{ + system("title 库存管理 - 缺货断货预警"); + if(listHead->next == NULL) // 库存为空 + { + printf("库存为空!\n"); // 输出提示信息 + system("pause"); + return false; + } + printf("请输入库存量预警值(剩余库存小于此数量时将会发出预警):\n\n"); + printf(">>> "); + int warningValue = 0; // 库存量预警值 + int count = 0; // 预警的条数 + while(scanf("%d", &warningValue) != 1 || warningValue <= 0) + { + // 输入不是数字或小于等于0,视为输入非法 + printf("输入错误,请重新输入:"); + } + fflush(stdin); + goods *p = listHead->next; + while(p != NULL) + { + if(p->remain_Number < warningValue) // 剩余库存小于预警值 + { + if(count == 0) // 如果是第一条预警信息 + { + // 输出列标题 + printf("%-20s %-20s %-8s %-8s %-10s %-6s %-10s %-8s %s\n", + "商品编号", "商品名", "商品进价", "商品售价", "生产日期", "保质期", "进货日期", "剩余数量", "库存位置"); + } + repo_printGoodsInfo(stdout, p); // 输出商品信息 + count++; + } + p = p->next; + } + if(count != 0) + { + printf("\n共 %d 条预警。\n", count); // 输出预警的条数 + printf("是否将预警信息输出到文件?如果需要输出,请键入yes,键入其它字符返回主菜单:"); + char choice[5]; + scanf("%s", choice); + fflush(stdin); + if(strcmp(choice, "yes") == 0) + { + // 输出到文件 + int fcount = 0; + FILE *fp = fopen("Goods Too Little - Warning.txt", "w"); + p = listHead->next; + while(p != NULL) + { + if(p->remain_Number < warningValue) // 剩余库存小于预警值 + { + if(fcount == 0) // 如果是第一条预警信息 + { + // 输出列标题 + fprintf(fp, "%-20s %-20s %-8s %-8s %-10s %-6s %-10s %-8s %s\n", + "商品编号", "商品名", "商品进价", "商品售价", "生产日期", "保质期", "进货日期", "剩余数量", "库存位置"); + } + repo_printGoodsInfo(fp, p); // 输出商品信息 + fcount++; + } + p = p->next; + } + fclose(fp); + printf("缺货断货预警信息已写入 Goods Too Little - Warning.txt\n"); + } + } + else + { + printf("没有剩余库存小于 %d 的货物。\n", warningValue); // 输出提示信息 + } + system("pause"); + return true; +} + +/**************************************************** + * repo_goodsOverdueWarning -- 查询货物过期预警 + * 参数:listHead:库存商品链表的头指针 + * 返回值:查询成功,返回true + * 查询失败,返回false + ****************************************************/ +bool repo_goodsOverdueWarning(goods *listHead) +{ + system("title 库存管理 - 货物过期预警"); + if(listHead->next == NULL) // 库存为空 + { + printf("库存为空!\n"); // 输出提示信息 + system("pause"); + return false; + } + int count = 0; // 预警的条数 + goods *p = listHead->next; + 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); + // 创建变量current_date,记录今天的日期 + + while(p != NULL) + { + // 库存商品已经过期,即当前日期 > 生产日期 + 保质期 + if(current_date > addDay(p->produce_Date, p->quality_Date)) + { + if(count == 0) // 如果是第一条预警信息 + { + // 输出列标题 + printf("%-20s %-20s %-8s %-8s %-10s %-6s %-10s %-8s %s\n", + "商品编号", "商品名", "商品进价", "商品售价", "生产日期", "保质期", "进货日期", "剩余数量", "库存位置"); + } + repo_printGoodsInfo(stdout, p); // 输出商品信息 + count++; + } + p = p->next; + } + if(count != 0) + { + printf("\n共 %d 条预警。\n", count); // 输出预警的条数 + printf("是否将预警信息输出到文件?如果需要输出,请键入yes,键入其它字符返回主菜单:"); + char choice[5]; + scanf("%s", choice); + fflush(stdin); + if(strcmp(choice, "yes") == 0) + { + // 输出到文件 + int fcount = 0; + FILE *fp = fopen("Goods Overdue - Warning.txt", "w"); + p = listHead->next; + while(p != NULL) + { + // 库存商品已经过期,即当前日期 > 生产日期 + 保质期 + if(current_date > addDay(p->produce_Date, p->quality_Date)) + { + if(fcount == 0) // 如果是第一条预警信息 + { + // 输出列标题 + fprintf(fp, "%-20s %-20s %-8s %-8s %-10s %-6s %-10s %-8s %s\n", + "商品编号", "商品名", "商品进价", "商品售价", "生产日期", "保质期", "进货日期", "剩余数量", "库存位置"); + } + repo_printGoodsInfo(fp, p); // 输出商品信息 + fcount++; + } + p = p->next; + } + fclose(fp); + printf("货物过期预警信息已写入 Goods Overdue - Warning.txt\n"); + } + } + else + { + printf("没有已经过期的货物。\n"); // 输出提示信息 + } + system("pause"); + return true; +} + +/**************************************************** + * repo_main -- 库存管理主函数 + * 参数:无 + * 返回值:无 + ****************************************************/ +void repo_main() +{ + puts(" 1 - 库存查询"); + puts(" 2 - 库存积压预警"); + puts(" 3 - 缺货断货预警"); + puts(" 4 - 货物过期预警"); + puts(" 0 - 返回主菜单"); + printf("请选择:"); + int choice; + scanf("%d", &choice); + fflush(stdin); + switch(choice) + { + case 1:system("cls"); repo_showRepoInfo(commodity_head); break; // 库存查询 + case 2:system("cls"); repo_goodsTooMuchWarning(commodity_head); break; // 库存积压预警 + case 3:system("cls"); repo_goodsTooLittleWarning(commodity_head); break; // 缺货断货预警 + case 4:system("cls"); repo_goodsOverdueWarning(commodity_head); break; // 货物过期预警 + case 0:return; // 返回主菜单 + + default:puts("输入错误!"); system("pause"); break; + } +} \ No newline at end of file diff --git a/code/repo.h b/code/repo.h index a507af6e2c499a82641029fe9e2b173ccad4d6a2..6102c26e478d6e3c444a2d0879b291273edb1e69 100644 --- a/code/repo.h +++ b/code/repo.h @@ -1,8 +1,34 @@ #ifndef __REPO_H__ #define __REPO_H__ -// 标准头文件结构。 +// 标准头文件结构 +#include +#include +#include +#include +#include "date.h" +#include "sell.h" +// 商品(库存)头指针 +extern commodity commodity_head; + +// 输出p所指向的商品信息 +void repo_printGoodsInfo(FILE *fp, goods *p); + +// 库存查询 +bool repo_showRepoInfo(goods *listHead); + +// 查询库存积压预警 +bool repo_goodsTooMuchWarning(goods *listHead); + +// 查询缺货断货预警 +bool repo_goodsTooLittleWarning(goods *listHead); + +// 查询货物过期预警 +bool repo_goodsOverdueWarning(goods *listHead); + +// 库存管理主函数 +void repo_main(); #endif