浏览代码

Z991239-5462 #comment fea: can open startup page at the beginning

chenliangyu 1 年之前
父节点
当前提交
2ad72a9b05

+ 2 - 3
Framework/spbase/sp_cfg.cpp

@@ -1991,11 +1991,10 @@ int init_defaultShellCfg(sp_dir_t* dir, sp_cfg_t* cfg)
 	default_shellConfig.insert(std::make_pair("Entity", entitySection));
 	std::map<std::string, std::string> startupSection;
 	long long index = 1;
-#ifdef _WIN32
+	//should not change those orders
+	startupSection.insert(std::make_pair(std::to_string(index++), "VtmLoader"));
 	startupSection.insert(std::make_pair(std::to_string(index++), "GUIConsole"));
-#endif
 	startupSection.insert(std::make_pair(std::to_string(index++), "Chromium"));
-	startupSection.insert(std::make_pair(std::to_string(index++), "VtmLoader"));
 	
 	default_shellConfig.insert(std::make_pair("Startup", startupSection));
 

+ 19 - 19
Module/include/EventCode.h

@@ -680,47 +680,47 @@ ERROR_ACCESSAUTH_CONNECT_ACS_x}
 //gui告警上送
 #define WARN_GUICONSOLE_LOG_INFO 0x50810005
 
-//LogSender已订阅
+//LogSender已订阅,请不要重复订阅
 #define WARN_GUICONSOLE_LOG_ALREADY_REGISTER	0x50820001
-//LogSender已反订阅
+//LogSender已反订阅,请不要重复调用
 #define WARN_GUICONSOLE_LOG_ALREADY_UNREGISTER	0x50820002
 //GetAllEntity-GetAllRegistedEntity失败
 #define WARN_GUICONSOLE_GETALLENTITY_REGISTERED	0x50820011
-//GetAllEntity-GetEntity失败
+//获取实体信息失败,调用GetEntity失败
 #define WARN_GUICONSOLE_GETALLENTITY_GETENTITY	0x50820012
-//GetEntity Failed
+//获取实体信息失败,GetEntity失败
 #define WARN_GUICONSOLE_GETENTITY_FAILED	0x50820013
-//no privilige
+//guiconsole无权限进行该操作
 #define WARN_GUICONSOLE_NO_PRIVILIGE	0x50820101
 //未知重启原因
 #define WARN_GUICONSOLE_REBOOT_UNKNOWN_REASON	0x50820301
-//performance failed:snapshot
+//性能监控打开失败,调用snapshot异常
 #define WARN_GUICONSOLE_PERFORMANCE_SNAPSHOT	0x50820401
-//performance failed:thread already existed
+//性能监控打开失败,thread已存在
 #define WARN_GUICONSOLE_PERFORMANCE_EXISTED		0x50820402
-//performance failed:thread not exist
+//性能监控关闭失败,thread不存在
 #define WARN_GUICONSOLE_PERFORMANCE_NOTEXISTED		0x50820403
-//performance failed:Process32First
+//性能监控打开失败,Process32First调用异常
 #define WARN_GUICONSOLE_PERFORMANCE_PROCESS32FIRST	0x50820402
-//openLogSender not vaild input
+//日志订阅参数错误,请检查输入参数
 #define WARN_GUICONSOLE_LOGSENDER_UNVAILD_INPUT	0x50820501
-//entity monitor get entity info failed
+//实体监控打开失败,获取实体信息错误
 #define WARN_GUICONSOLE_ENTITYMONITOR_GETINFO_FAILED	0x50820601
-//entityMonitor failed:thread already existed
+//实体监控打开失败,thread已存在
 #define WARN_GUICONSOLE_ENTITYMONITOR_EXISTED		0x50820602
-//entityMonitor failed:thread not exist
+//实体监控关闭失败,thread不存在
 #define WARN_GUICONSOLE_ENTITYMONITOR_NOTEXISTED		0x50820603
