zxs 1 mês atrás
pai
commit
ebddd4652b
2 arquivos alterados com 139 adições e 63 exclusões
  1. 5 5
      src/config/config.xml
  2. 134 58
      src/network/http_network.hpp

+ 5 - 5
src/config/config.xml

@@ -4,12 +4,12 @@
         <item id="1" modify_time="2025-06-02 19:53:32" name="管理员" code="admin" password="123456" enable="true" remarks="管理员"/>
     </users>
     <after>
-        <item id="1" modify_time="2025-06-13 16:53:40" value="VggJGwBRnmpSx3dZzCkJtB2+QTs4/DqqdJr00ifspyObshLf68GKNS+K8GwN2YzdMFlK1rwFU1XQnorbU+1YEdl4nBSlGtMIHkSCbp6K92r2hJR7Q9/KYiLSvxaRnXOxbPt23VXljjWHjcZQuDdacSd51xo+qxfXOIWPUbxGLsdPM5d+mXYbNI18nF5NzXrYWbyNGrnQ+wkBn6cASbCsWKtfK1Ud3kDm8v16QDb1fYw=" enable="true" remarks="售后配置信息"/>
+        <item id="1" modify_time="2025-06-23 16:37:40" value="VggJGwBRnmpSx3dZzCkJtB2+QTs4/DqqdJr00ifspyObshLf68GKNS+K8GwN2YzdMFlK1rwFU1XQnorbU+1YEdl4nBSlGtMIHkSCbp6K92r2hJR7Q9/KYiLSvxaRnXOxbPt23VXljjWHjcZQuDdacSd51xo+qxfXOIWPUbxGLsdPM5d+mXYbNI18nF5NzXrYWbyNGrnQ+wkBn6cASbCsWKtfK1Ud3kDm8v16QDb1fYw=" enable="true" remarks="售后配置信息"/>
     </after>
     <general>
-        <item id="4" modify_time="2025-06-12 22:42:29" key="4" value="http://127.0.0.1:8002/api/base/config" enable="true" remarks="配置服务器地址"/>
-        <item id="5" modify_time="2025-06-14 15:54:31" key="1" value="2" enable="true" remarks="售后方式 1:rpc,2:老分布式,3:新分布式"/>
-        <item id="6" modify_time="2025-06-14 15:54:31" key="2" value="1900" enable="true" remarks="RPC售后服务端口"/>
-        <item id="7" modify_time="2025-06-14 15:54:31" key="3" value="http://127.0.0.1:8002/api/after/get_after" enable="true" remarks="获取售后配置数据接口"/>
+        <item id="1" modify_time="2025-06-23 16:38:12" key="1" value="http://127.0.0.1:9004/api/base/config" enable="true" remarks="通用地址配置"/>
+        <item id="2" modify_time="2025-06-23 16:38:12" key="2" value="http://127.0.0.1:9004/api/after/params" enable="true" remarks="参数地址配置"/>
+        <item id="3" modify_time="2025-06-23 16:38:12" key="3" value="1" enable="true" remarks="售后方式 1:rpc,2:老分布式,3:新分布式"/>
+        <item id="4" modify_time="2025-06-23 16:38:12" key="4" value="1900" enable="true" remarks="RPC售后服务端口"/>
     </general>
 </root>

+ 134 - 58
src/network/http_network.hpp

@@ -7,6 +7,85 @@
 #include "../models/web_after_response_info.h"
 
 using namespace robotics;
