2021-06-15 11:55:10 +00:00
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-16 08:30:14 +00:00
|
|
|
|
function onExecuteContractTrustfully(obj) {
|
|
|
|
|
console.log(obj);
|
|
|
|
|
$("#consistencyResult").html(global.executeResult.size + "个结果一致");
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-15 11:55:10 +00:00
|
|
|
|
function showContractResult(requestID) {
|
|
|
|
|
var data = global.responseCollector[requestID][0];
|
|
|
|
|
result = data;
|
|
|
|
|
$("#statusSpan")[0].innerHTML = result.status;
|
|
|
|
|
$("#timeSpan")[0].innerHTML = "调用耗时:" + data.executeTime + "(ms)";
|
2021-06-15 13:52:53 +00:00
|
|
|
|
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)
|
2021-06-15 11:55:10 +00:00
|
|
|
|
$("#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;
|
2021-08-09 13:08:23 +00:00
|
|
|
|
document.title = `数瑞浏览器(${host})`
|
2021-06-15 11:55:10 +00:00
|
|
|
|
if (!host.startsWith("ws")) {
|
2021-06-16 16:00:54 +00:00
|
|
|
|
if (location.href.startsWith("https")) {
|
|
|
|
|
host = "wss://" + host;
|
|
|
|
|
} else {
|
|
|
|
|
host = "ws://" + host;
|
|
|
|
|
}
|
2021-06-15 11:55:10 +00:00
|
|
|
|
}
|
|
|
|
|
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,
|
2021-06-15 13:52:53 +00:00
|
|
|
|
signature: sm2.doSignature(global.session, global.sm2Key.privateKey, {hash: true, der: true}),
|
2021-06-15 11:55:10 +00:00
|
|
|
|
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);
|
2021-08-09 13:34:06 +00:00
|
|
|
|
document.title = `数瑞浏览器(${global.currentContract.name} - ${$("#urlInput")[0].value})`
|
2021-06-15 11:55:10 +00:00
|
|
|
|
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"
|
2021-07-24 03:09:14 +00:00
|
|
|
|
+ " <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"
|
2021-06-15 11:55:10 +00:00
|
|
|
|
+ " <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"
|
2021-07-01 09:42:39 +00:00
|
|
|
|
+ " <input type=\"text\" class=\"form-control col-2\" id=\"gasInput\" placeholder=\"填写gas\" >\n"
|
2021-06-16 16:00:54 +00:00
|
|
|
|
+ " <div class=\"input-group-append input-group-text\">\n"
|
2021-06-16 10:49:45 +00:00
|
|
|
|
|
|
|
|
|
+ "<input type=\"checkbox\" id=\"executeContractAsDebug\" aria-label=\"Checkbox for isDebug\" data-toggle=\"tooltip\" title=\"模拟调用\"></input>"
|
|
|
|
|
+ " </div>\n"
|
|
|
|
|
|
2021-06-15 11:55:10 +00:00
|
|
|
|
+ " <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;
|
2021-07-24 03:09:14 +00:00
|
|
|
|
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>`);
|
2021-06-15 11:55:10 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
2021-06-15 13:52:53 +00:00
|
|
|
|
for (var i = 0; i < global.currentContract.exportedFunctions.length; i++) {
|
|
|
|
|
if (global.currentContract.exportedFunctions[i].functionName == funPos) {
|
2021-06-15 11:55:10 +00:00
|
|
|
|
funNode = global.currentContract.exportedFunctions[i];
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
console.log(funNode);
|
|
|
|
|
const argInput = $("#argInput");
|
2021-06-16 10:49:45 +00:00
|
|
|
|
var contract = global.currentContract;
|
2021-08-09 13:08:23 +00:00
|
|
|
|
var gas = $("#gasInput")[0].value / 1;
|
|
|
|
|
executeContractWithGas(contract.id, funNode.functionName, argInput[0].value, gas,
|
2021-06-16 16:00:54 +00:00
|
|
|
|
fillResultInternal, executeContractAsDebug.checked);
|
2021-07-01 09:42:39 +00:00
|
|
|
|
var iHtml = "/SCIDE/SCManager?action=executeContract&contractID="
|
2021-06-15 11:55:10 +00:00
|
|
|
|
+ global.currentContract.name + "&operation="
|
2021-07-01 09:42:39 +00:00
|
|
|
|
+ funNode.functionName + "&arg=" + argInput[0].value;
|
|
|
|
|
|
|
|
|
|
var toSign = global.currentContract.name + "|" + funNode.functionName + "|"
|
2021-08-09 13:08:23 +00:00
|
|
|
|
+ argInput[0].value;
|
|
|
|
|
if (gas > 0) {
|
|
|
|
|
toSign += "|" + gas;
|
|
|
|
|
iHtml += "&gasLimit=" + gas;
|
2021-07-01 09:42:39 +00:00
|
|
|
|
}
|
2021-08-09 13:08:23 +00:00
|
|
|
|
iHtml += "&pubkey=" + global.sm2Key.publicKey + "&signature=";
|
|
|
|
|
toSign += "|" + global.sm2Key.publicKey;
|
2021-06-15 13:52:53 +00:00
|
|
|
|
const signature = sm2.doSignature(toSign, global.sm2Key.privateKey, {hash: true, der: true});
|
2021-06-15 11:55:10 +00:00
|
|
|
|
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;
|
2021-06-15 13:52:53 +00:00
|
|
|
|
for (var i = 0; i < global.currentContract.exportedFunctions.length; i++) {
|
|
|
|
|
if (global.currentContract.exportedFunctions[i].functionName == funPos) {
|
2021-06-15 11:55:10 +00:00
|
|
|
|
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) {
|
2021-06-15 13:52:53 +00:00
|
|
|
|
if (global.responseCollector[data.responseID] == undefined) {
|
|
|
|
|
global.responseCollector[data.responseID] = [];
|
2021-06-15 11:55:10 +00:00
|
|
|
|
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)";
|
2021-08-09 13:08:23 +00:00
|
|
|
|
if (data.executionGas != undefined && data.executionGas > 0)
|
|
|
|
|
$("#timeSpan")[0].innerHTML += "<br> " + data.executionGas + "(gas)";
|
2021-07-01 09:42:39 +00:00
|
|
|
|
$("#timeSpan")[0].innerHTML
|
2021-06-15 13:52:53 +00:00
|
|
|
|
if (result.result instanceof Object) {
|
|
|
|
|
$("#responseArea")[0].value = JSON.stringify(result.result);
|
|
|
|
|
$("#timeSpan")[0].innerHTML += "<br> JSON格式";
|
|
|
|
|
} else {
|
|
|
|
|
$("#timeSpan")[0].innerHTML += "<br> 字符串格式";
|
2021-06-15 11:55:10 +00:00
|
|
|
|
$("#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);
|
2021-06-15 13:52:53 +00:00
|
|
|
|
for (var i = 0; i < scriptList.length; i++) {
|
2021-06-15 11:55:10 +00:00
|
|
|
|
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");
|
2021-06-15 13:52:53 +00:00
|
|
|
|
for (var i = 0; i < linkList.length; i++) {
|
2021-06-15 11:55:10 +00:00
|
|
|
|
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);
|
2021-06-16 08:30:14 +00:00
|
|
|
|
if (c.contractStatus == "KILLED") continue;
|
2021-06-15 11:55:10 +00:00
|
|
|
|
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() {
|
2021-06-15 13:52:53 +00:00
|
|
|
|
const urlParams = getRequestParameters();
|
2021-06-15 11:55:10 +00:00
|
|
|
|
initVue();
|
2021-06-15 13:52:53 +00:00
|
|
|
|
initGlobal(urlParams);
|
2021-06-15 11:55:10 +00:00
|
|
|
|
|
|
|
|
|
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() {
|
2021-06-16 15:42:41 +00:00
|
|
|
|
if (isBaaS) {
|
2021-06-15 13:52:53 +00:00
|
|
|
|
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];
|
|
|
|
|
}
|
2021-06-15 11:55:10 +00:00
|
|
|
|
}
|
2021-06-15 13:52:53 +00:00
|
|
|
|
return params;
|
2021-06-15 11:55:10 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-07 02:30:48 +00:00
|
|
|
|
|
2021-06-15 11:55:10 +00:00
|
|
|
|
function changeRender() {
|
|
|
|
|
if (global.urlparam["noRender"] === "true") {
|
|
|
|
|
global.urlparam["noRender"] = undefined;
|
|
|
|
|
switchRenderBtn.innerHTML = "不加载界面";
|
|
|
|
|
} else {
|
|
|
|
|
global.urlparam["noRender"] = "true";
|
|
|
|
|
switchRenderBtn.innerHTML = "加载界面";
|
|
|
|
|
}
|
|
|
|
|
changeApp();
|
|
|
|
|
}
|