فهرست منبع

#IQRV #comment [LocalMerge] 因为去分行化不上线,需要先将其余非去分行化内容拆出来上线

gifur 3 سال پیش
والد
کامیت
1016667270
44فایلهای تغییر یافته به همراه4149 افزوده شده و 138 حذف شده
  1. 0 2
      CMakeLists.txt
  2. 48 0
      Module/include/DevEntityCommBase.hpp
  3. 1 0
      Module/include/EventCode.h
  4. 10 17
      Module/mod_CenterSetting/CenterSettingConn.cpp
  5. 1 1
      Module/mod_CenterSetting/CenterSettingConn.h
  6. 96 1
      Module/mod_CenterSetting/CenterSettingService.xml
  7. 178 2
      Module/mod_CenterSetting/CenterSetting_client_g.h
  8. 186 0
      Module/mod_CenterSetting/CenterSetting_def_g.h
  9. 158 2
      Module/mod_CenterSetting/CenterSetting_server_g.h
  10. 668 9
      Module/mod_CenterSetting/mod_centersetting.cpp
  11. 93 1
      Module/mod_CenterSetting/mod_centersetting.h
  12. 1 1
      Module/mod_DeviceControl/DeviceControl.xml
  13. 1 1
      Module/mod_DeviceControl/mod_DeviceControl.cpp
  14. 61 0
      Module/mod_ResourceWatcher/mod_ResourceWatcher.cpp
  15. 16 9
      Module/mod_ResourceWatcher/mod_ResourceWatcher.h
  16. 2 1
      Module/mod_chromium/CModTools.cpp
  17. 43 15
      Module/mod_chromium/mod_chromium.cpp
  18. 1 0
      Module/mod_chromium/mod_chromium.h
  19. 30 30
      addin/res/ManagerDesktop/css/emui-style.css
  20. BIN
      addin/res/ManagerDesktop/images/check_off_disable.png
  21. BIN
      addin/res/ManagerDesktop/images/delete.png
  22. BIN
      addin/res/ManagerDesktop/images/edit.png
  23. BIN
      addin/res/ManagerDesktop/images/new.png
  24. BIN
      addin/res/ManagerDesktop/images/new_disable.png
  25. BIN
      addin/res/ManagerDesktop/images/new_hover.png
  26. BIN
      addin/res/ManagerDesktop/images/select_in_disable.png
  27. BIN
      addin/res/ManagerDesktop/images/select_input340_disabled.png
  28. BIN
      addin/res/ManagerDesktop/images/switch_off_disable.png
  29. BIN
      addin/res/ManagerDesktop/images/switch_on_disable.png
  30. BIN
      addin/res/ManagerDesktop/images/table_border.png
  31. 4 2
      addin/res/ManagerDesktop/js/menu.js
  32. 5 1
      addin/res/ManagerDesktop/js/page.js
  33. 1 3
      addin/res/ManagerDesktop/js/page/browser.js
  34. 456 0
      addin/res/ManagerDesktop/js/page/business.js
  35. 0 24
      addin/res/ManagerDesktop/js/page/centersettings.js
  36. 544 0
      addin/res/ManagerDesktop/js/page/context.js
  37. 1 3
      addin/res/ManagerDesktop/js/page/dns.js
  38. 1 3
      addin/res/ManagerDesktop/js/page/initializer.js
  39. 212 4
      addin/res/ManagerDesktop/js/page/logswitch.js
  40. 1 3
      addin/res/ManagerDesktop/js/page/reset.js
  41. 357 3
      addin/res/ManagerDesktop/js/public.js
  42. 310 0
      addin/res/ManagerDesktop/prototype/context.html
  43. 325 0
      addin/res/ManagerDesktop/prototype/logswitch.html
  44. 338 0
      addin/res/ManagerDesktop/prototype/vermanagement.html

+ 0 - 2
CMakeLists.txt

@@ -76,12 +76,10 @@ if($ENV{PIPELINE_BUILD_ID})
 
 	set(DEVOPS_ON TRUE)
 else()
-	# 获取当前的GIT_HASH
 	set(GIT_HASH "unknown")
 	get_git_hash(GIT_HASH)
 	message(STATUS "Git hash is ${GIT_HASH}")
 
-	# 获取当前的分支
 	set(GIT_BRANCH "unknown")
 	get_git_branch(GIT_BRANCH)
 	message(STATUS "Git branch is ${GIT_BRANCH}")

+ 48 - 0
Module/include/DevEntityCommBase.hpp

@@ -221,7 +221,43 @@ inline void CDevAdptEntityBase::InitializeVendorLogSwitch()
 		}
 	}
 
+	bool fromLocal = false;
+
+	if (stLogConfig.strLevel.Compare("OFF", true) == 0) {
+		Dbg("Try to read from global settings.");
+		CSmartPointer<IConfigInfo> spConfig;
+		ErrorCodeEnum erroCode = GetFunction()->OpenConfig(Config_Cache, spConfig);
+		CAutoArray<CSimpleStringA> adapters;
+		spConfig->ReadAllKeys("AdapterLogSwith", adapters);
+		CSimpleStringA strKey(true);
+		for (int i = 0; i < adapters.GetCount(); ++i) {
+            Dbg("%d: %s, %s", i, adapters[i].GetData(), GetEntityName());
+			if (adapters[i].Compare(GetEntityName(), true) == 0) {
+				strKey = adapters[i];
+				break;
+			}
+		}
+		if (!strKey.IsNullOrEmpty()) {
+			CSimpleStringA strValue(true);
+			spConfig->ReadConfigValue("AdapterLogSwith", strKey, strValue);
+			CAutoArray<CSimpleStringA> settings;
+			Dbg("Value: %s", strValue.GetData());
+			if (!strValue.IsNullOrEmpty() && (settings = strValue.Split(',')).GetCount() == 2) {
+				if (settings[0].GetLength() == 1 && atoi(settings[0]) >= 1 && settings[1].GetLength() == 1) {
+					if (settings[1].Compare("1") == 0)  stLogConfig.strLevel = "Fatal";
+					else if (settings[1].Compare("2") == 0)  stLogConfig.strLevel = "Error";
+					else if (settings[1].Compare("3") == 0)  stLogConfig.strLevel = "Warn";
+					else if (settings[1].Compare("4") == 0)  stLogConfig.strLevel = "Info";
+					else if (settings[1].Compare("5") == 0)  stLogConfig.strLevel = "Trace";
+					else stLogConfig.strLevel = "All";
+					fromLocal = true;
+				}
+			}
+		}
+	} 
+
 	if (stLogConfig.strLevel.Compare("OFF", true) != 0) {
+
 		str.Clear();
 		centerConfig->ReadConfigValue(GetEntityName(), "Type", str);
 		if (!str.IsNullOrEmpty())
@@ -230,6 +266,18 @@ inline void CDevAdptEntityBase::InitializeVendorLogSwitch()
 		GetFunction()->GetPath("Dbg", stLogConfig.strLogPath);
 		Dbg("Dbg: %s", stLogConfig.strLogPath.GetData());
 		stLogConfig.Settle();
+
+        do {
+            CEntityStaticInfo staticInfo;
+            GetFunction()->GetEntityStaticInfo(GetEntityName(), staticInfo);
+            DWORD dwUsrCode = fromLocal ? 0xFFFEE : 0xFFFEF;
+            dwUsrCode |= (staticInfo.wEntityDevelopID << 20);
+            LogWarn(Severity_Middle, Error_Debug, dwUsrCode,
+                    CSimpleStringA::Format("{\"RecordLevel\":\"%s\"£¬\"RecordType\":\"%s\"£¬\"DeterminedBy\":\"%s\"}",
+                                           stLogConfig.strLevel.GetData(),
+                                           stLogConfig.strType.GetData(),
+                                           fromLocal ? "LocalMaintain" : "CenterSettings"));
+        } while (false);
 	}
 }
 

+ 1 - 0
Module/include/EventCode.h

@@ -62,6 +62,7 @@ static const char* Device_Type_Table[] = {
 #define EVENT_MOD_CENTERSETTING_UPDATE            0x10100017          //集中配置发生更新
 #define ERR_MOD_CENTERSETTING_HTTP_FAILED         0x10100018          //HTTP连接失败
 #define ERR_MOD_CENTERSETTING_WRITE_FAILED        0x10100019          //集中配置写入失败
+#define EVENT_CENTERSETTING_CHANGE_ROOT_TERMINALNO        0x1010001A //更新root.ini中的终端号
 
 /*----SystemCustomization--modify--by--LZM--at--2020/4/8----*/
 #define LOG_WARN_SYSTEMINITIAL_FAILED                0x10B40001  //系统定制失败

+ 10 - 17
Module/mod_CenterSetting/CenterSettingConn.cpp

@@ -4,7 +4,7 @@
 #include <map>
 #include <regex>
 using namespace std;
-
+using std::regex;
 #include "mod_centersetting.h"
 
 #include "fileutil.h"
@@ -91,7 +91,7 @@ bool CCenterSettingConn::IsServiceAvailable(const char *pszServiceAddr)
 }
 
 // 上送多个请求结构,对应多个配置