+namespace utils {
+	enum class http_type_enum {
+		post,
+		get
+	};
+
+	struct http_request {
+		std::string get(std::string const& url, std::map<std::string, std::string> const& headers = {}) {
+			http::web_request request = http::make_request(url);
+			request.method(http::verb::get);
+			for (auto& [key, value] : headers) {
+				request.set(key, value);
+			}
+			request.prepare_payload();
+			auto response = asio2::http_client::execute(request);
+			if (asio2::get_last_error()) {
+				throw std::runtime_error("HTTP request failed: " + v3::utils::gbk_to_utf8(asio2::get_last_error_msg()));
+			}
+			else if (response.result() != http::status::ok) {
+				throw std::runtime_error("HTTP request failed: " + std::to_string((int)response.result()));
+			}
+			return response.body();
+		}
+		std::string post(std::string const& url, std::string const& data, std::map<std::string, std::string> const& headers = {}) {
+			http::web_request request = http::make_request(url);
+			request.method(http::verb::post);
+			for (auto& [key, value] : headers) {
+				request.set(key, value);
+			}
+			request.body() = data;
+			request.prepare_payload();
+			auto response = asio2::http_client::execute(request);
+			if (asio2::get_last_error()) {
+				throw std::runtime_error("HTTP request failed: " + asio2::get_last_error_msg());
+			}
+			else if (response.result() != http::status::ok) {
+				throw std::runtime_error("HTTP request failed: " + std::to_string((int)response.result()));
+			}
+			return response.body();
+		}
+	};
+
+	struct web_http {
+		template<http_type_enum _Type, typename _Ret>
+		_Ret request(std::string const& url, std::string const& data, std::map<std::string, std::string> const& headers = {}) {
+			static_assert(!std::is_same<_Ret, std::string>::value, "type err");
+			std::string json = request<_Type>(url, data, headers);
+			LOG_INFO << "http响应:" << json;
+			return response<_Ret>(json);
+		}
+
+		template<http_type_enum _Type, typename _Ret>
+		_Ret request(std::string const& url, std::map<std::string, std::string> const& headers = {}) {
+			static_assert(!std::is_same<_Ret, std::string>::value, "type err");
+			std::string json = request<_Type>(url, "", headers);
+			LOG_INFO << "http响应:" << json;
+			return response<_Ret>(json);
+		}
+
+		template<http_type_enum _Type>
+		std::string request(std::string const& url, std::string const& data, std::map<std::string, std::string> const& headers = {}) {
+			if constexpr (_Type == http_type_enum::post) {
+				return request_.post(url, data, headers);
+			}
+			else {
+				return request_.get(url, headers);
+			}
+		}
+	private:
+		template<typename _Ret>
+		_Ret response(std::string const& json) {
+			_Ret result;
+			v3::json_convert::deserialize(json, result);
+			return result;
+		}
+	private:
+		http_request request_;
+	};
+}
 /**
  * @brief http_network 类用于管理 HTTP 网络请求,包括获取和设置设备 ID、发送售后请求、获取通用配置信息等功能,并实现了单例模式。
  */
