项目描述:模拟实现超市后台管理系统,对员工以及商品进行管理
实现环境:Windows-10 VS2013 MySQL-5.7.27 Duilib 库
涉及技术:继承 多态 数据库 STL
系统流程图:
项目代码维护于github上:https://github.com/luchunabf/item
安装MySQL(5.7.27) Windows版本,然后封装数据库
本项目设计到以下几种表格:
create table Employee(
id int, -- 员工编号
name varchar(20), -- 员工名字
gender varchar(3), -- 员工性别
birthday Date, -- 生日
password varchar(20), -- 员工密码
position varchar(10), -- 员工职位
telphone varchar(11), -- 联系方式
salary double(9,2) -- 联系方式
);
create table Goods(
GoodsID int, -- 商品编号
GoodsName varchar(20), -- 商品名称
GoodsType varchar(20), -- 商品类别:水果、烟酒、日常用品、副食等
ProductDate DATE, -- 商品生产日期
DeadDate DATE, -- 商品过期日期
Price double(9,2), -- 商品价格
Unit varchar(3), -- 计量单位
Inventory int, -- 库存量:商品剩余数量
AlarmValye int -- 报警值:低于该值时,应提醒管理员进货
);
封装数据库的基本的增删改查操作, 在头文件中声明,源文件中定义
MySQL.h
#pragma once
#include
#include
#include
#include
#include
using namespace std;
#pragma comment(lib, "libmysql.lib")
class MySQL
{
public:
MySQL();
bool ConnectMySql(const char* host, // 主机名称
const char* user, // 用户名
const char* passward, // 密码
const char* dbName, // 数据库名
int port = 3306); // 端口号:默认为3306
~MySQL();
bool Insert(const string& strSQL);
bool Delete(const string& strSQL);
bool Update(const string& strSQL);
size_t GetCount(const string& strSQL);
vector<vector<string>> Select(const string& strSQL);
// 切换数据库
bool SelectDB(const string& daName);
private:
MYSQL* _mySql; // mysql连接的实例对象
std::string _dbName;
vector<string> _tables;
};
MySQL.cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include "MySQL.h"
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "libmysql.lib")
MySQL::MySQL()
{
// 初始化mySql
_mySql = mysql_init(nullptr);
}
bool MySQL::ConnectMySql(const char* host, const char* user, const char* passward,
const char* dbName, int port)
{
// 连接mySql数据库
if (!mysql_real_connect(_mySql, host, user, passward, dbName, port, NULL, 0))
{
cout << "数据库连接失败" << endl;
return false;
}
/*
c++连接mysql时,比如查询语句中含有中文,或者得到结果中含有中文,经常出现编译出错或乱码问
题。
VS编译器默认使用gbk编码。
如果将mysql设置为utf-8编码,则需要先将c++中的各种中文字符串转为utf-8编码输入mysql,得到
的结果为utf-8编码,需要转为gbk才能正常显示。转来转去很麻烦。
*/
mysql_query(_mySql, "set names 'gbk'");
return true;
}
bool MySQL::SelectDB(const string& dbName)
{
if (mysql_select_db(_mySql, dbName.c_str()))
{
return false;
}
return true;
}
bool MySQL::Insert(const string& strSql)
{
// 执行sql语句
if (mysql_query(_mySql, strSql.c_str()))
{
cout << mysql_error(_mySql) << endl;
return false;
}
return true;
}
bool MySQL::Update(const string& strSQL)
{
// 执行sql语句
if (mysql_query(_mySql, strSQL.c_str()))
{
cout << mysql_error(_mySql) << endl;
return false;
}
return true;
}
vector<vector<string>> MySQL::Select(const string& sql)
{
vector<vector<string>> vRet;
// 指定指定SQL语句
if (mysql_query(_mySql, sql.c_str()))
{
string vsRet(mysql_error(_mySql));
return vRet;
}
// 检索完整的数据集到客户端
MYSQL_RES *res = mysql_store_result(_mySql);
if (res == NULL)
{
return vRet;
}
// 用来保存结果集中行的信息
MYSQL_ROW rows;
// 结果集中总共有多少行数据
int num_fields = mysql_num_fields(res);
while (rows = mysql_fetch_row(res))
{
int i = 0;
vector<string> vItem;
vItem.resize(num_fields);
for (i = 0; i < num_fields; i++)
{
vItem[i] = rows[i];
}
vRet.push_back(vItem);
}
const char* str = mysql_error(_mySql);
mysql_free_result(res);//释放记录集
return vRet;
}
size_t MySQL::GetCount(const string& strSQL)
{
// 指定指定SQL语句
if (mysql_query(_mySql, strSQL.c_str()))
{
return 0;
}
// 检索完整的数据集到客户端
MYSQL_RES *res = mysql_store_result(_mySql);
if (res == NULL)
{
return 0;
}
return mysql_num_fields(res);
}
bool MySQL::Delete(const string& strSQL)
{
// 执行sql语句
if (mysql_query(_mySql, strSQL.c_str()))
{
cout << mysql_error(_mySql) << endl;
return false;
}
return true;
}
MySQL::~MySQL()
{
mysql_close(_mySql);
}
class CDuiFrameWnd : public WindowImplBase
{
public:
virtual LPCTSTR GetWindowClassName() const { return _T("DUIMainFrame"); }
virtual CDuiString GetSkinFile() { return _T("Cashier.xml"); }
virtual CDuiString GetSkinFolder() { return _T(""); }
virtual void Notify(TNotifyUI& msg)
{
if (msg.sType == _T("click"))
{
MessageBox(m_hWnd, _T("Hello World"), _T("DuiFramWnd"), IDOK);
}
}
};
可通过该界面布局器,快速方便的对界面进行布局,完成后保存成XML即可,Duilib程序就可以解析:
利用DuiDesigner绘制好xml文件并保存于debug文件目录下
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<Window size="679,492">
<VerticalLayout width="679" height="492" bkimage="登录背景.png">
<Button name="BTN_CLOSE" float="true" pos="612,11,0,0" width="48" height="31" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" normalimage="frame_btn_close_normal.bmp" hotimage="frame_btn_close_hot.bmp" pushedimage="frame_btn_close_down.bmp" />
<Button name="BTN_MIN" float="true" pos="556,11,0,0" width="48" height="31" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" normalimage="min1.png" hotimage="min2.png" pushedimage="min3.png" />
<Label name="ACCOUNT" float="true" pos="185,166,0,0" width="62" height="40" bkimage="登录账户.png" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" />
<Label name="PASSWORD" float="true" pos="185,226,0,0" width="62" height="40" bkimage="密码.png" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" />
<Edit name="EDIT_USER_NAME" float="true" pos="266,169,0,0" width="196" height="32" bkcolor="#FFFFFFFF" textpadding="4,3,4,3" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" />
<Edit name="EDIT_USER_PASSWORD" float="true" pos="266,228,0,0" width="196" height="32" bkcolor="#FFFFFFFF" textpadding="4,3,4,3" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" />
<Button name="BTN_LOGIN" text="登 录" float="true" pos="304,288,0,0" width="87" height="33" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" />
</VerticalLayout>
</Window>
利用DuiDesigner绘制好xml文件并保存于debug文件目录下
对应的管理员操作页面xml文件内容如下:
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<Window size="675,495">
<VerticalLayout float="true" pos="0,0,0,0" width="675" height="495" bkcolor="#FFA0A0FF">
<HorizontalLayout float="true" pos="2,2,0,0" width="675" height="33" bkcolor="#FF00FFFF">
<Button name="BTN_CLOSE" float="true" pos="603,6,0,0" width="56" height="22" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" normalimage="frame_btn_close_normal.bmp" hotimage="frame_btn_close_hot.bmp" pushedimage="frame_btn_close_down.bmp" />
<Button name="BTN_MIN" float="true" pos="528,6,0,0" width="56" height="22" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" normalimage="min1.png" hotimage="min2.png" pushedimage="min3.png" />
</HorizontalLayout>
<HorizontalLayout float="true" pos="1,33,0,0" width="675" height="31">
<Option name="OPTION_EMPLOYEE" text="员工操作" float="true" pos="16,5,0,0" width="59" height="19" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" normalimage="button_nor.bmp" hotimage="button_over.bmp" pushedimage="button_down.bmp" group="true" selected="true" />
<Option name="OPTION_GOODS" text="商品操作" float="true" pos="89,5,0,0" width="59" height="19" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" normalimage="button_nor.bmp" hotimage="button_over.bmp" pushedimage="button_down.bmp" group="true" />
</HorizontalLayout>
<TabLayout name="tablayout" float="true" pos="6,68,0,0" width="663" height="423">
<VerticalLayout float="true" pos="8,7,0,0" width="647" height="404">
<Edit name="username" float="true" pos="15,10,0,0" width="68" height="27" bkcolor="#FFFFFFFF" textpadding="4,3,4,3" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" />
<Combo name="usergender" float="true" pos="95,13,0,0" width="71" height="22" itemtextcolor="#FF000000" itemselectedtextcolor="#FF000000" itemselectedbkcolor="#FFC1E3FF" itemhottextcolor="#FF000000" itemhotbkcolor="#FFE9F5FF" itemdisabledtextcolor="#FFCCCCCC" itemdisabledbkcolor="#FFFFFFFF" normalimage="Combo_nor.bmp" hotimage="Combo_over.bmp" pushedimage="Combo_over.bmp" dropboxsize="0,150">
<ListLabelElement text="男"/>
<ListLabelElement text="女"/>
</Combo>
<Edit name="userbirthday" float="true" pos="191,10,0,0" width="68" height="27" bkcolor="#FFFFFFFF" textpadding="4,3,4,3" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" />
<Combo name="position" float="true" pos="279,13,0,0" width="71" height="22" itemtextcolor="#FF000000" itemselectedtextcolor="#FF000000" itemselectedbkcolor="#FFC1E3FF" itemhottextcolor="#FF000000" itemhotbkcolor="#FFE9F5FF" itemdisabledtextcolor="#FFCCCCCC" itemdisabledbkcolor="#FFFFFFFF" normalimage="Combo_nor.bmp" hotimage="Combo_over.bmp" pushedimage="Combo_over.bmp" dropboxsize="0,150">
<ListLabelElement text="管理员"/>
<ListLabelElement text="售货员"/>
</Combo>
<Edit name="telphone" float="true" pos="367,10,0,0" width="68" height="27" bkcolor="#FFFFFFFF" textpadding="4,3,4,3" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" />
<Edit name="usersalary" float="true" pos="456,10,0,0" width="68" height="27" bkcolor="#FFFFFFFF" textpadding="4,3,4,3" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" />
<List name="ListEmployeeInfo" float="true" pos="9,43,0,0" width="523" height="353" itemtextcolor="#FF000000" itemselectedtextcolor="#FF000000" itemselectedbkcolor="#FFC1E3FF" itemhottextcolor="#FF000000" itemhotbkcolor="#FFE9F5FF" itemdisabledtextcolor="#FFCCCCCC" itemdisabledbkcolor="#FFFFFFFF">
<ListHeader name="domain" align="center">
<ListHeaderItem text="姓名" width="85" height="23" minwidth="16" textcolor="#FF000000" sepwidth="1" align="center" hotimage="list_header_hot.png" pushedimage="list_header_pushed.png" sepimage="list_header_bg.png" />
<ListHeaderItem text="性别" width="85" height="23" minwidth="16" textcolor="#FF000000" sepwidth="1" align="center" hotimage="list_header_hot.png" pushedimage="list_header_pushed.png" sepimage="list_header_bg.png" />
<ListHeaderItem text="生日" width="85" height="23" minwidth="16" textcolor="#FF000000" sepwidth="1" align="center" hotimage="list_header_hot.png" pushedimage="list_header_pushed.png" sepimage="list_header_bg.png" />
<ListHeaderItem text="职务" width="85" height="23" minwidth="16" textcolor="#FF000000" sepwidth="1" align="center" hotimage="list_header_hot.png" pushedimage="list_header_pushed.png" sepimage="list_header_bg.png" />
<ListHeaderItem text="电话" width="85" height="23" minwidth="16" textcolor="#FF000000" sepwidth="1" align="center" hotimage="list_header_hot.png" pushedimage="list_header_pushed.png" sepimage="list_header_bg.png" />
<ListHeaderItem text="薪资" width="85" height="23" minwidth="16" textcolor="#FF000000" sepwidth="1" align="center" hotimage="list_header_hot.png" pushedimage="list_header_pushed.png" sepimage="list_header_bg.png" />
</ListHeader>
</List>
<Button name="BTN_INSERT" text="插入" float="true" pos="557,169,0,0" width="58" height="36" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" />
<Button name="BTN_UPDATE" text="更新" float="true" pos="557,228,0,0" width="58" height="36" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" />
<Button name="BTN_SELL_RECORD" text="销售记录" float="true" pos="557,347,0,0" width="58" height="36" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" />
<Button name="BTN_DELETE" text="删除" float="true" pos="557,287,0,0" width="58" height="36" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" />
<Button name="BTN_SELECT" text="查询" float="true" pos="557,110,0,0" width="58" height="36" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" />
<Combo name="COMOB_SELECT" float="true" pos="559,45,0,0" width="71" height="22" itemtextcolor="#FF000000" itemselectedtextcolor="#FF000000" itemselectedbkcolor="#FFC1E3FF" itemhottextcolor="#FF000000" itemhotbkcolor="#FFE9F5FF" itemdisabledtextcolor="#FFCCCCCC" itemdisabledbkcolor="#FFFFFFFF" normalimage="Combo_nor.bmp" hotimage="Combo_over.bmp" pushedimage="Combo_over.bmp" dropboxsize="0,150">
<ListLabelElement text="无" selected="true"/>
<ListLabelElement text="姓名"/>
<ListLabelElement text="性别"/>
<ListLabelElement text="薪资"/>
</Combo>
</VerticalLayout>
<VerticalLayout>
<Edit name="testpage2" text="page2" width="100" bkcolor="#FFFFFFFF" textpadding="4,3,4,3" />
</VerticalLayout>
</TabLayout>
</VerticalLayout>
</Window>
利用DuiDesigner绘制好xml文件并保存于debug文件目录下
对应的管理员操作页面xml文件内容如下:
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<Window size="679,480">
<VerticalLayout width="679" height="480" bkimage="bg_image1.jpg">
<HorizontalLayout float="true" pos="0,2,0,0" width="679" height="31" bkcolor="#FF00FFFF">
<Button name="BTN_MIN" float="true" pos="602,8,0,0" width="30" height="15" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" normalimage="min1.png" hotimage="min2.png" pushedimage="min3.png" />
<Button name="BTN_CLOSE" float="true" pos="641,8,0,0" width="30" height="15" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" normalimage="frame_btn_close_normal.bmp" hotimage="frame_btn_close_hot.bmp" pushedimage="frame_btn_close_down.bmp" />
</HorizontalLayout>
<Label name="Label1" text="商品名称" float="true" pos="11,40,0,0" width="69" height="28" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" />
<Label name="Label2" text="库存剩余" float="true" pos="176,41,0,0" width="51" height="28" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" />
<Edit name="EDIT_GOODS_NAME" float="true" pos="95,42,0,0" width="60" height="28" bkcolor="#FFFFFFFF" textpadding="4,3,4,3" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" />
<Edit name="EDIT_GOODS_LEFT" float="true" pos="247,43,0,0" width="60" height="28" bkcolor="#FFFFFFFF" textpadding="4,3,4,3" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" />
<Button name="BTN_SELECT" text="查询" float="true" pos="322,45,0,0" width="45" height="23" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" normalimage="button_nor.bmp" hotimage="button_over.bmp" pushedimage="button_down.bmp" />
<Button name="BTN_ADD" text="+" float="true" pos="411,43,0,0" width="26" height="25" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" normalimage="button_nor.bmp" hotimage="button_over.bmp" pushedimage="button_down.bmp" />
<Button name="BTN_SUB" text="-" float="true" pos="523,41,0,0" width="26" height="28" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" normalimage="button_nor.bmp" hotimage="button_over.bmp" pushedimage="button_down.bmp" />
<Edit name="EDIT_GOODS_COUNT" text="0" float="true" pos="444,41,0,0" width="71" height="28" bkcolor="#FFFFFFFF" textpadding="4,3,4,3" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" />
<List name="OrderList" float="true" pos="24,87,0,0" width="615" height="336" itemtextcolor="#FF000000" itemselectedtextcolor="#FF000000" itemselectedbkcolor="#FFC1E3FF" itemhottextcolor="#FF000000" itemhotbkcolor="#FFE9F5FF" itemdisabledtextcolor="#FFCCCCCC" itemdisabledbkcolor="#FFFFFFFF" headerbkimage="list_header_bg.png">
<ListHeader name="domain1" bkimage="list_header_bg.png" >
<ListHeaderItem text="商品名称" width="123" height="23" minwidth="16" textcolor="#FF000000" sepwidth="1" align="center" hotimage="list_header_hot.png" pushedimage="list_header_pushed.png" sepimage="list_header_bg.png" />
<ListHeaderItem text="价格" width="123" height="23" minwidth="16" textcolor="#FF000000" sepwidth="1" align="center" hotimage="list_header_hot.png" pushedimage="list_header_pushed.png" sepimage="list_header_bg.png" />
<ListHeaderItem text="数量" width="123" height="23" minwidth="16" textcolor="#FF000000" sepwidth="1" align="center" hotimage="list_header_hot.png" pushedimage="list_header_pushed.png" sepimage="list_header_bg.png" />
<ListHeaderItem text="单位" width="123" height="23" minwidth="16" textcolor="#FF000000" sepwidth="1" align="center" hotimage="list_header_hot.png" pushedimage="list_header_pushed.png" sepimage="list_header_bg.png" />
<ListHeaderItem text="总价" width="123" height="23" minwidth="16" textcolor="#FF000000" sepwidth="1" align="center" hotimage="list_header_hot.png" pushedimage="list_header_pushed.png" sepimage="list_header_bg.png" />
</ListHeader>
</List>
<Label name="Label3" text="总价格" float="true" pos="44,438,0,0" width="57" height="25" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" />
<Edit name="EDIT_TOTAL" float="true" pos="110,435,0,0" width="82" height="28" bkcolor="#FFFFFFFF" textpadding="4,3,4,3" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" />
<Button name="BTN_COMMIT" text="确认售出" float="true" pos="320,438,0,0" width="86" height="24" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" normalimage="button_nor.bmp" hotimage="button_over.bmp" pushedimage="button_down.bmp" />
<Button name="BTN_CANCEL" text="取 消" float="true" pos="425,438,0,0" width="86" height="24" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" normalimage="button_nor.bmp" hotimage="button_over.bmp" pushedimage="button_down.bmp" />
<Button name="BTN_OK" text="OK" float="true" pos="581,44,0,0" width="45" height="23" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" normalimage="button_nor.bmp" hotimage="button_over.bmp" pushedimage="button_down.bmp" />
</VerticalLayout>
</Window>
c++连接mysql时,比如查询语句中含有中文,或者得到结果中含有中文,经常出现编译出错或乱码问题。VS编译器默认使用gbk编码。
如果将mysql设置为utf-8编码,则需要先将c++中的各种中文字符串转为utf-8编码输入mysql,得到
的结果为utf-8编码,需要转为gbk才能正常显示。
mysql_query(_mySql, "set names 'gbk'");
混淆了Duilib库封装好的方法中的GetName()与GetText()
GetName():获取控件名字
GetText():获取控件中用户手动输入的内容
pData->SetAttribute(_T(“align”), _T(“center”));//文字对齐方式:居中
构造strSQL命令语句时int/double也要当成ANSI字符串
CDuiString strCount = pItem->GetText(2);//获取每行第3列元素(本行该出售商品数量)
//获取到的都是Unicode,即使text中内容是int/double
strSQL += UnicodeToANSI(strCount);
代码中必须将空间名称显式用if/else if分完全情况给出,不能因为只有两种切换模式就用if/else
错误方式:
CTabLayoutUI* pTab = (CTabLayoutUI*)m_PaintManager.FindControl(_T("tablayout"));//找控件
if (strName == _T("OPTION_EMPLOYEE"))
pTab->SelectItem(0);//第一个option:对员工的操作
else
pTab->SelectItem(1);//第二个option:对商品的操作
正确方式:
CTabLayoutUI* pTab = (CTabLayoutUI*)m_PaintManager.FindControl(_T("tablayout"));//找控件
if (strName == _T("OPTION_EMPLOYEE"))
pTab->SelectItem(0);//第一个option:对员工的操作
else if (strName == _T("OPTION_GOODS"))
pTab->SelectItem(1);//第二个option:对商品的操作