-ErrorCodeEnum CCenterSettingConn::BeginPollConfig()
+ErrorCodeEnum CCenterSettingConn::BeginPollConfig(const CSystemStaticInfo& info)
 {
 	assert(IsConnectionOK());
 	auto pEntity = (CCenterSettingEntity *)m_pEntity;
@@ -99,11 +99,6 @@ ErrorCodeEnum CCenterSettingConn::BeginPollConfig()
 	assert(pFunc != NULL);
 	CSimpleStringA strPath;
 	pFunc->GetPath("Cfg", strPath);
-
-	CSystemStaticInfo info;
-	auto rc = pFunc->GetSystemStaticInfo(info);
-	assert(rc == Error_Succeed);
-
 	auto pPackage = CreateNewPackage("PollSM");
 	const int nArrayNum = pEntity->m_SyncFileInfo.size();
 	if (nArrayNum> 0)
@@ -191,7 +186,7 @@ ErrorCodeEnum CCenterSettingConn::OnEndPollConfig(const CSmartPointer<IPackage>
 		assert(bSuc && nRetLen == nBufLen);
 		PollSMA*pRet = (PollSMA*)pBuf;
 
-		Dbg("CenterConfig has been changed, hash: %s, file: %s", (const char*)pRet->FileHash, (const char*)pRet->FileName);
+		Dbg("center config changed, hash: %s, file: %s", (const char*)pRet->FileHash, (const char*)pRet->FileName);
 
 		// 校验Hash是否匹配
 		BYTE sm3[32] = {};
@@ -238,16 +233,14 @@ ErrorCodeEnum CCenterSettingConn::OnEndPollConfig(const CSmartPointer<IPackage>
 		char tmp[32] = {};
 		if(inifile_read_str_s("CenterSetting", "Server", "", tmp, 32, strNewFile) < 10)
 		{
-			Dbg("read center setting service addr from %s fail", (const char*)strNewFile);
-			delete[] pBuf;
-			return Error_NotConfig;
-		}
-
-		if (!IsServiceAvailable(tmp))
-		{
-			Dbg("the new centersetting server ip[%s] cannot be connectable!!!", tmp);
+			Dbg("read center setting service addr from new file %s fail", (const char*)strNewFile);
+            delete[] pBuf;
+            return Error_NotConfig;
 		}
-
+        else if (!IsServiceAvailable(tmp)) {
+            Dbg("the new centersetting server ip[%s] cannot be connectable!!!", tmp);
+        }
+	
 		// 读出当前集中配置服务地址
 		memset(tmp, 0, 32);
 		inifile_read_str_s("CenterSetting", "Server", "", tmp, 32, strCurFile);

+ 1 - 1
Module/mod_CenterSetting/CenterSettingConn.h

@@ -72,7 +72,7 @@ class CCenterSettingConn : public SpSecureClient
 {
 public:
 	CCenterSettingConn(CEntityBase *pEntity);
-	ErrorCodeEnum BeginPollConfig();
+	ErrorCodeEnum BeginPollConfig(const CSystemStaticInfo& info);
 
 private:
 	virtual ~CCenterSettingConn(void);

+ 96 - 1
Module/mod_CenterSetting/CenterSettingService.xml

@@ -7,7 +7,6 @@
         <param name="nPort" type="int"/>
       </req>
 		</twoway>
-		
     <twoway name="GetSyncInfo" overlap="true">
       <res>
         <param name="nSyncTime" type="uint"/>
@@ -15,5 +14,101 @@
         <param name="strFileHash" type="string"/>
       </res>
     </twoway>
+    <twoway name="EditWebUrl" overlap="true">
+      <req>
+        <!--0:invalid;1:new;2:delete;3:update-->
+        <param name="operation" type="int"/>
+        <param name="index" type="int"/>
+        <param name="futureUrl" type="string"/>
+        <param name="adUrl" type="string"/>
+        <param name="remark" type="string"/>
+        <param name="env" type="int"/>
+        <param name="setDefault" type="bool"/>
+      </req>
+      <res>
+        <param name="result" type="int"/>
+        <param name="addition" type="int"/>
+        <param name="msg" type="string"/>
+      </res>
+    </twoway>
+    <twoway name="GetWebUrlList" overlap="true">
+      <req>
+        <param name="filter1" type="int"/>
+        <param name="filter2" type="int"/>
+        <param name="filter3" type="int"/>
+        <param name="filter4" type="string"/>
+      </req>
+      <res>
+        <param name="index" type="array_int"/>
+        <param name="futureUrl" type="array_string"/>
+        <param name="adUrl" type="array_string"/>
+        <param name="remark" type="array_string"/>
+        <!--1:DEV;2:ST;3:UAT-->
+        <param name="env" type="array_int"/>
+        <!--0:default;1:custom-->
+        <param name="type" type="array_int"/>
+        <!--0:backup;3:invalid;1:current apply;2:current using-->
+        <param name="status" type="array_int"/>
+      </res>
+    </twoway>
+    <twoway name="GetActiveCustomUrl" overlap="true">
+      <res>
+        <param name="fultureUrl" type="string"/>
+        <param name="adUrl" type="string"/>
+      </res>
+    </twoway>
+    <twoway name="EditTerminalBackupInfo" overlap="true">
+      <req>
+        <!--0:invalid;1:new;2:delete;3:update-->
+        <param name="operation" type="int"/>
+        <param name="index" type="int"/>
+        <param name="terminalNo" type="string"/>
+        <param name="branchIP" type="string"/>
+        <param name="remark" type="string"/>
+        <param name="env" type="int"/>
+        <param name="setDefault" type="bool"/>
+      </req>
+      <res>
+        <param name="result" type="int"/>
+        <param name="addition" type="int"/>
+        <param name="msg" type="string"/>
+      </res>
+    </twoway>
+    <twoway name="GetTerminalBackupInfoList" overlap="true">
+      <req>
+        <param name="filter1" type="int"/>
+        <param name="filter2" type="int"/>
+        <param name="filter3" type="int"/>
+        <param name="filter4" type="string"/>
+      </req>
+      <res>
+        <param name="index" type="array_int"/>
+        <param name="terminalNo" type="array_string"/>
+        <param name="branchIP" type="array_string"/>
+        <param name="remark" type="array_string"/>
+        <!--1:DEV;2:ST;3:UAT-->
+        <param name="env" type="array_int"/>
+        <!--0:backup;3:invalid;1:current apply;2:current using-->
+        <param name="status" type="array_int"/>
+      </res>
+    </twoway>
+    <twoway name="DownloadCenterFiles" overlap="true">
+      <req>
+        <param name="operation" type="int"/>
+        <param name="strAddr" type="string"/>
+        <param name="nPort" type="int"/>
+        <param name="deleteIfExist" type="bool"/>
+        <param name="additional1" type="string"/>
+        <param name="additional2" type="string"/>
+        <param name="additional3" type="string"/>
+        <param name="additional4" type="string"/>
+        <param name="reserved1" type="int"/>
+        <param name="reserved2" type="int"/>
+      </req>
+      <res>
+        <param name="result" type="int"/>
+        <param name="msg" type="string"/>
+      </res>
+    </twoway>
     </class>
 </entity>

+ 178 - 2
Module/mod_CenterSetting/CenterSetting_client_g.h

@@ -11,10 +11,13 @@
 namespace CenterSetting {
 class CenterSettingService_ClientBase : public CClientSessionBase {
 public:
-	CenterSettingService_ClientBase(CEntityBase *pEntity) : m_pEntityBase(pEntity), m_bSysManaged(false) {}
+	explicit CenterSettingService_ClientBase(CEntityBase *pEntity) : m_pEntityBase(pEntity), m_bSysManaged(false) {}
 
 protected:
-	virtual ~CenterSettingService_ClientBase() {}
+	virtual ~CenterSettingService_ClientBase()
+	{
+		/// override by user
+	}
 public:
 
 	ErrorCodeEnum Connect(CSmartPointer<IAsynWaitSp> &spAsyncWait)
@@ -94,6 +97,179 @@ public:
 		return Error;
 	}
 
+	ErrorCodeEnum EditWebUrl(CenterSettingService_EditWebUrl_Req &Req, CSmartPointer<IAsynWaitSp> &spAsyncWait, DWORD dwTimeout)
+	{
+		CSmartPointer<IClientSessionFunction> pFunc = GetFunction();
+		CAutoBuffer Buf = SpObject2Buffer(Req);
+		return pFunc->AsyncRequest(CenterSettingService_Method_EditWebUrl, CenterSettingService_MethodSignature_EditWebUrl, Buf, spAsyncWait, dwTimeout);
+	}
+	ErrorCodeEnum EditWebUrl(CenterSettingService_EditWebUrl_Req &Req, CenterSettingService_EditWebUrl_Ans &Ans, DWORD dwTimeout)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = EditWebUrl(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+	ErrorCodeEnum EditWebUrl(CenterSettingService_EditWebUrl_Req &Req, CenterSettingService_EditWebUrl_Ans &Ans, DWORD dwTimeout, DWORD &dwUserError)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = EditWebUrl(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwUserError, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+
+	ErrorCodeEnum GetWebUrlList(CenterSettingService_GetWebUrlList_Req &Req, CSmartPointer<IAsynWaitSp> &spAsyncWait, DWORD dwTimeout)
+	{
+		CSmartPointer<IClientSessionFunction> pFunc = GetFunction();
+		CAutoBuffer Buf = SpObject2Buffer(Req);
+		return pFunc->AsyncRequest(CenterSettingService_Method_GetWebUrlList, CenterSettingService_MethodSignature_GetWebUrlList, Buf, spAsyncWait, dwTimeout);
+	}
+	ErrorCodeEnum GetWebUrlList(CenterSettingService_GetWebUrlList_Req &Req, CenterSettingService_GetWebUrlList_Ans &Ans, DWORD dwTimeout)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = GetWebUrlList(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+	ErrorCodeEnum GetWebUrlList(CenterSettingService_GetWebUrlList_Req &Req, CenterSettingService_GetWebUrlList_Ans &Ans, DWORD dwTimeout, DWORD &dwUserError)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = GetWebUrlList(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwUserError, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+
+	ErrorCodeEnum GetActiveCustomUrl(CenterSettingService_GetActiveCustomUrl_Req &Req, CSmartPointer<IAsynWaitSp> &spAsyncWait, DWORD dwTimeout)
+	{
+		CSmartPointer<IClientSessionFunction> pFunc = GetFunction();
+		CAutoBuffer Buf = SpObject2Buffer(Req);
+		return pFunc->AsyncRequest(CenterSettingService_Method_GetActiveCustomUrl, CenterSettingService_MethodSignature_GetActiveCustomUrl, Buf, spAsyncWait, dwTimeout);
+	}
+	ErrorCodeEnum GetActiveCustomUrl(CenterSettingService_GetActiveCustomUrl_Req &Req, CenterSettingService_GetActiveCustomUrl_Ans &Ans, DWORD dwTimeout)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = GetActiveCustomUrl(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+	ErrorCodeEnum GetActiveCustomUrl(CenterSettingService_GetActiveCustomUrl_Req &Req, CenterSettingService_GetActiveCustomUrl_Ans &Ans, DWORD dwTimeout, DWORD &dwUserError)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = GetActiveCustomUrl(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwUserError, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+
+	ErrorCodeEnum EditTerminalBackupInfo(CenterSettingService_EditTerminalBackupInfo_Req &Req, CSmartPointer<IAsynWaitSp> &spAsyncWait, DWORD dwTimeout)
+	{
+		CSmartPointer<IClientSessionFunction> pFunc = GetFunction();
+		CAutoBuffer Buf = SpObject2Buffer(Req);
+		return pFunc->AsyncRequest(CenterSettingService_Method_EditTerminalBackupInfo, CenterSettingService_MethodSignature_EditTerminalBackupInfo, Buf, spAsyncWait, dwTimeout);
+	}
+	ErrorCodeEnum EditTerminalBackupInfo(CenterSettingService_EditTerminalBackupInfo_Req &Req, CenterSettingService_EditTerminalBackupInfo_Ans &Ans, DWORD dwTimeout)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = EditTerminalBackupInfo(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+	ErrorCodeEnum EditTerminalBackupInfo(CenterSettingService_EditTerminalBackupInfo_Req &Req, CenterSettingService_EditTerminalBackupInfo_Ans &Ans, DWORD dwTimeout, DWORD &dwUserError)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = EditTerminalBackupInfo(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwUserError, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+
+	ErrorCodeEnum GetTerminalBackupInfoList(CenterSettingService_GetTerminalBackupInfoList_Req &Req, CSmartPointer<IAsynWaitSp> &spAsyncWait, DWORD dwTimeout)
+	{
+		CSmartPointer<IClientSessionFunction> pFunc = GetFunction();
+		CAutoBuffer Buf = SpObject2Buffer(Req);
+		return pFunc->AsyncRequest(CenterSettingService_Method_GetTerminalBackupInfoList, CenterSettingService_MethodSignature_GetTerminalBackupInfoList, Buf, spAsyncWait, dwTimeout);
+	}
+	ErrorCodeEnum GetTerminalBackupInfoList(CenterSettingService_GetTerminalBackupInfoList_Req &Req, CenterSettingService_GetTerminalBackupInfoList_Ans &Ans, DWORD dwTimeout)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = GetTerminalBackupInfoList(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+	ErrorCodeEnum GetTerminalBackupInfoList(CenterSettingService_GetTerminalBackupInfoList_Req &Req, CenterSettingService_GetTerminalBackupInfoList_Ans &Ans, DWORD dwTimeout, DWORD &dwUserError)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = GetTerminalBackupInfoList(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwUserError, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+
+	ErrorCodeEnum DownloadCenterFiles(CenterSettingService_DownloadCenterFiles_Req &Req, CSmartPointer<IAsynWaitSp> &spAsyncWait, DWORD dwTimeout)
+	{
+		CSmartPointer<IClientSessionFunction> pFunc = GetFunction();
+		CAutoBuffer Buf = SpObject2Buffer(Req);
+		return pFunc->AsyncRequest(CenterSettingService_Method_DownloadCenterFiles, CenterSettingService_MethodSignature_DownloadCenterFiles, Buf, spAsyncWait, dwTimeout);
+	}
+	ErrorCodeEnum DownloadCenterFiles(CenterSettingService_DownloadCenterFiles_Req &Req, CenterSettingService_DownloadCenterFiles_Ans &Ans, DWORD dwTimeout)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = DownloadCenterFiles(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
+	ErrorCodeEnum DownloadCenterFiles(CenterSettingService_DownloadCenterFiles_Req &Req, CenterSettingService_DownloadCenterFiles_Ans &Ans, DWORD dwTimeout, DWORD &dwUserError)
+	{
+		CSmartPointer<IAsynWaitSp> spAsyncWait;
+		ErrorCodeEnum Error = DownloadCenterFiles(Req, spAsyncWait, dwTimeout);
+		if (Error == Error_Succeed) {
+			bool bEnd = false;
+			Error = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwUserError, dwTimeout);
+			LOG_ASSERT(Error || bEnd);
+		}
+		return Error;
+	}
 
 	bool SafeDelete()
 	{

+ 186 - 0
Module/mod_CenterSetting/CenterSetting_def_g.h

@@ -14,9 +14,21 @@ namespace CenterSetting {
 
 #define CenterSettingService_Method_Download 0
 #define CenterSettingService_Method_GetSyncInfo 1
+#define CenterSettingService_Method_EditWebUrl 2
+#define CenterSettingService_Method_GetWebUrlList 3
+#define CenterSettingService_Method_GetActiveCustomUrl 4
+#define CenterSettingService_Method_EditTerminalBackupInfo 5
+#define CenterSettingService_Method_GetTerminalBackupInfoList 6
+#define CenterSettingService_Method_DownloadCenterFiles 7
 
 #define CenterSettingService_MethodSignature_Download -101852141
 #define CenterSettingService_MethodSignature_GetSyncInfo 1338819403
+#define CenterSettingService_MethodSignature_EditWebUrl 112159607
+#define CenterSettingService_MethodSignature_GetWebUrlList 166192532
+#define CenterSettingService_MethodSignature_GetActiveCustomUrl -2094137460
+#define CenterSettingService_MethodSignature_EditTerminalBackupInfo -1684426310
+#define CenterSettingService_MethodSignature_GetTerminalBackupInfoList 652072921
+#define CenterSettingService_MethodSignature_DownloadCenterFiles 1100121901
 
 struct CenterSettingService_Download_Req
 {
@@ -61,6 +73,180 @@ struct CenterSettingService_GetSyncInfo_Ans
 
 };
 
+struct CenterSettingService_EditWebUrl_Req
+{
+	int operation;
+	int index;
+	CSimpleStringA futureUrl;
+	CSimpleStringA adUrl;
+	CSimpleStringA remark;
+	int env;
+	bool setDefault;
+
+	void Serialize(SpBuffer &Buf)
+	{
+		auto & buf = Buf & operation & index & futureUrl & adUrl & remark & env & setDefault;
+	}
+
+};
+
+struct CenterSettingService_EditWebUrl_Ans
+{
+	int result;
+	int addition;
+	CSimpleStringA msg;
+
+	void Serialize(SpBuffer &Buf)
+	{
+		auto & buf = Buf & result & addition & msg;
+	}
+
+};
+
+struct CenterSettingService_GetWebUrlList_Req
+{
+	int filter1;
+	int filter2;
+	int filter3;
+	CSimpleStringA filter4;
+
+	void Serialize(SpBuffer &Buf)
+	{
+		auto & buf = Buf & filter1 & filter2 & filter3 & filter4;
+	}
+
+};
+
+struct CenterSettingService_GetWebUrlList_Ans
+{
+	CAutoArray<int> index;
+	CAutoArray<CSimpleStringA> futureUrl;
+	CAutoArray<CSimpleStringA> adUrl;
+	CAutoArray<CSimpleStringA> remark;
+	CAutoArray<int> env;
+	CAutoArray<int> type;
+	CAutoArray<int> status;
+
+	void Serialize(SpBuffer &Buf)
+	{
+		auto & buf = Buf & index & futureUrl & adUrl & remark & env & type & status;
+	}
+
+};
+
+struct CenterSettingService_GetActiveCustomUrl_Req
+{
+
+	void Serialize(SpBuffer &Buf)
+	{
+	}
+
+};
+
+struct CenterSettingService_GetActiveCustomUrl_Ans
+{
+	CSimpleStringA fultureUrl;
+	CSimpleStringA adUrl;
+
+	void Serialize(SpBuffer &Buf)
+	{
+		auto & buf = Buf & fultureUrl & adUrl;
+	}
+
+};
+
+struct CenterSettingService_EditTerminalBackupInfo_Req
+{
+	int operation;
+	int index;
+	CSimpleStringA terminalNo;
+	CSimpleStringA branchIP;
+	CSimpleStringA remark;
+	int env;
+	bool setDefault;
+
+	void Serialize(SpBuffer &Buf)
+	{
+		auto & buf = Buf & operation & index & terminalNo & branchIP & remark & env & setDefault;
+	}
+
+};
+
+struct CenterSettingService_EditTerminalBackupInfo_Ans
+{
+	int result;
+	int addition;
+	CSimpleStringA msg;
+
+	void Serialize(SpBuffer &Buf)
+	{
+		auto & buf = Buf & result & addition & msg;
+	}
+
+};
+
+struct CenterSettingService_GetTerminalBackupInfoList_Req
+{
+	int filter1;
+	int filter2;
+	int filter3;
+	CSimpleStringA filter4;
+
+	void Serialize(SpBuffer &Buf)
+	{
+		auto & buf = Buf & filter1 & filter2 & filter3 & filter4;
+	}
+
+};
+
+struct CenterSettingService_GetTerminalBackupInfoList_Ans
+{
+	CAutoArray<int> index;
+	CAutoArray<CSimpleStringA> terminalNo;
+	CAutoArray<CSimpleStringA> branchIP;
+	CAutoArray<CSimpleStringA> remark;
+	CAutoArray<int> env;
+	CAutoArray<int> status;
+
+	void Serialize(SpBuffer &Buf)
+	{
+		auto & buf = Buf & index & terminalNo & branchIP & remark & env & status;
+	}
+
+};
+
+struct CenterSettingService_DownloadCenterFiles_Req
+{
+	int operation;
+	CSimpleStringA strAddr;
+	int nPort;
+	bool deleteIfExist;
+	CSimpleStringA additional1;
+	CSimpleStringA additional2;
+	CSimpleStringA additional3;
+	CSimpleStringA additional4;
+	int reserved1;
+	int reserved2;
+
+	void Serialize(SpBuffer &Buf)
+	{
+		auto & buf = Buf & operation & strAddr & nPort & deleteIfExist & additional1 & additional2 & additional3 & additional4 & reserved1 & reserved2;
+	}
+
+};
+
+struct CenterSettingService_DownloadCenterFiles_Ans
+{
+	int result;
+	CSimpleStringA msg;
+
+	void Serialize(SpBuffer &Buf)
+	{
+		auto & buf = Buf & result & msg;
+	}
+
+};
+
 
 ///////////////////////////
 

+ 158 - 2
Module/mod_CenterSetting/CenterSetting_server_g.h

@@ -12,9 +12,15 @@ namespace CenterSetting {
 class CenterSettingService_ServerSessionBase : public CServerSessionBase
 {
 public:
-	CenterSettingService_ServerSessionBase() { }
+	CenterSettingService_ServerSessionBase()
+	{
+		/// override by user
+	}
 
-	virtual ~CenterSettingService_ServerSessionBase() { }
+	virtual ~CenterSettingService_ServerSessionBase()
+	{
+		/// override by user
+	}
 
 	virtual bool IsExclusive() { return false; }
 
@@ -38,6 +44,48 @@ public:
 				Error = Error_MethodSignatureFailed;
 			}
 			break;
+		case CenterSettingService_Method_EditWebUrl:
+			if (dwSignature == CenterSettingService_MethodSignature_EditWebUrl) {
+				bOverlap = true;
+			} else {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
+		case CenterSettingService_Method_GetWebUrlList:
+			if (dwSignature == CenterSettingService_MethodSignature_GetWebUrlList) {
+				bOverlap = true;
+			} else {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
+		case CenterSettingService_Method_GetActiveCustomUrl:
+			if (dwSignature == CenterSettingService_MethodSignature_GetActiveCustomUrl) {
+				bOverlap = true;
+			} else {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
+		case CenterSettingService_Method_EditTerminalBackupInfo:
+			if (dwSignature == CenterSettingService_MethodSignature_EditTerminalBackupInfo) {
+				bOverlap = true;
+			} else {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
+		case CenterSettingService_Method_GetTerminalBackupInfoList:
+			if (dwSignature == CenterSettingService_MethodSignature_GetTerminalBackupInfoList) {
+				bOverlap = true;
+			} else {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
+		case CenterSettingService_Method_DownloadCenterFiles:
+			if (dwSignature == CenterSettingService_MethodSignature_DownloadCenterFiles) {
+				bOverlap = true;
+			} else {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
 		default:
 			Error = Error_MethodNotFound;
 			break;
@@ -59,6 +107,36 @@ public:
 				Error = Error_MethodSignatureFailed;
 			}
 			break;
+		case CenterSettingService_Method_EditWebUrl:
+			if (dwSignature != CenterSettingService_MethodSignature_EditWebUrl) {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
+		case CenterSettingService_Method_GetWebUrlList:
+			if (dwSignature != CenterSettingService_MethodSignature_GetWebUrlList) {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
+		case CenterSettingService_Method_GetActiveCustomUrl:
+			if (dwSignature != CenterSettingService_MethodSignature_GetActiveCustomUrl) {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
+		case CenterSettingService_Method_EditTerminalBackupInfo:
+			if (dwSignature != CenterSettingService_MethodSignature_EditTerminalBackupInfo) {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
+		case CenterSettingService_Method_GetTerminalBackupInfoList:
+			if (dwSignature != CenterSettingService_MethodSignature_GetTerminalBackupInfoList) {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
+		case CenterSettingService_Method_DownloadCenterFiles:
+			if (dwSignature != CenterSettingService_MethodSignature_DownloadCenterFiles) {
+				Error = Error_MethodSignatureFailed;
+			}
+			break;
 		default:
 			Error = Error_MethodNotFound;
 			break;
@@ -76,6 +154,36 @@ public:
 	/// override by user
 	}
 
+	virtual void Handle_EditWebUrl(SpReqAnsContext<CenterSettingService_EditWebUrl_Req, CenterSettingService_EditWebUrl_Ans>::Pointer ctx)
+	{
+	/// override by user
+	}
+
+	virtual void Handle_GetWebUrlList(SpReqAnsContext<CenterSettingService_GetWebUrlList_Req, CenterSettingService_GetWebUrlList_Ans>::Pointer ctx)
+	{
+	/// override by user
+	}
+
+	virtual void Handle_GetActiveCustomUrl(SpReqAnsContext<CenterSettingService_GetActiveCustomUrl_Req, CenterSettingService_GetActiveCustomUrl_Ans>::Pointer ctx)
+	{
+	/// override by user
+	}
+
+	virtual void Handle_EditTerminalBackupInfo(SpReqAnsContext<CenterSettingService_EditTerminalBackupInfo_Req, CenterSettingService_EditTerminalBackupInfo_Ans>::Pointer ctx)
+	{
+	/// override by user
+	}
+
+	virtual void Handle_GetTerminalBackupInfoList(SpReqAnsContext<CenterSettingService_GetTerminalBackupInfoList_Req, CenterSettingService_GetTerminalBackupInfoList_Ans>::Pointer ctx)
+	{
+	/// override by user
+	}
+
+	virtual void Handle_DownloadCenterFiles(SpReqAnsContext<CenterSettingService_DownloadCenterFiles_Req, CenterSettingService_DownloadCenterFiles_Ans>::Pointer ctx)
+	{
+	/// override by user
+	}
+
 	virtual void OnRequest(CSmartPointer<ITransactionContext> pTransactionContext)
 	{
 		CAutoBuffer Buf;
@@ -108,6 +216,54 @@ public:
 						Handle_GetSyncInfo(ctx);
 					}
 					break;
+				case CenterSettingService_Method_EditWebUrl:
+					{
+						SpReqAnsContext<CenterSettingService_EditWebUrl_Req,CenterSettingService_EditWebUrl_Ans>::Pointer ctx;
+						ctx.Attach(new SpReqAnsContext<CenterSettingService_EditWebUrl_Req,CenterSettingService_EditWebUrl_Ans>(pTransactionContext));
+						SpBuffer2Object(Buf, ctx->Req);
+						Handle_EditWebUrl(ctx);
+					}
+					break;
+				case CenterSettingService_Method_GetWebUrlList:
+					{
+						SpReqAnsContext<CenterSettingService_GetWebUrlList_Req,CenterSettingService_GetWebUrlList_Ans>::Pointer ctx;
+						ctx.Attach(new SpReqAnsContext<CenterSettingService_GetWebUrlList_Req,CenterSettingService_GetWebUrlList_Ans>(pTransactionContext));
+						SpBuffer2Object(Buf, ctx->Req);
+						Handle_GetWebUrlList(ctx);
+					}
+					break;
+				case CenterSettingService_Method_GetActiveCustomUrl:
+					{
+						SpReqAnsContext<CenterSettingService_GetActiveCustomUrl_Req,CenterSettingService_GetActiveCustomUrl_Ans>::Pointer ctx;
+						ctx.Attach(new SpReqAnsContext<CenterSettingService_GetActiveCustomUrl_Req,CenterSettingService_GetActiveCustomUrl_Ans>(pTransactionContext));
+						SpBuffer2Object(Buf, ctx->Req);
+						Handle_GetActiveCustomUrl(ctx);
+					}
+					break;
+				case CenterSettingService_Method_EditTerminalBackupInfo:
+					{
+						SpReqAnsContext<CenterSettingService_EditTerminalBackupInfo_Req,CenterSettingService_EditTerminalBackupInfo_Ans>::Pointer ctx;
+						ctx.Attach(new SpReqAnsContext<CenterSettingService_EditTerminalBackupInfo_Req,CenterSettingService_EditTerminalBackupInfo_Ans>(pTransactionContext));
+						SpBuffer2Object(Buf, ctx->Req);
+						Handle_EditTerminalBackupInfo(ctx);
+					}
+					break;
+				case CenterSettingService_Method_GetTerminalBackupInfoList:
+					{
+						SpReqAnsContext<CenterSettingService_GetTerminalBackupInfoList_Req,CenterSettingService_GetTerminalBackupInfoList_Ans>::Pointer ctx;
+						ctx.Attach(new SpReqAnsContext<CenterSettingService_GetTerminalBackupInfoList_Req,CenterSettingService_GetTerminalBackupInfoList_Ans>(pTransactionContext));
+						SpBuffer2Object(Buf, ctx->Req);
+						Handle_GetTerminalBackupInfoList(ctx);
+					}
+					break;
+				case CenterSettingService_Method_DownloadCenterFiles:
+					{
+						SpReqAnsContext<CenterSettingService_DownloadCenterFiles_Req,CenterSettingService_DownloadCenterFiles_Ans>::Pointer ctx;
+						ctx.Attach(new SpReqAnsContext<CenterSettingService_DownloadCenterFiles_Req,CenterSettingService_DownloadCenterFiles_Ans>(pTransactionContext));
+						SpBuffer2Object(Buf, ctx->Req);
+						Handle_DownloadCenterFiles(ctx);
+					}
+					break;
 				default:
 					assert(0);
 					break;

+ 668 - 9
Module/mod_CenterSetting/mod_centersetting.cpp

@@ -125,7 +125,12 @@ void CCenterSettingEntity::OnStarted()
 
 	 m_nConnectFailCount = 0;
 	 LOG_ASSERT(IsServerConnectedNow());
-	 auto rc = m_pConnection->BeginPollConfig();
+
+     CSystemStaticInfo info;
+     auto rc = GetFunction()->GetSystemStaticInfo(info);
+     assert(rc == Error_Succeed);
+
+	 rc = m_pConnection->BeginPollConfig(info);
 	 return rc;
  }
 
@@ -138,20 +143,14 @@ void CCenterSettingEntity::OnStarted()
 	 //if (rc == Error_Succeed)
 		// LogEvent(Severity_Middle, EVENT_MOD_CENTERSETTING_DOWNOK, "集中配置同步成功");
 
-	 if (m_spDownloadCall != NULL)
-	 {
-		 Dbg("download call completed!");
-		 m_spDownloadCall->Answer(rc);
-		 m_spDownloadCall.Clear();
-	 }
-
+	 ReturnAndClearDownloadContext(rc);
 	 return rc;
  }
 
  ErrorCodeEnum CCenterSettingEntity::DownloadCenterSetting(
 	  SpReqAnsContext<CenterSettingService_Download_Req, CenterSettingService_Download_Ans>::Pointer sp)
  {
-	 if (m_spDownloadCall != nullptr)
+	 if (IsDownloadPending())
 	 {
 		 Dbg("last download call not complet");
 		 sp->Answer(Error_Duplication);
@@ -190,6 +189,470 @@ void CCenterSettingEntity::OnStarted()
 	 pTransactionContext->SendAnswer(error);
  }
 
+ void CCenterSettingEntity::EditWebUrl(SpReqAnsContext<CenterSettingService_EditWebUrl_Req, CenterSettingService_EditWebUrl_Ans>::Pointer ctx)
+ {
+	 ErrorCodeEnum result(Error_Unexpect);
+	 ctx->Ans.result = 0;
+	 ctx->Ans.msg = "";
+
+	 switch (ctx->Req.operation) {
+	 case 1: //new
+	 {
+         CSmartPointer<IConfigInfo> pConfig;
+         GetFunction()->OpenConfig(Config_Cache, pConfig);
+		 int count(0);
+		 bool newCreate = true;
+		 pConfig->ReadConfigValueInt("CustomWebUrl", "Count", count);
+		 int newIndex(count + 1);
+         for (int i = 1; i <= count; ++i) {
+             CustomWebUrlConfig item;
+             CSimpleStringA strSection = CSimpleStringA::Format("CustomWebUrl%d", i);
+             pConfig->ReadConfigValue(strSection, "FultureUrl", item.strFutureUrl);
+             pConfig->ReadConfigValue(strSection, "AdUrl", item.strAdUrl);
+             pConfig->ReadConfigValue(strSection, "Remark", item.strRemark);
+             pConfig->ReadConfigValueInt(strSection, "Env", item.useEnv);
+             pConfig->ReadConfigValueInt(strSection, "Status", item.curStatus);
+             if (!item.IsValid()) {
+				 newIndex = i;
+				 newCreate = false;
+				 break;
+             }
+         }
+		 CSimpleStringA strNewSection = CSimpleStringA::Format("CustomWebUrl%d", newIndex);
+         pConfig->WriteConfigValue(strNewSection, "FultureUrl", ctx->Req.futureUrl);
+         pConfig->WriteConfigValue(strNewSection, "AdUrl", ctx->Req.adUrl);
+		 CSimpleStringA strRemark(ctx->Req.remark);
+		 if (strRemark.IsNullOrEmpty()) {
+			 if (ctx->Req.env == 1) strRemark = "DEV:";
+			 else if(ctx->Req.env == 2) strRemark = "ST:";
+             if (ctx->Req.env == 3) strRemark = "UAT:";
+			 strRemark += ctx->Req.futureUrl;
+		 }
+         pConfig->WriteConfigValue(strNewSection, "Remark", strRemark);
+         pConfig->WriteConfigValueInt(strNewSection, "Env", ctx->Req.env);
+         pConfig->WriteConfigValueInt(strNewSection, "Status", WEBURL_STATUS_PROVIDE);
+		 if (ctx->Req.setDefault) {
+			 pConfig->WriteConfigValueInt("CustomWebUrl", "Current", newIndex);
+		 }
+		 if (newCreate) {
+			 pConfig->WriteConfigValueInt("CustomWebUrl", "Count", newIndex);
+		 }
+
+		 ctx->Ans.addition = newIndex;
+		 result = Error_Succeed;
+	 }
+		 break;
+     case 2: //delete
+	 {
+		 if (ctx->Req.index >= WEBURL_ITEM_INDEX_CENTERSETTING) {
+			 result = Error_NoPrivilege;
+		 } else {
+             CSmartPointer<IConfigInfo> pConfig;
+             GetFunction()->OpenConfig(Config_Cache, pConfig);
+			 int oldStatus(0);
+			 CSimpleStringA strSection = CSimpleStringA::Format("CustomWebUrl%d", ctx->Req.index);
+             pConfig->ReadConfigValueInt(strSection, "Status", oldStatus);
+             pConfig->WriteConfigValueInt(strSection, "Status", WEBURL_STATUS_DEPRECATE);
+             int currentUsing(0);
+             pConfig->ReadConfigValueInt("CustomWebUrl", "Current", currentUsing);
+             if (ctx->Req.index == currentUsing) {
+                 pConfig->WriteConfigValueInt("CustomWebUrl", "Current", 0);
+             }
+			 result = Error_Succeed;
+		 }
+	 }
+         break;
+     case 3: //update
+	 {
+         if (ctx->Req.index >= WEBURL_ITEM_INDEX_CENTERSETTING) { //如果当前是集中配置文件
+             CSmartPointer<IConfigInfo> pConfig;
+             GetFunction()->OpenConfig(Config_Cache, pConfig);
+             int currentUsing(0);
+             pConfig->ReadConfigValueInt("CustomWebUrl", "Current", currentUsing);
+			 if (currentUsing != 0 && ctx->Req.setDefault) {
+				 pConfig->WriteConfigValueInt("CustomWebUrl", "Current", 0);
+				 result = Error_Succeed;
+			 } else {
+                 result = Error_NoPrivilege;
+			 }
+			 break;
+         }
+         CSmartPointer<IConfigInfo> pConfig;
+         GetFunction()->OpenConfig(Config_Cache, pConfig);
+         CSimpleStringA strExistedSection = CSimpleStringA::Format("CustomWebUrl%d", ctx->Req.index);
+         pConfig->WriteConfigValue(strExistedSection, "FultureUrl", ctx->Req.futureUrl);
+         pConfig->WriteConfigValue(strExistedSection, "AdUrl", ctx->Req.adUrl);
+         CSimpleStringA strRemark(ctx->Req.remark);
+         if (strRemark.IsNullOrEmpty()) {
+             if (ctx->Req.env == 1) strRemark = "DEV:";
+             else if (ctx->Req.env == 2) strRemark = "ST:";
+             if (ctx->Req.env == 3) strRemark = "UAT:";
+             strRemark += ctx->Req.futureUrl;
+         }
+         pConfig->WriteConfigValue(strExistedSection, "Remark", strRemark);
+         pConfig->WriteConfigValueInt(strExistedSection, "Env", ctx->Req.env);
+         pConfig->WriteConfigValueInt(strExistedSection, "Status", WEBURL_STATUS_PROVIDE);
+         if (ctx->Req.setDefault) {
+             pConfig->WriteConfigValueInt("CustomWebUrl", "Current", ctx->Req.index);
+         }
+         ctx->Ans.addition = ctx->Req.index;
+         result = Error_Succeed;
+	 }
+         break;
+	 default:
+		 result = Error_NotSupport;
+		 break;
+	 }
+
+     ctx->Answer(result);
+     return;
+ }
+
+ void CCenterSettingEntity::GetWebUrlList(SpReqAnsContext<CenterSettingService_GetWebUrlList_Req, CenterSettingService_GetWebUrlList_Ans>::Pointer ctx)
+ {
+	 ErrorCodeEnum result(Error_Succeed);
+     CSmartPointer<IConfigInfo> pConfig;
+     GetFunction()->OpenConfig(Config_Cache, pConfig);
+	 int cnt(0), curIndex(0), realCnt(0);
+	 bool hasDefaultFromCustom(false);
+	 pConfig->ReadConfigValueInt("CustomWebUrl", "Count", cnt);
+     int currentUsing(0);
+     pConfig->ReadConfigValueInt("CustomWebUrl", "Current", currentUsing);
+
+	 CAutoArray< CustomWebUrlConfig> configs(cnt);
+	 Dbg("custom count: %d", cnt);
+	 for (int i = 1; i <= cnt; ++i) {
+		 CustomWebUrlConfig& item = configs[i - 1];
+		 item.configFrom = WEBURL_CONFIG_CUSTOM;
+		 item.index = i;
+		 CSimpleStringA strSection = CSimpleStringA::Format("CustomWebUrl%d", i);
+		 pConfig->ReadConfigValue(strSection, "FultureUrl", item.strFutureUrl);
+         pConfig->ReadConfigValue(strSection, "AdUrl", item.strAdUrl);
+         pConfig->ReadConfigValue(strSection, "Remark", item.strRemark);
+		 pConfig->ReadConfigValueInt(strSection, "Env", item.useEnv);
+         pConfig->ReadConfigValueInt(strSection, "Status", item.curStatus);
+		 if (item.IsValid()) {
+			 realCnt++;
+			 if (currentUsing == i) {
+				 hasDefaultFromCustom = true;
+				 item.curStatus = WEBURL_STATUS_DEFAULT;
+			 } else {
+				 item.curStatus = WEBURL_STATUS_PROVIDE;
+			 }
+		 }
+	 }
+	
+	 CustomWebUrlConfig defaultOne;
+	 ErrorCodeEnum resultFromFetch = GetWebUrlInfoFromCenterSettings(defaultOne);
+	 if (resultFromFetch == Error_Succeed) {
+		 Dbg("add centersettings config");
+		 realCnt += 1;
+		 if (!hasDefaultFromCustom) {
+			 defaultOne.curStatus = WEBURL_STATUS_DEFAULT;
+		 }
+	 }
+
+     Dbg("total count: %d", realCnt);
+
+	 ctx->Ans.index.Init(realCnt);
+     ctx->Ans.futureUrl.Init(realCnt);
+     ctx->Ans.adUrl.Init(realCnt);
+     ctx->Ans.remark.Init(realCnt);
+     ctx->Ans.env.Init(realCnt);
+     ctx->Ans.type.Init(realCnt);
+     ctx->Ans.status.Init(realCnt);
+	 
+	 if (resultFromFetch == Error_Succeed) {
+		 ctx->Ans.index[curIndex] = WEBURL_ITEM_INDEX_CENTERSETTING;
+		 ctx->Ans.futureUrl[curIndex] = defaultOne.strFutureUrl;
+		 ctx->Ans.adUrl[curIndex] = defaultOne.strAdUrl;
+		 ctx->Ans.remark[curIndex] = defaultOne.strRemark;
+		 ctx->Ans.env[curIndex] = defaultOne.useEnv;
+		 ctx->Ans.type[curIndex] = defaultOne.configFrom;
+		 ctx->Ans.status[curIndex] = defaultOne.curStatus;
+		 curIndex++;
+	 }
+	 
+	 for (int i = 0; i < configs.GetCount(); ++i) {
+		 CustomWebUrlConfig& item = configs[i];
+		 if (item.IsValid()) {
+             ctx->Ans.index[curIndex] = item.index;
+             ctx->Ans.futureUrl[curIndex] = item.strFutureUrl;
+             ctx->Ans.adUrl[curIndex] = item.strAdUrl;
+             ctx->Ans.remark[curIndex] = item.strRemark;
+             ctx->Ans.env[curIndex] = item.useEnv;
+             ctx->Ans.type[curIndex] = item.configFrom;
+             ctx->Ans.status[curIndex] = item.curStatus;
+             curIndex++;
+		 }
+	 }
+
+	 ctx->Answer(result);
+ }
+
+ void CCenterSettingEntity::GetActiveCustomUrl(
+	 SpReqAnsContext<CenterSettingService_GetActiveCustomUrl_Req, CenterSettingService_GetActiveCustomUrl_Ans>::Pointer ctx)
+ {
+     ErrorCodeEnum result(Error_Succeed);
+     CSmartPointer<IConfigInfo> pConfig;
+     GetFunction()->OpenConfig(Config_Cache, pConfig);
+     int cnt(0), currentUsing(0);
+     pConfig->ReadConfigValueInt("CustomWebUrl", "Count", cnt);
+     pConfig->ReadConfigValueInt("CustomWebUrl", "Current", currentUsing);
+
+	 if (cnt == 0 || currentUsing == 0) {
+		 result = Error_NotConfig;
+	 } else {
+         CSimpleStringA strSection = CSimpleStringA::Format("CustomWebUrl%d", currentUsing);
+         pConfig->ReadConfigValue(strSection, "FultureUrl", ctx->Ans.fultureUrl);
+         pConfig->ReadConfigValue(strSection, "AdUrl", ctx->Ans.adUrl);
+
+		 if (!ctx->Ans.fultureUrl.IsNullOrEmpty()) {
+			 result = Error_Succeed;
+		 } else {
+			 result = Error_CheckSum;
+		 }
+	 }
+
+	 ctx->Answer(result);
+	 return;
+ }
+
+ void CCenterSettingEntity::EditTerminalBackupInfo(SpReqAnsContext<CenterSettingService_EditTerminalBackupInfo_Req, CenterSettingService_EditTerminalBackupInfo_Ans>::Pointer ctx)
+ {
+     ErrorCodeEnum result(Error_Succeed);
+	 CSimpleStringA errMsg(true);
+	 ErrorCodeEnum tmpResult(Error_Succeed);
+
+     switch (ctx->Req.operation) {
+     case 1: //new
+     {
+         CSmartPointer<IConfigInfo> pConfig;
+         GetFunction()->OpenConfig(Config_Cache, pConfig);
+         int count(0);
+         bool newCreate = true;
+         pConfig->ReadConfigValueInt("TerminalBackup", "Count", count);
+         int newIndex(count + 1);
+         for (int i = 1; i <= count; ++i) {
+             CustomWebUrlConfig item;
+             CSimpleStringA strSection = CSimpleStringA::Format("TerminalBackup%d", i);
+             pConfig->ReadConfigValue(strSection, "TerminalNo", item.strFutureUrl);
+             pConfig->ReadConfigValue(strSection, "ServerIP", item.strAdUrl);
+             pConfig->ReadConfigValue(strSection, "Remark", item.strRemark);
+             pConfig->ReadConfigValueInt(strSection, "Env", item.useEnv);
+             pConfig->ReadConfigValueInt(strSection, "Status", item.curStatus);
+             if (!item.IsValid()) {
+                 newIndex = i;
+                 newCreate = false;
+                 break;
+             }
+         }
+         CSimpleStringA strNewSection = CSimpleStringA::Format("TerminalBackup%d", newIndex);
+         pConfig->WriteConfigValue(strNewSection, "TerminalNo", ctx->Req.terminalNo);
+         pConfig->WriteConfigValue(strNewSection, "ServerIP", ctx->Req.branchIP);
+         CSimpleStringA strRemark(ctx->Req.remark);
+         if (strRemark.IsNullOrEmpty()) {
+             if (ctx->Req.env == 1) strRemark = "DEV:";
+             else if (ctx->Req.env == 2) strRemark = "ST:";
+             if (ctx->Req.env == 3) strRemark = "UAT:";
+             strRemark += ctx->Req.terminalNo;
+         }
+         pConfig->WriteConfigValue(strNewSection, "Remark", strRemark);
+         pConfig->WriteConfigValueInt(strNewSection, "Env", ctx->Req.env);
+         pConfig->WriteConfigValueInt(strNewSection, "Status", WEBURL_STATUS_PROVIDE);
+         if (ctx->Req.setDefault) {
+			 tmpResult = UpdateTerminalInfoAtChange(ctx->Req.terminalNo);
+			 if (!(tmpResult == Error_Succeed || tmpResult == Error_AlreadyExist)) {
+                 pConfig->WriteConfigValueInt(strNewSection, "Status", WEBURL_STATUS_DEPRECATE);
+                 errMsg = CSimpleStringA::Format("更新终端号信息失败!");
+                 break;
+			 } 
+         }
+         if (newCreate) {
+             pConfig->WriteConfigValueInt("TerminalBackup", "Count", newIndex);
+         }
+		 ctx->Ans.addition = (int)ConfirmCenterSettingsFileAndUpdateIfNecessary(ctx->Req.branchIP);
+         result = Error_Succeed;
+     }
+     break;
+     case 2: //delete
+     {
+         CSmartPointer<IConfigInfo> pConfig;
+         GetFunction()->OpenConfig(Config_Cache, pConfig);
+         CSimpleStringA strSection = CSimpleStringA::Format("TerminalBackup%d", ctx->Req.index);
+         int oldStatus(0);
+         pConfig->ReadConfigValueInt(strSection, "Status", oldStatus);
+         pConfig->WriteConfigValueInt(strSection, "Status", WEBURL_STATUS_DEPRECATE);
+     }
+     break;
+     case 3: //update
+     {
+         CSmartPointer<IConfigInfo> pConfig;
+         GetFunction()->OpenConfig(Config_Cache, pConfig);
+         CSimpleStringA strExistedSection = CSimpleStringA::Format("TerminalBackup%d", ctx->Req.index);
+
+         if (ctx->Req.setDefault) {
+             tmpResult = UpdateTerminalInfoAtChange(ctx->Req.terminalNo);
+             if (!(tmpResult == Error_Succeed || tmpResult == Error_AlreadyExist)) {
+                 errMsg = CSimpleStringA::Format("更新终端号信息失败!");
+                 break;
+             }
+         }
+
+         pConfig->WriteConfigValue(strExistedSection, "TerminalNo", ctx->Req.terminalNo);
+         pConfig->WriteConfigValue(strExistedSection, "ServerIP", ctx->Req.branchIP);
+         CSimpleStringA strRemark(ctx->Req.remark);
+         if (strRemark.IsNullOrEmpty()) {
+             if (ctx->Req.env == 1) strRemark = "DEV:";
+             else if (ctx->Req.env == 2) strRemark = "ST:";
+             if (ctx->Req.env == 3) strRemark = "UAT:";
+             strRemark += ctx->Req.terminalNo;
+         }
+         pConfig->WriteConfigValue(strExistedSection, "Remark", strRemark);
+         pConfig->WriteConfigValueInt(strExistedSection, "Env", ctx->Req.env);
+         pConfig->WriteConfigValueInt(strExistedSection, "Status", WEBURL_STATUS_PROVIDE);
+
+		 ctx->Ans.addition = (int)ConfirmCenterSettingsFileAndUpdateIfNecessary(ctx->Req.branchIP);
+         result = Error_Succeed;
+     }
+     break;
+     default:
+         result = Error_NotSupport;
+         break;
+     }
+
+     ctx->Ans.result = tmpResult;
+	 ctx->Ans.msg = errMsg;
+     ctx->Answer(result);
+     return;
+ }
+
+ void CCenterSettingEntity::GetTerminalBackupInfoList(SpReqAnsContext<CenterSettingService_GetTerminalBackupInfoList_Req, CenterSettingService_GetTerminalBackupInfoList_Ans>::Pointer ctx)
+ {
+     ErrorCodeEnum result(Error_Succeed);
+     CSmartPointer<IConfigInfo> pConfig;
+     GetFunction()->OpenConfig(Config_Cache, pConfig);
+     int cnt(0), curIndex(0), realCnt(0);
+     bool hasDefaultFromCustom(false);
+     pConfig->ReadConfigValueInt("TerminalBackup", "Count", cnt);
+     CAutoArray< CustomWebUrlConfig> configs(cnt);
+     Dbg("custom count: %d", cnt);
+     for (int i = 1; i <= cnt; ++i) {
+         CustomWebUrlConfig& item = configs[i - 1];
+         item.configFrom = WEBURL_CONFIG_CUSTOM;
+         item.index = i;
+         CSimpleStringA strSection = CSimpleStringA::Format("TerminalBackup%d", i);
+         pConfig->ReadConfigValue(strSection, "TerminalNo", item.strFutureUrl);
+         pConfig->ReadConfigValue(strSection, "ServerIP", item.strAdUrl);
+         pConfig->ReadConfigValue(strSection, "Remark", item.strRemark);
+         pConfig->ReadConfigValueInt(strSection, "Env", item.useEnv);
+         pConfig->ReadConfigValueInt(strSection, "Status", item.curStatus);
+         if (item.IsValid()) {
+             realCnt++;
+			 DWORD dwMask(0);
+			 if (IsParamCurrentUsed(item.strFutureUrl, item.strAdUrl, dwMask)) {
+                 hasDefaultFromCustom = true;
+                 item.curStatus = WEBURL_STATUS_DEFAULT;
+			 } else {
+				 item.curStatus = WEBURL_STATUS_PROVIDE;
+			 }
+         }
+     }
+
+	 ErrorCodeEnum resultFromFetch(Error_NotInit);
+	 CustomWebUrlConfig defaultOne;
+	 if (!hasDefaultFromCustom) {
+         resultFromFetch = GetParamCurrentUseing(defaultOne);
+         if (resultFromFetch == Error_Succeed) {
+             Dbg("add root config");
+             realCnt += 1;
+			 defaultOne.curStatus = WEBURL_STATUS_DEFAULT;
+         }
+	 }
+
+     Dbg("total count: %d", realCnt);
+
+     ctx->Ans.index.Init(realCnt);
+     ctx->Ans.terminalNo.Init(realCnt);
+     ctx->Ans.branchIP.Init(realCnt);
+     ctx->Ans.remark.Init(realCnt);
+     ctx->Ans.env.Init(realCnt);
+     ctx->Ans.status.Init(realCnt);
+
+     if (resultFromFetch == Error_Succeed) {
+         ctx->Ans.index[curIndex] = defaultOne.index;
+         ctx->Ans.terminalNo[curIndex] = defaultOne.strFutureUrl;
+         ctx->Ans.branchIP[curIndex] = defaultOne.strAdUrl;
+         ctx->Ans.remark[curIndex] = defaultOne.strRemark;
+         ctx->Ans.env[curIndex] = defaultOne.useEnv;
+         ctx->Ans.status[curIndex] = defaultOne.curStatus;
+
+		 Dbg("index: %d", ctx->Ans.index[curIndex]);
+		 Dbg("terminalNo: %s", ctx->Ans.terminalNo[curIndex].GetData());
+         Dbg("branchIP: %s", ctx->Ans.branchIP[curIndex].GetData());
+         Dbg("remark: %s", ctx->Ans.remark[curIndex].GetData());
+         Dbg("env: %d", ctx->Ans.env[curIndex]);
+         Dbg("status: %d", ctx->Ans.status[curIndex]);
+
+         curIndex++;
+     }
+
+     for (int i = 0; i < configs.GetCount(); ++i) {
+         CustomWebUrlConfig& item = configs[i];
+         if (item.IsValid()) {
+             ctx->Ans.index[curIndex] = item.index;
+             ctx->Ans.terminalNo[curIndex] = item.strFutureUrl;
+             ctx->Ans.branchIP[curIndex] = item.strAdUrl;
+             ctx->Ans.remark[curIndex] = item.strRemark;
+             ctx->Ans.env[curIndex] = item.useEnv;
+             ctx->Ans.status[curIndex] = item.curStatus;
+             curIndex++;
+         }
+     }
+
+     ctx->Answer(result);
+ }
+
+ void CCenterSettingEntity::DownloadCenterFiles(SpReqAnsContext<CenterSettingService_DownloadCenterFiles_Req, CenterSettingService_DownloadCenterFiles_Ans>::Pointer ctx)
+ {
+     if (IsDownloadPending()) {
+         Dbg("%s: last download call not complet", __FUNCTION__);
+         ctx->Answer(Error_Duplication);
+         return;
+     }
+
+	 if (ctx->Req.strAddr == NULL || strlen(ctx->Req.strAddr) == 0 || ctx->Req.nPort <= 0) {
+		 ctx->Answer(Error_Param);
+		 return;
+	 }
+
+     m_spDownloadCallEx = ctx;
+
+	 SecureClientRelease();
+	 m_pConnection = new CCenterSettingConn(this);
+
+	 if (!m_pConnection->Connect(ctx->Req.strAddr, ctx->Req.nPort, 3)) {
+		 SecureClientRelease();
+		 ReturnAndClearDownloadContext(Error_NetBroken);
+	 } else {
+		 Dbg("custom download from server %s:%d", ctx->Req.strAddr.GetData(), ctx->Req.nPort, 3);
+		 if (ctx->Req.deleteIfExist) {
+			 Dbg("Remove CenterSettings file!");
+			 RemoveAllCenterSettingFiles();
+		 }
+
+         CSystemStaticInfo info;
+         GetFunction()->GetSystemStaticInfo(info);
+		 if (!ctx->Req.additional1.IsNullOrEmpty()) {
+			 Dbg("Render TeminalNo from %s to %s", info.strTerminalID.GetData(), ctx->Req.additional1.GetData());
+			 info.strTerminalID = ctx->Req.additional1;
+		 }
+
+		 /** 该接口永远返回成功,所以没有做判断 [Gifur@2021127]*/
+		 ErrorCodeEnum ret = m_pConnection->BeginPollConfig(info);
+	 }
+ }
+
  ErrorCodeEnum CCenterSettingEntity::GetSyncInfo(unsigned int& dwSyncTime, CSimpleStringA& strSyncHash, CSimpleStringA& strSyncFile)
  {
 	 if (m_SyncFileInfo.find((const char*)m_strCurSiteExtName) != m_SyncFileInfo.end())
@@ -236,6 +699,28 @@ void CCenterSettingEntity::OnStarted()
 	 return true;
  }
 
+ ErrorCodeEnum CCenterSettingEntity::GetWebUrlInfoFromCenterSettings(CustomWebUrlConfig& config)
+ {
+	 CSmartPointer<IConfigInfo> spCerConfig;
+	 ErrorCodeEnum err = GetFunction()->OpenConfig(Config_CenterSetting, spCerConfig);
+     SpIniMappingTable table;
+	 CSimpleStringA entityName("Chromium");
+     // clean cache every time
+     table.AddEntryString(entityName, "UserMgrUrlFulture", config.strFutureUrl, "");
+     table.AddEntryString(entityName, "UserMgrAd", config.strAdUrl, "");
+	 err = table.Load(spCerConfig);
+	 if (err == Error_Succeed) {
+		 config.configFrom = WEBURL_CONFIG_CENTESETTING;
+		 config.curStatus = WEBURL_STATUS_PROVIDE;
+		 config.useEnv = WEBURL_ENV_ALL;
+		 config.strRemark = "Default Config From CenterSettings";
+	 }
+	 if (config.strFutureUrl.IsNullOrEmpty()) {
+		 err = Error_NotConfig;
+	 }
+	 return err;
+ }
+
  bool CCenterSettingEntity::SecureClientConnect(ConnectServerType type, LPCTSTR serverIP, int port)
  {
 	 LOG_FUNCTION();
@@ -294,7 +779,181 @@ void CCenterSettingEntity::OnStarted()
 	 }
  }
 
+
+ ErrorCodeEnum CCenterSettingEntity::UpdateTerminalInfoAtChange(const CSimpleStringA& newTerminalInfo)
+ {
+	 ErrorCodeEnum result(Error_Succeed);
+
+     CSystemStaticInfo sysInfo;
+     result = GetFunction()->GetSystemStaticInfo(sysInfo);
+	 if (result == Error_Succeed) {
+		 if (sysInfo.strTerminalID == newTerminalInfo) {
+			 result = Error_AlreadyExist;
+		 } else {
+			 CSimpleStringA strTemp = CSimpleStringA::Format("更新终端号信息:%s -> %s", sysInfo.strTerminalID.GetData(), newTerminalInfo.GetData());
+			 LogWarn(Severity_High, Error_Debug, EVENT_CENTERSETTING_CHANGE_ROOT_TERMINALNO, strTemp);
+             CSimpleStringA strRootCfgPath, rootPath;
+             ErrorCodeEnum ec = GetFunction()->GetPath("HardwareCfg", strRootCfgPath);
+             rootPath = strRootCfgPath;
+             rootPath += SPLIT_SLASH_STR;
+             rootPath += "root.ini";
+
+			 inifile_write_str(rootPath, "Terminal", "TerminalNo", newTerminalInfo);
+			 inifile_write_str(rootPath, "Terminal", "LastTerminalNo", sysInfo.strTerminalID);
+
+			 char tmp[32] = {'\0'};
+			 inifile_read_str_s("Terminal", "TerminalNo", "", tmp, 31, rootPath);
+			 CSimpleStringA strConfirmTerminalNo(tmp);
+			 if (strConfirmTerminalNo != newTerminalInfo) {
+				 Dbg("Update TeminalNo failed: read returned: %s, write into: %s", strConfirmTerminalNo.GetData(), newTerminalInfo.GetData());
+				 result = Error_FailVerify;
+			 }
+		 }
+	 }
+	 return result;
+ }
+
+
+ bool CCenterSettingEntity::IsParamCurrentUsed(const CSimpleStringA& strTerminalInfo, const CSimpleStringA& strServerIP, DWORD& outMask)
+ {
+	 bool result(true);
+	 outMask = 0;
+
+     CSystemStaticInfo sysInfo;
+     GetFunction()->GetSystemStaticInfo(sysInfo);
+     if (sysInfo.strTerminalID.IsNullOrEmpty() || sysInfo.strTerminalID != strTerminalInfo) {
+        result = false;
+	 } else {
+		outMask |= 0x1;
+	 }
+
+     CSmartPointer<IConfigInfo> pConfig;
+     CSimpleStringA strServer;
+     GetFunction()->OpenConfig(Config_CenterSetting, pConfig);
+     pConfig->ReadConfigValue("CenterSetting", "Server", strServer);
+     CAutoArray<CSimpleStringA> ipPorts = strServer.Split(' ');
+     if (strServer.IsNullOrEmpty() || ipPorts.GetCount() != 2 || ipPorts[0] != strServerIP) {
+         result = false;
+     } else {
+         outMask |= 0x2;
+     }
+
+	 return result;
+ }
+
+ ErrorCodeEnum CCenterSettingEntity::GetParamCurrentUseing(CustomWebUrlConfig& config)
+ {
+	 ErrorCodeEnum result(Error_Succeed);
+
+     CSystemStaticInfo sysInfo;
+	 result = GetFunction()->GetSystemStaticInfo(sysInfo);
+	 config.strFutureUrl = sysInfo.strTerminalID;
+
+     CSmartPointer<IConfigInfo> pConfig;
+     CSimpleStringA strServer;
+	 result = GetFunction()->OpenConfig(Config_CenterSetting, pConfig);
+	 result = pConfig->ReadConfigValue("CenterSetting", "Server", strServer);
+	 CAutoArray<CSimpleStringA> ipPorts = strServer.Split(' ');
+	 if (ipPorts.GetCount() == 2) {
+         config.strAdUrl = ipPorts[0];
+	 } else {
+		 config.strAdUrl = "";
+	 }
+	 config.index = WEBURL_ITEM_INDEX_CENTERSETTING;
+     config.configFrom = WEBURL_CONFIG_CENTESETTING;
+     config.curStatus = WEBURL_STATUS_PROVIDE;
+     config.useEnv = WEBURL_ENV_ALL;
+     config.strRemark = "root.ini&CenterSetting";
+
+	 return result;
+ }
+
+ void CCenterSettingEntity::RemoveAllCenterSettingFiles()
+ {
+     CSimpleStringA strEntityCfgPath;
+     GetFunction()->GetPath("Cfg", strEntityCfgPath);
+     array_header_t* subs = fileutil_get_sub_files_a(strEntityCfgPath);
+     if (subs) {
+         regex_t reg;
+         CSimpleStringA pattern = "CenterSetting\.[a-zA-Z0-9_\\(\\)\\-]*\.ini";
+         int ret = regcomp(&reg, pattern, REG_EXTENDED | REG_NOSUB);
+         if (ret) {
+             char ebuff[256];
+             regerror(ret, &reg, ebuff, 256);
+             Dbg("regex failed: %s", ebuff);
+		 } else {
+             Dbg("pattern: %s", pattern.GetData());
+             for (int i = 0; i < subs->nelts; ++i) {
+                 char* filenamePath = ARRAY_IDX(subs, i, char*);
+                 char* filename = &filenamePath[strEntityCfgPath.GetLength() + 1];
+                 ret = regexec(&reg, filename, 0, NULL, 0);
+                 if (0 == ret) {
+                     Dbg("filename %s matched and remove it.", filename);
+                     fileutil_delete_file(filenamePath);
+                 }
+             }
+		 }
+         toolkit_array_free2(subs);
+     }
+
+	 if (m_pConnection != NULL) {
+		 m_pConnection->DeleteErrorFiles(strEntityCfgPath);
+	 }
+ }
+
+ ErrorCodeEnum CCenterSettingEntity::ConfirmCenterSettingsFileAndUpdateIfNecessary(const CSimpleStringA& serverIP)
+ {
+     CSmartPointer<IConfigInfo> pConfig;
+	 CSimpleStringA strServer;
+     ErrorCodeEnum result = GetFunction()->OpenConfig(Config_CenterSetting, pConfig);
+	 result = pConfig->ReadConfigValue("CenterSetting", "Server", strServer);
+     CAutoArray<CSimpleStringA> ipPorts = strServer.Split(' ');
+	 if (strServer.IsNullOrEmpty() || ipPorts.GetCount() !=2 || ipPorts[0] != serverIP) {
+		 result = Error_FailVerify;
+	 }
+	 return result;
+ }
+
+ void CCenterSettingService::Handle_EditWebUrl(SpReqAnsContext<CenterSettingService_EditWebUrl_Req, CenterSettingService_EditWebUrl_Ans>::Pointer ctx)
+ {
+	 LOG_FUNCTION();
+	 m_pEntity->EditWebUrl(ctx);
+ }
+
+ void CCenterSettingService::Handle_GetWebUrlList(SpReqAnsContext<CenterSettingService_GetWebUrlList_Req, CenterSettingService_GetWebUrlList_Ans>::Pointer ctx)
+ {
+	 LOG_FUNCTION();
+	 m_pEntity->GetWebUrlList(ctx);
+ }
+
+ void CCenterSettingService::Handle_GetActiveCustomUrl(SpReqAnsContext<CenterSettingService_GetActiveCustomUrl_Req, CenterSettingService_GetActiveCustomUrl_Ans>::Pointer ctx)
+ {
+	 LOG_FUNCTION();
+	 m_pEntity->GetActiveCustomUrl(ctx);
+ }
+
+ void CCenterSettingService::Handle_EditTerminalBackupInfo(SpReqAnsContext<CenterSettingService_EditTerminalBackupInfo_Req, CenterSettingService_EditTerminalBackupInfo_Ans>::Pointer ctx)
+ {
+     LOG_FUNCTION();
+     m_pEntity->EditTerminalBackupInfo(ctx);
+ }
+
+ void CCenterSettingService::Handle_GetTerminalBackupInfoList(SpReqAnsContext<CenterSettingService_GetTerminalBackupInfoList_Req, CenterSettingService_GetTerminalBackupInfoList_Ans>::Pointer ctx)
+ {
+     LOG_FUNCTION();
+     m_pEntity->GetTerminalBackupInfoList(ctx);
+ }
+
+ void CCenterSettingService::Handle_DownloadCenterFiles(SpReqAnsContext<CenterSettingService_DownloadCenterFiles_Req, CenterSettingService_DownloadCenterFiles_Ans>::Pointer ctx)
+ {
+     LOG_FUNCTION();
+     m_pEntity->DownloadCenterFiles(ctx);
+ }
+
+
 SP_BEGIN_ENTITY_MAP()
 	SP_ENTITY(CCenterSettingEntity)
 SP_END_ENTITY_MAP()
 
+
+

+ 93 - 1
Module/mod_CenterSetting/mod_centersetting.h

@@ -20,11 +20,44 @@ enum ConnectServerType
 	PARAM = 2
 };
 
+
+#define WEBURL_ENV_DEV 1
+#define WEBURL_ENV_ST 2
+#define WEBURL_ENV_UAT 3
+#define WEBURL_ENV_ALL 0
+
+#define WEBURL_CONFIG_CENTESETTING 0
+#define WEBURL_CONFIG_CUSTOM 1
+
+#define WEBURL_STATUS_PROVIDE 0 
+#define WEBURL_STATUS_DEFAULT 1
+#define WEBURL_STATUS_USING 2
+#define WEBURL_STATUS_DEPRECATE 3
+
+#define WEBURL_ITEM_COUNT_MAX 100
+#define WEBURL_ITEM_INDEX_CENTERSETTING (WEBURL_ITEM_COUNT_MAX + 1)
+
+struct CustomWebUrlConfig
+{
+	CSimpleStringA strFutureUrl;
+	CSimpleStringA strAdUrl;
+	CSimpleStringA strRemark;
+	int useEnv;
+	int configFrom;
+	int curStatus;
+	int index;
+
+	bool IsValid()
+	{
+		return (!strFutureUrl.IsNullOrEmpty() && curStatus != WEBURL_STATUS_DEPRECATE);
+	}
+};
 class CCenterSettingEntity : public CEntityBase, public ITimerListener
 {
 public:
 	CCenterSettingEntity() : /*m_dwLastSyncTime(0),*/
-		m_pConnection(nullptr), m_nConnectFailCount(0), m_bUseBackupNow(false){}
+		m_pConnection(nullptr), m_nConnectFailCount(0), m_bUseBackupNow(false)
+		, m_spDownloadCall(NULL), m_spDownloadCallEx(NULL){}
 	virtual ~CCenterSettingEntity() {}
 	virtual const char *GetEntityName() const { return "CenterSetting"; }
 	const char* GetEntityVersion() const { return MODULE_VERSION_FULL; }
@@ -44,6 +77,14 @@ public:
 
 	void OnPrePause(CSmartPointer<ITransactionContext> pTransactionContext);
 
+    void EditWebUrl(SpReqAnsContext<CenterSettingService_EditWebUrl_Req, CenterSettingService_EditWebUrl_Ans>::Pointer ctx);
+    void GetWebUrlList(SpReqAnsContext<CenterSettingService_GetWebUrlList_Req, CenterSettingService_GetWebUrlList_Ans>::Pointer ctx);
+    void GetActiveCustomUrl(SpReqAnsContext<CenterSettingService_GetActiveCustomUrl_Req, CenterSettingService_GetActiveCustomUrl_Ans>::Pointer ctx);
+    void EditTerminalBackupInfo(SpReqAnsContext<CenterSettingService_EditTerminalBackupInfo_Req, CenterSettingService_EditTerminalBackupInfo_Ans>::Pointer ctx);
+    void GetTerminalBackupInfoList(SpReqAnsContext<CenterSettingService_GetTerminalBackupInfoList_Req, CenterSettingService_GetTerminalBackupInfoList_Ans>::Pointer ctx);
+    void DownloadCenterFiles(SpReqAnsContext<CenterSettingService_DownloadCenterFiles_Req, CenterSettingService_DownloadCenterFiles_Ans>::Pointer ctx);
+
+
 private:
 	ErrorCodeEnum BeginDownloadCenterSetting(LPCTSTR serverIP = NULL, int port = 0);
 	ErrorCodeEnum EndDownloadCenterSetting(ErrorCodeEnum rc);
@@ -53,10 +94,50 @@ private:
 	bool ParseIPAddress(const char *str, CSimpleStringA &ip, int &port);
 	bool TryExtractSiteFromFileName(const char *pszPath, CSimpleStringA &strFileName, CSimpleStringA &strSite);
 	
+	ErrorCodeEnum GetWebUrlInfoFromCenterSettings(CustomWebUrlConfig& config);
+
 	bool IsServerConnectedNow() const
 	{
 		return (m_pConnection != nullptr && m_pConnection->IsConnectionOK());
 	}
+	ErrorCodeEnum UpdateTerminalInfoAtChange(const CSimpleStringA& newTerminalInfo);
+	ErrorCodeEnum ConfirmCenterSettingsFileAndUpdateIfNecessary(const CSimpleStringA& serverIP);
+	bool IsParamCurrentUsed(const CSimpleStringA& strTerminalInfo, const CSimpleStringA& strServerIP, DWORD& outMask);
+	ErrorCodeEnum GetParamCurrentUseing(CustomWebUrlConfig& config);
+
+	bool IsDownloadPending()
+	{
+		if (m_spDownloadCall != NULL) {
+			Dbg("Download Call Pending!");
+			return true;
+		}
+
+		if (m_spDownloadCallEx != NULL) {
+            Dbg("Download Call Ex Pending!");
+			return true;
+		}
+
+		return false;
+	}
+
+	void ReturnAndClearDownloadContext(ErrorCodeEnum ec)
+	{
+        if (m_spDownloadCall != NULL) {
+			Dbg("DownloadCall return %s", SpStrError(ec));
+            m_spDownloadCall->Answer(ec);
+            m_spDownloadCall.Clear();
+			m_spDownloadCall = NULL;
+        }
+
+        if (m_spDownloadCallEx != NULL) {
+            Dbg("DownloadCallEx return %s", SpStrError(ec));
+			m_spDownloadCallEx->Answer(ec);
+			m_spDownloadCallEx.Clear();
+			m_spDownloadCallEx = NULL;
+        }
+	}
+
+	void RemoveAllCenterSettingFiles();
 
 private:
 	struct ConfigFileInfo
@@ -74,6 +155,8 @@ private:
 	CCenterSettingConn *m_pConnection;
 	
 	SpReqAnsContext<CenterSettingService_Download_Req, CenterSettingService_Download_Ans>::Pointer m_spDownloadCall;
+    SpReqAnsContext<CenterSettingService_DownloadCenterFiles_Req, CenterSettingService_DownloadCenterFiles_Ans>::Pointer m_spDownloadCallEx;
+
 	friend class CCenterSettingConn;
 };
 
@@ -109,6 +192,15 @@ public:
 		ctx->Answer(rc);
 	}
 
+	void Handle_EditWebUrl(SpReqAnsContext<CenterSettingService_EditWebUrl_Req, CenterSettingService_EditWebUrl_Ans>::Pointer ctx);
+	void Handle_GetWebUrlList(SpReqAnsContext<CenterSettingService_GetWebUrlList_Req, CenterSettingService_GetWebUrlList_Ans>::Pointer ctx);
+	void Handle_GetActiveCustomUrl(SpReqAnsContext<CenterSettingService_GetActiveCustomUrl_Req, CenterSettingService_GetActiveCustomUrl_Ans>::Pointer ctx);
+    void Handle_EditTerminalBackupInfo(SpReqAnsContext<CenterSettingService_EditTerminalBackupInfo_Req, CenterSettingService_EditTerminalBackupInfo_Ans>::Pointer ctx);
+    void Handle_GetTerminalBackupInfoList(SpReqAnsContext<CenterSettingService_GetTerminalBackupInfoList_Req, CenterSettingService_GetTerminalBackupInfoList_Ans>::Pointer ctx);
+	void Handle_DownloadCenterFiles(SpReqAnsContext<CenterSettingService_DownloadCenterFiles_Req, CenterSettingService_DownloadCenterFiles_Ans>::Pointer ctx);
+
+
+
 private:
 	CCenterSettingEntity *m_pEntity;
 };

+ 1 - 1
Module/mod_DeviceControl/DeviceControl.xml

@@ -110,7 +110,7 @@
 		</twoway>
 		<twoway name="ReadConfigValue" overlap="true">
 			<req>
-				<!--0:Custom, 1:Config_Hardware,2:Config_Software, 3:Config_Run, 4:Config_Shell, 5:Config_Root, 6:Config_CenterSetting-->
+				<!--0:Custom, 1:Config_Hardware,2:Config_Software, 3:Config_Run, 4:Config_Shell, 5:Config_Root, 6:Config_CenterSetting, 7:Config_Cache-->
 				<param name="configType" type="int" />
 				<param name="section" type="string" />
 				<!-- true: write; false: read -->

+ 1 - 1
Module/mod_DeviceControl/mod_DeviceControl.cpp

@@ -114,7 +114,7 @@ void CDeviceControlEntity::ReadConfigValue(SpReqAnsContext<DeviceControlService_
 {
     LOG_FUNCTION();
 
-    if (ctx->Req.configType < 0 || ctx->Req.configType > Config_CenterSetting + 1) {
+    if (ctx->Req.configType < 0 || ctx->Req.configType > Config_Cache + 1) {
         ctx->Answer(Error_Param);
         return;
     }

+ 61 - 0
Module/mod_ResourceWatcher/mod_ResourceWatcher.cpp

@@ -8,12 +8,16 @@
 #include "fileutil.h"
 #include "iniutil.h"
 #include "toolkit.h"
+#include "osutil.h"
 
 #if defined(RVC_OS_LINUX)
 #include "SogouVersion.h"
 #include <winpr/sysinfo.h>
 #endif //RVC_OS_LINUX
 
+#include "publicFunExport.h"
+#include <map>
+
 struct SogouRunVersionInfo 
 {
 	CSimpleStringA strInstallDir;
@@ -771,6 +775,63 @@ ErrorCodeEnum ResourceWatcherEntity::DoCheckInstallStateJob()
     return Error_Succeed;
 }
 
+void ResourceWatcherEntity::DoCheckSogouProcessStatus()
+{
+    static int old_process_id[2] = { -1, -1 };
+    char* relate_processes[2] = {"sogouImeWebSrv", "sogouImeService"};
+
+    int count = 3;
+    alive_process_info processes[3];
+    memset(processes, 0, sizeof(processes));
+
+    osutil_detect_unique_app(relate_processes, array_size(relate_processes), &count, processes);
+
+    CAutoArray<CSimpleStringA> msgs(array_size(relate_processes));
+    int cnt(0);
+
+    for (int i = 0; i < array_size(relate_processes); ++i) {
+        int k = -1;
+        for (int j = 0; j < count; ++j) {
+            if (strcmp(processes[j].name, relate_processes[i]) == 0) {
+                k = j;
+                break;
+            }
+        }
+
+        if (k != -1 && old_process_id[i] == -1) {
+            old_process_id[i] = processes[k].pid;
+
+        } else if (k != -1 && (processes[k].pid != old_process_id[i])) {
+            msgs[cnt++] = CSimpleStringA::Format("{\"name\":\"%s\", \"prev\":%d, \"pid\":%d}"
+                                                 , relate_processes[i], old_process_id[i], processes[k].pid);
+            old_process_id[i] = processes[k].pid;
+
+        } else if(k == -1 && old_process_id[i] != 0) {
+            msgs[cnt++] = CSimpleStringA::Format("{\"name\":\"%s\", \"prev\":%d, \"pid\":%d}"
+                                                 , relate_processes[i], old_process_id[i], 0);
+            old_process_id[i] = 0;
+        }
+    }
+
+    if (cnt > 0) {
+        std::string uploadInfo("");
+        if (cnt > 1) {
+            uploadInfo = "{";
+        }
+        for (int i = 0; i < cnt; ++i) {
+            if (i != 0) {
+                uploadInfo += ",";
+            }
+            uploadInfo += msgs[i].GetData();
+        }
+        if (cnt > 1) {
+            uploadInfo += "}";
+        }
+
+        LogWarn(Severity_Middle, Error_Debug, LOG_RESOURCEWATCHER_SOGOU_PROCESS_STATUS_CHANGE, uploadInfo.c_str());
+    }
+}
+
 //# all available outputs
 //OUTPUTS = $(xrandr | awk '$2 ~ /connected/ {print $1}')
 //echo outputs : $OUTPUTS

+ 16 - 9
Module/mod_ResourceWatcher/mod_ResourceWatcher.h

@@ -10,6 +10,9 @@ class ResourceWatcherEntity;
 #define ENT_TIMERID_CHECK_SOGOU_INPUT_INSTALLED_STATE 1
 #define ENT_TIMERINTERVAL_CHECK_SOGOU_INPUT_INSTALLED_STATE 60 * 1000
 
+#define ENT_TIMERID_CHECK_SOGOU_INPUT_PROCESS_STATUS_CHANGE 3
+#define ENT_TIMERINTERVAL_CHECK_SOGOU_INPUT_PROCESS_STATUS_CHANGE 30 * 1000
+
 
 class ResourceWatcherServiceSession : public ResourceWatcherService_ServerSessionBase
 {
@@ -96,7 +99,7 @@ public:
 	void OnStarted()
 	{
 		m_fsm.AfterInit();
-		///**TODO(Gifur@10/21/2021): 此接口有问题,待查!!! */
+		///**TODO(Gifur@10/21/2021): 麓脣陆脫驴脷脫脨脦脢脤芒拢卢麓媒虏茅拢隆拢隆拢隆 */
 		//m_bInitMode = m_fsm.IsInitMode();
         //Dbg("%s: %u", __FUNCTION__, m_bInitMode);
 
@@ -242,26 +245,30 @@ private:
 
 		ErrorCodeEnum DoCheckInstallStateJob();
 
+		void DoCheckSogouProcessStatus();
+
 		void OnTimeout(DWORD dwTimerID) 
 		{
 			if(dwTimerID == ENT_TIMERID_CHECK_SOGOU_INPUT_INSTALLED_STATE) {
 
 				CSimpleStringA strState;
 				auto err = GetFunction()->GetSysVar("UIState",strState);
-
-				if(TRUE || err == Error_Succeed && strState == "M") {
+				/** 璁╄繘鍏ラ�椤典箣鍚庢墠鑾峰彇杈撳叆娉曚俊鎭� [Gifur@20211212]*/
+				if(/*TRUE || */err == Error_Succeed && strState == "M") {
 					Dbg("to check Sogou input install state...");
 					if(Error_Succeed == DoCheckInstallStateJob()) {
 						GetFunction()->KillTimer(ENT_TIMERID_CHECK_SOGOU_INPUT_INSTALLED_STATE);
-					}
 
+						GetFunction()->SetTimer(ENT_TIMERID_CHECK_SOGOU_INPUT_PROCESS_STATUS_CHANGE,
+                                 this, ENT_TIMERINTERVAL_CHECK_SOGOU_INPUT_PROCESS_STATUS_CHANGE);
+					}
 				} else {
-
-					Dbg("Get UIState result: %d, %s", err, strState.GetData());
+					Dbg("Get UIState result: %s, %s", SpStrError(err), strState.GetData());
 				}
-
-			} else {
-
+			} else if (dwTimerID == ENT_TIMERID_CHECK_SOGOU_INPUT_PROCESS_STATUS_CHANGE) {
+				DoCheckSogouProcessStatus();
+			}
+			else {
 				Dbg("Unkonwn timer id: %u", dwTimerID);
 			}
 		}

+ 2 - 1
Module/mod_chromium/CModTools.cpp

@@ -1015,7 +1015,8 @@ namespace Chromium {
 		CChromiumEntity* pChromiumEntity = reinterpret_cast<CChromiumEntity*>(m_pEntity);
 		if (pChromiumEntity != nullptr && pChromiumEntity->HasCustomMainUrl()) {
 			strFulture = pChromiumEntity->GetCustomMainUrl();
-			DbgEx("Replace FultureUrl with %s", strFulture.GetData());
+			CSimpleStringA strTmp = CSimpleStringA::Format("更新业务中台链接为:[%s]", strFulture.GetData());
+			LogWarn(Severity_High, Error_Debug, LOG_EVT_CHROMIUM_USE_CUSTOM_FULTURE_URL, strTmp);
 		}
 
 		return std::make_tuple(str, strNew, strEx, strFulture, strAd);

+ 43 - 15
Module/mod_chromium/mod_chromium.cpp

@@ -167,6 +167,9 @@ namespace Chromium {
 			DbgEx("Generate chromiumAnalyze, %s", str.c_str());
 			}, profStr.GetData()).detach();
 #endif // OPEN_PERF
+
+			FetchCustomMainUrl(strArgs);
+
 			CModTools::get_mutable_instance().InitCModTools(this);
 			CModTools::get_mutable_instance().killAllChromium();
 
@@ -198,18 +201,10 @@ namespace Chromium {
 				}).detach();
 #endif
 
-				const int ArgsCount = strArgs.GetCount();
-				LOG_TRACE("strArgs.GetCount() = %d", ArgsCount);
-				for (int i = 0; i < ArgsCount; ++i) {
-					DbgEx("strArgs[%d] = %s", i, strArgs[i].GetData());
-				}
-				if (ArgsCount == 1) {
-					m_strCustomMainUrl = strArgs[0];
-					DbgEx("Get custom main ulr: %s", m_strCustomMainUrl.GetData());
-				}
 
-				GetFunction()->GetSystemStaticInfo(m_sysInfo);
-				if (!IsConfigMode()) {
+
+			GetFunction()->GetSystemStaticInfo(m_sysInfo);
+			if (!IsConfigMode()) {
 				CSmartPointer<IConfigInfo> spConfig;
 				if (Error_Succeed == GetFunction()->OpenConfig(Config_CenterSetting, spConfig))//特别坑,这个OpenConfig返回一直都是success
 				{
@@ -258,14 +253,14 @@ namespace Chromium {
 					}
 
 				}
-#if (defined _WIN32 || defined _WIN64)
+	#if (defined _WIN32 || defined _WIN64)
 				if (!logProducer)
 					logProducer = create_log_producer_storage("cefclient", "0", "");
-#endif
+	#endif
 
 				std::string magicStr = CModTools::get_mutable_instance().getMagicStr();
 				boost::thread(boost::bind(SaveCefclientLog, magicStr)).detach();
-		}
+			}
 	}
 
 	bool CChromiumEntity::OnPreStart_socketStart(CAutoArray<CSimpleStringA>& strArgs, CSmartPointer<ITransactionContext>& pTransactionContext)
@@ -410,7 +405,6 @@ namespace Chromium {
 		if (!OnPreStart_socketStart(strArgs, pTransactionContext)) {
 			return;
 		}
-
 		if (!IsConfigMode()) {
 			if (!OnPreStart_register(strArgs, pTransactionContext)) {
 				return;
@@ -501,6 +495,40 @@ namespace Chromium {
 		}
 	}
 
+	/** 查看启动顺序发现集中配置实体启动在本实体之前,无法调用集中配置的接口,随将实现搬到这里来 [Gifur@2021124]*/
+    void CChromiumEntity::FetchCustomMainUrl(CAutoArray<CSimpleStringA>& strArgs)
+    {
+        const int ArgsCount = strArgs.GetCount();
+        LOG_TRACE("strArgs.GetCount() = %d", ArgsCount);
+        for (int i = 0; i < ArgsCount; ++i) {
+            DbgEx("strArgs[%d] = %s", i, strArgs[i].GetData());
+        }
+        if (ArgsCount == 1) {
+            m_strCustomMainUrl = strArgs[0];
+            DbgEx("Get custom main url: %s", m_strCustomMainUrl.GetData());
+			if (!m_strCustomMainUrl.IsNullOrEmpty()) {
+                LogWarn(Severity_High, Error_Debug, LOG_EVT_CHROMIUM_DETECT_CUSTOM_FULTURE_URL_FROM_START,
+						CSimpleStringA::Format("从模块入参获取自定义链接:%s", m_strCustomMainUrl.GetData()));
+			}
+		} else {
+            CSmartPointer<IConfigInfo> pConfig;
+            GetFunction()->OpenConfig(Config_Cache, pConfig);
+            int cnt(0), currentUsing(0);
+            pConfig->ReadConfigValueInt("CustomWebUrl", "Count", cnt);
+            pConfig->ReadConfigValueInt("CustomWebUrl", "Current", currentUsing);
+			if (cnt > 0 && currentUsing > 0) {
+				CSimpleStringA strAdUrl(true);
+                CSimpleStringA strSection = CSimpleStringA::Format("CustomWebUrl%d", currentUsing);
+                pConfig->ReadConfigValue(strSection, "FultureUrl", m_strCustomMainUrl);
+                pConfig->ReadConfigValue(strSection, "AdUrl", strAdUrl);
+				if (!m_strCustomMainUrl.IsNullOrEmpty()) {
+                    LogWarn(Severity_High, Error_Debug, LOG_EVT_CHROMIUM_DETECT_CUSTOM_FULTURE_URL_FROM_CONFIG,
+							CSimpleStringA::Format("从本地维护桌面获取自定义链接:%s", m_strCustomMainUrl.GetData()));
+				}
+			}
+		}
+    }
+
 #if (defined _WIN32 || defined _WIN64)
 	void CChromiumEntity::OnLog(const CAutoArray<CUUID>& SubIDs, const CUUID nLogID, const LogTypeEnum eLogType, const SeverityLevelEnum eLevel,
 		const DWORD dwSysError, const DWORD dwUserCode, const DWORD dwEntityInstanceID, const WORD wEntityDevelID,

+ 1 - 0
Module/mod_chromium/mod_chromium.h

@@ -78,6 +78,7 @@ namespace Chromium {
 		virtual void OnPreClose(EntityCloseCauseEnum eCloseCause, CSmartPointer<ITransactionContext> pTransactionContext);
 		//void CefClintNotify();
 		void exitClean();
+		void FetchCustomMainUrl(CAutoArray<CSimpleStringA>& strArgs);
 		bool HasCustomMainUrl() const { return !m_strCustomMainUrl.IsNullOrEmpty(); }
 		const char* GetCustomMainUrl()  const { return m_strCustomMainUrl; }
 		bool IsConfigMode() 

+ 30 - 30
addin/res/ManagerDesktop/css/emui-style.css

@@ -1169,8 +1169,8 @@ height: 32px;
 overflow: hidden;
 cursor: pointer;
 background-repeat: no-repeat;
-background-image: url('../images/emui-icon.png?r=0.1517399082388049&_=2311627385677326');
-background-position: left -4446px;
+background-image: url('../images/select_input340_disabled.png');
+background-position: left 0px;
 }
 .select_off_normal {
 width: 340px;
@@ -1181,8 +1181,8 @@ line-height: 32px;
 text-indent: 15px;
 *padding-left: 15px;
 background-repeat: no-repeat;
-background-image: url('../images/emui-icon.png?r=0.1517399082388049&_=2311627385677326');
-background-position: left -4478px;
+background-image: url('../images/select_input340_disabled.png');
+background-position: left 0px;
 }
 .select_on_normal:hover {
 width: 340px;
@@ -1401,8 +1401,8 @@ height: 26px;
 overflow: hidden;
 cursor: pointer;
 background-repeat: no-repeat;
-background-image: url('../images/emui-icon.png?r=0.1517399082388049&_=2311627385677326');
-background-position: left -2058px;
+background-image: url('../images/switch_on_disable.png');
+background-position: left 0px;
 }
 .switch_off_disable {
 width: 50px;
@@ -1410,8 +1410,8 @@ height: 26px;
 overflow: hidden;
 cursor: pointer;
 background-repeat: no-repeat;
-background-image: url('../images/emui-icon.png?r=0.1517399082388049&_=2311627385677326');
-background-position: left -2084px;
+background-image: url('../images/switch_off_disable.png');
+background-position: left 0px;
 }
 .check_off {
 width: 20px;
@@ -2844,16 +2844,16 @@ width: 680px;
 height: 12px;
 overflow: hidden;
 background-repeat: no-repeat;
-background-image: url('../images/emui-icon2.png?r=0.1517399082388049&_=2311627385677326');
-background-position: left -2296px;
+background-image: url('../images/table_border.png');
+background-position: left -120px;
 }
 .table_top {
 width: 680px;
 height: 65px;
 overflow: hidden;
 background-repeat: no-repeat;
-background-image: url('../images/emui-icon2.png?r=0.1517399082388049&_=2311627385677326');
-background-position: left -2308px;
+background-image: url('../images/table_border.png');
+background-position: left 0px;
 }
 .table_top_lower {
 width: 680px;
@@ -2874,8 +2874,8 @@ margin-top: 20px;
 margin-right: 20px;
 cursor: pointer;
 background-repeat: no-repeat;
-background-image: url('../images/emui-icon2.png?r=0.1517399082388049&_=2311627385677326');
-background-position: left -2385px;
+background-image: url('../images/new.png');
+background-position: left 0px;
 }
 .ic_setup_normal {
 width: 22px;
@@ -2914,24 +2914,24 @@ height: 22px;
 cursor: pointer;
 margin-right: 20px;
 background-repeat: no-repeat;
-background-image: url('../images/emui-icon2.png?r=0.1517399082388049&_=2311627385677326');
-background-position: left -2451px;
+background-image: url('../images/delete.png');
+background-position: left 0px;
 }
 .btn_edit {
 width: 22px;
 height: 22px;
 cursor: pointer;
 background-repeat: no-repeat;
-background-image: url('../images/emui-icon2.png?r=0.1517399082388049&_=2311627385677326');
-background-position: left -2473px;
+background-image: url('../images/edit.png');
+background-position: left 0px;
 }
 .btn_edit_disable {
 width: 22px;
 height: 22px;
 cursor: pointer;
 background-repeat: no-repeat;
-background-image: url('../images/emui-icon2.png?r=0.1517399082388049&_=2311627385677326');
-background-position: left -2495px;
+background-image: url('../images/edit.png');
+background-position: left 0px;
 }
 .btn_sort_up {
 width: 22px;
@@ -3451,8 +3451,8 @@ height: 22px;
 margin-right: 20px;
 margin-top: 20px;
 background-repeat: no-repeat;
-background-image: url('../images/emui-icon3.png?r=0.1517399082388049&_=2311627385677326');
-background-position: left -5561px;
+background-image: url('../images/new_disable.png');
+background-position: left 0px;
 }
 .btn_new:hover {
 width: 22px;
@@ -3461,8 +3461,8 @@ margin-right: 20px;
 margin-top: 20px;
 cursor: pointer;
 background-repeat: no-repeat;
-background-image: url('../images/emui-icon3.png?r=0.1517399082388049&_=2311627385677326');
-background-position: left -5583px;
+background-image: url('../images/new_hover.png');
+background-position: left 0px;
 }
 .btn_upload:hover {
 width: 22px;
@@ -3485,8 +3485,8 @@ height: 22px;
 cursor: pointer;
 margin-right: 20px;
 background-repeat: no-repeat;
-background-image: url('../images/emui-icon3.png?r=0.1517399082388049&_=2311627385677326');
-background-position: left -5605px;
+background-image: url('../images/delete.png');
+background-position: left 0px;
 }
 .btn_edit:hover {
 width: 22px;
@@ -6341,8 +6341,8 @@ height: 20px;
 overflow: hidden;
 cursor: pointer;
 background-repeat: no-repeat;
-background-image: url('../images/emui-icon5.png?r=0.1517399082388049&_=2311627385677326');
-background-position: left -8473px;
+background-image: url('../images/check_off_disable.png');
+background-position: left 0px;
 }
 .check_on_disable {
 width: 20px;
@@ -6350,8 +6350,8 @@ height: 20px;
 overflow: hidden;
 cursor: pointer;
 background-repeat: no-repeat;
-background-image: url('../images/emui-icon5.png?r=0.1517399082388049&_=2311627385677326');
-background-position: left -8493px;
+background-image: url('../images/select_in_disable.png');
+background-position: left 0px;
 }
 .ic_eye_close_disable {
 width: 24px;

BIN
addin/res/ManagerDesktop/images/check_off_disable.png


BIN
addin/res/ManagerDesktop/images/delete.png


BIN
addin/res/ManagerDesktop/images/edit.png


BIN
addin/res/ManagerDesktop/images/new.png


BIN
addin/res/ManagerDesktop/images/new_disable.png


BIN
addin/res/ManagerDesktop/images/new_hover.png


BIN
addin/res/ManagerDesktop/images/select_in_disable.png


BIN
addin/res/ManagerDesktop/images/select_input340_disabled.png


BIN
addin/res/ManagerDesktop/images/switch_off_disable.png


BIN
addin/res/ManagerDesktop/images/switch_on_disable.png


BIN
addin/res/ManagerDesktop/images/table_border.png


+ 4 - 2
addin/res/ManagerDesktop/js/menu.js

@@ -43,8 +43,10 @@ var gMenuDisplayName = {
     'reboot':'应用重启',
     'poweroff':'关机',
     'diagnosis':'诊断',
-    'reset':'重置'
-
+    'reset':'重置',
+    'develop':'开发者',
+    'business':'业务中台',
+    'context':'环境切换'
 };
 
 function getDisplayName(name) {

+ 5 - 1
addin/res/ManagerDesktop/js/page.js

@@ -26,7 +26,7 @@ $(document).ready(function () {
             <hardwareconfig> \
                     <adapters> \
                         <cardissuer>cardissuer</cardissuer> \
-                        <contactless>cardissuer</contactless> \
+                        <contactless>contactless</contactless> \
                         <idcertificate>idcertificate</idcertificate> \
                         <pinpad>pinpad</pinpad> \
                         <fingerprint>fingerprint</fingerprint> \
@@ -59,6 +59,10 @@ $(document).ready(function () {
                     <diagnosis>diagnosis</diagnosis> \
                     <reset>reset</reset> \
                 </system> \
+                <develop> \
+                    <business>business</business> \
+                    <context>context</context> \
+                </develop> \
             </advanceset> \
         </menu> \
     </config>';

+ 1 - 3
addin/res/ManagerDesktop/js/page/browser.js

@@ -28,9 +28,7 @@ function browserGenPage() {
     </div>\
     <div id="browser_activation_content" class="page_prompt_info page_scenes_info_text hide">\
     </div>\
-    </div>\
-    <div style="height:40px;">&nbsp;</div>\
-</div>';
+    </div></div>';
 
     $("#rightpagearea").prepend(page);
     if (typeof browserRenderPage == "function") {

+ 456 - 0
addin/res/ManagerDesktop/js/page/business.js

@@ -0,0 +1,456 @@
+function businessGenPage() {
+    var page = '<div id="business_page" style="display: block;">\
+    <div class="maintitle">\
+    <div>业务中台切换</div>\
+    <div class="page_description_text">用于开发测试环境<strong>灵活</strong>切换业务中台链接。将替代集中配置中的业务链接,设置永久有效<br/>\
+            信息有变更时需重启Chromium实体或者重启应用方能生效。\
+            </div>\
+    </div>\
+    <div id="businessContent">\
+    <div class="clearboth" id="apn_list" style="padding-top:70px;">\
+    <div class="table_top">\
+    <div class="table_list_title">自定义业务链接\
+    </div>\
+    <div class="pull-right">\
+    <div id="web_new" class="btn_new pull-left" >\
+    &nbsp;\
+    </div>\
+    </div>\
+    </div>\
+    <div class="border_left border_right color_Darkgray" style="width:678px;padding-top:-1px;">\
+    <div id="web_lists" class="clearboth" style="width:100%;overflow:hidden;">\
+    </div>\
+    </div>\
+    <div class="table_bottom">\
+    </div>\
+    </div>\
+    <div id="add_web_item_win" class="out_win_content submit_background hide">\
+    <div class="table_top">\
+    <div style="border-bottom: #E9E9E9 solid 1px;font-size: 16px;text-align:center;line-height: 65px;">\
+    业务链接设置</div>\
+    </div>\
+    <div class="border_left border_right margin_bottom_box2 color_background_white"\
+    style="padding-top: 40px;">\
+    <div id="add_web_item_win_scroll" style="max-height:300px;">\
+    <div id="web_env_type_div" class="clearboth">\
+    <div class="control-label-win"><span>环境</span></div>\
+    <div class="controls-win">\
+    <div id="web_env" class="select_on_normal"\
+    onclick="SelectItem(this)"></div>\
+    <div id="web_env_list" class="select_list hide"\
+    style="display: none;">\
+    <div id="web_env_list_item_dev" option="1"\
+    class="select_medium"">DEV</div>\
+    <div id="web_env_list_item_st" option="2"\
+    class="select_medium">ST</div>\
+    <div id="web_env_list_item_uat" option="3"\
+    class="select_medium">UAT</div>\
+    <div id="web_env_list_item_all" option="0"\
+    class="select_medium">Unclassfied</div>\
+    </div>\
+    </div>\
+    </div>\
+    <input style="display:none;" id="web_url_profile_index" type="text">\
+    <div id="web_main_url" class="clearboth" style="padding-top:29px;">\
+    <div class="control-label-win"><span>业务URL(主屏)</span></div>\
+    <div class="controls-win input_normal"><input id="web_main_url_text"\
+    onfocus="showInputBorder(this)" onblur="hideInputBorder(this)"\
+    type="text" maxlength="128"></div>  \
+    </div>\
+    <div id="web_ad_url" class="clearboth" style="padding-top:29px;">\
+    <div class="control-label-win"><span>广告URL(上屏)</span></div>\
+    <div class="controls-win input_normal"><input id="web_ad_url_text" placeholder="(目前该值没应用,将使用默认的)"\
+    onfocus="showInputBorder(this)" onblur="hideInputBorder(this)"\
+    type="text" maxlength="128" disabled></div>\
+    </div>\
+    <div id="remark" class="clearboth" style="padding-top:29px;">\
+    <div class="control-label-win"><span">备注</span></div>\
+    <div class="controls-win input_normal"><input id="input_remark" placeholder="(可不填)"\
+    onfocus="showInputBorder(this)" onblur="hideInputBorder(this)"\
+    type="text" maxlength="63"></div>\
+    </div>\
+    <div id="web_list_input_set_default_div" class="clearboth" style="padding-top: 27px;">\
+    <div class="control-label-win pull-left">\
+    <span>设置为当前使用链接</span>\
+    </div>\
+    <div id="web_list_input_set_default" class="check_off controls-win pull-right" style="margin-top:8px;">\
+    </div>\
+    </div>\
+    <div id="web_select_blank" style="height: 145px; display: none;" class="hide"></div>\
+    <div class="clearboth"></div>\
+    </div>\
+    <div style="padding-top:50px;padding-bottom:8px;" align="center">\
+    <button id="web_item_cancel" class="btn_normal_short" >取消</button>\
+    <button id="web_item_save" class="btn_normal_short btn_disabled margin-left-20">保存</button>\
+    </div>\
+    </div>\
+    <div class="table_bottom"></div>\
+    </div>\
+    </div>\
+    </div>';
+
+    $("#rightpagearea").prepend(page);
+    if (typeof businessRenderPage == "function") {
+        beforeRenderPage("business");
+        businessRenderPage();
+        afterRenderPage("business");
+    }
+}
+
+var businessController = (function() {
+
+    var CONST = {
+        SWITCH_ON: '1',
+        PROFILE_MAX_NUM: 100
+    };
+    
+    var weblistCount = 0;
+    var isNewWebConfig = true;
+
+    var modifyIndex = -1;
+    var profilesArray = [];
+    var modifyProfile = {};
+
+    function loadData(flag) {
+        let req = new Request();
+        req.filter1 = 0;
+        req.filter2 = 0;
+        req.filter3 = 0;
+        req.filter4 = '';
+
+        profilesArray = [];
+        weblistCount = 0;
+
+        if(typeof flag === 'undefined') {
+            utilStartSubmitDialog();
+        }
+        RVC.CenterSettingEntity.GetWebUrlList(req, function(ret) {
+            if(typeof flag === 'undefined'){
+                utilStopSubmitDialog();
+            }
+            console.log('result: ' + ret.errorCode);
+            if (ret.errorCode === 0) {
+                let result = JSON.parse(ret[RVC.CenterSettingEntity.sigResponseUUID])
+                console.log('count: ' + result.index.length + ' ' + result);
+
+                if (result.index.length === 0) {
+                    $('#web_lists').css('height', 0);
+                    $('#web_lists').hide();
+                    return;
+                } else if (result.index.length <= 8) {
+                    $('#web_lists').css('height', (result.index.length * 70 - 12) + result.index.length + 'px');
+                } else {
+                    $('#web_lists').css('height', '561px');
+                }
+                $('#web_lists').show();
+                $('#web_lists').empty();
+                RVC.Scroll.initScroll('#web_lists');
+
+                for (var n = 0; n < result.index.length; n++)
+                {
+                    var templateData = {
+                        profileItemIndex: result.index[n],
+                        profileItemName: result.remark[n],
+                        profileItemMainUrl: result.futureUrl[n],
+                        profileItemAdUrl: result.adUrl[n],
+                        profileItemEnvType: result.env[n],
+                        profileItemFromType: result.type[n],
+                        profileItemStatus: result.status[n]
+                    };
+                    profilesArray.push(templateData);
+
+                    var profileHtml;
+                    if (n === result.index.length - 1) {
+                        profileHtml = '<div  id="web_list_{{profileItemIndex}}" style="height:59px;cursor:pointer;" class="list_item_hover">';
+                        profileHtml += '<div id="web_list_name_{{profileItemIndex}}"  class="pull-left padding-left-20" style="height:45px;padding-top:14px;width:600px;" onclick="RVC.WebUrlController.ShowWebUrlInfo({{profileItemIndex}})">';
+                    } else {
+                        profileHtml = '<div  id="web_list_{{profileItemIndex}}" class="border_bottom list_item_hover" style="height:70px;cursor:pointer;">';
+                        profileHtml += '<div id="web_list_name_{{profileItemIndex}}"  class="pull-left padding-left-20" style="height:56px;padding-top:14px;width:600px;" onclick="RVC.WebUrlController.ShowWebUrlInfo({{profileItemIndex}})">';
+                    }
+                    if (templateData.profileItemStatus === 1) {
+                        profileHtml += '<pre class="web_profile_name_{{profileItemIndex}}" style="font-size:16px;margin-top:0px;"><span class="web_profile_itemname pull-left" style="line-height:21px;" title="{{profileItemName}}">{{profileItemName}}</span><span class="pull-left" style="line-height:21px;">(当前采用)</span><div class="clearboth"></div></pre>';
+                    } else {
+                        profileHtml += '<pre class="web_profile_name_{{profileItemIndex}}" style="font-size:16px;margin-top:0px;"><span class="web_profile_itemname" title="{{profileItemName}}">{{profileItemName}}</span></pre>';
+                    }
+                    profileHtml += '<div class="web_web_name_{{profileItemIndex}} color_descroption_gray web_profile_itemapnname" style="margin-top:-10px;font-size:14px;" title="{{profileItemMainUrl}}">{{profileItemMainUrl}}</div></div>';
+                    if (templateData.profileItemFromType === 0 || templateData.profileItemStatus === 1 || templateData.profileItemStatus === 2) {
+                        profileHtml += '<div class="pull-right"></div></div>';
+                    } else {
+                        if (n === 0) {
+                            profileHtml += '<div class="pull-right"><div class="btn_delete mobileconnet_btn_delete" onclick="RVC.WebUrlController.RemoveWebUrlProfile({{profileItemIndex}})" >&nbsp;</div></div></div>';
+                        } else {
+                            profileHtml += '<div class="pull-right"><div class="btn_delete mobileconnet_btn_delete" onclick="RVC.WebUrlController.RemoveWebUrlProfile({{profileItemIndex}})" >&nbsp;</div></div></div>';
+                        }
+                    }
+                    $('#web_lists .scroll_text').secureAppend(profileHtml, templateData);
+                }
+                weblistCount = result.index.length;
+
+            } else if(typeof flag === 'undefined') {
+                RVC.CenterSettingEntity.commErrorCallback(ret);
+            }
+        });
+    }
+
+    
+    function preShowWebList()
+    {
+        $('#web_lists').show();
+        $('#web_lists').empty();
+        RVC.Scroll.initScroll('#web_lists');
+    }
+
+    function webProfileCancel() {
+        $('#add_web_item_win').hide();
+        $('#submit_fade').hide();
+    }
+
+    function saveProfileData(newConfig)
+    {
+        if (!isButtonEnable('web_item_save')) {
+            return;
+        }
+
+        var mainUrl = $('#web_main_url_text').val();
+        var adUrl = $('#web_ad_url_text').val();
+        var remark = $('#input_remark').val();
+
+        var isSetDefault = $('#web_list_input_set_default').hasClass('check_on') ? true : false;
+        var envType = parseInt($('#web_env').val());
+        var index = parseInt($('#web_url_profile_index').val());
+
+        if(mainUrl === '') {
+            utilStartAlertDialog('请输入业务链接地址!');
+            return;
+        }
+
+        let req = new Request();
+        if(newConfig) {
+            req.operation = 1;
+            req.index = 0;
+        } else {
+            req.operation = 3;
+            req.index = index;
+        }
+        req.futureUrl = mainUrl;
+        req.adUrl = adUrl;
+        req.remark = remark;
+        req.env = envType;
+        req.setDefault = isSetDefault;
+
+        utilStartSubmitDialog();
+        RVC.CenterSettingEntity.EditWebUrl(req, function(ret) {
+            utilStopSubmitDialog();
+            if (ret.errorCode === 0) {
+                let result = JSON.parse(ret[RVC.CenterSettingEntity.sigResponseUUID])
+                webProfileCancel();
+                utilStartAlertDialog('操作成功!点击确认将重启Chromium实体以让设置生效(该页面由Chromium实体控制,如果出现突然消失属正常现象)', function(){
+                    RVC.HealthmanagerEntityCtrl.StartEntity('Chromium', function() {
+                        utilShowToast('Chromium实体重启时会断开与此页面的通讯连接,如果长时间此提示或当前页面未消失,请转到后台管理窗口查看告警或自行重启!', 30000);
+                    });
+                });
+            } else {
+                RVC.CenterSettingEntity.commErrorCallback(ret);
+            }
+        });
+    }
+
+    function checkboxDisabled(id) {
+        var checkElement = $('#' + id);
+        if (checkElement.hasClass('check_on') && checkElement.hasClass('disabled')) {
+            checkElement.removeClass('check_on').addClass('check_on_disable').addClass('check_on');
+        } else {
+            checkElement.removeClass('check_on_disable');
+        }
+        if (checkElement.hasClass('check_off') && checkElement.hasClass('disabled')) {
+            checkElement.removeClass('check_off').addClass('check_off_disable').addClass('check_off');
+        } else {
+            checkElement.removeClass('check_off_disable');
+        }
+    }
+
+    function showWebBox() {
+        clearAllErrorMsg();
+        $('#web_item_save').addClass('btn_disabled');
+        var outwin = $('#add_web_item_win');
+        checkboxDisabled('web_list_input_set_default');
+        var heightest = $(document).height();
+        $('#submit_fade').css('height', heightest + 'px');
+        $('#submit_fade').show();
+        outwin.show();
+    }
+
+    function setDefaultWebUrlSwitch() {
+        if ($('#web_list_input_set_default').hasClass('disabled')) {
+            return;
+        }
+        $('#web_item_save').removeClass('btn_disabled');
+        if ($('#web_list_input_set_default').hasClass('check_on')) {
+            $('#web_list_input_set_default').removeClass('check_on').addClass('check_off');
+        } else {
+            $('#web_list_input_set_default').removeClass('check_off').addClass('check_on');
+        }
+        if ($('#web_list_input_set_default').hasClass('check_off')) {
+            $('#web_item_save').addClass('btn_disabled');
+        }
+    }
+
+    function ResetWebUrlInfoShowDialog()
+    {
+        $('#web_url_profile_index').val('');
+        $('#add_web_item_win input').val('');
+        $('#add_web_item_win input').removeAttr('disabled');
+        $('#add_web_item_win .select_on_normal').removeClass('disabled');
+    }
+
+    RVC.WebUrlController = RVC.ObjController.extend({
+
+        ShowWebUrlInfo: function(index) {
+            modifyIndex = index;
+            var webUrlShowItem = {};
+            for (var i = 0; i < profilesArray.length; i++) {
+                if (profilesArray[i].profileItemIndex === index) {
+                    webUrlShowItem = profilesArray[i];
+                    break;
+                }
+            }
+            /**
+             *          profileItemIndex: result.index[n],
+                        profileItemName: result.remark[n],
+                        profileItemMainUrl: result.futureUrl[n],
+                        profileItemAdUrl: result.adUrl[n],
+                        profileItemEnvType: result.env[n],
+                        profileItemFromType: result.type[n],
+                        profileItemStatus: result.status[n]
+             */
+
+            ResetWebUrlInfoShowDialog();
+
+            modifyProfile = webUrlShowItem;
+            $('#web_url_profile_index').val(webUrlShowItem.profileItemIndex.toString());
+            $('#web_main_url_text').val(webUrlShowItem.profileItemMainUrl);
+            $('#web_ad_url_text').val(webUrlShowItem.profileItemAdUrl);
+            $('#input_remark').val(webUrlShowItem.profileItemName);
+
+            if (webUrlShowItem.profileItemStatus === 1) { //默认配置
+                $('#web_list_input_set_default').removeClass('check_off').addClass('check_on');
+                $('#web_list_input_set_default').addClass('disabled');
+            } else {
+                $('#web_list_input_set_default').removeClass('check_on').addClass('check_off');
+                $('#web_list_input_set_default').removeClass('disabled');
+            }
+
+            showSelectedValue('web_env', webUrlShowItem.profileItemEnvType.toString());
+
+            $(document).off('click', '#web_item_save');
+            $(document).on('click', '#web_item_save', function () {
+                saveProfileData(false);
+            });
+
+            if(webUrlShowItem.profileItemFromType === 0) { //集中配置文件不让修改
+                $('#add_web_item_win input').attr('disabled', true);
+                $('#add_web_item_win .select_on_normal').addClass('disabled');
+                console.log(webUrlShowItem.profileItemName);
+            }
+
+            showWebBox();
+        },
+        RemoveWebUrlProfile: function(index)
+        {
+            utilStartConfirmDialog("确定要移除该配置吗?", function() {
+                let req = new Request();
+                req.operation = 2; //删除
+                req.index = parseInt(index);
+                req.futureUrl = '';
+                req.adUrl = '';
+                req.remark = '';
+                req.env = 0;
+                req.setDefault = false;
+
+                utilStartSubmitDialog();
+                RVC.CenterSettingEntity.EditWebUrl(req, function(ret) {
+                    utilStopSubmitDialog();
+                    if (ret.errorCode === 0) {
+                        let result = JSON.parse(ret[RVC.CenterSettingEntity.sigResponseUUID])
+        
+                        preShowWebList();
+                        loadData();
+                    } else {
+                        RVC.CenterSettingEntity.commErrorCallback(ret);
+                    }
+                });
+            });
+        }
+
+    });
+
+    function bindEvents() {
+
+        $('#web_new').click(function () {
+            $('#web_select_blank').hide();
+            if (weblistCount === CONST.PROFILE_MAX_NUM) {
+                utilStartCommonDialog('配置数量超过上限(' + CONST.PROFILE_MAX_NUM + '),请删除再新建!');
+                setTimeout(function () {
+                    utilStopCommonDialog();
+                }, 3000);
+                return;
+            }
+            modifyIndex = -1;
+            ResetWebUrlInfoShowDialog();
+            $('#web_list_input_set_default').removeClass('check_off').addClass('check_on');
+            $('#web_list_input_set_default').addClass('disabled');
+            showSelectedValue('web_env', '1');
+            isNewWebConfig = true;
+            showWebBox();
+            $(document).off('click', '#web_item_save');
+            $(document).on('click', '#web_item_save', function () {
+                saveProfileData(true);
+            });
+            $('#web_main_url_text').focus();
+        });
+
+        $('#web_item_cancel').click(webProfileCancel);
+        $(document).on('click keyup change', '#add_web_item_win input', function () {
+            $('#web_item_save').removeClass('btn_disabled');
+        });
+        $(document).on('change click', '#add_web_item_win .select_on_normal', function () {
+            $('#web_item_save').removeClass('btn_disabled');
+        });
+        $('#web_list_input_set_default').click(setDefaultWebUrlSwitch);
+
+        $('#web_env').click(function () {
+            //RVC.Scroll.setTop('#add_web_item_win_scroll', 200);
+        });
+    }
+
+    function initPage() 
+    {
+        preShowWebList();
+        loadData(true);
+
+    }
+
+    var fistTime = true;
+
+    function init() {
+
+        initPage();
+        
+        if (fistTime) {
+            fistTime = false;
+            bindEvents();
+            RVC.Scroll.initScroll('#add_web_item_win_scroll');
+        }
+        
+    }
+
+    function destory() {
+        clearAllErrorMsg();
+    }
+    
+    return { init: init, destory: destory };
+}());
+
+window.businessRenderPage = function () {
+    businessController.init();
+};

+ 0 - 24
addin/res/ManagerDesktop/js/page/centersettings.js

@@ -18,30 +18,6 @@ function centersettingsGenPage() {
 
 var centersettingsController = (function() {
 
-    RVC.CenterSettingEntity = RVC.EntityController.extend({
-        entityName: 'CenterSetting',
-        className: 'CenterSettingService',
-        methodID: {
-            Download: 0,
-            GetSyncInfo: 1
-        },
-        methodSignature: {
-            Download: -101852141,
-            GetSyncInfo: 1338819403
-        },
-
-        Download: function(req, callback) {
-            this.webSocketInvokeEx(req, 
-                ({id:this.methodID.Download, sig:this.methodSignature.Download}),
-                 callback);
-        },
-        GetSyncInfo: function(req, callback) {
-            this.webSocketInvokeEx(req, 
-                ({id:this.methodID.GetSyncInfo, sig:this.methodSignature.GetSyncInfo}),
-                 callback);
-        }
-    });
-
     function initPage() {
 
     }

+ 544 - 0
addin/res/ManagerDesktop/js/page/context.js

@@ -0,0 +1,544 @@
+function contextGenPage() {
+    var page = '<div id="context_page" style="display: block;">\
+        <div class="maintitle">\
+            <div>终端号切换</div>\
+            <div class="page_description_text">用于开发测试环境终端切换管理。侵入式操作!!<br/>\
+            填写终端号以切换终端,填写分行服务IP地址以重新下载集中配置文件,信息有变更时需按照提示重启应用后方能生效。\
+            </div>\
+        </div>\
+        <div id="contextSwitchContent">\
+            <div class="clearboth" id="apn_list" style="padding-top:70px;">\
+                <div class="table_top">\
+                    <div class="table_list_title">终端号备选列表\
+                    </div>\
+                    <div class="pull-right">\
+                        <div id="termbackup_new" class="btn_new pull-left">\
+                            &nbsp;\
+                        </div>\
+                    </div>\
+                </div>\
+                <div class="border_left border_right color_Darkgray"\
+                    style="width:678px;padding-top:-1px;">\
+                    <div id="termbackup_lists" class="clearboth" style="width:100%;overflow:hidden;">\
+                    </div>\
+                </div>\
+                <div class="table_bottom">\
+                </div>\
+            </div>\
+            <div id="add_termbackup_item_win" class="out_win_content submit_background hide">\
+                <div class="table_top">\
+                    <div style="border-bottom: #E9E9E9 solid 1px;font-size: 16px;text-align:center;line-height: 65px;">\
+                        终端号相关设置</div>\
+                </div>\
+                <div class="border_left border_right margin_bottom_box2 color_background_white"\
+                    style="padding-top: 40px;">\
+                    <div id="add_termbackup_item_win_scroll" style="max-height:300px;">\
+                        <div id="termbackup_env_type_div" class="clearboth">\
+                            <div class="control-label-win"><span>环境</span></div>\
+                            <div class="controls-win">\
+                                <div id="termbackup_env" class="select_on_normal" onclick="SelectItem(this)">\
+                                </div>\
+                                <div id="termbackup_env_list" class="select_list hide" style="display: none;">\
+                                    <div id="termbackup_env_list_item_dev" option="1" class="select_medium"">DEV</div>\
+                                    <div id="termbackup_env_list_item_st" option="2" class="select_medium">ST</div>\
+                                    <div id="termbackup_env_list_item_uat" option="3" class="select_medium">UAT </div>\
+                                    <div id="termbackup_env_list_item_all" option="0" class="select_medium">Unclassfied</div>\
+                                </div>\
+                            </div>\
+                        </div>\
+                        <input style="display:none;" id="termbackup_url_profile_index" type="text">\
+                        <div id="termbackup_terminalno_div" class="clearboth" style="padding-top:29px;">\
+                            <div class="control-label-win"><span>终端号</span></div>\
+                            <div class="controls-win input_normal"><input id="termbackup_terminalno"\
+                                    onfocus="showInputBorder(this)" onblur="hideInputBorder(this)"\
+                                    type="text" maxlength="10"></div>\
+                        </div>\
+                        <div id="termbackup_branch_ip_div" class="clearboth" style="padding-top:29px;">\
+                            <div class="control-label-win"><span>分行服务IP</span></div>\
+                            <div class="controls-win input_normal"><input id="termbackup_branch_ip"\
+                                    onfocus="showInputBorder(this)" onblur="hideInputBorder(this)"\
+                                    type="text" maxlength="64"></div>\
+                        </div>\
+                        <div id="remark" class="clearboth" style="padding-top:29px;">\
+                            <div class="control-label-win">\
+                                <span">备注</span>\
+                            </div>\
+                            <div class="controls-win input_normal"><input id="input_remark"\
+                                 placeholder="(可不填)" onfocus="showInputBorder(this)"\
+                                 onblur="hideInputBorder(this)" type="text" maxlength="128"></div>\
+                        </div>\
+                        <div id="termbackup_list_input_set_default_div" class="clearboth"\
+                            style="padding-top: 27px;">\
+                            <div class="control-label-win pull-left">\
+                                <span>设置为当前使用</span>\
+                            </div>\
+                            <div id="termbackup_list_input_set_default"\
+                                class="check_off controls-win pull-right" style="margin-top:8px;">\
+                            </div>\
+                        </div>\
+                        <div id="termbackup_select_blank" style="height: 145px; display: none;" class="hide">\
+                        </div>\
+                        <div class="clearboth"></div>\
+                    </div>\
+                    <div style="padding-top:50px;padding-bottom:8px;" align="center">\
+                        <button id="termbackup_item_cancel" class="btn_normal_short">取消</button>\
+                        <button id="termbackup_item_save"\
+                            class="btn_normal_short btn_disabled margin-left-20">保存</button>\
+                    </div>\
+                </div>\
+                <div class="table_bottom"></div>\
+            </div>\
+        </div>\
+    </div>\
+    <div style="height:40px;">&nbsp;</div>';
+
+    $("#rightpagearea").prepend(page);
+    if (typeof contextRenderPage == "function") {
+        beforeRenderPage("context");
+        contextRenderPage();
+        afterRenderPage("context");
+    }
+}
+
+var contextController = (function() {
+
+    var CONST = {
+        SWITCH_ON: '1',
+        PROFILE_MAX_NUM: 100
+    };
+    
+    var terinalListCount = 0;
+    var isNewConfig = true;
+
+    var modifyIndex = -1;
+    var profilesArray = [];
+    var modifyProfile = {};
+
+    function loadData(flag) {
+        let req = new Request();
+        req.filter1 = 0;
+        req.filter2 = 0;
+        req.filter3 = 0;
+        req.filter4 = '';
+
+        profilesArray = [];
+        termbackuplistCount = 0;
+
+        if(typeof flag === 'undefined') {
+            utilStartSubmitDialog();
+        }
+        RVC.CenterSettingEntity.GetTerminalBackupInfoList(req, function(ret) {
+            if(typeof flag === 'undefined'){
+                utilStopSubmitDialog();
+            }
+            console.log('result: ' + ret.errorCode);
+            if (ret.errorCode === 0) {
+                let result = JSON.parse(ret[RVC.CenterSettingEntity.sigResponseUUID])
+                console.log('count: ' + result.index.length + ' ' + result);
+
+                if (result.index.length === 0) {
+                    $('#termbackup_lists').css('height', 0);
+                    $('#termbackup_lists').hide();
+                    return;
+                } else if (result.index.length <= 8) {
+                    $('#termbackup_lists').css('height', (result.index.length * 70 - 12) + result.index.length + 'px');
+                } else {
+                    $('#termbackup_lists').css('height', '561px');
+                }
+                $('#termbackup_lists').show();
+                $('#termbackup_lists').empty();
+                RVC.Scroll.initScroll('#termbackup_lists');
+
+                for (var n = 0; n < result.index.length; n++)
+                {
+                    console.log('profileItemIndex: ' + result.index[n]);
+                    console.log('profileItemName: ' + result.remark[n]);
+                    console.log('profileItemMainUrl: ' + result.terminalNo[n]);
+                    console.log('profileItemAdUrl: ' + result.branchIP[n]);
+                    console.log('profileItemEnvType: ' + result.env[n]);
+                    console.log('profileItemStatus: ' + result.status[n]);
+
+                    var templateData = {
+                        profileItemIndex: result.index[n],
+                        profileItemName: result.remark[n],
+                        profileItemMainUrl: result.terminalNo[n],
+                        profileItemAdUrl: result.branchIP[n],
+                        profileItemEnvType: result.env[n],
+                        profileItemStatus: result.status[n]
+                    };
+                    profilesArray.push(templateData);
+
+                    var profileHtml;
+                    if (n === result.index.length - 1) {
+                        profileHtml = '<div  id="termbackup_list_{{profileItemIndex}}" style="height:59px;cursor:pointer;" class="list_item_hover">';
+                        profileHtml += '<div id="termbackup_list_name_{{profileItemIndex}}"  class="pull-left padding-left-20" style="height:45px;padding-top:14px;width:600px;" onclick="RVC.TerminalBackupConfigController.ShowTerminalBkInfo({{profileItemIndex}})">';
+                    } else {
+                        profileHtml = '<div  id="termbackup_list_{{profileItemIndex}}" class="border_bottom list_item_hover" style="height:70px;cursor:pointer;">';
+                        profileHtml += '<div id="termbackup_list_name_{{profileItemIndex}}"  class="pull-left padding-left-20" style="height:56px;padding-top:14px;width:600px;" onclick="RVC.TerminalBackupConfigController.ShowTerminalBkInfo({{profileItemIndex}})">';
+                    }
+                    if (templateData.profileItemStatus === 1) { //当前使用
+                        profileHtml += '<pre class="termbackup_profile_name_{{profileItemIndex}}" style="font-size:16px;margin-top:0px;"><span class="termbackup_profile_itemname pull-left" style="line-height:21px;" title="{{profileItemName}}">{{profileItemName}}</span><span class="pull-left" style="line-height:21px;">(当前使用)</span><div class="clearboth"></div></pre>';
+                    } else {
+                        profileHtml += '<pre class="termbackup_profile_name_{{profileItemIndex}}" style="font-size:16px;margin-top:0px;"><span class="termbackup_profile_itemname" title="{{profileItemName}}">{{profileItemName}}</span></pre>';
+                    }
+                    profileHtml += '<div class="termbackup_termbackup_name_{{profileItemIndex}} color_descroption_gray termbackup_profile_itemapnname" style="margin-top:-10px;font-size:14px;" title="{{profileItemMainUrl}}&nbsp;|&nbsp;{{profileItemAdUrl}}">{{profileItemMainUrl}}&nbsp;|&nbsp;{{profileItemAdUrl}}</div></div>';
+                    if (templateData.profileItemStatus === 1 || templateData.profileItemStatus === 2) { //当前正在使用
+                        profileHtml += '<div class="pull-right"></div></div>';
+                    } else {
+                        if (n === 0) {
+                            profileHtml += '<div class="pull-right"><div class="btn_delete mobileconnet_btn_delete" onclick="RVC.TerminalBackupConfigController.RemoveTerminalBkProfile({{profileItemIndex}})" >&nbsp;</div></div></div>';
+                        } else {
+                            profileHtml += '<div class="pull-right"><div class="btn_delete mobileconnet_btn_delete" onclick="RVC.TerminalBackupConfigController.RemoveTerminalBkProfile({{profileItemIndex}})" >&nbsp;</div></div></div>';
+                        }
+                    }
+                    $('#termbackup_lists .scroll_text').secureAppend(profileHtml, templateData);
+                }
+                termbackuplistCount = result.index.length;
+
+            } else if(typeof flag === 'undefined') {
+                RVC.CenterSettingEntity.commErrorCallback(ret);
+            }
+        });
+    }
+
+    
+    function preShowTermBkList()
+    {
+        $('#termbackup_lists').show();
+        $('#termbackup_lists').empty();
+        RVC.Scroll.initScroll('#termbackup_lists');
+    }
+
+    function termbkProfileCancel() {
+        $('#add_termbackup_item_win').hide();
+        $('#submit_fade').hide();
+    }
+
+    function saveTerminalBkProfileData(newConfig)
+    {
+        if (!isButtonEnable('termbackup_item_save')) {
+            return;
+        }
+
+        var mainUrl = xss($.trim($('#termbackup_terminalno').val()));
+        var adUrl = xss($.trim($('#termbackup_branch_ip').val()));
+        var remark = xss($.trim($('#input_remark').val()));
+
+        var isSetDefault = $('#termbackup_list_input_set_default').hasClass('check_on') ? true : false;
+        var envType = parseInt($('#termbackup_env').val());
+        var index = parseInt($('#termbackup_url_profile_index').val());
+
+        if(mainUrl === '') {
+            utilStartAlertDialog('请输入终端号!');
+            return;
+        }
+        if(adUrl === '') {
+            utilStartAlertDialog('请输入分行服务IP地址!');
+            return;
+        }
+
+        let req = new Request();
+        if(newConfig) {
+            req.operation = 1;
+            req.index = 0;
+        } else {
+            req.operation = 3;
+            req.index = index;
+        }
+        req.terminalNo = mainUrl;
+        req.branchIP = adUrl;
+        req.remark = remark;
+        req.env = envType;
+        req.setDefault = isSetDefault;
+
+        utilStartSubmitDialog();
+        RVC.CenterSettingEntity.EditTerminalBackupInfo(req, function(ret) {
+            utilStopSubmitDialog();
+            if (ret.errorCode === 0) {
+                let result = JSON.parse(ret[RVC.CenterSettingEntity.sigResponseUUID])
+                if(req.setDefault && (result.result === 0 || result.result === 519)) {
+                    termbkProfileCancel();
+                    if(result.addition !== 0) {
+                        console.log('需要更新集中配置!');
+                        var tips = '即将从新服务器IP ' + adUrl + ' 下载集中配置';
+                        utilShowToast(tips, 3000, function() {
+                            utilStartSubmitDialog();
+                            let req2 = new Request();
+                            req2.operation = 0;
+                            req2.strAddr = adUrl;
+                            req2.nPort = 6024;
+                            req2.deleteIfExist = true;
+                            if(result.result === 0){
+                                req2.additional1 = mainUrl;
+                            } else { 
+                                req2.additional1 = ''; 
+                            }
+                            req2.additional2 = ''; 
+                            req2.additional3 = ''; 
+                            req2.additional4 = ''; 
+                            req2.reserved1 = 0; 
+                            req2.reserved2 = 0;
+                            RVC.CenterSettingEntity.DownloadCenterFiles(req2, function(ret1) {
+                                utilStopSubmitDialog();
+                                if (ret1.errorCode === 0) {
+                                    utilStartAlertDialog('集中配置下载成功,点击确认以【重启应用】', function(){
+                                        RVC.HealthmanagerEntityCtrl.RestartApp(true);
+                                    });
+                                } else {
+                                    if(result.result === 0) {
+                                        utilStartConfirmDialog('尝试从' + adUrl + '下载集中配置失败 ' + ErrorCodeStringfy(ret1.errorCode) + ',请稍后在重启后手动下载!<br/>因终端号有更新,建议点击确认以重启应用', function(){
+                                            RVC.HealthmanagerEntityCtrl.RestartApp(true);
+                                        }, function() {
+                                            utilShowToast('重启取消,即将刷新列表(终端号已变更,列表部分信息不准确!)', 1500, function(){
+                                                preShowTermBkList();
+                                                loadData();
+                                            });
+                                        });
+                                    } else {
+                                        utilStartAlertDialog('尝试从' + adUrl + '下载集中配置失败 ' + ErrorCodeStringfy(ret1.errorCode) + ',请稍后自行手动下载!', function() {
+                                            utilShowToast('重启取消,即将刷新列表', 1500, function() {
+                                                preShowTermBkList();
+                                                loadData();
+                                            });
+                                        });
+                                    }
+                                }
+                            });
+                        });
+                    } else if(result.result === 519) {
+                        utilShowToast('检测到与当前的配置一致!', 2000, function() {
+                            preShowTermBkList();
+                            loadData();
+                        });
+                    } else {
+                        utilStartConfirmDialog('终端号已更换,点击确认以【重启应用】!', function() {
+                            RVC.HealthmanagerEntityCtrl.RestartApp(true);
+                        }, function() {
+                            utilShowToast('重启取消,即将刷新列表(终端号已变更,列表信息部分不准确!)', 1500, function(){
+                                preShowTermBkList();
+                                loadData();
+                            });
+                        });
+                    }
+                } else if(result.result === 0) {
+                    utilStartAlertDialog('操作成功!', function() {
+                        preShowTermBkList();
+                        loadData();
+                    });
+                } 
+                else {
+                    if(newConfig) {
+                        utilStartAlertDialog('添加失败:' + result.msg);
+                    } else {
+                        utilStartAlertDialog('更新失败:' + result.msg);
+                    }
+                }
+                
+            } else {
+                RVC.CenterSettingEntity.commErrorCallback(ret);
+            }
+        });
+    }
+
+    function checkboxDisabled(id) {
+        var checkElement = $('#' + id);
+        if (checkElement.hasClass('check_on') && checkElement.hasClass('disabled')) {
+            checkElement.removeClass('check_on').addClass('check_on_disable').addClass('check_on');
+        } else {
+            checkElement.removeClass('check_on_disable');
+        }
+        if (checkElement.hasClass('check_off') && checkElement.hasClass('disabled')) {
+            checkElement.removeClass('check_off').addClass('check_off_disable').addClass('check_off');
+        } else {
+            checkElement.removeClass('check_off_disable');
+        }
+    }
+
+    function showTerminalBkBox() {
+        clearAllErrorMsg();
+        $('#termbackup_item_save').addClass('btn_disabled');
+        var outwin = $('#add_termbackup_item_win');
+        checkboxDisabled('termbackup_list_input_set_default');
+        var heightest = $(document).height();
+        $('#submit_fade').css('height', heightest + 'px');
+        $('#submit_fade').show();
+        outwin.show();
+    }
+
+    function setDefaultTeminalBkSwitch() {
+        if ($('#termbackup_list_input_set_default').hasClass('disabled')) {
+            return;
+        }
+        $('#termbackup_item_save').removeClass('btn_disabled');
+        if ($('#termbackup_list_input_set_default').hasClass('check_on')) {
+            $('#termbackup_list_input_set_default').removeClass('check_on').addClass('check_off');
+        } else {
+            $('#termbackup_list_input_set_default').removeClass('check_off').addClass('check_on');
+        }
+        if ($('#termbackup_list_input_set_default').hasClass('check_off')) {
+            $('#termbackup_item_save').addClass('btn_disabled');
+        }
+    }
+
+    function ResetTerminalBackupInfoShowDialog()
+    {
+        $('#termbackup_url_profile_index').val('');
+        $('#add_termbackup_item_win input').val('');
+        $('#add_termbackup_item_win input').removeAttr('disabled');
+        $('#add_termbackup_item_win .select_on_normal').removeClass('disabled');
+    }
+
+    RVC.TerminalBackupConfigController = RVC.ObjController.extend({
+
+        ShowTerminalBkInfo: function(index) {
+            modifyIndex = index;
+            var termbackupUrlShowItem = {};
+            for (var i = 0; i < profilesArray.length; i++) {
+                if (profilesArray[i].profileItemIndex === index) {
+                    termbackupUrlShowItem = profilesArray[i];
+                    break;
+                }
+            }
+            /**
+            profileItemIndex: result.index[n],
+            profileItemName: result.remark[n],
+            profileItemMainUrl: result.futureUrl[n],
+            profileItemAdUrl: result.adUrl[n],
+            profileItemEnvType: result.env[n],
+            profileItemFromType: result.type[n],
+            profileItemStatus: result.status[n]
+             */
+
+            ResetTerminalBackupInfoShowDialog();
+
+            modifyProfile = termbackupUrlShowItem;
+            $('#termbackup_url_profile_index').val(termbackupUrlShowItem.profileItemIndex.toString());
+            $('#termbackup_terminalno').val(termbackupUrlShowItem.profileItemMainUrl);
+            $('#termbackup_branch_ip').val(termbackupUrlShowItem.profileItemAdUrl);
+            $('#input_remark').val(termbackupUrlShowItem.profileItemName);
+
+            if (termbackupUrlShowItem.profileItemStatus === 1) { //默认配置
+                $('#termbackup_list_input_set_default').removeClass('check_off').addClass('check_on');
+                $('#termbackup_list_input_set_default').addClass('disabled');
+            } else {
+                $('#termbackup_list_input_set_default').removeClass('check_on').addClass('check_off');
+                $('#termbackup_list_input_set_default').removeClass('disabled');
+            }
+
+            showSelectedValue('termbackup_env', termbackupUrlShowItem.profileItemEnvType.toString());
+
+            $(document).off('click', '#termbackup_item_save');
+            $(document).on('click', '#termbackup_item_save', function () {
+                saveTerminalBkProfileData(false);
+            });
+
+            if(termbackupUrlShowItem.profileItemStatus === 1) { //当前使用的不让修改
+                $('#add_termbackup_item_win input').attr('disabled', true);
+                $('#add_termbackup_item_win .select_on_normal').addClass('disabled');
+                console.log(termbackupUrlShowItem.profileItemName);
+            }
+
+            showTerminalBkBox();
+        },
+        RemoveTerminalBkProfile: function(index)
+        {
+            utilStartConfirmDialog("确定要移除该配置吗?", function() {
+                let req = new Request();
+                req.operation = 2; //删除
+                req.index = parseInt(index);
+                req.terminalNo = '';
+                req.branchIP = '';
+                req.remark = '';
+                req.env = 0;
+                req.setDefault = false;
+
+                utilStartSubmitDialog();
+                RVC.CenterSettingEntity.EditTerminalBackupInfo(req, function(ret) {
+                    utilStopSubmitDialog();
+                    if (ret.errorCode === 0) {
+                        let result = JSON.parse(ret[RVC.CenterSettingEntity.sigResponseUUID])
+                        if(result.result == 0) {
+                            preShowTermBkList();
+                            loadData();
+                        } else {
+                            utilStartAlertDialog('删除失败:' + result.msg);
+                        }
+                    } else {
+                        RVC.CenterSettingEntity.commErrorCallback(ret);
+                    }
+                });
+            });
+        }
+
+    });
+
+    function bindEvents() {
+
+        $('#termbackup_new').click(function () {
+            $('#termbackup_select_blank').hide();
+            if (termbackuplistCount === CONST.PROFILE_MAX_NUM) {
+                utilStartCommonDialog('配置数量超过上限(' + CONST.PROFILE_MAX_NUM + '),请删除再新建!');
+                setTimeout(function () {
+                    utilStopCommonDialog();
+                }, 3000);
+                return;
+            }
+            modifyIndex = -1;
+            ResetTerminalBackupInfoShowDialog();
+            $('#termbackup_list_input_set_default').removeClass('check_off').addClass('check_on');
+            $('#termbackup_list_input_set_default').addClass('disabled');
+            showSelectedValue('termbackup_env', '1');
+            isNewTerminalBkConfig = true;
+            showTerminalBkBox();
+            $(document).off('click', '#termbackup_item_save');
+            $(document).on('click', '#termbackup_item_save', function () {
+                saveTerminalBkProfileData(true);
+            });
+            $('#termbackup_terminalno').focus();
+        });
+
+        $('#termbackup_item_cancel').click(termbkProfileCancel);
+        $(document).on('click keyup change', '#add_termbackup_item_win input', function () {
+            $('#termbackup_item_save').removeClass('btn_disabled');
+        });
+        $(document).on('change click', '#add_termbackup_item_win .select_on_normal', function () {
+            $('#termbackup_item_save').removeClass('btn_disabled');
+        });
+        $('#termbackup_list_input_set_default').click(setDefaultTeminalBkSwitch);
+
+        $('#termbackup_env').click(function () {
+            //RVC.Scroll.setTop('#add_termbackup_item_win_scroll', 200);
+        });
+    }
+
+    function initPage() 
+    {
+        preShowTermBkList();
+        loadData(true);
+
+    }
+
+    var fistTime = true;
+
+    function init() {
+
+        initPage();
+        
+        if (fistTime) {
+            fistTime = false;
+            bindEvents();
+            RVC.Scroll.initScroll('#add_termbackup_item_win_scroll');
+        }
+        
+    }
+
+    function destory() {
+        clearAllErrorMsg();
+    }
+    
+    return { init: init, destory: destory };
+}());
+
+window.contextRenderPage = function () {
+    contextController.init();
+};

+ 1 - 3
addin/res/ManagerDesktop/js/page/dns.js

@@ -37,9 +37,7 @@ function dnsGenPage() {
         </div> \
         <div id="dns_activation_content" class="page_prompt_info page_scenes_info_text hide"> \
         </div> \
-    </div> \
-    <div style="height:40px;">&nbsp;</div> \
-</div>';
+    </div></div>';
 
     $("#rightpagearea").prepend(page);
     if (typeof dnsRenderPage == "function") {

+ 1 - 3
addin/res/ManagerDesktop/js/page/initializer.js

@@ -18,9 +18,7 @@ function initializerGenPage() {
         </div>\
         <div id="initializer_activation_content" class="page_prompt_info page_scenes_info_text hide">\
         </div>\
-    </div>\
-    <div style="height:40px;">&nbsp;</div>\
-</div>';
+    </div></div>';
 
     $("#rightpagearea").prepend(page);
     if (typeof initializerRenderPage == "function") {

+ 212 - 4
addin/res/ManagerDesktop/js/page/logswitch.js

@@ -1,11 +1,12 @@
 function logswitchGenPage() {
     var page = '<div id="logswitch_page">\
-    <div id="logswitch_tip" align="center" style="display: block;">\
-    <div class="color_descroption_gray"\
-    style="width:auto;margin-top:200px;font-size:18px;line-height:120%;">\
-    <span>相关功能正在开发中,敬请期待!</span>\
+    <div class="maintitle">\
+    <div>硬件适配器日志记录管理</div>\
+    <div class="page_description_text">本地临时打开硬件适配器日志记录,方便及时排查硬件问题。有改动更新需重启应用方能生效。\
     </div>\
     </div>\
+    <div id="logswitchContent" class="hide" style="display: block;">\
+    </div>\
     </div>';
 
     $("#rightpagearea").prepend(page);
@@ -18,8 +19,215 @@ function logswitchGenPage() {
 
 var logswitchController = (function() {
 
+    var devSectionPlaceHolder = '<div id="log_switch_{{devName}}_section" class="wps_connect_way_title " style="margin-top: 40px; padding-top: 40px;">{{devSectionName}}</div>\
+    <div id="log_switch_{{devName}}_section_description" class="three_way_instruction maintitle" style="padding-bottom: 0px !important;" >&nbsp;</div>\
+    <div id="log_switch_{{devName}}_switch_div" class="clearboth" style="padding-top: 15px;">\
+        <div class="control-label" style="margin-top:3px;">\
+            <span>日志开关</span>\
+        </div>\
+        <div class="controls">\
+            <div id="log_switch_{{devName}}_switch" onclick="SwitchEx(this, RVC.VendorLogSwitchController.LogSwitch)" class="switch_on"></div>\
+        </div>\
+    </div>\
+    <div id="log_switch_{{devName}}_level" class="clearboth" style="padding-top: 15px;">\
+        <div class="control-label" style="margin-top:3px;">\
+            <span>日志等级</span>\
+        </div>\
+        <div class="controls">\
+            <div id="log_switch_{{devName}}_log_level_select_all">\
+                <div id="log_switch_{{devName}}_log_level_select" class="select_on_normal" value="0" onclick="SelectItem(this)"></div>\
+                <div id="log_switch_{{devName}}_log_level_select_list" class="select_list hide" style="display: none;">\
+                    <div id="log_switch_{{devName}}_log_level_select_list_item_fatal" option="1" class="select_medium" onclick=\"RVC.VendorLogSwitchController.LogLevelChange(this, \'1\')\">Fatal</div>\
+                    <div id="log_switch_{{devName}}_log_level_select_list_item_error" option="2" class="select_medium" onclick=\"RVC.VendorLogSwitchController.LogLevelChange(this, \'2\')\">Error</div>\
+                    <div id="log_switch_{{devName}}_log_level_select_list_item_warn" option="3" class="select_medium" onclick=\"RVC.VendorLogSwitchController.LogLevelChange(this, \'3\')\">Warn</div>\
+                    <div id="log_switch_{{devName}}_log_level_select_list_item_info" option="4" class="select_medium" onclick=\"RVC.VendorLogSwitchController.LogLevelChange(this, \'4\')\">Info</div>\
+                    <div id="log_switch_{{devName}}_log_level_select_list_item_trace" option="5" class="select_medium" onclick=\"RVC.VendorLogSwitchController.LogLevelChange(this, \'5\')\">Trace</div>\
+                </div>\
+            </div>\
+        </div>\
+    </div>';
+
+    var hardwares = [];
+
+    function SwithDevAdapterLogRecord(adapterName, record_on, record_level, failCallback)
+    {
+        let req = new Request();
+        req.configType = 7; //GlobalCache
+        req.section = 'AdapterLogSwith';
+        req.option = true; //Write
+        req.key = adapterName;
+        req.reserved1 = 0;
+        req.reserved2 = 0;
+        if(record_on) {
+            req.reserved3 = '1,' + record_level;
+        } else {
+            req.reserved3 = '0,' + record_level;
+        }
+        req.reserved4 = '';
+        RVC.DeviceControlEntityCtrl.ReadConfigValue(req, function(ret) {
+            if (ret.errorCode === 0) {
+                utilShowToast('设置成功!');
+            } else {
+                utilStartAlertDialog("设置失败! ErrorCode: " + ErrorCodeStringfy(ret.errorCode), function(){
+                    if(failCallback) {
+                        failCallback();
+                    }
+                });
+            }
+        });
+    }
+
+    RVC.VendorLogSwitchController = RVC.ObjController.extend({
+
+        LogLevelChange: function(widget, value) {
+            var thatWidget = widget;
+            var hardwareName = '';
+            for(var i=0; i<hardwares.length; ++i) {
+                if(-1 !== widget.id.indexOf(hardwares[i])) {
+                    hardwareName = hardwares[i];
+                    console.log(widget.id + " " + widget.className + ' ' + hardwareName);
+                    break;
+                }
+            }
+            if(hardwareName === '') {
+                return;
+            }
+            var switchon = true;
+            var switch_id = 'log_switch_' + hardwareName + '_switch';
+            var classlist = $('#' + switch_id).attr('class');
+            if (classlist.indexOf('switch_on') < 0) {
+                switchon = false;
+            }
+            var recordLevel = value;
+            SwithDevAdapterLogRecord(hardwareName, switchon, recordLevel);
+        },
+
+        LogSwitch: function(widget) {
+            var thatWidget = widget;
+            var switchon = false;
+            var hardwareName = '';
+            for(var i=0; i<hardwares.length; ++i) {
+                if(-1 !== widget.id.indexOf(hardwares[i])) {
+                    hardwareName = hardwares[i];
+                    console.log(widget.id + " " + widget.className + ' ' + hardwareName);
+                    break;
+                }
+            }
+            if(hardwareName === '') {
+                return;
+            }
+
+            var classlist = $(widget).attr('class');
+            if (classlist.indexOf('switch_on') >= 0) {
+                switchon = true;
+            }
+            var select_id = 'log_switch_' + hardwareName + '_log_level_select';
+            setSelectWidgetEnableState(select_id, switchon);
+
+            var recordLevel = $('#' + select_id).attr('value');
+
+            SwithDevAdapterLogRecord(hardwareName, switchon, recordLevel, function() {
+                setSelectWidgetEnableState(select_id, !switchon);
+                Switch(thatWidget);
+            });
+        }
+    });
+
+    function initEachDevLogStatus(index) {
+
+        if(index >= hardwares.length) {
+            return;
+        }
+
+        const adapterName = hardwares[index];
+        var switch_id = 'log_switch_' + adapterName + '_switch';
+        var select_id = 'log_switch_' + adapterName + '_log_level_select';
+        console.log('adapterName: ' + adapterName + ' ' + switch_id + ' ' + select_id);
+
+        let req = new Request();
+        req.configType = 7; //GlobalCache
+        req.section = 'AdapterLogSwith';
+        req.option = false;
+        req.key = adapterName;
+        req.reserved1 = 0;
+        req.reserved2 = 0;
+        req.reserved3 = '';
+        req.reserved4 = '';
+        RVC.DeviceControlEntityCtrl.ReadConfigValue(req, function(ret) {
+            if (ret.errorCode === 0) {
+                
+                var recordOn = false;
+                var recordLevel = '2';
+
+                let result = JSON.parse(ret[RVC.EntityController.sigResponseUUID])
+                console.log(adapterName + ': ' + result.value);
+                if(result.value !== '') {
+                    var values = result.value.split(',');
+                    if(values.length >= 1 && parseInt(values[0]) > 0) {
+                        recordOn = true;
+                    }
+                    if(values.length >= 2) {
+                        recordLevel = (values[1]);
+                    }
+                }
+                setSwitchState(switch_id, recordOn);
+                showSelectedValue(select_id, recordLevel);
+                setSelectWidgetEnableState(select_id, recordOn);
+                //setSwitchEnableState(switch_id, true);
+                //setSelectWidgetEnableState(select_id, true);
+
+            } else {
+                setSwitchEnableState(switch_id, false);
+                setSelectWidgetEnableState(select_id, false);
+            }
+
+            initEachDevLogStatus(index+1);
+        });
+    }
+
     function initPage() {
+        for (var i = 0; i < gMenu.length; i++) {
+            var menuitems = gMenu[i];
+            var hash = menuitems.pagename;
+            if(hash === 'hardwareconfig') {
+                if (menuitems.submenus) {
+                    var subitems = menuitems.submenus;
+                    for(var j = 0; j < subitems.length; j++) {
+                        hash = subitems[j].pagename;
+                        if(hash === 'adapters') {
+                            if (typeof subitems[j].submenus !== 'undefined') {
+                                var thrditems = subitems[j].submenus;
+                                for(var k = 0; k <thrditems.length; ++k) {
+                                    hash = subitems[j].submenus[k].pagename;
+                                    hardwares.push(hash);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        for(var i=0; i<hardwares.length; ++i) {
+            console.log('hash1: ' + hardwares[i]);
+            var templateData = {
+                devName: hardwares[i],
+                devSectionName: gMenuDisplayName[hardwares[i]]
+            };
+            $('#logswitchContent').secureAppend(devSectionPlaceHolder, templateData);
+            
+        }
 
+        setTimeout(function () {
+            // for(var i=0; i<hardwares.length; ++i) {
+            //     const adapterName = hardwares[i];
+            //     var switch_id = 'log_switch_' + adapterName + '_switch';
+            //     var select_id = 'log_switch_' + adapterName + '_log_level_select';
+            //     setSwitchEnableState(switch_id, false);
+            //     setSelectWidgetEnableState(select_id, false);
+            // }
+            initEachDevLogStatus(0);
+        }, 500);
     }
 
     var fistTime = true;

+ 1 - 3
addin/res/ManagerDesktop/js/page/reset.js

@@ -18,9 +18,7 @@ function resetGenPage() {
         </div>\
         <div id="reset_activation_content" class="page_prompt_info page_scenes_info_text hide">\
         </div>\
-    </div>\
-    <div style="height:40px;">&nbsp;</div>\
-</div>';
+    </div></div>';
 
     $("#rightpagearea").prepend(page);
     if (typeof resetRenderPage == "function") {

+ 357 - 3
addin/res/ManagerDesktop/js/public.js

@@ -390,6 +390,18 @@ function _recursiveXml2Object($xml) {
 }
 
 var beforeselectid = '';
+
+function setSelectWidgetEnableState(select_id, enable)
+{
+    if (!$('#' + select_id).hasClass('disabled') && !enable) {
+        $('#' + select_id).addClass('disabled');
+        $('#' + select_id).removeClass('select_on_normal').addClass('select_off_normal');
+    } else if ($('#' + select_id).hasClass('disabled') && enable){
+        $('#' + select_id).removeClass('disabled');
+        $('#' + select_id).removeClass('select_off_normal').addClass('select_on_normal');
+    }
+}
+
 function SelectItem(obj) {
     var normalselect = {
         select_top: 'select_top',
@@ -493,6 +505,36 @@ function xml2object($xml) {
     return obj;
 }
 
+function setSwitchEnableState(switch_id, enable) {
+    var classlist = $('#' + switch_id).attr('class');
+    if (classlist.indexOf('switch_on') >= 0) {
+        if (!$('#' + switch_id).hasClass('disabled') && !enable) {
+            $('#' + switch_id).addClass('disabled');
+            $('#' + switch_id).removeClass('switch_on').addClass('switch_on_disable');
+        } else if ($('#' + switch_id).hasClass('disabled') && enable){
+            $('#' + switch_id).removeClass('disabled');
+            $('#' + switch_id).removeClass('switch_on_disable').addClass('switch_on');
+        }
+    } else if(classlist.indexOf('switch_off') >= 0) {
+        if (!$('#' + switch_id).hasClass('disabled') && !enable) {
+            $('#' + switch_id).addClass('disabled');
+            $('#' + switch_id).removeClass('switch_off').addClass('switch_off_disable');
+        } else if ($('#' + switch_id).hasClass('disabled') && enable){
+            $('#' + switch_id).removeClass('disabled');
+            $('#' + switch_id).removeClass('switch_off_disable').addClass('switch_off');
+        }
+    }
+}
+
+function setSwitchState(switch_id, on) {
+    var classlist = $('#' + switch_id).attr('class');
+    if (classlist.indexOf('switch_on') >= 0 && !on) {
+        $('#' + switch_id).addClass('switch_off').removeClass('switch_on');
+    } else if (classlist.indexOf('switch_off') >= 0 && on){
+        $('#' + switch_id).addClass('switch_on').removeClass('switch_off');
+    }
+}
+
 function Switch(obj, callback) {
     var classlist = $(obj).attr('class');
     if (classlist.indexOf('switch_on') >= 0) {
@@ -505,6 +547,13 @@ function Switch(obj, callback) {
     }
 }
 
+function SwitchEx(obj, callback) {
+    Switch(obj);
+    if(callback) {
+        callback(obj);
+    }
+}
+
 function checkbox(obj, callback) {
     var classlist = $(obj).attr('class');
     if (classlist.indexOf('check_on') >= 0) {
@@ -1587,6 +1636,207 @@ $(function () {
         }
     });
 
+    RVC.ObjController = RVC.Object.extend({
+        objName: '',
+        cloneObject: function (obj) {
+            return cloneObject(obj);
+        },
+        compareObject: function (obj1, obj2) {
+            return compareObject(obj1, obj2);
+        },
+        utf8Encode: function (string) {
+            var stringTemp = string.replace(/\r\n/g, '\n');
+            var utftext = '';
+            for (var n = 0; n < stringTemp.length; n++) {
+                var charStr = stringTemp.charCodeAt(n);
+                if (charStr < 128) {
+                    utftext += String.fromCharCode(charStr);
+                } else if ((charStr > 127) && (charStr < 2048)) {
+                    utftext += String.fromCharCode((charStr >> 6) | 192);
+                    utftext += String.fromCharCode((charStr & 63) | 128);
+                } else {
+                    utftext += String.fromCharCode((charStr >> 12) | 224);
+                    utftext += String.fromCharCode(((charStr >> 6) & 63) | 128);
+                    utftext += String.fromCharCode((charStr & 63) | 128);
+                }
+            }
+            return utftext;
+        },
+        base64encode: function (str) {
+            var keyStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
+            var outputStr = '';
+            var char1;
+            var char2;
+            var char3;
+            var encry1;
+            var encry2;
+            var encry3;
+            var encry4;
+            var i = 0;
+            var input = this.utf8Encode(str);
+            while (i < input.length) {
+                char1 = input.charCodeAt(i++);
+                char2 = input.charCodeAt(i++);
+                char3 = input.charCodeAt(i++);
+                encry1 = char1 >> 2;
+                encry2 = ((char1 & 3) << 4) | (char2 >> 4);
+                encry3 = ((char2 & 15) << 2) | (char3 >> 6);
+                encry4 = char3 & 63;
+                if (isNaN(char2)) {
+                    encry3 = encry4 = 64;
+                } else if (isNaN(char3)) {
+                    encry4 = 64;
+                }
+                outputStr += keyStr.charAt(encry1) + keyStr.charAt(encry2) + keyStr.charAt(encry3) + keyStr.charAt(encry4);
+            }
+            return outputStr;
+        },
+        utf16to8: function (str) {
+            var output, i, leng, unic;
+            output = "";
+            leng = str.length;
+            for (i = 0; i < leng; i++) {
+                unic = str.charCodeAt(i);
+                if ((unic >= 0x0001) && (unic <= 0x007F)) {
+                    output += str.charAt(i);
+                } else if (unic > 0x07FF) {
+                    output += String.fromCharCode(0xE0 | ((unic >> 12) & 0x0F));
+                    output += String.fromCharCode(0x80 | ((unic >> 6) & 0x3F));
+                    output += String.fromCharCode(0x80 | ((unic >> 0) & 0x3F));
+                } else {
+                    output += String.fromCharCode(0xC0 | ((unic >> 6) & 0x1F));
+                    output += String.fromCharCode(0x80 | ((unic >> 0) & 0x3F));
+                }
+            }
+            return output;
+        },
+        utf8to16: function (str) {
+            var output, i, leng, unic;
+            var char1, char2;
+            output = "";
+            leng = str.length;
+            i = 0;
+            while (i < leng) {
+                unic = str.charCodeAt(i++);
+                switch (unic >> 4) {
+                    case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
+                        output += str.charAt(i - 1);
+                        break;
+                    case 12: case 13:
+                        char1 = str.charCodeAt(i++);
+                        output += String.fromCharCode(((unic & 0x1F) << 6) | (char1 & 0x3F));
+                        break;
+                    case 14:
+                        char1 = str.charCodeAt(i++);
+                        char2 = str.charCodeAt(i++);
+                        output += String.fromCharCode(((unic & 0x0F) << 12) |
+                            ((char1 & 0x3F) << 6) |
+                            ((char2 & 0x3F) << 0));
+                        break;
+                }
+            }
+            return output;
+        },
+        object2xml: function (name, obj) {
+            var xmlstr = '<?xml version="1.0" encoding="UTF-8"?>';
+            xmlstr += this.recursiveObject2Xml(name, obj);
+            return xmlstr;
+        },
+        xml2object: function ($xml) {
+            var obj = {};
+            if ($xml.find('response').size() > 0) {
+                var _response = this.recursiveXml2Object($xml.find('response'));
+                obj.type = 'response';
+                obj.response = _response;
+            } else if ($xml.find('error').size() > 0) {
+                var _code = $xml.find('code').text();
+                var _message = $xml.find('message').text();
+                obj.type = 'error';
+                obj.error = {
+                    code: _code,
+                    message: _message
+                };
+                if ($xml.find('remaincount').text()) {
+                    obj.error.remaincount = $xml.find('remaincount').text();
+                }
+                if ($xml.find('waittime').text()) {
+                    obj.error.waittime = $xml.find('waittime').text();
+                }
+                if ($xml.find('tobelockedtime').text()) {
+                    obj.error.tobelockedtime = $xml.find('tobelockedtime').text();
+                }
+            } else if ($xml.find('config').size() > 0) {
+                var _config = this.recursiveXml2Object($xml.find('config'));
+                obj.type = 'config';
+                obj.config = _config;
+            } else {
+                obj.type = 'unknown';
+            }
+            return obj;
+        },
+        createNodeStr: function (nodeName, nodeValue) {
+            return '<' + nodeName + '>' + nodeValue + '</' + nodeName + '>';
+        },
+        recursiveXml2Object: function ($xml) {
+            var self = this;
+            if ($xml.children().size() > 0) {
+                var _obj = {};
+                $xml.children().each(function () {
+                    var _childObj = ($(this).children().size() > 0) ? self.recursiveXml2Object($(this)) : $(this).text();
+                    if ($(this).siblings().size() > 0 && $(this).siblings().get(0).tagName === this.tagName) {
+                        if (typeof _obj[this.tagName] === 'undefined' || _obj[this.tagName] === null) {
+                            _obj[this.tagName] = [];
+                        }
+                        _obj[this.tagName].push(_childObj);
+                    } else {
+                        _obj[this.tagName] = _childObj;
+                    }
+                });
+                return _obj;
+            }
+            return $xml.text();
+        },
+        recursiveObject2Xml: function (name, obj) {
+            var xmlstr = '';
+            var self = this;
+            if (typeof (obj) === 'string' || typeof (obj) === 'number') {
+                xmlstr = this.createNodeStr(name, obj);
+            } else if (jQuery.isArray(obj)) {
+                jQuery.each(obj, function (idx, item) {
+                    xmlstr += self.recursiveObject2Xml(name, item);
+                });
+            } else if (typeof (obj) === 'object') {
+                if (obj === null) {
+                    return '';
+                }
+                xmlstr += '<' + name + '>';
+                $.each(obj, function (propName, propVal) {
+                    xmlstr += self.recursiveObject2Xml(propName, propVal);
+                });
+                xmlstr += '</' + name + '>';
+            }
+            return xmlstr;
+        },
+        clearAllErrorLabel: function () {
+            clearAllErrorMsg();
+        },
+        checkVisibleChar: function (str) {
+            var numCharStr;
+            if (str === '') {
+                return true;
+            }
+            for (var i = 0; i < str.length; i++) {
+                numCharStr = str.charCodeAt(i);
+                if ((numCharStr > MACRO_SUPPORT_CHAR_MAX) || (numCharStr < MACRO_SUPPORT_CHAR_MIN)) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+    });
+
+
     RVC.EntityController = RVC.Object.extend({
         entityName:'',
         className: '',
@@ -1909,6 +2159,50 @@ $(function () {
                     RVC.HealthmanagerEntityCtrl.commErrorCallback(ret);
                 }
             });
+        },
+        StartEntity: function (entityName, preInvokeCallback, sucCallback, failCallback)
+        {
+            let req = new Request();
+            req.option = 1; //启动实体
+            req.additional = 0;
+            req.devId = 0;
+            req.entityName = entityName;
+            req.force = true;
+            req.param = '';
+            req.reserved1 = 0;
+            req.reserved2 = '';
+            req.timeout = 60000;
+
+            if(preInvokeCallback) {
+                preInvokeCallback();
+            }
+
+            this.ControlEntityLife(req, function(ret) {
+                console.log('control life:' + ret.errorCode);
+                if(ret.errorCode === 0) {
+                    let result = JSON.parse(ret[RVC.EntityController.sigResponseUUID])
+                    console.log('control life:' + result.result);
+                    if(result.result == 0) {
+                        if(sucCallback) {
+                            utilShowToast("启动模块" + entityName + "成功!", 2000, function(){
+                                sucCallback();
+                            });
+                        }
+                    } else {
+                        utilShowToast("启动模块" + entityName + "失败:[" + result.result + "] " + result.msg, 5000, function(){
+                            if(failCallback) {
+                                failCallback();
+                            }
+                        });
+                    }
+                } else {
+                    utilShowToast("请求失败:" + ErrorCodeStringfy(ret.errorCode), function() {
+                        if(failCallback) {
+                            failCallback();
+                        }
+                    });
+                }
+            });
         }
     });
 
@@ -1943,9 +2237,71 @@ $(function () {
         }
     });
 
+    RVC.CenterSettingEntity = RVC.EntityController.extend({
+        entityName: 'CenterSetting',
+        className: 'CenterSettingService',
+        methodID: {
+            Download: 0,
+            GetSyncInfo: 1,
+            EditWebUrl: 2,
+            GetWebUrlList:3,
+            GetActiveCustomUrl:4,
+            EditTerminalBackupInfo:5,
+            GetTerminalBackupInfoList:6,
+            DownloadCenterFiles:7
+        },
+        methodSignature: {
+            Download: -101852141,
+            GetSyncInfo: 1338819403,
+            EditWebUrl: 112159607,
+            GetWebUrlList:166192532,
+            GetActiveCustomUrl:-2094137460,
+            EditTerminalBackupInfo:-1684426310,
+            GetTerminalBackupInfoList:652072921,
+            DownloadCenterFiles:1100121901
+
+        },
+
+        Download: function(req, callback) {
+            this.webSocketInvokeEx(req, 
+                ({id:this.methodID.Download, sig:this.methodSignature.Download}),
+                 callback);
+        },
+        GetSyncInfo: function(req, callback) {
+            this.webSocketInvokeEx(req, 
+                ({id:this.methodID.GetSyncInfo, sig:this.methodSignature.GetSyncInfo}),
+                 callback);
+        },
+        EditWebUrl: function(req, callback) {
+            this.webSocketInvokeEx(req, 
+                ({id:this.methodID.EditWebUrl, sig:this.methodSignature.EditWebUrl}),
+                 callback);
+        },
+        GetWebUrlList: function(req, callback) {
+            this.webSocketInvokeEx(req, 
+                ({id:this.methodID.GetWebUrlList, sig:this.methodSignature.GetWebUrlList}),
+                 callback);
+        },
+        EditTerminalBackupInfo: function(req, callback) {
+            this.webSocketInvokeEx(req, 
+                ({id:this.methodID.EditTerminalBackupInfo, sig:this.methodSignature.EditTerminalBackupInfo}),
+                 callback);
+        },
+        GetTerminalBackupInfoList: function(req, callback) {
+            this.webSocketInvokeEx(req, 
+                ({id:this.methodID.GetTerminalBackupInfoList, sig:this.methodSignature.GetTerminalBackupInfoList}),
+                 callback);
+        },
+        DownloadCenterFiles: function(req, callback) {
+            this.webSocketInvokeEx(req, 
+                ({id:this.methodID.DownloadCenterFiles, sig:this.methodSignature.DownloadCenterFiles}),
+                 callback);
+        }
+    });
+
     RVC.DeviceControlEntityCtrl.init();
     RVC.HealthmanagerEntityCtrl.init();
-
+    RVC.CenterSettingEntity.init();
 });
 
 function quitThisPage() {
@@ -2135,7 +2491,6 @@ function showSelectedValue(selectid, selectval) {
         var selectitem = $(selectitems[loop]);
         var selectvalue = selectitem.attr('option') || selectitem.find('span').attr('option');
         var description = selectitem.text() || selectitem.find('span').text();
-        var selectlangid = selectitem.attr('lang-id') || selectitem.find('span').attr('lang-id') || '';
         if (selectval === selectvalue) {
             if (selectparent[0].localName !== 'input' && selectparent[0].localName !== 'textarea') {
                 selectparent.attr('value', selectval);
@@ -2143,7 +2498,6 @@ function showSelectedValue(selectid, selectval) {
                 selectparent.val(selecthtml);
             }
             selectparent.text(description);
-            selectparent.attr('lang-id', selectlangid);
             break;
         }
     }

+ 310 - 0
addin/res/ManagerDesktop/prototype/context.html

@@ -0,0 +1,310 @@
+<html id="html">
+
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>可视柜台终端管理</title>
+    <meta name="viewport"
+        content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
+    <meta name="description" content="default">
+    <meta name="author" content="default">
+    <link type="text/css" rel="stylesheet" href="../css/emui-style.css">
+    <script type="text/javascript" src="../Include/LsyCookie.js"></script>
+    <script type="text/javascript" src="../js/errorCodeEnum.js"></script>
+    <script type="text/javascript" src="../js/common.js"></script>
+    <script type="text/javascript" src="../js/termbackupsocket.js"></script>
+    <script type="text/javascript" src="../js/termbackupSocketBase.js"></script>
+    <script type="text/javascript" src="../js/entityMessage.js"></script>
+    <script type="text/javascript" src="../js/eventEmitter.js"></script>
+    <script type="text/javascript" src="../js/innerEventEmitter.js"></script>
+    <script type="text/javascript" src="../js/entityService.js"></script>
+    <script type="text/javascript" src="../Include/jQuery/js/emui-jquery.min.js"></script>
+    <script type="text/javascript" src="../js/public.js"></script>
+    <script type="text/javascript">
+        $(document).ready(function () {
+            var headerHeight = $(".header div.logo img").height();
+            $(".header").height(headerHeight);
+        });
+    </script>
+</head>
+
+<body style="display: block;">
+    <div id="preLoadEyeImg">
+        <div class="ic_guide_eye_open" style="opacity:0;height:0;margin:0"></div>
+        <div class="ic_eye_open" style="opacity:0;height:0;margin:0"></div>
+    </div>
+    <div>
+        <div class="headcontainer">
+            <div class="header" style="height: 38px;">
+                <div class="pull-left">
+                    <div class="logo pull-left"><img src="images/logo_cmb.png"> &nbsp;</div>
+                    <div class="pull-left devicename" id="deicename">&nbsp;</div>
+                </div>
+                <div id="header_right" class="pull-right">
+                    <table class="pull-right" cellpadding="0" cellspacing="0" frame="void" rules="none">
+                        <tbody>
+                            <tr>
+                                <td id="header_upgrade_info" style="width:52px;" align="center">
+                                    <div title="版本更新" style="position: relative;" class="ic_update_normal"
+                                        onclick="test();">
+                                    </div>
+                                </td>
+                                <td style="width:52px;" align="center" id="loginallowed_btn">
+                                    <div title="重启应用" class="ic_reboot"
+                                        onclick="RVC.HealthmanagerEntityCtrl.RestartApp();"></div>
+                                </td>
+                                <td style="width:52px;" align="center">
+                                    <div title="设备关机" class="ic_poweroff"
+                                        onclick="RVC.HealthmanagerEntityCtrl.PowerOffPC();"></div>
+                                </td>
+                                <td style="width:52px;border-left: 2px solid #A9A9A9;" align="center" id="quitpage_btn">
+                                    <div title="退出页面" class="ic_signout" onclick="quitThisPage();"></div>
+                                </td>
+                            </tr>
+                        </tbody>
+                    </table>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div class="clearboth"></div>
+    <div id="topmenucontainer" class="border_top border_bottom color_background_blue"
+        style="height:76px;font-size:18px;">
+        <table style="border-spacing:0px;border-collapse:collapse;width:1000px;margin:0 auto;left:0px;">
+            <tbody>
+                <tr>
+                    <td class="topmenu selectmenu" id="menu_home" onclick="selectPage('home')"><span id="ic_home_icon"
+                            style="display:inline-block;vertical-align: middle;margin-right:5px;"
+                            class="ic_home_selected">&nbsp;</span><span id="menu_top_home"
+                            style="display:inline-block;vertical-align: middle;" class="topmenu_selected">首页</span></td>
+                    <td class="topmenu color_Darkgray" id="menu_terminalmanagement"
+                        onclick="selectPage('terminalmanagement')">
+                        <span id="ic_terminalmanagement_icon"
+                            style="display:inline-block;vertical-align: middle;margin-right:5px;"
+                            class="ic_terminalmanagement">&nbsp;</span><span id="menu_top_terminalmanagement"
+                            style="display:inline-block;vertical-align: middle;" class="topmenu_normal">终端管理</span>
+                    </td>
+                    <td class="topmenu color_Darkgray" id="menu_networkmanagement"
+                        onclick="selectPage('networkmanagement')"><span id="ic_networkmanagement_icon"
+                            style="display:inline-block;vertical-align: middle;margin-right:5px;"
+                            class="ic_networkmanagement">&nbsp;</span><span id="menu_top_networkmanagement"
+                            style="display:inline-block;vertical-align: middle;" class="topmenu_normal">网络连接</span></td>
+                    <td class="topmenu color_Darkgray" id="menu_hardwareconfig" onclick="selectPage('hardwareconfig')">
+                        <span id="ic_hardwareconfig_icon"
+                            style="display:inline-block;vertical-align: middle;margin-right:5px;"
+                            class="ic_hardwareconfig">&nbsp;</span><span id="menu_top_hardwareconfig"
+                            style="display:inline-block;vertical-align: middle;" class="topmenu_normal">硬件管理</span>
+                    </td>
+                    <td class="topmenu color_Darkgray" id="menu_mediacontrol" onclick="selectPage('mediacontrol')"><span
+                            id="ic_mediacontrol_icon"
+                            style="display:inline-block;vertical-align: middle;margin-right:5px;"
+                            class="ic_mediacontrol">&nbsp;</span><span id="menu_top_mediacontrol"
+                            style="display:inline-block;vertical-align: middle;" class="topmenu_normal">媒体控制</span></td>
+                    <td class="topmenu color_Darkgray" id="menu_advanceset" onclick="selectPage('advanceset')"><span
+                            id="ic_advanceset_icon"
+                            style="display:inline-block;vertical-align: middle;margin-right:5px;"
+                            class="ic_advanceset">&nbsp;</span><span id="menu_top_advanceset"
+                            style="display:inline-block;vertical-align: middle;" class="topmenu_normal">高级设置</span></td>
+                </tr>
+            </tbody>
+        </table>
+    </div>
+    <div class="clearboth color_background_white">
+        <div class="bodycontainer">
+            <div id="leftmenuarea" class="leftmenuarea" style="padding-top: 20px; height: 802px;">
+                <div id="vermnt_childrens_menu">
+                    <div class="clearboth secondmenu selectmenu" id="menu_mobilenetwork"
+                        onclick="selectThirdPage('mobileconnection','mobilenetwork')">
+                        <div class="secondmenu_child">
+                            <div class="pull-left pointer" style="width: 200px;word-break: break-all;"
+                                lang-id="menu.mobilenetwork">终端配置</div>
+                            <div class="pull-right menu_arrow_open" id="menu_mobilenetwork_arrow"></div>
+                        </div>
+                    </div>
+                    <div id="mobilenetwork_childrens_menu" class="hide" style="display: block;">
+                        <div class="clearboth thirdleftmenu selectmenu" id="menu_mobileconnection"
+                            onclick="selectPage('mobileconnection')">
+                            <div class="pointer" lang-id="menu.mobileconnection">终端信息</div>
+                        </div>
+                        <div class="clearboth thirdleftmenu color_Darkgray" id="menu_mobilesearch"
+                            onclick="selectPage('mobilesearch')">
+                            <div class="pointer" lang-id="menu.mobilesearch">移动网络搜索</div>
+                        </div>
+                    </div>
+                    <div class="clearboth secondmenu color_Darkgray" id="menu_wifinetworks"
+                        onclick="selectThirdPage('wifinetworkssetting','wifinetworks')">
+                        <div class="secondmenu_child">
+                            <div class="pull-left pointer" style="width: 200px;word-break: break-all;"
+                                lang-id="menu.wifinetworks">WLAN 扩展</div>
+                            <div class="pull-right menu_arrow_close" id="menu_wifinetworks_arrow"></div>
+                        </div>
+                    </div>
+                    <div id="wifinetworks_childrens_menu" class="hide" style="display: none;">
+                        <div class="clearboth thirdleftmenu color_Darkgray" id="menu_wifinetworkssetting"
+                            onclick="selectPage('wifinetworkssetting')">
+                            <div class="pointer" lang-id="menu.wifinetworkssetting">WLAN 扩展设置</div>
+                        </div>
+                        <div class="clearboth thirdleftmenu color_Darkgray" id="menu_wifinetworksconnect"
+                            onclick="selectPage('wifinetworksconnect')">
+                            <div class="pointer" lang-id="menu.wifinetworksconnect">WLAN 扩展连接</div>
+                        </div>
+                        <div class="clearboth thirdleftmenu color_Darkgray" id="menu_wifinetworkswps"
+                            onclick="selectPage('wifinetworkswps')">
+                            <div class="pointer" lang-id="menu.wifinetworkswps">WLAN 扩展 WPS</div>
+                        </div>
+                    </div>
+                </div>
+                <div style="height:60px;">&nbsp;</div>
+            </div>
+            <div id="rightpagearea" class="rightpagearea margin-left-50" style="padding-top: 40px; width: 690px;">
+                <div id="context_page" style="display: block;">
+                    <div class="maintitle">
+                        <div>终端号切换</div>
+                        <div class="page_description_text">用于开发测试环境终端切换管理。
+                        </div>
+                    </div>
+                    <div id="contextSwitchContent">
+                        <div class="clearboth" id="apn_list" style="padding-top:70px;">
+                            <div class="table_top">
+                                <div class="table_list_title">终端号候选列表
+                                </div>
+                                <div class="pull-right">
+                                    <div id="termbackup_new" class="btn_new pull-left">
+                                        &nbsp;
+                                    </div>
+                                </div>
+                            </div>
+                            <div class="border_left border_right color_Darkgray"
+                                style="width:678px;padding-top:-1px;">
+                                <div id="termbackup_lists" class="clearboth" style="width:100%;overflow:hidden;">
+                                </div>
+                            </div>
+                            <div class="table_bottom">
+                            </div>
+                        </div>
+                        <div id="add_termbackup_item_win" class="out_win_content submit_background hide">
+                            <div class="table_top">
+                                <div style="border-bottom: #E9E9E9 solid 1px;font-size: 16px;text-align:center;line-height: 65px;">
+                                    候选终端号相关设置</div>
+                            </div>
+                            <div class="border_left border_right margin_bottom_box2 color_background_white"
+                                style="padding-top: 40px;">
+                                <div id="add_termbackup_item_win_scroll" style="max-height:300px;">
+                                    <div id="termbackup_env_type_div" class="clearboth">
+                                        <div class="control-label-win"><span>环境</span></div>
+                                        <div class="controls-win">
+                                            <div id="termbackup_env" class="select_on_normal" onclick="SelectItem(this)">
+                                            </div>
+                                            <div id="termbackup_env_list" class="select_list hide" style="display: none;">
+                                                <div id="termbackup_env_list_item_dev" option="1" class="select_medium"">DEV</div>
+                                                <div id=" termbackup_env_list_item_st" option="2" class="select_medium">ST</div>
+                                                <div id="termbackup_env_list_item_uat" option="3" class="select_medium">UAT </div>
+                                                <div id="termbackup_env_list_item_all" option="0" class="select_medium">Unclassfied</div>
+                                            </div>
+                                        </div>
+                                    </div>
+                                    <input style="display:none;" id="termbackup_url_profile_index" type="text">
+                                    <div id="termbackup_terminalno_div" class="clearboth" style="padding-top:29px;">
+                                        <div class="control-label-win"><span>终端号</span></div>
+                                        <div class="controls-win input_normal"><input id="termbackup_terminalno"
+                                                onfocus="showInputBorder(this)" onblur="hideInputBorder(this)"
+                                                type="text" maxlength="10"></div>
+                                    </div>
+                                    <div id="termbackup_branch_ip_div" class="clearboth" style="padding-top:29px;">
+                                        <div class="control-label-win"><span>分行服务IP</span></div>
+                                        <div class="controls-win input_normal"><input id="termbackup_branch_ip"
+                                                onfocus="showInputBorder(this)" onblur="hideInputBorder(this)"
+                                                type="text" maxlength="64"></div>
+                                    </div>
+                                    <div id="remark" class="clearboth" style="padding-top:29px;">
+                                        <div class="control-label-win">
+                                            <span">备注</span>
+                                        </div>
+                                        <div class="controls-win input_normal"><input id="input_remark"
+                                             placeholder="(可不填)" onfocus="showInputBorder(this)"
+                                             onblur="hideInputBorder(this)" type="text" maxlength="128"></div>
+                                    </div>
+                                    <div id="termbackup_list_input_set_default_div" class="clearboth"
+                                        style="padding-top: 27px;">
+                                        <div class="control-label-win pull-left">
+                                            <span>设置为当前使用</span>
+                                        </div>
+                                        <div id="termbackup_list_input_set_default"
+                                            class="check_off controls-win pull-right" style="margin-top:8px;">
+                                        </div>
+                                    </div>
+                                    <div id="termbackup_select_blank" style="height: 145px; display: none;" class="hide">
+                                    </div>
+                                    <div class="clearboth"></div>
+                                </div>
+                                <div style="padding-top:50px;padding-bottom:8px;" align="center">
+                                    <button id="termbackup_item_cancel" class="btn_normal_short">取消</button>
+                                    <button id="termbackup_item_save"
+                                        class="btn_normal_short btn_disabled margin-left-20">保存</button>
+                                </div>
+                            </div>
+                            <div class="table_bottom"></div>
+                        </div>
+                    </div>
+                </div>
+                <div style="height:40px;">&nbsp;</div>
+            </div>
+            <div class="clearboth"></div>
+        </div>
+    </div>
+    <div class="clearboth"></div>
+    <div id="page_footer" style="height:80px;background-color:#F3F3F3;width:100%;" class="hide">
+        <div style="width:1150px;height:50px;margin:0 auto;background-color:#F3F3F3;">
+            <div class="clearboth footercontainer">
+                <div id="copyright">
+                    <table style="margin-top:5px; margin-bottom:12px" cellpadding="0" cellspacing="0" frame="void"
+                        rules="none" align="center">
+                        <tbody>
+                            <tr>
+                                <td class="padding-left-20">
+                                    <a id="help_href" href="#" rel="noopener noreferrer" target="_blank"
+                                        class="pull-left  padding-left-20 color_descroption_gray"
+                                        style="display: inline;">
+                                        <div class="pull-left footer-help" lang-id="footer.faqs">常见问题</div>
+                                    </a>
+                                </td>
+                                <td class="padding-left-20">
+                                    <div class="padding-left-20 border_left color_border_gray color_descroption_gray"
+                                        id="footer_copyright">©2021 招商银行 版权所有</div>
+                                </td>
+                            </tr>
+                        </tbody>
+                    </table>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div class="clearboth"></div>
+    <div id="submit_light" class="submit_white_content" style="display: none;"></div>
+    <div id="pwd_submit_light" class="pwd_submit_white_content"></div>
+    <div id="toast_location" class="toast_location hide">
+        <div class="toast_left pull-left"></div>
+        <div class="pull-left color_Darkgray" style="background-color:#DBDBDB;height:44px;font-size:14px;">
+            <div style="margin-top:14px;" id="toast_info"></div>
+        </div>
+        <div class="toast_right pull-left"></div>
+    </div>
+    <div id="confirm_light" class="submit_white_content hide" style="display: none;"></div>
+    <div id="submit_fade" class="submit_black_overlay hide" style="display: none;"></div>
+    <div id="emui_content_pop_win" class="pop_win hide">
+        <div class="adv_pop_win_top">
+            <div class="pull-left padding-left-30" id="emui_pop_win_title" lang-id="cbs.win.title"
+                style="font-size:16px;padding-top:25px;"></div>
+            <div class="pull-right btn_cancel padding-right-8" onclick="EMUI.popWinController.closeAll();"
+                style="margin-top:25px;"></div>
+        </div>
+        <div class="adv_pop_win_middle" style="min-height:100px;">
+            <div class="clearboth border_bottom margin-left-10" style="width:504px;"></div>
+            <div id="pop_win_content_area" class="pop_win_content" style="word-wrap:break-word;">&nbsp;</div>
+        </div>
+        <div class="adv_pop_win_bottom"></div>
+    </div>
+
+
+</body>
+
+</html>

+ 325 - 0
addin/res/ManagerDesktop/prototype/logswitch.html

@@ -0,0 +1,325 @@
+<html id="html">
+
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>可视柜台终端管理</title>
+    <meta name="viewport"
+        content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
+    <meta name="description" content="default">
+    <meta name="author" content="default">
+    <link type="text/css" rel="stylesheet" href="../css/emui-style.css">
+    <script type="text/javascript" src="../Include/LsyCookie.js"></script>
+    <script type="text/javascript" src="../js/errorCodeEnum.js"></script>
+    <script type="text/javascript" src="../js/common.js"></script>
+    <script type="text/javascript" src="../js/websocket.js"></script>
+    <script type="text/javascript" src="../js/webSocketBase.js"></script>
+    <script type="text/javascript" src="../js/entityMessage.js"></script>
+    <script type="text/javascript" src="../js/eventEmitter.js"></script>
+    <script type="text/javascript" src="../js/innerEventEmitter.js"></script>
+    <script type="text/javascript" src="../js/entityService.js"></script>
+    <script type="text/javascript" src="../Include/jQuery/js/emui-jquery.min.js"></script>
+    <script type="text/javascript" src="../js/public.js"></script>
+    <script type="text/javascript">
+        $(document).ready(function () {
+            var headerHeight = $(".header div.logo img").height();
+            $(".header").height(headerHeight);
+        });
+    </script>
+</head>
+
+<body style="display: block;">
+    <div id="preLoadEyeImg">
+        <div class="ic_guide_eye_open" style="opacity:0;height:0;margin:0"></div>
+        <div class="ic_eye_open" style="opacity:0;height:0;margin:0"></div>
+    </div>
+    <div>
+        <div class="headcontainer">
+            <div class="header" style="height: 38px;">
+                <div class="pull-left">
+                    <div class="logo pull-left"><img src="images/logo_cmb.png"> &nbsp;</div>
+                    <div class="pull-left devicename" id="deicename">&nbsp;</div>
+                </div>
+                <div id="header_right" class="pull-right">
+                    <table class="pull-right" cellpadding="0" cellspacing="0" frame="void" rules="none">
+                        <tbody>
+                            <tr>
+                                <td id="header_upgrade_info" style="width:52px;" align="center">
+                                    <div title="版本更新" style="position: relative;" class="ic_update_normal"
+                                        onclick="test();">
+                                    </div>
+                                </td>
+                                <td style="width:52px;" align="center" id="loginallowed_btn">
+                                    <div title="重启应用" class="ic_reboot"
+                                        onclick="RVC.HealthmanagerEntityCtrl.RestartApp();"></div>
+                                </td>
+                                <td style="width:52px;" align="center">
+                                    <div title="设备关机" class="ic_poweroff"
+                                        onclick="RVC.HealthmanagerEntityCtrl.PowerOffPC();"></div>
+                                </td>
+                                <td style="width:52px;border-left: 2px solid #A9A9A9;" align="center" id="quitpage_btn">
+                                    <div title="退出页面" class="ic_signout" onclick="quitThisPage();"></div>
+                                </td>
+                            </tr>
+                        </tbody>
+                    </table>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div class="clearboth"></div>
+    <div id="topmenucontainer" class="border_top border_bottom color_background_blue"
+        style="height:76px;font-size:18px;">
+        <table style="border-spacing:0px;border-collapse:collapse;width:1000px;margin:0 auto;left:0px;">
+            <tbody>
+                <tr>
+                    <td class="topmenu selectmenu" id="menu_home" onclick="selectPage('home')"><span id="ic_home_icon"
+                            style="display:inline-block;vertical-align: middle;margin-right:5px;"
+                            class="ic_home_selected">&nbsp;</span><span id="menu_top_home"
+                            style="display:inline-block;vertical-align: middle;" class="topmenu_selected">首页</span></td>
+                    <td class="topmenu color_Darkgray" id="menu_terminalmanagement"
+                        onclick="selectPage('terminalmanagement')">
+                        <span id="ic_terminalmanagement_icon"
+                            style="display:inline-block;vertical-align: middle;margin-right:5px;"
+                            class="ic_terminalmanagement">&nbsp;</span><span id="menu_top_terminalmanagement"
+                            style="display:inline-block;vertical-align: middle;" class="topmenu_normal">终端管理</span>
+                    </td>
+                    <td class="topmenu color_Darkgray" id="menu_networkmanagement"
+                        onclick="selectPage('networkmanagement')"><span id="ic_networkmanagement_icon"
+                            style="display:inline-block;vertical-align: middle;margin-right:5px;"
+                            class="ic_networkmanagement">&nbsp;</span><span id="menu_top_networkmanagement"
+                            style="display:inline-block;vertical-align: middle;" class="topmenu_normal">网络连接</span></td>
+                    <td class="topmenu color_Darkgray" id="menu_hardwareconfig" onclick="selectPage('hardwareconfig')">
+                        <span id="ic_hardwareconfig_icon"
+                            style="display:inline-block;vertical-align: middle;margin-right:5px;"
+                            class="ic_hardwareconfig">&nbsp;</span><span id="menu_top_hardwareconfig"
+                            style="display:inline-block;vertical-align: middle;" class="topmenu_normal">硬件管理</span></td>
+                    <td class="topmenu color_Darkgray" id="menu_mediacontrol" onclick="selectPage('mediacontrol')"><span
+                            id="ic_mediacontrol_icon"
+                            style="display:inline-block;vertical-align: middle;margin-right:5px;"
+                            class="ic_mediacontrol">&nbsp;</span><span id="menu_top_mediacontrol"
+                            style="display:inline-block;vertical-align: middle;" class="topmenu_normal">媒体控制</span></td>
+                    <td class="topmenu color_Darkgray" id="menu_advanceset" onclick="selectPage('advanceset')"><span
+                            id="ic_advanceset_icon"
+                            style="display:inline-block;vertical-align: middle;margin-right:5px;"
+                            class="ic_advanceset">&nbsp;</span><span id="menu_top_advanceset"
+                            style="display:inline-block;vertical-align: middle;" class="topmenu_normal">高级设置</span></td>
+                </tr>
+            </tbody>
+        </table>
+    </div>
+    <div class="clearboth color_background_white">
+        <div class="bodycontainer">
+            <div id="leftmenuarea" class="leftmenuarea" style="padding-top: 20px; height: 802px;">
+                <div id="logswitch_childrens_menu">
+                    <div class="clearboth secondmenu selectmenu" id="menu_mobilenetwork"
+                        onclick="selectThirdPage('mobileconnection','mobilenetwork')">
+                        <div class="secondmenu_child">
+                            <div class="pull-left pointer" style="width: 200px;word-break: break-all;"
+                                lang-id="menu.mobilenetwork">终端配置</div>
+                            <div class="pull-right menu_arrow_open" id="menu_mobilenetwork_arrow"></div>
+                        </div>
+                    </div>
+                    <div id="mobilenetwork_childrens_menu" class="hide" style="display: block;">
+                        <div class="clearboth thirdleftmenu selectmenu" id="menu_mobileconnection"
+                            onclick="selectPage('mobileconnection')">
+                            <div class="pointer" lang-id="menu.mobileconnection">终端信息</div>
+                        </div>
+                        <div class="clearboth thirdleftmenu color_Darkgray" id="menu_mobilesearch"
+                            onclick="selectPage('mobilesearch')">
+                            <div class="pointer" lang-id="menu.mobilesearch">移动网络搜索</div>
+                        </div>
+                    </div>
+                    <div class="clearboth secondmenu color_Darkgray" id="menu_wifinetworks"
+                        onclick="selectThirdPage('wifinetworkssetting','wifinetworks')">
+                        <div class="secondmenu_child">
+                            <div class="pull-left pointer" style="width: 200px;word-break: break-all;"
+                                lang-id="menu.wifinetworks">WLAN 扩展</div>
+                            <div class="pull-right menu_arrow_close" id="menu_wifinetworks_arrow"></div>
+                        </div>
+                    </div>
+                    <div id="wifinetworks_childrens_menu" class="hide" style="display: none;">
+                        <div class="clearboth thirdleftmenu color_Darkgray" id="menu_wifinetworkssetting"
+                            onclick="selectPage('wifinetworkssetting')">
+                            <div class="pointer" lang-id="menu.wifinetworkssetting">WLAN 扩展设置</div>
+                        </div>
+                        <div class="clearboth thirdleftmenu color_Darkgray" id="menu_wifinetworksconnect"
+                            onclick="selectPage('wifinetworksconnect')">
+                            <div class="pointer" lang-id="menu.wifinetworksconnect">WLAN 扩展连接</div>
+                        </div>
+                        <div class="clearboth thirdleftmenu color_Darkgray" id="menu_wifinetworkswps"
+                            onclick="selectPage('wifinetworkswps')">
+                            <div class="pointer" lang-id="menu.wifinetworkswps">WLAN 扩展 WPS</div>
+                        </div>
+                    </div>
+                </div>
+                <div style="height:60px;">&nbsp;</div>
+            </div>
+            <div id="rightpagearea" class="rightpagearea margin-left-50" style="padding-top: 40px; width: 690px;">
+                <div id="logswitch_page" style="display: block;">
+                    <div class="maintitle">
+                        <div>硬件适配器日志记录管理</div>
+                        <div class="page_description_text">本地临时打开硬件适配器日志记录,方便及时排查硬件问题。注意:该功能在完成去分行化后将移除。
+                        </div>
+                    </div>
+                    <div id="logswitchContent" class="hide" style="display: block;">
+                        <div id="log_switch_cardissuer" class="clearboth" style="margin-top: 37px;">
+                            <div class="control-label" style="margin-top: 8px;"><span>发卡器</span></div>
+                            <div class="controls" style="margin-top:3px;">
+                                <div id="log_switch_cardissuer_switch" onclick="Switch(this)" class="switch_on"></div>
+                            </div>
+                        </div>
+                        <div id="log_switch_contactless" class="clearboth" style="margin-top: 37px;padding-top: 27px;">
+                            <div class="control-label" style="margin-top: 8px;"><span>非接读卡器</span></div>
+                            <div class="controls" style="margin-top:3px;">
+                                <div id="log_switch_contactless_switch" onclick="Switch(this)" class="switch_on"></div>
+                            </div>
+                        </div>
+                        <div id="log_switch_idcertificate" class="clearboth" style="margin-top: 37px;padding-top: 27px;">
+                            <div class="control-label" style="margin-top: 8px;"><span>身份证阅读器</span></div>
+                            <div class="controls" style="margin-top:3px;">
+                                <div id="log_switch_idcertificate_switch" onclick="Switch(this)" class="switch_on"></div>
+                            </div>
+                        </div>
+                        
+                        <div id="log_switch_pinpad" class="clearboth" style="margin-top: 37px;padding-top: 27px;">
+                            <div class="control-label" style="margin-top: 8px;"><span>密码键盘</span></div>
+                            <div class="controls" style="margin-top:3px;">
+                                <div id="log_switch_pinpad_switch" onclick="Switch(this)" class="switch_on"></div>
+                            </div>
+                        </div>
+                        <div id="log_switch_fingerprint" class="clearboth" style="margin-top: 37px;padding-top: 27px;">
+                            <div class="control-label" style="margin-top: 8px;"><span>指纹仪</span></div>
+                            <div class="controls" style="margin-top:3px;">
+                                <div id="log_switch_fingerprint_switch" onclick="Switch(this)" class="switch_on"></div>
+                            </div>
+                        </div>
+                        <div id="log_switch_hspscanner" class="clearboth" style="margin-top: 37px;padding-top: 27px;">
+                            <div class="control-label" style="margin-top: 8px;"><span>高拍仪</span></div>
+                            <div class="controls" style="margin-top:3px;">
+                                <div id="log_switch_hspscanner_switch" onclick="Switch(this)" class="switch_on"></div>
+                            </div>
+                        </div>
+                        <div id="log_switch_gpio" class="clearboth" style="margin-top: 37px;padding-top: 27px;">
+                            <div class="control-label" style="margin-top: 8px;"><span>GPIO</span></div>
+                            <div class="controls" style="margin-top:3px;">
+                                <div id="log_switch_gpio_switch" onclick="Switch(this)" class="switch_on"></div>
+                            </div>
+                        </div>
+                        <div id="log_switch_watchdog_section" class="wps_connect_way_title " style="margin-top: 40px; padding-top: 40px;">看门狗</div>
+                        <div id="log_switch_watchdog_section_description" class="three_way_instruction maintitle" style="padding-bottom: 0px !important;" >&nbsp;</div>
+                        <div id="log_switch_watchdog_switch" class="clearboth" style="padding-top: 15px;">
+                            <div class="control-label" style="margin-top:3px;">
+                                <span>日志开关</span>
+                            </div>
+                            <div class="controls">
+                                <div id="log_switch_watchdog_switch" onclick="Switch(this)" class="switch_on"></div>
+                            </div>
+                        </div>
+                        <div id="log_switch_watchdog_level" class="clearboth" style="padding-top: 15px;">
+                            <div class="control-label" style="margin-top:3px;">
+                                <span>日志等级</span>
+                            </div>
+                            <div class="controls">
+                                <div id="log_switch_watchdog_log_level_select_all">
+                                    <div id="log_switch_watchdog_log_level_select" class="select_on_normal" value="0" onclick="SelectItem(this)"></div>
+                                    <div id="log_switch_watchdog_log_level_select_list" class="select_list hide" style="display: none;">
+                                        <div id="log_switch_watchdog_log_level_select_list_item_fatal" option="1" class="select_medium">Fatal</div>
+                                        <div id="log_switch_watchdog_log_level_select_list_item_error" option="2" class="select_medium">Error</div>
+                                        <div id="log_switch_watchdog_log_level_select_list_item_warn" option="3" class="select_medium">Warn</div>
+                                        <div id="log_switch_watchdog_log_level_select_list_item_info" option="4" class="select_medium">Info</div>
+                                        <div id="log_switch_watchdog_log_level_select_list_item_trace" option="5" class="select_medium">Trace</div>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                        <div id="log_switch_ups_section" class="wps_connect_way_title " style="margin-top: 40px; padding-top: 40px;">UPS</div>
+                        <div id="log_switch_ups_section_description" class="three_way_instruction maintitle" style="padding-bottom: 0px !important;" >&nbsp;</div>
+                        <div id="log_switch_ups_switch" class="clearboth" style="padding-top: 15px;">
+                            <div class="control-label" style="margin-top:3px;">
+                                <span>日志开关</span>
+                            </div>
+                            <div class="controls">
+                                <div id="log_switch_ups_switch" onclick="Switch(this)" class="switch_on"></div>
+                            </div>
+                        </div>
+                        <div id="log_switch_ups_level" class="clearboth" style="padding-top: 15px;">
+                            <div class="control-label" style="margin-top:3px;">
+                                <span>日志等级</span>
+                            </div>
+                            <div class="controls">
+                                <div id="log_switch_ups_log_level_select_all">
+                                    <div id="log_switch_ups_log_level_select" class="select_on_normal" value="0" onclick="SelectItem(this)"></div>
+                                    <div id="log_switch_ups_log_level_select_list" class="select_list hide" style="display: none;">
+                                        <div id="log_switch_ups_log_level_select_list_item_fatal" option="0" class="select_medium">Fatal</div>
+                                        <div id="log_switch_ups_log_level_select_list_item_error" option="1" class="select_medium">Error</div>
+                                        <div id="log_switch_ups_log_level_select_list_item_warn" option="2" class="select_medium">Warn</div>
+                                        <div id="log_switch_ups_log_level_select_list_item_info" option="3" class="select_medium">Info</div>
+                                        <div id="log_switch_ups_log_level_select_list_item_trace" option="4" class="select_medium">Trace</div>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                    <div style="height:40px;">&nbsp;</div>
+                </div>
+            </div>
+            <div class="clearboth"></div>
+        </div>
+    </div>
+    <div class="clearboth"></div>
+    <div id="page_footer" style="height:80px;background-color:#F3F3F3;width:100%;" class="hide">
+        <div style="width:1150px;height:50px;margin:0 auto;background-color:#F3F3F3;">
+            <div class="clearboth footercontainer">
+                <div id="copyright">
+                    <table style="margin-top:5px; margin-bottom:12px" cellpadding="0" cellspacing="0" frame="void"
+                        rules="none" align="center">
+                        <tbody>
+                            <tr>
+                                <td class="padding-left-20">
+                                    <a id="help_href" href="#" rel="noopener noreferrer" target="_blank"
+                                        class="pull-left  padding-left-20 color_descroption_gray"
+                                        style="display: inline;">
+                                        <div class="pull-left footer-help" lang-id="footer.faqs">常见问题</div>
+                                    </a>
+                                </td>
+                                <td class="padding-left-20">
+                                    <div class="padding-left-20 border_left color_border_gray color_descroption_gray"
+                                        id="footer_copyright">©2021 招商银行 版权所有</div>
+                                </td>
+                            </tr>
+                        </tbody>
+                    </table>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div class="clearboth"></div>
+    <div id="submit_light" class="submit_white_content" style="display: none;"></div>
+    <div id="pwd_submit_light" class="pwd_submit_white_content"></div>
+    <div id="toast_location" class="toast_location hide">
+        <div class="toast_left pull-left"></div>
+        <div class="pull-left color_Darkgray" style="background-color:#DBDBDB;height:44px;font-size:14px;">
+            <div style="margin-top:14px;" id="toast_info"></div>
+        </div>
+        <div class="toast_right pull-left"></div>
+    </div>
+    <div id="confirm_light" class="submit_white_content hide" style="display: none;"></div>
+    <div id="submit_fade" class="submit_black_overlay hide" style="display: none;"></div>
+    <div id="emui_content_pop_win" class="pop_win hide">
+        <div class="adv_pop_win_top">
+            <div class="pull-left padding-left-30" id="emui_pop_win_title" lang-id="cbs.win.title"
+                style="font-size:16px;padding-top:25px;"></div>
+            <div class="pull-right btn_cancel padding-right-8" onclick="EMUI.popWinController.closeAll();"
+                style="margin-top:25px;"></div>
+        </div>
+        <div class="adv_pop_win_middle" style="min-height:100px;">
+            <div class="clearboth border_bottom margin-left-10" style="width:504px;"></div>
+            <div id="pop_win_content_area" class="pop_win_content" style="word-wrap:break-word;">&nbsp;</div>
+        </div>
+        <div class="adv_pop_win_bottom"></div>
+    </div>
+
+
+</body>
+
+</html>

+ 338 - 0
addin/res/ManagerDesktop/prototype/vermanagement.html

@@ -0,0 +1,338 @@
+<html id="html">
+
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>可视柜台终端管理</title>
+    <meta name="viewport"
+        content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
+    <meta name="description" content="default">
+    <meta name="author" content="default">
+    <link type="text/css" rel="stylesheet" href="../css/emui-style.css">
+    <script type="text/javascript" src="../Include/LsyCookie.js"></script>
+    <script type="text/javascript" src="../js/errorCodeEnum.js"></script>
+    <script type="text/javascript" src="../js/common.js"></script>
+    <script type="text/javascript" src="../js/websocket.js"></script>
+    <script type="text/javascript" src="../js/webSocketBase.js"></script>
+    <script type="text/javascript" src="../js/entityMessage.js"></script>
+    <script type="text/javascript" src="../js/eventEmitter.js"></script>
+    <script type="text/javascript" src="../js/innerEventEmitter.js"></script>
+    <script type="text/javascript" src="../js/entityService.js"></script>
+    <script type="text/javascript" src="../Include/jQuery/js/emui-jquery.min.js"></script>
+    <script type="text/javascript" src="../js/public.js"></script>
+    <script type="text/javascript">
+        $(document).ready(function () {
+            var headerHeight = $(".header div.logo img").height();
+            $(".header").height(headerHeight);
+        });
+    </script>
+</head>
+
+<body style="display: block;">
+    <div id="preLoadEyeImg">
+        <div class="ic_guide_eye_open" style="opacity:0;height:0;margin:0"></div>
+        <div class="ic_eye_open" style="opacity:0;height:0;margin:0"></div>
+    </div>
+    <div>
+        <div class="headcontainer">
+            <div class="header" style="height: 38px;">
+                <div class="pull-left">
+                    <div class="logo pull-left"><img src="images/logo_cmb.png"> &nbsp;</div>
+                    <div class="pull-left devicename" id="deicename">&nbsp;</div>
+                </div>
+                <div id="header_right" class="pull-right">
+                    <table class="pull-right" cellpadding="0" cellspacing="0" frame="void" rules="none">
+                        <tbody>
+                            <tr>
+                                <td id="header_upgrade_info" style="width:52px;" align="center">
+                                    <div title="版本更新" style="position: relative;" class="ic_update_normal"
+                                        onclick="test();">
+                                    </div>
+                                </td>
+                                <td style="width:52px;" align="center" id="loginallowed_btn">
+                                    <div title="重启应用" class="ic_reboot"
+                                        onclick="RVC.HealthmanagerEntityCtrl.RestartApp();"></div>
+                                </td>
+                                <td style="width:52px;" align="center">
+                                    <div title="设备关机" class="ic_poweroff"
+                                        onclick="RVC.HealthmanagerEntityCtrl.PowerOffPC();"></div>
+                                </td>
+                                <td style="width:52px;border-left: 2px solid #A9A9A9;" align="center" id="quitpage_btn">
+                                    <div title="退出页面" class="ic_signout" onclick="quitThisPage();"></div>
+                                </td>
+                            </tr>
+                        </tbody>
+                    </table>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div class="clearboth"></div>
+    <div id="topmenucontainer" class="border_top border_bottom color_background_blue"
+        style="height:76px;font-size:18px;">
+        <table style="border-spacing:0px;border-collapse:collapse;width:1000px;margin:0 auto;left:0px;">
+            <tbody>
+                <tr>
+                    <td class="topmenu selectmenu" id="menu_home" onclick="selectPage('home')"><span id="ic_home_icon"
+                            style="display:inline-block;vertical-align: middle;margin-right:5px;"
+                            class="ic_home_selected">&nbsp;</span><span id="menu_top_home"
+                            style="display:inline-block;vertical-align: middle;" class="topmenu_selected">首页</span></td>
+                    <td class="topmenu color_Darkgray" id="menu_terminalmanagement"
+                        onclick="selectPage('terminalmanagement')">
+                        <span id="ic_terminalmanagement_icon"
+                            style="display:inline-block;vertical-align: middle;margin-right:5px;"
+                            class="ic_terminalmanagement">&nbsp;</span><span id="menu_top_terminalmanagement"
+                            style="display:inline-block;vertical-align: middle;" class="topmenu_normal">终端管理</span>
+                    </td>
+                    <td class="topmenu color_Darkgray" id="menu_networkmanagement"
+                        onclick="selectPage('networkmanagement')"><span id="ic_networkmanagement_icon"
+                            style="display:inline-block;vertical-align: middle;margin-right:5px;"
+                            class="ic_networkmanagement">&nbsp;</span><span id="menu_top_networkmanagement"
+                            style="display:inline-block;vertical-align: middle;" class="topmenu_normal">网络连接</span></td>
+                    <td class="topmenu color_Darkgray" id="menu_hardwareconfig" onclick="selectPage('hardwareconfig')">
+                        <span id="ic_hardwareconfig_icon"
+                            style="display:inline-block;vertical-align: middle;margin-right:5px;"
+                            class="ic_hardwareconfig">&nbsp;</span><span id="menu_top_hardwareconfig"
+                            style="display:inline-block;vertical-align: middle;" class="topmenu_normal">硬件管理</span></td>
+                    <td class="topmenu color_Darkgray" id="menu_mediacontrol" onclick="selectPage('mediacontrol')"><span
+                            id="ic_mediacontrol_icon"
+                            style="display:inline-block;vertical-align: middle;margin-right:5px;"
+                            class="ic_mediacontrol">&nbsp;</span><span id="menu_top_mediacontrol"
+                            style="display:inline-block;vertical-align: middle;" class="topmenu_normal">媒体控制</span></td>
+                    <td class="topmenu color_Darkgray" id="menu_advanceset" onclick="selectPage('advanceset')"><span
+                            id="ic_advanceset_icon"
+                            style="display:inline-block;vertical-align: middle;margin-right:5px;"
+                            class="ic_advanceset">&nbsp;</span><span id="menu_top_advanceset"
+                            style="display:inline-block;vertical-align: middle;" class="topmenu_normal">高级设置</span></td>
+                </tr>
+            </tbody>
+        </table>
+    </div>
+    <div class="clearboth color_background_white">
+        <div class="bodycontainer">
+            <div id="leftmenuarea" class="leftmenuarea" style="padding-top: 20px; height: 802px;">
+                <div id="vermnt_childrens_menu">
+                    <div class="clearboth secondmenu selectmenu" id="menu_mobilenetwork"
+                        onclick="selectThirdPage('mobileconnection','mobilenetwork')">
+                        <div class="secondmenu_child">
+                            <div class="pull-left pointer" style="width: 200px;word-break: break-all;"
+                                lang-id="menu.mobilenetwork">终端配置</div>
+                            <div class="pull-right menu_arrow_open" id="menu_mobilenetwork_arrow"></div>
+                        </div>
+                    </div>
+                    <div id="mobilenetwork_childrens_menu" class="hide" style="display: block;">
+                        <div class="clearboth thirdleftmenu selectmenu" id="menu_mobileconnection"
+                            onclick="selectPage('mobileconnection')">
+                            <div class="pointer" lang-id="menu.mobileconnection">终端信息</div>
+                        </div>
+                        <div class="clearboth thirdleftmenu color_Darkgray" id="menu_mobilesearch"
+                            onclick="selectPage('mobilesearch')">
+                            <div class="pointer" lang-id="menu.mobilesearch">移动网络搜索</div>
+                        </div>
+                    </div>
+                    <div class="clearboth secondmenu color_Darkgray" id="menu_wifinetworks"
+                        onclick="selectThirdPage('wifinetworkssetting','wifinetworks')">
+                        <div class="secondmenu_child">
+                            <div class="pull-left pointer" style="width: 200px;word-break: break-all;"
+                                lang-id="menu.wifinetworks">WLAN 扩展</div>
+                            <div class="pull-right menu_arrow_close" id="menu_wifinetworks_arrow"></div>
+                        </div>
+                    </div>
+                    <div id="wifinetworks_childrens_menu" class="hide" style="display: none;">
+                        <div class="clearboth thirdleftmenu color_Darkgray" id="menu_wifinetworkssetting"
+                            onclick="selectPage('wifinetworkssetting')">
+                            <div class="pointer" lang-id="menu.wifinetworkssetting">WLAN 扩展设置</div>
+                        </div>
+                        <div class="clearboth thirdleftmenu color_Darkgray" id="menu_wifinetworksconnect"
+                            onclick="selectPage('wifinetworksconnect')">
+                            <div class="pointer" lang-id="menu.wifinetworksconnect">WLAN 扩展连接</div>
+                        </div>
+                        <div class="clearboth thirdleftmenu color_Darkgray" id="menu_wifinetworkswps"
+                            onclick="selectPage('wifinetworkswps')">
+                            <div class="pointer" lang-id="menu.wifinetworkswps">WLAN 扩展 WPS</div>
+                        </div>
+                    </div>
+                </div>
+                <div style="height:60px;">&nbsp;</div>
+            </div>
+            <div id="rightpagearea" class="rightpagearea margin-left-50" style="padding-top: 40px; width: 690px;">
+                <div id="vermanagement_page" style="display: block;">
+                    <div class="maintitle">
+                        <div>环境切换</div>
+                        <div class="page_description_text">用于开发测试环境:终端版本切换、业务中台链接切换、ST/UAT环境终端号切换。
+                        </div>
+                    </div>
+                    <div id="vermntContent">
+                        <div class="clearboth" id="web_list" style="padding-top:70px;">
+                            <div class="table_top">
+                                <div class="table_list_title">
+                                    <div>&nbsp;</div>
+                                </div>
+                                <div class="pull-right">
+                                    <div id="web_new" class="btn_new pull-left">&nbsp;</div>
+                                </div>
+                            </div>
+                            <div class="border_left border_right color_Darkgray" style="width:678px;padding-top:-1px;">
+                                <div id="web_lists" class="clearboth">
+                                    <div id="web_list_1" class="border_bottom list_item_hover"
+                                                style="height:70px;cursor:pointer;">
+                                                <div id="web_list_name_1" class="pull-left padding-left-20"
+                                                    style="height:56px;padding-top:14px;width:600px;"
+                                                    onclick="EMUI.profileController.showProfile(1)">
+                                                    <pre class="web_profile_name_1"
+                                                        style="font-size:16px;margin-top:0px;"><span class="web_profile_itemname pull-left" style="line-height:21px;" title="中国电信CTNET">中国电信CTNET</span><span class="pull-left" style="line-height:21px;"><span lang-id="common_default">(默认)</span></span><div class="clearboth"></div></pre>
+                                                    <div class="web_web_name_1 color_descroption_gray web_profile_itemwebname"
+                                                        style="margin-top:-10px;font-size:14px;" title="CTNET">CTNET
+                                                    </div>
+                                                </div>
+                                                <div class="pull-right"></div>
+                                            </div>
+                                            <div id="web_list_2" class="border_bottom list_item_hover"
+                                                style="height:70px;cursor:pointer;">
+                                                <div id="web_list_name_2" class="pull-left padding-left-20"
+                                                    style="height:56px;padding-top:14px;width:600px;"
+                                                    onclick="EMUI.profileController.showProfile(2)">
+                                                    <pre class="web_profile_name_2"
+                                                        style="font-size:16px;margin-top:0px;"><span class="web_profile_itemname" title="电信物联网卡">电信物联网卡</span></pre>
+                                                    <div class="web_web_name_2 color_descroption_gray web_profile_itemwebname"
+                                                        style="margin-top:-10px;font-size:14px;" title="ctnb">ctnb</div>
+                                                </div>
+                                                <div class="pull-right"></div>
+                                            </div>
+                                            <div id="web_list_3" style="height:59px;cursor:pointer;"
+                                                class="list_item_hover">
+                                                <div id="web_list_name_3" class="pull-left padding-left-20"
+                                                    style="height:45px;padding-top:14px;width:600px;"
+                                                    onclick="EMUI.profileController.showProfile(3)">
+                                                    <pre class="web_profile_name_3"
+                                                        style="font-size:16px;margin-top:0px;"><span class="web_profile_itemname" title="Auto">Auto</span></pre>
+                                                    <div class="web_web_name_3 color_descroption_gray web_profile_itemwebname"
+                                                        style="margin-top:-10px;font-size:14px;" title=""></div>
+                                                </div>
+                                                <div class="pull-right"></div>
+                                            </div>
+                                </div>
+                            </div>
+                            <div class="table_bottom"></div>
+                        </div>
+                        <div id="add_web_item_win" class="out_win_content submit_background hide"
+                        style="display: none;">
+                        <div class="table_top">
+                            <div style="border-bottom: #E9E9E9 solid 1px;font-size: 16px;text-align:center;line-height: 65px;">
+                                业务链接设置</div>
+                        </div>
+                        <div class="border_left border_right margin_bottom_box2 color_background_white"
+                            style="padding-top: 40px;">
+                            
+                            <div id="web_main_url" class="clearboth">
+                                <div class="control-label-win"><span>业务URL(主屏)</span></div>
+                                <div class="controls-win input_normal"><input id="web_main_url_text"
+                                        onfocus="showInputBorder(this)" onblur="hideInputBorder(this)"
+                                        type="text" maxlength="128"></div>  
+                            </div>
+                            <div id="web_ad_url" class="clearboth" style="padding-top:29px;">
+                                <div class="control-label-win"><span>广告URL(上屏)</span></div>
+                                <div class="controls-win input_normal"><input id="web_ad_url_text"
+                                        onfocus="showInputBorder(this)" onblur="hideInputBorder(this)"
+                                        type="text" maxlength="128"></div>
+                            </div>
+                            <div id="web_env_type_div" class="clearboth" style="padding-top:29px;">
+                                <div class="control-label-win"><span>环境</span></div>
+                                <div class="controls-win">
+                                    <div id="web_env" class="select_on_normal"
+                                        onclick="SelectItem(this)"></div>
+                                    <div id="web_env_list" class="select_list hide"
+                                        style="display: none;">
+                                        <div id="web_env_list_item_dev" option="0"
+                                            class="select_medium"">DEV</div>
+                                        <div id="web_env_list_item_st" option="1"
+                                            class="select_medium">ST</div>
+                                        <div id="web_env_list_item_UAT" option="2"
+                                            class="select_medium">UAT</div>
+                                    </div>
+                                </div>
+                            </div>
+                            <div id="remark" class="clearboth" style="padding-top:29px;">
+                                <div class="control-label-win"><span">备注</span></div>
+                                <div class="controls-win input_normal"><input id="input_remark" placeholder="(可不填)"
+                                        onfocus="showInputBorder(this)" onblur="hideInputBorder(this)"
+                                        type="text" maxlength="63"></div>
+                            </div>
+                            <div id="web_list_input_set_default" class="clearboth" style="padding-top: 27px;">
+                                <div class="control-label-win pull-left"><span>设置为当前使用链接</span></div>
+                                <div id="web_list_input_set_default"
+                                    class="check_off controls-win pull-right" style="margin-top:3px;">
+                                </div>
+                            </div>
+                            <div id="web_select_blank" style="height: 145px; display: none;" class="hide"></div>
+                            <div class="clearboth"></div>
+                            <div style="padding-top:50px;padding-bottom:8px;" align="center">
+                                <button id="web_item_cancel" class="btn_normal_short" >取消</button>
+                                <button id="web_item_save" class="btn_normal_short btn_disabled margin-left-20">保存</button>
+                            </div>
+                        </div>
+                        <div class="table_bottom"></div>
+                    </div>
+                    </div>
+                    <div style="height:40px;">&nbsp;</div>
+                </div>
+            </div>
+            <div class="clearboth"></div>
+        </div>
+    </div>
+    <div class="clearboth"></div>
+    <div id="page_footer" style="height:80px;background-color:#F3F3F3;width:100%;" class="hide">
+        <div style="width:1150px;height:50px;margin:0 auto;background-color:#F3F3F3;">
+            <div class="clearboth footercontainer">
+                <div id="copyright">
+                    <table style="margin-top:5px; margin-bottom:12px" cellpadding="0" cellspacing="0" frame="void"
+                        rules="none" align="center">
+                        <tbody>
+                            <tr>
+                                <td class="padding-left-20">
+                                    <a id="help_href" href="#" rel="noopener noreferrer" target="_blank"
+                                        class="pull-left  padding-left-20 color_descroption_gray"
+                                        style="display: inline;">
+                                        <div class="pull-left footer-help" lang-id="footer.faqs">常见问题</div>
+                                    </a>
+                                </td>
+                                <td class="padding-left-20">
+                                    <div class="padding-left-20 border_left color_border_gray color_descroption_gray"
+                                        id="footer_copyright">©2021 招商银行 版权所有</div>
+                                </td>
+                            </tr>
+                        </tbody>
+                    </table>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div class="clearboth"></div>
+    <div id="submit_light" class="submit_white_content" style="display: none;"></div>
+    <div id="pwd_submit_light" class="pwd_submit_white_content"></div>
+    <div id="toast_location" class="toast_location hide">
+        <div class="toast_left pull-left"></div>
+        <div class="pull-left color_Darkgray" style="background-color:#DBDBDB;height:44px;font-size:14px;">
+            <div style="margin-top:14px;" id="toast_info"></div>
+        </div>
+        <div class="toast_right pull-left"></div>
+    </div>
+    <div id="confirm_light" class="submit_white_content hide" style="display: none;"></div>
+    <div id="submit_fade" class="submit_black_overlay hide" style="display: none;"></div>
+    <div id="emui_content_pop_win" class="pop_win hide">
+        <div class="adv_pop_win_top">
+            <div class="pull-left padding-left-30" id="emui_pop_win_title" lang-id="cbs.win.title"
+                style="font-size:16px;padding-top:25px;"></div>
+            <div class="pull-right btn_cancel padding-right-8" onclick="EMUI.popWinController.closeAll();"
+                style="margin-top:25px;"></div>
+        </div>
+        <div class="adv_pop_win_middle" style="min-height:100px;">
+            <div class="clearboth border_bottom margin-left-10" style="width:504px;"></div>
+            <div id="pop_win_content_area" class="pop_win_content" style="word-wrap:break-word;">&nbsp;</div>
+        </div>
+        <div class="adv_pop_win_bottom"></div>
+    </div>
+
+
+</body>
+
+</html>