-//entityMonitor failed:no privilege
+//实体监控打开失败,无权限
 #define WARN_GUICONSOLE_ENTITYMONITOR_NO_PRIVILEGE		0x50820604
-//entityMonitor failed:register failed
+//实体监控打开失败,注册异常
 #define WARN_GUICONSOLE_ENTITYMONITOR_REGISTER		0x50820605
-//entityMonitor failed:unregister failed
+//实体监控关闭失败,反注册异常
 #define WARN_GUICONSOLE_ENTITYMONITOR_UNREGISTER		0x50820606
-//GetBasicInformation failed:GetAllEntity failed
+//获取终端基本信息失败,GetAllEntity失败
 #define WARN_GUICONSOLE_BASICINFO_GETENTITY		0x50820701
-//GetBasicInformation failed:CSystemStaticInfo failed
+//获取终端基本信息失败,systemInfo失败
 #define WARN_GUICONSOLE_BASICINFO_SYSTEMINFO_FAILED		0x50820702
-//GetBasicInformation failed:GetSystemRunInfo failed
+//获取终端基本信息失败,runinfo失败
 #define WARN_GUICONSOLE_BASICINFO_RUNINFO_FAILED		0x50820703
 
 

+ 52 - 0
Module/mod_chromium/CModTools.cpp

@@ -25,6 +25,7 @@
 #include "EventCode.h"
 #include "url_encoder.h"
 #include "SpUtility.h"
+#include <winpr/wnd.h>
 
 
 void SystemRunTest(const std::string& systemCmd);
