浏览代码

#代码生成器

zxs 3 月之前
父节点
当前提交
9d16af8abe
共有 5 个文件被更改,包括 1396 次插入1656 次删除
  1. 1026 1249
      generator/class_view.hpp
  2. 3 235
      generator/main.cpp
  3. 132 0
      robot/robotics/http_client.hpp
  4. 100 39
      robot/robotics/mvc.hpp
  5. 135 133
      robot/robotics/web_service.hpp

+ 1026 - 1249
generator/class_view.hpp

@@ -1,1368 +1,1145 @@
-#ifndef __CODE_GENERATOR_CODE_ANALYSIS_H__
-#define __CODE_GENERATOR_CODE_ANALYSIS_H__
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
 #pragma once
-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
-
 #include <iostream>
 #include <filesystem>
 #include <regex>
+#include <map>
+#include <any>
+#include <variant>
 #include <fstream>
-#include "../robot/robotics/utils.hpp"
-using namespace robotics;
-
-struct file_info {
-	/**
-	 * @brief 路径
-	*/
-	std::string					file_path;
-	/**
-	 * @brief 代码
-	*/
-	std::vector<std::string>	content;
-	/**
-	 * @brief 类型 0控制器 1实体类 2soap
-	*/
-	int							class_type = 0;
-};
+#include <chrono>
+#include <random>
+#include <fmt/format.h>
 
-struct PropertyInfo {
-	/**
-	 * @brief 类型名称
-	*/
-	std::string		type_name;
-	/**
-	 * @brief 属性名称
-	*/
-	std::string		prop_name;
-	/**
-	 * @brief json字段名称
-	*/
-	std::string		json_name;
-	/**
-	 * @brief 数据库字段名称
-	*/
-	std::string		sql_name;
-	/**
-	 * @brief excel字段名称
-	*/
-	std::string		excel_name;
-	/**
-	 * @brief 不序列化json 默认false
-	*/
-	bool			no_json = false;
-	/**
-	 * @brief 不创建数据库字段 默认false
-	*/
-	bool			no_sql = false;
-	/**
-	 * @brief 不导出excel字段 默认false
-	*/
-	bool			no_excel = false;
-	/**
-	 * @brief 字段索引
-	*/
-	bool			sql_key = false;
-	/**
-	 * @brief 二进制序列化
-	*/
-	bool			no_archive = false;
-};
-
-struct ParameterInfo {
-	/**
-	 * @brief 参数名称
-	*/
-	std::string name;
-	/**
-	 * @brief 参数类型
-	*/
-	std::string type;
-	/**
-	 * @brief 参数名称
-	*/
-	std::string parameter_name;
-	/**
-	 * @brief 类型名称
-	*/
-	std::string argument_type = "robotics::v3::mvc::argument_type::Binary";
-	/**
-	 * @brief 提取位置 QUERY Body Header
-	*/
-	std::string from_storage_type = "robotics::v3::mvc::from_storage_type::QUERY";
-};
-
-struct MethodInfo {
-	/**
-	 * @brief 身份验证
-	*/
-	bool authen = true;
-	/**
-	 * @brief 未登录跳转
-	*/
-	std::string authen_jump;
-
-	/**
-	 * @brief
-	*/
-	std::string method = "robotics::v3::mvc::http_method::GET";
-	/**
-	 * @brief
-	*/
-	std::string content_type = "application/x-www-form-urlencoded";
-	/**
-	 * @brief
-	*/
-	std::string action_type;
-	/**
-	 * @brief
-	*/
-	std::string file_mapping;
-	/**
-	 * @brief
-	*/
-	std::string route;
-	/**
-	 * @brief
-	*/
-	std::string name;
-	/**
-	 * @brief 函数签名
-	*/
-	std::string signature;
-	/**
-	 * @brief 参数
-	*/
-	std::vector<ParameterInfo> parameters;
-};
-
-struct SoapParameterInfo {
-	/**
-	 * @brief 类型
-	*/
-	std::string type = "std::string";
-	/**
-	 * @brief 参数类型
-	*/
-	std::string argument_type = "robotics::v3::mvc::soap_argument_type::String";
-	/**
-	 * @brief 参数名称
-	*/
-	std::string parameter_name = "value";
-};
-
-struct soap_method_info {
-	/**
-	 * @brief 方法名称
-	*/
-	std::string name;
-	/**
-	 * @brief 路由方法名称
-	*/
-	std::string action_name;
-	/**
-	 * @brief 函数签名
-	*/
-	std::string signature;
-	/**
-	 * @brief 参数
-	*/
-	std::vector<SoapParameterInfo> parameters;
-};
-
-struct class_view_info {
-	/**
-	 * @brief 0:控制器 1:实体类 2:soap
-	*/
-	int							class_type = 0;
-	/**
-	 * @brief 是否是模板
-	*/
-	bool						is_template = false;
-	/**
-	 * @brief 模板类型列表
-	*/
-	std::vector<std::string>	template_types;
-	/**
-	 * @brief 模板参数列表
-	*/
-	std::vector<std::string>	template_parameters;
-	/**
-	 * @brief 类名称
-	*/
-	std::string					class_name;
-	/**
-	 * @brief 数据库表名称
-	*/
-	std::string					sql_table_name;
-	/**
-	 * @brief 属性列表
-	*/
-	std::vector<PropertyInfo>	propertys;
-	/**
-	 * @brief 控制器列表
-	*/
-	std::vector<MethodInfo>		methods;
-	/**
-	 * @brief soap 方法列表
-	*/
-	std::vector<soap_method_info> soap_methods;
-	/**
-	 * @brief soap版本
-	*/
-	std::string soap_version = "1.1";
-	/**
-	 * @brief soap命名空间
-	*/
-	std::string soap_namepsace = "http://tempuri.org/";
-	/**
-	 * @brief soap路由
-	*/
-	std::string soap_route;
-	/**
-	 * @brief soap wsdl文件
-	*/
-	std::string soap_wsdl;
+namespace analysis {
+	struct class_attribute_info;
 	/**
-	 * @brief 头文件
-	*/
-	std::string include;
-	/**
-	 * @brief 反射
-	*/
-	bool is_reflect = true;
-};
-
-class code_analysis_core {
-public:
-	static std::vector<class_view_info> getClassView(std::filesystem::path path) {
-		return code_analysis_core(path).getClassView();
-	}
-protected:
-	code_analysis_core(std::filesystem::path path) :
-		_path(path) {
-	}
-private:
-	std::vector<class_view_info> getClassView() {
-		std::vector<class_view_info> result;
-		auto fileInfos = getiFileInfo();
-		//控制器
-		for (auto& it : fileInfos) {
-			if (it.class_type != 0)
-				continue;
-
-			for (auto code : it.content) {
-				std::regex pattern("class[ \r\n\t]{1,30}([a-zA-Z_0-9]{1,100})");
-				std::smatch smatch;
-				if (std::regex_search(code, smatch, pattern)) {
-					if (smatch.size() == 2) {
-						class_view_info add;
-						add.include = it.file_path;
-						add.class_type = 0;
-						add.class_name = smatch[1];
-						add.methods = getMethods(smatch.suffix());
-						result.push_back(add);
-					}
+	 * @brief 工具
+	 */
+	class utils {
+	public:
+		/**
+		 * @brief 字符串
+		 */
+		class string {
+		public:
+			/**
+			 * @brief 替换
+			 * @param value
+			 * @param old_str
+			 * @param new_str
+			 * @return
+			 */
+			static std::string replace(std::string const& value, std::string const& old_str, std::string const& new_str) {
+				std::string result = value;
+				for (std::string::size_type pos(0); pos != std::string::npos; pos += new_str.length()) {
+					pos = result.find(old_str, pos);
+					if (pos != std::string::npos)
+						result.replace(pos, old_str.length(), new_str);
+					else
+						break;
 				}
+				return result;
 			}
-		}
-		//实体类
-		for (auto& it : fileInfos) {
-			if (it.class_type != 1)
-				continue;
-
-			for (auto code : it.content) {
-
-				//普通模板结构体
-				{
-					std::regex pattern("template[ \r\n\t]{0,30}<([\\s\\S]*?)>[ \r\n\t]{0,30}struct[ \r\n\t]{1,30}([a-zA-Z_0-9]{1,100})");
-					std::smatch smatch;
-					if (std::regex_search(code, smatch, pattern)) {
-						if (smatch.size() == 3) {
-							class_view_info add;
-							add.include = it.file_path;
-							add.class_type = 1;
-							add.class_name = smatch[2];
-							add.is_template = true;
-							add.sql_table_name = smatch[2];
-							auto templteTypeList = v3::utils::split(smatch[1], ",");
-							for (auto& tempType : templteTypeList) {
-								auto tempValue = v3::utils::split(tempType, " ");
-								if (tempValue.size() == 2) {
-									add.template_types.push_back(v3::utils::trim(tempValue[1]));
-								}
-							}
-							add.propertys = getPropertys(smatch.suffix());
-							result.push_back(add);
-							code = smatch.suffix();
-						}
-					}
+			/**
+			 * @brief 分割字符串
+			 * @param value
+			 * @return
+			 */
+			static std::vector<std::string> split(std::string const& value) {
+				std::string c = ",";
+				std::vector<std::string> result;
+				if (value.empty()) {
+					return result;
 				}
-				//带特性模板结构体
-				{
-					std::regex pattern("template[ \r\n\t]{0,30}<([\\s\\S]*?)>[ \r\n\t]{0,30}struct[ \r\n\t]{0,30}(\\[\\[[\\s\\S]*?\\]\\])[ \r\n\t]{0,30}([a-zA-Z_0-9]{1,100})[ \r\n\t]{0,30}\\{");
-					std::smatch smatch;
-					if (std::regex_search(code, smatch, pattern)) {
-						if (smatch.size() == 4) {
-							class_view_info add;
-							add.include = it.file_path;
-							add.class_type = 1;
-							add.class_name = smatch[3];
-							add.is_template = true;
-							auto templteTypeList = v3::utils::split(smatch[1], ",");
-							for (auto& tempType : templteTypeList) {
-								auto tempValue = v3::utils::split(tempType, " ");
-								if (tempValue.size() == 2) {
-									add.template_types.push_back(v3::utils::trim(tempValue[1]));
-								}
-							}
-
-							getTemplateParameter(smatch[2], add.template_types.size(), add);
-
-							add.sql_table_name = add.sql_table_name.empty() ? add.class_name : add.sql_table_name;
-							add.propertys = getPropertys("{" + smatch.suffix().str());
-							result.push_back(add);
-							code = smatch.suffix();
-						}
-					}
+				std::string strs = value + c;
+				size_t pos = strs.find(c);
+				while (pos != strs.npos) {
+					std::string temp = strs.substr(0, pos);
+					result.push_back(temp);
+					strs = strs.substr(pos + c.size(), strs.size());
+					pos = strs.find(c);
 				}
-				//普通结构体
-				{
-					std::regex pattern("struct[ \r\n\t]{1,30}([a-zA-Z_0-9]{1,100})");
-					std::smatch smatch;
-					if (std::regex_search(code, smatch, pattern)) {
-						if (smatch.size() == 2) {
-							class_view_info add;
-							add.include = it.file_path;
-							add.class_type = 1;
-							add.class_name = smatch[1];
-							add.sql_table_name = smatch[1];
-							add.propertys = getPropertys(smatch.suffix());
-							result.push_back(add);
-							code = smatch.suffix();
-						}
+				return result;
+			}
+			/**
+			 * @brief
+			 * @param values
+			 * @return
+			 */
+			static std::string join(std::vector<std::string> values, std::string c = ",") {
+				std::string result;
+				while (!values.empty()) {
+					if (result.empty()) {
+						result = values[0];
+						values.erase(values.begin());
 					}
-				}
-				//带反射特性结构体
-				{
-					std::regex pattern("struct[ \r\n\t]{0,30}\\[\\[NoReflect\\]\\][ \r\n\t]{0,30}([a-zA-Z_0-9]{1,100})");
-					std::smatch smatch;
-					if (std::regex_search(code, smatch, pattern)) {
-						if (smatch.size() == 2) {
-							class_view_info add;
-							add.include = it.file_path;
-							add.class_type = 1;
-							add.class_name = smatch[1];
-							add.sql_table_name = smatch[1].length() == 0 ? add.class_name : smatch[1];
-							add.propertys = getPropertys(smatch.suffix());
-							add.is_reflect = false;
-							result.push_back(add);
-							code = smatch.suffix();
-						}
+					else {
+						result += c + values[0];
+						values.erase(values.begin());
 					}
 				}
-				//带数据库特性结构体
-				{
-					std::regex pattern("struct[ \r\n\t]{0,30}\\[\\[SqlTable\\(\"(.*?)\"\\)\\]\\][ \r\n\t]{0,30}([a-zA-Z_0-9]{1,100})");
-					std::smatch smatch;
-					if (std::regex_search(code, smatch, pattern)) {
-						if (smatch.size() == 3) {
-							class_view_info add;
-							add.include = it.file_path;
-							add.class_type = 1;
-							add.class_name = smatch[2];
-							add.sql_table_name = smatch[1].length() == 0 ? add.class_name : smatch[1];
-							add.propertys = getPropertys(smatch.suffix());
-							result.push_back(add);
-							code = smatch.suffix();
-						}
-					}
+				return result;
+			}
+			/**
+			 * @brief 删除首尾空格
+			 * @param value
+			 * @return
+			 */
+			static std::string trim(std::string const& value) {
+				std::string result = value;
+				while (!result.empty()) {
+					if (result[0] == ' ' || result[0] == '\t' || result[0] == '\r' || result[0] == '\n')
+						result.erase(result.begin());
+					else
+						break;
 				}
-				//带数据库反射特性结构体
-				{
-					std::regex pattern("struct[ \r\n\t]{0,30}\\[\\[NoReflect\\]\\][ \r\n\t]{0,30}\\[\\[SqlTable\\(\"(.*?)\"\\)\\]\\][ \r\n\t]{0,30}([a-zA-Z_0-9]{1,100})");
-					std::smatch smatch;
-					if (std::regex_search(code, smatch, pattern)) {
-						if (smatch.size() == 3) {
-							class_view_info add;
-							add.include = it.file_path;
-							add.class_type = 1;
-							add.class_name = smatch[2];
-							add.sql_table_name = smatch[1].length() == 0 ? add.class_name : smatch[1];
-							add.propertys = getPropertys(smatch.suffix());
-							add.is_reflect = false;
-							result.push_back(add);
-							code = smatch.suffix();
-						}
+				while (!result.empty()) {
+					if (result[result.size() - 1] == ' ' || result[result.size() - 1] == '\t' || result[result.size() - 1] == '\r' || result[result.size() - 1] == '\n')
+						result.pop_back();
+					else
+						break;
+				}
+				return result;
+			}
+			/**
+			 * @brief 大括号
+			 * @param code
+			 * @param index
+			 * @return
+			 */
+			static bool ergodic(std::string& code, std::size_t& index) {
+				index++;
+				for (; index < code.size(); ++index) {
+					if (code[index] == '}' || code[index] == ')') {
+						return true;
+					}
+					else if (code[index] == '{') {
+						ergodic(code, index);
+					}
+					else if (code[index] == '(') {
+						ergodic(code, index);
+					}
+					else if (code[index] == '"') {
+						quotation_mark(code, index);
 					}
 				}
+				return false;
 			}
-		}
-		//soap
-		for (auto& it : fileInfos) {
-			if (it.class_type != 2)
-				continue;
-
-			for (auto code : it.content) {
-				std::regex pattern("class[ \r\n\t]{1,30}\\[\\[(.*?)\\]\\][ \r\n\t]{1,30}\\[\\[(.*?)\\]\\][ \r\n\t]{1,30}\\[\\[(.*?)\\]\\][ \r\n\t]{1,30}\\[\\[(.*?)\\]\\][ \r\n\t]{1,30}([a-zA-Z_0-9]{1,100})");
-				std::smatch smatch;
-				if (std::regex_search(code, smatch, pattern)) {
-					if (smatch.size() == 6) {
-						class_view_info add;
-						add.include = it.file_path;
-						add.class_type = 2;
-						getSoapAttribute(smatch[1], add);
-						getSoapAttribute(smatch[2], add);
-						getSoapAttribute(smatch[3], add);
-						getSoapAttribute(smatch[4], add);
-						add.class_name = smatch[5];
-
-						add.soap_methods = getSoapMethods(smatch.suffix());
-						result.push_back(add);
+			/**
+			 * @brief 引号
+			 * @param code
+			 * @param index
+			 * @return
+			 */
+			static bool quotation_mark(std::string& code, std::size_t& index) {
+				index++;
+				for (; index < code.size(); ++index) {
+					if (code[index] == '"') {
+						return true;
 					}
 				}
+				return false;
 			}
-		}
-		std::string rootPath = _path.string();
-
-		rootPath = v3::utils::replace(rootPath, "\\", "/");
-
-		if (rootPath[rootPath.size() - 1] != '/') {
-			rootPath += "/";
-		}
-
-		for (auto& it : result) {
-			it.include = v3::utils::replace(it.include, rootPath, "");
-		}
-
-		return result;
-	}
-	std::vector<file_info> getiFileInfo() {
-		std::vector<file_info> result;
-
-		auto controllerFiles = getControllerFiles();
-
-		auto modelFiles = getModelsFiles();
-
-		auto webServiceFiles = getWebServicesFiles();
-
-		for (auto& item : controllerFiles) {
-			file_info add;
-			//获取代码
-			std::string code = getCode(item);
-			//剔除无用代码
-			eliminateNotes(code);
-			//
-			add.class_type = 0;
-			add.content = getStructContent(code);
-			for (auto& it : add.content) {
-				eliminateController(it);
+			/**
+			 * @brief
+			 * @return
+			 */
+			static unsigned int random_char() {
+				std::random_device rd;
+				std::mt19937 gen(rd());
+				std::uniform_int_distribution<> dis(0, 255);
+				return dis(gen);
 			}
-
-			add.file_path = v3::utils::replace(item.string(), "\\", "/");
-			result.push_back(add);
-		}
-
-		for (auto& item : modelFiles) {
-			file_info add;
-			//获取代码
-			std::string code = getCode(item);
-			//剔除无用代码
-			eliminateNotes(code);
-			//
-			add.class_type = 1;
-			add.content = getStructContent(code);
-			add.file_path = v3::utils::replace(item.string(), "\\", "/");
-			result.push_back(add);
-		}
-
-		for (auto& item : webServiceFiles) {
-			file_info add;
-			//获取代码
-			std::string code = getCode(item);
-			//剔除无用代码
-			eliminateNotes(code);
-			//
-			add.class_type = 2;
-			add.content = getStructContent(code);
-			for (auto& it : add.content) {
-				eliminateWebService(it);
-			}
-			add.file_path = v3::utils::replace(item.string(), "\\", "/");
-			result.push_back(add);
-		}
-
-		return result;
-	}
-	std::vector<std::filesystem::path> getControllerFiles() {
-		std::filesystem::path controllersPath = _path;
-		controllersPath /= "controllers";
-		std::vector<std::filesystem::path> files;
-		getFiles(controllersPath, { ".hpp" }, files);
-		return files;
-	}
-	std::vector<std::filesystem::path> getModelsFiles() {
-		std::filesystem::path modelsPath = _path;
-		modelsPath /= "models";
-		std::vector<std::filesystem::path> files;
-		getFiles(modelsPath, { ".h" }, files);
-		return files;
-	}
-	std::vector<std::filesystem::path> getWebServicesFiles() {
-		std::filesystem::path webServicesPath = _path;
-		webServicesPath /= "webservices";
-		std::vector<std::filesystem::path> files;
-		getFiles(webServicesPath, { ".hpp" }, files);
-		return files;
-	}
-
-	void getFiles(std::filesystem::path path, std::vector<std::string> extension, std::vector<std::filesystem::path>& files)
-	{
-		if (!std::filesystem::is_directory(path)) {
-			return;
-		}
-		for (auto& itr : std::filesystem::directory_iterator(path))
-		{
-			if (std::filesystem::is_directory(itr.status()))
-			{
-				getFiles(itr.path(), extension, files);
-			}
-			else
-			{
-				if (std::find(extension.begin(), extension.end(), itr.path().extension()) != extension.end()) {
-					files.push_back(itr.path());
+			/**
+			 * @brief
+			 * @param len
+			 * @return
+			 */
+			static std::string generate_hex(const unsigned int len) {
+				std::stringstream ss;
+				for (unsigned int i = 0; i < len; i++) {
+					const auto rc = random_char();
+					std::stringstream hexstream;
+					hexstream << std::hex << rc;
+					auto hex = hexstream.str();
+					ss << (hex.length() < 2 ? '0' + hex : hex);
 				}
+				return ss.str();
+			}
+			/**
+			 * @brief 当前时间
+			 * @return
+			 */
+			static std::string current_time() {
+				std::time_t timestamp = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
+				std::tm now_time;
+#ifdef WINDOWS_BUILD
+				localtime_s(&now_time, &timestamp);
+#elif LINUX_BUILD
+				localtime_r(&timestamp, &now_time);
+#endif
+				std::stringstream ss;
+				ss << std::put_time(&now_time, "%Y-%m-%d %H:%M:%S");
+				return ss.str();
 			}
-		}
-	}
-	std::string getCode(std::filesystem::path const& path) {
-		std::ifstream file(path, std::ios::out);
-		if (file.is_open()) {
-			return std::string((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
-		}
-		return "";
-	}
-	void eliminateNotes(std::string& code) {
-		std::vector<std::pair<std::string, std::string>> notes = {
-			{"/*","*/"},
-			{"//","\n"},
-			{"#include","\n"},
-			{"#pragma", "\n"},
-			{"#ifndef", "\n"},
-			{"#define", "\n"},
-			{"#if", "\n"},
-			{"#endif", "\n"}
 		};
-		for (auto& note : notes) {
-			std::size_t begin = 0;
-			std::size_t end = 0;
-			while ((begin = code.find(note.first, begin)) != std::string::npos && (end = code.find(note.second, begin)) != std::string::npos) {
-				if (begin > 0 && code[begin - 1] == ':') {
-					begin += note.second.size();
-					continue;
+		/**
+		 * @brief 正则表达式
+		 */
+		class regex {
+		public:
+			/**
+			 * @brief 特性
+			 * @return
+			 */
+			static std::regex& attribute() {
+				static std::regex value("\\[\\[[ \t]{0,30}(ActionType|Method|Authen|Route|ContentType|FileMapping|Json|NoJson|Sql|NoSql|SqlKey|Excel|NoExcel|NoArchive|NoReflect|SqlTable|TemplateType|FromQuery|FromBody|FromHeader|FromUrl|Version|Namespace|Wsdl)[ \t]{0,30}\\([ \t]{0,30}([\\s\\S]*?)[ \t]{0,30}\\)\\]\\]");
+				return value;
+			}
+			/**
+			 * @brief 属性
+			 * @return
+			 */
+			static std::regex& property() {
+				static std::regex value("(\\[\\[[\\s\\S]*?\\]\\]|)[ \r\n\t]{0,100}(int|bool|double|float|std::int64_t|v3::datetime|std::string|std::vector<[a-zA-Z_0-9]{1,100}>|[a-zA-Z_0-9]{1,100})[ \t]{1,30}([a-zA-Z_0-9]{1,100})[^;]*;");
+				return value;
+			}
+			/**
+			 * @brief 方法
+			 * @return
+			 */
+			static std::regex& method() {
+				static std::regex value("(\\[\\[[\\s\\S]*?\\]\\]|)[ \r\n\t]{0,100}(WebResponse|SoapResponse)[ \r\n\t]{1,30}([a-zA-Z_0-9]{1,100})[ \r\n\t]{0,30}\\(([a-zA-Z0-9\",\\[\\], \r\n\t:<>_\\(\\)]{0,500})\\)");
+				return value;
+			}
+			/**
+			 * @brief 类
+			 * @return
+			 */
+			static std::regex& class_() {
+				static std::regex value("(template[ \r\n\t]{0,30}<[\\s\\S]{1,100}>|)[ \r\n\t]{1,30}(struct|class)[ \r\n\t]{1,30}(\\[\\[[\\s\\S]*?\\]\\]|)[ \r\n\t]{0,30}([a-zA-Z_0-9]{1,200})");
+				return value;
+			}
+			/**
+			 * @brief 模板
+			 * @return
+			 */
+			static std::regex& template_() {
+				static std::regex value("template[ \r\n\t]{0,30}<([\\s\\S]{1,100})>");
+				return value;
+			}
+			/**
+			 * @brief 参数
+			 * @return
+			 */
+			static std::regex& parameter() {
+				static std::regex value("(\\[\\[[ \t]{0,30}(FromQuery|FromBody|FromHeader|FromUrl)[ \t]{0,30}\\([ \t]{0,30}([\\s\\S]*?)[ \t]{0,30}\\)\\]\\]|)[ \r\n\t]{0,100}([a-zA-Z_0-9:<>]{1,100})[ \t\r\n]{1,100}([a-zA-Z_0-9]{1,100})");
+				return value;
+			}
+		};
+		/**
+		 * @brief 特性
+		 */
+		class attribute {
+		public:
+			//查找
+			static std::vector<class_attribute_info> find(std::vector<class_attribute_info> const& src, std::string const& attribute);
+		};
+	};
+
+	struct class_attribute_info {
+		class_attribute_info() {}
+		class_attribute_info(std::string code) :
+			content(code) {
+			deserialize(code);
+		}
+		std::string					content;
+		std::string					attribute;
+		bool						bool_value = false;
+		std::string					string_value;
+		std::vector<std::string>	vector_string_value;
+		std::vector<bool>			vector_bool_value;
+	private:
+		/**
+		 * @brief
+		 * @param code
+		 */
+		void deserialize(std::string code) {
+			std::smatch smatch;
+			if (std::regex_search(code, smatch, utils::regex::attribute())) {
+				if (smatch.size() == 3) {
+					std::vector<std::any> item;
+					attribute = smatch[1];
+					get_value(smatch[2]);
 				}
-				code.erase(begin, end - begin + note.second.size());
 			}
 		}
-	}
-	void eliminateController(std::string& code) {
-		std::string tmpCode = code;
-		std::regex pattern("WebResponse[ \r\n\t]{1,30}[a-zA-Z_0-9]{1,100}[ \r\n\t]{0,30}([a-zA-Z0-9\",\\[\\], \r\n\t:<>_\\(\\)]{0,500})");
-		std::smatch smatch;
-		while (std::regex_search(tmpCode, smatch, pattern)) {
-			std::string value = smatch[0];
-
-			std::size_t pos = code.find(value);
-
-			if (pos == std::string::npos)
-				break;
-			pos += value.size();
-			int begin = 0;
-			int end = 0;
-
-			for (std::size_t i = pos; i < code.size(); ++i) {
-
-				if (code[i] == '"') {
-					int tmpBegin = 0;
-					for (std::size_t i1 = i; i1 < code.size(); ++i1) {
-						if (code[i1] == '"') {
-							tmpBegin++;
-						}
-						code.erase(i1, 1);
-						i1--;
-						if (tmpBegin == 2) {
-							break;
-						}
+		/**
+		 * @brief 获取值
+		 * @param code
+		 */
+		void get_value(std::string code) {
+			if (code.empty())
+				return;
+			auto params = utils::string::split(code);
+			for (auto it : params) {
+				it = utils::string::trim(it);
+				if (attribute == "TemplateType") {
+					if (it == "false" || it == "true") {
+						vector_bool_value.push_back(it == "true");
+					}
+					else if (it.find('"') != std::string::npos) {
+						vector_string_value.push_back(it.substr(1, it.size() - 2));
 					}
 				}
-
-
-				if (code[i] == '{') {
-					begin++;
-				}
-				else if (code[i] == '}') {
-					end++;
-				}
-				code.erase(i, 1);
-				i--;
-				if (begin > 0 && end == begin) {
-					code.insert(code.begin() + i, ';');
-					break;
+				else {
+					if (it == "false" || it == "true") {
+						bool_value = it == "true";
+					}
+					else if (it.find('"') != std::string::npos) {
+						string_value = it.substr(1, it.size() - 2);
+					}
 				}
-
 			}
+		}
+	};
 
-			tmpCode = smatch.suffix();
+	std::vector<class_attribute_info> utils::attribute::find(std::vector<class_attribute_info> const& src, std::string const& attribute) {
+		std::vector<class_attribute_info> result;
+		for (auto it : src) {
+			if (it.attribute == attribute) {
+				result.push_back(it);
+			}
 		}
+		return result;
 	}
-	void eliminateWebService(std::string& code) {
-		std::string tmpCode = code;
-		std::regex pattern("SoapResponse[ \r\n\t]{1,30}[a-zA-Z_0-9]{1,100}[ \r\n\t]{0,30}([a-zA-Z0-9\",\\[\\], \r\n\t:<>_\\(\\)]{0,500})");
-		std::smatch smatch;
-		while (std::regex_search(tmpCode, smatch, pattern)) {
-			std::string value = smatch[0];
-
-			std::size_t pos = code.find(value);
-
-			if (pos == std::string::npos)
-				break;
-			pos += value.size();
-			int begin = 0;
-			int end = 0;
-
-			for (std::size_t i = pos; i < code.size(); ++i) {
 
-				if (code[i] == '"') {
-					int tmpBegin = 0;
-					for (std::size_t i1 = i; i1 < code.size(); ++i1) {
-						if (code[i1] == '"') {
-							tmpBegin++;
-						}
-						code.erase(i1, 1);
-						i1--;
-						if (tmpBegin == 2) {
-							break;
-						}
+	struct class_property_info {
+		class_property_info() {}
+		class_property_info(std::string code) :
+			content(code) {
+			deserialize(code);
+		}
+		std::string							content;
+		std::string							type;
+		std::string							name;
+		std::vector<class_attribute_info>	attributes;
+		std::string generate_code() {
+			auto Json = utils::attribute::find(attributes, "Json");
+			auto Sql = utils::attribute::find(attributes, "Sql");
+			auto Excel = utils::attribute::find(attributes, "Excel");
+			auto NoJson = utils::attribute::find(attributes, "NoJson");
+			auto NoSql = utils::attribute::find(attributes, "NoSql");
+			auto NoExcel = utils::attribute::find(attributes, "NoExcel");
+			auto SqlKey = utils::attribute::find(attributes, "SqlKey");
+			auto NoArchive = utils::attribute::find(attributes, "NoArchive");
+			return fmt::format("property(\"{}\",&{{0}}::{})(rttr::metadata(\"Json\",\"{}\"),rttr::metadata(\"Sql\",\"{}\"),rttr::metadata(\"Excel\",R\"({})\"),rttr::metadata(\"NoJson\",{}),rttr::metadata(\"NoSql\",{}),rttr::metadata(\"NoExcel\",{}),rttr::metadata(\"SqlKey\",{}),rttr::metadata(\"NoArchive\",{}),rttr::metadata(\"Offset\",robotics::v3::utils::pointer_cast<int>(&{{0}}::{})))",
+				name,
+				name,
+				Json.empty() ? name : Json[0].string_value,
+				Sql.empty() ? name : Sql[0].string_value,
+				Excel.empty() ? name : Excel[0].string_value,
+				NoJson.empty() ? "false" : (NoJson[0].bool_value ? "true" : "false"),
+				NoSql.empty() ? "false" : (NoSql[0].bool_value ? "true" : "false"),
+				NoExcel.empty() ? "false" : (NoExcel[0].bool_value ? "true" : "false"),
+				SqlKey.empty() ? "false" : (SqlKey[0].bool_value ? "true" : "false"),
+				NoArchive.empty() ? "false" : (NoArchive[0].bool_value ? "true" : "false"),
+				name);
+		}
+	private:
+		/**
+		 * @brief 反序列化
+		 * @param code
+		 */
+		void deserialize(std::string code) {
+			std::smatch smatch;
+			if (std::regex_search(code, smatch, utils::regex::property())) {
+				if (smatch.size() == 4) {
+					type = smatch[2];
+					name = smatch[3];
+					for (auto& it : get_attributes(smatch[1])) {
+						attributes.push_back(class_attribute_info(it));
 					}
 				}
-
-
-				if (code[i] == '{') {
-					begin++;
-				}
-				else if (code[i] == '}') {
-					end++;
-				}
-				code.erase(i, 1);
-				i--;
-				if (begin > 0 && end == begin) {
-					code.insert(code.begin() + i, ';');
-					break;
-				}
-
 			}
-
-			tmpCode = smatch.suffix();
 		}
-	}
-	std::vector<std::string> getStructContent(std::string code) {
-		std::vector<std::string> result;
-
-		auto func = [](std::string reg, std::string code) {
+		/**
+		 * @brief 获取特性列表
+		 * @param code
+		 * @return
+		 */
+		std::vector<std::string> get_attributes(std::string code) {
 			std::vector<std::string> result;
-			std::regex pattern(reg);
 			std::smatch smatch;
-			while (std::regex_search(code, smatch, pattern)) {
-				std::string structContent = smatch[0];
-				std::size_t pos = code.find(structContent);
-				if (pos == std::string::npos)
-					break;
-
-				int begin = 0;
-				int end = 0;
-				std::string content;
-				for (int i = pos; i < code.size(); ++i) {
-					content += code[i];
-					if (code[i] == '{') {
-						begin++;
-					}
-					else if (code[i] == '}') {
-						end++;
-					}
-					if (begin > 0 && begin == end) {
-						break;
-					}
+			while (std::regex_search(code, smatch, utils::regex::attribute())) {
+				if (smatch.size() == 3) {
+					result.push_back(smatch[0]);
 				}
-				result.push_back(content);
-
 				code = smatch.suffix();
 			}
-
 			return result;
-			};
-
-		std::vector<std::string> regList;
-		//普通模板结构体
-		regList.push_back("template[ \r\n\t]{0,30}<[\\s\\S]*?>[ \r\n\t]{0,30}struct[ \r\n\t]{1,30}[a-zA-Z_0-9]{1,100}");
-		//带特性模板结构体
-		regList.push_back("template[ \r\n\t]{0,30}<[\\s\\S]*?>[ \r\n\t]{0,30}struct[ \r\n\t]{0,30}\\[\\[[\\s\\S]*?\\]\\][ \r\n\t]{0,30}[a-zA-Z_0-9]{1,100}[ \r\n\t]{0,30}\\{");
-		//普通结构体
-		regList.push_back("struct[ \r\n\t]{1,30}[a-zA-Z_0-9]{1,100}");
-		//带特性结构体
-		regList.push_back("struct[ \r\n\t]{0,30}\\[\\[NoReflect\\]\\][ \r\n\t]{0,30}[a-zA-Z_0-9]{1,100}");
-		//带特性结构体
-		regList.push_back("struct[ \r\n\t]{0,30}\\[\\[SqlTable\\(\".*?\"\\)\\]\\][ \r\n\t]{0,30}[a-zA-Z_0-9]{1,100}");
-		//带特性结构体
-		regList.push_back("struct[ \r\n\t]{0,30}\\[\\[NoReflect\\]\\][ \r\n\t]{0,30}\\[\\[SqlTable\\(\".*?\"\\)\\]\\][ \r\n\t]{0,30}[a-zA-Z_0-9]{1,100}");
-		//控制器
-		regList.push_back("class[ \r\n\t]{1,30}[a-zA-Z_0-9]{1,200}");
-		//soap
-		regList.push_back("class[ \r\n\t]{1,30}\\[\\[.*?\\]\\][ \r\n\t]{1,30}\\[\\[.*?\\]\\][ \r\n\t]{1,30}\\[\\[.*?\\]\\][ \r\n\t]{1,30}\\[\\[.*?\\]\\][ \r\n\t]{1,30}[a-zA-Z_0-9]{1,100}");
-
-		std::string tmpCode = code;
-		for (auto& it : regList) {
-			auto values = func(it, tmpCode);
-
-			for (auto& item : values) {
-				std::size_t pos = 0;
-				if ((pos = tmpCode.find(item)) != std::string::npos) {
-					tmpCode.erase(pos, item.size());
-				}
-			}
-
-			result.insert(result.end(), values.begin(), values.end());
-		}
-		return result;
-	}
-	void getTemplateParameter(std::string code, int count, class_view_info& result) {
-
-		auto attributes = v3::utils::split(code, "]]");
-
-		for (auto& it : attributes) {
-			std::size_t begin = 0;
-			std::size_t end = 0;
-			//TemplateType
-			if (it.find("TemplateType") != std::string::npos && (begin = it.find("\"")) != std::string::npos && (end = it.rfind("\"")) != std::string::npos) {
-				std::string value = it.substr(begin, end - begin + 1);
-				auto values = v3::utils::split(value, ",");
-				if (values.size() != count)
-					continue;
-
-				std::vector<std::string> addItem;
-
-				for (auto temp : values) {
-
-					if ((begin = temp.find("\"")) != std::string::npos && (end = temp.rfind("\"")) != std::string::npos) {
-
-						if (begin == end)
-							continue;
-						addItem.push_back(temp.substr(begin + 1, end - begin - 1));
-					}
-				}
-
-				if (addItem.size() != count)
-					continue;
-
-				result.template_parameters.push_back(v3::utils::format("{}", v3::utils::join(addItem, ",")));
-			}
-			//SqlTable
-			else if (it.find("SqlTable") != std::string::npos && (begin = it.find("\"")) != std::string::npos && (end = it.rfind("\"")) != std::string::npos) {
-				result.sql_table_name = it.substr(begin + 1, end - begin - 1);
-			}
 		}
-
-	}
-	//获取属性
-	std::vector<PropertyInfo> getPropertys(std::string code) {
-		std::vector<PropertyInfo> result;
-		code.erase(code.find("{"), 1);
-		code.erase(code.rfind("}"), 1);
-
-		std::vector<std::string> propertyCodes = v3::utils::split(code, ";");
-
-		for (auto& prop : propertyCodes) {
-			PropertyInfo add;
-			//提取特性
-			{
-				std::regex pattern("\\[\\[(.*?)\\]\\]");
-				std::smatch smatch;
-				while (std::regex_search(prop, smatch, pattern)) {
-					std::string attribute = smatch[1];
-
-					std::string Json = "Json";
-					std::string NoJson = "NoJson";
-					std::string Sql = "Sql";
-					std::string NoSql = "NoSql";
-					std::string SqlKey = "SqlKey";
-					std::string Excel = "Excel";
-					std::string NoExcel = "NoExcel";
-					std::string NoArchive = "NoArchive";
-
-					if (attribute.size() > Json.size() && attribute.substr(0, Json.size()) == Json) {
-						auto values = v3::utils::split(attribute, "\"");
-						if (values.size() == 3) {
-							add.json_name = values[1];
-							std::size_t pos = values[2].find("false");
-							add.no_json = pos != std::string::npos;
-						}
+	};
+
+	struct class_parameter_info {
+		class_parameter_info() {}
+		class_parameter_info(std::string code) :
+			content(code) {
+			deserialize(code);
+		}
+		std::string							content;
+		std::string							type;
+		std::string							name;
+		std::vector<class_attribute_info>	attributes;
+		std::string generate_cntlr_code(std::string const& method_type) {
+			static std::map<std::string, std::string> type_map = {
+				{"int",									"robotics::v3::mvc::argument_type::Int"},
+				{"std::int64_t",						"robotics::v3::mvc::argument_type::Int64"},
+				{"float",								"robotics::v3::mvc::argument_type::Float"},
+				{"double",								"robotics::v3::mvc::argument_type::Double"},
+				{"long",								"robotics::v3::mvc::argument_type::Long"},
+				{"bool",								"robotics::v3::mvc::argument_type::Bool_"},
+				{"std::string",							"robotics::v3::mvc::argument_type::String"},
+				{"robotics::v3::datetime",				"robotics::v3::mvc::argument_type::DateTime"},
+				{"v3::datetime",						"robotics::v3::mvc::argument_type::DateTime"},
+				{"datetime",							"robotics::v3::mvc::argument_type::DateTime"},
+				{"std::vector<std::uint8_t>",			"robotics::v3::mvc::argument_type::Binary"},
+				{"std::vector<int>",					"robotics::v3::mvc::argument_type::VecInt"},
+				{"std::vector<std::int64_t>",			"robotics::v3::mvc::argument_type::VecInt64"},
+				{"std::vector<float>",					"robotics::v3::mvc::argument_type::VecFloat"},
+				{"std::vector<double>",					"robotics::v3::mvc::argument_type::VecDouble"},
+				{"std::vector<long>",					"robotics::v3::mvc::argument_type::VecLong"},
+				{"std::vector<bool>",					"robotics::v3::mvc::argument_type::VecBool"},
+				{"std::vector<std::string>",			"robotics::v3::mvc::argument_type::VecString"},
+				{"std::vector<robotics::v3::datetime>",	"robotics::v3::mvc::argument_type::VecDateTime"},
+				{"std::vector<v3::datetime>",			"robotics::v3::mvc::argument_type::VecDateTime"},
+				{"std::vector<datetime>",				"robotics::v3::mvc::argument_type::VecDateTime"},
+				{"VecJson",								"robotics::v3::mvc::argument_type::VecJson"},
+				{"Json",								"robotics::v3::mvc::argument_type::Json"},
+				{"Multipart",							"robotics::v3::mvc::argument_type::Multipart"}
+			};
+			auto FromQuery = utils::attribute::find(attributes, "FromQuery");
+			auto FromBody = utils::attribute::find(attributes, "FromBody");
+			auto FromHeader = utils::attribute::find(attributes, "FromHeader");
+			auto FromUrl = utils::attribute::find(attributes, "FromUrl");
+			std::stringstream ss;
+			ss << "\t\t{" << std::endl;
+			ss << "\t\t\tstd::shared_ptr<robotics::v3::mvc::action_argument> argument(new robotics::v3::mvc::action_argument());" << std::endl;
+			if (type_map.contains(type)) {
+				ss << "\t\t\targument->argument_type_ = " << type_map[type] << ";" << std::endl;
+				if (method_type == "POST") {
+					if (!FromQuery.empty()) {
+						ss << "\t\t\targument->from_storage_type_ = robotics::v3::mvc::from_storage_type::QUERY;" << std::endl;
+						ss << fmt::format("\t\t\targument->parameter_name_ = \"{}\";", FromQuery[0].string_value.empty() ? name : FromQuery[0].string_value) << std::endl;
 					}
-					else if (attribute.size() > NoJson.size() && attribute.substr(0, NoJson.size()) == NoJson) {
-						attribute = v3::utils::to_upper(attribute);
-						if (attribute.find("TRUE") != std::string::npos) {
-							add.no_json = true;
-						}
+					else if (!FromBody.empty()) {
+						ss << "\t\t\targument->from_storage_type_ = robotics::v3::mvc::from_storage_type::BODY;" << std::endl;
+						ss << fmt::format("\t\t\targument->parameter_name_ = \"{}\";", FromBody[0].string_value) << std::endl;
 					}
-					else if (attribute.size() > SqlKey.size() && attribute.substr(0, SqlKey.size()) == SqlKey) {
-						attribute = v3::utils::to_upper(attribute);
-						if (attribute.find("TRUE") != std::string::npos) {
-							add.sql_key = true;
-						}
+					else if (!FromHeader.empty()) {
+						ss << "\t\t\targument->from_storage_type_ = robotics::v3::mvc::from_storage_type::HEADER;" << std::endl;
+						ss << fmt::format("\t\t\targument->parameter_name_ = \"{}\";", FromHeader[0].string_value.empty() ? name : FromHeader[0].string_value) << std::endl;
 					}
-					else if (attribute.size() > Sql.size() && attribute.substr(0, Sql.size()) == Sql) {
-						auto values = v3::utils::split(attribute, "\"");
-						if (values.size() == 3) {
-							add.sql_name = values[1];
-							std::size_t pos = values[2].find("false");
-							add.no_sql = pos != std::string::npos;
-						}
+					else {
+						ss << "\t\t\targument->from_storage_type_ = robotics::v3::mvc::from_storage_type::BODY;" << std::endl;
+						ss << fmt::format("\t\t\targument->parameter_name_ = \"{}\";", name) << std::endl;
 					}
-					else if (attribute.size() > NoSql.size() && attribute.substr(0, NoSql.size()) == NoSql) {
-						attribute = v3::utils::to_upper(attribute);
-						if (attribute.find("TRUE") != std::string::npos) {
-							add.no_sql = true;
-						}
+				}
+				else {
+					if (!FromQuery.empty()) {
+						ss << "\t\t\targument->from_storage_type_ = robotics::v3::mvc::from_storage_type::QUERY;" << std::endl;
+						ss << fmt::format("\t\t\targument->parameter_name_ = \"{}\";", FromQuery[0].string_value.empty() ? name : FromQuery[0].string_value) << std::endl;
 					}
-
-					else if (attribute.size() > Excel.size() && attribute.substr(0, Excel.size()) == Excel) {
-						auto values = v3::utils::split(attribute, "\"");
-						if (values.size() == 3) {
-							add.excel_name = values[1];
-							std::size_t pos = values[2].find("false");
-							add.no_excel = pos != std::string::npos;
-						}
+					else if (!FromUrl.empty()) {
+						ss << "\t\t\targument->from_storage_type_ = robotics::v3::mvc::from_storage_type::URL;" << std::endl;
+						ss << fmt::format("\t\t\targument->parameter_name_ = \"{}\";", FromUrl[0].string_value.empty() ? name : FromUrl[0].string_value) << std::endl;
 					}
-					else if (attribute.size() > NoExcel.size() && attribute.substr(0, NoExcel.size()) == NoExcel) {
-						attribute = v3::utils::to_upper(attribute);
-						if (attribute.find("TRUE") != std::string::npos) {
-							add.no_excel = true;
-						}
+					else if (!FromHeader.empty()) {
+						ss << "\t\t\targument->from_storage_type_ = robotics::v3::mvc::from_storage_type::HEADER;" << std::endl;
+						ss << fmt::format("\t\t\targument->parameter_name_ = \"{}\";", FromHeader[0].string_value.empty() ? name : FromHeader[0].string_value) << std::endl;
 					}
-					else if (attribute.size() > NoArchive.size() && attribute.substr(0, NoArchive.size()) == NoArchive) {
-						attribute = v3::utils::to_upper(attribute);
-						if (attribute.find("TRUE") != std::string::npos) {
-							add.no_archive = true;
-						}
+					else {
+						ss << "\t\t\targument->from_storage_type_ = robotics::v3::mvc::from_storage_type::QUERY;" << std::endl;
+						ss << fmt::format("\t\t\targument->parameter_name_ = \"{}\";", name) << std::endl;
 					}
-					prop = smatch.suffix();
 				}
 			}
-			//提取属性
-			{
-				std::regex pattern("([a-zA-Z_0-9:<>]{1,100})[ \r\n\t]{1,30}([a-zA-Z_0-9]{1,100})");
-				std::smatch smatch;
-				if (std::regex_search(prop, smatch, pattern)) {
-					if (smatch.size() == 3 &&
-						((smatch[1].str().find('<') != std::string::npos && smatch[1].str().find('>') != std::string::npos) ||
-							(smatch[1].str().find('<') == std::string::npos && smatch[1].str().find('>') == std::string::npos))) {
-						add.type_name = smatch[1];
-						add.prop_name = smatch[2];
-						add.json_name = add.json_name.empty() ? add.prop_name : add.json_name;
-						add.sql_name = add.sql_name.empty() ? add.prop_name : add.sql_name;
-						add.excel_name = add.excel_name.empty() ? add.prop_name : add.excel_name;
-						result.push_back(add);
+			else if (type == "robotics::v3::mvc::multipart_value" || type == "v3::mvc::multipart_value" || type == "mvc::multipart_value") {
+				ss << "\t\t\targument->argument_type_ = " << type_map["Multipart"] << ";" << std::endl;
+				ss << "\t\t\targument->from_storage_type_ = robotics::v3::mvc::from_storage_type::BODY;" << std::endl;
+				ss << "\t\t\targument->parameter_name_ = "";" << std::endl;
+			}
+			else if (type.size() > 12 && type.substr(0, 11) == "std::vector") {
+				ss << "\t\t\targument->argument_type_ = " << type_map["VecJson"] << ";" << std::endl;
+				ss << "\t\t\targument->from_storage_type_ = robotics::v3::mvc::from_storage_type::BODY;" << std::endl;
+				ss << "\t\t\targument->parameter_name_ = "";" << std::endl;
+			}
+			else {
+				ss << "\t\t\targument->argument_type_ = " << type_map["Json"] << ";" << std::endl;
+				ss << "\t\t\targument->from_storage_type_ = robotics::v3::mvc::from_storage_type::BODY;" << std::endl;
+				ss << "\t\t\targument->parameter_name_ = "";" << std::endl;
+			}
+			ss << "\t\t\taction->arguments.push_back(argument);" << std::endl;
+			ss << "\t\t}" << std::endl;
+			return ss.str();
+		}
+		std::string generate_soap_code() {
+			static std::map<std::string, std::string> type_map = {
+				{"int","robotics::v3::soap_argument_type::Int"},
+				{"std::int64_t","robotics::v3::soap_argument_type::Int64"},
+				{"float","robotics::v3::soap_argument_type::Float"},
+				{"double","robotics::v3::soap_argument_type::Double"},
+				{"long","robotics::v3::soap_argument_type::Long"},
+				{"bool","robotics::v3::soap_argument_type::Bool_"},
+				{"std::string","robotics::v3::soap_argument_type::String"},
+				{"robotics::v3::datetime","robotics::v3::soap_argument_type::DateTime"},
+				{"v3::datetime","robotics::v3::soap_argument_type::DateTime"},
+				{"datetime","robotics::v3::soap_argument_type::DateTime"}
+			};
+			std::stringstream ss;
+			ss << "\t\t{" << std::endl;
+			ss << "\t\t\tstd::shared_ptr<robotics::v3::soap_action_argument> argument(new robotics::v3::soap_action_argument());" << std::endl;
+			if (type_map.contains(type)) {
+				ss << fmt::format("\t\t\targument->argument_type_ = {};", type_map[type]) << std::endl;
+			}
+			ss << fmt::format("\t\t\targument->parameter_name_ = \"{}\";", name) << std::endl;
+			ss << "\t\t\taction->arguments.push_back(argument);" << std::endl;
+			ss << "\t\t}" << std::endl;
+			return ss.str();
+		}
+	private:
+		/**
+		 * @brief 反序列化
+		 * @param code
+		 */
+		void deserialize(std::string code) {
+			std::smatch smatch;
+			if (std::regex_search(code, smatch, utils::regex::parameter())) {
+				if (smatch.size() == 6) {
+					type = smatch[4];
+					name = smatch[5];
+					for (auto& it : get_attributes(smatch[1])) {
+						attributes.push_back(class_attribute_info(it));
 					}
 				}
-
 			}
 		}
-
-		return result;
-	}
-	//获取方法
-	std::vector<MethodInfo> getMethods(std::string code) {
-		std::vector<MethodInfo> result;
-		std::vector<std::pair<std::string, std::string>> funcList;
-		//提取方法列表
-		{
-			std::regex pattern("WebResponse[ \r\n\t]{1,30}[a-zA-Z_0-9]{1,100}[ \r\n\t]{0,30}\\([a-zA-Z0-9\",\\[\\], \r\n\t:<>_\\(\\)]{0,500}\\)");
+		/**
+		 * @brief 获取特性列表
+		 * @param code
+		 * @return
+		 */
+		std::vector<std::string> get_attributes(std::string code) {
+			std::vector<std::string> result;
 			std::smatch smatch;
-			while (std::regex_search(code, smatch, pattern)) {
-				std::string value = smatch[0];
-
-				std::size_t pos = code.find(value);
-
-				if (pos == std::string::npos)
-					break;
-				if (pos > 0)
-					pos--;
-				std::string func;
-				for (int i = pos; i >= 0; --i) {
-
-					if (code[i] == ']') {
-
-						int count = 0;
-
-						for (; i >= 0; --i) {
-
-							if (code[i] == '[')
-								count++;
-
-							func += code[i];
-							if (count == 2) {
-								i--;
-								break;
-							}
-						}
-					}
-
-					if (!(code[i] == '\r' || code[i] == '\n' || code[i] == '\t' || code[i] == ' ')) {
-						break;
-					}
+			while (std::regex_search(code, smatch, utils::regex::attribute())) {
+				if (smatch.size() == 3) {
+					result.push_back(smatch[0]);
 				}
-				std::reverse(func.begin(), func.end());
-				funcList.push_back(std::make_pair(value, func));
 				code = smatch.suffix();
 			}
+			return result;
 		}
-
-		for (auto& it : funcList) {
-			MethodInfo add;
-			//特性
-			methodAttribute(it.second, add);
-			methodParameter(it.first, add);
-			result.push_back(add);
+	};
+
+	struct class_method_info {
+		class_method_info() {}
+		class_method_info(std::string code) :
+			content(code) {
+			deserialize(code);
+		}
+		std::string							content;
+		std::string							result;
+		std::string							name;
+		std::string							signature;
+		std::vector<class_parameter_info>	parameters;
+		std::vector<class_attribute_info>	attributes;
+		std::string generate_code() {
+			if (parameters.empty()) {
+				return fmt::format("method(\"{}\",&{{}}::{})",
+					name,
+					name);
+			}
+			else {
+				std::vector<std::string> param_names;
+				std::vector<std::string> param_types;
+				for (auto& it : parameters) {
+					param_names.push_back(fmt::format("\"{}\"", it.name));
+					param_types.push_back(fmt::format("{}{{{{}}}}", it.type));
+				}
+				return fmt::format("method(\"{}\",&{{}}::{})(rttr::default_arguments({}),rttr::parameter_names({}))",
+					name,
+					name,
+					utils::string::join(param_types, ","),
+					utils::string::join(param_names, ","));
+			}
 		}
-		return result;
-	}
-	//提取特性
-	void methodAttribute(std::string code, MethodInfo& result) {
-		auto attributes = v3::utils::split(code, "]]");
-
-		for (auto it : attributes) {
-
-			std::size_t begin = 0;
-			std::size_t end = 0;
-
-			//[[ActionType("Page")]]
-			if (it.find("[[ActionType") != std::string::npos && (begin = it.find("\"")) != std::string::npos && (end = it.rfind("\"")) != std::string::npos) {
-				result.action_type = it.substr(begin + 1, end - begin - 1);
-			}
-			//[[Method("POST")]]
-			if (it.find("[[Method") != std::string::npos && (begin = it.find("\"")) != std::string::npos && (end = it.rfind("\"")) != std::string::npos) {
-				std::string value = it.substr(begin + 1, end - begin - 1);
-				if (value == "GET") {
-					result.method = "robotics::v3::mvc::http_method::GET";
+		std::string generate_cntlr_code() {
+			std::stringstream ss;
+			auto ActionType = utils::attribute::find(attributes, "ActionType");
+			auto Method = utils::attribute::find(attributes, "Method");
+			auto Authen = utils::attribute::find(attributes, "Authen");
+			auto Route = utils::attribute::find(attributes, "Route");
+			auto ContentType = utils::attribute::find(attributes, "ContentType");
+			auto FileMapping = utils::attribute::find(attributes, "FileMapping");
+			ss << "\t{" << std::endl;
+			ss << "\t\tstd::shared_ptr<robotics::v3::mvc::controller_action> action(new robotics::v3::mvc::controller_action());" << std::endl;
+			for (auto& it : parameters) {
+				if (!Method.empty()) {
+					ss << it.generate_cntlr_code(Method[0].string_value == "POST" ? "POST" : "GET");
 				}
 				else {
-					result.method = "robotics::v3::mvc::http_method::POST";
+					ss << it.generate_cntlr_code("GET");
 				}
 			}
-			//[[Authen(false,"Home/Index")]]
-			if (it.find("[[Authen") != std::string::npos && (begin = it.find("(")) != std::string::npos && (end = it.find(")")) != std::string::npos && (begin = it.find("\"")) != std::string::npos && (end = it.rfind("\"")) != std::string::npos) {
-
-				if (it.find("false") != std::string::npos) {
-					result.authen_jump = it.substr(begin + 1, end - begin - 1);
-					result.authen = false;
+			ss << fmt::format("\t\taction->action_name = \"{}\";", name) << std::endl;
+			ss << "\t\taction->parent = controller;" << std::endl;
+			if (!Authen.empty()) {
+				ss << fmt::format("\t\taction->authen = {};", Authen[0].bool_value ? "true" : "false") << std::endl;
+				ss << fmt::format("\t\taction->authen_jump = \"{}\";", Authen[0].string_value) << std::endl;
+			}
+			else {
+				ss << "\t\taction->authen = true;" << std::endl;
+				ss << "\t\taction->authen_jump = \"\";" << std::endl;
+			}
+			if (!ContentType.empty()) {
+				ss << fmt::format("\t\taction->content_type = \"{}\";", ContentType[0].string_value.empty() ? "application/x-www-form-urlencoded" : ContentType[0].string_value) << std::endl;
+			}
+			else {
+				ss << "\t\taction->content_type = \"application/x-www-form-urlencoded\";" << std::endl;
+			}
+			if (!ActionType.empty()) {
+				ss << fmt::format("\t\taction->action_type = \"{}\";", ActionType[0].string_value) << std::endl;
+			}
+			else {
+				ss << "\t\taction->action_type = \"\";" << std::endl;
+			}
+			if (!FileMapping.empty()) {
+				ss << fmt::format("\t\taction->file_mapping = \"{}\";", FileMapping[0].string_value) << std::endl;
+			}
+			else {
+				ss << "\t\taction->file_mapping = \"\";" << std::endl;
+			}
+			if (!Method.empty()) {
+				if (Method[0].string_value == "POST") {
+					ss << "\t\taction->method = robotics::v3::mvc::http_method::POST;" << std::endl;
 				}
 				else {
-					result.authen_jump = it.substr(begin + 1, end - begin - 1);
-					result.authen = true;
+					ss << "\t\taction->method = robotics::v3::mvc::http_method::GET;" << std::endl;
 				}
 			}
-			//[[Authen(false)]]	
-			else if (it.find("[[Authen") != std::string::npos && (begin = it.find("(")) != std::string::npos && (end = it.find(")")) != std::string::npos) {
-				std::string value = v3::utils::to_upper(it.substr(begin, end - begin + 1));
-				result.authen = value.find("FALSE") == std::string::npos;
+			else {
+				ss << "\t\taction->method = robotics::v3::mvc::http_method::GET;" << std::endl;
 			}
-			//[[Route("Account/Login")]]
-			if (it.find("[[Route") != std::string::npos && (begin = it.find("\"")) != std::string::npos && (end = it.rfind("\"")) != std::string::npos) {
-				result.route = it.substr(begin + 1, end - begin - 1);
-				if (result.route.find('<') != std::string::npos) {
-
-				}
+			if (!Route.empty()) {
+				ss << fmt::format("\t\tcontroller->actions[\"{}\"] = action;", Route[0].string_value.empty() ? name : Route[0].string_value) << std::endl;
+			}
+			else {
+				ss << fmt::format("\t\tcontroller->actions[\"{}\"] = action;", name) << std::endl;
 			}
-			//[[ContentType("application/x-www-form-urlencoded")]]
-			if (it.find("[[ContentType") != std::string::npos && (begin = it.find("\"")) != std::string::npos && (end = it.rfind("\"")) != std::string::npos) {
-				result.content_type = it.substr(begin + 1, end - begin - 1);
+			ss << "\t}" << std::endl;
+			return ss.str();
+		}
+		std::string generate_soap_code() {
+			auto Method = utils::attribute::find(attributes, "Method");
+			std::stringstream ss;
+			ss << "\t{" << std::endl;
+			ss << "\t\tstd::shared_ptr<robotics::v3::soap_controller_action> action(new robotics::v3::soap_controller_action());" << std::endl;
+			for (auto& it : parameters) {
+				ss << it.generate_soap_code();
 			}
-			//[[FileMapping("Account/Index.html")]]
-			if (it.find("[[FileMapping") != std::string::npos && (begin = it.find("\"")) != std::string::npos && (end = it.rfind("\"")) != std::string::npos) {
-				result.file_mapping = it.substr(begin + 1, end - begin - 1);
+			ss << fmt::format("\t\taction->action_name = \"{}\";", name) << std::endl;
+			if (!Method.empty()) {
+				ss << fmt::format("\t\tcontroller->actions[\"{}\"] = action;", Method[0].string_value.empty() ? name : Method[0].string_value) << std::endl;
+			}
+			else {
+				ss << fmt::format("\t\tcontroller->actions[\"{}\"] = action;", name) << std::endl;
+			}
+			ss << "\t}" << std::endl;
+			return ss.str();
+		}
+	private:
+		/**
+		 * @brief 反序列化
+		 * @param code
+		 */
+		void deserialize(std::string code) {
+			std::smatch smatch;
+			if (std::regex_search(code, smatch, utils::regex::method())) {
+				if (smatch.size() == 5) {
+					std::vector<std::string> params;
+					result = smatch[2];
+					name = smatch[3];
+					for (auto& it : get_parameters(smatch[4])) {
+						parameters.push_back(class_parameter_info(it));
+						params.push_back(parameters[parameters.size() - 1].type);
+					}
+					for (auto& it : get_attributes(smatch[1])) {
+						attributes.push_back(class_attribute_info(it));
+					}
+					signature = result + "(" + utils::string::join(params) + ")";
+				}
 			}
-
 		}
-
-	}
-	//
-	void methodParameter(std::string code, MethodInfo& result) {
-		bool succ = false;
-		std::string parameter;
-		std::string funcName;
-		//提取方法列表
-		{
-			std::regex pattern("WebResponse[ \r\n\t]{1,30}([a-zA-Z_0-9]{1,100})[ \r\n\t]{0,30}\\(([a-zA-Z0-9\",\\[\\], \r\n\t:<>_\\(\\)]{0,500})\\)");
+		/**
+		 * @brief 获取特性列表
+		 * @param code
+		 * @return
+		 */
+		std::vector<std::string> get_attributes(std::string code) {
+			std::vector<std::string> result;
 			std::smatch smatch;
-			if (std::regex_search(code, smatch, pattern)) {
+			while (std::regex_search(code, smatch, utils::regex::attribute())) {
 				if (smatch.size() == 3) {
-					succ = true;
-					funcName = smatch[1];
-					parameter = smatch[2];
+					result.push_back(smatch[0]);
 				}
+				code = smatch.suffix();
 			}
+			return result;
 		}
-
-		if (!succ)return;
-
-		std::vector<ParameterInfo> parameterValues;
-		{
-			auto parameters = v3::utils::split(parameter, ",");
-
-			for (auto& it : parameters) {
-				//带特性
-				{
-					std::regex pattern("\\[\\[(.*?)\\]\\][\r\n\t ]{0,30}([a-zA-Z_0-9<>:]{1,100})[\r\n\t ]{1,30}([a-zA-Z0-9_]{1,100})");
-					std::smatch smatch;
-					if (std::regex_search(it, smatch, pattern)) {
-						if (smatch.size() == 4) {
-							ParameterInfo add;
-							std::string attribute = smatch[1];
-							std::string paramType = smatch[2];
-							std::string paramName = smatch[3];
-							for (int i = 0; i < paramType.size(); ++i) {
-								if (paramType[i] == ' ') {
-									paramType.erase(i, 1);
-									--i;
-								}
-							}
-							parameterType(paramType, add);
-							parameterAttribute(attribute, add);
-							if (add.parameter_name.empty()) {
-								add.parameter_name = paramName;
+		/**
+		 * @brief 获取参数列表
+		 * @param code
+		 * @return
+		 */
+		std::vector<std::string> get_parameters(std::string code) {
+			std::vector<std::string> result;
+			std::smatch smatch;
+			while (std::regex_search(code, smatch, utils::regex::parameter())) {
+				if (smatch.size() == 6) {
+					result.push_back(smatch[0]);
+				}
+				code = smatch.suffix();
+			}
+			return result;
+		}
+	};
+
+	struct class_view_info {
+		class_view_info() {}
+		class_view_info(std::string code, int type) :
+			content(code),
+			class_type(type) {
+			deserialize(code);
+		}
+		int									class_type = 0;
+		std::string							content;
+		std::string							type;
+		std::string							name;
+		bool								is_tmpl = false;
+		std::vector<std::string>			tmpl_params;
+		std::vector<class_attribute_info>	attributes;
+		std::vector<class_property_info>	propertys;
+		std::vector<class_method_info>		cntlr_methods;
+		std::vector<class_method_info>		soap_methods;
+		std::pair<std::string, std::string> generate_code() {
+			std::stringstream ss;
+			std::string funcname = fmt::format("func_{}()", utils::string::generate_hex(16));
+			ss << "static void " << funcname << " {" << std::endl;
+			if (class_type == 0) {
+				auto SqlTable = utils::attribute::find(attributes, "SqlTable");
+				auto NoReflect = utils::attribute::find(attributes, "NoReflect");
+				auto TemplateType = utils::attribute::find(attributes, "TemplateType");
+				if (NoReflect.empty() || (!NoReflect.empty() && !NoReflect[0].bool_value)) {
+					if (!is_tmpl) {
+						std::vector<std::string> item;
+						item.push_back(fmt::format("\trttr::registration::class_<{} {}>(\"{}\").constructor<>()(rttr::detail::as_object{{}})", type, name, SqlTable.empty() ? name : SqlTable[0].string_value));
+						for (auto it : propertys) {
+							item.push_back(fmt::vformat(it.generate_code(), fmt::make_format_args(name)));
+						}
+						if (item.size() > 1) {
+							ss << utils::string::join(item, ".\n\t\t") << ";" << std::endl;
+						}
+					}
+					else {
+						std::vector<std::string> class_propertys;
+						for (auto it : propertys) {
+							class_propertys.push_back(it.generate_code());
+						}
+						for (auto it : TemplateType) {
+							std::vector<std::string> item;
+							std::string tablename = name + "<" + utils::string::join(it.vector_string_value, ",") + ">";
+							item.push_back(fmt::format("\trttr::registration::class_<{} {}>(\"{}\").constructor<>()(rttr::detail::as_object{{}})", type, tablename, tablename));
+							for (auto it1 : class_propertys) {
+								item.push_back(fmt::vformat(it1, fmt::make_format_args(tablename)));
 							}
-							if (add.parameter_name == " ") {
-								add.parameter_name = "";
+							if (item.size() > 1) {
+								ss << utils::string::join(item, ".\n\t\t") << ";" << std::endl;
 							}
-							add.name = paramName;
-							add.type = paramType;
-							parameterValues.push_back(add);
-							continue;
 						}
 					}
 				}
-				//不带特性
-				{
-					std::regex pattern("([a-zA-Z_0-9<>:]{1,100})[\r\n\t ]{1,30}([a-zA-Z0-9_]{1,100})");
-					std::smatch smatch;
-					if (std::regex_search(it, smatch, pattern)) {
-						if (smatch.size() == 3) {
-							ParameterInfo add;
-							std::string paramType = smatch[1];
-							std::string paramName = smatch[2];
-							for (int i = 0; i < paramType.size(); ++i) {
-								if (paramType[i] == ' ') {
-									paramType.erase(i, 1);
-									--i;
-								}
-							}
-							parameterType(paramType, add);
-							add.name = paramName;
-							add.type = paramType;
-							add.parameter_name = paramName;
-							parameterValues.push_back(add);
-							continue;
-						}
+
+			}
+			else if (class_type == 1) {
+				auto NoReflect = utils::attribute::find(attributes, "NoReflect");
+				if (NoReflect.empty() || (!NoReflect.empty() && !NoReflect[0].bool_value)) {
+					std::vector<std::string> item;
+					item.push_back(fmt::format("\trttr::registration::class_<{} {}>(\"{}\").constructor<>()()", type, name, name));
+					for (auto it : cntlr_methods) {
+						item.push_back(fmt::vformat(it.generate_code(), fmt::make_format_args(name)));
+					}
+					if (item.size() > 1) {
+						ss << utils::string::join(item, ".\n\t\t") << ";" << std::endl;
 					}
 				}
+				ss << "\tstd::shared_ptr<robotics::v3::mvc::controller> controller(new robotics::v3::mvc::controller());" << std::endl;
+				for (auto& it : cntlr_methods) {
+					ss << it.generate_cntlr_code();
+				}
+				ss << fmt::format("\tcontroller->controller_name = \"{}\";", name) << std::endl;
+				ss << "\trobotics::v3::mvc::ico_controller::attach(controller);" << std::endl;
 			}
-		}
-		result.parameters = parameterValues;
-
-		std::string signature = "WebResponse({})";
-
-		std::vector<std::string> tmpParams;
-
-		for (auto& it : result.parameters) {
-			tmpParams.push_back(it.type);
-		}
-
-		signature = v3::utils::format(signature, v3::utils::join(tmpParams, ","));
-
-		result.signature = signature;
-
-		result.name = funcName;
-	}
-	void parameterType(std::string code, ParameterInfo& parameter) {
-		if (code == "robotics::v3::mvc::multipart_value" || code == "v3::mvc::multipart_value" || code == "mvc::multipart_value" || code == "multipart_value") {
-			parameter.argument_type = "robotics::v3::mvc::argument_type::Multipart";
-		}
-		else if (code == "int") {
-			parameter.argument_type = "robotics::v3::mvc::argument_type::Int";
-		}
-		else if (code == "std::uint64_t") {
-			parameter.argument_type = "robotics::v3::mvc::argument_type::Int64";
-		}
-		else if (code == "float") {
-			parameter.argument_type = "robotics::v3::mvc::argument_type::Float";
-		}
-		else if (code == "double") {
-			parameter.argument_type = "robotics::v3::mvc::argument_type::Double";
-		}
-		else if (code == "long") {
-			parameter.argument_type = "robotics::v3::mvc::argument_type::Long";
-		}
-		else if (code == "bool") {
-			parameter.argument_type = "robotics::v3::mvc::argument_type::Bool_";
-		}
-		else if (code == "std::string") {
-			parameter.argument_type = "robotics::v3::mvc::argument_type::String";
-		}
-		else if (code == "robotics::v3::datetime" || code == "v3::datetime" || code == "datetime") {
-			parameter.argument_type = "robotics::v3::mvc::argument_type::DateTime";
-		}
-		else if (code == "std::vector<std::uint8_t>") {
-			parameter.argument_type = "robotics::v3::mvc::argument_type::Binary";
-		}
-		else if (code == "std::vector<int>") {
-			parameter.argument_type = "robotics::v3::mvc::argument_type::VecInt";
-		}
-		else if (code == "std::vector<std::uint64_t>") {
-			parameter.argument_type = "robotics::v3::mvc::argument_type::VecInt64";
-		}
-		else if (code == "std::vector<float>") {
-			parameter.argument_type = "robotics::v3::mvc::argument_type::VecFloat";
-		}
-		else if (code == "std::vector<double>") {
-			parameter.argument_type = "robotics::v3::mvc::argument_type::VecDouble";
-		}
-		else if (code == "std::vector<long>") {
-			parameter.argument_type = "robotics::v3::mvc::argument_type::VecLong";
-		}
-		else if (code == "std::vector<bool>") {
-			parameter.argument_type = "robotics::v3::mvc::argument_type::VecBool";
-		}
-		else if (code == "std::vector<std::string>") {
-			parameter.argument_type = "robotics::v3::mvc::argument_type::VecString";
-		}
-		else if (code == "std::vector<robotics::v3::datetime>" || code == "std::vector<v3::datetime>" || code == "std::vector<datetime>") {
-			parameter.argument_type = "robotics::v3::mvc::argument_type::VecDateTime";
-		}
-		else if (code.size() > 12 && code.substr(0, 11) == "std::vector") {
-			parameter.argument_type = "robotics::v3::mvc::argument_type::VecJson";
-		}
-		else {
-			parameter.argument_type = "robotics::v3::mvc::argument_type::Json";
-		}
-	}
-	void parameterAttribute(std::string code, ParameterInfo& parameter) {
-
-		std::size_t begin = 0;
-		std::size_t end = 0;
-
-		//FromQuery
-		if (code.find("FromQuery") != std::string::npos && (begin = code.find("\"")) != std::string::npos && (end = code.rfind("\"")) != std::string::npos) {
-			parameter.from_storage_type = "robotics::v3::mvc::from_storage_type::QUERY";
-			parameter.parameter_name = code.substr(begin + 1, end - begin - 1);
-		}
-		//FromBody
-		else if (code.find("FromBody") != std::string::npos && (begin = code.find("\"")) != std::string::npos && (end = code.rfind("\"")) != std::string::npos) {
-			parameter.from_storage_type = "robotics::v3::mvc::from_storage_type::BODY";
-			parameter.parameter_name = code.substr(begin + 1, end - begin - 1);
-			if (parameter.parameter_name.empty()) {
-				parameter.parameter_name = " ";
+			else if (class_type == 2) {
+				auto NoReflect = utils::attribute::find(attributes, "NoReflect");
+				auto Route = utils::attribute::find(attributes, "Route");
+				auto Version = utils::attribute::find(attributes, "Version");
+				auto Namespace = utils::attribute::find(attributes, "Namespace");
+				auto Wsdl = utils::attribute::find(attributes, "Wsdl");
+				if (NoReflect.empty() || (!NoReflect.empty() && !NoReflect[0].bool_value)) {
+					std::vector<std::string> item;
+					item.push_back(fmt::format("\trttr::registration::class_<{} {}>(\"{}\").constructor<>()()", type, name, name));
+					for (auto it : soap_methods) {
+						item.push_back(fmt::vformat(it.generate_code(), fmt::make_format_args(name)));
+					}
+					if (item.size() > 1) {
+						ss << utils::string::join(item, ".\n\t\t") << ";" << std::endl;
+					}
+					ss << "\tstd::shared_ptr<robotics::v3::soap_controller> controller(new robotics::v3::soap_controller());" << std::endl;
+					for (auto& it : soap_methods) {
+						ss << it.generate_soap_code();
+					}
+					ss << fmt::format("\tcontroller->controller_name = \"{}\";", name) << std::endl;
+					if (!Wsdl.empty()) {
+						ss << fmt::format("\tcontroller->wsdl = \"{}\";", Wsdl[0].string_value) << std::endl;
+					}
+					else {
+						ss << "\tstatic_assert(false, \"wsdl path error\");" << std::endl;
+					}
+					if (!Route.empty()) {
+						ss << fmt::format("\tcontroller->route = \"{}\";", Route[0].string_value) << std::endl;
+					}
+					else {
+						ss << "\tstatic_assert(false, \"route path error\");" << std::endl;
+					}
+					if (!Namespace.empty()) {
+						ss << fmt::format("\tcontroller->namespace_name = \"{}\";", Namespace[0].string_value) << std::endl;
+					}
+					else {
+						ss << "\tstatic_assert(false, \"namespace path error\");" << std::endl;
+					}
+					if (!Version.empty()) {
+						ss << fmt::format("\tcontroller->version = {};", Version[0].string_value == "1.1" ? "robotics::v3::soap_version::VER1_1" : "robotics::v3::soap_version::VER1_2") << std::endl;
+					}
+					else {
+						ss << "\tcontroller->version = robotics::v3::soap_version::VER1_1;" << std::endl;
+					}
+					ss << "\trobotics::v3::soap_ioc_controller::attach(controller);" << std::endl;
+				}
 			}
-		}
-		//FromHeader
-		else if (code.find("FromHeader") != std::string::npos && (begin = code.find("\"")) != std::string::npos && (end = code.rfind("\"")) != std::string::npos) {
-			parameter.from_storage_type = "robotics::v3::mvc::from_storage_type::HEADER";
-			parameter.parameter_name = code.substr(begin + 1, end - begin - 1);
-		}
-		//FromUrl
-		else if (code.find("FromUrl") != std::string::npos && (begin = code.find("\"")) != std::string::npos && (end = code.rfind("\"")) != std::string::npos) {
-			parameter.from_storage_type = "robotics::v3::mvc::from_storage_type::URL";
-			parameter.parameter_name = code.substr(begin + 1, end - begin - 1);
-		}
-	}
-
-	void getSoapAttribute(std::string code, class_view_info& result) {
-		std::size_t begin = 0;
-		std::size_t end = 0;
-
-		//Version
-		if (code.find("Version") != std::string::npos && (begin = code.find("\"")) != std::string::npos && (end = code.rfind("\"")) != std::string::npos) {
-			result.soap_version = code.substr(begin + 1, end - begin - 1);
-		}
-		//Namepsace
-		else if (code.find("Namespace") != std::string::npos && (begin = code.find("\"")) != std::string::npos && (end = code.rfind("\"")) != std::string::npos) {
-			result.soap_namepsace = code.substr(begin + 1, end - begin - 1);
-		}
-		//Route
-		else if (code.find("Route") != std::string::npos && (begin = code.find("\"")) != std::string::npos && (end = code.rfind("\"")) != std::string::npos) {
-			result.soap_route = code.substr(begin + 1, end - begin - 1);
-		}
-		//Wsdl
-		else if (code.find("Wsdl") != std::string::npos && (begin = code.find("\"")) != std::string::npos && (end = code.rfind("\"")) != std::string::npos) {
-			result.soap_wsdl = code.substr(begin + 1, end - begin - 1);
-		}
-	}
-	std::vector<soap_method_info> getSoapMethods(std::string code) {
-		std::vector<soap_method_info> result;
-		std::vector<std::pair<std::string, std::string>> funcList;
-		//提取方法列表
-		{
-			std::regex pattern("SoapResponse[ \r\n\t]{1,30}[a-zA-Z_0-9]{1,100}[ \r\n\t]{0,30}\\([a-zA-Z0-9\",\\[\\], \r\n\t:<>_\\(\\)]{0,500}\\)");
+			ss << "}" << std::endl;
+			return std::pair(funcname, ss.str());
+		}
+	private:
+		/**
+		 * @brief
+		 * @param code
+		 */
+		void deserialize(std::string code) {
 			std::smatch smatch;
-			while (std::regex_search(code, smatch, pattern)) {
-				std::string value = smatch[0];
-
-				std::size_t pos = code.find(value);
-
-				if (pos == std::string::npos)
-					break;
-				if (pos > 0)
-					pos--;
-				std::string func;
-				for (int i = pos; i >= 0; --i) {
-
-					if (code[i] == ']') {
-
-						int count = 0;
-
-						for (; i >= 0; --i) {
-
-							if (code[i] == '[')
-								count++;
-
-							func += code[i];
-							if (count == 2) {
-								i--;
-								break;
+			if (std::regex_search(code, smatch, utils::regex::class_())) {
+				if (smatch.size() == 5) {
+					std::string tmp_code = smatch.suffix();
+					std::size_t index = tmp_code.find('{');
+					if (index != std::string::npos && utils::string::ergodic(tmp_code, index)) {
+						tmpl_params = get_tmpl_params(smatch[1]);
+						type = smatch[2];
+						name = smatch[4];
+						is_tmpl = !smatch[1].str().empty();
+						for (auto& it : get_attributes(smatch[3])) {
+							attributes.push_back(class_attribute_info(it));
+						}
+						if (class_type == 0) {
+							for (auto& it : get_propertys(tmp_code.substr(0, index + 1))) {
+								propertys.push_back(class_property_info(it));
+							}
+						}
+						else if (class_type == 1) {
+							for (auto& it : get_methods(tmp_code.substr(0, index + 1))) {
+								cntlr_methods.push_back(class_method_info(it));
 							}
 						}
+						else if (class_type == 2) {
+							for (auto& it : get_methods(tmp_code.substr(0, index + 1))) {
+								soap_methods.push_back(class_method_info(it));
+							}
+						}
+						code = smatch.suffix().str().substr(index + 1);
 					}
-
-					if (!(code[i] == '\r' || code[i] == '\n' || code[i] == '\t' || code[i] == ' ')) {
-						break;
+					else {
+						code = smatch.suffix();
 					}
 				}
-				std::reverse(func.begin(), func.end());
-				funcList.push_back(std::make_pair(value, func));
+				else {
+					code = smatch.suffix();
+				}
+			}
+		}
+		/**
+		 * @brief 获取特性列表
+		 * @param code
+		 * @return
+		 */
+		std::vector<std::string> get_attributes(std::string code) {
+			std::vector<std::string> result;
+			std::smatch smatch;
+			while (std::regex_search(code, smatch, utils::regex::attribute())) {
+				if (smatch.size() == 3) {
+					result.push_back(smatch[0]);
+				}
 				code = smatch.suffix();
 			}
+			return result;
 		}
-
-		for (auto& it : funcList) {
-			soap_method_info add;
-			//特性
-			soapMethodAttribute(it.second, add);
-			soapMethodParameter(it.first, add);
-			result.push_back(add);
+		/**
+		 * @brief 获取模板参数名称
+		 * @param code
+		 * @return
+		 */
+		std::vector<std::string> get_tmpl_params(std::string code) {
+			std::vector<std::string> result;
+			std::smatch smatch;
+			while (std::regex_search(code, smatch, utils::regex::template_())) {
+				if (smatch.size() == 2) {
+					auto params = utils::string::split(smatch[1]);
+					for (auto it : params) {
+						it = utils::string::replace(it, "typename", "");
+						result.push_back(utils::string::trim(it));
+					}
+				}
+				code = smatch.suffix();
+			}
+			return result;
 		}
-		return result;
-	}
-	void soapMethodAttribute(std::string code, soap_method_info& result) {
-		auto attributes = v3::utils::split(code, "]]");
-
-		for (auto it : attributes) {
-
-			std::size_t begin = 0;
-			std::size_t end = 0;
-
-			//[[Method("get")]]
-			if (it.find("Method") != std::string::npos && (begin = it.find("\"")) != std::string::npos && (end = it.rfind("\"")) != std::string::npos) {
-				result.action_name = it.substr(begin + 1, end - begin - 1);
+		/**
+		 * @brief 获取属性列表
+		 * @param code
+		 * @return
+		 */
+		std::vector<std::string> get_propertys(std::string code) {
+			std::vector<std::string> result;
+			std::smatch smatch;
+			while (std::regex_search(code, smatch, utils::regex::property())) {
+				if (smatch.size() == 4) {
+					result.push_back(smatch[0]);
+				}
+				code = smatch.suffix();
 			}
+			return result;
 		}
-	}
-	void soapMethodParameter(std::string code, soap_method_info& result) {
-		std::regex pattern("SoapResponse[ \r\n\t]{1,30}([a-zA-Z_0-9]{1,100})[ \r\n\t]{0,30}\\(([a-zA-Z0-9\",\\[\\], \r\n\t:<>_\\(\\)]{0,500})\\)");
-		std::smatch smatch;
-		std::vector<SoapParameterInfo> parameterValues;
-		while (std::regex_search(code, smatch, pattern)) {
-			if (smatch.size() == 3) {
-				result.name = smatch[1];
-				if (result.action_name.empty()) {
-					result.action_name = result.name;
+		/**
+		 * @brief
+		 * @param code
+		 * @return
+		 */
+		std::vector<std::string> get_methods(std::string code) {
+			std::vector<std::string> result;
+			std::smatch smatch;
+			while (std::regex_search(code, smatch, utils::regex::method())) {
+				if (smatch.size() == 5) {
+					result.push_back(smatch[0]);
 				}
-
-				auto parameters = v3::utils::split(smatch[2], ",");
-
-
-				for (auto& it : parameters)
-				{
-					std::regex pattern1("([a-zA-Z_0-9<>:]{1,100})[\r\n\t ]{1,30}([a-zA-Z0-9_]{1,100})");
-					std::smatch smatch1;
-					if (std::regex_search(it, smatch1, pattern1)) {
-						if (smatch1.size() == 3) {
-							SoapParameterInfo add;
-							std::string paramType = smatch1[1];
-							std::string paramName = smatch1[2];
-							for (int i = 0; i < paramType.size(); ++i) {
-								if (paramType[i] == ' ') {
-									paramType.erase(i, 1);
-									--i;
-								}
-							}
-							soapParameterType(paramType, add);
-							add.parameter_name = paramName;
-							add.type = paramType;
-							parameterValues.push_back(add);
-							continue;
-						}
+				code = smatch.suffix();
+			}
+			return result;
+		}
+	};
+
+	struct class_code_info {
+		class_code_info() {}
+		class_code_info(std::string code, int _type, std::string path, std::string relative_path) :
+			content(code),
+			type(_type),
+			root_directory(path),
+			relative_directory(relative_path) {
+			deserialize(code);
+		}
+		//0实体类,1web控制器,2saop控制器
+		int								type = 0;
+		std::string						root_directory;
+		std::string						content;
+		std::string						relative_directory;
+		std::vector<class_view_info>	views;
+		std::pair<std::vector<std::string>, std::string> generate_code() {
+			std::vector<std::string> funclist;
+			std::stringstream ss;
+			for (auto& it : views) {
+				auto view_code = it.generate_code();
+				funclist.push_back(view_code.first);
+				ss << view_code.second;
+			}
+			return std::pair(funclist, ss.str());
+		}
+	private:
+		/**
+		 * @brief
+		 * @param code
+		 */
+		void deserialize(std::string code) {
+			delete_excess(code);
+			std::smatch smatch;
+			while (std::regex_search(code, smatch, utils::regex::class_())) {
+				if (smatch.size() == 5) {
+					std::string src = smatch[0];
+					std::string tmp_code = smatch.suffix();
+					std::size_t index = tmp_code.find('{');
+					if (index != std::string::npos && utils::string::ergodic(tmp_code, index)) {
+						src += tmp_code.substr(0, index + 1);
+						views.push_back(class_view_info(src, type));
+						code = smatch.suffix().str().substr(index + 1);
+					}
+					else {
+						code = smatch.suffix();
 					}
-
 				}
-
+				else {
+					code = smatch.suffix();
+				}
 			}
-			break;
-		}
-
-		result.parameters = parameterValues;
-
-		std::string signature = "SoapResponse({})";
-
-		std::vector<std::string> tmpParams;
-
-		for (auto& it : result.parameters) {
-			tmpParams.push_back(it.type);
-		}
-
-		signature = v3::utils::format(signature, v3::utils::join(tmpParams, ","));
-
-		result.signature = signature;
-	}
-	void soapParameterType(std::string code, SoapParameterInfo& parameter) {
-
-		if (code == "int") {
-			parameter.argument_type = "robotics::v3::soap::soap_argument_type::Int";
 		}
-		else if (code == "std::uint64_t") {
-			parameter.argument_type = "robotics::v3::soap::soap_argument_type::Int64";
+		/**
+		 * @brief 删除注释
+		 * @param code
+		 */
+		void delete_excess(std::string& code) {
+			static std::vector<std::pair<std::string, std::string>> notes = {
+				{"/*","*/"},
+				{"//","\n"},
+				{"#include","\n"},
+				{"#pragma", "\n"},
+				{"#ifndef", "\n"},
+				{"#define", "\n"},
+				{"#if", "\n"},
+				{"#endif", "\n"}
+			};
+			for (auto& note : notes) {
+				std::size_t begin = 0;
+				std::size_t end = 0;
+				while ((begin = code.find(note.first, begin)) != std::string::npos && (end = code.find(note.second, begin)) != std::string::npos) {
+					if (begin > 0 && code[begin - 1] == ':') {
+						begin += note.second.size();
+						continue;
+					}
+					code.erase(begin, end - begin + note.second.size());
+				}
+			}
 		}
-		else if (code == "float") {
-			parameter.argument_type = "robotics::v3::soap::soap_argument_type::Float";
+	};
+
+	class code_analysis {
+	public:
+		static std::string generate_code(std::string const& path) {
+			std::stringstream ss;
+			std::vector<std::string> funclist;
+			//解析代码
+			auto values = code_analysis(path).get_class_code();
+			//生成时间
+			ss << "//生成时间:" << utils::string::current_time() << std::endl;
+			ss << "#pragma once" << std::endl;
+			ss << "#include <rttr/registration>" << std::endl;
+			ss << "#include <robotics/logger.hpp>" << std::endl;
+			//头文件
+			for (auto& it : values) {
+				ss << "#include \"" << it.relative_directory << "\"" << std::endl;
+			}
+			ss << std::endl;
+			for (auto& it : values) {
+				auto view_code = it.generate_code();
+				funclist.insert(funclist.end(), view_code.first.begin(), view_code.first.end());
+				ss << view_code.second;
+			}
+			ss << "RTTR_REGISTRATION {" << std::endl;
+			ss << "\t" << utils::string::join(funclist, ";\n\t") << ";" << std::endl;
+			ss << "}" << std::endl;
+			return ss.str();
+		}
+		static std::vector<class_code_info> get_class_code(std::string const& path) {
+			return code_analysis(path).get_class_code();
+		}
+	private:
+		code_analysis(std::string const& path) :
+			path_(path) {
+			path_ = utils::string::replace(path_, "\\", "/");
+			if (path_[path_.size() - 1] != '/') {
+				path_ += '/';
+			}
 		}
-		else if (code == "double") {
-			parameter.argument_type = "robotics::v3::soap::soap_argument_type::Double";
+		std::vector<class_code_info> get_class_code() {
+			std::vector<class_code_info> result;
+			auto values = get_models();
+			result.insert(result.end(), values.begin(), values.end());
+			values = get_controllers();
+			result.insert(result.end(), values.begin(), values.end());
+			values = get_webservices();
+			result.insert(result.end(), values.begin(), values.end());
+			return result;
 		}
-		else if (code == "long") {
-			parameter.argument_type = "robotics::v3::soap::soap_argument_type::Long";
+		std::vector<class_code_info> get_models() {
+			std::vector<class_code_info> result;
+			for (auto& it : get_files(path_ + "models", { ".h" })) {
+				result.push_back(class_code_info(get_code(path_ + it), 0, path_, it));
+			}
+			return result;
 		}
-		else if (code == "bool") {
-			parameter.argument_type = "robotics::v3::soap::soap_argument_type::Bool_";
+		std::vector<class_code_info> get_controllers() {
+			std::vector<class_code_info> result;
+			for (auto& it : get_files(path_ + "controllers", { ".hpp" })) {
+				result.push_back(class_code_info(get_code(path_ + it), 1, path_, it));
+				result[result.size() - 1].root_directory = path_;
+				result[result.size() - 1].relative_directory = it;
+				result[result.size() - 1].type = 1;
+			}
+			return result;
 		}
-		else if (code == "std::string") {
-			parameter.argument_type = "robotics::v3::soap::soap_argument_type::String";
+		std::vector<class_code_info> get_webservices() {
+			std::vector<class_code_info> result;
+			for (auto& it : get_files(path_ + "webservices", { ".hpp" })) {
+				result.push_back(class_code_info(get_code(path_ + it), 2, path_, it));
+				result[result.size() - 1].root_directory = path_;
+				result[result.size() - 1].relative_directory = it;
+				result[result.size() - 1].type = 2;
+			}
+			return result;
 		}
-		else if (code == "robotics::v3::datetime" || code == "v3::datetime" || code == "datetime") {
-			parameter.argument_type = "robotics::v3::soap::soap_argument_type::DateTime";
+		std::string get_code(std::string const& path) {
+			std::ifstream file(path, std::ios::out);
+			if (file.is_open()) {
+				return std::string((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
+			}
+			return "";
 		}
-		else {
-			parameter.argument_type = "robotics::v3::soap_argument_type::Json";
+		std::vector<std::string> get_files(std::string const& path, std::vector<std::string> const& extension) {
+			std::vector<std::string> result;
+			if (!std::filesystem::is_directory(path)) {
+				return result;
+			}
+			for (auto& itr : std::filesystem::directory_iterator(path)) {
+				if (std::filesystem::is_directory(itr.status())) {
+					auto values = get_files(itr.path().string(), extension);
+					result.insert(result.end(), values.begin(), values.end());
+				}
+				else {
+					if (std::find(extension.begin(), extension.end(), itr.path().extension()) != extension.end()) {
+						std::string tmp = itr.path().string();
+						tmp = utils::string::replace(tmp, "\\", "/");
+						tmp = utils::string::replace(tmp, path_, "");
+						result.push_back(tmp);
+					}
+				}
+			}
+			return result;
 		}
-	}
-private:
-	std::filesystem::path _path;
-};
-
-#endif //!__CODE_GENERATOR_CODE_ANALYSIS_H__
+	private:
+		std::string path_;
+	};
+}

+ 3 - 235
generator/main.cpp

@@ -4,241 +4,9 @@
 #include <chrono>
 #include "class_view.hpp"
 
-static std::string getCode(std::vector<class_view_info> classViews)
-{
-    std::string code;
-    // 获取当前时间点
-    auto now = std::chrono::system_clock::now();
-    std::time_t now_c = std::chrono::system_clock::to_time_t(now);
-    std::stringstream ss;
-    ss << std::put_time(std::localtime(&now_c), "%F %T");
-    //头文件
-    code += "//生成时间 " + ss.str() + "\n";
-    code += "#pragma once\n";
-    code += "#include <rttr/registration>\n";
-    for (auto& it : classViews) {
-        code += "#include \"" + it.include + "\"\n";
-    }
-
-
-    //生成实体类
-    code += "\n";
-    code += "static void __models_register__()\n";
-    code += "{\n";
-    for (auto& it : classViews) {
-        //生成实体类
-        if (it.class_type == 1) {
-            std::cout << "生成实体类反射代码,类名:" << it.class_name << std::endl;
-            std::cout << "                Sql表名:" << it.sql_table_name << std::endl;
-
-            if (!it.is_reflect) {
-                std::cout << "                不生成:" << it.sql_table_name << std::endl;
-                continue;
-            }
-            //非模板
-            if (!it.is_template) {
-                std::string modelCode = "\trttr::registration::class_<struct {0}>(\"{1}\").constructor<>()(rttr::detail::as_object{{}}).\n";
-                modelCode = v3::utils::format(modelCode, it.class_name, it.sql_table_name);
-                std::vector<std::string> propertyList;
-                for (auto& property : it.propertys) {
-                    std::cout << "                    属性:" << property.prop_name << std::endl;
-                    std::cout << "                     Sql:" << property.sql_name << std::endl;
-                    std::cout << "                    Json:" << property.json_name << std::endl;
-                    std::cout << "                   Excel:" << property.excel_name << std::endl;
-                    std::string propertyCode = "\t\tproperty(\"{0}\",&{1}::{2})(rttr::metadata(\"Json\",\"{3}\"),rttr::metadata(\"Sql\",\"{4}\"),rttr::metadata(\"Excel\",R\"({5})\"),rttr::metadata(\"NoJson\",{6}),rttr::metadata(\"NoSql\",{7}),rttr::metadata(\"NoExcel\",{8}),rttr::metadata(\"SqlKey\",{9}),rttr::metadata(\"Offset\",robotics::v3::utils::pointer_cast<int>(&{1}::{2})))";
-                    propertyCode = v3::utils::format(propertyCode, property.prop_name, it.class_name, property.prop_name, property.json_name, property.sql_name, (property.excel_name), (property.no_json ? "true" : "false"), (property.no_sql ? "true" : "false"), (property.no_excel ? "true" : "false"), (property.sql_key ? "true" : "false"));
-                    propertyList.push_back(propertyCode);
-                }
-                code += modelCode + v3::utils::join(propertyList, ".\n") + ";\n\n";
-            }
-            else {
-                std::string modelTemplate;
-                for (auto& templateProerty : it.template_parameters) {
-                    std::string modelCode = "\trttr::registration::class_<struct {0}<{1}>>(\"{2}<{3}>\").constructor<>()(rttr::detail::as_object{{}}).\n";
-                    modelCode = v3::utils::format(modelCode, it.class_name, templateProerty, it.sql_table_name, templateProerty);
-                    std::vector<std::string> propertyList;
-                    for (auto& property : it.propertys) {
-                        std::string propertyCode = "\t\tproperty(\"{0}\",&{1}<{2}>::{3})(rttr::metadata(\"Json\",\"{4}\"),rttr::metadata(\"Sql\",\"{5}\"),rttr::metadata(\"Excel\",R\"({6})\"),rttr::metadata(\"NoJson\",{7}),rttr::metadata(\"NoSql\",{8}),rttr::metadata(\"NoExcel\",{9}),rttr::metadata(\"SqlKey\",{10}),rttr::metadata(\"Offset\",robotics::v3::utils::pointer_cast<int>(&{1}<{2}>::{3})))";
-                        propertyCode = v3::utils::format(propertyCode, property.prop_name, it.class_name, templateProerty, property.prop_name, property.json_name, property.sql_name, (property.excel_name), (property.no_json ? "true" : "false"), (property.no_sql ? "true" : "false"), (property.no_excel ? "true" : "false"), (property.sql_key ? "true" : "false"));
-                        propertyList.push_back(propertyCode);
-                    }
-                    modelTemplate += modelCode + v3::utils::join(propertyList, ".\n") + ";\n\n";
-
-                }
-
-                code += modelTemplate;
-            }
-        }
-    }
-    code += "}\n";
-    //生成控制器
-    code += "\n";
-    code += "static void __controllers_register__()\n";
-    code += "{\n";
-    for (auto& it : classViews) {
-        //生成控制器
-        if (it.class_type == 0) {
-            std::cout << "生成控制器反射代码,类名:" << it.class_name << std::endl;
-            std::string controllerCode = "\trttr::registration::class_<class {0}>(\"{1}\").constructor<>()().\n";
-            controllerCode = v3::utils::format(controllerCode, it.class_name, it.class_name);
-            std::vector<std::string> methodList;
-            for (auto& method : it.methods) {
-                //无参数
-                if (method.parameters.empty()) {
-                    std::string methodCode = "\t\tmethod(\"{0}\",&{1}::{2})";
-                    methodCode = v3::utils::format(methodCode, method.name, it.class_name, method.name);
-                    methodList.push_back(methodCode);
-                }
-                //有参数
-                else {
-                    std::string methodCode = "\t\tmethod(\"{0}\",&{1}::{2})(rttr::default_arguments({3}),rttr::parameter_names({4}))";
-                    std::vector<std::string> parameterTypes;
-                    std::vector<std::string> parameters;
-                    for (auto& parameter : method.parameters) {
-                        parameters.push_back("\"" + parameter.name + "\"");
-                        parameterTypes.push_back(parameter.type + "{}");
-                    }
-                    methodCode = v3::utils::format(methodCode, method.name, it.class_name, method.name, v3::utils::join(parameterTypes, ","), v3::utils::join(parameters, ","));
-                    methodList.push_back(methodCode);
-                }
-            }
-            code += controllerCode + v3::utils::join(methodList, ".\n") + ";\n\n";
-        }
-    }
-    code += "}\n";
-    //生成soap
-    code += "\n";
-    code += "static void __soap_register__()\n";
-    code += "{\n";
-    for (auto& it : classViews) {
-        //生成soap
-        if (it.class_type == 2) {
-            std::cout << "生成SOPA反射代码,类名:" << it.class_name << std::endl;
-            std::string controllerCode = "\trttr::registration::class_<class {0}>(\"{1}\").constructor<>()().\n";
-            controllerCode = v3::utils::format(controllerCode, it.class_name, it.class_name);
-            std::vector<std::string> methodList;
-            for (auto& method : it.soap_methods) {
-                //无参数
-                if (method.parameters.empty()) {
-                    std::string methodCode = "\t\tmethod(\"{0}\",&{1}::{2})";
-                    methodCode = v3::utils::format(methodCode, method.name, it.class_name, method.name);
-                    methodList.push_back(methodCode);
-                }
-                //有参数
-                else {
-                    std::string methodCode = "\t\tmethod(\"{0}\",&{1}::{2})(rttr::parameter_names({3}))";
-                    std::vector<std::string> parameters;
-                    for (auto& parameter : method.parameters) {
-                        parameters.push_back("\"" + parameter.parameter_name + "\"");
-                    }
-                    methodCode = v3::utils::format(methodCode, method.name, it.class_name, method.name, v3::utils::join(parameters, ","));
-                    methodList.push_back(methodCode);
-                }
-            }
-            code += controllerCode + v3::utils::join(methodList, ".\n") + ";\n\n";
-        }
-    }
-    code += "}\n";
-    //注册控制器
-    code += "\n";
-    code += "static void __controllers_ioc_register__()\n";
-    code += "{\n";
-    for (auto& it : classViews) {
-        if (it.class_type != 0)
-            continue;
-        std::cout << "生成控制器Ioc代码,类名:" << it.class_name << std::endl;
-        code += "   {\n";
-        code += "       std::shared_ptr<robotics::v3::mvc::controller> controller(new robotics::v3::mvc::controller);\n";
-
-        for (auto& action : it.methods) {
-            code += "       {\n";
-            code += "           std::shared_ptr<robotics::v3::mvc::controller_action> action(new robotics::v3::mvc::controller_action);\n";
-            for (auto& argument : action.parameters) {
-                code += "           {\n";
-                code += "               std::shared_ptr<robotics::v3::mvc::action_argument> argument(new robotics::v3::mvc::action_argument);\n";
-                code += "               argument->argument_type_ = " + argument.argument_type + ";\n";
-                code += "               argument->from_storage_type_ = " + argument.from_storage_type + ";\n";
-                code += "               argument->parameter_name_ = \"" + argument.parameter_name + "\";\n";
-                code += "               action->arguments.push_back(argument);\n";
-                code += "           }\n";
-            }
-            code += "           action->action_name = \"" + action.name + "\";\n";
-            code += "           action->authen = " + (action.authen ? std::string("true") : std::string("false")) + ";\n";
-            code += "           action->authen_jump = \"" + action.authen_jump + "\";\n";
-            code += "           action->content_type = \"" + action.content_type + "\";\n";
-            code += "           action->action_type = \"" + action.action_type + "\";\n";
-            code += "           action->file_mapping = \"" + action.file_mapping + "\";\n";
-            code += "           action->method = " + action.method + ";\n";
-            code += "           action->parent = controller;\n";
-
-            if (action.route.empty()) {
-                code += "           controller->actions[\"" + it.class_name + "/" + action.name + "\"] = action;\n";
-            }
-            else {
-                code += "           controller->actions[\"" + action.route + "\"] = action;\n";
-            }
-            code += "       }\n";
-        }
-        code += "       controller->controller_name = \"" + it.class_name + "\";\n";
-        code += "       robotics::v3::mvc::ico_controller::attach(controller);\n";
-        code += "   }\n";
-    }
-    code += "}\n";
-    //注册soap
-    code += "\n";
-    code += "static void __soap_ioc_register__()\n";
-    code += "{\n";
-    for (auto& it : classViews) {
-        if (it.class_type != 2)
-            continue;
-        std::cout << "生成SOPAIoc代码,类名:" << it.class_name << std::endl;
-        code += "   {\n";
-        code += "       std::shared_ptr<robotics::v3::soap::soap_controller> controller(new robotics::v3::soap::soap_sontroller);\n";
-
-        for (auto& action : it.soap_methods) {
-            code += "       {\n";
-            code += "           std::shared_ptr<robotics::v3::soap::soap_controller_action> action(new robotics::v3::soap::soap_sontroller);\n";
-
-            for (auto& argument : action.parameters) {
-                code += "           {\n";
-                code += "               std::shared_ptr<robotics::v3::soap::soap_action_argument> argument(new robotics::v3::soap::soap_action_argument);\n";
-                code += "               argument->argument_type_ = " + argument.argument_type + ";\n";
-                code += "               argument->parameter_name_ = \"" + argument.parameter_name + "\";\n";
-                code += "               action->arguments.push_back(argument);\n";
-                code += "           }\n";
-            }
-
-            code += "           action->action_name = \"" + action.name + "\";\n";
-            code += "           controller->actions[\"" + action.action_name + "\"] = action;\n";
-            code += "       }\n";
-        }
-
-
-        code += "       controller->controller_name = \"" + it.class_name + "\";\n";
-        code += "       controller->wsdl = \"" + it.soap_wsdl + "\";\n";
-        code += "       controller->route = \"" + it.soap_route + "\";\n";
-        code += "       controller->namespace_name = \"" + it.soap_namepsace + "\";\n";
-        code += "       controller->version = " + (it.soap_version == "1.1" ? std::string("robotics::v3::soap::soap_version::VER1_1") : std::string("robotics::v3::soap::soap_version::VER1_2")) + ";\n";
-        code += "       robotics::v3::soap::soap_ioc_controller::attach(controller);\n";
-        code += "   }\n";
-    }
-    code += "}\n";
-
-    code += "\n";
-    code += "RTTR_REGISTRATION\n";
-    code += "{\n";
-    code += "   __models_register__();\n";
-    code += "   __controllers_register__();\n";
-    code += "   __soap_register__();\n";
-    code += "   __controllers_ioc_register__();\n";
-    code += "   __soap_ioc_register__();\n";
-    code += "}\n";
-
-    return code.c_str();
-}
-
 int main(int argc, char* argv[])
 {
+    system("chcp 65001");
     if (argc <= 0) {
         std::cout << "参数错误!" << std::endl;
         return -1;
@@ -255,8 +23,8 @@ int main(int argc, char* argv[])
         reflect_path = project_path + "/reflect.h";
     }
     std::cout << "项目反射文件:" << reflect_path << std::endl;
-    std::vector<class_view_info> classViews = code_analysis_core::getClassView(project_path);
-    std::string code = getCode(classViews);
+    //std::vector<class_view_info> classViews = code_analysis_core::getClassView(project_path);
+    std::string code = analysis::code_analysis::generate_code(project_path);
     std::cout << "项目反射代码生成完成" << std::endl;
     std::ofstream file(reflect_path, std::ios::out);
     if (!file.is_open()) {

+ 132 - 0
robot/robotics/http_client.hpp

@@ -0,0 +1,132 @@
+/**
+*
+*  @file http_client.hpp
+*  @author zxw
+*  Copyright 2024, yjrobotics.  All rights reserved.
+*
+*  robotics
+*
+*/
+#pragma once
+//asio2
+#include <asio2/asio2.hpp>
+
+namespace robotics::v3 {
+	class http_type{
+	public:
+		using HTTP  = asio2::http_client;
+		using HTTPS = asio2::https_client;
+	};
+	template<typename _HttpType, int _Count = 5>
+	class http_client {
+		typedef std::vector<std::pair<std::shared_ptr<_HttpType>, bool>> HttpClientType;
+		struct http_client_gc {
+			http_client_gc(std::shared_ptr<_HttpType>& client, std::mutex& mutex, HttpClientType& clients, std::condition_variable& cv) :
+				client_(client),
+				mutex_(mutex),
+				clients_(clients),
+				cv_(cv) {
+			}
+			~http_client_gc() {
+				std::lock_guard<std::mutex> locker(mutex_);
+				for (auto& it : clients_) {
+					if (it.first == client_) {
+						it.second = false;
+						break;
+					}
+				}
+				cv_.notify_one();
+			}
+		private:
+			std::mutex&					mutex_;
+			HttpClientType&				clients_;
+			std::condition_variable&	cv_;
+			std::shared_ptr<_HttpType>& client_;
+		};
+	public:
+		~http_client() {
+			stop();
+		}
+		/**
+		 * @brief 请求
+		 * @param req 
+		 * @param timeout 
+		 * @return 
+		 */
+		http::web_response execute(http::web_request&& req, int timeout) {
+			std::shared_ptr<_HttpType> client = get_client(timeout);
+			if (!client)
+				throw std::runtime_error("Http pool error!");
+			http_client_gc gc(client, client_mutex_, clients_, cv_);
+			if (!client->is_started())
+				client->start(req.host(), req.port());
+			if (asio2::get_last_error())
+				throw std::runtime_error(asio2::get_last_error_msg().c_str());
+			auto result = client->call<http::web_response>(std::move(req), std::chrono::milliseconds(timeout));
+			if (asio2::get_last_error()) {
+				std::string err = asio2::get_last_error_msg();
+				client->stop();
+				throw std::runtime_error(err.c_str());
+			}
+			return result;
+		}
+		/**
+		 * @brief 启动
+		 */
+		void start() {
+			run_ = true;
+		}
+		/**
+		 * @brief 停止
+		 */
+		void stop() {
+			run_ = false;
+			cv_.notify_all();
+		}
+	private:
+		std::shared_ptr<_HttpType> get_client(int timeout) {
+			std::shared_ptr<_HttpType> result;
+			std::unique_lock<std::mutex> locker(client_mutex_);
+			cv_.wait(locker, [&]() {
+				if (!run_)
+					return true;
+				//判断有没有可用连接
+				for (auto& it : clients_) {
+					if (!it.second) {
+						it.second = true;
+						result = it.first;
+						return true;
+					}
+				}
+				//判断是否添加
+				if (clients_.size() < _Count) {
+					auto item = std::make_pair(std::make_shared<_HttpType>(), true);
+					clients_.push_back(item);
+					result = item.first;
+					return true;
+				}
+				return false; });
+			result->set_connect_timeout(std::chrono::milliseconds(timeout));
+			return result;
+		}
+	private:
+		bool					run_ = false;
+		std::mutex				client_mutex_;
+		HttpClientType			clients_;
+		std::condition_variable cv_;
+	};
+	/*
+	* http_client<asio2::http_client> request;
+	* https http判断 req.schema();
+	* http::web_request req = http::make_request("http://127.0.0.1:8888/BranchWeb/sortService");
+			req.method(http::verb::post);
+			req.set(http::field::content_type,"application/x-www-form-urlencoded");
+			req.body() = "data=123456&data_digest=987654321&msg_type=TEST_INFO&company_id=yjkj";
+			req.keep_alive(false);
+			auto response = request.execute(std::move(req),2000);
+			if (asio2::get_last_error())
+				throw std::exception(asio2::get_last_error_msg().c_str());
+			LOG_INFO << response.body().text();
+	*/
+}
+

+ 100 - 39
robot/robotics/mvc.hpp

@@ -14,8 +14,6 @@
 #include "utils.hpp"
 #include "json.hpp"
 #include "CImg.h"
-//rttr
-#include <rttr/registration>
 
 namespace robotics::v3 {
 	namespace mvc {
@@ -102,9 +100,9 @@ namespace robotics::v3 {
 				for (auto& property : propertys) {
 					auto name = std::string(property.get_name());
 					auto type = property.get_type();
-					if (values.find(name) == values.end())
+					if (!values.contains(name))
 						continue;
-					std::string value = values.find(name)->second;//values[name];
+					std::string value = values.find(name)->second;
 					if (type == rttr::type::get<int>()) {
 						property.set_value(obj1, atoi(value.c_str()));
 					}
@@ -1659,7 +1657,11 @@ namespace robotics::v3 {
 			/**
 			 * @brief header
 			*/
-			HEADER
+			HEADER,
+			/**
+			 * @brief url
+			 */
+			URL
 		};
 
 		enum class argument_type {
@@ -1724,18 +1726,10 @@ namespace robotics::v3 {
 			void parameter(http::web_request& request, const rttr::parameter_info& type) {
 				parameter_value_.clear();
 				switch (from_storage_type_) {
-				case from_storage_type::HEADER: {
-					analysis_header(request, type);
-					return;
-				}
-				case from_storage_type::QUERY: {
-					analysis_query(request, type);
-					return;
-				}
-				case from_storage_type::BODY: {
-					analysis_body(request, type);
-					return;
-				}
+				case from_storage_type::HEADER:  analysis_header(request, type);  return;
+				case from_storage_type::QUERY:   analysis_query(request, type);   return;
+				case from_storage_type::BODY:    analysis_body(request, type);    return;
+				case from_storage_type::URL:     analysis_url(request, type);     return;
 				}
 				throw std::runtime_error("FormStorageType:错误!");
 			}
@@ -1823,6 +1817,18 @@ namespace robotics::v3 {
 					convert(bodys[parameter_name_], type);
 				}
 			}
+			/**
+			 * @brief url
+			 * @param request 
+			 * @param type 
+			 */
+			void analysis_url(http::web_request& request, const rttr::parameter_info& type) {
+				std::string query(request.find("http_route_parameter")->value());
+				std::map<std::string, std::string>  querys = v3::utils::split_http_form(query);
+				if (querys.find(parameter_name_) == querys.end())
+					throw std::runtime_error("解析Query参数错误!");
+				convert(querys[parameter_name_], type);
+			}
 			/**
 			 * @brief 数据转换
 			 * @param data
@@ -2043,13 +2049,13 @@ namespace robotics::v3 {
 
 		struct controller {
 			rttr::variant invoke(http::web_request& request) {
-				std::string route(request.path().begin() + 1, request.path().end());
-				if (actions.find(route) == actions.end())
+				std::string key(request.find("http_route_key")->value());
+				if (!actions.contains(key))
 					throw std::runtime_error("Action:不存在!");
 				rttr::type type = rttr::type::get_by_name(controller_name);
 				if (!variant.is_valid())
 					variant = type.create();
-				return actions[route]->invoke(request, variant, type);
+				return actions[key]->invoke(request, variant, type);
 			}
 			/**
 			 * @brief 控制器名称
@@ -2066,15 +2072,74 @@ namespace robotics::v3 {
 			rttr::variant variant;
 		};
 
+		struct mvc_route {
+			bool contains(http::web_request& req) {
+				std::string key;
+				std::string route(req.find("http_route")->value());
+				if (contains(route, key)) {
+					std::size_t index = key.find('<');
+					std::vector<std::string> params;
+					if (std::string::npos != index) {
+						auto keys = v3::utils::split(key.substr(index), "/");
+						auto values = v3::utils::split(route.substr(index), "/");
+						for (int i = 0; i < keys.size() && i < values.size(); ++i) {
+							params.push_back(keys[i].substr(1, keys[i].size() - 2) + "=" + values[i]);
+						}
+					}
+					req.insert("http_route_key",key);
+					req.insert("http_route_parameter", v3::utils::join(params, "&"));
+					return true;
+				}
+				return false;
+			}
+			bool contains(std::string const&route) {
+				std::string key;
+				return contains(route, key);
+			}
+			void add(std::string const& route, std::shared_ptr<controller> value) {
+				routes_[route] = value;
+			}
+			std::shared_ptr<controller>& operator[](std::string const& route) {
+				std::string key;
+				if (contains(route, key)) {
+					return routes_[key];
+				}
+				throw std::runtime_error("key does not exist");
+			}
+			std::shared_ptr<controller>& operator[](http::web_request& req) {
+				return this->operator[](std::string(req.find("http_route_key")->value()));
+			}
+		private:
+			bool contains(std::string const& route, std::string& result) {
+				if (routes_.contains(route)) {
+					result = route;
+					return true;
+				}
+				else {
+					int slash_count = std::count(route.begin(), route.end(), '/');
+					for (auto& [first, second] : routes_) {
+						std::size_t index = first.find('<');
+						if (std::count(first.begin(), first.end(), '/') == slash_count && index != std::string::npos) {
+							if (first.substr(0, index) == route.substr(0, index)) {
+								result = first;
+								return true;
+							}
+						}
+					}
+					return false;
+				}
+			}
+		private:
+			std::map<std::string, std::shared_ptr<controller>> routes_;
+		};
+
 		struct ico_controller {
 			/**
 			 * @brief 注册
 			*/
 			static void attach(std::shared_ptr<controller> controller) {
-				for (auto& it : controller->actions) {
-					if (controllers_().find(it.first) == controllers_().end()) {
-						controllers_()[it.first] = controller;
-					}
+				for (auto& [first, second] : controller->actions) {
+					controllers_.add(first, controller);
 				}
 			}
 			/**
@@ -2082,24 +2147,19 @@ namespace robotics::v3 {
 			 * @param url
 			 * @return
 			*/
-			static std::shared_ptr<controller> resolve(std::string const& route) {
-				if (route.empty()) {
-					return std::shared_ptr<controller>();
+			static std::shared_ptr<controller> resolve(http::web_request& req) {
+				if (controllers_.contains(req)) {
+					return controllers_[req];
 				}
-				if (controllers_().find(route) != controllers_().end()) {
-					return controllers_()[route];
-				}
-				return std::shared_ptr<controller>();
+				return nullptr;
 			}
 		private:
 			/**
 			 * @brief
 			*/
-			static std::map<std::string, std::shared_ptr<controller>>& controllers_() {
-				static std::map<std::string, std::shared_ptr<controller>> g_controllers;
-				return g_controllers;
-			}
+			static mvc_route controllers_;
 		};
+		mvc_route ico_controller::controllers_;
 
 		struct web_base_response {
 			void set_header(std::string_view name, std::string_view value) {
@@ -2749,10 +2809,11 @@ namespace robotics::v3 {
 			virtual void on_request(http::web_request& req, http::web_response& rep)override {
 				http_context_gc http_context(req, rep);
 				try {
-					std::string route(req.path().begin() + 1, req.path().end());
-					std::shared_ptr<controller> controller = v3::mvc::ico_controller::resolve(route);
-					http_context::current()->set_controller_action((bool)controller ? controller->actions[route] : nullptr);
-					if (before_.before((bool)controller ? controller->actions[route] : nullptr, req, rep)) {
+					req.insert("http_route",std::string(req.path()).substr(1));
+					std::shared_ptr<controller> controller = v3::mvc::ico_controller::resolve(req);
+					std::string key(req.find("http_route_key")->value());
+					http_context::current()->set_controller_action((bool)controller ? controller->actions[key] : nullptr);
+					if (before_.before((bool)controller ? controller->actions[key] : nullptr, req, rep)) {
 						rttr::variant variant = controller->invoke(req);
 						if (variant.is_valid()) {
 							auto response = variant.get_value<web_base_response>();

+ 135 - 133
robot/robotics/web_service.hpp

@@ -11,8 +11,9 @@
 //stl
 #include <iostream>
 //robotics
-#include <robotics/logger.hpp>
-#include <robotics/datetime.hpp>
+#include "utils.hpp"
+#include "logger.hpp"
+#include "datetime.hpp"
 //asio
 #include <asio2/asio2.hpp>
 //rttr
@@ -38,10 +39,10 @@ namespace robotics::v3 {
 					values[prop_name] = std::to_string(prop_value.get_value<std::int64_t>());
 				}
 				else if (prop_type == rttr::type::get<float>()) {
-					values[prop_name] = format("%1$.2f", prop_value.get_value<float>());
+					values[prop_name] = v3::utils::format("%1$.2f", prop_value.get_value<float>());
 				}
 				else if (prop_type == rttr::type::get<double>()) {
-					values[prop_name] = format("%1$.2f", prop_value.get_value<double>());
+					values[prop_name] = v3::utils::format("%1$.2f", prop_value.get_value<double>());
 				}
 				else if (prop_type == rttr::type::get<long>()) {
 					values[prop_name] = std::to_string(prop_value.get_value<long>());
@@ -57,35 +58,35 @@ namespace robotics::v3 {
 				}
 				else if (prop_type == rttr::type::get<std::vector<int>>()) {
 					auto vecValue = prop_value.get_value<std::vector<int>>();
-					values[prop_name] = join(vecValue, ",");
+					values[prop_name] = v3::utils::join(vecValue, ",");
 				}
 				else if (prop_type == rttr::type::get<std::vector<std::int64_t>>()) {
 					auto vecValue = prop_value.get_value<std::vector<std::int64_t>>();
-					values[prop_name] = join(vecValue, ",");
+					values[prop_name] = v3::utils::join(vecValue, ",");
 				}
 				else if (prop_type == rttr::type::get<std::vector<float>>()) {
 					auto vecValue = prop_value.get_value<std::vector<float>>();
-					values[prop_name] = join(vecValue, ",");
+					values[prop_name] = v3::utils::join(vecValue, ",");
 				}
 				else if (prop_type == rttr::type::get<std::vector<double>>()) {
 					auto vecValue = prop_value.get_value<std::vector<double>>();
-					values[prop_name] = join(vecValue, ",");
+					values[prop_name] = v3::utils::join(vecValue, ",");
 				}
 				else if (prop_type == rttr::type::get<std::vector<long>>()) {
 					auto vecValue = prop_value.get_value<std::vector<long>>();
-					values[prop_name] = join(vecValue, ",");
+					values[prop_name] = v3::utils::join(vecValue, ",");
 				}
 				else if (prop_type == rttr::type::get<std::vector<bool>>()) {
 					auto vecValue = prop_value.get_value<std::vector<bool>>();
-					values[prop_name] = join(vecValue, ",");
+					values[prop_name] = v3::utils::join(vecValue, ",");
 				}
 				else if (prop_type == rttr::type::get<std::vector<std::string>>()) {
 					auto vecValue = prop_value.get_value<std::vector<std::string>>();
-					values[prop_name] = join(vecValue, ",");
+					values[prop_name] = v3::utils::join(vecValue, ",");
 				}
 				else if (prop_type == rttr::type::get<std::vector<v3::datetime>>()) {
 					auto vecValue = prop_value.get_value<std::vector<v3::datetime>>();
-					values[prop_name] = join(vecValue, ",");
+					values[prop_name] = v3::utils::join(vecValue, ",");
 				}
 			}
 		}
@@ -128,7 +129,7 @@ namespace robotics::v3 {
 					property.set_value(obj, v3::datetime(value));
 				}
 				else if (type == rttr::type::get<std::vector<int>>()) {
-					std::vector<std::string> vec = split(value, ",");
+					std::vector<std::string> vec = v3::utils::split(value, ",");
 					std::vector<int> vecValue;
 					for (auto vecIt : vec) {
 						vecValue.push_back(std::atoi(vecIt.c_str()));
@@ -136,7 +137,7 @@ namespace robotics::v3 {
 					property.set_value(obj, vecValue);
 				}
 				else if (type == rttr::type::get<std::vector<std::int64_t>>()) {
-					std::vector<std::string> vec = split(value, ",");
+					std::vector<std::string> vec = v3::utils::split(value, ",");
 					std::vector<std::int64_t> vecValue;
 					for (auto vecIt : vec) {
 						vecValue.push_back(std::atoll(vecIt.c_str()));
@@ -144,7 +145,7 @@ namespace robotics::v3 {
 					property.set_value(obj, vecValue);
 				}
 				else if (type == rttr::type::get<std::vector<float>>()) {
-					std::vector<std::string> vec = split(value, ",");
+					std::vector<std::string> vec = v3::utils::split(value, ",");
 					std::vector<float> vecValue;
 					for (auto vecIt : vec) {
 						vecValue.push_back(std::atof(vecIt.c_str()));
@@ -152,7 +153,7 @@ namespace robotics::v3 {
 					property.set_value(obj, vecValue);
 				}
 				else if (type == rttr::type::get<std::vector<double>>()) {
-					std::vector<std::string> vec = split(value, ",");
+					std::vector<std::string> vec = v3::utils::split(value, ",");
 					std::vector<double> vecValue;
 					for (auto vecIt : vec) {
 						vecValue.push_back(std::atof(vecIt.c_str()));
@@ -160,7 +161,7 @@ namespace robotics::v3 {
 					property.set_value(obj, vecValue);
 				}
 				else if (type == rttr::type::get<std::vector<long>>()) {
-					std::vector<std::string> vec = split(value, ",");
+					std::vector<std::string> vec = v3::utils::split(value, ",");
 					std::vector<long> vecValue;
 					for (auto vecIt : vec) {
 						vecValue.push_back(std::atol(vecIt.c_str()));
@@ -168,7 +169,7 @@ namespace robotics::v3 {
 					property.set_value(obj, vecValue);
 				}
 				else if (type == rttr::type::get<std::vector<bool>>()) {
-					std::vector<std::string> vec = split(value, ",");
+					std::vector<std::string> vec = v3::utils::split(value, ",");
 					std::vector<bool> vecValue;
 					for (auto vecIt : vec) {
 						vecValue.push_back(vecIt == "1" || vecIt == "true" || vecIt == "TRUE" || vecIt == "True");
@@ -176,11 +177,11 @@ namespace robotics::v3 {
 					property.set_value(obj, vecValue);
 				}
 				else if (type == rttr::type::get<std::vector<std::string>>()) {
-					std::vector<std::string> vecValue = split(value, ",");
+					std::vector<std::string> vecValue = v3::utils::split(value, ",");
 					property.set_value(obj, vecValue);
 				}
 				else if (type == rttr::type::get<std::vector<v3::datetime>>()) {
-					std::vector<std::string> vec = split(value, ",");
+					std::vector<std::string> vec = v3::utils::split(value, ",");
 					std::vector<v3::datetime> vecValue;
 					for (auto &vecIt : vec) {
 						vecValue.push_back(v3::datetime(vecIt));
@@ -234,11 +235,11 @@ namespace robotics::v3 {
 	};
 
 	struct xml_node_info {
-		std::string										node_name;		//当前节点名字
-		std::unordered_map<std::string, std::string>	xml_attr;		//当前节点的属性
-		std::vector<std::string>						list_sub_name;	//子节点名字
-		std::string										parent_name;	//父节点 记录了从根节点到上一个节点的名字,用"."隔开 
-		std::string										value;			//当前节点的值
+		std::string										node_name;		//褰撳墠鑺傜偣鍚嶅瓧
+		std::unordered_map<std::string, std::string>	xml_attr;		//褰撳墠鑺傜偣鐨勫睘鎬�
+		std::vector<std::string>						list_sub_name;	//瀛愯妭鐐瑰悕瀛�
+		std::string										parent_name;	//鐖惰妭鐐� 璁板綍浜嗕粠鏍硅妭鐐瑰埌涓婁竴涓�妭鐐圭殑鍚嶅瓧锛岀敤"."闅斿紑 
+		std::string										value;			//褰撳墠鑺傜偣鐨勫€�
 	};
 
 	class xml_manage {
@@ -268,31 +269,31 @@ namespace robotics::v3 {
 		}
 		void xml_parse(const boost::property_tree::ptree& pxml, std::vector<xml_node_info>& listNode, std::string strNode = "") {
 			for (const auto& node : pxml) {
-				std::string  NodeKey = node.first.data(); //属性或者子节点
-				if (NodeKey == "<xmlattr>") {//判断是否是属性
-					continue; //属性已经在父节点中做了保存
+				std::string  NodeKey = node.first.data(); //灞炴€ф垨鑰呭瓙鑺傜偣
+				if (NodeKey == "<xmlattr>") {//鍒ゆ柇鏄�惁鏄�睘鎬�
+					continue; //灞炴€у凡缁忓湪鐖惰妭鐐逛腑鍋氫簡淇濆瓨
 				}
 				xml_node_info xmlnode;
-				xmlnode.node_name = std::string(node.first.data()); //节点名
-				xmlnode.value = node.second.data(); //
-				xmlnode.parent_name = strNode; //父节点是外面传入进来的
-				//获取该节点的属性
+				xmlnode.node_name = std::string(node.first.data()); //鑺傜偣鍚�
+				xmlnode.value = node.second.data(); //鍊�
+				xmlnode.parent_name = strNode; //鐖惰妭鐐规槸澶栭潰浼犲叆杩涙潵鐨�
+				//鑾峰彇璇ヨ妭鐐圭殑灞炴€�
 				for (const auto& attr : node.second) {
 					std::string strAttr = attr.first.data();
-					if (std::string(strAttr) == "<xmlattr>") {//是属性
-						//获取属性的值
+					if (std::string(strAttr) == "<xmlattr>") {//鏄�睘鎬�
+						//鑾峰彇灞炴€х殑鍊�
 						for (auto& att : attr.second) {
 							xmlnode.xml_attr[att.first.data()] = att.second.data();
 						}
 					}
-					else {//节点自身
-						xmlnode.list_sub_name.emplace_back(strAttr); //当前节点的子节点名字
+					else {//鑺傜偣鑷�韩
+						xmlnode.list_sub_name.emplace_back(strAttr); //褰撳墠鑺傜偣鐨勫瓙鑺傜偣鍚嶅瓧
 					}
 				}
-				listNode.emplace_back(xmlnode); //保存当前节点
-				if (!NodeKey.empty()) {//当前节点
+				listNode.emplace_back(xmlnode); //淇濆瓨褰撳墠鑺傜偣
+				if (!NodeKey.empty()) {//褰撳墠鑺傜偣
 					xmlnode.xml_attr.clear();
-					//获取子节点信息 递归
+					//鑾峰彇瀛愯妭鐐逛俊鎭� 閫掑綊
 					std::string str_parent_name;
 					if (!xmlnode.parent_name.empty()) {
 						str_parent_name += xmlnode.parent_name + "." + xmlnode.node_name;
@@ -300,8 +301,8 @@ namespace robotics::v3 {
 					else {
 						str_parent_name = xmlnode.node_name;
 					}
-					//生成父节点 写入XML的时候需要知道父节点
-					xml_parse(node.second, listNode, str_parent_name); //递归遍历
+					//鐢熸垚鐖惰妭鐐� 鍐欏叆XML鐨勬椂鍊欓渶瑕佺煡閬撶埗鑺傜偣
+					xml_parse(node.second, listNode, str_parent_name); //閫掑綊閬嶅巻
 				}
 			}
 		}
@@ -408,8 +409,8 @@ namespace robotics::v3 {
 			else if (value.get_type() == rttr::type::get<const char*>()) {
 				method_request_.put(method_name + "Result", value.get_value<const char*>());
 			}
-			else if (value.get_type() == rttr::type::get<v3::DateTime>()) {
-				method_request_.put(method_name + "Result", value.get_value<v3::DateTime>().getFormatDateTime());
+			else if (value.get_type() == rttr::type::get<v3::datetime>()) {
+				method_request_.put(method_name + "Result", value.get_value<v3::datetime>().to_string());
 			}
 			else {
 				std::map<std::string, std::string> property_values;
@@ -446,7 +447,7 @@ namespace robotics::v3 {
 			std::map<std::string, rttr::variant> _parameter;
 			soap_parameter parameter;
 			std::string envelope = "Envelope";
-			//获取soapenv
+			//鑾峰彇soapenv
 			for (auto& it : nodes) {
 				size_t size = it.node_name.size();
 				if (size > envelope.size() && it.node_name.substr(size - envelope.size(), envelope.size()) == envelope) {
@@ -454,7 +455,7 @@ namespace robotics::v3 {
 					break;
 				}
 			}
-			//获取版本
+			//鑾峰彇鐗堟湰
 			for (auto& it : nodes) {
 				if (it.node_name == soapenv + ":Envelope") {
 					for (auto& attr : it.xml_attr) {
@@ -467,7 +468,7 @@ namespace robotics::v3 {
 					}
 				}
 			}
-			//获取命名空间1
+			//鑾峰彇鍛藉悕绌洪棿1
 			for (auto& it : nodes) {
 				if (it.parent_name == soapenv + ":Envelope." + soapenv + ":Body") {
 					for (auto& attr : it.xml_attr) {
@@ -478,12 +479,12 @@ namespace robotics::v3 {
 					}
 				}
 			}
-			//获取命名空间2
+			//鑾峰彇鍛藉悕绌洪棿2
 			if (namespace_name.empty()) {
 				for (auto& it : nodes) {
 					if (it.parent_name == soapenv + ":Envelope." + soapenv + ":Body") {
 						size_t size = it.node_name.size();
-						auto values = v3::split(it.node_name, ":");
+						auto values = v3::utils::split(it.node_name, ":");
 						if (values.size() == 2) {
 							for (auto& attr : nodes[0].xml_attr) {
 								if (attr.first == "xmlns:" + values[0]) {
@@ -495,10 +496,10 @@ namespace robotics::v3 {
 					}
 				}
 			}
-			//获取方法名称
+			//鑾峰彇鏂规硶鍚嶇О
 			for (auto& it : nodes) {
 				if (it.parent_name == soapenv + ":Envelope." + soapenv + ":Body") {
-					auto values = v3::split(it.node_name, ":");
+					auto values = v3::utils::split(it.node_name, ":");
 
 					if (values.size() == 2) {
 						tem_name = values[0];
@@ -511,13 +512,13 @@ namespace robotics::v3 {
 					break;
 				}
 			}
-			//获取参数
+			//鑾峰彇鍙傛暟
 			for (auto& it : nodes) {
 				if (it.parent_name == soapenv + ":Envelope." + soapenv + ":Body." +
 					(tem_name.empty() ? method_name : tem_name + ":" + method_name)) {
 
 					if (it.list_sub_name.size() == 0) {
-						auto values = v3::split(it.node_name, ":");
+						auto values = v3::utils::split(it.node_name, ":");
 
 						if (values.size() == 2) {
 							_parameter[values[1]] = it.value;
@@ -533,7 +534,7 @@ namespace robotics::v3 {
 							if (it1.parent_name == soapenv + ":Envelope." + soapenv + ":Body." +
 								(tem_name.empty() ? method_name + "." : tem_name + ":" + method_name + ".") + value) {
 
-								auto values = v3::split(it1.node_name, ":");
+								auto values = v3::utils::split(it1.node_name, ":");
 								if (values.size() == 2) {
 									tmpParameter[values[1]] = it1.value;
 								}
@@ -542,7 +543,7 @@ namespace robotics::v3 {
 								}
 							}
 						}
-						auto values1 = v3::split(it.node_name, ":");
+						auto values1 = v3::utils::split(it.node_name, ":");
 						if (values1.size() == 2) {
 							_parameter[values1[1]] = tmpParameter;
 						}
@@ -583,64 +584,64 @@ namespace robotics::v3 {
 			return os.str();
 		}
 	private:
-		void add_value(std::string const&method_name, std::map<std::string, rttr::variant> const& values, std::map<std::string, bool> const& namespaces) {
+		void add_value(std::string const&method_name, std::map<std::string, rttr::variant> values, std::map<std::string, bool> namespaces) {
 			xmltree parameters;
-			for (auto& value : values) {
-				if (value.second.get_type() == rttr::type::get<int>()) {
-					parameters.add(value.first, value.second.get_value<int>());
-					if (namespaces.find(value.first) != namespaces.end() && namespaces[value.first])
-						parameters.add(v3::format("%1%.<xmlattr>.xmlns", value.first), "");
-				}
-				else if (value.second.get_type() == rttr::type::get<std::int64_t>()) {
-					parameters.add(value.first, value.second.get_value<std::int64_t>());
-					if (namespaces.find(value.first) != namespaces.end() && namespaces[value.first])
-						parameters.add(v3::format("%1%.<xmlattr>.xmlns", value.first), "");
-				}
-				else if (value.second.get_type() == rttr::type::get<float>()) {
-					parameters.add(value.first, value.second.get_value<float>());
-					if (namespaces.find(value.first) != namespaces.end() && namespaces[value.first])
-						parameters.add(v3::format("%1%.<xmlattr>.xmlns", value.first), "");
-				}
-				else if (value.second.get_type() == rttr::type::get<double>()) {
-					parameters.add(value.first, value.second.get_value<double>());
-					if (namespaces.find(value.first) != namespaces.end() && namespaces[value.first])
-						parameters.add(v3::format("%1%.<xmlattr>.xmlns", value.first), "");
-				}
-				else if (value.second.get_type() == rttr::type::get<long>()) {
-					parameters.add(value.first, value.second.get_value<long>());
-					if (namespaces.find(value.first) != namespaces.end() && namespaces[value.first])
-						parameters.add(v3::format("%1%.<xmlattr>.xmlns", value.first), "");
-				}
-				else if (value.second.get_type() == rttr::type::get<bool>()) {
-					parameters.add(value.first, value.second.get_value<bool>() ? "True" : "False");
-					if (namespaces.find(value.first) != namespaces.end() && namespaces[value.first])
-						parameters.add(v3::format("%1%.<xmlattr>.xmlns", value.first), "");
-				}
-				else if (value.second.get_type() == rttr::type::get<std::string>()) {
-					parameters.add(value.first, value.second.get_value<std::string>());
-					if (namespaces.find(value.first) != namespaces.end() && namespaces[value.first])
-						parameters.add(v3::format("%1%.<xmlattr>.xmlns", value.first), "");
-				}
-				else if (value.second.get_type() == rttr::type::get<const char*>()) {
-					parameters.add(value.first, value.second.get_value<const char*>());
-					if (namespaces.find(value.first) != namespaces.end() && namespaces[value.first])
-						parameters.add(v3::format("%1%.<xmlattr>.xmlns", value.first), "");
-				}
-				else if (value.second.get_type() == rttr::type::get<v3::datetime>()) {
-					parameters.add(value.first, value.second.get_value<v3::datetime>().to_string());
-					if (namespaces.find(value.first) != namespaces.end() && namespaces[value.first])
-						parameters.add(v3::format("%1%.<xmlattr>.xmlns", value.first), "");
+			for (auto& [first,second] : values) {
+				if (second.get_type() == rttr::type::get<int>()) {
+					parameters.add(first, second.get_value<int>());
+					if (namespaces.contains(first) && namespaces[first])
+						parameters.add(v3::utils::format("%1%.<xmlattr>.xmlns", first), "");
+				}
+				else if (second.get_type() == rttr::type::get<std::int64_t>()) {
+					parameters.add(first, second.get_value<std::int64_t>());
+					if (namespaces.contains(first) && namespaces[first])
+						parameters.add(v3::utils::format("%1%.<xmlattr>.xmlns", first), "");
+				}
+				else if (second.get_type() == rttr::type::get<float>()) {
+					parameters.add(first, second.get_value<float>());
+					if (namespaces.contains(first) && namespaces[first])
+						parameters.add(v3::utils::format("%1%.<xmlattr>.xmlns", first), "");
+				}
+				else if (second.get_type() == rttr::type::get<double>()) {
+					parameters.add(first, second.get_value<double>());
+					if (namespaces.contains(first) && namespaces[first])
+						parameters.add(v3::utils::format("%1%.<xmlattr>.xmlns", first), "");
+				}
+				else if (second.get_type() == rttr::type::get<long>()) {
+					parameters.add(first, second.get_value<long>());
+					if (namespaces.contains(first) && namespaces[first])
+						parameters.add(v3::utils::format("%1%.<xmlattr>.xmlns", first), "");
+				}
+				else if (second.get_type() == rttr::type::get<bool>()) {
+					parameters.add(first, second.get_value<bool>() ? "True" : "False");
+					if (namespaces.contains(first) && namespaces[first])
+						parameters.add(v3::utils::format("%1%.<xmlattr>.xmlns", first), "");
+				}
+				else if (second.get_type() == rttr::type::get<std::string>()) {
+					parameters.add(first, second.get_value<std::string>());
+					if (namespaces.contains(first) && namespaces[first])
+						parameters.add(v3::utils::format("%1%.<xmlattr>.xmlns", first), "");
+				}
+				else if (second.get_type() == rttr::type::get<const char*>()) {
+					parameters.add(first, second.get_value<const char*>());
+					if (namespaces.contains(first) && namespaces[first])
+						parameters.add(v3::utils::format("%1%.<xmlattr>.xmlns", first), "");
+				}
+				else if (second.get_type() == rttr::type::get<v3::datetime>()) {
+					parameters.add(first, (second.get_value<v3::datetime>()).to_string());
+					if (namespaces.contains(first) && namespaces[first])
+						parameters.add(v3::utils::format("%1%.<xmlattr>.xmlns", first), "");
 				}
 				else {
 					std::map<std::string, std::string> property_values;
-					v3::soap_reflect::get_object_value(value.second, property_values);
+					v3::soap_reflect::get_object_value(second, property_values);
 					xmltree propertys;
 					for (auto& it : property_values) {
 						propertys.add(it.first, it.second);
 					}
-					parameters.add_child(value.first, propertys);
-					if (namespaces.find(value.first) != namespaces.end() && namespaces[value.first])
-						parameters.add(v3::format("%1%.<xmlattr>.xmlns", value.first), "");
+					parameters.add_child(first, propertys);
+					if (namespaces.contains(first) && namespaces[first])
+						parameters.add(v3::utils::format("%1%.<xmlattr>.xmlns", first), "");
 				}
 			}
 			method_request_.add_child(method_name, parameters);
@@ -677,7 +678,7 @@ namespace robotics::v3 {
 					break;
 				}
 			}
-			//获取版本
+			//鑾峰彇鐗堟湰
 			for (auto& it : nodes) {
 				if (it.node_name == soapenv + ":Envelope") {
 					for (auto& attr : it.xml_attr) {
@@ -690,7 +691,7 @@ namespace robotics::v3 {
 					}
 				}
 			}
-			//获取命名空间1
+			//鑾峰彇鍛藉悕绌洪棿1
 			for (auto& it : nodes) {
 				if (it.parent_name == soapenv + ":Envelope." + soapenv + ":Body") {
 					size_t size = it.node_name.size();
@@ -704,13 +705,13 @@ namespace robotics::v3 {
 					}
 				}
 			}
-			//获取命名空间2
+			//鑾峰彇鍛藉悕绌洪棿2
 			if (namespace_name.empty()) {
 				for (auto& it : nodes) {
 					if (it.parent_name == soapenv + ":Envelope." + soapenv + ":Body") {
 						size_t size = it.node_name.size();
 						if (size > response.size() && it.node_name.substr(size - response.size(), response.size()) == response) {
-							auto values = v3::split(it.node_name, ":");
+							auto values = v3::utils::split(it.node_name, ":");
 							if (values.size() == 2) {
 								for (auto& attr : it.xml_attr) {
 									if (attr.first == "xmlns:" + values[0]) {
@@ -723,12 +724,12 @@ namespace robotics::v3 {
 					}
 				}
 			}
-			//获取方法名称
+			//鑾峰彇鏂规硶鍚嶇О
 			for (auto& it : nodes) {
 				if (it.parent_name == soapenv + ":Envelope." + soapenv + ":Body") {
 					size_t size = it.node_name.size();
 					if (size > response.size() && it.node_name.substr(size - response.size(), response.size()) == response) {
-						auto values = v3::split(it.node_name, ":");
+						auto values = v3::utils::split(it.node_name, ":");
 						if (values.size() == 2) {
 							tem_name = values[0];
 							method_name = values[1];
@@ -743,7 +744,7 @@ namespace robotics::v3 {
 					}
 				}
 			}
-			//获取参数
+			//鑾峰彇鍙傛暟
 			for (auto& it : nodes) {
 				if (it.parent_name == soapenv + ":Envelope." + soapenv + ":Body." +
 					(tem_name.empty() ? method_name + "Response" : tem_name + ":" + method_name + "Response") &&
@@ -763,7 +764,7 @@ namespace robotics::v3 {
 						tmp_parameter[it.node_name] = it.value;
 					}
 					else {
-						auto values = v3::split(it.node_name, ":");
+						auto values = v3::utils::split(it.node_name, ":");
 						if (values.size() == 2) {
 							tmp_parameter[values[1]] = it.value;
 						}
@@ -790,7 +791,7 @@ namespace robotics::v3 {
 						tmp_parameter[it.node_name] = it.value;
 					}
 					else {
-						auto values = v3::split(it.node_name, ":");
+						auto values = v3::utils::split(it.node_name, ":");
 						if (values.size() == 2) {
 							tmp_parameter[values[1]] = it.value;
 						}
@@ -815,7 +816,7 @@ namespace robotics::v3 {
 		Float,
 		Double,
 		Long,
-		Bool,
+		Bool_,
 		String,
 		DateTime
 	};
@@ -917,7 +918,7 @@ namespace robotics::v3 {
 					parameter_value_ = std::atol(data.c_str());
 					return;
 				}
-				case soap_argument_type::Bool: {
+				case soap_argument_type::Bool_: {
 					std::string tmpValue(data);
 					parameter_value_ = tmpValue == "1" || tmpValue == "true" || tmpValue == "TRUE" || tmpValue == "True";
 					return;
@@ -927,7 +928,7 @@ namespace robotics::v3 {
 					return;
 				}
 				case soap_argument_type::DateTime: {
-					parameter_value_ = v3::DateTime(data);
+					parameter_value_ = v3::datetime(data);
 					return;
 				}
 				}
@@ -967,7 +968,7 @@ namespace robotics::v3 {
 				}
 			}
 			rttr::variant result = controller_type.invoke(action_name, variant, parameters);
-			soap_parameter.resp_parameter = result.get_value<soap_response>().getValue();
+			soap_parameter.resp_parameter = result.get_value<soap_response>().get_value();
 		}
 		std::string											action_name;
 		std::vector<std::shared_ptr<soap_action_argument>>	arguments;
@@ -1029,7 +1030,8 @@ namespace robotics::v3 {
 	private:
 		static std::map<std::string, std::shared_ptr<soap_controller>> controllers_;
 	};
-
+	std::map<std::string, std::shared_ptr<soap_controller>> soap_ioc_controller::controllers_;
+	
 	class http_web_service {
 	public:
 		http_web_service() {
@@ -1040,25 +1042,25 @@ namespace robotics::v3 {
 			}
 		}
 		/**
-		 * @brief 启动
+		 * @brief 鍚�姩
 		 * @param host 
 		 * @param port 
 		 */
 		void start(std::string host = "0.0.0.0", int port = 80) {
-			_server->start(host, port);
+			server_.start(host, port);
 		}
 		/**
-		 * @brief 停止
+		 * @brief 鍋滄�
 		 */
 		void stop() {
-			_server->stop();
+			server_.stop();
 		}
 	protected:
 		virtual void on_request(http::web_request& req, http::web_response& rep) = 0;
 		virtual void on_wsdl(http::web_request& req, http::web_response& rep) = 0;
 	private:
 		/**
-		 * @brief 请求
+		 * @brief 璇锋眰
 		 * @param session 
 		 * @param req 
 		 * @param rep 
@@ -1089,21 +1091,21 @@ namespace robotics::v3 {
 			}
 		}
 		/**
-		 * @brief 启动
+		 * @brief 鍚�姩
 		 * @param host
 		 * @param port
 		 */
 		void start(std::string host = "0.0.0.0", int port = 80) {
-			_server->start(host, port);
+			server_.start(host, port);
 		}
 		/**
-		 * @brief 停止
+		 * @brief 鍋滄�
 		 */
 		void stop() {
-			_server->stop();
+			server_.stop();
 		}
 		/**
-		 * @brief 证书
+		 * @brief 璇佷功
 		 * @param ca_cert_file 
 		 * @param private_cert_file 
 		 * @param private_key_file 
@@ -1119,7 +1121,7 @@ namespace robotics::v3 {
 		virtual void on_wsdl(http::web_request& req, http::web_response& rep) = 0;
 	private:
 		/**
-		 * @brief 请求
+		 * @brief 璇锋眰
 		 * @param session
 		 * @param req
 		 * @param rep
@@ -1153,7 +1155,7 @@ namespace robotics::v3 {
 		 * @param rep 
 		 */
 		virtual void on_request(http::web_request& req, http::web_response& rep) override {
-			std::shared_ptr<soap_controller> controller = soap_ioc_controller::resolve(req.url().string().substr(1));
+			std::shared_ptr<soap_controller> controller = soap_ioc_controller::resolve(std::string(req.path()).substr(1));
 			if (controller) {
 				std::string xml;
 				try {
@@ -1174,9 +1176,9 @@ namespace robotics::v3 {
 		 * @param rep 
 		 */
 		virtual void on_wsdl(http::web_request& req, http::web_response& rep) override {
-			std::shared_ptr<soap_controller> controller = soap_ioc_controller::resolve(req.url().string().substr(1));
+			std::shared_ptr<soap_controller> controller = soap_ioc_controller::resolve(std::string(req.path()).substr(1));
 			if (controller) {
-				rep.fill_file(controller->wsdl);
+				rep.fill_file("/" + controller->wsdl);
 				rep.chunked(true);
 			}
 			else {
@@ -1187,5 +1189,5 @@ namespace robotics::v3 {
 	};
 
 	template<typename _HttpBase>
-	using https_server = web_service_base<_HttpBase>;
+	using web_service = web_service_base<_HttpBase>;
 }