bdcontract-web-client/js/bdwareclient.js

815 lines
27 KiB
JavaScript
Raw Normal View History

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 + "个结果一致");
}
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)
$("#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")) {
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,
2021-06-15 13:52:53 +00:00
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\">\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"
+ " <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;
for (const f of global.currentContract.exportedFunctions) {
$('#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;
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) {
funNode = global.currentContract.exportedFunctions[i];
break;
}
}
console.log(funNode);
const argInput = $("#argInput");
executeCurrentContract(funNode.functionName, argInput[0].value,
fillResultInternal);
const iHtml = "/SCIDE/SCManager?action=executeContract&contractID="
+ global.currentContract.name + "&operation="
+ funNode.functionName + "&arg=" + argInput[0].value
+ "&pubkey=" + global.sm2Key.publicKey + "&signature=";
const toSign = global.currentContract.name + "|" + funNode.functionName + "|"
+ argInput[0].value + "|" + global.sm2Key.publicKey;
2021-06-15 13:52:53 +00:00
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;
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) {
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] = [];
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-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;
}
}
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++) {
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++) {
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;
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();
initVue();
2021-06-15 13:52:53 +00:00
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() {
2021-06-15 13:52:53 +00:00
if (location.href.indexOf("BaaSClient") !== -1) {
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 13:52:53 +00:00
return params;
}
}
function changeRender() {
if (global.urlparam["noRender"] === "true") {
global.urlparam["noRender"] = undefined;
switchRenderBtn.innerHTML = "不加载界面";
} else {
global.urlparam["noRender"] = "true";
switchRenderBtn.innerHTML = "加载界面";
}
changeApp();
}