Procházet zdrojové kódy

更新windows接单软件的版本,把推送改成MQTT

张洋 před 1 rokem
rodič
revize
1f111da027

binární
bin/Win32/Release/setup/lewaimai_pos_windows_setup_1.0.4.2.exe


+ 1 - 1
bin/Win32/Release/setup/乐外卖接单软件安装脚本.nsi

@@ -2,7 +2,7 @@
 
 ; HM NIS Edit Wizard helper defines
 !define PRODUCT_NAME "乐外卖接单软件"
-!define PRODUCT_VERSION "1.0.4.2"
+!define PRODUCT_VERSION "1.0.5.0"
 !define PRODUCT_PUBLISHER "深圳市迅享科技有限公司"
 !define PRODUCT_WEB_SITE "https://www.lewaimai.com"
 !define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\${PRODUCT_NAME}.exe"

+ 139 - 0
lewaimai_pos_windows/helper/CLewaimaiJson.cpp

@@ -0,0 +1,139 @@
+#include "../pch/pch.h"
+#include "CLewaimaiJson.h"
+
+CLewaimaiJson::CLewaimaiJson()
+{
+}
+
+
+CLewaimaiJson::~CLewaimaiJson()
+{
+}
+
+std::string CLewaimaiJson::JsonToString(const rapidjson::Value& valObj)
+{
+	rapidjson::StringBuffer sbBuf;
+	rapidjson::Writer<rapidjson::StringBuffer> jWriter(sbBuf);
+	valObj.Accept(jWriter);
+	return std::string(sbBuf.GetString());
+}
+
+rapidjson::Document CLewaimaiJson::StringToJson(std::string jsonString, rapidjson::Document::AllocatorType &allocator)
+{
+	rapidjson::Document document(&allocator);
+	document.Parse(jsonString.c_str());
+
+	if (document.HasParseError())
+	{
+		return false;
+	}
+
+	return document;
+}
+
+//把一个数组转化成json变量,数组的每个元素是一个map,map的key是json的名字,map的value是json的value
+rapidjson::Document CLewaimaiJson::ParamArrayToJson(std::vector<std::map<string, string>> paramArray, rapidjson::Document::AllocatorType &allocator)
+{
+	rapidjson::Document doc(&allocator);
+
+	doc.SetArray();
+
+	for (std::vector<std::map<string, string>>::iterator it = paramArray.begin(); it != paramArray.end(); it++)
+	{
+		rapidjson::Value array_object(rapidjson::kObjectType);
+
+		for (std::map<string, string>::iterator m_it = it->begin(); m_it != it->end(); m_it++)
+		{
+			Value key;
+			Value value;
+			key.SetString(m_it->first.c_str(), m_it->first.length(), allocator);
+			value.SetString(m_it->second.c_str(), m_it->second.length(), allocator);
+
+			array_object.AddMember(key, value, allocator);
+		}
+
+		doc.PushBack(array_object, allocator);
+	}
+
+	return doc;
+}
+
+//把一个数组转化成json字符串,数组的每个元素是一个map,map的key是json的名字,map的value是json的value
+std::string CLewaimaiJson::ParamArrayToJsonstring(std::vector<std::map<string, string>> paramArray)
+{
+	rapidjson::Document doc;
+	rapidjson::Document::AllocatorType &allocator = doc.GetAllocator(); //获取分配器
+
+	Value& data = CLewaimaiJson::ParamArrayToJson(paramArray, allocator);
+
+	rapidjson::StringBuffer buffer;
+	rapidjson::Writer<StringBuffer> writer(buffer);
+	data.Accept(writer);
+
+	std::string result = buffer.GetString();
+
+	return result;
+}
+
+//把一个map转化成json字符串,map的key是json的名字,map的value是json的value
+std::string CLewaimaiJson::ParamMapToJsonstring(std::map<string, string> param)
+{
+	rapidjson::Document doc;
+	rapidjson::Document::AllocatorType &allocator = doc.GetAllocator(); //获取分配器
+
+	doc.SetObject();
+
+	for (std::map<string, string>::iterator m_it = param.begin(); m_it != param.end(); m_it++)
+	{
+		Value key;
+		Value value;
+		key.SetString(m_it->first.c_str(), m_it->first.length(), allocator);
+		value.SetString(m_it->second.c_str(), m_it->second.length(), allocator);
+
+		doc.AddMember(key, value, allocator);
+	}
+
+	rapidjson::StringBuffer buffer;
+	rapidjson::Writer<StringBuffer> writer(buffer);
+	doc.Accept(writer);
+
+	std::string result = buffer.GetString();
+
+	return result;
+}
+
+std::string CLewaimaiJson::ToString(const rapidjson::Value& valObj)
+{
+	if (valObj.IsString())
+	{
+		return valObj.GetString();
+	}
+	else if (valObj.IsInt())
+	{
+		return to_string(valObj.GetInt());
+	}
+	else if (valObj.IsDouble())
+	{
+		return to_string(valObj.GetDouble());
+	}
+	else
+	{
+		return "";
+	}
+}
+
+int CLewaimaiJson::ToInt(const rapidjson::Value& valObj)
+{
+	if (valObj.IsString())
+	{
+		return atoi(std::string(valObj.GetString()).c_str());
+	}
+	else if (valObj.IsInt())
+	{
+		return valObj.GetInt();
+	}
+	else
+	{
+		return 0;
+	}
+}

