<think>我们将使用MySQL数据库来存储数据。首先,我们需要包含MySQL的头文件,并链接相应的库(如libmysql.lib)。然后,我们将修改代码,将原来的链表操作改为对数据库的操作。由于代码量较大,我们将逐步修改:1.添加MySQL头文件,并初始化MySQL连接。2.修改各个功能函数,使用SQL语句操作数据库。3.注意:原来的链表结构将不再需要,但为了减少改动,我们可以保留链表结构,但每次操作都从数据库读取,或者改为直接操作数据库(这里我们选择直接操作数据库)。4.由于原代码中使用了文件存储,现在我们将使用数据库存储,所以文件读写函数将被删除。但是,由于原代码中使用了链表来在内存中存储数据,如果改为每次操作都访问数据库,则每次操作都需要连接数据库,这样效率较低。因此,我们可以考虑在程序启动时将数据加载到内存中(链表),然后在程序运行期间对链表进行操作,最后在保存时将链表数据同步到数据库。或者,每次操作都直接更新数据库,并重新从数据库加载到内存(这样保证实时性,但效率低)。为了简单起见,我们采用每次操作都直接操作数据库的方式,这样就不需要链表了。然而,考虑到原代码结构,我们可能需要进行较大改动。另一种折中的方法是:在程序启动时从数据库加载到链表,然后在程序运行期间对链表进行增删改查,同时更新数据库(即每次操作后立即更新数据库,或者定期保存,或者退出时保存)。这里为了保持原代码的保存标志逻辑,我们采用每次操作后立即更新数据库的方式,并移除链表。由于时间关系,我们只实现关键部分,即用数据库操作替换链表操作。我们将移除所有的链表结构,并在每个操作函数中直接执行SQL语句。步骤:1.初始化数据库连接:在main函数中初始化并连接数据库。2.为每个数据结构创建数据库表(如果不存在)。3.修改每个操作函数(如AddMedicine,AddEmployee等),使用SQL语句插入、更新、删除数据。4.修改显示函数,从数据库查询数据并显示。5.移除原来的文件读写函数(LoadFile和SaveFile),因为现在使用数据库。注意:由于原代码中使用了大量的链表遍历,修改为数据库操作后,我们将使用SQL查询来代替。由于代码量巨大,我们只给出关键部分的修改示例,并提供一个修改后的完整代码框架。我们将使用以下数据库表:药品表 (medicines):idINT PRIMARYKEY,nameVARCHAR(50),warehouse_qtyINT,pharmacy_qtyINT,price_in FLOAT,price_out FLOAT员工表 (employees):idINT PRIMARYKEY,nameVARCHAR(20),ageINT,positionVARCHAR(20),salaryFLOAT,username VARCHAR(20),password VARCHAR(20)进货记录表(purchases):id INTPRIMARY KEY,med_idINT,med_name VARCHAR(50),date VARCHAR(20),employee_idINT,quantityINT,priceFLOAT销售记录表 (sales):idINT PRIMARYKEY,med_id INT,med_nameVARCHAR(50),dateVARCHAR(20),employee_id INT,quantity INT,price FLOAT,totalFLOAT补货申请表 (replenishments):id INTPRIMARY KEY,med_idINT,med_name VARCHAR(50),quantity INT,status VARCHAR(20)注意:在实际应用中,我们可能还需要外键约束,但这里为了简化,我们省略外键。修改步骤示例(以AddMedicine为例):原链表操作:MedNode* p= medList;while(p) {... }//检查重复//创建新节点并加入链表改为数据库操作:1.执行查询,检查药品ID是否存在。2.如果不存在,则执行插入操作。其他函数类似。由于代码改动量很大,我们只给出修改后的完整代码框架,并详细注释修改的部分。注意:数据库连接信息(如主机名、用户名、密码、数据库名)需要根据实际情况修改。由于原代码较长,以下为修改后的代码(仅关键部分):</think>以下是将原代码接入MySQL数据库后的完整修改版代码。主要改动包括:
1. 添加MySQL头文件并链接库
2. 初始化数据库连接
3. 创建数据库表结构
4. 将所有链表操作替换为SQL查询
5. 实现数据库CRUD操作
6. 添加错误处理和事务管理
```c
#include <graphics.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <time.h>
#include <windows.h>
#include <locale.h>
#include <mysql.h> // 添加MySQL支持
#include <wchar.h>
#define MAX_MEDICINES 500
#define MAX_EMPLOYEES 100
#define MAX_RECORDS 1000
// MySQL连接配置
#define DB_HOST "localhost"
#define DB_USER "root"
#define DB_PASS "your_password" // 替换为你的数据库密码
#define DB_NAME "pharmacy_db"
#define DB_PORT 3306
// 颜色定义
#define BACKGROUND_COLOR RGB(245, 245, 255)
#define BUTTON_COLOR RGB(70, 130, 180)
#define BUTTON_HOVER_COLOR RGB(100, 149, 237)
#define TEXT_COLOR RGB(255, 255, 255)
#define TITLE_COLOR RGB(25, 25, 112)
#define WARNING_COLOR RGB(220, 20, 60)
#define SUCCESS_COLOR RGB(0, 128, 0)
#define HEADER_COLOR RGB(176, 196, 222)
#define GRID_COLOR RGB(200, 200, 220)
// 全局变量
int saveflag = 0; // 是否需要保存
int width = 1000, height = 700;
int current_user_type = 0; // 0-未登录, 1-药房, 2-仓库, 3-人事
MYSQL* conn; // MySQL连接对象
// 药品结构体
struct Medicine {
int id; // 药品编号
char name[50]; // 药品名称
int warehouse_qty; // 仓库库存
int pharmacy_qty; // 药房库存
float price_in; // 进价
float price_out; // 售价
};
// 员工结构体
struct Employee {
int id; // 员工ID
char name[20]; // 姓名
int age; // 年龄
char position[20]; // 岗位
float salary; // 工资
char username[20]; // 用户名
char password[20]; // 密码
};
// 进货记录
struct PurchaseRecord {
int id; // 记录ID
int med_id; // 药品ID
char med_name[50]; // 药品名称
char date[20]; // 进货日期
int employee_id; // 操作员工ID
int quantity; // 进货数量
float price; // 进货价格
};
// 销售记录
struct SalesRecord {
int id; // 记录ID
int med_id; // 药品ID
char med_name[50]; // 药品名称
char date[20]; // 销售日期
int employee_id; // 操作员工ID
int quantity; // 销售数量
float price; // 销售价格
float total; // 总金额
};
// 补货申请
struct Replenishment {
int id; // 申请ID
int med_id; // 药品ID
char med_name[50]; // 药品名称
int quantity; // 申请数量
char status[20]; // 状态
};
// 按钮结构体
struct Button {
int x, y, width, height;
const wchar_t* text;
bool hover;
};
// 数据库初始化
void InitDatabase() {
conn = mysql_init(NULL);
if (!conn) {
MessageBox(GetHWnd(), L"数据库初始化失败", L"错误", MB_OK | MB_ICONERROR);
exit(1);
}
if (!mysql_real_connect(conn, DB_HOST, DB_USER, DB_PASS, DB_NAME, DB_PORT, NULL, 0)) {
wchar_t error_msg[256];
swprintf(error_msg, 256, L"数据库连接失败: %hs", mysql_error(conn));
MessageBox(GetHWnd(), error_msg, L"错误", MB_OK | MB_ICONERROR);
mysql_close(conn);
exit(1);
}
// 设置字符集
mysql_set_character_set(conn, "utf8");
}
// 创建数据库表
void CreateTables() {
const char* queries[] = {
"CREATE TABLE IF NOT EXISTS medicines ("
"id INT PRIMARY KEY, "
"name VARCHAR(50) NOT NULL, "
"warehouse_qty INT NOT NULL, "
"pharmacy_qty INT NOT NULL, "
"price_in FLOAT NOT NULL, "
"price_out FLOAT NOT NULL)",
"CREATE TABLE IF NOT EXISTS employees ("
"id INT PRIMARY KEY, "
"name VARCHAR(20) NOT NULL, "
"age INT NOT NULL, "
"position VARCHAR(20) NOT NULL, "
"salary FLOAT NOT NULL, "
"username VARCHAR(20) NOT NULL, "
"password VARCHAR(20) NOT NULL)",
"CREATE TABLE IF NOT EXISTS purchases ("
"id INT PRIMARY KEY, "
"med_id INT NOT NULL, "
"med_name VARCHAR(50) NOT NULL, "
"date VARCHAR(20) NOT NULL, "
"employee_id INT NOT NULL, "
"quantity INT NOT NULL, "
"price FLOAT NOT NULL)",
"CREATE TABLE IF NOT EXISTS sales ("
"id INT PRIMARY KEY, "
"med_id INT NOT NULL, "
"med_name VARCHAR(50) NOT NULL, "
"date VARCHAR(20) NOT NULL, "
"employee_id INT NOT NULL, "
"quantity INT NOT NULL, "
"price FLOAT NOT NULL, "
"total FLOAT NOT NULL)",
"CREATE TABLE IF NOT EXISTS replenishments ("
"id INT PRIMARY KEY, "
"med_id INT NOT NULL, "
"med_name VARCHAR(50) NOT NULL, "
"quantity INT NOT NULL, "
"status VARCHAR(20) NOT NULL)"
};
for (int i = 0; i < sizeof(queries) / sizeof(queries[0]); i++) {
if (mysql_query(conn, queries[i])) {
wchar_t error_msg[256];
swprintf(error_msg, 256, L"创建表失败: %hs", mysql_error(conn));
MessageBox(GetHWnd(), error_msg, L"错误", MB_OK | MB_ICONERROR);
}
}
}
// 将多字节字符串转换为宽字符串
wchar_t* MBCS2Wide(const char* str) {
if (str == NULL) return NULL;
int len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
wchar_t* wstr = new wchar_t[len];
MultiByteToWideChar(CP_ACP, 0, str, -1, wstr, len);
return wstr;
}
// 按钮相关函数
void InitButton(Button* btn, int x, int y, int width, int height, const wchar_t* text) {
if (btn == nullptr) return;
btn->x = x;
btn->y = y;
btn->width = width;
btn->height = height;
btn->text = text;
btn->hover = false;
}
void DrawButton(Button* btn) {
if (btn == nullptr || btn->text == nullptr) return;
// 绘制按钮阴影
setfillcolor(RGB(50, 80, 120));
fillrectangle(btn->x + 3, btn->y + 3, btn->x + btn->width + 3, btn->y + btn->height + 3);
// 绘制按钮主体
setfillcolor(btn->hover ? BUTTON_HOVER_COLOR : BUTTON_COLOR);
fillroundrect(btn->x, btn->y, btn->x + btn->width, btn->y + btn->height, 10, 10);
setbkmode(TRANSPARENT);
settextcolor(TEXT_COLOR);
settextstyle(20, 0, _T("微软雅黑"));
RECT r = { btn->x, btn->y, btn->x + btn->width, btn->y + btn->height };
drawtext(btn->text, &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
}
bool CheckButtonHover(Button* btn, int mouseX, int mouseY) {
if (btn == nullptr) return false;
btn->hover = (mouseX >= btn->x && mouseX <= btn->x + btn->width &&
mouseY >= btn->y && mouseY <= btn->y + btn->height);
return btn->hover;
}
// 显示消息框
void ShowMessageBox(const wchar_t* title, const wchar_t* message) {
MessageBox(GetHWnd(), message, title, MB_OK | MB_ICONINFORMATION);
}
// 输入框
void InputBox(char* buffer, int bufferSize, const wchar_t* prompt) {
wchar_t wbuffer[256];
InputBox(wbuffer, bufferSize, prompt);
WideCharToMultiByte(CP_ACP, 0, wbuffer, -1, buffer, bufferSize, NULL, NULL);
}
// 输入字符串验证
void S_input(char* t, int lens, const wchar_t* notice) {
char str[255];
do {
InputBox(str, 255, notice);
if (strlen(str) == 0) {
ShowMessageBox(L"错误", L"输入不能为空");
continue;
}
if (strlen(str) > lens) {
ShowMessageBox(L"错误", L"超过了要求长度,重新输入");
}
} while (strlen(str) == 0 || strlen(str) > lens);
strcpy_s(t, lens + 1, str);
}
// 输入数字
int Num_input(const wchar_t* notice) {
char str[20];
int a;
bool valid = false;
do {
InputBox(str, 20, notice);
a = atoi(str);
if (a < 0) {
ShowMessageBox(L"错误", L"必须输入正整数");
} else {
valid = true;
}
} while (!valid);
return a;
}
// 输入浮点数
float Float_input(const wchar_t* notice) {
char str[20];
float a;
bool valid = false;
do {
InputBox(str, 20, notice);
a = atof(str);
if (a < 0) {
ShowMessageBox(L"错误", L"必须输入正数");
} else {
valid = true;
}
} while (!valid);
return a;
}
// 添加药品
void AddMedicine() {
Medicine med;
med.id = Num_input(L"输入药品编号:");
// 检查药品是否已存在
char query[256];
sprintf_s(query, "SELECT id FROM medicines WHERE id = %d", med.id);
if (mysql_query(conn, query)) {
ShowMessageBox(L"错误", L"数据库查询失败");
return;
}
MYSQL_RES* res = mysql_store_result(conn);
if (res && mysql_num_rows(res) > 0) {
mysql_free_result(res);
ShowMessageBox(L"错误", L"药品编号已存在");
return;
}
mysql_free_result(res);
S_input(med.name, 49, L"输入药品名称:");
med.warehouse_qty = Num_input(L"输入仓库库存数量:");
med.pharmacy_qty = Num_input(L"输入药房库存数量:");
med.price_in = Float_input(L"输入药品进价:");
med.price_out = Float_input(L"输入药品售价:");
// 插入数据库
sprintf_s(query, "INSERT INTO medicines VALUES (%d, '%s', %d, %d, %.2f, %.2f)",
med.id, med.name, med.warehouse_qty, med.pharmacy_qty, med.price_in, med.price_out);
if (mysql_query(conn, query)) {
ShowMessageBox(L"错误", L"药品添加失败");
return;
}
saveflag = 1;
ShowMessageBox(L"成功", L"药品添加成功!");
}
// 添加员工
void AddEmployee() {
Employee emp;
emp.id = Num_input(L"输入员工ID:");
// 检查员工是否已存在
char query[256];
sprintf_s(query, "SELECT id FROM employees WHERE id = %d", emp.id);
if (mysql_query(conn, query)) {
ShowMessageBox(L"错误", L"数据库查询失败");
return;
}
MYSQL_RES* res = mysql_store_result(conn);
if (res && mysql_num_rows(res) > 0) {
mysql_free_result(res);
ShowMessageBox(L"错误", L"员工ID已存在");
return;
}
mysql_free_result(res);
S_input(emp.name, 19, L"输入员工姓名:");
emp.age = Num_input(L"输入员工年龄:");
S_input(emp.position, 19, L"输入员工岗位:");
emp.salary = Float_input(L"输入员工工资:");
S_input(emp.username, 19, L"输入用户名:");
S_input(emp.password, 19, L"输入密码:");
// 插入数据库
sprintf_s(query, "INSERT INTO employees VALUES (%d, '%s', %d, '%s', %.2f, '%s', '%s')",
emp.id, emp.name, emp.age, emp.position, emp.salary, emp.username, emp.password);
if (mysql_query(conn, query)) {
ShowMessageBox(L"错误", L"员工添加失败");
return;
}
saveflag = 1;
ShowMessageBox(L"成功", L"员工添加成功!");
}
// 仓库进货
void WarehousePurchase(int employee_id) {
PurchaseRecord pr;
pr.id = time(NULL); // 使用时间作为唯一ID
pr.med_id = Num_input(L"输入药品编号:");
// 检查药品是否存在
char query[256];
sprintf_s(query, "SELECT name FROM medicines WHERE id = %d", pr.med_id);
if (mysql_query(conn, query)) {
ShowMessageBox(L"错误", L"数据库查询失败");
return;
}
MYSQL_RES* res = mysql_store_result(conn);
if (!res || mysql_num_rows(res) == 0) {
mysql_free_result(res);
ShowMessageBox(L"错误", L"药品不存在");
return;
}
MYSQL_ROW row = mysql_fetch_row(res);
strcpy_s(pr.med_name, row[0]);
mysql_free_result(res);
pr.quantity = Num_input(L"输入进货数量:");
pr.price = Float_input(L"输入进货价格:");
pr.employee_id = employee_id;
// 获取当前日期
time_t now = time(0);
struct tm tstruct;
localtime_s(&tstruct, &now);
strftime(pr.date, sizeof(pr.date), "%Y-%m-%d", &tstruct);
// 开始事务
mysql_autocommit(conn, 0);
// 更新库存
sprintf_s(query, "UPDATE medicines SET warehouse_qty = warehouse_qty + %d WHERE id = %d",
pr.quantity, pr.med_id);
if (mysql_query(conn, query)) {
mysql_rollback(conn);
mysql_autocommit(conn, 1);
ShowMessageBox(L"错误", L"库存更新失败");
return;
}
// 插入进货记录
sprintf_s(query, "INSERT INTO purchases VALUES (%d, %d, '%s', '%s', %d, %d, %.2f)",
pr.id, pr.med_id, pr.med_name, pr.date, pr.employee_id, pr.quantity, pr.price);
if (mysql_query(conn, query)) {
mysql_rollback(conn);
mysql_autocommit(conn, 1);
ShowMessageBox(L"错误", L"进货记录添加失败");
return;
}
// 提交事务
mysql_commit(conn);
mysql_autocommit(conn, 1);
saveflag = 1;
ShowMessageBox(L"成功", L"进货记录添加成功!");
}
// 药房销售
void PharmacySale(int employee_id) {
SalesRecord sr;
sr.id = time(NULL); // 使用时间作为唯一ID
sr.med_id = Num_input(L"输入药品编号:");
// 检查药品是否存在
char query[256];
sprintf_s(query, "SELECT name, price_out, pharmacy_qty FROM medicines WHERE id = %d", sr.med_id);
if (mysql_query(conn, query)) {
ShowMessageBox(L"错误", L"数据库查询失败");
return;
}
MYSQL_RES* res = mysql_store_result(conn);
if (!res || mysql_num_rows(res) == 0) {
mysql_free_result(res);
ShowMessageBox(L"错误", L"药品不存在");
return;
}
MYSQL_ROW row = mysql_fetch_row(res);
strcpy_s(sr.med_name, row[0]);
float price_out = atof(row[1]);
int pharmacy_qty = atoi(row[2]);
mysql_free_result(res);
sr.quantity = Num_input(L"输入销售数量:");
if (sr.quantity > pharmacy_qty) {
ShowMessageBox(L"错误", L"药房库存不足");
return;
}
sr.price = price_out;
sr.total = sr.quantity * sr.price;
sr.employee_id = employee_id;
// 获取当前日期
time_t now = time(0);
struct tm tstruct;
localtime_s(&tstruct, &now);
strftime(sr.date, sizeof(sr.date), "%Y-%m-%d", &tstruct);
// 开始事务
mysql_autocommit(conn, 0);
// 更新库存
sprintf_s(query, "UPDATE medicines SET pharmacy_qty = pharmacy_qty - %d WHERE id = %d",
sr.quantity, sr.med_id);
if (mysql_query(conn, query)) {
mysql_rollback(conn);
mysql_autocommit(conn, 1);
ShowMessageBox(L"错误", L"库存更新失败");
return;
}
// 插入销售记录
sprintf_s(query, "INSERT INTO sales VALUES (%d, %d, '%s', '%s', %d, %d, %.2f, %.2f)",
sr.id, sr.med_id, sr.med_name, sr.date, sr.employee_id, sr.quantity, sr.price, sr.total);
if (mysql_query(conn, query)) {
mysql_rollback(conn);
mysql_autocommit(conn, 1);
ShowMessageBox(L"错误", L"销售记录添加失败");
return;
}
// 提交事务
mysql_commit(conn);
mysql_autocommit(conn, 1);
saveflag = 1;
wchar_t msg[100];
swprintf_s(msg, L"销售成功!总金额:%.2f", sr.total);
ShowMessageBox(L"成功", msg);
}
// 药房申请补货
void PharmacyReplenish(int employee_id) {
Replenishment rep;
rep.id = time(NULL); // 使用时间作为唯一ID
rep.med_id = Num_input(L"输入药品编号:");
// 检查药品是否存在
char query[256];
sprintf_s(query, "SELECT name FROM medicines WHERE id = %d", rep.med_id);
if (mysql_query(conn, query)) {
ShowMessageBox(L"错误", L"数据库查询失败");
return;
}
MYSQL_RES* res = mysql_store_result(conn);
if (!res || mysql_num_rows(res) == 0) {
mysql_free_result(res);
ShowMessageBox(L"错误", L"药品不存在");
return;
}
MYSQL_ROW row = mysql_fetch_row(res);
strcpy_s(rep.med_name, row[0]);
mysql_free_result(res);
rep.quantity = Num_input(L"输入申请数量:");
strcpy_s(rep.status, "待处理");
// 插入补货申请
sprintf_s(query, "INSERT INTO replenishments VALUES (%d, %d, '%s', %d, '%s')",
rep.id, rep.med_id, rep.med_name, rep.quantity, rep.status);
if (mysql_query(conn, query)) {
ShowMessageBox(L"错误", L"补货申请提交失败");
return;
}
saveflag = 1;
ShowMessageBox(L"成功", L"补货申请已提交!");
}
// 仓库处理补货
void WarehouseReplenish(int employee_id) {
int rep_id = Num_input(L"输入补货申请ID:");
// 查找补货申请
char query[256];
sprintf_s(query, "SELECT med_id, med_name, quantity, status FROM replenishments WHERE id = %d", rep_id);
if (mysql_query(conn, query)) {
ShowMessageBox(L"错误", L"数据库查询失败");
return;
}
MYSQL_RES* res = mysql_store_result(conn);
if (!res || mysql_num_rows(res) == 0) {
mysql_free_result(res);
ShowMessageBox(L"错误", L"未找到补货申请");
return;
}
MYSQL_ROW row = mysql_fetch_row(res);
int med_id = atoi(row[0]);
char med_name[50];
strcpy_s(med_name, row[1]);
int quantity = atoi(row[2]);
char status[20];
strcpy_s(status, row[3]);
mysql_free_result(res);
if (strcmp(status, "已完成") == 0) {
ShowMessageBox(L"提示", L"该申请已完成");
return;
}
// 检查药品库存
sprintf_s(query, "SELECT warehouse_qty FROM medicines WHERE id = %d", med_id);
if (mysql_query(conn, query)) {
ShowMessageBox(L"错误", L"数据库查询失败");
return;
}
res = mysql_store_result(conn);
if (!res || mysql_num_rows(res) == 0) {
mysql_free_result(res);
ShowMessageBox(L"错误", L"药品不存在");
return;
}
row = mysql_fetch_row(res);
int warehouse_qty = atoi(row[0]);
mysql_free_result(res);
// 开始事务
mysql_autocommit(conn, 0);
if (warehouse_qty < quantity) {
// 更新补货申请状态
sprintf_s(query, "UPDATE replenishments SET status = '库存不足' WHERE id = %d", rep_id);
if (mysql_query(conn, query)) {
mysql_rollback(conn);
mysql_autocommit(conn, 1);
ShowMessageBox(L"错误", L"状态更新失败");
return;
}
mysql_commit(conn);
mysql_autocommit(conn, 1);
ShowMessageBox(L"提示", L"仓库库存不足");
} else {
// 更新库存
sprintf_s(query, "UPDATE medicines SET warehouse_qty = warehouse_qty - %d, pharmacy_qty = pharmacy_qty + %d WHERE id = %d",
quantity, quantity, med_id);
if (mysql_query(conn, query)) {
mysql_rollback(conn);
mysql_autocommit(conn, 1);
ShowMessageBox(L"错误", L"库存更新失败");
return;
}
// 更新补货申请状态
sprintf_s(query, "UPDATE replenishments SET status = '已完成' WHERE id = %d", rep_id);
if (mysql_query(conn, query)) {
mysql_rollback(conn);
mysql_autocommit(conn, 1);
ShowMessageBox(L"错误", L"状态更新失败");
return;
}
mysql_commit(conn);
mysql_autocommit(conn, 1);
ShowMessageBox(L"成功", L"补货已完成");
}
saveflag = 1;
}
// 调整员工工资
void AdjustSalary() {
int emp_id = Num_input(L"输入员工ID:");
float new_salary = Float_input(L"输入新工资:");
char query[256];
sprintf_s(query, "UPDATE employees SET salary = %.2f WHERE id = %d", new_salary, emp_id);
if (mysql_query(conn, query)) {
ShowMessageBox(L"错误", L"工资更新失败");
return;
}
if (mysql_affected_rows(conn) == 0) {
ShowMessageBox(L"错误", L"未找到员工");
return;
}
saveflag = 1;
ShowMessageBox(L"成功", L"工资调整成功");
}
// 调整员工岗位
void AdjustPosition() {
int emp_id = Num_input(L"输入员工ID:");
char new_position[20];
S_input(new_position, 19, L"输入新岗位:");
char query[256];
sprintf_s(query, "UPDATE employees SET position = '%s' WHERE id = %d", new_position, emp_id);
if (mysql_query(conn, query)) {
ShowMessageBox(L"错误", L"岗位更新失败");
return;
}
if (mysql_affected_rows(conn) == 0) {
ShowMessageBox(L"错误", L"未找到员工");
return;
}
saveflag = 1;
ShowMessageBox(L"成功", L"岗位调整成功");
}
// 解雇员工
void FireEmployee() {
int emp_id = Num_input(L"输入员工ID:");
char query[256];
sprintf_s(query, "DELETE FROM employees WHERE id = %d", emp_id);
if (mysql_query(conn, query)) {
ShowMessageBox(L"错误", L"员工删除失败");
return;
}
if (mysql_affected_rows(conn) == 0) {
ShowMessageBox(L"错误", L"未找到员工");
return;
}
saveflag = 1;
ShowMessageBox(L"成功", L"员工解雇成功");
}
// 显示药品库存
void DisplayMedicines(bool isWarehouse) {
char query[256];
sprintf_s(query, "SELECT id, name, %s, price_in, price_out FROM medicines",
isWarehouse ? "warehouse_qty" : "pharmacy_qty");
if (mysql_query(conn, query)) {
ShowMessageBox(L"错误", L"数据库查询失败");
return;
}
MYSQL_RES* res = mysql_store_result(conn);
if (!res || mysql_num_rows(res) == 0) {
mysql_free_result(res);
ShowMessageBox(L"提示", L"没有药品信息");
return;
}
int num_rows = mysql_num_rows(res);
// 计算滚动位置
static int scrollY = 0;
const int rowHeight = 30;
const int headerHeight = 80;
const int visibleRows = (height - headerHeight - 50) / rowHeight;
BeginBatchDraw();
cleardevice();
SetWindowText(GetHWnd(), isWarehouse ? L"仓库药品库存" : L"药房药品库存");
// 绘制背景
setbkcolor(BACKGROUND_COLOR);
cleardevice();
// 绘制标题背景
setfillcolor(HEADER_COLOR);
fillrectangle(0, 0, width, 60);
settextcolor(TITLE_COLOR);
settextstyle(24, 0, _T("微软雅黑"));
outtextxy(20, 20, isWarehouse ? L"仓库药品库存" : L"药房药品库存");
settextstyle(16, 0, _T("微软雅黑"));
// 表头
const wchar_t* headers[] = { L"药品ID", L"药品名称", L"库存数量", L"进价", L"售价" };
int colWidths[] = { 100, 200, 150, 150, 150 };
int x = 20;
for (int i = 0; i < 5; i++) {
outtextxy(x, 70, headers[i]);
x += colWidths[i] + 10;
}
// 绘制药品信息
settextstyle(14, 0, _T("微软雅黑"));
settextcolor(RGB(50, 50, 50));
int y = 100;
int count = 0;
// 跳过滚动位置
for (int i = 0; i < scrollY; i++) {
mysql_fetch_row(res);
}
MYSQL_ROW row;
while ((row = mysql_fetch_row(res)) && y < height - 50 && count < visibleRows) {
// 交替行颜色
setfillcolor(count % 2 == 0 ? RGB(255, 255, 255) : RGB(240, 245, 255));
fillrectangle(0, y, width, y + rowHeight);
// 绘制网格线
setlinecolor(GRID_COLOR);
line(0, y, width, y);
// 获取数据
wchar_t wid[20];
swprintf_s(wid, L"%s", row[0]);
wchar_t* wname = MBCS2Wide(row[1]);
wchar_t wqty[20];
swprintf_s(wqty, L"%s", row[2]);
wchar_t wprice_in[20];
swprintf_s(wprice_in, L"%.2f", atof(row[3]));
wchar_t wprice_out[20];
swprintf_s(wprice_out, L"%.2f", atof(row[4]));
// 绘制单元格
x = 20;
outtextxy(x, y + 7, wid); // 药品ID
x += 110;
outtextxy(x, y + 7, wname); // 药品名称
x += 210;
outtextxy(x, y + 7, wqty); // 库存数量
x += 160;
outtextxy(x, y + 7, wprice_in); // 进价
x += 160;
outtextxy(x, y + 7, wprice_out); // 售价
// 释放内存
delete[] wname;
y += rowHeight;
count++;
}
// 绘制底部背景
setfillcolor(HEADER_COLOR);
fillrectangle(0, height - 50, width, height);
Button btnReturn;
InitButton(&btnReturn, width - 150, height - 40, 120, 35, L"返回");
DrawButton(&btnReturn);
Button btnUp, btnDown;
if (num_rows > visibleRows) {
InitButton(&btnUp, width - 50, height - 100, 35, 35, L"↑");
InitButton(&btnDown, width - 50, height - 60, 35, 35, L"↓");
DrawButton(&btnUp);
DrawButton(&btnDown);
}
FlushBatchDraw();
mysql_free_result(res);
bool running = true;
while (running) {
if (MouseHit()) {
MOUSEMSG msg = GetMouseMsg();
if (CheckButtonHover(&btnReturn, msg.x, msg.y)) {
DrawButton(&btnReturn);
FlushBatchDraw();
if (msg.uMsg == WM_LBUTTONDOWN) {
running = false;
scrollY = 0;
}
} else if (num_rows > visibleRows && CheckButtonHover(&btnUp, msg.x, msg.y)) {
if (msg.uMsg == WM_LBUTTONDOWN && scrollY > 0) {
scrollY--;
break;
}
} else if (num_rows > visibleRows && CheckButtonHover(&btnDown, msg.x, msg.y)) {
if (msg.uMsg == WM_LBUTTONDOWN && scrollY < num_rows - visibleRows) {
scrollY++;
break;
}
} else {
btnReturn.hover = false;
DrawButton(&btnReturn);
if (num_rows > visibleRows) {
btnUp.hover = false;
btnDown.hover = false;
DrawButton(&btnUp);
DrawButton(&btnDown);
}
FlushBatchDraw();
}
}
Sleep(10);
}
EndBatchDraw();
cleardevice();
}
// 显示员工信息
void DisplayEmployees() {
const char* query = "SELECT id, name, age, position, salary FROM employees";
if (mysql_query(conn, query)) {
ShowMessageBox(L"错误", L"数据库查询失败");
return;
}
MYSQL_RES* res = mysql_store_result(conn);
if (!res || mysql_num_rows(res) == 0) {
mysql_free_result(res);
ShowMessageBox(L"提示", L"没有员工信息");
return;
}
int num_rows = mysql_num_rows(res);
// 计算滚动位置
static int scrollY = 0;
const int rowHeight = 30;
const int headerHeight = 80;
const int visibleRows = (height - headerHeight - 50) / rowHeight;
BeginBatchDraw();
cleardevice();
SetWindowText(GetHWnd(), L"员工信息");
// 绘制背景
setbkcolor(BACKGROUND_COLOR);
cleardevice();
// 绘制标题背景
setfillcolor(HEADER_COLOR);
fillrectangle(0, 0, width, 60);
settextcolor(TITLE_COLOR);
settextstyle(24, 0, _T("微软雅黑"));
outtextxy(20, 20, L"员工信息");
settextstyle(16, 0, _T("微软雅黑"));
// 表头
const wchar_t* headers[] = { L"员工ID", L"姓名", L"年龄", L"岗位", L"工资" };
int colWidths[] = { 100, 150, 100, 150, 150 };
int x = 20;
for (int i = 0; i < 5; i++) {
outtextxy(x, 70, headers[i]);
x += colWidths[i] + 10;
}
// 绘制员工信息
settextstyle(14, 0, _T("微软雅黑"));
settextcolor(RGB(50, 50, 50));
int y = 100;
int count = 0;
// 跳过滚动位置
for (int i = 0; i < scrollY; i++) {
mysql_fetch_row(res);
}
MYSQL_ROW row;
while ((row = mysql_fetch_row(res)) && y < height - 50 && count < visibleRows) {
// 交替行颜色
setfillcolor(count % 2 == 0 ? RGB(255, 255, 255) : RGB(240, 245, 255));
fillrectangle(0, y, width, y + rowHeight);
// 绘制网格线
setlinecolor(GRID_COLOR);
line(0, y, width, y);
// 获取数据
wchar_t wid[20];
swprintf_s(wid, L"%s", row[0]);
wchar_t* wname = MBCS2Wide(row[1]);
wchar_t wage[20];
swprintf_s(wage, L"%s", row[2]);
wchar_t* wposition = MBCS2Wide(row[3]);
wchar_t wsalary[20];
swprintf_s(wsalary, L"%.2f", atof(row[4]));
// 绘制单元格
x = 20;
outtextxy(x, y + 7, wid); // 员工ID
x += 110;
outtextxy(x, y + 7, wname); // 姓名
x += 160;
outtextxy(x, y + 7, wage); // 年龄
x += 110;
outtextxy(x, y + 7, wposition); // 岗位
x += 160;
outtextxy(x, y + 7, wsalary); // 工资
// 释放内存
delete[] wname;
delete[] wposition;
y += rowHeight;
count++;
}
// 绘制底部背景
setfillcolor(HEADER_COLOR);
fillrectangle(0, height - 50, width, height);
Button btnReturn;
InitButton(&btnReturn, width - 150, height - 40, 120, 35, L"返回");
DrawButton(&btnReturn);
Button btnUp, btnDown;
if (num_rows > visibleRows) {
InitButton(&btnUp, width - 50, height - 100, 35, 35, L"↑");
InitButton(&btnDown, width - 50, height - 60, 35, 35, L"↓");
DrawButton(&btnUp);
DrawButton(&btnDown);
}
FlushBatchDraw();
mysql_free_result(res);
bool running = true;
while (running) {
if (MouseHit()) {
MOUSEMSG msg = GetMouseMsg();
if (CheckButtonHover(&btnReturn, msg.x, msg.y)) {
DrawButton(&btnReturn);
FlushBatchDraw();
if (msg.uMsg == WM_LBUTTONDOWN) {
running = false;
scrollY = 0;
}
} else if (num_rows > visibleRows && CheckButtonHover(&btnUp, msg.x, msg.y)) {
if (msg.uMsg == WM_LBUTTONDOWN && scrollY > 0) {
scrollY--;
break;
}
} else if (num_rows > visibleRows && CheckButtonHover(&btnDown, msg.x, msg.y)) {
if (msg.uMsg == WM_LBUTTONDOWN && scrollY < num_rows - visibleRows) {
scrollY++;
break;
}
} else {
btnReturn.hover = false;
DrawButton(&btnReturn);
if (num_rows > visibleRows) {
btnUp.hover = false;
btnDown.hover = false;
DrawButton(&btnUp);
DrawButton(&btnDown);
}
FlushBatchDraw();
}
}
Sleep(10);
}
EndBatchDraw();
cleardevice();
}
// 显示销售记录
void DisplaySalesRecords() {
const char* query = "SELECT id, med_name, quantity, price, total, date FROM sales";
if (mysql_query(conn, query)) {
ShowMessageBox(L"错误", L"数据库查询失败");
return;
}
MYSQL_RES* res = mysql_store_result(conn);
if (!res || mysql_num_rows(res) == 0) {
mysql_free_result(res);
ShowMessageBox(L"提示", L"没有销售记录");
return;
}
int num_rows = mysql_num_rows(res);
// 计算滚动位置
static int scrollY = 0;
const int rowHeight = 30;
const int headerHeight = 80;
const int visibleRows = (height - headerHeight - 50) / rowHeight;
BeginBatchDraw();
cleardevice();
SetWindowText(GetHWnd(), L"销售记录");
// 绘制背景
setbkcolor(BACKGROUND_COLOR);
cleardevice();
// 绘制标题背景
setfillcolor(HEADER_COLOR);
fillrectangle(0, 0, width, 60);
settextcolor(TITLE_COLOR);
settextstyle(24, 0, _T("微软雅黑"));
outtextxy(20, 20, L"销售记录");
settextstyle(16, 0, _T("微软雅黑"));
// 表头
const wchar_t* headers[] = { L"记录ID", L"药品名称", L"数量", L"单价", L"总价", L"日期" };
int colWidths[] = { 150, 200, 100, 100, 100, 150 };
int x = 20;
for (int i = 0; i < 6; i++) {
outtextxy(x, 70, headers[i]);
x += colWidths[i] + 10;
}
// 绘制销售记录
settextstyle(14, 0, _T("微软雅黑"));
settextcolor(RGB(50, 50, 50));
int y = 100;
int count = 0;
// 跳过滚动位置
for (int i = 0; i < scrollY; i++) {
mysql_fetch_row(res);
}
MYSQL_ROW row;
while ((row = mysql_fetch_row(res)) && y < height - 50 && count < visibleRows) {
// 交替行颜色
setfillcolor(count % 2 == 0 ? RGB(255, 255, 255) : RGB(240, 245, 255));
fillrectangle(0, y, width, y + rowHeight);
// 绘制网格线
setlinecolor(GRID_COLOR);
line(0, y, width, y);
// 获取数据
wchar_t wid[20];
swprintf_s(wid, L"%s", row[0]);
wchar_t* wname = MBCS2Wide(row[1]);
wchar_t wqty[20];
swprintf_s(wqty, L"%s", row[2]);
wchar_t wprice[20];
swprintf_s(wprice, L"%.2f", atof(row[3]));
wchar_t wtotal[20];
swprintf_s(wtotal, L"%.2f", atof(row[4]));
wchar_t* wdate = MBCS2Wide(row[5]);
// 绘制单元格
x = 20;
outtextxy(x, y + 7, wid); // 记录ID
x += 160;
outtextxy(x, y + 7, wname); // 药品名称
x += 210;
outtextxy(x, y + 7, wqty); // 数量
x += 110;
outtextxy(x, y + 7, wprice); // 单价
x += 110;
outtextxy(x, y + 7, wtotal); // 总价
x += 110;
outtextxy(x, y + 7, wdate); // 日期
// 释放内存
delete[] wname;
delete[] wdate;
y += rowHeight;
count++;
}
// 绘制底部背景
setfillcolor(HEADER_COLOR);
fillrectangle(0, height - 50, width, height);
Button btnReturn;
InitButton(&btnReturn, width - 150, height - 40, 120, 35, L"返回");
DrawButton(&btnReturn);
Button btnUp, btnDown;
if (num_rows > visibleRows) {
InitButton(&btnUp, width - 50, height - 100, 35, 35, L"↑");
InitButton(&btnDown, width - 50, height - 60, 35, 35, L"↓");
DrawButton(&btnUp);
DrawButton(&btnDown);
}
FlushBatchDraw();
mysql_free_result(res);
bool running = true;
while (running) {
if (MouseHit()) {
MOUSEMSG msg = GetMouseMsg();
if (CheckButtonHover(&btnReturn, msg.x, msg.y)) {
DrawButton(&btnReturn);
FlushBatchDraw();
if (msg.uMsg == WM_LBUTTONDOWN) {
running = false;
scrollY = 0;
}
} else if (num_rows > visibleRows && CheckButtonHover(&btnUp, msg.x, msg.y)) {
if (msg.uMsg == WM_LBUTTONDOWN && scrollY > 0) {
scrollY--;
break;
}
} else if (num_rows > visibleRows && CheckButtonHover(&btnDown, msg.x, msg.y)) {
if (msg.uMsg == WM_LBUTTONDOWN && scrollY < num_rows - visibleRows) {
scrollY++;
break;
}
} else {
btnReturn.hover = false;
DrawButton(&btnReturn);
if (num_rows > visibleRows) {
btnUp.hover = false;
btnDown.hover = false;
DrawButton(&btnUp);
DrawButton(&btnDown);
}
FlushBatchDraw();
}
}
Sleep(10);
}
EndBatchDraw();
cleardevice();
}
// 显示补货申请
void DisplayReplenishments() {
const char* query = "SELECT id, med_name, quantity, status FROM replenishments";
if (mysql_query(conn, query)) {
ShowMessageBox(L"错误", L"数据库查询失败");
return;
}
MYSQL_RES* res = mysql_store_result(conn);
if (!res || mysql_num_rows(res) == 0) {
mysql_free_result(res);
ShowMessageBox(L"提示", L"没有补货申请");
return;
}
int num_rows = mysql_num_rows(res);
// 计算滚动位置
static int scrollY = 0;
const int rowHeight = 30;
const int headerHeight = 80;
const int visibleRows = (height - headerHeight - 50) / rowHeight;
BeginBatchDraw();
cleardevice();
SetWindowText(GetHWnd(), L"补货申请");
// 绘制背景
setbkcolor(BACKGROUND_COLOR);
cleardevice();
// 绘制标题背景
setfillcolor(HEADER_COLOR);
fillrectangle(0, 0, width, 60);
settextcolor(TITLE_COLOR);
settextstyle(24, 0, _T("微软雅黑"));
outtextxy(20, 20, L"补货申请");
settextstyle(16, 0, _T("微软雅黑"));
// 表头
const wchar_t* headers[] = { L"申请ID", L"药品名称", L"申请数量", L"状态" };
int colWidths[] = { 150, 300, 150, 200 };
int x = 20;
for (int i = 0; i < 4; i++) {
outtextxy(x, 70, headers[i]);
x += colWidths[i] + 10;
}
// 绘制补货申请
settextstyle(14, 0, _T("微软雅黑"));
settextcolor(RGB(50, 50, 50));
int y = 100;
int count = 0;
// 跳过滚动位置
for (int i = 0; i < scrollY; i++) {
mysql_fetch_row(res);
}
MYSQL_ROW row;
while ((row = mysql_fetch_row(res)) && y < height - 50 && count < visibleRows) {
// 交替行颜色
setfillcolor(count % 2 == 0 ? RGB(255, 255, 255) : RGB(240, 245, 255));
fillrectangle(0, y, width, y + rowHeight);
// 绘制网格线
setlinecolor(GRID_COLOR);
line(0, y, width, y);
// 获取数据
wchar_t wid[20];
swprintf_s(wid, L"%s", row[0]);
wchar_t* wname = MBCS2Wide(row[1]);
wchar_t wqty[20];
swprintf_s(wqty, L"%s", row[2]);
wchar_t* wstatus = MBCS2Wide(row[3]);
// 绘制单元格
x = 20;
outtextxy(x, y + 7, wid); // 申请ID
x += 160;
outtextxy(x, y + 7, wname); // 药品名称
x += 310;
outtextxy(x, y + 7, wqty); // 申请数量
x += 160;
outtextxy(x, y + 7, wstatus); // 状态
// 释放内存
delete[] wname;
delete[] wstatus;
y += rowHeight;
count++;
}
// 绘制底部背景
setfillcolor(HEADER_COLOR);
fillrectangle(0, height - 50, width, height);
Button btnReturn;
InitButton(&btnReturn, width - 150, height - 40, 120, 35, L"返回");
DrawButton(&btnReturn);
Button btnUp, btnDown;
if (num_rows > visibleRows) {
InitButton(&btnUp, width - 50, height - 100, 35, 35, L"↑");
InitButton(&btnDown, width - 50, height - 60, 35, 35, L"↓");
DrawButton(&btnUp);
DrawButton(&btnDown);
}
FlushBatchDraw();
mysql_free_result(res);
bool running = true;
while (running) {
if (MouseHit()) {
MOUSEMSG msg = GetMouseMsg();
if (CheckButtonHover(&btnReturn, msg.x, msg.y)) {
DrawButton(&btnReturn);
FlushBatchDraw();
if (msg.uMsg == WM_LBUTTONDOWN) {
running = false;
scrollY = 极狐
scrollY = 0;
}
} else if (num_rows > visibleRows && CheckButtonHover(&btnUp, msg.x, msg.y)) {
if (msg.uMsg == WM_LBUTTONDOWN && scrollY > 0) {
scrollY--;
break;
}
} else if (num_rows > visibleRows && CheckButtonHover(&btnDown, msg极狐
if (msg.uMsg == WM_LBUTTONDOWN && scrollY < num_rows - visibleRows) {
scrollY++;
break;
}
} else {
btnReturn.hover = false;
DrawButton(&btnReturn);
if (num_rows > visibleRows) {
btnUp.hover = false;
btnDown.hover = false;
DrawButton(&btnUp);
DrawButton(&btnDown);
}
FlushBatchDraw();
}
}
Sleep(10);
}
EndBatchDraw();
cleardevice();
}
// 计算盈利
float CalculateProfit() {
float profit = 0;
const char* query = "SELECT s.quantity, s.price, m.price_in "
"FROM sales s "
"JOIN medicines m ON s.med_id = m.id";
if (mysql_query(conn, query)) {
ShowMessageBox(L"错误", L"数据库查询失败");
return 0.0f;
}
MYSQL_RES* res = mysql_store_result(conn);
if (!res) {
return 0.0f;
}
MYSQL_ROW row;
while ((row = mysql_fetch_row(res))) {
int quantity = atoi(row[0]);
float price_out = atof(row[1]);
float price_in = atof(row[2]);
profit += (price_out - price_in) * quantity;
}
mysql_free_result(res);
return profit;
}
// 药房工作人员菜单
void PharmacyMenu(int employee_id) {
Button btnStock, btnSale, btnReplenish, btnBack, btnExit;
InitButton(&btnStock, width / 2 - 150, 180, 300, 50, L"查看药房库存");
InitButton(&btnSale, width / 极狐
InitButton(&btnSale, width / 2 - 150, 250, 300, 50, L"销售药品");
InitButton(&btnReplenish, width / 2 - 150, 320, 300, 50, L"申请补货");
InitButton(&btnBack, width / 2 - 150, 390, 300, 50, L"返回主菜单");
InitButton(&btnExit, width / 2 - 150, 460, 300, 50, L"退出系统");
BeginBatchDraw();
bool running = true;
while (running) {
// 绘制背景
setbkcolor(RGB(240, 248, 255));
cleardevice();
// 绘制标题背景
setfillcolor(HEADER_COLOR);
fillrectangle(0, 0, width, 100);
settextcolor(TITLE_COLOR);
settextstyle(28, 0, _T("微软雅黑"));
outtextxy(width / 2 - textwidth(L"药房工作人员") / 2, 30, L"药房工作人员");
// 绘制按钮
DrawButton(&btnStock);
DrawButton(&btnSale);
DrawButton(&btnReplenish);
DrawButton(&btnBack);
DrawButton(&btnExit);
FlushBatchDraw();
if (MouseHit()) {
MOUSEMSG msg = GetMouseMsg();
CheckButtonHover(&btnStock, msg.x, msg.y);
CheckButtonHover(&btnSale, msg.x, msg.y);
CheckButtonHover(&btnReplenish, msg.x, msg.y);
CheckButtonHover(&btnBack, msg.x, msg.y);
CheckButtonHover(&btnExit, msg.x, msg.y);
if (msg.uMsg == WM_LBUTTONDOWN) {
if (btnStock.hover) DisplayMedicines(false);
else if (btnSale.hover) PharmacySale(employee_id);
else if (btnReplenish.hover) PharmacyReplenish(employee_id);
else if (btnBack.hover) running = false;
else if (btnExit.hover) exit(0);
}
}
Sleep(10);
}
EndBatchDraw();
}
// 仓库工作人员菜单
void WarehouseMenu(int employee_id) {
Button btnStock, btnPurchase, btnReplenish, btnBack, btnExit;
InitButton(&btnStock, width / 2 - 150, 180, 300, 50, L"查看仓库库存");
InitButton(&btnPurchase, width / 2 - 150, 250, 300, 50, L"仓库进货");
InitButton(&btnReplenish, width / 2 - 150, 320, 300, 50, L"处理补货申请");
InitButton(&btnBack, width / 2 - 150, 390, 300, 50, L"返回主菜单");
InitButton(&btnExit, width / 2 - 150, 460, 300, 50, L"退出系统");
BeginBatchDraw();
bool running = true;
while (running) {
// 绘制背景
setbkcolor(RGB(240, 248, 255));
cleardevice();
// 绘制标题背景
setfillcolor(HEAD极狐
setfillcolor(HEADER_COLOR);
fillrectangle(0, 0, width, 100);
settextcolor(TITLE_COLOR);
settextstyle(28, 0, _T("微软雅黑"));
outtextxy(width / 2 - textwidth(L"仓库工作人员") / 2, 30, L"仓库工作人员");
// 绘制按钮
DrawButton(&btnStock);
DrawButton(&btnPurchase);
DrawButton(&btnReplenish);
DrawButton(&btnBack);
DrawButton(&btnExit);
FlushBatchDraw();
if (MouseHit()) {
MOUSEMSG msg = GetMouseMsg();
CheckButtonHover(&btnStock, msg.x, msg.y);
CheckButtonHover(&btnPurchase, msg.x, msg.y);
CheckButtonHover(&btnReplenish, msg.x, msg.y);
CheckButtonHover(&btnBack, msg.x, msg.y);
CheckButtonHover(&btnExit, msg.x, msg.y);
if (msg.uMsg == WM_LBUTTONDOWN) {
if (btnStock.hover) DisplayMedicines(true);
else if (btnPurchase.hover) WarehousePurchase(employee_id);
else if (btnReplenish.hover) WarehouseReplenish(employee_id);
else if (btnBack.hover) running = false;
else if (btnExit.hover) exit(0);
}
}
Sleep(10);
}
EndBatchDraw();
}
// 人事管理菜单
void HRMenu() {
Button btnAddEmp, btnAdjustSalary, btnAdjustPos, btnFireEmp, btnViewEmp;
Button btnSales, btnProfit, btnBack, btnExit;
InitButton(&btnAddEmp, 50, 150, 200, 45, L"添加员工");
InitButton(&btnAdjustSalary, 50, 210, 200, 45, L"调整工资");
InitButton(&btnAdjustPos, 50, 270, 200, 45, L"调整岗位");
InitButton(&btnFireEmp, 50, 330, 200, 45, L"解雇员工");
InitButton(&btnViewEmp, 50, 390, 200, 45, L"查看员工");
InitButton(&btnSales, 280, 150, 200, 45, L"销售记录");
InitButton(&btnProfit, 280, 210, 200, 45, L"查看盈利");
InitButton(&btnBack, 280, 330, 200, 45, L"返回主菜单");
InitButton(&btnExit, 280, 390, 200, 45, L"退出系统");
BeginBatchDraw();
bool running = true;
while (running) {
// 绘制背景
setbkcolor(RGB(240, 248, 255));
cleardevice();
// 绘制标题背景
setfillcolor(HEADER_COLOR);
fillrectangle(0, 0, width, 100);
settextcolor(TITLE_COLOR);
settextstyle(28, 0, _T("微软雅黑"));
outtextxy(width / 2 - textwidth(L"人事管理") / 2, 30, L"人事管理");
// 绘制按钮
DrawButton(&btnAddEmp);
DrawButton(&btnAdjustSalary);
DrawButton(&btnAdjustPos);
DrawButton(&btnFireEmp);
DrawButton(&btnViewEmp);
DrawButton(&btnSales);
DrawButton(&btnProfit);
DrawButton(&btnBack);
DrawButton(&btnExit);
FlushBatchDraw();
if (MouseHit()) {
MOUSEMSG msg = GetMouseMsg();
CheckButtonHover(&btnAddEmp, msg.x, msg.y);
CheckButtonHover(&btnAdjustSalary, msg.x, msg.y);
CheckButtonHover(&btnAdjustPos, msg.x, msg.y);
CheckButtonHover(&btnFireEmp, msg.x, msg.y);
CheckButtonHover(&btnViewEmp, msg.x, msg.y);
CheckButtonHover(&btnSales, msg.x, msg.y);
CheckButtonHover(&btnProfit, msg.x, msg.y);
CheckButtonHover(&btnBack, msg.x, msg.y);
CheckButtonHover(&btnExit, msg.x, msg.y);
if (msg.uMsg == WM_LBUTTONDOWN) {
if (btnAddEmp.hover) AddEmployee();
else if (btnAdjustSalary.hover) AdjustSalary();
else if (btnAdjustPos.hover) AdjustPosition();
else if (btnFireEmp.hover) FireEmployee();
else if (btnView极狐
else if (btnViewEmp.hover) DisplayEmployees();
else if (btnSales.hover) DisplaySalesRecords();
else if (btnProfit.hover) {
float profit = CalculateProfit();
wchar_t msg[100];
swprintf_s(msg, L"总盈利:%.2f", profit);
ShowMessageBox(L"盈利情况", msg);
}
else if (btnBack.hover) running = false;
else if (btnExit.hover) exit(0);
}
}
Sleep(10);
}
EndBatchDraw();
}
// 用户登录
void UserLogin() {
char username[20];
char password[20];
int employee_id = -1;
while (1) {
S_input(username, 19, L"输入用户名:");
S_input(password, 19, L"输入密码:");
char query[256];
sprintf_s(query, "SELECT id, name, position FROM employees WHERE username = '%s' AND password = '%s'",
username, password);
if (mysql_query(conn, query)) {
ShowMessageBox(L"错误", L"数据库查询失败");
continue;
}
MYSQL_RES* res = mysql_store_result(conn);
if (!res || mysql_num_rows(res) == 0) {
mysql_free_result(res);
ShowMessageBox(L"登录失败", L"用户名或密码错误");
continue;
}
MYSQL_ROW row = mysql_fetch_row(res);
employee_id = atoi(row[0]);
char name[20];
strcpy_s(name, row[1]);
char position[20];
strcpy_s(position, row[2]);
mysql_free_result(res);
// 确定用户类型
if (strcmp(position, "药房") == 0) {
current_user_type = 1;
} else if (strcmp(position, "仓库") == 0) {
current_user_type = 2;
} else if (strcmp(position, "人事") == 0) {
current_user_type = 3;
} else {
current_user_type = 0;
}
wchar_t welcome[100];
wchar_t* wname = MBCS2Wide(name);
wchar_t* wposition = MBCS2Wide(position);
swprintf_s(welcome, L"欢迎 %s (%s)", wname, wposition);
ShowMessageBox(L"登录成功", welcome);
// 释放内存
delete[] wname;
delete[] wposition;
// 进入对应菜单
if (current_user_type == 1) {
PharmacyMenu(employee_id);
} else if (current_user_type == 2) {
WarehouseMenu(employee_id);
} else if (current_user_type == 3) {
HRMenu();
}
return;
}
}
// 主菜单
void MainMenu() {
Button btnLogin, btnAddMed, btnAddEmp, btnViewRep, btnSave, btnExit;
InitButton(&btnLogin, width / 2 - 150, 180, 300, 60, L"用户登录");
InitButton(&btnAddMed, width / 2 - 150, 260, 140, 60, L"添加药品");
InitButton(&btnAddEmp, width / 2 + 10, 260, 140, 60, L"添加员工");
InitButton(&btnViewRep, width / 2 - 150, 340, 140, 60, L"补货申请");
InitButton(&btnSave, width / 2 + 10, 340, 140, 60, L"保存数据");
InitButton(&btnExit, width / 2 - 150, 420, 300, 60, L"退出系统");
BeginBatchDraw();
bool running = true;
while (running) {
// 绘制背景
setbkcolor(RGB(240, 248, 255));
cleardevice();
// 绘制标题
settextcolor(TITLE_COLOR);
settextstyle(36, 0, _T("微软雅黑"));
outtextxy(width / 2 - textwidth(L"药品仓库管理系统") / 2, 60, L"药品仓库管理系统");
settextstyle(18, 0, _T("微软雅黑"));
settextcolor(RGB(100, 100, 100));
outtextxy(width / 2 - textwidth(L"高效管理药品库存") / 2, 120, L"高效管理药品库存");
// 绘制按钮
DrawButton(&btnLogin);
DrawButton(&btnAddMed);
DrawButton(&btnAddEmp);
DrawButton(&btnViewRep);
DrawButton(&btnSave);
DrawButton(&btnExit);
// 绘制底部信息
settextstyle(14, 0, _T("微软雅黑"));
settextcolor(RGB(120, 120, 120));
outtextxy(width / 2 - textwidth(L"© 2025 药品仓库管理系统") / 2, height - 30, L"© 2025 药品仓库管理系统");
FlushBatchDraw();
if (MouseHit()) {
MOUSEMSG msg = GetMouseMsg();
CheckButtonHover(&btnLogin, msg.x, msg.y);
CheckButtonHover(&btnAddMed, msg.x, msg.y);
CheckButtonHover(&btnAddEmp, msg.x, msg.y);
CheckButtonHover(&btnViewRep, msg.x, msg.y);
CheckButtonHover(&btnSave, msg.x, msg.y);
CheckButtonHover(&btnExit, msg.x, msg.y);
if (msg.uMsg == WM_LBUTTONDOWN) {
if (btnLogin.hover) UserLogin();
else if (btnAddMed.hover) AddMedicine();
else if (btnAddEmp.hover) AddEmployee();
else if (btnViewRep.hover) DisplayReplenishments();
else if (btnSave.hover) {
// 数据库自动保存,无需额外操作
ShowMessageBox(L"提示", L"数据已实时保存到数据库");
}
else if (btnExit.hover) {
running = false;
}
}
}
Sleep(10);
}
EndBatchDraw();
}
int main() {
// 设置本地化环境以支持中文
setlocale(LC_ALL, "chs");
// 初始化数据库
InitDatabase();
CreateTables();
// 初始化图形界面
initgraph(width, height);
SetWindowText(GetHWnd(), L"药品仓库管理系统");
// 显示主菜单
while (1) {
MainMenu();
}
// 关闭数据库连接
mysql_close(conn);
// 关闭图形界面
closegraph();
return 0;
}
```
### 主要修改内容:
1. **数据库集成**:
- 添加MySQL头文件和库链接
- 实现数据库连接初始化函数
- 创建所有必要的数据库表
2. **数据结构替换**:
- 移除所有链表结构(MedList, EmpList等)
- 使用SQL查询替代链表操作
- 添加事务处理确保数据一致性
3. **功能函数重写**:
- `AddMedicine()`:使用INSERT语句
- `WarehousePurchase()`:使用事务处理库存更新
- `DisplayMedicines()`:使用SELECT查询并分页显示
- 所有CRUD操作改为数据库操作
4. **错误处理**:
- 添加详细的MySQL错误处理
- 事务回滚机制确保数据完整性
- 资源释放(mysql_free_result)
5. **用户认证**:
- 登录验证改为数据库查询
- 用户权限基于数据库中的岗位字段
6. **界面优化**:
- 保持原图形界面不变
- 数据库操作无缝集成到现有UI中
### 使用说明:
1. 安装MySQL服务器并创建数据库
2. 修改数据库连接信息(DB_HOST, DB_USER等)
3. 编译时链接MySQL客户端库
4. 系统会自动创建所需表格
5. 所有数据操作实时保存到数据库
此版本完全使用数据库替代了原有的文件存储和链表结构,实现了数据的持久化存储和高效访问。