许多年以来,饮料的销售与补货都是通过人工的方式进行的。商家每天需要清点饮料的数量,根据不同的货物需求从厂家采购。除此之外,商家还需要每天都呆在店铺,等候着客户的到来。这样的销售方式显然非常浪费人力物力。首先,每天清点货物的剩余数量,不够就则补货,这个清理过程是非常繁琐的,重复器械的工作不应该由人来大量承担。第二,为了保证饮料的安全,商家必须每天都守在店铺,防止被人偷窃,这是对人类生产力的一种限制。第三,为了保证利润最大化,商家需要经常记录下销量比较好的饮料,然后加大该货的进货量。这个记录的过程也是十分麻烦与不人性化的,很容易发生漏记,或者错记的情况。
人工管理方式消耗了大量不必要的人力和物力,想要解决这些痛点就必须提供一个新的管理方式。这种新的管理方式就是靠计算机去自动化管理。就如同工业革命时期,由机器来代替人类进行重复的工作,解放了生产力还提高了效率。现在互联网时代,通过互联网强大的算力,来代替人类进行更高效的管理,智能饮料机控系统就能解决这个问题。
智能饮料机控系统的功能如下:1、账号管理 2、线上充值 3、线上付款 4、实时通讯 5、智能提醒 6、远程操控 7、智能统计8、广告模块等等
(一)客户端
1.用户登陆界面
用户账号密码检测、重复登陆检查、广告智能展示
2.用户注销、注册界面
用户的账号密码检测、用户密码的MD5加密
3.用户购买主界面
展示用户的用户名、实时金钱数。含有饮料类型下拉框,可以选择不同的类型的饮料(冷饮、热饮、常温)。含有设备id下拉框,可以选择不同的设备。含有切换登陆按钮,通过点击切换登陆,用户可以退出登陆或者选择其他账号登陆。含有购买按钮通过点击购买按钮,用户可以购买自己想买的饮料。如果用户是管理员,可以点击进入管理员模式。
4.用户充值界面
用户可以在线充值
5.用户与服务器交互界面
实时显示服务器发来的命令信息。用户可以通过往输入框里输入信息,点击发送,发送给服务器请求信息。
6.管理员模式界面
如果是管理员身份,可以进入管理员界面来对饮料进行添货。如果不是管理员身份则不能进入该模式。管理员身份需要在服务器端添加。
(二)服务端
1、服务端控制主界面
实时显示客户端发来的请求信息。含有自动按钮,点击则进入等待连接状态。含有停止按钮,点击则断开与所有客户端的连接。含有更新设备信息按钮,点击可进入设备信息界面。含有更新饮料信息按钮,点击可进入更新饮料信息界面。含有查看购买记录按钮,点击可进入查看购买记录界面。含有查看用户记录按钮,点击可进入查看用户记录界面。
2、查看更新设备信息界面
含有刷新按钮,点击可通过表格形式显示数据库的设备信息。含有更新数据按钮,点击后会将修改后的表格数据更新到数据库中。
3、查看更新饮料信息界面
含有刷新按钮,点击可通过表格形式显示数据库的饮料信息。含有更新数据按钮,点击后会将修改后表格数据更新到数据库中。
4、查看购买记录界面
含有刷新按钮,点击可通过表格形式显示数据库的购买记录信息。
5、查看用户记录界面
含有刷新按钮,点击可通过表格形式显示数据库的用户记录信息。
6、添加管理员界面
含有账号、密码输入框和注册按钮,点击可实现管理员的添加注册。
7、广告管理界面
含有输入框、开始、停止、前一个、后一个、插入、删除等按钮,点击这些可实现对服务端对客户端广告显示的远程操控。
(一)所需技术
1、通过UI界面设计,设计出不同的前端交互界面
2、通过TCP网络通信,实现客户端与服务端的信息传送与交互
3、通过数据库技术,实现服务端的数据储存、修改与提取
4、通过MD5对密码进行加密,保证用户的密码的安全
5、QT提供的一些基本类,例如事件、信号与槽等
(二)具体方法
1.注册注销
(1)获取相应的用户和密码,然后包装成一个字符串
(2)加上标识符,说明请求类型,然后将字符串发送给服务器
(3)服务器通过dealdata函数,识别请求类型,确认这是一个注册、注销请求,调用相应的处理函数。
(4)调用的函数与数据库进行交互,判断是否进行数据库的删除和添加处理
(5)将判断结果通过字符串的形式发送给客户端
(6)客户端收到服务器发送的注册注销命令,进入dealdata函数,调用相应的处理函数
(7)相应的处理函数根据命令,来向用户显示是否注册成功
(8)如果注册或者注销成功了,客户端再将用户名、时间、活动时间打包成用户记录发送给服务器。
(9)服务器接受到了客户端的请求,调用dealdata函数对数据库进行处理,添加新加的userLog。
2.登陆
(1)获取用户名和密码的字符串,加上请求类型,通过包装成字符串发送给服务器。
(2)服务器读取客户端发来的的登陆请求,通过dealdata函数判断请求类型,并且调用相应的处理函数。
(3)调用相应的处理函数,该函数与数据库进行交互,遍历数据库判断是否可以登陆,然后将登陆命令与数据库的饮料信息、用户信息一起打包成字符串发给客户端。
(4)客户端通过dealdata函数来解析命令,如果不可以登陆,则弹Qmessagebox提醒用户不能登陆。如果可以登陆,则利用服务端发来的饮料和用户信息,调用flush函数,来刷新购买界面,加载用户的姓名、金钱,还有每种饮料的价格和剩余量。
(5)确定可以登陆后,客户端再将用户名、时间、活动时间打包成用户记录发送给服务器。
(6)服务器接受到了客户端的请求,调用dealdata函数对数据库进行处理,添加新加的userLog。
3.购买与补货
(1)获取所购饮料的信息:饮料名、设备id、饮料类型、价格、购买数量、饮料剩余数量。
(2)用户信息:用户名、金钱数
(3)状态:购买或者补货
(4)将请求类型和饮料信息、用户信息、状态打包成一个字符串发送给服务端。
(5)服务端通过dealdate函数解析命令,确认这是一个购买/补货请求,进入相应的处理函数。
(6)相应的处理函数通过遍历数据库,判断是否可以购买或者补货,然后修改数据库:drinks、users、buyLog中相应的数据。
(7)根据不同的判断情况,发送不同的命令给客户端。
(8)客户端通过dealdata来解析服务器的命令,如果可以购买、补货就弹出购买或者补货成功消息框,并且刷新购买界面。如果购买或者补货失败就会弹出购买或者补货失败的消息框。
4.切换设备或者饮料类型
(1)客户端向服务器发送刷新请求。
(2)服务器通过dealdata函数解析请求,判断出这是一个刷新请求,调用相应的函数。
(3)调用的函数将数据库的饮料和用户信息打包,给客户端发送刷新命令。
(4)客户端通过dealdata函数解析刷新命令,调用相应的函数刷新界面。
5.进入管理员模式
(1)客户端从本地用户获取用户信息。
(2)通过用户信息判断是否是管理员身份。
(3)如果是则刷新界面,进入管理员界面,如果不是则弹出消息框提示。
6.切换用户
(1)点击切换用户按钮,则进入切换用户界面。
(2)界面含有三个按钮:登陆、返回、退出。
(3)如果点击登陆则进行和2一样的流程。
(4)如果点击返回则返回购买界面。
(5)如果点击退出,则退出登录,进入到初始登陆界面。
7.充值
(1)输入相应的充值数目然后点击充值按钮,客户端将进入付款界面。
(2)付款成功后点击确认按钮,客户端将用户信息、充值信息打包,向服务器发送充值请求。
(3)服务器通过dealdata函数解析充值请求,并且调用相应的函数。
(4)相应的函数,通过一系列判断,如果充值成功则修改数据库中的user和userLog两个表中相应的数据,然后向客户端发送充值成功的命令。如果经过判断后充值失败,则给客户端发送充值失败的命令。
(5)客户端通过dealdata函数解析服务端的充值命令,然后调用相应的函数
(6)相应的函数判断充值是否成功,如果成功则刷新界面并且弹出充值成功消息框,如果充值失败则弹出充值失败消息框。
8.sendMessage界面
(1)界面包含消息显示框、输入框、发送按钮、返回按钮。
(2)消息显示框实时更新服务器发来的命令请求。
(3)在输入框输入想发送的内容,然后点击发送按钮,客户端就会将消息发送到服务器的消息显示框上,实现简单的消息传送。
(4)点击返回按钮,如果在线则返回购买界面,如果不在线则返回登陆界面。
9.Disconnect menubar
(1)点击菜单栏的Link,客户端会调用相应的函数。
(2)该函数会调用TcpSocket的disconnecFromHost方法,从而断开与服务器的连接。
10.Link menubar
(1)点击菜单栏的linkt,客户端会调用相应的函数。
(2)该函数会调用TcpSocket的linkToHost方法,从而连接服务器。
11.显示设备信息界面
(1)设备信息界面含有显示界面、刷新按钮、更新数据按钮。
(2)点击刷新按钮,服务端从数据库获得设备信息,然后通过QStandardItemModel将数据库的设备信息通过表格显示在显示界面上。
(3)修改数据后,点击刷新按钮,服务端将会把表格信息一一更新到数据库,实现了可视化人工数据库操作。
12.显示饮料信息界面
(1)饮料信息界面含有显示界面、刷新按钮、更新数据按钮。
(2)点击刷新按钮,服务端从数据库获得饮料信息,然后通过QStandardItemModel将数据库的饮料通过表格显示在显示界面上。
(3)修改数据后,点击刷新按钮,服务端将会把表格信息一一更新到数据库,实现了可视化人工数据库操作。
13.显示用户日志信息界面
(1)用户日志信息界面含有显示界面、刷新按钮。
(2)点击刷新按钮,服务端从数据库获得用户日志信息,然后通过QStandardItemModel将数据库的用户日志通过表格显示在显示界面上。
14.显示购买日志信息界面
(1)购买日志信息界面含有显示界面、刷新按钮。
(2)点击刷新按钮,服务端从数据库获得购买日志信息,然后通过QStandardItemModel将数据库的购买日志通过表格显示在显示界面上。
15.添加管理员界面
(1)添加管理员界面含有:用户名输入框、密码输入框、注册按钮、返回按钮。
(2)流程和客户端的注册类似,只是服务端可以直接和数据库进行交互,不需要通过tcp发送接受请求。
16.广告管理界面
(1)添加管理员界面含有:广告资源输入框、插入按钮、删除按钮、启动按钮、停止按钮、前一个按钮、后一个按钮、返回按钮。
(2)在输入框输入需要操作的广告资源(如果需要的话),然后点击不同的按钮,服务端会向客户端发送不同的命令。
(3)客户端通过dealdata函数解析不同的命令,然后调用不同的函数,从而达到了服务端对客户端的广告管理。
本次项目最主要的部分为tcp通信模块和数据库模块,下面就分别从这两个方面来介绍本项目的主要模块。
(一)tcp通信模块
1.客户端的发送请求模块,例如购买请求
/** 点击购买1对应的槽函数 */
void MainWindow::button_buy_1_clicked()
{
//购买的饮料信息:name、equ_id、温度、价格、购买数量、饮料数。
//用户的信息:name、money
//购买情况信息:add/buy
QString equ = QString::number(this->change_equ(ui->comboBox_equipment->currentText()));
QString nameOfdrink = “0”;
QString num_buy = QString::number(ui->residue_1->value());
QString temp = QString::number(this->change_temp(ui->comboBox_temperature->currentText()));
QString price = ui->label_1->text().split(":’’)[1];
QString numOfuser = this->user->name;
QString money = this->user->money;
QString num_drink = ui->number_1->text().split(":’’)[1];
if(ui->button_buy_1->text() == “购买”){
QMessageBox message(QMessageBox::Warning,“购买提醒”,“确认购买?”,QMessageBox::Yes|QMessageBox::No,NULL);
if (message.exec()==QMessageBox::Yes)
this->client->write(“requestOfbuy:1:” + nameOfdrink + “:” + equ + “:” + temp + “:” + price + “:” + num_buy + “:” + numOfuser + “:” + money+ “:” + num_drink + “:” + “buy”);
}
if(ui->button_buy_1->text() == “补货”){
QMessageBox message(QMessageBox::Warning,“添加”,“确认添加?”,QMessageBox::Yes|QMessageBox::No,NULL);
if (message.exec()==QMessageBox::Yes)
this->client->write(“requestOfbuy:1:” + nameOfdrink + “:” + equ + “:” + temp + “:” + price + “:” + num_buy + “:” + numOfuser + “:” + money+ “:” + num_drink + “:” + “add”);
}
}
2.服务器端的路由函数,来处理客户端发来的不同请求
/** 服务端收到客户端请求后的路由函数 **/
void Widget::dealData(QString data){
if(data.split(":’’)[0] == “requestOflog”){
this->comfirm_log(data);
}
if(data.split(":’’)[0] == “requestOfregister”){
this->comfirm_register(data);
}
if(data.split(":’’)[0] == “requestOfdelete”){
this->comfirm_delete(data);
}
if(data.split(":’’)[0] == “requestOfbuy”){
this->comfirm_buy(data);
}
if(data.split(":’’)[0] == “requestOfflush”){
this->service->write(“requireOfflush:can_flush”+ this->send_drinks() + “#” + this->send_user(data.split(":’’)[1]) + “#” + this->comfirm_hot());
if(data.split(":’’).size() >=3){
if(data.split(":’’)[2] == “changeEquipment”){
QString equ_id = data.split(":’’)[3];
db->query->exec(“UPDATE equipments SET isopen = 0”);
db->query->exec(QString(“UPDATE equipments SET isopen = 1 WHERE name = ‘%1’”).arg(equ_id));
}
}
}
if(data.split(":’’)[0] == “requestOfuserlog”){
this->insertUserLog(data.split(":’’)[1],data.split(":’’)[2],data.split(":’’)[3],data.split(":’’)[4]);
qDebug() << data.split(":’’)[1] << data.split(":’’)[2]<
if(data.split(":’’)[0] == “requestOflogOff”){
db->query->exec(QString(“UPDATE users SET isOnline = 0 WHERE name = ‘%1’”).arg(data.split(":’’)[1]));
}
if(data.split(":’’)[0] == “requestOfSendMessage”){
this->service->write(“requireOfSendMessage:can_send”);
}
if(data.split(":’’)[0] == “requestOfRecharge”){
this->db->query->exec(QString(“UPDATE users SET money = ‘%1’ WHERE name = ‘%2’”).arg(QString::number(data.split(":’’)[2].toInt() + data.split(":’’)[3].toInt())).arg(data.split(":’’)[1]));
this->service->write(“requireOfRecharge:can_Recharge” + this->send_drinks() + “#” + this->send_user(data.split(":’’)[1]) + “#” + this->comfirm_hot());
}
}
3.服务器端的路由函数经过判断后调用的处理函数,例如购买处理函数
/** 处理客户端发来的购买/添加请求 **/
//index = 10 为购买添加标识符
void Widget::comfirm_buy(QString data){
//data的形式为requestOfbuy:index:nameOfdrink:equ:temp:price:num_buy:numOfuser:money:num_drinks:status
//获得的这些数据都是之前在服务器里面get的,所以就是服务器的数据,就不需要再次从服务器获取了
QString nameOfdrink = data.split(":’’)[2];
QString equ = data.split(":’’)[3];
QString temp = data.split(":’’)[4];
QString price = data.split(":’’)[5];
QString num_buy = data.split(":’’)[6];
QString numOfuser = data.split(":’’)[7];
QString money = data.split(":’’)[8];
QString num_drinks = data.split(":’’)[9];
QString status = data.split(":’’)[10];
QString remain_drink = QString::number(num_drinks.toInt() - num_buy.toInt());
QString after_drinks = QString::number(num_drinks.toInt() + num_buy.toInt());
// QString str = “nameOfdrink” + nameOfdrink + “numOfuser” + numOfuser + “price” + price + “num_buy” + num_buy + “money” + money + “num_drinks” + num_drinks;
// qDebug() << str;
bool can_buy = false;
bool is_open = false;
//检查设备的开启状态
this->db->query->exec(QString(“SELECT * FROM equipments WHERE name = ‘%1’ AND isOpen = ‘1’”).arg(equ));
while (this->db->query->next()) {
is_open = true;
}
//服务器端每次收到添加或者购买请求的时候,就会监控所有的饮料数量
if(is_open){
if(status == “buy”){
if(num_buy.toInt() <= num_drinks.toInt() && num_drinks.toInt() != 0 && num_buy.toInt() != 0){
if(num_buy.toInt() * price.toInt() <= money.toInt()){
//库存够,钱够,可以买
can_buy = true;
qDebug() << “可以买!!!”;
//进行服务端数据库user的更新
this->db->query->exec(QString(“UPDATE users SET money = ‘%1’ WHERE name = ‘%2’”).arg(QString::number(money.toInt() - num_buy.toInt() * price.toInt())).arg(numOfuser));
//进行服务端数据库drinks的更新
this->db->query->exec(QString(“UPDATE drinks SET num%1 = ‘%2’ WHERE name = ‘%3’ AND equipment_id = ‘%4’”).arg(temp).arg(remain_drink).arg(nameOfdrink).arg(equ));
//进行服务端数据库buylog的更新
this->db->query->exec(QString(“INSERT INTO buyLog (userName, drinkrName, equipment, tempture, type,creat_time,message,numOfdrink)”
“VALUES (’%1’, ‘%2’, ‘%3’, ‘%4’, ‘%5’,’%6’,’%7’,’%8’)”).arg(numOfuser).arg(nameOfdrink).arg(equ).arg(temp).arg(“1”).arg(QDateTime::currentDateTime().toString(“yyyy.MM.dd hh.mm”)).arg(numOfuser+":buy the drinks"+nameOfdrink).arg(num_buy));
//让客户端收到可以购买的指令并且刷新购买购买界面
this->service->write(“requireOfbuy:can_buy”+ this->send_drinks() + “#” + this->send_user(numOfuser) + “#” + this->comfirm_hot());
}
}
if(!can_buy){
//让客户端收到不可以购买的指令
this->service->write(“requireOfbuy:not_buy”+ this->send_drinks() + “#” + this->send_user(numOfuser) + “#” + this->comfirm_hot());
qDebug() << “不可以买!!!”;
}
}
else if(status == “add” && num_buy != “0”){
//进行服务端数据库drinks的更新
this->db->query->exec(QString(“UPDATE drinks SET num%1 = ‘%2’ WHERE name = ‘%3’ AND equipment_id = ‘%4’”).arg(temp).arg(after_drinks).arg(nameOfdrink).arg(equ));
//进行服务端数据库buyLog的更新
this->db->query->exec(QString(“INSERT INTO buyLog (userName, drinkrName, equipment, tempture, type,creat_time,message,numOfdrink)”
“VALUES (’%1’, ‘%2’, ‘%3’, ‘%4’, ‘%5’,’%6’,’%7’,’%8’)”).arg(numOfuser).arg(nameOfdrink).arg(equ).arg(temp).arg(“2”).arg(QDateTime::currentDateTime().toString(“yyyy.MM.dd hh.mm”)).arg(numOfuser+":buy the drinks"+nameOfdrink).arg(num_buy));
//让客户端收到可以添加的指令并且刷新购买页面
this->service->write(“requireOfbuy:can_add”+ this->send_drinks() + “#” + this->send_user(numOfuser) + “#” + this->comfirm_hot());
}
else if(status == “add”){
this->service->write(“requireOfbuy:not_add”);
}
//监控饮料的数目
this->comfirm_drinks();
}
else{
this->service->write(“requireOfbuy:no_open”+ this->send_drinks() + “#” + this->send_user(numOfuser) + “#” + this->comfirm_hot());
}
}
4.客户端的路由函数,来处理服务器端发来的不同的命令
/** 客户端根据服务器命令的路由函数 */
void MainWindow::dealDate(QString data){
if(data.split(":’’)[0] == “requireOflog”)
this->decideCanlog(data);
if(data.split(":’’)[0] == “requireOfregister”)
this->decideCanRegister(data);
if(data.split(":’’)[0] == “requireOfdelete”)
this->decideCanDelete(data);
if(data.split(":’’)[0] == “requireOfbuy”)
this->decideCanbuy(data);
if(data.split(":’’)[0] == “requireOfflush”)
this->flush_buyWindow(data);
if(data == “requireOfSendMessage:can_send”){
ui->textEdit->clear();
}
if(data.split(":’’)[0] == “requireOfRecharge”){
this->flush_buyWindow(data);
QMessageBox *msb = new QMessageBox;
msb->setWindowTitle(“充值提示”);
msb->setText(“充值成功!”);
msb->setIcon(QMessageBox::Information);
msb->setStandardButtons(QMessageBox::Ok|QMessageBox::Cancel);
msb->show();
}
if(data.split(":’’)[0] == “requireOfbreaklink”){
QMessageBox *msb = new QMessageBox;
msb->setWindowTitle(“断开提示”);
msb->setText(“服务器已断开连接!”);
msb->setIcon(QMessageBox::Information);
msb->setStandardButtons(QMessageBox::Ok|QMessageBox::Cancel);
msb->show();
}
if(data.split(":’’)[0] == “requireOfAdv”){
this->op_advertisment(data);
}
}
5.客户端的路由函数调用的相应的处理函数,例如购买命令
/** 客服端的接受到服务器的购买命令时调用的函数 */
void MainWindow::decideCanbuy(QString data){
if(data.split(":’’)[1] == “can_buy”){
qDebug() << “我可以购买!”;
qDebug() << data;
this->flush_buyWindow(data);
QMessageBox *msb = new QMessageBox;
msb->setWindowTitle(“购买提示”);
msb->setText(“购买成功!”);
msb->setIcon(QMessageBox::Information);
msb->setStandardButtons(QMessageBox::Ok|QMessageBox::Cancel);
msb->show();
this->sendUserlog(this->user->name,“5”,this->user->name+" has been bought a drink!");
}
else if(data.split(":’’)[1] == “can_add”){
this->flush_buyWindow(data);
QMessageBox *msb = new QMessageBox;
msb->setWindowTitle(“添货提示”);
msb->setText(“添加货物成功!”);
msb->setIcon(QMessageBox::Information);
msb->setStandardButtons(QMessageBox::Ok|QMessageBox::Cancel);
msb->show();
}
else if(data.split(":’’)[1] == “not_buy”){
QMessageBox *msb = new QMessageBox;
msb->setWindowTitle(“购买提示”);
msb->setText(“购买失败,请确认购买数目和金钱数!”);
msb->setIcon(QMessageBox::Information);
msb->setStandardButtons(QMessageBox::Ok|QMessageBox::Cancel);
msb->show();
}
else if(data.split(":’’)[1] == “not_add”){
QMessageBox *msb = new QMessageBox;
msb->setWindowTitle(“添加提示”);
msb->setText(“添加失败,请注意添加数目!”);
msb->setIcon(QMessageBox::Information);
msb->setStandardButtons(QMessageBox::Ok|QMessageBox::Cancel);
msb->show();
}
else if(data.split(":’’)[1] == “no_open”){
QMessageBox *msb = new QMessageBox;
msb->setWindowTitle(“设备提示”);
msb->setText(“设备未启动”);
msb->setIcon(QMessageBox::Information);
msb->setStandardButtons(QMessageBox::Ok|QMessageBox::Cancel);
msb->show();
}
}
(二)数据库模块
1.服务端购买成功时对数据库进行的更新
//进行服务端数据库user的更新
this->db->query->exec(QString(“UPDATE users SET money = ‘%1’ WHERE name = ‘%2’”).arg(QString::number(money.toInt() - num_buy.toInt() * price.toInt())).arg(numOfuser));
//进行服务端数据库drinks的更新
this->db->query->exec(QString(“UPDATE drinks SET num%1 = ‘%2’ WHERE name = ‘%3’ AND equipment_id = ‘%4’”).arg(temp).arg(remain_drink).arg(nameOfdrink).arg(equ));
//进行服务端数据库buylog的更新
this->db->query->exec(QString(“INSERT INTO buyLog (userName, drinkrName, equipment, tempture, type,creat_time,message,numOfdrink)”
“VALUES (’%1’, ‘%2’, ‘%3’, ‘%4’, ‘%5’,’%6’,’%7’,’%8’)”).arg(numOfuser).arg(nameOfdrink).arg(equ).arg(temp).arg(“1”).arg(QDateTime::currentDateTime().toString(“yyyy.MM.dd hh.mm”)).arg(numOfuser+":buy the drinks"+nameOfdrink).arg(num_buy));
2.服务端从数据库得到饮料的信息
/** 服务端从数据库获得饮料信息并且打包成字串发送给客户端 **/
QString Widget::send_drinks(){
QString data;
this->db->query->exec(“SELECT * FROM drinks”);
while(this->db->query->next()){
data += “:” + this->db->query->value(1).toString();
data += “:” + this->db->query->value(2).toString();
data += “:” + this->db->query->value(3).toString();
data += “:” + this->db->query->value(4).toString();
data += “:” + this->db->query->value(5).toString();
data += “:” + this->db->query->value(6).toString();
}
return data;
}
1.客户端的路由函数的调用关系
2.服务器端的路由函数的调用关系
1.客户端的登陆界面的广告
2.客户端的登陆界面
3.客户端的登陆界面
4.客户端的切换用户界面
5.客户端的管理员模式界面
6.服务器端的控制主界面
7.服务器端的展现用户日志界面
8.服务器端的展现消费日志界面
9.服务器端的展现设备修改设备情况界面
10.服务器端的展现饮料修改饮料情况界面
11.服务器端的添加管理员界面
12.服务器端的远程控制广告界面