+ 42 - 0
lewaimai_pos_windows/helper/CLewaimaiJson.h

@@ -0,0 +1,42 @@
+#pragma once
+
+#include <codecvt>
+#include <iostream>
+#include <sstream>
+#include <regex>
+#include <string>
+
+//json库
+#include "rapidjson/document.h"
+#include "rapidjson/prettywriter.h"  
+#include "rapidjson/writer.h"
+#include "rapidjson/stringbuffer.h"
+
+using namespace rapidjson;
+
+class CLewaimaiJson
+{
+public:
+	CLewaimaiJson();
+	~CLewaimaiJson();
+
+	static std::string JsonToString(const rapidjson::Value& valObj);
+
+	static rapidjson::Document StringToJson(std::string jsonString, rapidjson::Document::AllocatorType &allocator);
+
+	//把一个数组转化成json变量,数组的每个元素是一个map,map的key是json的名字,map的value是json的value
+	static rapidjson::Document ParamArrayToJson(std::vector<std::map<string, string>> paramArray, rapidjson::Document::AllocatorType &allocator);
+
+	//把一个数组转化成json字符串,数组的每个元素是一个map,map的key是json的名字,map的value是json的value
+	static std::string ParamArrayToJsonstring(std::vector<std::map<string,string>> paramArray);
+
+	//把一个map转化成json字符串,map的key是json的名字,map的value是json的value
+	static std::string ParamMapToJsonstring(std::map<string, string> param);
+
+	//把json值转换成字符串类型,兼容各种后端返回类型,避免报错
+	static std::string ToString(const rapidjson::Value& valObj);
+
+	//把json值转换成整数类型,兼容各种后端返回类型,避免报错
+	static int ToInt(const rapidjson::Value& valObj);
+};
+

+ 3 - 1
lewaimai_pos_windows/lewaimai_pos_windows.vcxproj