@@ -37,14 +116,13 @@ public:
 	 * @return 包含售后响应信息的 web_response_info<web_after_response_info> 对象。
 	 */
 	web_response_info<web_after_response_info> request_after() {
-		auto url_config = xml_context::from<web_general_config_info>().where([](auto it) {return it->enable && it->key == 3; }).first();
-		if (!url_config) {
-			url_config.reset(new web_general_config_info());
-			url_config->value = "http://127.0.0.1:8002/api/after/get_after";
+		auto config = xml_context::from<web_general_config_info>().where([](auto it) {return it->enable && it->key == 2; }).first();
+		if (!config) {
+			config.reset(new web_general_config_info());
+			config->value = "http://127.0.0.1:9004/api/after/params";
 		}
-		std::string url = url_config->value + "?devece_id=" + device_id_;
-		LOG_INFO << "Url:" << url;
-		return get<web_after_response_info>(http::url_encode(url));
+		LOG_INFO << "Url:" << config->value;
+		return request<utils::http_type_enum::get, web_response_info<web_after_response_info>>(config->value);
 	}
 	/**
 	 * @brief 根据给定的 key 获取通用配置信息的 Web 响应。
@@ -52,67 +130,57 @@ public:
 	 * @return 包含通用配置信息的 web_response_info<web_general_config_info> 对象。
 	 */
 	web_response_info<web_general_config_info> request_general(int key) {
-		auto url_config = xml_context::from<web_general_config_info>().where([](auto it) {return it->enable && it->key == 4; }).first();
-		if (!url_config) {
-			url_config.reset(new web_general_config_info());
-			url_config->value = "http://127.0.0.1:8002/api/base/config";
+		auto config = xml_context::from<web_general_config_info>().where([](auto it) {return it->enable && it->key == 1; }).first();
+		if (!config) {
+			config.reset(new web_general_config_info());
+			config->value = "http://127.0.0.1:9004/api/base/config";
 		}
-		std::string url = url_config->value + "?devece_id=" + device_id_ + "&app_name=after_service&key=" + std::to_string(key);
+		std::string url = config->value + "?key=" + std::to_string(key);
 		LOG_INFO << "Url:" << url;
-		return get<web_general_config_info>(http::url_encode(url));
+		return request<utils::http_type_enum::get, web_response_info<web_general_config_info>>(url);
 	}
 private:
 	/**
 	 * @brief 初始化或处理 HTTP 网络操作。
 	 */
-	http_network() {}
-	template<typename _Ret>
-	web_response_info<_Ret> post(std::string const& url, std::string const& data) {
-		http::web_request request = http::make_request(url);
-		request.method(http::verb::post);
-		request.set(http::field::user_agent, "Chrome");
-		request.set(http::field::content_type, "application/json");
-		request.set("token", sign());
-		request.body() = data;
-		request.prepare_payload();
-		auto response = asio2::http_client::execute(request);
-		if (asio2::get_last_error()) {
-			throw std::runtime_error("HTTP request failed: " + asio2::get_last_error_msg());
-		}
-		else if (response.result() != http::status::ok) {
-			throw std::runtime_error("HTTP request failed: " + std::to_string((int)response.result()));
-		}
-		std::string json = response.body();
-		web_response_info<_Ret> result;
-		LOG_INFO << json;
-		v3::json_convert::deserialize(json, result);
-		return result;
-	}
+	http_network():
+		app_name_("after_service") { }
+private:
 	/**
-	 * @brief 发送一个 HTTP GET 请求到指定的 URL,并返回响应体内容。
+	 * @brief 发送带有指定数据的 HTTP 请求,并返回响应结果。
+	 * @tparam _Ret 请求返回值的类型。
+	 * @tparam _Value 要序列化并发送的数据类型。
+	 * @tparam _Type HTTP 请求类型(如 GET、POST 等),由 utils::http_type_enum 枚举指定。
 	 * @param url 要请求的目标 URL。
-	 * @return HTTP 响应的正文内容(body),类型为 std::string。如果请求失败,则抛出 std::runtime_error 异常。
+	 * @param data 要随请求发送的数据,将被序列化为 JSON 格式。
+	 * @return HTTP 请求的响应结果,类型为 _Ret。
 	 */
-	template<typename _Ret>
-	web_response_info<_Ret> get(std::string const& url) {
-		http::web_request request = http::make_request(url);
-		request.method(http::verb::get);
-		request.set(http::field::user_agent, "Chrome");
-		request.set(http::field::content_type, "text/html");
-		request.set("token", sign());
-		request.prepare_payload();
-		auto response = asio2::http_client::execute(request);
-		if (asio2::get_last_error()) {
-			throw std::runtime_error("HTTP request failed: " + v3::utils::gbk_to_utf8(asio2::get_last_error_msg()));
-		}
-		else if (response.result() != http::status::ok) {
-			throw std::runtime_error("HTTP request failed: " + std::to_string((int)response.result()));
-		}
-		std::string json = response.body();
-		web_response_info<_Ret> result;
-		LOG_INFO << json;
-		v3::json_convert::deserialize(json, result);
-		return result;
+	template<utils::http_type_enum _Type, typename _Ret, typename _Value>
+	_Ret request(std::string const& url, _Value const& data) {
+		return http_.request<_Type, _Ret>(http::url_encode(url), v3::json_convert::serialize(data), { {"Content-Type","application/json"},{"User-Agent","Chrome"},{"Token",sign()},{"DeviceId",device_id_ },{"AppName",app_name_ } });
+	}
+	/**
+	 * @brief 发送一个HTTP POST请求,并返回指定类型的结果。
+	 * @tparam _Ret 请求返回值的类型。
+	 * @tparam _Type HTTP请求类型的枚举值(通常为utils::http_type_enum类型)。
+	 * @param url 要请求的URL地址。
+	 * @param data 要发送的请求数据(通常为JSON格式)。
+	 * @return 指定类型的HTTP响应结果。
+	 */
+	template<utils::http_type_enum _Type, typename _Ret>
+	_Ret request(std::string const& url, std::string const& data) {
+		return http_.request<_Type, _Ret>(http::url_encode(url), data, { {"Content-Type","application/json"},{"User-Agent","Chrome"},{"Token",sign()},{"DeviceId",device_id_ },{"AppName",app_name_ } });
+	}
+	/**
+	 * @brief 发送一个HTTP GET请求到指定的URL,并返回指定类型的结果。
+	 * @tparam _Ret 请求返回值的类型。
+	 * @tparam _Type HTTP请求类型的枚举值,通常为utils::http_type_enum类型(此函数内部固定为GET)。
+	 * @param url 要请求的目标URL字符串。
+	 * @return 指定类型(_Ret)的HTTP响应结果。
+	 */
+	template<utils::http_type_enum _Type, typename _Ret>
+	_Ret request(std::string const& url) {
+		return http_.request<_Type, _Ret>(http::url_encode(url), { {"Content-Type","text/html"},{"User-Agent","Chrome"},{"Token",sign()},{"DeviceId",device_id_ },{"AppName",app_name_ } });
 	}
 private:
 	/**
@@ -123,8 +191,16 @@ private:
 		return v3::utils::md5(device_id_ + "GqBRMZHKlBDCWlwyYolk24BXHElKUo5Z");
 	}
 private:
+	/**
+	 * @brief utils::web_http 类型的 http_ 变量。
+	 */
+	utils::web_http http_;
 	/**
 	 * @brief 设备的唯一标识符字符串。
 	 */
 	std::string device_id_;
+	/**
+	 * @brief 应用程序的名称。
+	 */
+	std::string app_name_;
 };