Commit c159ec9d by unknown

Add 1: git init

parent bc2bb8b1
#-------------------------------------------------
#
# Project created by QtCreator 2017-11-02T10:38:18
#
#-------------------------------------------------
QT += network
QT -= gui
TARGET = fmHttp
TEMPLATE = lib
DEFINES += FMHTTP_LIBRARY
SOURCES += fmhttp.cpp
HEADERS += fmhttp.h\
fmhttp_global.h
unix {
target.path = /usr/lib
INSTALLS += target
}
#include "fmhttp.h"
FmHttp::FmHttp()
{
}
#ifndef FMHTTP_H
#define FMHTTP_H
#include "fmhttp_global.h"
class FMHTTPSHARED_EXPORT FmHttp
{
public:
FmHttp();
};
#endif // FMHTTP_H
#ifndef FMHTTP_GLOBAL_H
#define FMHTTP_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(FMHTTP_LIBRARY)
# define FMHTTPSHARED_EXPORT Q_DECL_EXPORT
#else
# define FMHTTPSHARED_EXPORT Q_DECL_IMPORT
#endif
#endif // FMHTTP_GLOBAL_H
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
#include "QsLogDestFile.h" #include "QsLogDestFile.h"
#include "QsLogDestFunctor.h" #include "QsLogDestFunctor.h"
#include <QString> #include <QString>
#include <QDir>
#include <QDate>
namespace QsLogging namespace QsLogging
{ {
...@@ -37,19 +39,37 @@ Destination::~Destination() ...@@ -37,19 +39,37 @@ Destination::~Destination()
} }
//! destination factory //! destination factory
DestinationPtr DestinationFactory::MakeFileDestination(const QString& filePath, DestinationPtr DestinationFactory::MakeFileDestination(const QString& fileDir, const QString &filePrefix, int fileHoldDays,
LogRotationOption rotation, const MaxSizeBytes &sizeInBytesToRotateAfter, LogRotationOption rotation, const MaxSizeBytes &sizeInBytesToRotateAfter,
const MaxOldLogCount &oldLogsToKeep) const MaxOldLogCount &oldLogsToKeep)
{ {
//清理之前的日志
QDir dir(fileDir);
if(dir.exists())
{
dir.setFilter(QDir::Files | QDir::NoSymLinks);
QFileInfoList list = dir.entryInfoList();
foreach(QFileInfo info, list)
{
if(info.baseName().startsWith(filePrefix) &&
QDate::currentDate()>=info.lastModified().date().addDays(fileHoldDays))
{
QFile(info.filePath()).remove();
}
}
}
QString logPath = QString("%1/%2%3.txt").arg(fileDir, filePrefix, QDate::currentDate().toString("yyyy-MM-dd"));
if (EnableLogRotation == rotation) { if (EnableLogRotation == rotation) {
QScopedPointer<SizeRotationStrategy> logRotation(new SizeRotationStrategy); QScopedPointer<SizeRotationStrategy> logRotation(new SizeRotationStrategy);
logRotation->setMaximumSizeInBytes(sizeInBytesToRotateAfter.size); logRotation->setMaximumSizeInBytes(sizeInBytesToRotateAfter.size);
logRotation->setBackupCount(oldLogsToKeep.count); logRotation->setBackupCount(oldLogsToKeep.count);
return DestinationPtr(new FileDestination(filePath, RotationStrategyPtr(logRotation.take()))); return DestinationPtr(new FileDestination(logPath, RotationStrategyPtr(logRotation.take())));
} }
return DestinationPtr(new FileDestination(filePath, RotationStrategyPtr(new NullRotationStrategy))); return DestinationPtr(new FileDestination(logPath, RotationStrategyPtr(new NullRotationStrategy)));
} }
DestinationPtr DestinationFactory::MakeDebugOutputDestination() DestinationPtr DestinationFactory::MakeDebugOutputDestination()
......
...@@ -94,7 +94,8 @@ struct QSLOG_SHARED_OBJECT MaxOldLogCount ...@@ -94,7 +94,8 @@ struct QSLOG_SHARED_OBJECT MaxOldLogCount
class QSLOG_SHARED_OBJECT DestinationFactory class QSLOG_SHARED_OBJECT DestinationFactory
{ {
public: public:
static DestinationPtr MakeFileDestination(const QString& filePath, static DestinationPtr MakeFileDestination(const QString& fileDir,
const QString& filePrefix, int fileHoldDays = 10,
LogRotationOption rotation = DisableLogRotation, LogRotationOption rotation = DisableLogRotation,
const MaxSizeBytes &sizeInBytesToRotateAfter = MaxSizeBytes(), const MaxSizeBytes &sizeInBytesToRotateAfter = MaxSizeBytes(),
const MaxOldLogCount &oldLogsToKeep = MaxOldLogCount()); const MaxOldLogCount &oldLogsToKeep = MaxOldLogCount());
......
...@@ -29,6 +29,8 @@ FlowControl::FlowControl() ...@@ -29,6 +29,8 @@ FlowControl::FlowControl()
// 初始化TcpServer监听 // 初始化TcpServer监听
m_tcpServer = new QTcpServer(this); m_tcpServer = new QTcpServer(this);
// 业务需求不高,未作并发处理
connect(m_tcpServer, &QTcpServer::newConnection, [this]() connect(m_tcpServer, &QTcpServer::newConnection, [this]()
{ {
QTcpSocket *socket = m_tcpServer->nextPendingConnection(); QTcpSocket *socket = m_tcpServer->nextPendingConnection();
...@@ -49,24 +51,40 @@ FlowControl::FlowControl() ...@@ -49,24 +51,40 @@ FlowControl::FlowControl()
connect(this, &FlowControl::recordSale, &Sales::Instance(), &Sales::onRecordSale); connect(this, &FlowControl::recordSale, &Sales::Instance(), &Sales::onRecordSale);
} }
void FlowControl::Start()
{
QLOG_INFO() << QString(">>>>>>>>>>>>>>>>>>程序启动%1<<<<<<<<<<<<<<<<<<").arg(PRODUCT_VERSION);
QString storeId = ConfigManage::Instance().storeId();
if( !storeId.isEmpty() )
{
m_storeInfo.sotoreId = storeId;
m_storeInfo.posId = "01";
_onLogin();
}
int port = ConfigManage::Instance().tcpServerPort();
bool result = m_tcpServer->listen(QHostAddress::Any, port);
QLOG_INFO() << QString("绑定端口[%1],结果[%2]").arg(port).arg(result);
}
int FlowControl::_ParseTcpData(const QString &data, QString& error) int FlowControl::_ParseTcpData(const QString &data, QString& error)
{ {
int result = 0; int result = 0;
error = "invalid data"; error = "无效的数据";
QJsonObject jsonObject, store_info; QJsonObject recvObj, infoObj;
QJsonParseError jsonError; QJsonParseError jsonError;
jsonObject = QJsonDocument::fromJson(data.toUtf8(), &jsonError).object(); recvObj = QJsonDocument::fromJson(data.toUtf8(), &jsonError).object();
if( jsonError.error == QJsonParseError::NoError ) if( jsonError.error == QJsonParseError::NoError )
{ {
QString fm_cmd = jsonObject["fm_cmd"].toString(); QString fm_cmd = recvObj["fm_cmd"].toString();
if( !fm_cmd.compare("put_store_info") ) if( !fm_cmd.compare("put_store_info") )
{ {
// 获取到的是门店信息->登陆 // 获取到的是门店信息->登陆
store_info = jsonObject["store_info"].toObject(); infoObj = recvObj["store_info"].toObject();
QString pos_id = store_info["pos_id"].toString(); QString pos_id = infoObj["pos_id"].toString();
QString store_id = store_info["store_id"].toString(); QString store_id = infoObj["store_id"].toString();
QString business_date = store_info["business_date"].toString(); QString business_date = infoObj["business_date"].toString();
if( !pos_id.isEmpty() && !store_id.isEmpty() ) if( !pos_id.isEmpty() && !store_id.isEmpty() )
{ {
if( !m_bLogged ) if( !m_bLogged )
...@@ -76,12 +94,11 @@ int FlowControl::_ParseTcpData(const QString &data, QString& error) ...@@ -76,12 +94,11 @@ int FlowControl::_ParseTcpData(const QString &data, QString& error)
m_storeInfo.businessDate = business_date; m_storeInfo.businessDate = business_date;
_onLogin(); _onLogin();
} }
error = QString("sucessful"); error = QString("成功");
result = 1; result = 1;
} }
} }
} }
return result; return result;
} }
...@@ -109,7 +126,7 @@ void FlowControl::_onLogin() ...@@ -109,7 +126,7 @@ void FlowControl::_onLogin()
m_storeInfo.phone = storeObj["phone"].toString(); m_storeInfo.phone = storeObj["phone"].toString();
m_storeInfo.address = storeObj["address"].toString(); m_storeInfo.address = storeObj["address"].toString();
emit loginSucessful(m_storeInfo.name); emit loginSucessful(m_storeInfo.name);
// 记录下门店号 // 记录下门店号到配置文件
ConfigManage::Instance().setStoreId(m_storeInfo.sotoreId); ConfigManage::Instance().setStoreId(m_storeInfo.sotoreId);
// 开始拉取订单 // 开始拉取订单
...@@ -143,7 +160,7 @@ void FlowControl::_onPullOrder() ...@@ -143,7 +160,7 @@ void FlowControl::_onPullOrder()
QJsonObject recvObj = QJsonDocument::fromJson(data).object(); QJsonObject recvObj = QJsonDocument::fromJson(data).object();
if(recvObj["statusCode"].toInt() == 100) if(recvObj["statusCode"].toInt() == 100)
{ {
hideAlertForm(); //hideAlertForm();
m_timestamp = recvObj["timestamp"].toString(); m_timestamp = recvObj["timestamp"].toString();
QJsonArray values = recvObj["orders"].toArray(); QJsonArray values = recvObj["orders"].toArray();
foreach(QJsonValue value, values) foreach(QJsonValue value, values)
...@@ -155,11 +172,15 @@ void FlowControl::_onPullOrder() ...@@ -155,11 +172,15 @@ void FlowControl::_onPullOrder()
{ {
orderObj = new OrderObject(this); orderObj = new OrderObject(this);
m_ordersMap.insert(order_id, orderObj); m_ordersMap.insert(order_id, orderObj);
}else }else
{ {
orderObj = m_ordersMap.value(order_id); orderObj = m_ordersMap.value(order_id);
} }
orderObj->FetchDataFromJson(order); orderObj->FetchDataFromJson(order);
// TODO
orderObj->dis_desc.append("拿破仑起酥蛋糕");
orderObj->dis_desc.append("香蒜脆片(4入装)");
emit updateOrderDisplay(orderObj); emit updateOrderDisplay(orderObj);
...@@ -176,7 +197,7 @@ void FlowControl::_onPullOrder() ...@@ -176,7 +197,7 @@ void FlowControl::_onPullOrder()
{ {
showAlertForm(AlertForm::ERROR, "拉取订单失败[网络错误,请检查网络连接]", true); showAlertForm(AlertForm::ERROR, "拉取订单失败[网络错误,请检查网络连接]", true);
QLOG_ERROR() << QString("轮询失败: %1").arg(error); QLOG_ERROR() << QString("轮询失败: %1").arg(error);
QTimer::singleShot(20000, this, &FlowControl::_onPullOrder); QTimer::singleShot(60000, this, &FlowControl::_onPullOrder);
} }
); );
} }
...@@ -247,23 +268,48 @@ void FlowControl::ProcessOrder(OrderObject *orderObj, const QString &operation) ...@@ -247,23 +268,48 @@ void FlowControl::ProcessOrder(OrderObject *orderObj, const QString &operation)
_onProcessOrderHandle(orderObj->order_id, operation, appendData, []{}); _onProcessOrderHandle(orderObj->order_id, operation, appendData, []{});
} }
OrderObject *FlowControl::GetOrderObject(const QString &orderId) void FlowControl::GetDailyInfo()
{ {
return m_ordersMap.value(orderId); QLOG_INFO() << QString(">>>>>>>>>>>>>>>>>>>>>>>>>");
} QByteArray appendData = DataManage::pullDailyData(m_token);
QLOG_INFO() << QString("获取日结信息,请求数据: %1").arg(QString(appendData));
showAlertForm(AlertForm::LOADING, QString("正在获取日结信息......"));
void FlowControl::Start() m_http.Post(appendData
{ ,[this](const QByteArray &data)
QLOG_INFO() << QString(">>>>>>>>>>>>>>>>>>程序启动%1<<<<<<<<<<<<<<<<<<").arg(PRODUCT_VERSION); {
QString storeId = ConfigManage::Instance().storeId(); QLOG_INFO() << QString("获取日结信息,返回数据: %1").arg(QString(data).simplified());
if( !storeId.isEmpty() ) QJsonObject recvObj = QJsonDocument::fromJson(data).object();
{ int status = recvObj["statusCode"].toInt();
m_storeInfo.sotoreId = storeId; if( status == 100)
m_storeInfo.posId = "01"; {
_onLogin(); emit hideAlertForm();
}
int port = ConfigManage::Instance().tcpServerPort(); QList<DailyInfo> infos;
bool result = m_tcpServer->listen(QHostAddress::Any, port); QJsonArray array = recvObj["daily_summarys"].toArray();
QLOG_INFO() << QString("绑定端口[%1],结果[%2]").arg(port).arg(result); foreach(QJsonValue v, array)
{
QJsonObject json = v.toObject();
DailyInfo info;
info.channel = json["channel"].toString();
info.total_number = json["total_number"].toInt();
info.total_fee = json["total_fee"].toInt();
info.refund_number = json["refund_number"].toInt();
info.refund_total_fee = json["refund_total_fee"].toInt();
info.total_projected_revenue = json["total_projected_revenue"].toInt();
infos.append(info);
}
emit showDailyForm(infos);
}else
{
showAlertForm(AlertForm::ERROR, QString("获取日结信息,失败[%1]").arg(recvObj["msg"].toString()), true);
}
}
,[this](const QNetworkReply::NetworkError &error)
{
showAlertForm(AlertForm::ERROR, QString("获取日结信息,失败[网络错误,请检查网络连接]"), true);
QLOG_ERROR() << QString("获取日结信息,失败: %1").arg(error);
}
);
} }
...@@ -20,23 +20,30 @@ public: ...@@ -20,23 +20,30 @@ public:
void Start(); void Start();
/* 功能:处理订单 /* 功能:获取门店信息
* 参数:[1]订单对象[2]操作 * 参数:NULL
* 返回:NULL * 返回:门店信息
* */ * */
void ProcessOrder(OrderObject* orderObj, const QString& operation); inline StoreInfo GetStoreInfo(){ return m_storeInfo; }
/* 功能:获取订单对象 /* 功能:获取订单对象
* 参数:[1]订单号 * 参数:[1]订单号
* 返回:订单对象 * 返回:订单对象
* */ * */
OrderObject* GetOrderObject(const QString& orderId); inline OrderObject* GetOrderObject(const QString& orderId)
{ return m_ordersMap.value(orderId); }
/* 功能:获取门店信息 /* 功能:处理订单
* 参数:[1]订单对象[2]操作
* 返回:NULL
* */
void ProcessOrder(OrderObject* orderObj, const QString& operation);
/* 功能:获取日结信息
* 参数:NULL * 参数:NULL
* 返回:门店信息 * 返回:NULL
* */ * */
StoreInfo GetStoreInfo(){ return m_storeInfo; } void GetDailyInfo();
private: private:
FlowControl(); FlowControl();
...@@ -48,16 +55,18 @@ private: ...@@ -48,16 +55,18 @@ private:
int _ParseTcpData(const QString &data, QString &error); int _ParseTcpData(const QString &data, QString &error);
private: private:
// 标记是否已经登陆
bool m_bLogged; bool m_bLogged;
// 用于接收POS信息的TcpServer // 用于接收POS信息的TcpServer
QTcpServer *m_tcpServer; QTcpServer *m_tcpServer;
// 门店信息 // 门店信息
StoreInfo m_storeInfo; StoreInfo m_storeInfo;
// http
FmHttp m_http; FmHttp m_http;
//用于和服务端通信的本地数据 // 用于和服务端通信的本地数据
QString m_token; QString m_token;
QString m_timestamp; QString m_timestamp;
//用于存储订单信息<订单ID, 订单对象> // 用于存储订单信息<订单ID, 订单对象>
QMap<QString, OrderObject*> m_ordersMap; QMap<QString, OrderObject*> m_ordersMap;
private slots: private slots:
...@@ -77,8 +86,8 @@ private slots: ...@@ -77,8 +86,8 @@ private slots:
* 参数:[1]操作名称[2]发送数据[3]成功对应的回调函数 * 参数:[1]操作名称[2]发送数据[3]成功对应的回调函数
* 返回:NULL * 返回:NULL
* */ * */
void _onProcessOrderHandle(const QString &orderId, const QString& operationName, const QByteArray& appendData void _onProcessOrderHandle(const QString &orderId, const QString& operationName,
, const std::function< void() > &onSucessful); const QByteArray& appendData, const std::function< void() > &onSucessful);
signals: signals:
/* 功能:登陆成功 /* 功能:登陆成功
...@@ -100,6 +109,12 @@ signals: ...@@ -100,6 +109,12 @@ signals:
void showAlertForm(AlertForm::AlertType type, const QString& msg, bool bFocus = false); void showAlertForm(AlertForm::AlertType type, const QString& msg, bool bFocus = false);
void hideAlertForm(); void hideAlertForm();
/* 功能:显示日结窗口
* 参数:[1]日结信息
* 返回:NULL
* */
void showDailyForm(QList<DailyInfo> infos);
/* 功能:打印 /* 功能:打印
* 参数:[1]订单对象 * 参数:[1]订单对象
* 返回:NULL * 返回:NULL
......
...@@ -62,6 +62,7 @@ bool Printer::_print(QString strData) ...@@ -62,6 +62,7 @@ bool Printer::_print(QString strData)
QString Printer::_printData(const OrderObject *orderObj) QString Printer::_printData(const OrderObject *orderObj)
{ {
QString result_str; QString result_str;
QString str_comd_list; QString str_comd_list;
// 分辨出所有篮子信息 // 分辨出所有篮子信息
...@@ -73,6 +74,12 @@ QString Printer::_printData(const OrderObject *orderObj) ...@@ -73,6 +74,12 @@ QString Printer::_printData(const OrderObject *orderObj)
map.insert(dishObj->bsk_num, dishObj); map.insert(dishObj->bsk_num, dishObj);
} }
foreach(QString comm, orderObj->dis_desc)
{
str_comd_list.append(QString("(赠)"+comm+"#"));
}
foreach(QString key, map.uniqueKeys()) foreach(QString key, map.uniqueKeys())
{ {
foreach(DishObject* dishObj, map.values(key)) foreach(DishObject* dishObj, map.values(key))
......
...@@ -36,7 +36,7 @@ private: ...@@ -36,7 +36,7 @@ private:
public slots: public slots:
/* 功能:接受打印任务 /* 功能:接受打印任务
* 参数:[1]订单对象 * 参数:[1]订单对象 [2]是否重新打印,如果是则忽略判断条件
* 返回:NULL * 返回:NULL
* */ * */
void onPrint( OrderObject const *orderObj = nullptr, bool bReprint = false ); void onPrint( OrderObject const *orderObj = nullptr, bool bReprint = false );
......
...@@ -18,6 +18,7 @@ public: ...@@ -18,6 +18,7 @@ public:
private: private:
Sales(); Sales();
~Sales();
private: private:
QThread* m_thread = nullptr; QThread* m_thread = nullptr;
...@@ -29,7 +30,7 @@ private: ...@@ -29,7 +30,7 @@ private:
public slots: public slots:
/* 功能:初始化数据 /* 功能:初始化数据
* 说明:由于写销售单动作放在单独的线程所以db链接对象也放在工作线程中创建 * 说明:由于写销售单动作放在单独的线程,所以db链接对象也放在工作线程中创建
* 参数:[1]订单对象 * 参数:[1]订单对象
* 返回:NULL * 返回:NULL
* */ * */
......
#include "dailyform.h"
#include "ui_dailyform.h"
#include <QDateTime>
#include "flowControl.h"
DailyForm::DailyForm(QWidget *parent) :
QDialog(parent),
ui(new Ui::DailyForm)
{
ui->setupUi(this);
setWindowFlags(this->windowFlags() | Qt::FramelessWindowHint);
this->setModal(true);
m_map.insert("mtwm", "美团外卖");
m_map.insert("bdwm", "百度外卖");
m_map.insert("jdwm", "京东到家");
m_map.insert("eleme2", "饿了么");
m_map.insert("fmwd", "非码微店");
m_map.insert("mall", "APP");
}
DailyForm::~DailyForm()
{
delete ui;
}
void DailyForm::InitData(QList<DailyInfo> infos)
{
ui->daily_table0->clearContents();
ui->daily_table0->setRowCount(0);
ui->daily_table1->clearContents();
ui->daily_table1->setRowCount(0);
QDateTime time = QDateTime::currentDateTime();
ui->daily_labStoreName->setText(FlowControl::Instance().GetStoreInfo().name);
ui->daily_labStoreId->setText(FlowControl::Instance().GetStoreInfo().sotoreId);
ui->daily_labDate->setText(time.toString("yyyy-MM-dd"));
ui->daily_labTime->setText(QString("00:00:00 - %1").arg(time.toString("hh:mm:ss")));
int channel0_total_fee = 0;
int channel0_total_num = 0;
int channel1_total_fee = 0;
int channel1_total_num = 0;
int shop_total_fee = 0;
foreach (DailyInfo info, infos) {
ui->daily_table0->insertRow(0);
ui->daily_table1->insertRow(0);
QTableWidgetItem *channel0 = new QTableWidgetItem(m_map.value(info.channel));
channel0->setTextAlignment(Qt::AlignCenter);
ui->daily_table0->setItem(0, 0, channel0);
QTableWidgetItem *num0 = new QTableWidgetItem(QString::number(info.total_number));
num0->setTextAlignment(Qt::AlignCenter);
ui->daily_table0->setItem(0, 1, num0);
QTableWidgetItem *fee0 = new QTableWidgetItem(Util::Penny2Dollar(info.total_fee));
fee0->setTextAlignment(Qt::AlignCenter);
ui->daily_table0->setItem(0, 2, fee0);
QTableWidgetItem *channel1 = new QTableWidgetItem(m_map.value(info.channel));
channel1->setTextAlignment(Qt::AlignCenter);
ui->daily_table1->setItem(0, 0, channel1);
QTableWidgetItem *num1 = new QTableWidgetItem(QString::number(info.refund_number));
num1->setTextAlignment(Qt::AlignCenter);
ui->daily_table1->setItem(0, 1, num1);
QTableWidgetItem *fee1 = new QTableWidgetItem(Util::Penny2Dollar(info.refund_total_fee));
fee1->setTextAlignment(Qt::AlignCenter);
ui->daily_table1->setItem(0, 2, fee1);
channel0_total_fee += info.total_fee;
channel0_total_num += info.total_number;
channel1_total_fee += info.refund_total_fee;
channel1_total_num += info.refund_number;
shop_total_fee += info.total_projected_revenue;
}
int rowIndex = infos.count();
ui->daily_table0->insertRow(rowIndex);
ui->daily_table1->insertRow(rowIndex);
QTableWidgetItem *channel0 = new QTableWidgetItem("总计");
channel0->setTextAlignment(Qt::AlignCenter);
ui->daily_table0->setItem(rowIndex, 0, channel0);
QTableWidgetItem *num0 = new QTableWidgetItem(QString::number(channel0_total_num));
num0->setTextAlignment(Qt::AlignCenter);
ui->daily_table0->setItem(rowIndex, 1, num0);
QTableWidgetItem *fee0 = new QTableWidgetItem(Util::Penny2Dollar(channel0_total_fee));
fee0->setTextAlignment(Qt::AlignCenter);
ui->daily_table0->setItem(rowIndex, 2, fee0);
QTableWidgetItem *channel1 = new QTableWidgetItem("总计");
channel1->setTextAlignment(Qt::AlignCenter);
ui->daily_table1->setItem(rowIndex, 0, channel1);
QTableWidgetItem *num1 = new QTableWidgetItem(QString::number(channel1_total_num));
num1->setTextAlignment(Qt::AlignCenter);
ui->daily_table1->setItem(rowIndex, 1, num1);
QTableWidgetItem *fee1 = new QTableWidgetItem(Util::Penny2Dollar(channel1_total_fee));
fee1->setTextAlignment(Qt::AlignCenter);
ui->daily_table1->setItem(rowIndex, 2, fee1);
ui->daily_labYJZSR->setText(Util::Penny2Dollar(shop_total_fee));
}
void DailyForm::on_daily_btnClose_clicked()
{
hide();
}
#ifndef DAILYFORM_H
#define DAILYFORM_H
#include <QDialog>
#include <QMap>
#include "util.h"
namespace Ui {
class DailyForm;
}
class DailyForm : public QDialog
{
Q_OBJECT
public:
explicit DailyForm(QWidget *parent = 0);
~DailyForm();
void InitData(QList<DailyInfo> infos);
private slots:
void on_daily_btnClose_clicked();
private:
Ui::DailyForm *ui;
// 用于存储平台码和平台名称映射
QMap<QString, QString> m_map;
};
#endif // DAILYFORM_H
...@@ -41,12 +41,12 @@ void DetailForm::InitData(OrderObject *orderObj) ...@@ -41,12 +41,12 @@ void DetailForm::InitData(OrderObject *orderObj)
// 当前订单详情 // 当前订单详情
ui->detail_labDDZT->setText(statusDesc); ui->detail_labDDZT->setText(statusDesc);
ui->detail_labDDBZ->setText(orderObj->remark); ui->detail_labDDBZ->setText( orderObj->remark.isEmpty()? "无" : orderObj->remark );
ui->detail_labGKXM->setText(orderObj->customer); ui->detail_labGKXM->setText( orderObj->customer );
ui->detail_labSHDZ->setText(orderObj->address); ui->detail_labSHDZ->setText( orderObj->address );
ui->detail_labSCY->setText(QString("%1 %2").arg(orderObj->courier_name, orderObj->courier_phone)); ui->detail_labSCY->setText( orderObj->courier_name.isEmpty() ? "正在分配中....." : QString("%1 %2").arg(orderObj->courier_name, orderObj->courier_phone) );
ui->detail_labSDSJ->setText(orderObj->delivery_time==0?"立即送出":QDateTime::fromTime_t(orderObj->delivery_time).toString("yyyy-MM-dd hh:mm")); ui->detail_labSDSJ->setText( orderObj->delivery_time==0?"立即送出":QDateTime::fromTime_t(orderObj->delivery_time).toString("yyyy-MM-dd hh:mm") );
ui->detail_labFPXX->setText(orderObj->invoice_title); ui->detail_labFPXX->setText( orderObj->invoice_title.isEmpty() ? "无需发票" : orderObj->invoice_title );
// 操作按钮 // 操作按钮
ui->detail_btnProc->setText(operation); ui->detail_btnProc->setText(operation);
...@@ -120,15 +120,15 @@ void DetailForm::_GetOrderAdditional(OrderObject *orderObj, QString &operation, ...@@ -120,15 +120,15 @@ void DetailForm::_GetOrderAdditional(OrderObject *orderObj, QString &operation,
operation = OPERATION_REJECT; operation = OPERATION_REJECT;
ui->detail_btnRefund->hide(); ui->detail_btnRefund->hide();
break; break;
case 2:
statusDesc = "正在分配骑手......";
operation = OPERATION_SENDOUT;
break;
case 20: case 20:
statusDesc = "等待退款,如需退款请返回上级页面."; statusDesc = "等待退款,如需退款请返回上级页面.";
operation = OPERATION_REFUSE_REFUND; operation = OPERATION_REFUSE_REFUND;
ui->detail_btnRefund->hide(); ui->detail_btnRefund->hide();
break; break;
case 2:
statusDesc = "正在分配骑手.";
operation = OPERATION_SENDOUT;
break;
case 4: case 4:
case 5: case 5:
statusDesc = "正在配送中."; statusDesc = "正在配送中.";
......
...@@ -43,7 +43,8 @@ SOURCES += main.cpp \ ...@@ -43,7 +43,8 @@ SOURCES += main.cpp \
dishmgtform.cpp \ dishmgtform.cpp \
detailform.cpp \ detailform.cpp \
controls/printer.cpp \ controls/printer.cpp \
controls/sales.cpp controls/sales.cpp \
dailyform.cpp
HEADERS += mainwindow.h \ HEADERS += mainwindow.h \
models/orderObject.h \ models/orderObject.h \
...@@ -59,14 +60,16 @@ HEADERS += mainwindow.h \ ...@@ -59,14 +60,16 @@ HEADERS += mainwindow.h \
dishmgtform.h \ dishmgtform.h \
detailform.h \ detailform.h \
controls/printer.h \ controls/printer.h \
controls/sales.h controls/sales.h \
dailyform.h
FORMS += mainwindow.ui \ FORMS += mainwindow.ui \
alertform.ui \ alertform.ui \
floatform.ui \ floatform.ui \
storemgtform.ui \ storemgtform.ui \
dishmgtform.ui \ dishmgtform.ui \
detailform.ui detailform.ui \
dailyform.ui
DISTFILES += \ DISTFILES += \
../run/client.ini \ ../run/client.ini \
......
...@@ -34,28 +34,13 @@ int main(int argc, char *argv[]) ...@@ -34,28 +34,13 @@ int main(int argc, char *argv[])
void InitLog() void InitLog()
{ {
QString logDir = QString("%1/log").arg(g_appDir); QString logDir = QString("%1/log").arg(g_appDir);
//清理之前的日志 QDir().mkdir(logDir);
QDir dir(logDir);
if(dir.exists())
{
dir.setFilter(QDir::Files | QDir::NoSymLinks);
QFileInfoList list = dir.entryInfoList();
foreach(QFileInfo info, list)
{
if(info.baseName().startsWith(ConfigManage::Instance().logPrefix()) &&
QDate::currentDate()>=info.lastModified().date().addDays(ConfigManage::Instance().logHoldTime()))
{
QFile(info.filePath()).remove();
}
}
}
QsLogging::Logger& logger = QsLogging::Logger::instance(); QsLogging::Logger& logger = QsLogging::Logger::instance();
logger.setLoggingLevel(QsLogging::TraceLevel); logger.setLoggingLevel(QsLogging::TraceLevel);
QDir().mkdir(logDir);
QString logPath = QString("%1/%2%3.txt").arg(logDir, ConfigManage::Instance().logPrefix() QsLogging::DestinationPtr fileDst(QsLogging::DestinationFactory::MakeFileDestination(logDir,
, QDate::currentDate().toString("yyyy-MM-dd")); ConfigManage::Instance().logPrefix(), ConfigManage::Instance().logHoldDays(),
QsLogging::DestinationPtr fileDst(QsLogging::DestinationFactory::MakeFileDestination(logPath,
QsLogging::EnableLogRotation, QsLogging::MaxSizeBytes(20*1024*1024), QsLogging::MaxOldLogCount(1))); QsLogging::EnableLogRotation, QsLogging::MaxSizeBytes(20*1024*1024), QsLogging::MaxOldLogCount(1)));
logger.addDestination(fileDst); logger.addDestination(fileDst);
QsLogging::DestinationPtr consoleDst(QsLogging::DestinationFactory::MakeDebugOutputDestination()); QsLogging::DestinationPtr consoleDst(QsLogging::DestinationFactory::MakeDebugOutputDestination());
......
...@@ -44,7 +44,7 @@ MainWindow::MainWindow(QWidget *parent) : ...@@ -44,7 +44,7 @@ MainWindow::MainWindow(QWidget *parent) :
// 网络状态显示 // 网络状态显示
ui->main_labNetStatus->setText("正常"); ui->main_labNetStatus->setText("正常");
// 订单显示 // 更新订单显示
connect(&FlowControl::Instance(), &FlowControl::updateOrderDisplay, this, &MainWindow::onUpdateOrderDisplay); connect(&FlowControl::Instance(), &FlowControl::updateOrderDisplay, this, &MainWindow::onUpdateOrderDisplay);
// 提示窗口显示 // 提示窗口显示
...@@ -54,14 +54,12 @@ MainWindow::MainWindow(QWidget *parent) : ...@@ -54,14 +54,12 @@ MainWindow::MainWindow(QWidget *parent) :
m_alertForm->SetContent(type, msg); m_alertForm->SetContent(type, msg);
if( bFocus ) if( bFocus )
{ {
show(); m_floatForm->hide();
this->show();
m_alertForm->show(); m_alertForm->show();
}else }else if( !isHidden() )
{ {
if( !isHidden() ) m_alertForm->show();
{
m_alertForm->show();
}
} }
}); });
connect(&FlowControl::Instance(), &FlowControl::hideAlertForm, [this]() connect(&FlowControl::Instance(), &FlowControl::hideAlertForm, [this]()
...@@ -75,8 +73,22 @@ MainWindow::MainWindow(QWidget *parent) : ...@@ -75,8 +73,22 @@ MainWindow::MainWindow(QWidget *parent) :
// 详情窗口 // 详情窗口
m_detailForm = new DetailForm(this); m_detailForm = new DetailForm(this);
// 初始化界面 // 日结窗口
m_dailyForm = new DailyForm(this);
connect(ui->main_btnRJ, &QPushButton::clicked, []()
{
FlowControl::Instance().GetDailyInfo();
});
connect(&FlowControl::Instance(), &FlowControl::showDailyForm, [this](QList<DailyInfo> infos)
{
m_dailyForm->move(pos());
m_dailyForm->InitData(infos);
m_dailyForm->show();
});
// 界面无边框&置顶
setWindowFlags(windowFlags() | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); setWindowFlags(windowFlags() | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
// 隐藏部分TAB页不需要的列
ui->main_tableDCL->setColumnHidden(7, true); ui->main_tableDCL->setColumnHidden(7, true);
ui->main_tableDCL->setColumnHidden(8, true); ui->main_tableDCL->setColumnHidden(8, true);
ui->main_tableYCL->setColumnHidden(7, true); ui->main_tableYCL->setColumnHidden(7, true);
...@@ -90,9 +102,9 @@ MainWindow::MainWindow(QWidget *parent) : ...@@ -90,9 +102,9 @@ MainWindow::MainWindow(QWidget *parent) :
table->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); table->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
table->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents); table->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
table->horizontalHeader()->setFixedHeight(35); table->horizontalHeader()->setFixedHeight(35);
table->hide(); table->hide();
} }
// 先将部分功能禁用(登陆后可以使用)
ui->main_btnMDGL->setEnabled(false); ui->main_btnMDGL->setEnabled(false);
ui->main_btnSPGL->setEnabled(false); ui->main_btnSPGL->setEnabled(false);
ui->main_btnRJ->setEnabled(false); ui->main_btnRJ->setEnabled(false);
...@@ -109,11 +121,18 @@ MainWindow::MainWindow(QWidget *parent) : ...@@ -109,11 +121,18 @@ MainWindow::MainWindow(QWidget *parent) :
m_trayIcon = new QSystemTrayIcon(QIcon(":fm.ico"), this); m_trayIcon = new QSystemTrayIcon(QIcon(":fm.ico"), this);
QMenu* menu = new QMenu(this); QMenu* menu = new QMenu(this);
menu->setObjectName("trayMenu"); menu->setObjectName("trayMenu");
QAction *acShow = new QAction("显示主界面", this);
connect(acShow, &QAction::triggered, [this]
{
m_floatForm->hide();
this->show();
});
QAction *acQuit = new QAction("退出", this); QAction *acQuit = new QAction("退出", this);
connect(acQuit, &QAction::triggered, [] connect(acQuit, &QAction::triggered, []
{ {
qApp->exit(0); qApp->exit(0);
}); });
menu->addAction(acShow);
menu->addAction(acQuit); menu->addAction(acQuit);
m_trayIcon->setContextMenu(menu); m_trayIcon->setContextMenu(menu);
m_trayIcon->show(); m_trayIcon->show();
...@@ -144,7 +163,7 @@ void MainWindow::_GetOrderAdditional(OrderObject *orderObj, QTableWidget *&table ...@@ -144,7 +163,7 @@ void MainWindow::_GetOrderAdditional(OrderObject *orderObj, QTableWidget *&table
if(orderType == 3 || orderType == 4) if(orderType == 3 || orderType == 4)
{ {
// 已核销 // 已核销
if(orderStatus == 4) if(orderStatus == 6)
{ {
statusDesc = "已核销"; statusDesc = "已核销";
table = ui->main_tableYWC; table = ui->main_tableYWC;
...@@ -364,3 +383,8 @@ void MainWindow::on_main_btnDown_clicked() ...@@ -364,3 +383,8 @@ void MainWindow::on_main_btnDown_clicked()
QTableWidget *table = findChild<QTableWidget*>(m_curtTabBtn->property("table").toString()); QTableWidget *table = findChild<QTableWidget*>(m_curtTabBtn->property("table").toString());
table->verticalScrollBar()->setValue(table->verticalScrollBar()->value()+1); table->verticalScrollBar()->setValue(table->verticalScrollBar()->value()+1);
} }
void MainWindow::on_main_btnSPGL_clicked()
{
}
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "alertform.h" #include "alertform.h"
#include "floatform.h" #include "floatform.h"
#include "detailform.h" #include "detailform.h"
#include "dailyform.h"
#include <QMainWindow> #include <QMainWindow>
#include <QPushButton> #include <QPushButton>
...@@ -39,6 +40,8 @@ private: ...@@ -39,6 +40,8 @@ private:
FloatForm *m_floatForm=nullptr; FloatForm *m_floatForm=nullptr;
// 详情窗口 // 详情窗口
DetailForm *m_detailForm=nullptr; DetailForm *m_detailForm=nullptr;
// 日结窗口
DailyForm *m_dailyForm=nullptr;
// 托盘 // 托盘
QSystemTrayIcon* m_trayIcon=nullptr; QSystemTrayIcon* m_trayIcon=nullptr;
...@@ -75,6 +78,7 @@ private slots: ...@@ -75,6 +78,7 @@ private slots:
void on_main_btnHide_clicked(); void on_main_btnHide_clicked();
void on_main_btnUp_clicked(); void on_main_btnUp_clicked();
void on_main_btnDown_clicked(); void on_main_btnDown_clicked();
void on_main_btnSPGL_clicked();
}; };
#endif // MAINWINDOW_H #endif // MAINWINDOW_H
...@@ -138,6 +138,7 @@ class OrderObject : public QObject ...@@ -138,6 +138,7 @@ class OrderObject : public QObject
Q_PROPERTY (QString courier_name READ getcourier_name WRITE setcourier_name) Q_PROPERTY (QString courier_name READ getcourier_name WRITE setcourier_name)
Q_PROPERTY (QString courier_phone READ getcourier_phone WRITE setcourier_phone) Q_PROPERTY (QString courier_phone READ getcourier_phone WRITE setcourier_phone)
Q_PROPERTY (QStringList records READ getrecords WRITE setrecords) Q_PROPERTY (QStringList records READ getrecords WRITE setrecords)
Q_PROPERTY (QStringList dis_desc READ getdis_desc WRITE setdis_desc)
Q_PROPERTY (int total_amount READ gettotal_amount WRITE settotal_amount) Q_PROPERTY (int total_amount READ gettotal_amount WRITE settotal_amount)
public: public:
...@@ -267,6 +268,9 @@ private: ...@@ -267,6 +268,9 @@ private:
inline QStringList getrecords(){ return records; } inline QStringList getrecords(){ return records; }
inline void setrecords(const QStringList& v){ records = v; } inline void setrecords(const QStringList& v){ records = v; }
inline QStringList getdis_desc(){ return dis_desc; }
inline void setdis_desc(const QStringList& v){ dis_desc = v; }
inline int gettotal_amount(){ return total_amount; } inline int gettotal_amount(){ return total_amount; }
inline void settotal_amount(const int& v){ total_amount = v; } inline void settotal_amount(const int& v){ total_amount = v; }
...@@ -312,6 +316,7 @@ public: ...@@ -312,6 +316,7 @@ public:
QString courier_phone; // 配送员手机号 QString courier_phone; // 配送员手机号
QStringList records; // 订单操作纪录 QStringList records; // 订单操作纪录
int total_amount; // 商品总数 int total_amount; // 商品总数
QStringList dis_desc; // 满赠描述
QList<DishObject*> products; // 子商品 QList<DishObject*> products; // 子商品
// 自定义属性 // 自定义属性
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
#include <QTimer> #include <QTimer>
#include "configManage.h" #include "configManage.h"
#include <QDebug>
FmHttp::FmHttp() FmHttp::FmHttp()
{ {
// 初始化Httprequest // 初始化Httprequest
...@@ -69,15 +71,16 @@ void FmHttp::handle(QNetworkReply *reply, const int &timeout, const std::functio ...@@ -69,15 +71,16 @@ void FmHttp::handle(QNetworkReply *reply, const int &timeout, const std::functio
timer = new QTimer; timer = new QTimer;
timer->setSingleShot(true); timer->setSingleShot(true);
QObject::connect( timer, &QTimer::timeout, [ timer, onTimeout ]() QObject::connect( timer, &QTimer::timeout, [reply, timer, onTimeout ]()
{ {
reply->deleteLater();
onTimeout(); onTimeout();
timer->deleteLater(); timer->deleteLater();
} ); } );
timer->start( timeout ); timer->start( timeout );
} }
QObject::connect( reply, &QNetworkReply::finished, [ reply, timer, onFinished ]() QObject::connect( reply, &QNetworkReply::finished, [ this, reply, timer, onFinished ]()
{ {
if ( timer->isActive() ) if ( timer->isActive() )
{ {
...@@ -87,10 +90,12 @@ void FmHttp::handle(QNetworkReply *reply, const int &timeout, const std::functio ...@@ -87,10 +90,12 @@ void FmHttp::handle(QNetworkReply *reply, const int &timeout, const std::functio
{ {
onFinished( reply->readAll() ); onFinished( reply->readAll() );
} }
reply->deleteLater();
} ); } );
QObject::connect( reply, ( void( QNetworkReply::* )( QNetworkReply::NetworkError ) )&QNetworkReply::error, [ reply, timer, onError ](const QNetworkReply::NetworkError &code) QObject::connect( reply, ( void( QNetworkReply::* )( QNetworkReply::NetworkError ) )&QNetworkReply::error, [ this, reply, timer, onError ](const QNetworkReply::NetworkError &code)
{ {
reply->deleteLater();
if ( timer->isActive() ) if ( timer->isActive() )
{ {
timer->stop(); timer->stop();
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <QNetworkRequest> #include <QNetworkRequest>
#include <QNetworkAccessManager> #include <QNetworkAccessManager>
#include <QNetworkReply> #include <QNetworkReply>
#include <QMutex>
class FmHttp class FmHttp
{ {
...@@ -14,12 +15,12 @@ public: ...@@ -14,12 +15,12 @@ public:
inline void SetRequest(const QNetworkRequest &request){ m_request = request; } inline void SetRequest(const QNetworkRequest &request){ m_request = request; }
bool Post(const QByteArray &appendData, QByteArray &target, const int &timeout = 30000); bool Post(const QByteArray &appendData, QByteArray &target, const int &timeout = 10000);
void Post(const QByteArray &appendData, void Post(const QByteArray &appendData,
const std::function< void(const QByteArray &data) > &onFinished, const std::function< void(const QByteArray &data) > &onFinished,
const std::function< void(const QNetworkReply::NetworkError &code) > &onError, const std::function< void(const QNetworkReply::NetworkError &code) > &onError,
const int &timeout = 20000); const int &timeout = 10000);
private: private:
void handle(QNetworkReply *reply, const int &timeout, void handle(QNetworkReply *reply, const int &timeout,
...@@ -30,6 +31,7 @@ private: ...@@ -30,6 +31,7 @@ private:
private: private:
QNetworkRequest m_request; QNetworkRequest m_request;
QNetworkAccessManager m_manage; QNetworkAccessManager m_manage;
QMutex m_mutex;
}; };
#endif // FMNET_H #endif // FMNET_H
...@@ -50,9 +50,9 @@ public: ...@@ -50,9 +50,9 @@ public:
* 参数:NULL * 参数:NULL
* 返回:保存天数 * 返回:保存天数
* */ * */
inline int logHoldTime() inline int logHoldDays()
{ {
return m_clientIni->value("log/holdTime").toInt(); return m_clientIni->value("log/holdDays").toInt();
} }
/* 功能:获取TcpServer监听端口 /* 功能:获取TcpServer监听端口
...@@ -123,6 +123,14 @@ public: ...@@ -123,6 +123,14 @@ public:
* */ * */
QString printerParameter(); QString printerParameter();
/* 功能:获取数据库路径
* 参数:NULLi
* 返回:数据库路径
* */
inline QString databasePath(){
return m_userIni->value("database/path").toString();
}
private: private:
ConfigManage(); ConfigManage();
......
...@@ -126,3 +126,11 @@ QByteArray DataManage::refuseRefundOrderData(const QString &token, const QString ...@@ -126,3 +126,11 @@ QByteArray DataManage::refuseRefundOrderData(const QString &token, const QString
json.insert("pos_version", g_posVersion); json.insert("pos_version", g_posVersion);
return QJsonDocument(json).toJson().simplified(); return QJsonDocument(json).toJson().simplified();
} }
QByteArray DataManage::pullDailyData(const QString &token)
{
QJsonObject json;
json.insert("reqtype", 260);
json.insert("token", token);
return QJsonDocument(json).toJson().simplified();
}
...@@ -18,6 +18,8 @@ public: ...@@ -18,6 +18,8 @@ public:
static QByteArray merchantRefundOrderData(const QString& token, const QString& orderId, const QString& reason); static QByteArray merchantRefundOrderData(const QString& token, const QString& orderId, const QString& reason);
static QByteArray agreeRefundOrderData(const QString& token, const QString& orderId, const QString& reason); static QByteArray agreeRefundOrderData(const QString& token, const QString& orderId, const QString& reason);
static QByteArray refuseRefundOrderData(const QString& token, const QString& orderId, const QString& reason); static QByteArray refuseRefundOrderData(const QString& token, const QString& orderId, const QString& reason);
static QByteArray pullDailyData(const QString& token);
}; };
#endif // DATAMANAGE_H #endif // DATAMANAGE_H
...@@ -91,6 +91,17 @@ namespace Util { ...@@ -91,6 +91,17 @@ namespace Util {
QString Penny2Dollar(const int penny); QString Penny2Dollar(const int penny);
} }
// 日结渠道信息
typedef struct DailyInfo
{
QString channel;
int total_number;
int total_fee;
int refund_number;
int refund_total_fee;
int total_projected_revenue;
}DailyInfo;
#endif // UTIL_H #endif // UTIL_H
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
#ifdef freemud #ifdef freemud
#define PRODUCT_VERSION BASE_VERSION "0.0" #define PRODUCT_VERSION BASE_VERSION "0.0"
#elif kesf #elif kesf
#define PRODUCT_VERSION BASE_VERSION "0.1" #define PRODUCT_VERSION BASE_VERSION "0.7"
#elif miy #elif miy
#define PRODUCT_VERSION BASE_VERSION "0.0" #define PRODUCT_VERSION BASE_VERSION "0.0"
#elif shanl #elif shanl
......
...@@ -8,7 +8,7 @@ bDishesManagement=false ...@@ -8,7 +8,7 @@ bDishesManagement=false
[log] [log]
;保存时间单位天 ;保存时间单位天
holdTime=20 holdDays=20
;外卖日志前缀 ;外卖日志前缀
prefix=wm prefix=wm
......
...@@ -217,4 +217,45 @@ ...@@ -217,4 +217,45 @@
#detail_btnClose:pressed,#detail_btnRefund:pressed #detail_btnClose:pressed,#detail_btnRefund:pressed
{ {
background-color: #cc3a41; background-color: #cc3a41;
}
/**********日结表样式**********/
#daily_wdgHead
{
background-color: rgb(121, 121, 121);
}
#daily_wdgBody
{
background-color: #ffffff;
}
#daily_labDate
{
color: rgb(255, 131, 74);
}
#daily_labStoreName,#daily_slabSKQK,#daily_slabTKQK
{
border: 0px;
border-bottom: 1px dashed #919191;
}
#daily_table0,#daily_table1
{
color: #878787;
}
#daily_wdgBody QHeaderView::section,#daily_wdgBody QHeaderView::section
{
border: 0px;
background: #ffffff;
color: #878787;
}
#daily_btnClose,#daily_btnPrint
{
background-color: #ffffff;
border: 1px solid rgb(121, 121, 121);
border-radius: 4px;
}
#daily_btnClose:pressed,#daily_btnPrint:pressed
{
background-color: rgb(121, 121, 121);
} }
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment