zxs 1 kuukausi sitten
vanhempi
commit
dafeea1a35

+ 1 - 1
src/CMakeLists.txt

@@ -19,7 +19,7 @@ execute_process(COMMAND "${GENERATOR_PATH}code_generator_command" "${CMAKE_CURRE
 
 
 # 代码生成器使用
-# add_executable(authorize_service "main.cpp")
+# add_executable(after_service "main.cpp")
 
 # 将源代码添加到此项目的可执行文件。
 add_executable("${PROJECT_NAME}" "main.cpp" "models/web_after_config_info.h" "models/web_general_config_info.h" "models/web_after_v1_info.h" "models/web_after_response_info.h")

+ 9 - 0
src/after_service.ini

@@ -15,3 +15,12 @@ INDEXweb_user_config_info1=true
 INDEXweb_user_config_info2=true
 INDEXweb_user_list_info1=true
 INDEXweb_user_list_info2=false
+
+[XMLCODE]
+web_user_config_info="@ByteArray(MKH1cm9ib3RpY3M6OnYzOjpkYXRldGltZTo6Y3VycmVudF9kYXRldGltZSgpofW53MDt1LGh9WFkbWluofUxMjM0NTah9VRSVUWh9bncwO3UsQ==)"
+
+[XMLLIST]
+VALUE="web_after_config_info,web_general_config_info,web_user_config_info"
+
+[XMLLISTUPDATE]
+VALUE="web_after_config_info=id,web_general_config_info=key,web_user_config_info=id"

+ 12 - 12
src/config/config.xml

@@ -1,15 +1,15 @@
 <?xml version="1.0" encoding="utf-8"?>
 <root>
-    <users>
-        <item id="1" modify_time="2025-06-02 19:53:32" name="管理员" code="admin" password="123456" enable="true" remarks="管理员"/>
-    </users>
-    <after>
-        <item id="1" modify_time="2025-06-23 16:37:40" value="VggJGwBRnmpSx3dZzCkJtB2+QTs4/DqqdJr00ifspyObshLf68GKNS+K8GwN2YzdMFlK1rwFU1XQnorbU+1YEdl4nBSlGtMIHkSCbp6K92r2hJR7Q9/KYiLSvxaRnXOxbPt23VXljjWHjcZQuDdacSd51xo+qxfXOIWPUbxGLsdPM5d+mXYbNI18nF5NzXrYWbyNGrnQ+wkBn6cASbCsWKtfK1Ud3kDm8v16QDb1fYw=" enable="true" remarks="售后配置信息"/>
-    </after>
-    <general>
-        <item id="1" modify_time="2025-06-23 16:38:12" key="1" value="http://127.0.0.1:9004/api/base/config" enable="true" remarks="通用地址配置"/>
-        <item id="2" modify_time="2025-06-23 16:38:12" key="2" value="http://127.0.0.1:9004/api/after/params" enable="true" remarks="参数地址配置"/>
-        <item id="3" modify_time="2025-06-23 16:38:12" key="3" value="1" enable="true" remarks="售后方式 1:rpc,2:老分布式,3:新分布式"/>
-        <item id="4" modify_time="2025-06-23 16:38:12" key="4" value="1900" enable="true" remarks="RPC售后服务端口"/>
-    </general>
+    <after_config>
+        <item id="1" modify_time="2025-06-25 15:37:30" value="VggJGwBRnmpSx3dZzCkJtB2+QTs4/DqqdJr00ifspyObshLf68GKNS+K8GwN2YzdMFlK1rwFU1XQnorbU+1YEdl4nBSlGtMIHkSCbp6K92r2hJR7Q9/KYiLSvxaRnXOxbPt23VXljjWHjcZQuDdacSd51xo+qxfXOIWPUbxGLsdPM5d+mXYbNI18nF5NzXrYWbyNGrnQ+wkBn6cASbCsWKtfK1Ud3kDm8v16QDb1fYw=" enable="true" remarks="售后配置信息"/>
+    </after_config>
+    <general_config>
+        <item id="1" modify_time="2025-06-25 15:37:37" key="1" value="http://127.0.0.1:9004/api/base/config" enable="true" remarks="通用地址配置"/>
+        <item id="2" modify_time="2025-06-25 15:37:37" key="2" value="http://127.0.0.1:9004/api/after/params" enable="true" remarks="参数地址配置"/>
+        <item id="3" modify_time="2025-06-25 15:37:37" key="3" value="1" enable="true" remarks="售后方式 1:rpc,2:老分布式,3:新分布式"/>
+        <item id="4" modify_time="2025-06-25 15:37:37" key="4" value="1900" enable="true" remarks="RPC售后服务端口"/>
+    </general_config>
+    <user_config>
+        <item id="1" modify_time="2025-06-25 15:15:15" name="管理员" code="admin" password="123456" enable="true" remarks="管理员"/>
+    </user_config>
 </root>

+ 3 - 4
src/core/core.hpp

@@ -1,6 +1,5 @@
 #pragma once
-#include "../xml/xml_context.hpp"
-#include "../xml/xml_config.hpp"
+#include "../xml/xml_update.hpp"
 #include "../network/network.hpp"
 
 class core {
@@ -59,14 +58,14 @@ private:
 	 * @param value 包含云端返回配置信息的 web_after_config_info 常量引用。
 	 */
 	void on_cloud_after_response(web_after_config_info const& value) {
-		xml_config::update(value);
+		xml_update::update(value);
 	}
 	/**
 	 * @brief 处理云端通用响应并更新本地配置。
 	 * @param values 包含 web_general_config_info 对象的常量引用向量,表示从云端接收到的配置信息。
 	 */
 	void on_cloud_general_response(std::vector<web_general_config_info> const&values) {
-		xml_config::update(values);
+		xml_update::update(values);
 	}
 private:
 	/**

+ 1 - 1
src/models/web_after_config_info.h

@@ -21,7 +21,7 @@ using namespace robotics;
 * Excel字段名			[[Excel("xxx")]]
 * 不生成Excel字段 		[[NoExcel(true)]]
 * *************************************************/
-struct [[SqlTable("web_after_config")]] web_after_config_info
+struct [[SqlTable("after_config")]] web_after_config_info
 {
 	/**
 	 * @brief id

+ 1 - 1
src/models/web_general_config_info.h

@@ -21,7 +21,7 @@ using namespace robotics;
 * Excel字段名			[[Excel("xxx")]]
 * 不生成Excel字段 		[[NoExcel(true)]]
 * *************************************************/
-struct [[SqlTable("web_general_config")]] web_general_config_info {
+struct [[SqlTable("general_config")]] web_general_config_info {
 	/**
 	 * @brief id
 	 */

+ 1 - 1
src/models/web_user_config_info.h

@@ -21,7 +21,7 @@ using namespace robotics;
 * Excel字段名			[[Excel("xxx")]]
 * 不生成Excel字段 		[[NoExcel(true)]]
 * *************************************************/
-struct [[SqlTable("web_user_config")]] web_user_config_info
+struct [[SqlTable("user_config")]] web_user_config_info
 {
 	/**
 	 * @brief id

+ 30 - 30
src/reflect.h

@@ -1,4 +1,4 @@
-//生成时间:2025-06-13 10:17:48
+//生成时间:2025-06-25 16:51:17
 #pragma once
 #include <rttr/registration>
 #include <robotics/logger.hpp>
@@ -16,24 +16,24 @@
 #include "controllers/home.hpp"
 #include "controllers/user.hpp"
 
-static void func_75a321aa4f539daa3dd82a0551757555() {
-	rttr::registration::class_<struct web_after_config_info>("web_after_config").constructor<>()(rttr::detail::as_object{}).
+static void func_47b8f25e21fb368adca2a651500e6e05() {
+	rttr::registration::class_<struct web_after_config_info>("after_config").constructor<>()(rttr::detail::as_object{}).
 		property("id",&web_after_config_info::id)(rttr::metadata("Json","id"),rttr::metadata("Sql","id"),rttr::metadata("Excel",R"(id)"),rttr::metadata("NoJson",false),rttr::metadata("NoSql",false),rttr::metadata("NoExcel",false),rttr::metadata("SqlKey",false),rttr::metadata("NoArchive",false),rttr::metadata("Offset",robotics::v3::utils::pointer_cast<int>(&web_after_config_info::id))).
 		property("modify_time",&web_after_config_info::modify_time)(rttr::metadata("Json","modify_time"),rttr::metadata("Sql","modify_time"),rttr::metadata("Excel",R"(modify_time)"),rttr::metadata("NoJson",false),rttr::metadata("NoSql",false),rttr::metadata("NoExcel",false),rttr::metadata("SqlKey",false),rttr::metadata("NoArchive",false),rttr::metadata("Offset",robotics::v3::utils::pointer_cast<int>(&web_after_config_info::modify_time))).
 		property("value",&web_after_config_info::value)(rttr::metadata("Json","value"),rttr::metadata("Sql","value"),rttr::metadata("Excel",R"(value)"),rttr::metadata("NoJson",false),rttr::metadata("NoSql",false),rttr::metadata("NoExcel",false),rttr::metadata("SqlKey",false),rttr::metadata("NoArchive",false),rttr::metadata("Offset",robotics::v3::utils::pointer_cast<int>(&web_after_config_info::value))).
 		property("enable",&web_after_config_info::enable)(rttr::metadata("Json","enable"),rttr::metadata("Sql","enable"),rttr::metadata("Excel",R"(enable)"),rttr::metadata("NoJson",false),rttr::metadata("NoSql",false),rttr::metadata("NoExcel",false),rttr::metadata("SqlKey",false),rttr::metadata("NoArchive",false),rttr::metadata("Offset",robotics::v3::utils::pointer_cast<int>(&web_after_config_info::enable))).
 		property("remarks",&web_after_config_info::remarks)(rttr::metadata("Json","remarks"),rttr::metadata("Sql","remarks"),rttr::metadata("Excel",R"(remarks)"),rttr::metadata("NoJson",false),rttr::metadata("NoSql",false),rttr::metadata("NoExcel",false),rttr::metadata("SqlKey",false),rttr::metadata("NoArchive",false),rttr::metadata("Offset",robotics::v3::utils::pointer_cast<int>(&web_after_config_info::remarks)));
 }
-static void func_3513af8bf53b14539d6d2782219f5fb1() {
+static void func_ed8225ceebcf5098f45371e967f09ce5() {
 	rttr::registration::class_<struct web_after_response_info>("web_after_response_info").constructor<>()(rttr::detail::as_object{}).
 		property("value",&web_after_response_info::value)(rttr::metadata("Json","value"),rttr::metadata("Sql","value"),rttr::metadata("Excel",R"(value)"),rttr::metadata("NoJson",false),rttr::metadata("NoSql",false),rttr::metadata("NoExcel",false),rttr::metadata("SqlKey",false),rttr::metadata("NoArchive",false),rttr::metadata("Offset",robotics::v3::utils::pointer_cast<int>(&web_after_response_info::value)));
 }
-static void func_03ca6db0d1b148625d712773223ff64a() {
+static void func_a4c49e985172b7ebf1ae5187d86d2cad() {
 	rttr::registration::class_<struct web_after_v1_info>("web_after_v1").constructor<>()(rttr::detail::as_object{}).
 		property("status",&web_after_v1_info::status)(rttr::metadata("Json","Status"),rttr::metadata("Sql","status"),rttr::metadata("Excel",R"(status)"),rttr::metadata("NoJson",false),rttr::metadata("NoSql",false),rttr::metadata("NoExcel",false),rttr::metadata("SqlKey",false),rttr::metadata("NoArchive",false),rttr::metadata("Offset",robotics::v3::utils::pointer_cast<int>(&web_after_v1_info::status))).
 		property("msg",&web_after_v1_info::msg)(rttr::metadata("Json","Msg"),rttr::metadata("Sql","msg"),rttr::metadata("Excel",R"(msg)"),rttr::metadata("NoJson",false),rttr::metadata("NoSql",false),rttr::metadata("NoExcel",false),rttr::metadata("SqlKey",false),rttr::metadata("NoArchive",false),rttr::metadata("Offset",robotics::v3::utils::pointer_cast<int>(&web_after_v1_info::msg)));
 }
-static void func_49fb0a902fa2c1f5cfaa531e73a9d7f8() {
+static void func_78f2a7d1e0bf1b27c6cfb47883d5dd33() {
 	rttr::registration::class_<struct web_cloud_after_info>("web_cloud_after_info").constructor<>()(rttr::detail::as_object{}).
 		property("is_show_msg",&web_cloud_after_info::is_show_msg)(rttr::metadata("Json","is_show_msg"),rttr::metadata("Sql","is_show_msg"),rttr::metadata("Excel",R"(is_show_msg)"),rttr::metadata("NoJson",false),rttr::metadata("NoSql",false),rttr::metadata("NoExcel",false),rttr::metadata("SqlKey",false),rttr::metadata("NoArchive",false),rttr::metadata("Offset",robotics::v3::utils::pointer_cast<int>(&web_cloud_after_info::is_show_msg))).
 		property("status",&web_cloud_after_info::status)(rttr::metadata("Json","status"),rttr::metadata("Sql","status"),rttr::metadata("Excel",R"(status)"),rttr::metadata("NoJson",false),rttr::metadata("NoSql",false),rttr::metadata("NoExcel",false),rttr::metadata("SqlKey",false),rttr::metadata("NoArchive",false),rttr::metadata("Offset",robotics::v3::utils::pointer_cast<int>(&web_cloud_after_info::status))).
@@ -43,8 +43,8 @@ static void func_49fb0a902fa2c1f5cfaa531e73a9d7f8() {
 		property("mac",&web_cloud_after_info::mac)(rttr::metadata("Json","mac"),rttr::metadata("Sql","mac"),rttr::metadata("Excel",R"(mac)"),rttr::metadata("NoJson",false),rttr::metadata("NoSql",false),rttr::metadata("NoExcel",false),rttr::metadata("SqlKey",false),rttr::metadata("NoArchive",false),rttr::metadata("Offset",robotics::v3::utils::pointer_cast<int>(&web_cloud_after_info::mac))).
 		property("msg",&web_cloud_after_info::msg)(rttr::metadata("Json","msg"),rttr::metadata("Sql","msg"),rttr::metadata("Excel",R"(msg)"),rttr::metadata("NoJson",false),rttr::metadata("NoSql",false),rttr::metadata("NoExcel",false),rttr::metadata("SqlKey",false),rttr::metadata("NoArchive",false),rttr::metadata("Offset",robotics::v3::utils::pointer_cast<int>(&web_cloud_after_info::msg)));
 }
-static void func_1ffe3a118fbe3cd3d744549f4a9e42d6() {
-	rttr::registration::class_<struct web_general_config_info>("web_general_config").constructor<>()(rttr::detail::as_object{}).
+static void func_04f0ad1ad2a6f3c9fa896b9f96260f55() {
+	rttr::registration::class_<struct web_general_config_info>("general_config").constructor<>()(rttr::detail::as_object{}).
 		property("id",&web_general_config_info::id)(rttr::metadata("Json","id"),rttr::metadata("Sql","id"),rttr::metadata("Excel",R"(id)"),rttr::metadata("NoJson",false),rttr::metadata("NoSql",false),rttr::metadata("NoExcel",false),rttr::metadata("SqlKey",false),rttr::metadata("NoArchive",false),rttr::metadata("Offset",robotics::v3::utils::pointer_cast<int>(&web_general_config_info::id))).
 		property("modify_time",&web_general_config_info::modify_time)(rttr::metadata("Json","modify_time"),rttr::metadata("Sql","modify_time"),rttr::metadata("Excel",R"(modify_time)"),rttr::metadata("NoJson",false),rttr::metadata("NoSql",false),rttr::metadata("NoExcel",false),rttr::metadata("SqlKey",false),rttr::metadata("NoArchive",false),rttr::metadata("Offset",robotics::v3::utils::pointer_cast<int>(&web_general_config_info::modify_time))).
 		property("key",&web_general_config_info::key)(rttr::metadata("Json","key"),rttr::metadata("Sql","key"),rttr::metadata("Excel",R"(key)"),rttr::metadata("NoJson",false),rttr::metadata("NoSql",false),rttr::metadata("NoExcel",false),rttr::metadata("SqlKey",false),rttr::metadata("NoArchive",false),rttr::metadata("Offset",robotics::v3::utils::pointer_cast<int>(&web_general_config_info::key))).
@@ -52,12 +52,12 @@ static void func_1ffe3a118fbe3cd3d744549f4a9e42d6() {
 		property("enable",&web_general_config_info::enable)(rttr::metadata("Json","enable"),rttr::metadata("Sql","enable"),rttr::metadata("Excel",R"(enable)"),rttr::metadata("NoJson",false),rttr::metadata("NoSql",false),rttr::metadata("NoExcel",false),rttr::metadata("SqlKey",false),rttr::metadata("NoArchive",false),rttr::metadata("Offset",robotics::v3::utils::pointer_cast<int>(&web_general_config_info::enable))).
 		property("remarks",&web_general_config_info::remarks)(rttr::metadata("Json","remarks"),rttr::metadata("Sql","remarks"),rttr::metadata("Excel",R"(remarks)"),rttr::metadata("NoJson",false),rttr::metadata("NoSql",false),rttr::metadata("NoExcel",false),rttr::metadata("SqlKey",false),rttr::metadata("NoArchive",false),rttr::metadata("Offset",robotics::v3::utils::pointer_cast<int>(&web_general_config_info::remarks)));
 }
-static void func_ca57981293d8a2cbfb9efca0a74fd706() {
+static void func_713c6f77bf4f9b35526449b6f4c67c4c() {
 	rttr::registration::class_<struct web_message_info>("web_message_info").constructor<>()(rttr::detail::as_object{}).
 		property("success",&web_message_info::success)(rttr::metadata("Json","success"),rttr::metadata("Sql","success"),rttr::metadata("Excel",R"(success)"),rttr::metadata("NoJson",false),rttr::metadata("NoSql",false),rttr::metadata("NoExcel",false),rttr::metadata("SqlKey",false),rttr::metadata("NoArchive",false),rttr::metadata("Offset",robotics::v3::utils::pointer_cast<int>(&web_message_info::success))).
 		property("message",&web_message_info::message)(rttr::metadata("Json","message"),rttr::metadata("Sql","message"),rttr::metadata("Excel",R"(message)"),rttr::metadata("NoJson",false),rttr::metadata("NoSql",false),rttr::metadata("NoExcel",false),rttr::metadata("SqlKey",false),rttr::metadata("NoArchive",false),rttr::metadata("Offset",robotics::v3::utils::pointer_cast<int>(&web_message_info::message)));
 }
-static void func_5185de0356db10a155e98f0015b55dab() {
+static void func_0bb7014b41c7ed38a52ad60758d9dd01() {
 	rttr::registration::class_<struct web_response_info<web_user_config_info>>("web_response_info<web_user_config_info>").constructor<>()(rttr::detail::as_object{}).
 		property("code",&web_response_info<web_user_config_info>::code)(rttr::metadata("Json","code"),rttr::metadata("Sql","code"),rttr::metadata("Excel",R"(code)"),rttr::metadata("NoJson",false),rttr::metadata("NoSql",false),rttr::metadata("NoExcel",false),rttr::metadata("SqlKey",false),rttr::metadata("NoArchive",false),rttr::metadata("Offset",robotics::v3::utils::pointer_cast<int>(&web_response_info<web_user_config_info>::code))).
 		property("msg",&web_response_info<web_user_config_info>::msg)(rttr::metadata("Json","msg"),rttr::metadata("Sql","msg"),rttr::metadata("Excel",R"(msg)"),rttr::metadata("NoJson",false),rttr::metadata("NoSql",false),rttr::metadata("NoExcel",false),rttr::metadata("SqlKey",false),rttr::metadata("NoArchive",false),rttr::metadata("Offset",robotics::v3::utils::pointer_cast<int>(&web_response_info<web_user_config_info>::msg))).
@@ -79,8 +79,8 @@ static void func_5185de0356db10a155e98f0015b55dab() {
 		property("count",&web_response_info<web_after_response_info>::count)(rttr::metadata("Json","count"),rttr::metadata("Sql","count"),rttr::metadata("Excel",R"(count)"),rttr::metadata("NoJson",false),rttr::metadata("NoSql",false),rttr::metadata("NoExcel",false),rttr::metadata("SqlKey",false),rttr::metadata("NoArchive",false),rttr::metadata("Offset",robotics::v3::utils::pointer_cast<int>(&web_response_info<web_after_response_info>::count))).
 		property("data",&web_response_info<web_after_response_info>::data)(rttr::metadata("Json","data"),rttr::metadata("Sql","data"),rttr::metadata("Excel",R"(data)"),rttr::metadata("NoJson",false),rttr::metadata("NoSql",false),rttr::metadata("NoExcel",false),rttr::metadata("SqlKey",false),rttr::metadata("NoArchive",false),rttr::metadata("Offset",robotics::v3::utils::pointer_cast<int>(&web_response_info<web_after_response_info>::data)));
 }
-static void func_40100f87e1d5c1f656c3725694e3f980() {
-	rttr::registration::class_<struct web_user_config_info>("web_user_config").constructor<>()(rttr::detail::as_object{}).
+static void func_186434e3b899ab90bb1d01f63ab21235() {
+	rttr::registration::class_<struct web_user_config_info>("user_config").constructor<>()(rttr::detail::as_object{}).
 		property("id",&web_user_config_info::id)(rttr::metadata("Json","id"),rttr::metadata("Sql","id"),rttr::metadata("Excel",R"(id)"),rttr::metadata("NoJson",false),rttr::metadata("NoSql",false),rttr::metadata("NoExcel",false),rttr::metadata("SqlKey",false),rttr::metadata("NoArchive",false),rttr::metadata("Offset",robotics::v3::utils::pointer_cast<int>(&web_user_config_info::id))).
 		property("modify_time",&web_user_config_info::modify_time)(rttr::metadata("Json","modify_time"),rttr::metadata("Sql","modify_time"),rttr::metadata("Excel",R"(modify_time)"),rttr::metadata("NoJson",false),rttr::metadata("NoSql",false),rttr::metadata("NoExcel",false),rttr::metadata("SqlKey",false),rttr::metadata("NoArchive",false),rttr::metadata("Offset",robotics::v3::utils::pointer_cast<int>(&web_user_config_info::modify_time))).
 		property("name",&web_user_config_info::name)(rttr::metadata("Json","name"),rttr::metadata("Sql","name"),rttr::metadata("Excel",R"(name)"),rttr::metadata("NoJson",false),rttr::metadata("NoSql",false),rttr::metadata("NoExcel",false),rttr::metadata("SqlKey",false),rttr::metadata("NoArchive",false),rttr::metadata("Offset",robotics::v3::utils::pointer_cast<int>(&web_user_config_info::name))).
@@ -89,7 +89,7 @@ static void func_40100f87e1d5c1f656c3725694e3f980() {
 		property("enable",&web_user_config_info::enable)(rttr::metadata("Json","enable"),rttr::metadata("Sql","enable"),rttr::metadata("Excel",R"(enable)"),rttr::metadata("NoJson",false),rttr::metadata("NoSql",false),rttr::metadata("NoExcel",false),rttr::metadata("SqlKey",false),rttr::metadata("NoArchive",false),rttr::metadata("Offset",robotics::v3::utils::pointer_cast<int>(&web_user_config_info::enable))).
 		property("remarks",&web_user_config_info::remarks)(rttr::metadata("Json","remarks"),rttr::metadata("Sql","remarks"),rttr::metadata("Excel",R"(remarks)"),rttr::metadata("NoJson",false),rttr::metadata("NoSql",false),rttr::metadata("NoExcel",false),rttr::metadata("SqlKey",false),rttr::metadata("NoArchive",false),rttr::metadata("Offset",robotics::v3::utils::pointer_cast<int>(&web_user_config_info::remarks)));
 }
-static void func_21d2de37ad99ce7ad9424aefe9c6c8b2() {
+static void func_664f8f30141ffe9e468d2755dc74bd9d() {
 	rttr::registration::class_<class account>("account").constructor<>()().
 		method("index",&account::index).
 		method("captcha",&account::captcha)(rttr::default_arguments(std::string{}),rttr::parameter_names("v")).
@@ -175,7 +175,7 @@ static void func_21d2de37ad99ce7ad9424aefe9c6c8b2() {
 	controller->controller_name = "account";
 	robotics::v3::mvc::ico_controller::attach(controller);
 }
-static void func_00876114e058bf48c560a630d35ab644() {
+static void func_bfaf9996beb050008d358b92c247b0b0() {
 	rttr::registration::class_<class after>("after").constructor<>()().
 		method("index",&after::index).
 		method("load",&after::load)(rttr::default_arguments(int{},int{},std::string{}),rttr::parameter_names("page","limit","enable")).
@@ -341,7 +341,7 @@ static void func_00876114e058bf48c560a630d35ab644() {
 	controller->controller_name = "after";
 	robotics::v3::mvc::ico_controller::attach(controller);
 }
-static void func_3050813c955a50f1ea22bab2b93b9e01() {
+static void func_d2403c86a3235a367dcb1b0984126a86() {
 	rttr::registration::class_<class general>("general").constructor<>()().
 		method("index",&general::index).
 		method("load",&general::load)(rttr::default_arguments(int{},int{},std::string{},std::string{}),rttr::parameter_names("page","limit","key","enable")).
@@ -514,7 +514,7 @@ static void func_3050813c955a50f1ea22bab2b93b9e01() {
 	controller->controller_name = "general";
 	robotics::v3::mvc::ico_controller::attach(controller);
 }
-static void func_81a437b8dfa03c1ac40da4890ca5da71() {
+static void func_bfa04d64815b946b332b217661242137() {
 	rttr::registration::class_<class home>("home").constructor<>()().
 		method("index",&home::index).
 		method("init",&home::init)(rttr::default_arguments(std::string{}),rttr::parameter_names("v"));
@@ -553,7 +553,7 @@ static void func_81a437b8dfa03c1ac40da4890ca5da71() {
 	controller->controller_name = "home";
 	robotics::v3::mvc::ico_controller::attach(controller);
 }
-static void func_cb1a69c497705bdcc10f238af6e9372b() {
+static void func_bc443389edc97fb168e5ecb56c0c1221() {
 	rttr::registration::class_<class user>("user").constructor<>()().
 		method("index",&user::index).
 		method("load",&user::load)(rttr::default_arguments(int{},int{},std::string{},std::string{},std::string{}),rttr::parameter_names("page","limit","name","code","enable")).
@@ -714,17 +714,17 @@ static void func_cb1a69c497705bdcc10f238af6e9372b() {
 	robotics::v3::mvc::ico_controller::attach(controller);
 }
 RTTR_REGISTRATION {
-	func_75a321aa4f539daa3dd82a0551757555();
-	func_3513af8bf53b14539d6d2782219f5fb1();
-	func_03ca6db0d1b148625d712773223ff64a();
-	func_49fb0a902fa2c1f5cfaa531e73a9d7f8();
-	func_1ffe3a118fbe3cd3d744549f4a9e42d6();
-	func_ca57981293d8a2cbfb9efca0a74fd706();
-	func_5185de0356db10a155e98f0015b55dab();
-	func_40100f87e1d5c1f656c3725694e3f980();
-	func_21d2de37ad99ce7ad9424aefe9c6c8b2();
-	func_00876114e058bf48c560a630d35ab644();
-	func_3050813c955a50f1ea22bab2b93b9e01();
-	func_81a437b8dfa03c1ac40da4890ca5da71();
-	func_cb1a69c497705bdcc10f238af6e9372b();
+	func_47b8f25e21fb368adca2a651500e6e05();
+	func_ed8225ceebcf5098f45371e967f09ce5();
+	func_a4c49e985172b7ebf1ae5187d86d2cad();
+	func_78f2a7d1e0bf1b27c6cfb47883d5dd33();
+	func_04f0ad1ad2a6f3c9fa896b9f96260f55();
+	func_713c6f77bf4f9b35526449b6f4c67c4c();
+	func_0bb7014b41c7ed38a52ad60758d9dd01();
+	func_186434e3b899ab90bb1d01f63ab21235();
+	func_664f8f30141ffe9e468d2755dc74bd9d();
+	func_bfaf9996beb050008d358b92c247b0b0();
+	func_d2403c86a3235a367dcb1b0984126a86();
+	func_bfa04d64815b946b332b217661242137();
+	func_bc443389edc97fb168e5ecb56c0c1221();
 }

+ 5 - 5
src/views/after/edit.html

@@ -23,24 +23,24 @@ ${mask name='edit'}
         <div class="layui-col-md12 top10">
             <form class="layui-form" action="">
                 <div class="layui-form-item">
-                    <input name="id" lay-verify="required" style="display: none;" lay-vertype="tips" class="layui-input" type="text" value="${model name='web_after_config.id' value='[#value]'/}" />
+                    <input name="id" lay-verify="required" style="display: none;" lay-vertype="tips" class="layui-input" type="text" value="${model name='after_config.id' value='[#value]'/}" />
                 </div>
 
                 <div class="layui-form-item">
                     <label class="layui-form-label">售后信息:</label>
                     <div class="layui-input-block">
-                        <input type="text" name="value" lay-verify="required|account" lay-min="1" autocomplete="off" class="layui-input account" placeholder="请输入售后信息" value="${model name='web_after_config.value' value='[#value]'/}" />
+                        <input type="text" name="value" lay-verify="required|account" lay-min="1" autocomplete="off" class="layui-input account" placeholder="请输入售后信息" value="${model name='after_config.value' value='[#value]'/}" />
                     </div>
                 </div>
 
                 <div class="layui-form-item">
                     <label class="layui-form-label">状态:</label>
                     <div class="layui-input-inline">
-                        <input name="enable" value="true" title="启用" ${model name='web_after_config.enable' value='['true':'checked']' /} type="radio">
+                        <input name="enable" value="true" title="启用" ${model name='after_config.enable' value='['true':'checked']' /} type="radio">
                         <div class="layui-unselect layui-form-radio layui-form-radioed">
                             <i class="layui-anim layui-icon"></i><div>启用</div>
                         </div>
-                        <input name="enable" value="false" title="停用" ${model name='web_after_config.enable' value='['false':'checked']' /} type="radio">
+                        <input name="enable" value="false" title="停用" ${model name='after_config.enable' value='['false':'checked']' /} type="radio">
                         <div class="layui-unselect layui-form-radio">
                             <i class="layui-anim layui-icon"></i><div>停用</div>
                         </div>
@@ -49,7 +49,7 @@ ${mask name='edit'}
                 <div class="layui-form-item">
                     <label class="layui-form-label">售后描述:</label>
                     <div class="layui-input-block">
-                        <textarea class="layui-textarea" cols="20" id="remarks" lay-verify="pass" lay-vertype="tips" name="remarks" rows="2" placeholder="请输入售后描述">${model name='web_after_config.remarks' value='[#value]'/}</textarea>
+                        <textarea class="layui-textarea" cols="20" id="remarks" lay-verify="pass" lay-vertype="tips" name="remarks" rows="2" placeholder="请输入售后描述">${model name='after_config.remarks' value='[#value]'/}</textarea>
                     </div>
                 </div>
                 <div class="layui-form-item">

+ 10 - 1
src/views/after/index.html

@@ -176,7 +176,16 @@
                                     layer.close(index); //关闭弹框
                                     layer.msg(result.message, {
                                         icon: 1  //1:勾 6:笑脸
-                                    });
+									});
+                                    //执行搜索重载
+                                    table.reload('currentTableId', {
+                                        page: {
+                                            curr: 1
+                                        },
+                                        where: {
+                                            enable: ''
+                                        }
+                                    }, 'data');
                                 }
                                 else {
                                     layer.msg(result.message, {

+ 6 - 6
src/views/general/edit.html

@@ -23,28 +23,28 @@ ${mask name='edit'}
         <div class="layui-col-md12 top10">
             <form class="layui-form" action="">
                 <div class="layui-form-item">
-                    <input name="id" lay-verify="required" style="display: none;" lay-vertype="tips" class="layui-input" type="text" value="${model name='web_general_config.id' value='[#value]'/}" />
+                    <input name="id" lay-verify="required" style="display: none;" lay-vertype="tips" class="layui-input" type="text" value="${model name='general_config.id' value='[#value]'/}" />
                 </div>
 
                 <div class="layui-form-item">
                     <label class="layui-form-label">KEY:</label>
                     <div class="layui-input-inline">
-                        <input type="number" name="key" lay-verify="required|account" lay-min="1" autocomplete="off" class="layui-input account" placeholder="请输入KEY" value="${model name='web_general_config.key' value='[#value]'/}" />
+                        <input type="number" name="key" lay-verify="required|account" lay-min="1" autocomplete="off" class="layui-input account" placeholder="请输入KEY" value="${model name='general_config.key' value='[#value]'/}" />
                     </div>
                     <label class="layui-form-label">VALUE:</label>
                     <div class="layui-input-inline">
-                        <input type="text" name="value" lay-verify="required|account" lay-min="1" autocomplete="off" class="layui-input account" placeholder="请输入VALUE" value="${model name='web_general_config.value' value='[#value]'/}" />
+                        <input type="text" name="value" lay-verify="required|account" lay-min="1" autocomplete="off" class="layui-input account" placeholder="请输入VALUE" value="${model name='general_config.value' value='[#value]'/}" />
                     </div>
                 </div>
 
                 <div class="layui-form-item">
                     <label class="layui-form-label">状态:</label>
                     <div class="layui-input-inline">
-                        <input name="enable" value="true" title="启用" ${model name='web_general_config.enable' value='['true':'checked']' /} type="radio">
+                        <input name="enable" value="true" title="启用" ${model name='general_config.enable' value='['true':'checked']' /} type="radio">
                         <div class="layui-unselect layui-form-radio layui-form-radioed">
                             <i class="layui-anim layui-icon"></i><div>启用</div>
                         </div>
-                        <input name="enable" value="false" title="停用" ${model name='web_general_config.enable' value='['false':'checked']' /} type="radio">
+                        <input name="enable" value="false" title="停用" ${model name='general_config.enable' value='['false':'checked']' /} type="radio">
                         <div class="layui-unselect layui-form-radio">
                             <i class="layui-anim layui-icon"></i><div>停用</div>
                         </div>
@@ -53,7 +53,7 @@ ${mask name='edit'}
                 <div class="layui-form-item">
                     <label class="layui-form-label">配置描述:</label>
                     <div class="layui-input-block">
-                        <textarea class="layui-textarea" cols="20" id="remarks" lay-verify="pass" lay-vertype="tips" name="remarks" rows="2" placeholder="请输入配置描述">${model name='web_general_config.remarks' value='[#value]'/}</textarea>
+                        <textarea class="layui-textarea" cols="20" id="remarks" lay-verify="pass" lay-vertype="tips" name="remarks" rows="2" placeholder="请输入配置描述">${model name='general_config.remarks' value='[#value]'/}</textarea>
                     </div>
                 </div>
                 <div class="layui-form-item">

+ 13 - 2
src/views/general/index.html

@@ -173,7 +173,8 @@
                                     layer.close(index); //关闭弹框
                                     layer.msg(result.message, {
                                         icon: 1  //1:勾 6:笑脸
-                                    });
+									});
+                                    
                                 }
                                 else {
                                     layer.msg(result.message, {
@@ -217,7 +218,17 @@
                                     layer.close(index); //关闭弹框
                                     layer.msg(result.message, {
                                         icon: 1  //1:勾 6:笑脸
-                                    });
+									});
+                                    //执行搜索重载
+                                    table.reload('currentTableId', {
+                                        page: {
+                                            curr: 1
+                                        },
+                                        where: {
+                                            key: '',
+                                            enable: ''
+                                        }
+                                    }, 'data');
                                 }
                                 else {
                                     layer.msg(result.message, {

+ 7 - 7
src/views/user/edit.html

@@ -23,35 +23,35 @@ ${mask name='edit'}
         <div class="layui-col-md12 top10">
             <form class="layui-form" action="">
                 <div class="layui-form-item">
-                    <input name="id" lay-verify="required" style="display: none;" lay-vertype="tips" class="layui-input" type="text" value="${model name='web_user_config.id' value='[#value]'/}" />
+                    <input name="id" lay-verify="required" style="display: none;" lay-vertype="tips" class="layui-input" type="text" value="${model name='user_config.id' value='[#value]'/}" />
                 </div>
 
                 <div class="layui-form-item">
                     <label class="layui-form-label">用户名称:</label>
                     <div class="layui-input-inline">
-                        <input type="text" name="name" lay-verify="required|account" lay-min="1" autocomplete="off" class="layui-input account" placeholder="请输入用户名称" value="${model name='web_user_config.name' value='[#value]'/}" />
+                        <input type="text" name="name" lay-verify="required|account" lay-min="1" autocomplete="off" class="layui-input account" placeholder="请输入用户名称" value="${model name='user_config.name' value='[#value]'/}" />
                     </div>
                     <label class="layui-form-label">用户代码:</label>
                     <div class="layui-input-inline">
-                        <input type="text" name="code" lay-verify="required|account" lay-min="1" autocomplete="off" class="layui-input account" placeholder="请输入用户代码" value="${model name='web_user_config.code' value='[#value]'/}" />
+                        <input type="text" name="code" lay-verify="required|account" lay-min="1" autocomplete="off" class="layui-input account" placeholder="请输入用户代码" value="${model name='user_config.code' value='[#value]'/}" />
                     </div>
                 </div>
 
                 <div class="layui-form-item">
                     <label class="layui-form-label">用户密码:</label>
                     <div class="layui-input-inline">
-                        <input type="password" name="password" lay-verify="required|account" lay-min="1" autocomplete="off" class="layui-input account" placeholder="请输入用户密码" value="${model name='web_user_config.password' value='[#value]'/}" />
+                        <input type="password" name="password" lay-verify="required|account" lay-min="1" autocomplete="off" class="layui-input account" placeholder="请输入用户密码" value="${model name='user_config.password' value='[#value]'/}" />
                     </div>
                 </div>
 
                 <div class="layui-form-item">
                     <label class="layui-form-label">状态:</label>
                     <div class="layui-input-inline">
-                        <input name="enable" value="true" title="启用" ${model name='web_user_config.enable' value='['true':'checked']' /} type="radio">
+                        <input name="enable" value="true" title="启用" ${model name='user_config.enable' value='['true':'checked']' /} type="radio">
                         <div class="layui-unselect layui-form-radio layui-form-radioed">
                             <i class="layui-anim layui-icon"></i><div>启用</div>
                         </div>
-                        <input name="enable" value="false" title="停用" ${model name='web_user_config.enable' value='['false':'checked']' /} type="radio">
+                        <input name="enable" value="false" title="停用" ${model name='user_config.enable' value='['false':'checked']' /} type="radio">
                         <div class="layui-unselect layui-form-radio">
                             <i class="layui-anim layui-icon"></i><div>停用</div>
                         </div>
@@ -60,7 +60,7 @@ ${mask name='edit'}
                 <div class="layui-form-item">
                     <label class="layui-form-label">用户描述:</label>
                     <div class="layui-input-block">
-                        <textarea class="layui-textarea" cols="20" id="remarks" lay-verify="pass" lay-vertype="tips" name="remarks" rows="2" placeholder="请输入用户描述">${model name='web_user_config.remarks' value='[#value]'/}</textarea>
+                        <textarea class="layui-textarea" cols="20" id="remarks" lay-verify="pass" lay-vertype="tips" name="remarks" rows="2" placeholder="请输入用户描述">${model name='user_config.remarks' value='[#value]'/}</textarea>
                     </div>
                 </div>
                 <div class="layui-form-item">

+ 0 - 103
src/xml/xml_config.hpp

@@ -1,103 +0,0 @@
-#pragma once
-//stl
-#include <iostream>
-#include <sstream>
-#include <vector>
-//local
-#include "../xml/xml_context.hpp"
-
-/**
- * @brief 用于定义一个以 _Table 为模板参数的空结构体。
- * @tparam _Table 要用于结构体的类型。
- */
-template<typename _Table>
-struct _update_ {};
-/**
- * @brief 更新指定的 web_after_config_info 实例:先根据 id 删除已有项,再追加新的值并提交更改。
- */
-template<>
-struct _update_<web_after_config_info> {
-	/**
-	 * @brief 更新或添加 web_after_config_info 配置信息到 XML 上下文中。
-	 * @param value 要更新或添加的 web_after_config_info 对象。
-	 */
-	static void invoke(web_after_config_info const&value) {
-		xml_context::from<web_after_config_info>().
-			remove([value](auto it) {return it->id == value.id; }).
-			submit();
-		
-		xml_context::from<web_after_config_info>().
-			append(value).
-			submit();
-	}
-};
-/**
- * @brief 更新或添加 web_general_config_info 配置信息到 XML 上下文中。
- */
-template<>
-struct _update_<web_general_config_info> {
-	/**
-	 * @brief 检查是否存在指定的 key,如果不存在则添加新的配置项,否则更新现有配置项。
-	 * @param value 要更新或添加的 web_general_config_info 对象。
-	 */
-	static void invoke(web_general_config_info const& value) {
-		if (xml_context::from<web_general_config_info>().where([value](auto it) {return it->key == value.key; }).empty()) {
-			web_general_config_info info{
-				.id = 0,
-				.modify_time = v3::datetime::current_time_stamp(),
-				.key = value.key,
-				.value = value.value,
-				.enable = value.enable,
-				.remarks = value.remarks };
-
-			xml_context::from<web_general_config_info>().
-				max(info.id, [](auto it) {return it->id; }).
-				inc(info.id).
-				append(info).
-				submit();
-		}
-		else {
-			xml_context::from<web_general_config_info>().
-				where([value](auto it) 
-					{
-						return it->key == value.key; 
-					}).
-				update([value](auto it)
-					{
-						it->modify_time = v3::datetime::current_time_stamp();
-						it->key = value.key;
-						it->value = value.value;
-						it->enable = value.enable;
-						it->remarks = value.remarks; 
-						return true;
-					}).
-				submit();
-		}
-	}
-};
-/**
- * @brief 用于更新指定表或表项的数据。
- */
-class xml_config {
-public:
-	/**
-	 * @brief 更新指定表的数据。
-	 * @tparam _Table 要更新的数据表类型。
-	 * @param value 要更新的数据表对象的常量引用。
-	 */
-	template<typename _Table>
-	static void update(_Table const& value) {
-		_update_<_Table>::invoke(value);
-	}
-	/**
-	 * @brief 使用给定的值集合更新表项。
-	 * @tparam _Table 表示表项类型的模板参数。
-	 * @param values 包含要更新的表项的常量引用向量。
-	 */
-	template<typename _Table>
-	static void update(std::vector<_Table> const& values) {
-		for (auto const& value : values) {
-			_update_<_Table>::invoke(value);
-		}
-	}
-};

+ 160 - 181
src/xml/xml_context.hpp

@@ -3,197 +3,176 @@
 #include <iostream>
 #include <sstream>
 #include <vector>
+#include <filesystem>
 //boost
-#include <boost/property_tree/ptree.hpp> 
+#include <boost/property_tree/ptree.hpp>
 #include <boost/property_tree/xml_parser.hpp>
 //robotics
 #include <robotics/linq.hpp>
 //local
-#include "../models/web_user_config_info.h"
 #include "../models/web_after_config_info.h"
 #include "../models/web_general_config_info.h"
-/**
- * @brief 配置
- */
+#include "../models/web_user_config_info.h"
+
 class xml_context {
 public:
-    /**
-     * @brief 根据类型返回对应的 v3::linq_ptr<_Type> 实例,并可选择重置实例。
-     * @tparam _Type 要获取的配置类型,可以是 web_user_config_info、web_after_config_info 或 web_general_config_info。
-     * @param reset 是否重置实例,默认为 true。
-     * @return 返回对应类型的 v3::linq_ptr<_Type> 引用。
-     */
-    template<typename _Type>
-    static v3::linq_ptr<_Type>& from(bool reset = true) {
-        if constexpr (std::is_same<web_user_config_info, _Type>::value) {
-            if (reset) {
-                instance()->linq_user_config_->reset();
-            }
-            return *instance()->linq_user_config_;
-        }
-        else if constexpr (std::is_same<web_after_config_info, _Type>::value) {
-            if (reset) {
-                instance()->linq_after_config_->reset();
-            }
-            return *instance()->linq_after_config_;
-        }
-        else if constexpr (std::is_same<web_general_config_info, _Type>::value) {
-            if (reset) {
-                instance()->linq_general_config_->reset();
-            }
-            return *instance()->linq_general_config_;
-        }
-    }
+	template<typename _Type>
+	static v3::linq_ptr<_Type>& from(bool reset = true) {
+		if constexpr (std::is_same<web_after_config_info, _Type>::value) {
+			if (reset) {
+				instance()->linq_web_after_config_info_->reset();
+			}
+			return *instance()->linq_web_after_config_info_;
+		}
+		else if constexpr (std::is_same<web_general_config_info, _Type>::value) {
+			if (reset) {
+				instance()->linq_web_general_config_info_->reset();
+			}
+			return *instance()->linq_web_general_config_info_;
+		}
+		else if constexpr (std::is_same<web_user_config_info, _Type>::value) {
+			if (reset) {
+				instance()->linq_web_user_config_info_->reset();
+			}
+			return *instance()->linq_web_user_config_info_;
+		}
+	}
 private:
-    /**
-     * @brief 返回 xml_context 的单例实例。
-     * @return 指向全局唯一 xml_context 实例的指针。
-     */
-    static xml_context* instance() {
-        static xml_context g_xml_context;
-        return &g_xml_context;
-    }
-private:
-    /**
-     * @brief 初始化 xml_context 对象,加载配置并将配置列表交给 linq 管理,同时绑定配置变更事件处理函数。
-     */
-    xml_context() {
-        load();
-        //配置列表交给linq管理
-        linq_user_config_.reset(new v3::linq_ptr<web_user_config_info>(user_config_list_));
-        //绑定改变事件
-        linq_user_config_->changed_bind(&xml_context::on_table_save<web_user_config_info>, this);
-
-        //配置列表交给linq管理
-        linq_after_config_.reset(new v3::linq_ptr<web_after_config_info>(after_config_list_));
-        //绑定改变事件
-        linq_after_config_->changed_bind(&xml_context::on_table_save<web_after_config_info>, this);
-
-        //配置列表交给linq管理
-        linq_general_config_.reset(new v3::linq_ptr<web_general_config_info>(general_config_list_));
-        //绑定改变事件
-        linq_general_config_->changed_bind(&xml_context::on_table_save<web_general_config_info>, this);
-    }
-    /**
-     * @brief 加载并解析 XML 配置文件,将用户、授权和通用配置信息读取到对应的配置列表中。
-     */
-    void load() {
-        boost::property_tree::ptree root;
-        try {
-            read_xml("./config/config.xml", root);
-            //用户读取
-            for (auto& it : root.get_child("root.users")) {
-                if (it.first != "item")
-                    continue;
-                std::shared_ptr<web_user_config_info> item(new web_user_config_info);
-                item->id = it.second.get<int>("<xmlattr>.id", 0);
-                item->modify_time = it.second.get<std::string>("<xmlattr>.modify_time", v3::datetime::current_datetime().to_string("yyyy-MM-dd HH:mm:ss"));
-                item->name = it.second.get<std::string>("<xmlattr>.name", "管理员");
-                item->code = it.second.get<std::string>("<xmlattr>.code", "admin");
-                item->password = it.second.get<std::string>("<xmlattr>.password", "123456");
-                item->enable = it.second.get<bool>("<xmlattr>.enable", false);
-                item->remarks = it.second.get<std::string>("<xmlattr>.remarks", "");
-                user_config_list_.push_back(item);
-            }
-            //授权读取
-            for (auto& it : root.get_child("root.after")) {
-                if (it.first != "item")
-                    continue;
-                std::shared_ptr<web_after_config_info> item(new web_after_config_info);
-                item->id = it.second.get<int>("<xmlattr>.id", 0);
-                item->modify_time = it.second.get<std::string>("<xmlattr>.modify_time", v3::datetime::current_datetime().to_string("yyyy-MM-dd HH:mm:ss"));
-                item->value = it.second.get<std::string>("<xmlattr>.value", "");
-                item->enable = it.second.get<bool>("<xmlattr>.enable", false);
-                item->remarks = it.second.get<std::string>("<xmlattr>.remarks", "");
-                after_config_list_.push_back(item);
-            }
-			//通用配置读取
-            for (auto& it : root.get_child("root.general")) {
-                if (it.first != "item")
-                    continue;
-                std::shared_ptr<web_general_config_info> item(new web_general_config_info);
-                item->id = it.second.get<int>("<xmlattr>.id", 0);
-                item->modify_time = it.second.get<std::string>("<xmlattr>.modify_time", v3::datetime::current_datetime().to_string("yyyy-MM-dd HH:mm:ss"));
-                item->key = it.second.get<int>("<xmlattr>.key", 1);
-                item->value = it.second.get<std::string>("<xmlattr>.value", "");
-                item->enable = it.second.get<bool>("<xmlattr>.enable", false);
-                item->remarks = it.second.get<std::string>("<xmlattr>.remarks", "");
-                general_config_list_.push_back(item);
-            }
-        }
-        catch (std::exception const& ec) {
-            LOG_ERROR << "读取xml配置异常" << ec;
-        }
-    }
-    /**
-     * @brief 保存当前的用户、授权用户和通用配置信息到 XML 文件中。
-     */
-    void save() {
-        std::lock_guard<std::mutex> lock(mutex_);
-        boost::property_tree::ptree root;
-        try {
-            //保存用户
-            auto& user = root.add("root.users", "");
-            for (auto& it : user_config_list_) {
-                auto& item = user.add("item", "");
-                item.put("<xmlattr>.id", it->id);
-                item.put("<xmlattr>.modify_time", it->modify_time.to_string("yyyy-MM-dd HH:mm:ss"));
-                item.put("<xmlattr>.name", it->name);
-                item.put("<xmlattr>.code", it->code);
-                item.put("<xmlattr>.password", it->password);
-                item.put("<xmlattr>.enable", it->enable);
-                item.put("<xmlattr>.remarks", it->remarks);
-            }
-            //授权用户
-            auto& after = root.add("root.after", "");
-            for (auto& it : after_config_list_) {
-                auto& item = after.add("item", "");
-                item.put("<xmlattr>.id", it->id);
-                item.put("<xmlattr>.modify_time", it->modify_time.to_string("yyyy-MM-dd HH:mm:ss"));
-                item.put("<xmlattr>.value", it->value);
-                item.put("<xmlattr>.enable", it->enable);
-                item.put("<xmlattr>.remarks", it->remarks);
-            }
-            //通用配置读取
-            auto& general = root.add("root.general", "");
-            for (auto& it : general_config_list_) {
-                auto& item = general.add("item", "");
-                item.put("<xmlattr>.id", it->id);
-                item.put("<xmlattr>.modify_time", it->modify_time.to_string("yyyy-MM-dd HH:mm:ss"));
-                item.put("<xmlattr>.key", it->key);
-                item.put("<xmlattr>.value", it->value);
-                item.put("<xmlattr>.enable", it->enable);
-                item.put("<xmlattr>.remarks", it->remarks);
-            }
-            boost::property_tree::xml_writer_settings<std::string> settings(' ', 4);
-            write_xml("./config/config.xml", root, std::locale(), settings);
-        }
-        catch (std::exception const& ec) {
-            LOG_ERROR << ec;
-        }
-    }
+	static xml_context* instance() {
+		static xml_context g_xml_context;
+			return &g_xml_context;
+	}
+	xml_context() {
+		create_file();
+		load();
+		linq_web_after_config_info_.reset(new v3::linq_ptr<web_after_config_info>(web_after_config_info_list_));
+		linq_web_after_config_info_->changed_bind(&xml_context::on_table_save<web_after_config_info>, this);
+		linq_web_general_config_info_.reset(new v3::linq_ptr<web_general_config_info>(web_general_config_info_list_));
+		linq_web_general_config_info_->changed_bind(&xml_context::on_table_save<web_general_config_info>, this);
+		linq_web_user_config_info_.reset(new v3::linq_ptr<web_user_config_info>(web_user_config_info_list_));
+		linq_web_user_config_info_->changed_bind(&xml_context::on_table_save<web_user_config_info>, this);
+	}
+	void load() {
+		boost::property_tree::ptree root;
+		try {
+			read_xml("./config/config.xml", root);
+			web_after_config_info_list_.clear();
+			for (auto& it : root.get_child("root.after_config")) {
+				if (it.first != "item") continue;
+				std::shared_ptr<web_after_config_info> item(new web_after_config_info);
+				item->id = it.second.get<int>("<xmlattr>.id", 0);
+				item->modify_time = it.second.get<std::string>("<xmlattr>.modify_time", v3::datetime::current_datetime().to_string("yyyy-MM-dd HH:mm:ss"));
+				item->value = it.second.get<std::string>("<xmlattr>.value", "");
+				item->enable = it.second.get<bool>("<xmlattr>.enable", false);
+				item->remarks = it.second.get<std::string>("<xmlattr>.remarks", "");
+				web_after_config_info_list_.push_back(item);
+			}
+			web_general_config_info_list_.clear();
+			for (auto& it : root.get_child("root.general_config")) {
+				if (it.first != "item") continue;
+				std::shared_ptr<web_general_config_info> item(new web_general_config_info);
+				item->id = it.second.get<int>("<xmlattr>.id", 0);
+				item->modify_time = it.second.get<std::string>("<xmlattr>.modify_time", v3::datetime::current_datetime().to_string("yyyy-MM-dd HH:mm:ss"));
+				item->key = it.second.get<int>("<xmlattr>.key", 0);
+				item->value = it.second.get<std::string>("<xmlattr>.value", "");
+				item->enable = it.second.get<bool>("<xmlattr>.enable", false);
+				item->remarks = it.second.get<std::string>("<xmlattr>.remarks", "");
+				web_general_config_info_list_.push_back(item);
+			}
+			web_user_config_info_list_.clear();
+			for (auto& it : root.get_child("root.user_config")) {
+				if (it.first != "item") continue;
+				std::shared_ptr<web_user_config_info> item(new web_user_config_info);
+				item->id = it.second.get<int>("<xmlattr>.id", 0);
+				item->modify_time = it.second.get<std::string>("<xmlattr>.modify_time", v3::datetime::current_datetime().to_string("yyyy-MM-dd HH:mm:ss"));
+				item->name = it.second.get<std::string>("<xmlattr>.name", "");
+				item->code = it.second.get<std::string>("<xmlattr>.code", "");
+				item->password = it.second.get<std::string>("<xmlattr>.password", "");
+				item->enable = it.second.get<bool>("<xmlattr>.enable", false);
+				item->remarks = it.second.get<std::string>("<xmlattr>.remarks", "");
+				web_user_config_info_list_.push_back(item);
+			}
+		}
+		catch (std::exception const& ec) {
+			LOG_ERROR << "读取xml配置异常" << ec;
+		}
+	}
+	void save() {
+		std::lock_guard<std::mutex> lock(mutex_);
+		boost::property_tree::ptree root;
+		try {
+			auto& tmp_after_config = root.add("root.after_config", "");
+			for (auto& it : web_after_config_info_list_) {
+				auto& item = tmp_after_config.add("item", "");
+				item.put("<xmlattr>.id", it->id);
+				item.put("<xmlattr>.modify_time", it->modify_time.to_string("yyyy-MM-dd HH:mm:ss"));
+				item.put("<xmlattr>.value", it->value);
+				item.put("<xmlattr>.enable", it->enable);
+				item.put("<xmlattr>.remarks", it->remarks);
+			}
+			auto& tmp_general_config = root.add("root.general_config", "");
+			for (auto& it : web_general_config_info_list_) {
+				auto& item = tmp_general_config.add("item", "");
+				item.put("<xmlattr>.id", it->id);
+				item.put("<xmlattr>.modify_time", it->modify_time.to_string("yyyy-MM-dd HH:mm:ss"));
+				item.put("<xmlattr>.key", it->key);
+				item.put("<xmlattr>.value", it->value);
+				item.put("<xmlattr>.enable", it->enable);
+				item.put("<xmlattr>.remarks", it->remarks);
+			}
+			auto& tmp_user_config = root.add("root.user_config", "");
+			for (auto& it : web_user_config_info_list_) {
+				auto& item = tmp_user_config.add("item", "");
+				item.put("<xmlattr>.id", it->id);
+				item.put("<xmlattr>.modify_time", it->modify_time.to_string("yyyy-MM-dd HH:mm:ss"));
+				item.put("<xmlattr>.name", it->name);
+				item.put("<xmlattr>.code", it->code);
+				item.put("<xmlattr>.password", it->password);
+				item.put("<xmlattr>.enable", it->enable);
+				item.put("<xmlattr>.remarks", it->remarks);
+			}
+			boost::property_tree::xml_writer_settings<std::string> settings(' ', 4);
+			write_xml("./config/config.xml", root, std::locale(), settings);
+		}
+		catch (std::exception const& ec) {
+			LOG_ERROR << "保存xml配置异常" << ec;
+		}
+	}
 private:
-    /**
-     * @brief 在表格保存操作中,根据条件决定是否执行保存。
-     * @tparam _Table 表格数据的类型。
-     * @param value 当前表格的值。
-     * @param value_tmp 临时表格的值。
-     * @param type 更改类型,指示表格发生了什么类型的更改(v3::linq_change_type)。
-     * @param end 布尔值,指示是否为保存操作的结束阶段。
-     */
-    template<typename _Table>
-    void on_table_save(_Table const& value, _Table const& value_tmp, v3::linq_change_type type, bool end) {
-        if (end) {
-            save();
-        }
-    }
+	template<typename _Table>
+	void on_table_save(_Table const& value, _Table const& value_tmp, v3::linq_change_type type, bool end) {
+		if (end) {
+			save();
+		}
+	}
+	bool create_file(std::filesystem::path const&filename = "./config/config.xml") {
+	    if (!std::filesystem::exists(filename.parent_path())) {
+	        if (!std::filesystem::create_directories(filename.parent_path()))
+	            return false;
+	    }
+	    if (!std::filesystem::exists(filename)) {
+	        std::ofstream file(filename);
+	        if (!file.is_open())
+	            return false;
+	        file.close();
+			web_user_config_info_list_.push_back(std::make_shared<web_user_config_info>(web_user_config_info{
+				1,
+				robotics::v3::datetime::current_datetime(),
+				"管理员",
+				"admin",
+				"123456",
+				true,
+				"管理员"}));
+			save();
+	    }
+	    return true;
+	}
 private:
-    std::mutex												        mutex_;
-    std::vector<std::shared_ptr<web_user_config_info>>	            user_config_list_;
-    std::shared_ptr<v3::linq_ptr<web_user_config_info>>	            linq_user_config_;
-    std::vector<std::shared_ptr<web_after_config_info>>	            after_config_list_;
-    std::shared_ptr<v3::linq_ptr<web_after_config_info>>	        linq_after_config_;
-    std::vector<std::shared_ptr<web_general_config_info>>	        general_config_list_;
-    std::shared_ptr<v3::linq_ptr<web_general_config_info>>	        linq_general_config_;
-    
+	std::mutex mutex_;
+	std::vector<std::shared_ptr<web_after_config_info>> web_after_config_info_list_;
+	std::shared_ptr<v3::linq_ptr<web_after_config_info>> linq_web_after_config_info_;
+	std::vector<std::shared_ptr<web_general_config_info>> web_general_config_info_list_;
+	std::shared_ptr<v3::linq_ptr<web_general_config_info>> linq_web_general_config_info_;
+	std::vector<std::shared_ptr<web_user_config_info>> web_user_config_info_list_;
+	std::shared_ptr<v3::linq_ptr<web_user_config_info>> linq_web_user_config_info_;
 };

+ 131 - 0
src/xml/xml_update.hpp

@@ -0,0 +1,131 @@
+#pragma once
+//stl
+#include <iostream>
+#include <sstream>
+#include <vector>
+//local
+#include "xml_context.hpp"
+
+template<typename _Table>
+struct _update_ {};
+template<>
+struct _update_<web_after_config_info> {
+	_update_(web_after_config_info const&value) {
+		if (xml_context::from<web_after_config_info>().where([value](auto it) {return it->id == value.id; }).empty()) {
+			web_after_config_info info{
+				.id = 0,
+				.modify_time = v3::datetime::current_time_stamp(),
+				.value = value.value,
+				.enable = value.enable,
+				.remarks = value.remarks };
+			xml_context::from<web_after_config_info>().
+				max(info.id, [](auto it) {return it->id; }).
+				inc(info.id).
+				append(info).
+				submit();
+		}
+		else {
+			xml_context::from<web_after_config_info>().
+				where([value](auto it)
+					{
+						return it->id == value.id;
+					}).
+				update([value](auto it)
+					{
+						it->modify_time = v3::datetime::current_time_stamp();
+						it->value = value.value;
+						it->enable = value.enable;
+						it->remarks = value.remarks;
+						return true;
+					}).
+				submit();
+		}
+	}
+};
+template<>
+struct _update_<web_general_config_info> {
+	_update_(web_general_config_info const&value) {
+		if (xml_context::from<web_general_config_info>().where([value](auto it) {return it->key == value.key; }).empty()) {
+			web_general_config_info info{
+				.id = 0,
+				.modify_time = v3::datetime::current_time_stamp(),
+				.key = value.key,
+				.value = value.value,
+				.enable = value.enable,
+				.remarks = value.remarks };
+			xml_context::from<web_general_config_info>().
+				max(info.id, [](auto it) {return it->id; }).
+				inc(info.id).
+				append(info).
+				submit();
+		}
+		else {
+			xml_context::from<web_general_config_info>().
+				where([value](auto it)
+					{
+						return it->key == value.key;
+					}).
+				update([value](auto it)
+					{
+						it->modify_time = v3::datetime::current_time_stamp();
+						it->key = value.key;
+						it->value = value.value;
+						it->enable = value.enable;
+						it->remarks = value.remarks;
+						return true;
+					}).
+				submit();
+		}
+	}
+};
+template<>
+struct _update_<web_user_config_info> {
+	_update_(web_user_config_info const&value) {
+		if (xml_context::from<web_user_config_info>().where([value](auto it) {return it->id == value.id; }).empty()) {
+			web_user_config_info info{
+				.id = 0,
+				.modify_time = v3::datetime::current_time_stamp(),
+				.name = value.name,
+				.code = value.code,
+				.password = value.password,
+				.enable = value.enable,
+				.remarks = value.remarks };
+			xml_context::from<web_user_config_info>().
+				max(info.id, [](auto it) {return it->id; }).
+				inc(info.id).
+				append(info).
+				submit();
+		}
+		else {
+			xml_context::from<web_user_config_info>().
+				where([value](auto it)
+					{
+						return it->id == value.id;
+					}).
+				update([value](auto it)
+					{
+						it->modify_time = v3::datetime::current_time_stamp();
+						it->name = value.name;
+						it->code = value.code;
+						it->password = value.password;
+						it->enable = value.enable;
+						it->remarks = value.remarks;
+						return true;
+					}).
+				submit();
+		}
+	}
+};
+class xml_update {
+public:
+	template<typename _Table>
+	static void update(_Table const& value) {
+		(_update_<_Table>)(value);
+	}
+	template<typename _Table>
+	static void update(std::vector<_Table> const& values) {
+		for (auto const& value : values) {
+			(_update_<_Table>)(value);
+		}
+	}
+};