@@ -191,6 +192,8 @@ namespace Chromium {
 			errPagePath.Append("cardStore.html");
 		else if (errType._to_integral() == ERR_PAGE_REASON::main)
 			errPagePath.Append("homePageErr.html");
+		else if (errType._to_integral() == ERR_PAGE_REASON::startup)
+			errPagePath.Append("startPage.html");
 		else
 			errPagePath.Append("entityCheck.html");
 
@@ -528,6 +531,33 @@ namespace Chromium {
 #endif //RVC_OS_LINUX
 	}
 
+	std::string CModTools::generateCommonPage(std::string url, std::string name, std::string size, std::string point, int top)
+	{
+#if defined(RVC_OS_LINUX)
+		return generateBrowserCMDForEverything(url, 0); //need change later, because common page may not run in full-screen mode
+#else
+		CSimpleStringA strChromiumPath = GetCefHead(this->m_pEntity), strCmdLine = "";
+		strCmdLine.Append(strChromiumPath).Append(" --url=").Append(url.c_str());
+		if(size.length() > 0)
+			strCmdLine.Append(" --center-size=").Append(size.c_str());
+		if(point.length() > 0)
+			strCmdLine.Append(" --src-pos=").Append(point.c_str());
+		CSimpleStringA cachePath;
+		this->m_pEntity->GetFunction()->GetPath("Temp", cachePath);
+		cachePath.Append(CSimpleStringA(SPLIT_SLASH_STR)).Append("cefCache_").Append(m_strCacheHead.length() > 0 ? m_strCacheHead.c_str() : "").Append(name.c_str());
+		strCmdLine.Append(" --cache-path=").Append(cachePath);
+		strCmdLine.Append(" --no-sandbox");
+		strCmdLine.Append(" --hide-controls");
+		strCmdLine.Append(" --lang=zh-CN");//install page need language chinese
+		strCmdLine.Append(" --hide-tabs");
+		strCmdLine.Append(" --logextend=").Append(name.c_str());
+		strCmdLine.Append(" --top=").Append(std::to_string(top).c_str());
+		DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("%s cmdline : %s", name.c_str(), strCmdLine.GetData());
+		return strCmdLine.GetData();
+#endif
+	}
+
+
 	std::string CModTools::generateSpecialPageFromOtherEntityCmd(std::string mainUrl)
 	{
 #if defined(RVC_OS_WIN)
@@ -770,6 +800,28 @@ namespace Chromium {
 				return std::make_pair(Error_Succeed, openCefRet.second);
 			else
 				DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("open cef for %s failed: %d", reason._to_string(), openCefRet.first);
+		}
+		 else if (reason._to_integral() == ERR_PAGE_REASON::startup)
+		{
+			auto url = std::string(R"(file:///)") + getErrUrl(reason).second;
+			auto strCmdline = generateCommonPage(url, (+ERR_PAGE_REASON::startup)._to_string(), "600*310", "", (int)HWND_NOTOPMOST);
+			auto openCefRet = openCef(strCmdline, false);
+			if (Error_Succeed == openCefRet.first)
+				return std::make_pair(Error_Succeed, openCefRet.second);
+			else
+				DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("open cef %s for %s failed: %d", (+ERR_PAGE_REASON::startup)._to_string(),
+					reason._to_string(), openCefRet.first);
+		}
+		 else if (reason._to_integral() == ERR_PAGE_REASON::performance_monitor)
+		{
+			auto url = std::string(R"(file:///)") + getErrUrl(reason).second;
+			auto strCmdline = generateCommonPage(url, (+ERR_PAGE_REASON::performance_monitor)._to_string(), "800*600", "", (int)HWND_NOTOPMOST);
+			auto openCefRet = openCef(strCmdline, false);
+			if (Error_Succeed == openCefRet.first)
+				return std::make_pair(Error_Succeed, openCefRet.second);
+			else
+				DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("open cef %s for %s failed: %d", (+ERR_PAGE_REASON::performance_monitor)._to_string(),
+					reason._to_string(), openCefRet.first);
 		}
 		 else if (reason._to_integral() == ERR_PAGE_REASON::Install)
 		{

+ 5 - 2
Module/mod_chromium/CModTools.h

@@ -20,9 +20,11 @@
 namespace Chromium {
 
 	BETTER_ENUM(ERR_PAGE_REASON, int, CameraConfig, CardStoreIsBusy, MachineTypeError, TerminalManagerKickOut,
-		TerminalManagerOff, breakdown, warnPrompt, disabled, jobuncomplete, ErrNotify, main, Ad, extend, OutsideRequest, SpecialPageFromOtherEntity, Install)
+		TerminalManagerOff, breakdown, warnPrompt, disabled, jobuncomplete, ErrNotify, main, Ad, extend, OutsideRequest, SpecialPageFromOtherEntity
+		, Install, startup, performance_monitor)
 
-		BETTER_ENUM(PAGE_TYPE, int, Deploy, CameraConfig, TerminalManager, errPage, Ad, slv, init, TradeManager, breakdown, extend, CardStoreIsBusy, Install)
+		BETTER_ENUM(PAGE_TYPE, int, Deploy, CameraConfig, TerminalManager, errPage, Ad, slv, init, TradeManager
+			, breakdown, extend, CardStoreIsBusy, Install, startup, performance_monitor)
 
 		BETTER_ENUM(TradeManageCodeEnum, int, Undefined, Trade, JobUncomplete, Disabled)
 
@@ -80,6 +82,7 @@ namespace Chromium {
 		std::string generateInstallCmd(std::string installUrl);
 		std::string generateAdCmd(std::string AdUrl);
 		std::string generateSpecialPageFromOtherEntityCmd(std::string mainUrl);
+		std::string generateCommonPage(std::string url, std::string name, std::string size, std::string point, int top);
 #if defined(RVC_OS_LINUX)
         //pagetype: 0: 首页全屏, 1:副屏全屏,2:错误页;3:外部调用
         std::string generateBrowserCMDForEverything(const std::string& url, int pageType);

+ 58 - 36
Module/mod_chromium/mod_chromium.cpp

@@ -517,28 +517,29 @@ namespace Chromium {
 		return;
 		*/
 		auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::Install);
-		DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("open page install %s, pid:%d", Error_Succeed == openRet.first ? "success" : "fail", openRet.second);
+		DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("open page install %s, pid:%d",
+			Error_Succeed == openRet.first ? "success" : "fail", openRet.second);
+	}
+
+	void CChromiumEntity::openStartupPage()
+	{
+		auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::startup);
+		DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("open page startup %s, pid:%d",
+			Error_Succeed == openRet.first ? "success" : "fail", openRet.second);
+	}
+	void CChromiumEntity::openPerformanceMonitorPage() 
+	{
+		auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::performance_monitor);
+		DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("open page performance_monitor %s, pid:%d",
+			Error_Succeed == openRet.first ? "success" : "fail", openRet.second);
 	}
 
 
 	void CChromiumEntity::startWithCfg()
 	{
-		// init cef logger first
-#if (defined _WIN32 || defined _WIN64)
-		if (!logProducer)
-			logProducer = create_log_producer_storage("cefclient_logger", "0", "");
-#else
-		CSimpleString dbgPath;
-		GetFunction()->GetPath("Dbg", dbgPath);
-		std::string dstDbgPath = dbgPath.GetData();
-		dstDbgPath.append(SPLIT_SLASH_STR).append("mod_chromium");
-
-#endif
-		
 		OnPreStart_Init(m_strArgs, m_pTransactionContext);//初始化部分, perf ,killchromium, signal, get custom url
-		if (!OnPreStart_socketStart(m_strArgs, m_pTransactionContext)) {//OnPreStart_socketStart()->new CWebsocketServer(strStructPath, this) 时间过长
-			return;
-		}
+
+
 		if (!IsConfigMode()) {
 			if (!OnPreStart_register(m_strArgs, m_pTransactionContext)) {
 				return;
@@ -611,11 +612,29 @@ namespace Chromium {
 
 		//all the init,register,openWeb run thread
 		auto startFun = [&]() {
+			// init cef logger first
+#if (defined _WIN32 || defined _WIN64)
+			if (!logProducer)
+				logProducer = create_log_producer_storage("cefclient_logger", "0", "");
+#else
+			CSimpleString dbgPath;
+			GetFunction()->GetPath("Dbg", dbgPath);
+			std::string dstDbgPath = dbgPath.GetData();
+			dstDbgPath.append(SPLIT_SLASH_STR).append("mod_chromium");
+
+#endif
+			OnPreStart_Init(m_strArgs, m_pTransactionContext);//初始化部分, perf ,killchromium, signal, get custom url
+			if (!OnPreStart_socketStart(m_strArgs, m_pTransactionContext)) {//OnPreStart_socketStart()->new CWebsocketServer(strStructPath, this) 时间过长
+				return;
+			}
+
+
 			//the system info may be not complete.If the device is not install ,it can't not read the terminalNo.
 			CSystemStaticInfo t_sysInfo;
 			GetFunction()->GetSystemStaticInfo(t_sysInfo);
 			if (t_sysInfo.strTerminalID.GetLength() == 0)// the machine is in install mode, hence start a simple init and open the install page 
 			{
+				openStartupPage();//open startup page in install mode
 				m_installMode = true;
 				DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("subscribe VtmLoader %s",
 					(Error_Succeed == GetFunction()->SubscribeLog(m_uuidVTMLoader, this, Log_Event, Severity_None, Error_IgnoreAll, -1, "VtmLoader")) ? "success" : "failed");
@@ -624,29 +643,32 @@ namespace Chromium {
 			}
 
 
-		CSimpleStringA t_terminalState;
-		if (ErrorCodeEnum::Error_Succeed == GetFunction()->GetSysVar("TerminalStage", t_terminalState))
-		{
-			DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("OnPreStart TerminalStage:%s", t_terminalState.GetData());
-			CAutoArray<CSimpleStringA> strErrorCodeArr;
-			CAutoArray<CSimpleStringA> strDescriptionArr;
-			CAutoArray<CSimpleStringA> strRemarkArr;
-			auto ret = GetFunction()->GetPrivilegeFunction()->GetVTMErrMsgArr(strErrorCodeArr, strDescriptionArr, strRemarkArr);
-			if (Error_Succeed == ret)
-				InitUserCodeToMsgTip(strErrorCodeArr, strDescriptionArr, strRemarkArr);
-
-			if (m_withSpecialTest)
+			CSimpleStringA t_terminalState;
+			if (ErrorCodeEnum::Error_Succeed == GetFunction()->GetSysVar("TerminalStage", t_terminalState))
 			{
-				CSimpleStringA strDescription, strVTMCode;
-				GetFunction()->GetVTMErrMsg(123456, strDescription, strVTMCode);
-			}
-
+				DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("OnPreStart TerminalStage:%s", t_terminalState.GetData());
+				CAutoArray<CSimpleStringA> strErrorCodeArr;
+				CAutoArray<CSimpleStringA> strDescriptionArr;
+				CAutoArray<CSimpleStringA> strRemarkArr;
+				auto ret = GetFunction()->GetPrivilegeFunction()->GetVTMErrMsgArr(strErrorCodeArr, strDescriptionArr, strRemarkArr);
+				if (Error_Succeed == ret)
+					InitUserCodeToMsgTip(strErrorCodeArr, strDescriptionArr, strRemarkArr);
 
-			startWithCfg();//属于chromium重启或者其他情况,已经初始化好配置
-		}
-		else
+				if (m_withSpecialTest)
+				{
+					CSimpleStringA strDescription, strVTMCode;
+					GetFunction()->GetVTMErrMsg(123456, strDescription, strVTMCode);
+				}
+				//should not open startup page, since it is already run before.
+				startWithCfg();//属于chromium重启或者其他情况,已经初始化好配置
+			}
+			else
+			{
+				openStartupPage();//open startup page in normal mode
 				DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("subscribe VtmLoader %s",
-				(Error_Succeed == GetFunction()->SubscribeLog(m_uuidVTMLoader, this, Log_Event, Severity_None, Error_IgnoreAll, -1, "VtmLoader")) ? "success" : "failed");
+					(Error_Succeed == GetFunction()->SubscribeLog(m_uuidVTMLoader, this, Log_Event, Severity_None, Error_IgnoreAll, -1, "VtmLoader")) ? "success" : "failed");
+			}
+				
 		};
 		
 		boost::thread(startFun).detach();

+ 2 - 0
Module/mod_chromium/mod_chromium.h

@@ -109,6 +109,8 @@ namespace Chromium {
 		void openAdPage();
 		void openExtendPage();
 		void openInstallPage();
+		void openStartupPage();
+		void openPerformanceMonitorPage();
 		void startWithCfg();
 		bool CheckIsCardStore();
 

+ 2 - 1
Module/mod_guiconsole/GUIConsole_def_g.h

@@ -308,12 +308,13 @@ struct GUIConsoleService_GetBasicInformation_Ans
 	CSimpleStringA manufacturer;
 	CSimpleStringA machineModel;
 	CSimpleStringA versionNo;
+	CSimpleStringA Env;
 	bool basicconfig_status;
 	bool errmsg_status;
 
 	void Serialize(SpBuffer &Buf)
 	{
-		auto & buf = Buf & result & additionalMsg & Idle_entityNum & total_entityNum & vtm_startupTime & terminalNo & machineType & manufacturer & machineModel & versionNo & basicconfig_status & errmsg_status;
+		auto & buf = Buf & result & additionalMsg & Idle_entityNum & total_entityNum & vtm_startupTime & terminalNo & machineType & manufacturer & machineModel & versionNo & Env & basicconfig_status & errmsg_status;
 	}
 
 };

+ 3 - 1
Module/mod_guiconsole/GuiConsole.xml

@@ -127,7 +127,7 @@
 			<req>
 				<!-- 实体名称,类型为字符串 -->
 				<param name="entityName" type="string"/>
-				<!-- 操作类型,类型为字符串, 有效值包含Start,Stop,Pause,Continue,Terminate -->
+				<!-- 操作类型,类型为字符串, 有效值包含Start,Stop,Pause,Continue,Terminate,OpenLog -->
 				<param name="operation" type="string"/>
 				<!-- 是否等待,类型为布尔值 -->
 				<param name="isWait" type="bool"/>
@@ -202,6 +202,8 @@
 				<param name="machineModel" type="string"/>
 				<!-- 版本号,类型为字符串 -->
 				<param name="versionNo" type="string"/>
+				<!-- 环境 DEV、ST、UAT、PRD,类型为字符串 -->
+				<param name="Env" type="string"/>
 				<!-- 基础配置获取状态,类型为bool -->
 				<param name="basicconfig_status" type="bool"/>
 				<!-- 错误码配置获取状态,类型为bool -->

+ 14 - 6
Module/mod_guiconsole/mod_guiconsole.cpp

@@ -27,9 +27,11 @@ void CGUIConsoleEntity::OnLog(const CAutoArray<CUUID>& SubIDs, const CUUID nLogI
 	if (dwUserCode == 0x2090000A || dwUserCode == 0x20900009)
 		return;
 
+	
 	//did not open log sender
 	if (!m_isOpenLogSender)
 		return;
+	DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("OnLog %s %s", pszEntityName, pszMessage);
 	if (pszMessage != NULL && strlen(pszMessage) > 2)
 	{
 		CSimpleStringA str = pszMessage;
@@ -118,9 +120,9 @@ std::pair<DWORD, std::string> CGUIConsoleEntity::closeLogSender()
 {
 	if ((__int64)m_logSubID == 0)
 	{
-		LogWarn(SeverityLevelEnum::Severity_Middle, ErrorCodeEnum::Error_AlreadyExist, WARN_GUICONSOLE_LOG_ALREADY_UNREGISTER, "openLogSender: already unregister");
+		LogWarn(SeverityLevelEnum::Severity_Middle, ErrorCodeEnum::Error_AlreadyExist, WARN_GUICONSOLE_LOG_ALREADY_UNREGISTER, "closeLogSender: already unregister");
 		m_isOpenLogSender = false;
-		return std::pair<DWORD, std::string>(WARN_GUICONSOLE_LOG_ALREADY_UNREGISTER, "openLogSender: already register");
+		return std::pair<DWORD, std::string>(WARN_GUICONSOLE_LOG_ALREADY_UNREGISTER, "closeLogSender: already unregister");
 	}
 	else
 	{
@@ -410,7 +412,16 @@ std::pair<DWORD, std::string> CGUIConsoleEntity::GetBasicInformation(SpReqAnsCon
 	ctx->Ans.manufacturer = m_terminalInfo.strManufacturer;
 	ctx->Ans.machineModel = m_terminalInfo.strMachineModel;
 	ctx->Ans.versionNo = getRunVersion();
-
+#ifdef DEVOPS_ON_ST /*DevOps流水线编译,ST环境*/
+	ctx->Ans.Env = "ST";
+#elif defined(DEVOPS_ON_UAT)/*DevOps流水线编译,UAT环境*/
+	ctx->Ans.Env = "UAT";
+#elif defined(DEVOPS_ON_PRD)/*DevOps流水线编译,PRD环境*/
+	ctx->Ans.Env = "PRD";
+#else/*本地编译等非DevOps环境编译的版本*/
+	ctx->Ans.Env = "DEV";
+#endif
+	
 	CSystemRunInfo sysRunInfo;
 	if (ErrorCodeEnum::Error_Succeed != (ret = GetFunction()->GetSystemRunInfo(sysRunInfo)))
 	{
@@ -422,9 +433,6 @@ std::pair<DWORD, std::string> CGUIConsoleEntity::GetBasicInformation(SpReqAnsCon
 	ctx->Ans.basicconfig_status = sysRunInfo.bBasicCfgWork;
 	ctx->Ans.errmsg_status = sysRunInfo.bErrCfgWork;
 
-
-	
-
 	return std::pair<DWORD, std::string>(ErrorCodeEnum::Error_Succeed, "");
 }
 

+ 2 - 0
addin/res/ManagerDesktop/README.md

@@ -0,0 +1,2 @@
+# ManagerDesktop
+H5公共错误页,密钥重置