@@ -180,7 +180,7 @@ copy $(SolutionDir)res\icon\ $(SolutionDir)bin\$(Platform)\$(Configuration)\$(Pr
       <OptimizeReferences>true</OptimizeReferences>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <AdditionalLibraryDirectories>$(SolutionDir)lib\release</AdditionalLibraryDirectories>
-      <AdditionalDependencies>dbghelp.lib;winmm.lib;setupapi.lib;AdvAPI32.lib;Shell32.lib;user32.lib;kernel32.lib;Gdi32.lib;winspool.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;version.lib;sqlite3.lib;DuiLib_u.lib;log4cplusU.lib;libboost_date_time-vc141-mt-s-x32-1_70.lib;libboost_regex-vc141-mt-s-x32-1_70.lib;libqrencode.lib;libcurl.lib;alibabacloud-oss-cpp-sdk.lib;libssl.lib;libcrypto.lib;paho-mqttpp3-static.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>dbghelp.lib;winmm.lib;setupapi.lib;AdvAPI32.lib;Shell32.lib;user32.lib;kernel32.lib;Gdi32.lib;winspool.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;version.lib;sqlite3.lib;DuiLib_u.lib;log4cplusU.lib;libboost_date_time-vc141-mt-s-x32-1_70.lib;libboost_regex-vc141-mt-s-x32-1_70.lib;libqrencode.lib;libcurl.lib;alibabacloud-oss-cpp-sdk.lib;libssl.lib;libcrypto.lib;paho-mqtt3a-static.lib;paho-mqttpp3-static.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalOptions>/ignore:4099 %(AdditionalOptions)</AdditionalOptions>
     </Link>
     <PostBuildEvent>
@@ -229,6 +229,7 @@ copy $(ProjectDir)conf\ $(SolutionDir)bin\$(Platform)\$(Configuration)\conf\</Co
     </PostBuildEvent>
   </ItemDefinitionGroup>
   <ItemGroup>
+    <ClInclude Include="helper\CLewaimaiJson.h" />
     <ClInclude Include="network\CMqttClient.h" />
     <ClInclude Include="tool\CExceptionDmp.h" />
     <ClInclude Include="helper\CBitmapHelper.h" />
@@ -261,6 +262,7 @@ copy $(ProjectDir)conf\ $(SolutionDir)bin\$(Platform)\$(Configuration)\conf\</Co
     <ClInclude Include="control\OrderListUI.h" />
   </ItemGroup>
   <ItemGroup>
+    <ClCompile Include="helper\CLewaimaiJson.cpp" />
     <ClCompile Include="network\CMqttClient.cpp" />
     <ClCompile Include="tool\CExceptionDmp.cpp" />
     <ClCompile Include="helper\CBitmapHelper.cpp" />

+ 6 - 0
lewaimai_pos_windows/lewaimai_pos_windows.vcxproj.filters

@@ -105,6 +105,9 @@
     <ClInclude Include="network\CMqttClient.h">
       <Filter>头文件</Filter>
     </ClInclude>
+    <ClInclude Include="helper\CLewaimaiJson.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="pch\pch.cpp">
@@ -191,6 +194,9 @@
     <ClCompile Include="network\CMqttClient.cpp">
       <Filter>源文件</Filter>
     </ClCompile>
+    <ClCompile Include="helper\CLewaimaiJson.cpp">
+      <Filter>源文件</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <Image Include="resource\lewaimai.ico">

+ 15 - 0
lewaimai_pos_windows/network/CLewaimaiHttpClient.cpp

@@ -7,6 +7,21 @@ CLewaimaiHttpClient CLewaimaiHttpClient::m_client;
 
 CLewaimaiHttpClient::CLewaimaiHttpClient()
 {
+#ifdef _DEBUG
+	m_env = DEV;
+#else
+	m_env = RELEASE;
+#endif	
+
+	if (m_env == DEV)
+	{
+		m_url = "https://api-beta.lewaimai.com/seller";
+	}
+	else if (m_env == RELEASE)
+	{
+		m_url = "https://api.lewaimai.com/seller";
+	}
+
 	m_username = CSetting::getUsername();
 	m_password = CSetting::getPassword();
 }

+ 10 - 2
lewaimai_pos_windows/network/CLewaimaiHttpClient.h

@@ -8,6 +8,12 @@ public:
 	CLewaimaiHttpClient();
 	~CLewaimaiHttpClient();
 
+	enum Env
+	{
+		DEV,
+		RELEASE
+	};
+
 public:
 	static void Init(std::string username, std::string password);
 
@@ -26,12 +32,14 @@ private:
 	std::string m_username;
 	std::string m_password;
 
-	std::string m_url = "https://api.lewaimai.com/seller";
+	std::string m_url;
 
 	//这个是当前登陆的账号对应的店铺ID(如果是连锁店账号就是返回的第一个店铺),主要用于厨房打印的分类打印时候用于获取商品分类
 	std::string m_shop_id;
 
 	//如果是连锁店账号,这个用来存储多个店铺ID
 	std::string m_shop_ids;
-};
 
