bdcontract-web-client/js/bdwareclient.js
2021-08-06 15:45:45 +08:00

845 lines
28 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

var dtLang = {
"sProcessing": "处理中...",
"lengthMenu": '显示 <select>' + '<option value="5">5</option>'
+ '<option value="20">20</option>'
+ '<option value="100">100</option>'
+ '<option value="-1">全部</option>' + '</select> 项结果',
"sZeroRecords": "没有匹配结果",
"sInfo": "显示第 _START_ 至 _END_ 项结果,共 _TOTAL_ 项",
"sInfoEmpty": "显示第 0 至 0 项结果,共 0 项",
"sInfoFiltered": "(由 _MAX_ 项结果过滤)",
"sInfoPostFix": "",
"sSearch": "搜索:",
"sUrl": "",
"sEmptyTable": "表中数据为空",
"sLoadingRecords": "载入中...",
"sInfoThousands": ",",
"oPaginate": {
"sFirst": "首页",
"sPrevious": "上页",
"sNext": "下页",
"sLast": "末页"
},
"oAria": {
"sSortAscending": ": 以升序排列此列",
"sSortDescending": ": 以降序排列此列"
}
};
function applyRole(role) {
global.wssocket.send("{\"action\":\"applyNodeRole\",\"role\":\"" + role
+ "\",\"pubKey\":\"" + global.sm2Key.publicKey + "\"}");
}
function WSHandler(event) {
console.log(event);
data = event.data;
// console.log(" -->" + data);
try {
var obj = JSON.parse(data);
switch (obj.action) {
case 'onTransferTo':
onTransferTo(obj);
break;
case 'onHashResult':
onHashResult(obj);
break;
case 'onListMemoryFiles':
onListMemoryFiles(obj);
break;
case 'onDumpContract':
onDumpContract(obj);
break;
case 'onChangeDumpPeriod':
onChangeDumpPeriod(obj);
break;
case 'onGetDumpPeriod':
onGetDumpPeriod(obj);
break;
case 'onStaticVerifyResult':
onStaticVerifyResult(obj);
break;
case "onListContractProcess":
onListContractProcess(obj);
break;
case "onDeleteFile":
onDeleteFile(obj);
break;
case "onCancelAuth":
onCancelAuth(obj);
break;
case "onDownloadContract":
onDownloadFile(obj);
break;
case "onChangePublic":
onChangePublic(obj);
break;
case "onListProjects":
onListProjects(obj);
break;
case "onListProject":
onListProject(obj);
break;
case "onListLocalNodeLog":
onListLocalNodeLog(obj);
break;
case "onListLocalNodeLogPie":
onListLocalNodeLogPie(obj);
break;
case "onListLocalNodeLogLine":
onListLocalNodeLogLine(obj);
break;
case "onListTheContractProcess":
onListTheContractProcess(obj);
break;
case "onListLocalContractLog":
onListLocalContractLog(obj);
break;
case "onListLocalContractLogPie":
onListLocalContractLogPie(obj);
break;
case "onListLocalContractLogLine":
onListLocalContractLogLine(obj);
break;
case "onGetNodeSessionID":
case "onSessionID":
onGetNodeSessionID(obj);
break;
case "onLogin":
onNodeLogin(obj);
break;
case "onGetNodeRole":
case "onGetRole":
onGetNodeRole(obj);
break;
case "onApplyRole":
onApplyRole(obj);
break;
case "onListAllAuthRole":
onListAllAuthRole(obj);
break;
case "onListUnAuthRole":
onListUnAuthRole(obj);
break;
case "onDeleteRole":
onDeleteRole(obj);
break;
case "onCountRole":
onCountRole(obj);
break;
case "onAuthNodeRole":
onAuthNodeRole(obj);
break;
case "onApplyNet":
onApplyNet(obj);
break;
case "onLoadNodeConfig":
onLoadNodeConfig(obj);
break;
case "onChangeNodeName":
onChangeNodeName(obj);
break;
case "onChangeYJSPath":
onChangeYJSPath(obj);
break;
case "onChangeIpPort":
onChangeIpPort(obj);
break;
case "onGetLicenceExpiredDate":
$("#expiredDate").html(convertDate(data.data));
break;
case "onGetPeerID":
global.peerID = obj.data;
// getNodeTrustUnits();//still connecting to centerportalws
break;
case "onViewContractInstance":
onViewContractInstance(obj);
break;
case 'onExecuteResult':
onExecuteResult(obj);
break;
case 'onExecuteContractTrustfully':
onExecuteContractTrustfully(obj);
break;
case 'onUploadFile':
onUploadFile(obj);
break;
case 'onStartContract':
onStartContract(obj);
break;
case 'onStartContractConfig':
onStartContractConfig(obj);
break;
case 'onKillContractProcess':
onStopContract(obj);
break;
case 'onKillAllContract':
onKillAllContract(obj);
break;
case 'onSetPermission':
onSetPermission(obj);
break;
case 'onOutputStream':
displayOutput(obj);
break;
case 'onChangeNodeCenter':
console.log("onChangeNodeCenter");
onChangeNodeCenter(obj);
break;
case 'onException':
onException(obj);
break;
// logException(obj);
// break;
default:
displayOutput(obj);
break;
}
} catch (err) {
console.log(err);
}
}
function onException(obj) {
if (obj.data.startsWith("unauthorised action")) {
const action = obj.data.replace("unauthorised action ", "");
switch (action) {
case "listContractProcess":
mainVue.contracts = [];
if (global.urlparam["contract"]) {
appendTargetContract(global.urlparam["contract"]);
} else
alertNoPermission("listContractProcess无授权请申请ContractUser权限", "提示");
break;
default:
alertNoPermission(action + "无权限", "提示");
}
}
}
function alertNoPermission(message, title) {
const npSpan = $("#nopermissionSpan");
if (npSpan.length > 0) {
console.log(message + " status:" + $("#dialog")[0].getAttribute("class"));
npSpan.append("<br/>" + message);
} else {
let body = "<div class='row'><div class='col-sm-12'><span id='nopermissionSpan'>";
body += message;
body += "</span></div></div>";
$("#dialogBodyDiv").html(body);
showDialog("提示", function () {
$("#dialogBodyDiv").html("");
});
}
}
function onExecuteResult(obj) {
console.log(obj);
global.executeResult = obj;
if (global.executeResult.size) {
onExecuteContractTrustfully(obj);
}
onExecuteResultInternal(obj);
}
function onExecuteContractTrustfully(obj) {
console.log(obj);
$("#consistencyResult").html(global.executeResult.size + "个结果一致");
}
function showContractResult(requestID) {
var data = global.responseCollector[requestID][0];
result = data;
$("#statusSpan")[0].innerHTML = result.status;
$("#timeSpan")[0].innerHTML = "调用耗时:" + data.executeTime + "(ms)";
if (result.result instanceof Object) {
$("#responseArea")[0].value = JSON.stringify(result.result);
$("#timeSpan")[0].innerHTML += "<br> JSON格式";
} else {
$("#timeSpan")[0].innerHTML += "<br> 字符串格式";
$("#responseArea")[0].value = result.result;
}
if (global.responseCollector[requestID].hashCode != undefined)
$("#hashDisplayDiv").html("溯源指纹:" + global.responseCollector[requestID].hashCode);
}
function switchContractResult() {
const requestID = reqIDSpan.value;
showContractResult(requestID);
}
function showInconsistentResult(list) {
global.resultList = list;
let html = "<table class='table table-striped'><thead><tr><td>status</td><td>executeTime</td><td>result</td></tr></thead><tbody>";
for (const r of list) {
html += "<tr><td>";
const data = JSON.parse(r.data);
html += data.status;
html += "</td><td>";
html += r.executeTime;
html += "</td><td><textarea class='form-control'>";
html += data.result;
html += "</textarea></td></tr>";
}
html += "</tbody></table>";
const consistencyResult = $("#consistencyResult");
if (consistencyResult.length > 0) {
consistencyResult.html(html);
} else {
$("#dialogBodyDiv").html(html);
showDialog("调用结果不一致", function () {
}, () => {
});
}
}
function showDialog(title, cb, cancelcb) {
$("#dialogTitleH5").html(title);
$("#dialogConfimBtn").off("click").on("click", cb);
$("#dialogCloseBtn").off("click").on("click", cancelcb);
$("#dialog").modal("show");
}
function onHashResult(obj) {
$("#hashDisplayDiv").html("溯源指纹:" + obj.data);
global.responseCollector[obj.responseID].hashCode = obj.data;
}
function displayOutput(obj) {
console.log(obj);
}
function initWSocket() {
let host = $("#urlInput")[0].value;
if (!host.startsWith("ws")) {
if (location.href.startsWith("https")) {
host = "wss://" + host;
} else {
host = "ws://" + host;
}
}
if (host.endsWith("/SCIDE")) {
host += "/SCExecutor";
} else if (host.endsWith("/SCIDE/")) {
host += "SCExecutor";
} else if (host.endsWith("NodeCenterWS")) {
//..
} else if (!host.endsWith("/SCIDE/SCExecutor")) {
host += "/SCIDE/SCExecutor";
}
console.log("connect ws:" + host);
global.wssocket = createWssocket(host, () => {
getSession();
}, WSHandler);
global.responseCollector = {};
global.commited = {};
}
function getSession() {
global.wssocket.send("{\"action\":\"getSessionID\"}");
}
function exportSMKeyPair() {
const dialog = $("#dialog");
dialog.html("Save Your key:<br/>" + JSON.stringify(global.sm2Key));
dialog.dialog("open");
}
// ====== wsHandler
function onGetNodeSessionID(data) {
console.log("onGetNodeSessionID");
global.session = data.session;
const loginParam = {
pubKey: global.sm2Key.publicKey,
signature: sm2.doSignature(global.session, global.sm2Key.privateKey, {hash: true, der: true}),
action: "login"
};
global.wssocket.send(JSON.stringify(loginParam));
}
function onNodeLogin(data) {
pubkeyDialogVue.myRole = data.data;
global.myRole = data.data;
listContracts();
}
function listContracts() {
global.wssocket.send(JSON.stringify({action: "listContractProcess"}));
}
function changeApp() {
global.currentContract = global.contracts[$("#selectContract")[0].value];
if (!global.currentContract) {
return;
}
console.log(global.currentContract);
changeAppInternal(needRender(global.currentContract));
}
function changeAppInternal(requireRendering) {
if ((global.urlparam["noRender"] !== "true") && requireRendering) {
$("#mainDiv")[0].innerHTML = "";
executeCurrentContract("getMainFrame", "", parseMainFrame);
} else {
let title = "只包含计算逻辑";
if (requireRendering) {
title = "包含界面";
}
title += getContractDesp();
const html = " <div class='container'> <div class=\"card mt-3 \">\n"
+ " <div class=\"card-body\">\n"
+ " <h5 class=\"card-title\">"
+ title
+ "</h5>\n"
+ " <div class=\"card-body\" >\n"
+ " <div class=\"row\">\n"
+ " <div class=\"col-sm-12 d-flex justify-content-center\">\n"
+ " <div class=\"input-group mb-2\">\n"
+ " <div class=\"input-group-prepend input-group-text\">\n"
+ "<input type=\"checkbox\" id=\"showIOInput\" onchange=\"filterIOFunction()\" checked=\"on\" aria-label=\"Checkbox for ShowIO\" data-toggle=\"tooltip\" title=\"仅显示有IO函数\"></input>"
+ " </div>\n"
+ " <div class=\"input-group-append\">\n"
+ " <select id=\"selectAction\" onchange=\"showDescription()\" class=\"custom-select\" style=\"-webkit-appearance: none;\"><option value=\"-1\">选择方法</option></select> \n"
+ " </div>\n"
+ " <input type=\"text\" class=\"form-control\" id=\"argInput\" placeholder=\"填写参数\" >\n"
+ " <input type=\"text\" class=\"form-control col-2\" id=\"gasInput\" placeholder=\"填写gas\" >\n"
+ " <div class=\"input-group-append input-group-text\">\n"
+ "<input type=\"checkbox\" id=\"executeContractAsDebug\" aria-label=\"Checkbox for isDebug\" data-toggle=\"tooltip\" title=\"模拟调用\"></input>"
+ " </div>\n"
+ " <div class=\"input-group-append\">\n"
+ " <button class=\"btn btn-outline-secondary\" type=\"button\" \n"
+ " onclick=\"triggerExecuteCurrentContract()\">\n"
+ " 调用\n"
+ " </button>\n"
+ " </div>\n"
+ " </div>\n"
+ " </div>\n"
+ " </div>"
+ "<div class='row mb-2'><div class='col-sm-12 d-flex '>"
+ "<div class=\"input-group\" ><div class=\"input-group-prepend\" > <span class=\"input-group-text\" >方法描述</span></div><input class=\"input-group-text form-control\" id=\"descriptionSpan\" placeholder=\"暂无\"></input></div>"
+ "</div></div>"
+ "<div class='row mb-4'><div class='col-sm-12 d-flex'>"
+ "<div class=\"input-group \" ><div class=\"input-group-prepend\" > <span class=\"input-group-text\" >http接口</span></div><input class=\"input-group-text form-control\" id=\"sigOutput\"></input></div></div></div>\n"
+ " <h5 class=\"card-title\">调用结果</h5>\n"
+ " <div class=\"input-group mb-3\">\n"
+ " <div class=\"input-group-prepend\">\n"
+ " <select class=\"custom-select form-control\" onchange='switchContractResult()' style=\"-webkit-appearance:none; appearance:none; height:100%\" id=\"reqIDSpan\"><option>请求ID</option></select>\n"
+ " </div>\n"
+ " <div class=\"input-group-append\"><span class=\"input-group-text\" id=\"statusSpan\">调用状态</span></div>\n"
+ " <div class=\"input-group-append\"><span class=\"input-group-text\" id=\"timeSpan\">调用耗时</span></div>\n"
+ " <textarea id=\"responseArea\" class=\"form-control\"></textarea>\n"
+ " </div><div class='row mb-3'><div class='col-sm-12 d-flex' id='consistencyResult'> </div></div>"
+ " <div class='row'><div class='col-sm-12 d-flex' id='hashDisplayDiv'> </div></div>"
+ " </div>\n"
+ " </div>\n"
+ " </div></div>\n" + "";
$("#mainDiv")[0].innerHTML = html;
filterIOFunction();
}
}
function filterIOFunction(){
var showIO = showIOInput.checked;
$('#selectAction').html("<option value=\"-1\">选择方法</option>");
for (const f of global.currentContract.exportedFunctions) {
if (!showIO || f.relatedPermission.length!=0)
$('#selectAction')
.append(`<option value="${f.functionName}">${f.functionName}</option>`);
}
}
function getContractDesp() {
try {
const annos = global.currentContract.annotations;
for (const anno of annos) {
if (anno.type === "Description") {
return ", " + JSON.parse(anno.args[0]);
}
}
} catch (e) {
console.log(e);
}
return "";
}
function triggerExecuteCurrentContract() {
const funPos = $("#selectAction")[0].value;
console.log(funPos);
if (funPos < 0) {
$("#dialogBodyDiv").html("请选择方法。");
showDialog("提示");
return;
}
var funNode;
for (var i = 0; i < global.currentContract.exportedFunctions.length; i++) {
if (global.currentContract.exportedFunctions[i].functionName == funPos) {
funNode = global.currentContract.exportedFunctions[i];
break;
}
}
console.log(funNode);
const argInput = $("#argInput");
var contract = global.currentContract;
var gas = $("#gasInput")[0].value/1;
executeContractWithGas(contract.id, funNode.functionName, argInput[0].value,gas,
fillResultInternal, executeContractAsDebug.checked);
var iHtml = "/SCIDE/SCManager?action=executeContract&contractID="
+ global.currentContract.name + "&operation="
+ funNode.functionName + "&arg=" + argInput[0].value;
var toSign = global.currentContract.name + "|" + funNode.functionName + "|"
+ argInput[0].value ;
if (gas>0){
toSign+="|"+gas;
iHtml+="&gasLimit="+gas;
}
iHtml+= "&pubkey=" + global.sm2Key.publicKey + "&signature=";
toSign+= "|" + global.sm2Key.publicKey;
const signature = sm2.doSignature(toSign, global.sm2Key.privateKey, {hash: true, der: true});
let urlPre = $("#urlInput")[0].value;
if (urlPre.startsWith("ws")) {
urlPre = urlPre.replace("ws", "http");
}
$("#sigOutput")[0].value = (urlPre + iHtml + signature);
}
function showDescription() {
const funPos = $("#selectAction")[0].value;
console.log($("#selectAction")[0]);
console.log(funPos);
console.log(global.currentContract.exportedFunctions);
var funNode;
for (var i = 0; i < global.currentContract.exportedFunctions.length; i++) {
if (global.currentContract.exportedFunctions[i].functionName == funPos) {
funNode = global.currentContract.exportedFunctions[i];
break;
}
}
console.log(funNode);
for (const anno of funNode.annotations) {
if (anno.type === "Description") {
descriptionSpan.value = JSON.parse(anno.args[0]);
}
}
}
function fillResultInternal(result, data) {
if (global.responseCollector[data.responseID] == undefined) {
global.responseCollector[data.responseID] = [];
const reqIDSpan = $("#reqIDSpan");
reqIDSpan.append("<option value='" + data.responseID + "'>" + data.responseID + "</option>");
reqIDSpan[0].value = data.responseID;
}
global.responseCollector[data.responseID].push(data);
$("#statusSpan")[0].innerHTML = result.status;
$("#timeSpan")[0].innerHTML = "调用耗时:" + data.executeTime + "(ms)";
if (data.executionGas !=undefined && data.executionGas>0)
$("#timeSpan")[0].innerHTML+="<br> "+data.executionGas+"(gas)";
$("#timeSpan")[0].innerHTML
if (result.result instanceof Object) {
$("#responseArea")[0].value = JSON.stringify(result.result);
$("#timeSpan")[0].innerHTML += "<br> JSON格式";
} else {
$("#timeSpan")[0].innerHTML += "<br> 字符串格式";
$("#responseArea")[0].value = result.result;
}
}
function parseMainFrame(data) {
console.log("parseMainFrame");
console.log(data);
const mainHtml = data.result;
executeCurrentContract("loadResource", mainHtml, loadMain);
}
function loadMain(data) {
const html = data.result;
$("#mainDiv").append(html);
setTimeout(function () {
console.log("listSize:");
const scriptList = $("#mainDiv script");
global.scriptList = [];
global.scriptOrder = 0;
console.log("listSize:" + scriptList.length);
for (var i = 0; i < scriptList.length; i++) {
const script = scriptList[i];
const re = script.getAttribute("fromContract");
if (!re) {
continue;
}
global.scriptList.push(re);
}
if (global.scriptList.length > 0) {
executeCurrentContract("loadResource", global.scriptList[0], loadScript);
}
const linkList = $("#mainDiv link");
for (var i = 0; i < linkList.length; i++) {
const link = linkList[i];
const re = link.getAttribute("fromContract");
executeCurrentContract("loadResource", re, loadCss);
}
}, 100);
}
function loadScript(data) {
console.log("loadScript");
global.lastScript = data;
setTimeout(eval, 1, global.lastScript.result);
global.scriptOrder++;
if (global.scriptOrder < global.scriptList.length) {
executeCurrentContract("loadResource", global.scriptList[global.scriptOrder], loadScript);
}
}
function loadCss(data) {
console.log("loadScript");
global.lastCss = data;
const ele = document.createElement("style");
ele.setAttribute("type", "text/css");
ele.innerHTML = data.result;
document.body.append(ele);
}
function needRender(con) {
for (const fun of con.exportedFunctions) {
console.log(fun);
if (fun.functionName === "needRender") {
return true;
}
}
return false;
}
function onListContractProcess(data) {
console.log(data);
console.log(data.data);
global.contracts = JSON.parse(data.data);
if (global.urlparam["contract"]) {
appendTargetContract(global.urlparam["contract"]);
} else {
renewList();
}
}
function renewList() {
const selectedContract = $("#selectContract");
selectedContract.html("");
selectedContract.append("<option value='-1'>选择合约</option>");
let selectValue = -1;
console.log(global.contracts);
console.log(global.contracts.length);
for (let i = 0; i < global.contracts.length; ++i) {
const c = global.contracts[i];
console.log(c);
if (c.contractStatus == "KILLED") continue;
if (!c.id) {
c.id = c.contractID;
}
if (!c.name) {
c.name = c.contractName;
}
selectedContract.append(`<option value='${i}'>${c.name}</option>`);
if (global.urlparam["contract"]) {
if (global.urlparam["contract"] === c.name
|| global.urlparam["contract"] === c.id) {
selectValue = i;
}
}
}
console.log(selectValue);
selectedContract[0].value = selectValue;
if (global.urlparam["contract"]) {
changeApp();
}
}
function appendTargetContract(target) {
global.wssocket.send(JSON.stringify({
action: "listTheContractProcess",
contractID: target
}));
}
function onListTheContractProcess(target) {
console.log(target);
const c = JSON.parse(target.data);
let hasTheSame = false;
if (!global.contracts) {
global.contracts = [];
}
for (const con of global.contracts) {
if (con.id === c.id) {
hasTheSame = true;
}
}
if (!hasTheSame) {
global.contracts.push(c);
}
renewList();
//"884422533"
}
function onListLocalNodeLog(data) {
const userManTab = $("#v-pills-userManager-tab")[0];
if (userManTab.getAttribute("aria-selected") === "true") {
drawUserActivityGraph(data);
} else {
drawLocalLogGraphs(data);
}
}
function onListAllAuthRole(data) {
console.log("onListAllAuthRole");
fillAuthRoleData(data.data);
}
function onListUnAuthRole(data) {
console.log("onListUnAuthRole");
fillUnAuthRoleData(data.data);
}
function onApplyNet(data) {
console.log("onApplyNet");
}
function onCountRole(data) {
console.log("onCountRole");
setUserTypeDistribution(data.data);
}
function onAuthNodeRole(data) {
myToast("授权/忽略操作", data.data);
if (data.data === "success") {
global.wssocket.send(JSON.stringify({action: "listAllAuthRole"}));
global.wssocket.send(JSON.stringify({action: "listUnAuthRole"}));
}
}
function onApplyRole(data) {
console.log(data.data);
myToast("申请操作", data.data);
}
function onDeleteRole(data) {
myToast("删除操作", data.data);
global.wssocket.send(JSON.stringify({action: "listAllAuthRole"}));
}
// ====== wsHandler done!
function myToast(title, msg) {
toastVue.toastTitle = title;
toastVue.toastMessage = msg;
$("#alertDiv").toast("show");
}
function countChar(str, c) {
let ret = 0;
for (const ch of str) {
if (ch === c) {
ret++;
}
}
return ret;
}
function generate() {
const key = sm2.generateKeyPairHex();
global.sm2Key = key;
localStorage.setItem("PrivKey", JSON.stringify(key));
}
function killAllContract() {
global.wssocket.send(JSON.stringify({action: "killAllContract"}));
}
function init() {
const urlParams = getRequestParameters();
initVue();
initGlobal(urlParams);
if (global.urlparam["noRender"] === "true") {
switchRenderBtn.innerHTML = "加载界面";
}
global.cbs = {};
const urlInput = $("#urlInput");
if (global.urlparam["self"] === "true") {
if (document.location.href.startsWith("http")) {
let path = document.location.origin + document.location.pathname;
path = path.replace("/client/bdwareclient.html", "");
urlInput[0].value = path.replace("http",
"ws");
if (global.urlparam["withNodeCenterWS"] === "true") {
urlInput[0].value += "/NodeCenterWS";
}
connectNode();
}
} else if (global.urlparam["nodeAddr"]) {
urlInput[0].value = global.urlparam["nodeAddr"];
connectNode();
} else {
const lastNode = localStorage.getItem("lastNode");
if (lastNode) {
urlInput[0].value = lastNode;
connectNode();
}
}
}
function connectNode() {
localStorage.setItem("lastNode", $("#urlInput")[0].value);
initWSocket();
}
function getRequestParameters() {
if (isBaaS) {
let params = location.href.replace(/[^#]*(#(\/)?|\?)/, '')
let url = location.href.replace(params, '')
while (!params) {
url = url.replace(/(#(\/)?|\?)$/, '')
params = url.replace(/[^#]*(#(\/)?|\?)/, '')
url = url.replace(params, '')
}
if (url.endsWith('#') || url.endsWith('#\/')) {
let sKey = Math.random().toString()
localStorage.setItem(sKey, params)
location.href = url.replace(/#(\/)?/, '?' + sKey)
} else {
let json = atob(localStorage.getItem(params))
try {
return JSON.parse(json);
} catch (e) {
localStorage.removeItem(params)
alert('链接失效!')
location.href = location.origin
}
}
} else {
const arr = (location.search || "").replace(/^\?/, '').split("&");
const params = {};
for (const a of arr) {
const data = a.split("=");
if (data.length === 2) {
params[data[0]] = data[1];
}
}
return params;
}
}
function changeRender() {
if (global.urlparam["noRender"] === "true") {
global.urlparam["noRender"] = undefined;
switchRenderBtn.innerHTML = "不加载界面";
} else {
global.urlparam["noRender"] = "true";
switchRenderBtn.innerHTML = "加载界面";
}
changeApp();
}