+	//当前运行环境
+	Env m_env;
+};

+ 30 - 63
lewaimai_pos_windows/network/CMqttClient.cpp

@@ -12,17 +12,17 @@
 CMqttClient::CMqttClient(HWND hwnd)
 {
     m_hwnd = hwnd;
-
-    m_async_client = new mqtt::async_client(SERVER_ADDRESS, CLIENT_ID);
 }
 
 CMqttClient::~CMqttClient()
 {
-    delete m_async_client;
+
 }
 
 void CMqttClient::Start()
 {
+	m_is_running = true;
+
     m_nStopNum = 0;
 
     //处理Mqtt消息接收
@@ -96,6 +96,9 @@ void CMqttClient::Stop()
 
 void CMqttClient::Run()
 {
+	m_client_id = "GID_LEWAIMAI_WINDOWS_POS@@@" + CSetting::getUsername();
+	m_async_client = new mqtt::async_client(m_server_address, m_client_id);
+
     // A subscriber often wants the server to remember its messages when its
     // disconnected. In that case, it needs a unique ClientID and a
     // non-clean session.
@@ -120,13 +123,12 @@ void CMqttClient::Run()
     }
     catch(const mqtt::exception& exc)
     {
-        std::string info = "ERROR: Unable to connect to MQTT server:" + SERVER_ADDRESS + exc.get_message();
+        std::string info = "ERROR: Unable to connect to MQTT server:" + m_server_address + exc.get_message();
 
         LOG_INFO(info.c_str());
         return;
     }
 
-    m_is_running = true;
     while(m_is_running)
     {
 		//一直循环,一直工作,等待接收消息
@@ -145,6 +147,9 @@ void CMqttClient::Run()
         return;
     }
 
+	//销毁客户端
+	delete m_async_client;
+
     AddStopNum();
 
     return;
@@ -224,11 +229,11 @@ void CMqttClient::connected(const std::string& cause)
 {
 	m_is_mqtt_connected = true;
 
-    std::string info = "Connection success, nSubscribing to topic " + TOPIC + " for client " + CLIENT_ID + " using QoS" + to_string(MQTT_QOS);
+    std::string info = "Connection success, nSubscribing to topic " + m_topic + " for client " + m_client_id + " using QoS" + to_string(MQTT_QOS);
     LOG_INFO(info.c_str());
 
 	//不管是第一次连接,还是重连,都订阅一次
-    m_async_client->subscribe(TOPIC, MQTT_QOS, nullptr, *this);
+    m_async_client->subscribe(m_topic, MQTT_QOS, nullptr, *this);
 }
 
 void CMqttClient::connection_lost(const std::string& cause)
@@ -269,53 +274,18 @@ void CMqttClient::delivery_complete(mqtt::delivery_token_ptr token)
 
 void CMqttClient::CalUserInfo()
 {
-    //实例 ID,购买后从控制台获取
-    char* instanceId = "post-cn-x0r3kjlsy02";
-
-    //测试收发消息的 Topic
-    char* topic = "lewaimai_windows_pos";
-
-    //接入点域名,从控制台获取
-    char* host = "post-cn-x0r3kjlsy02.mqtt.aliyuncs.com";
-
-    //客户端使用的 GroupID,从控制台申请
-    char* groupId = "GID_LEWAIMAI_WINDOWS_POS";
-
-    //客户端 ClientID 的后缀,由业务自行指定,只需要保证全局唯一即可
-    char* deviceId = "abcde";
-
-    /**
-      * 账号 accesskey,从账号系统控制台获取
-      * 阿里云账号AccessKey拥有所有API的访问权限,建议您使用RAM用户进行API访问或日常运维。
-      * 强烈建议不要把AccessKey ID和AccessKey Secret保存到工程代码里,否则可能导致AccessKey泄露,威胁您账号下所有资源的安全。
-      * 可以把AccessKey ID和AccessKey Secret保存在环境变量。运行本代码示例之前,请先配置环境变量MQTT_AK_ENV和MQTT_SK_ENV
-      * 例如:export MQTT_AK_ENV=<access_key_id>
-      *      export MQTT_SK_ENV=<access_key_secret>
-      * 需要将<access_key_id>替换为已准备好的AccessKey ID,<access_key_secret>替换为AccessKey Secret。
-    */
-    char* accessKey = "LTAI4G5oikJPMfhq5PuW26qu";
-    //账号 SecretKey,从账号控制台获取
-    char* secretKey = "LsIxqepi2o3X0b17FSa7JaANfIMDVY";
-
     unsigned char tempData[100];
     unsigned int len = 0;
 
-    //ClientID要求使用 GroupId 和 DeviceId 拼接而成,长度不得超过64个字符
-    char clientIdUrl[64];
-    sprintf(clientIdUrl, "%s@@@%s", groupId, deviceId);
-
-    const unsigned char* abc = (unsigned char*)clientIdUrl;
-
     //username和 Password 签名模式下的设置方法,参考文档 https://help.aliyun.com/document_detail/48271.html?spm=a2c4g.11186623.6.553.217831c3BSFry7
-    HMAC(EVP_sha1(), secretKey, strlen(secretKey), abc, strlen(clientIdUrl), tempData, &len);
+    HMAC(EVP_sha1(), m_secretKey.c_str(), m_secretKey.length(), (unsigned char*)m_client_id.c_str(), m_client_id.length(), tempData, &len);
 
     char resultData[100];
     int passWordLen = EVP_EncodeBlock((unsigned char*)resultData, tempData, len);
     resultData[passWordLen] = '\0';
-    printf("passWord is %s", resultData);
 
     char userNameData[128];
-    sprintf(userNameData, "Signature|%s|%s", accessKey, instanceId);
+    sprintf(userNameData, "Signature|%s|%s", m_accessKey.c_str(), m_instanceId.c_str());
 
     m_UserName = userNameData;
     m_Password = resultData;
@@ -332,20 +302,17 @@ void CMqttClient::HandleMessage(std::string message)
         return;
     }
 
-    std::string type;
-    if(document["msg_type"].IsInt())
-    {
-        type = to_string(document["msg_type"].GetInt());
-    }
-    else
-    {
-        type = document["msg_type"].GetString();
-    }
+	//这个可以到时候用来判断是否消息过期,暂时不处理
+	std::string timestamp = CLewaimaiJson::ToString(document["timestamp"]);
+
+	rapidjson::Value& data = document["data"];
+
+	std::string type = CLewaimaiJson::ToString(data["msg_type"]);
 
     if(type == "1")
     {
-        std::string order_id = document["waimai_order_id"].GetString();
-        std::string order_no = document["waimai_order_no"].GetString();
+        std::string order_id = data["waimai_order_id"].GetString();
+        std::string order_no = data["waimai_order_no"].GetString();
 
         //新订单来了,首先判断是否要语音提醒
         if(CSetting::GetParam("setting_is_new_waimai_voice") == "1")
@@ -382,8 +349,8 @@ void CMqttClient::HandleMessage(std::string message)
     {
         AddVoice(4);
 
-        std::string order_id = document["waimai_order_id"].GetString();
-        std::string order_no = document["waimai_order_no"].GetString();
+        std::string order_id = data["waimai_order_id"].GetString();
+        std::string order_no = data["waimai_order_no"].GetString();
 
         AddPinter(order_id, order_no, 1, 3);
     }
@@ -459,7 +426,7 @@ void CMqttClient::AddChufangPrinter(CWaimaiOrder order)
 
 void CMqttClient::HandleVoice()
 {
-    while(m_is_work)
+    while(m_is_running)
     {
         m_voice_mutex.lock();
 
@@ -506,7 +473,7 @@ void CMqttClient::HandleVoice()
 
 void CMqttClient::HandleConfirm()
 {
-    while(m_is_work)
+    while(m_is_running)
     {
         m_confirm_mutex.lock();
 
@@ -532,7 +499,7 @@ void CMqttClient::HandleConfirm()
 
 void CMqttClient::HandlePrinter()
 {
-    while(m_is_work)
+    while(m_is_running)
     {
         m_printer_mutex.lock();
 
@@ -641,7 +608,7 @@ void CMqttClient::HandlePrinter()
 
 void CMqttClient::HandleShouyinPrinter()
 {
-    while(m_is_work)
+    while(m_is_running)
     {
         m_shouyin_printer_mutex.lock();
 
@@ -668,7 +635,7 @@ void CMqttClient::HandleShouyinPrinter()
 
 void CMqttClient::HandleBiaoqianPrinter()
 {
-    while(m_is_work)
+    while(m_is_running)
     {
         m_biaoqian_printer_mutex.lock();
 
@@ -695,7 +662,7 @@ void CMqttClient::HandleBiaoqianPrinter()
 
 void CMqttClient::HandleChufangPrinter()
 {
-    while(m_is_work)
+    while(m_is_running)
     {
         m_chufang_printer_mutex.lock();
 

+ 10 - 8
lewaimai_pos_windows/network/CMqttClient.h

@@ -36,9 +36,13 @@ class CMqttClient : public virtual mqtt::callback,
 {
 private:
     //定义一些常量
-    std::string SERVER_ADDRESS = "post-cn-x0r3kjlsy02.mqtt.aliyuncs.com";
-    std::string CLIENT_ID = "GID_LEWAIMAI_WINDOWS_POS@@@abcde";
-    std::string TOPIC = "lewaimai_windows_pos";
+    std::string m_server_address = "post-cn-x0r3kjlsy02.mqtt.aliyuncs.com";
+	std::string m_instanceId = "post-cn-x0r3kjlsy02";
+    std::string m_topic = "lewaimai_windows_pos";
+	std::string m_accessKey = "LTAI4G5oikJPMfhq5PuW26qu";
+	std::string m_secretKey = "LsIxqepi2o3X0b17FSa7JaANfIMDVY";
+
+	std::string m_client_id;
 
     //要保证可靠传输
     int MQTT_QOS = 2;
@@ -46,9 +50,6 @@ private:
     //一直重试
     int N_RETRY_ATTEMPTS = 1000000;
 
-    //工作状态
-    bool m_is_running = false;
-
     //连接阿里云的用户身份,计算出来的
     std::string m_UserName;
     std::string m_Password;
@@ -64,9 +65,10 @@ private:
 
 	bool m_is_mqtt_connected = false;
 
-    //下面是消息处理相关的
-    bool m_is_work;
+	//工作状态
+	bool m_is_running = false;
 
+	//下面是消息处理相关的
     int m_nStopNum = 0;
     std::mutex m_nStopNumMutex;
 

+ 1 - 0
lewaimai_pos_windows/pch/pch.h

@@ -69,6 +69,7 @@ using namespace rapidjson;
 #include "../helper/CRandomHelper.h"
 #include "../helper/CSystem.h"
 #include "../helper/CLewaimaiString.h"
+#include "../helper/CLewaimaiJson.h"
 
 #include "../tool/CLewaimaiLog.h"
 #include "../tool/CLewaimaiTime.h"

binární
lewaimai_pos_windows/resource/lewaimai_pos_windows.aps


binární
lewaimai_pos_windows/resource/lewaimai_pos_windows.rc


+ 3 - 3
lewaimai_pos_windows/wnd/CMainWnd.cpp

@@ -2218,9 +2218,9 @@ void CMainWnd::InitSettingStatus()
 		{
 			rapidjson::Value& v_row_i = v_rows[i];
 
-			std::string type_id = v_row_i["type_id"].GetString();
-			//std::string shopname = v_row_i["shopname"].GetString();
-			std::string shopname = "abcde";
+			std::string type_id = CLewaimaiJson::ToString(v_row_i["type_id"]);
+
+			std::string shopname = CLewaimaiJson::ToString(v_row_i["shopname"]);
 			std::string name = CLewaimaiString::UnicodeToUTF8(L"【") + shopname + CLewaimaiString::UnicodeToUTF8(L"】") + v_row_i["name"].GetString();
 
 			CSetting::AddFoodtype(name, type_id);