@ -0,0 +1,7 @@ | |||
import re | |||
with open('src/taskGrid/FlowChart.js', 'r', encoding='utf-8') as file: | |||
for line in file: | |||
line = re.split('//', line)[0] | |||
if re.search('[\u4e00-\u9fff]', line): | |||
print(line) |
@ -1,627 +0,0 @@ | |||
//处理表现层 | |||
let nodeList = Array(); //所有新生成的节点全部存储在这里,并且有唯一索引号,所有的定位均通过index进行,即将图保存下来了 | |||
let root = { | |||
index: 0, //在nodeList中的索引号 | |||
id: 0, | |||
parentId: 0, | |||
type: -1, | |||
option: 0, | |||
title: "root", | |||
sequence: [], | |||
parameters: { | |||
history: 1, | |||
tabIndex: 0, | |||
useLoop: false, //是否使用循环中的元素 | |||
xpath: "", //xpath | |||
wait: 0, | |||
waitType: 0, | |||
}, | |||
isInLoop: false, //是否处于循环内 | |||
}; | |||
nodeList.push(root); | |||
let queue = new Array(); | |||
let actionSequence = new Array(); //存储图结构,每个元素为在nodelist里面的索引值,下面的id和pid根据此数组进行索引,然后再在nodelist里找 | |||
let nowNode = null; //存储现在所在的节点 | |||
let vueData = { nowNodeIndex: 0 }; //存储目前所在节点的索引号,不能直接使用变量而需要用对象包起来 | |||
let option = 0; //工具箱选项 | |||
let title = ""; | |||
let parameterNum = 1; //记录目前的参数个数 | |||
//处理逻辑层 | |||
let app = new Vue({ | |||
el: '#app', | |||
data: { | |||
list: { nl: nodeList }, | |||
index: vueData, | |||
nodeType: 0, // 当前元素的类型 | |||
nowNode: null, // 用来临时存储元素的节点 | |||
codeMode: 0, //代码模式 | |||
loopType: -1, //点击循环时候用来循环选项 | |||
useLoop: false, //记录是否使用循环内元素 | |||
nowArrow: { "position": -1, "pId": 0, "num": 0 }, | |||
paras: { "parameters": [] }, //提取数据的参数列表 | |||
TClass: -1, //条件分支的条件类别 | |||
paraIndex: 0, //当前参数的index | |||
XPaths: "", //xpath列表 | |||
}, | |||
watch: { | |||
nowArrow: { //变量发生变化的时候进行一些操作 | |||
deep: true, | |||
handler: function(newVal, oldVal) { | |||
let arrlist = document.getElementsByClassName("arrow"); | |||
if (oldVal != null) { | |||
for (let i = 0; i < arrlist.length; i++) { | |||
if (arrlist[i].getAttribute("position") == oldVal["position"] && | |||
arrlist[i].getAttribute("pid") == oldVal["pId"]) { | |||
arrlist[i].style.backgroundColor = ""; // 时刻指示现在应该插入的节点的位置 | |||
break; | |||
} | |||
} | |||
} | |||
for (let i = 0; i < arrlist.length; i++) { | |||
if (arrlist[i].getAttribute("position") == newVal["position"] && | |||
arrlist[i].getAttribute("pid") == newVal["pId"]) { | |||
arrlist[i].style.backgroundColor = "lavender"; // 时刻指示现在应该插入的节点的位置 | |||
break; | |||
} | |||
} | |||
} | |||
}, | |||
loopType: { //循环类型发生变化的时候更新参数值 | |||
handler: function(newVal, oldVal) { | |||
this.nowNode["parameters"]["loopType"] = newVal; | |||
} | |||
}, | |||
TClass: { | |||
handler: function(newVal, oldVal) { | |||
this.nowNode["parameters"]["class"] = newVal; | |||
} | |||
}, | |||
useLoop: { | |||
handler: function(newVal, oldVal) { | |||
this.nowNode["parameters"]["useLoop"] = newVal; | |||
} | |||
}, | |||
paras: { | |||
handler: function(newVal, oldVal) { | |||
this.nowNode["parameters"]["paras"] = newVal["parameters"]; | |||
} | |||
}, | |||
codeMode: { | |||
handler: function(newVal, oldVal) { | |||
this.nowNode["parameters"]["codeMode"] = newVal; | |||
} | |||
} | |||
}, | |||
methods: { | |||
getCookies: function() { //获取cookies | |||
let command = new WebSocket("ws://localhost:"+getUrlParam("wsport")) | |||
command.onopen = function() { | |||
let message = { | |||
type: 7, //消息类型,0代表连接操作 | |||
}; | |||
this.send(JSON.stringify(message)); | |||
}; | |||
}, | |||
changeXPaths: function (XPaths){ | |||
let result = ""; | |||
for (let i = 0; i < XPaths.length; i++) { | |||
result += XPaths[i] + "\n"; | |||
} | |||
this.XPaths = result; | |||
}, | |||
addPara: function() { //添加参数 | |||
this.nowNode["parameters"]["paras"].push({ | |||
"nodeType": 0, | |||
"contentType": 0, | |||
"relative": false, | |||
"name": "自定义参数_" + this.nowNode["parameters"]["paras"].length.toString(), | |||
"desc": "", | |||
"extractType": 0, | |||
"relativeXPath": "//body", | |||
"recordASField": 1, | |||
"allXPaths": [], | |||
"exampleValues": [ | |||
{ | |||
"num": 0, | |||
"value": "自定义字段" | |||
} | |||
], | |||
"default": "", | |||
"beforeJS": "", | |||
"beforeJSWaitTime": 0, | |||
"JS": "", | |||
"paraType": "text", | |||
"JSWaitTime": 0, | |||
"afterJS": "", | |||
"afterJSWaitTime": 0, | |||
"downloadPic": 0 | |||
}); | |||
this.paraIndex = this.nowNode["parameters"]["paras"].length - 1; | |||
}, | |||
modifyParas: function(i) { //修改第i个参数 | |||
this.paraIndex = i; | |||
console.log(this.paras); | |||
}, | |||
deleteParas: function(i) { //删除第i个参数 | |||
this.nowNode["parameters"]["paras"].splice(i, 1); | |||
//如果参数删除完了,就把提取数据也删掉 | |||
if (this.nowNode["parameters"]["paras"].length == 0) { | |||
deleteElement(); | |||
} | |||
}, | |||
upParas: function(i) { //上移第i个参数 | |||
if (i != 0) { | |||
let t = this.nowNode["parameters"]["paras"].splice(i, 1)[0]; | |||
this.nowNode["parameters"]["paras"].splice(i - 1, 0, t); | |||
} | |||
}, | |||
downParas: function(i) { //下移第i个参数 | |||
if (i != this.nowNode["parameters"]["paras"].length - 1) { | |||
let t = this.nowNode["parameters"]["paras"].splice(i, 1)[0]; | |||
this.nowNode["parameters"]["paras"].splice(i + 1, 0, t); | |||
} | |||
}, | |||
getType: function(nodeType, contentType) { //根据类型得到字段名称 | |||
if (contentType == 2) { | |||
return "InnerHTML"; | |||
} else if (contentType == 3) { | |||
return "OuterHTML"; | |||
} | |||
if (nodeType == 2) { | |||
return "链接地址"; | |||
} else if (nodeType == 1) { | |||
return "链接文本"; | |||
} else if (nodeType == 4) { | |||
return "图片地址"; | |||
} else { | |||
return "文本"; | |||
} | |||
} | |||
} | |||
}) | |||
//深复制 | |||
function DeepClone(obj) { | |||
if (obj === null || typeof obj !== 'object') return obj; | |||
let cpObj = obj instanceof Array ? [] : {}; | |||
for (let key in obj) cpObj[key] = DeepClone(obj[key]); | |||
return cpObj; | |||
} | |||
// 根据元素类型返回不同元素的样式 | |||
function newNode(node) { | |||
id = node["id"]; | |||
title = node["title"]; | |||
type = node["type"]; | |||
if (type == 0) //顺序 | |||
{ | |||
return `<div class="sequence"><div class="node clk" data="${id}" dataType=${type} id = "${id}" position=${node["position"]} pId=${node["parentId"]}> | |||
<div > | |||
<p>${title}</p> | |||
</div> | |||
</div> | |||
<p class="arrow" position=${node["position"]} data = "${id}" pId=${node["parentId"]}>↓</p></div>`; | |||
} else if (type == 1) //循环 | |||
{ | |||
return `<div class="loop clk" data="${id}" dataType=${type} id = "${id}" position=${node["position"]} pId=${node["parentId"]}> | |||
<p style="background:#d6d6d6;text-align:left;padding:2px">${title}</p> | |||
<p class="arrow" position=-1 data = "${id}" pId=${id}>↓</p> | |||
</div> | |||
<p class="arrow" data = "${id}" position=${node["position"]} pId=${node["parentId"]}>↓</p></div>`; | |||
} else if (type == 2) //判断 | |||
{ | |||
return `<div class="loop clk" dataType=${type} data="${id}" position=${node["position"]} pId=${node["parentId"]}> | |||
<p style="background:#d6d6d6;text-align:left;padding:2px">${title}</p> | |||
<p class="branchAdd" data="${id}">点击此处在最左边增加条件分支</p> | |||
<div class="judge" id = "${id}"> | |||
</div></div> | |||
<p class="arrow" data = "${id}" position=${node["position"]} pId=${node["parentId"]}>↓</p></div>`; | |||
} else //判断分支 | |||
{ | |||
return `<div class="branch clk" dataType=${type} data="${id}" position=${node["position"]} pId=${node["parentId"]}> | |||
<p style="background:#d6d6d6;text-align:left;padding:2px">${title}</p> | |||
<p data = "${id}" class="arrow" position=-1 pId=${id}>↓</p> | |||
<div id = "${id}"> | |||
</div></div>`; | |||
} | |||
} | |||
function branchMouseDown(e) { | |||
if (e.button == 2) //右键点击 | |||
{ | |||
let judgeId = this.getAttribute('data'); | |||
let l = nodeList.length; | |||
let t = { | |||
index: l, | |||
id: 0, | |||
parentId: 0, | |||
type: 3, | |||
option: 10, | |||
title: "条件分支", | |||
sequence: [], | |||
isInLoop: false, | |||
}; | |||
addParameters(t) | |||
nodeList.push(t); | |||
nodeList[actionSequence[judgeId]]["sequence"].splice(0, 0, t.index); | |||
refresh(); | |||
app._data.nowArrow = { "position": -1, "pId": t["id"], "num": 0 }; | |||
$("#" + t["id"]).click(); | |||
} | |||
e.stopPropagation(); //防止冒泡 | |||
} | |||
function arrowMouseDown(e) { | |||
if (e.button == 2) //右键点击 | |||
{ | |||
if (option != 0) { | |||
app._data.nowArrow = { "position": this.getAttribute('position'), "pId": this.getAttribute('pId'), "num": 0 }; | |||
} | |||
toolBoxKernel(e); | |||
} | |||
} | |||
//增加分支点击事件 | |||
function branchClick(e) { | |||
let judgeId = this.getAttribute('data'); | |||
let l = nodeList.length; | |||
let t = { | |||
index: l, | |||
id: 0, | |||
parentId: 0, | |||
type: 3, | |||
option: 10, | |||
title: "条件分支", | |||
sequence: [], | |||
isInLoop: false, | |||
}; | |||
addParameters(t); | |||
nodeList.push(t); | |||
nodeList[actionSequence[judgeId]]["sequence"].splice(0, 0, t.index); | |||
refresh(); | |||
app._data.nowArrow = { "position": -1, "pId": t["id"], "num": 0 }; | |||
$("#" + t["id"]).click(); | |||
e.stopPropagation(); //防止冒泡 | |||
} | |||
function elementMousedown(e) { | |||
if (e.button == 2) //右键点击 | |||
{ | |||
if (nowNode != null) { | |||
nowNode.style.borderColor = "skyblue"; | |||
} | |||
nowNode = this; | |||
vueData.nowNodeIndex = actionSequence[this.getAttribute("data")]; | |||
this.style.borderColor = "blue"; | |||
handleElement(); //处理元素 | |||
} | |||
e.stopPropagation(); //防止冒泡 | |||
} | |||
//元素点击事件 | |||
function elementClick(e) { | |||
if (nowNode != null) { | |||
nowNode.style.borderColor = "skyblue"; | |||
} | |||
nowNode = this; | |||
vueData.nowNodeIndex = actionSequence[this.getAttribute("data")]; | |||
this.style.borderColor = "blue"; | |||
handleElement(); //处理元素 | |||
e.stopPropagation(); //防止冒泡 | |||
} | |||
//箭头点击事件 | |||
function arrowClick(e) { | |||
if (option != 0) { | |||
app._data.nowArrow = { "position": this.getAttribute('position'), "pId": this.getAttribute('pId'), "num": 0 }; | |||
} | |||
toolBoxKernel(e); | |||
} | |||
//增加元素函数 | |||
function addElement(op, para) { | |||
option = op; | |||
if (option == 1) { //打开网页选项 | |||
title = "打开网页"; | |||
} else { | |||
title = $(".options")[option - 1].innerHTML; //获取新增操作名称 | |||
} | |||
toolBoxKernel(null, para); | |||
} | |||
// 工具箱操作函数 | |||
function toolBoxKernel(e, para = null) { | |||
if (option == 13) { //调整锚点 | |||
// let tarrow = DeepClone(app.$data.nowArrow); | |||
// refresh(); | |||
// app._data.nowArrow =tarrow; | |||
} else if (option == 11) { //复制操作 | |||
if (nowNode == null) { | |||
e.stopPropagation(); //防止冒泡 | |||
} else if (nowNode.getAttribute("dataType") > 0) { | |||
alert("循环和判断、条件分支不可复制!"); | |||
e.stopPropagation(); //防止冒泡 | |||
} else { | |||
let position = parseInt(nowNode.getAttribute('position')); | |||
let pId = nowNode.getAttribute('pId'); | |||
let tt = nodeList[nodeList[actionSequence[pId]]["sequence"][position]]; //在相应位置添加新元素 | |||
t = DeepClone(tt); //浅复制元素 | |||
let l = nodeList.length; | |||
t.index = l; | |||
nodeList.push(t); | |||
let position2 = parseInt(app._data.nowArrow['position']); | |||
let pId2 = app._data.nowArrow['pId']; | |||
nodeList[actionSequence[pId2]]["sequence"].splice(position2 + 1, 0, t.index); //在相应位置添加新元素 | |||
refresh(); //重新渲染页面 | |||
app._data.nowArrow = { "position": t["position"], "pId": t["parentId"], "num": 0 }; | |||
$("#" + t["id"]).click(); //复制后点击复制后的元素 | |||
e.stopPropagation(); //防止冒泡 | |||
} | |||
} else if (option == 10) { //剪切操作 | |||
if (nowNode == null) { | |||
e.stopPropagation(); //防止冒泡 | |||
} else if ($(nowNode).is(".branch")) { | |||
alert("判断分支不可移动!"); | |||
e.stopPropagation(); //防止冒泡 | |||
} else { | |||
let position = parseInt(nowNode.getAttribute('position')); | |||
let pId = nowNode.getAttribute('pId'); | |||
let position2 = parseInt(app._data.nowArrow['position']); | |||
let pId2 = app._data.nowArrow['pId']; | |||
let id = nowNode.getAttribute('data'); | |||
let pidt = pId2; | |||
let move = true; | |||
console.log(pidt, id); | |||
while (pidt != 0) { | |||
if (pidt == id) { | |||
move = false; | |||
break; | |||
} | |||
pidt = nodeList[actionSequence[pidt]]["parentId"]; | |||
} | |||
if (move) //如果自己要移动到自己节点里就不允许移动 | |||
{ | |||
let element = nodeList[actionSequence[pId]]["sequence"].splice(position, 1); //在相应位置删除元素 | |||
if (pId == pId2 && position < position2) //如果要移动的位置属于同一层并且是从前往后移动,注意需要控制数组插入位置向前错位 | |||
{ | |||
position2--; | |||
} | |||
console.log(element); | |||
nodeList[actionSequence[pId2]]["sequence"].splice(position2 + 1, 0, element[0]); //在相应位置添加新元素 | |||
refresh(); //重新渲染页面 | |||
console.log(nodeList[element[0]]); | |||
app._data.nowArrow = { "position": nodeList[element[0]]["position"], "pId": nodeList[element[0]]["parentId"], "num": 0 }; | |||
$("#" + nodeList[element[0]]["id"]).click(); | |||
} else { | |||
alert("自己不能移动到自己的节点里!"); | |||
} | |||
e.stopPropagation(); //防止冒泡 | |||
} | |||
} else if (option > 0) { //新增操作 | |||
let l = nodeList.length; | |||
let t = { | |||
id: 0, | |||
index: l, | |||
parentId: 0, | |||
type: 0, | |||
option: option, | |||
title: title, | |||
sequence: [], | |||
isInLoop: false, | |||
}; | |||
nodeList.push(t); | |||
if (option == 8) //循环 | |||
{ | |||
t["type"] = 1; | |||
} else if (option == 9) //判断 | |||
{ | |||
t["type"] = 2; | |||
// 增加两个分支 | |||
let nt = { | |||
id: 0, | |||
parentId: 0, | |||
index: l + 1, | |||
type: 3, | |||
option: 10, | |||
title: "条件分支", | |||
sequence: [], | |||
isInLoop: false, | |||
}; | |||
let nt2 = { | |||
id: 0, | |||
parentId: 0, | |||
index: l + 2, | |||
type: 3, | |||
option: 10, | |||
title: "条件分支", | |||
sequence: [], | |||
isInLoop: false, | |||
}; | |||
t["sequence"].push(nt.index); | |||
t["sequence"].push(nt2.index); | |||
nodeList.push(nt) | |||
nodeList.push(nt2); | |||
addParameters(nt); //增加选项的默认参数 | |||
addParameters(nt2); //增加选项的默认参数 | |||
} | |||
let position = parseInt(app._data.nowArrow['position']); | |||
let pId = app._data.nowArrow['pId']; | |||
nodeList[actionSequence[pId]]["sequence"].splice(position + 1, 0, t.index); //在相应位置添加新元素 | |||
refresh(); //重新渲染页面 | |||
//下面是确定添加元素之后下一个要插入的节点的位置 | |||
app._data.nowArrow = { "position": t["position"], "pId": t["parentId"], "num": 0 }; | |||
addParameters(t); //增加选项的默认参数 | |||
if (para != null) { | |||
modifyParameters(t, para); | |||
} | |||
if (option == 8) //循环情况下应插入在循环里面 | |||
{ | |||
app._data.nowArrow = { "position": -1, "pId": t["id"], "num": 0 }; | |||
$("#" + t["id"]).click(); | |||
} else if (option == 9) //判断插入到第一个判断条件中 | |||
{ | |||
app._data.nowArrow = { "position": -1, "pId": nt["id"], "num": 0 }; | |||
$("#" + nt["id"]).click(); | |||
} else { | |||
$("#" + t["id"]).click(); | |||
} | |||
if (e != null) | |||
e.stopPropagation(); //防止冒泡 | |||
option = 0; | |||
return t; | |||
} | |||
option = 0; | |||
} | |||
$(".options").mousedown(function() { | |||
option = parseInt(this.getAttribute("data")); | |||
title = this.innerHTML; | |||
if (option >= 10 && option <= 12 && (nowNode == null || nowNode.getAttribute("id") == 0)) { | |||
alert("目前未选中元素"); | |||
} else if (option == 12) { | |||
deleteElement(); | |||
$(".options")[12].click(); | |||
} | |||
}); | |||
function bindEvents() { | |||
// 清空原来的listener然后再添加新的listener | |||
//以下绑定了左右键的行为 | |||
let rect = document.getElementsByClassName('clk'); | |||
for (let i = 0, rule; rule = rect[i++];) { | |||
rule.removeEventListener('mousedown', elementMousedown); | |||
rule.addEventListener('mousedown', elementMousedown); | |||
rule.removeEventListener('click', elementClick); | |||
rule.addEventListener('click', elementClick); | |||
} | |||
let arr = document.getElementsByClassName('arrow'); | |||
for (let i = 0, rule; rule = arr[i++];) { | |||
rule.removeEventListener('click', arrowClick); | |||
rule.addEventListener('click', arrowClick); | |||
rule.removeEventListener('mousedown', arrowMouseDown); | |||
rule.addEventListener('mousedown', arrowMouseDown); | |||
} | |||
let branch = document.getElementsByClassName('branchAdd'); | |||
for (let i = 0, rule; rule = branch[i++];) { | |||
rule.removeEventListener('click', branchClick); | |||
rule.addEventListener('click', branchClick); | |||
rule.removeEventListener('mousedown', branchMouseDown); | |||
rule.addEventListener('mousedown', branchMouseDown); | |||
} | |||
} | |||
//重新画图 | |||
function refresh(nowArrowReset = true) { | |||
$("#0").empty(); | |||
$("#0").append(`<div style="border-radius: 50%;width: 40px;height: 40px;border:solid;border-color:seagreen;margin:5px auto;background-color:lightcyan;margin-top:20px"> | |||
<p style="font-size: 24px!important;text-align: center;margin-left: 6px;font-family:'Times New Roman'">▶</p> | |||
</div> | |||
<p id="firstArrow" class="arrow" position=-1 pId=0>↓</p>`); | |||
actionSequence.splice(0); | |||
queue.splice(0); | |||
let idd = 1; | |||
queue.push(0); | |||
actionSequence.push(0); | |||
while (queue.length != 0) { | |||
let nd = queue.shift(); //取出父元素并建立对子元素的链接 | |||
for (let i = 0; i < nodeList[nd].sequence.length; i++) { | |||
nodeList[nodeList[nd].sequence[i]].parentId = nodeList[nd].id; | |||
nodeList[nodeList[nd].sequence[i]]["position"] = i; | |||
nodeList[nodeList[nd].sequence[i]].id = idd++; | |||
//检测元素是否位于循环内 | |||
if (nodeList[nd].option == 8 || nodeList[nd].isInLoop) { | |||
nodeList[nodeList[nd].sequence[i]].isInLoop = true; | |||
} else { | |||
nodeList[nodeList[nd].sequence[i]].isInLoop = false; | |||
} | |||
queue.push(nodeList[nd].sequence[i]); | |||
actionSequence.push(nodeList[nd].sequence[i]); | |||
} | |||
} | |||
if (nowArrowReset) //如果要重置锚点位置 | |||
{ | |||
app._data.nowArrow = { "position": nodeList[0].sequence.length - 1, "pId": 0, "num": 0 }; //设置默认要添加的位置是元素流程最开头处 | |||
} | |||
//第一个元素不渲染 | |||
for (let i = 1; i < actionSequence.length; i++) { | |||
let parentId = nodeList[actionSequence[i]]["parentId"]; | |||
$("#" + parentId).append(newNode(nodeList[actionSequence[i]])); | |||
} | |||
bindEvents(); | |||
} | |||
function deleteElement() { | |||
if (nowNode.getAttribute("id") == 0) { | |||
alert("当前未选中元素!"); //root | |||
return; | |||
} | |||
// if (nodeList[actionSequence[nowNode.getAttribute("data")]]["option"] == 1) { | |||
// alert("打开网页操作不可删除!"); | |||
// return; | |||
// } | |||
let position = parseInt(nowNode.getAttribute('position')); | |||
let pId = nowNode.getAttribute('pId'); | |||
let tnode = nodeList[actionSequence[pId]]["sequence"].splice(position, 1); //在相应位置删除元素 | |||
//循环的标记已经被删除的元素,因为删除循环后,循环内的元素也会 | |||
let queue = new Array(); | |||
queue.push(tnode[0]); | |||
while (queue.length > 0) { | |||
let index = queue.shift(); | |||
nodeList[index]["id"] = -1; //标记服务已被删除 | |||
for (let i = 0; i < nodeList[index]["sequence"].length; i++) { | |||
queue.push(nodeList[index]["sequence"][i]); | |||
} | |||
} | |||
app._data["nowNode"] = null; | |||
app._data["nodeType"] = 0; | |||
vueData.nowNodeIndex = 0; | |||
if (nowNode.getAttribute("datatype") == 3) { //如果删掉的是条件分支的话 | |||
pId = nowNode.parentNode.parentNode.getAttribute('pId'); | |||
position = nowNode.parentNode.parentNode.getAttribute('position'); | |||
} | |||
app.$data.nowArrow = { position: position - 1, "pId": pId, "num": 0 }; //删除元素后锚点跳转到当前元素的上一个节点 | |||
refresh(false); //重新渲染页面 | |||
nowNode = null; //取消选择 | |||
} | |||
document.oncontextmenu = function() { | |||
return false; | |||
} //屏蔽右键菜单 | |||
//删除元素 | |||
document.onkeydown = function(e) { | |||
if (nowNode != null && e.keyCode == 46) { | |||
// if (confirm("确定要删除元素吗?")) { | |||
deleteElement(); | |||
// } | |||
} else { //ctrl+s保存服务 | |||
let currKey = 0; | |||
currKey = e.keyCode || e.which || e.charCode; | |||
if (currKey == 83 && (e.ctrlKey || e.metaKey)) { | |||
$('#save').click(); | |||
return true; | |||
} else if (currKey == 116) { | |||
location.reload(); | |||
} else if (currKey == 123) { | |||
console.log("打开devtools") | |||
let command = new WebSocket("ws://localhost:"+getUrlParam("wsport")) | |||
command.onopen = function() { | |||
let message = { | |||
type: 6, //消息类型,0代表连接操作 | |||
}; | |||
this.send(JSON.stringify(message)); | |||
}; | |||
} | |||
} | |||
} | |||
function inputDelete(e) { | |||
if (e.keyCode == 46) { | |||
e.stopPropagation(); //输入框按delete应该正常运行 | |||
//Electron中如果有alert或者confirm,执行后会卡死输入框,所以最好不要用 | |||
} | |||
} |
@ -1,511 +0,0 @@ | |||
exampleMsg = { //示例消息 | |||
"type": 0, //消息类型,1代表增加操作 | |||
"data": { | |||
"option": 1, //增加选项 | |||
"parameters": { //传入的参数 | |||
"url": "https://www.baidu.com" | |||
} | |||
} | |||
} | |||
console.log(JSON.stringify(exampleMsg)); | |||
ws = new WebSocket("ws://localhost:"+getUrlParam("wsport")); | |||
ws.onopen = function() { | |||
// Web Socket 已连接上,使用 send() 方法发送数据 | |||
console.log("已连接"); | |||
message = { | |||
type: 0, //消息类型,0代表链接操作 | |||
message: { | |||
id: 2, //socket id | |||
} | |||
}; | |||
this.send(JSON.stringify(message)); | |||
}; | |||
ws.onclose = function() { | |||
// 关闭 websocket | |||
console.log("连接已关闭..."); | |||
}; | |||
let old_title = ""; | |||
ws.onmessage = function(evt) { | |||
evt = JSON.parse(evt.data); | |||
console.log(evt); | |||
if (evt["type"] == "title") { //如果不是特殊处理的话,默认全部是增加元素操作 | |||
if (old_title == "New Task") { //只记录第一次的title | |||
$("#serviceName").val(evt.data.title); | |||
} | |||
old_title = evt.data.title; | |||
} else { | |||
handleAddElement(evt); //处理增加元素操作 | |||
} | |||
}; | |||
function changeGetDataParameters(msg, i) { | |||
msg["parameters"][i]["default"] = ""; //找不到元素时候的默认值 | |||
msg["parameters"][i]["paraType"] = "text"; //参数类型 | |||
msg["parameters"][i]["recordASField"] = 1; //是否记录为字段值 | |||
msg["parameters"][i]["beforeJS"] = ""; //执行前执行的js | |||
msg["parameters"][i]["beforeJSWaitTime"] = 0; //执行前js等待时间 | |||
msg["parameters"][i]["JS"] = ""; //如果是JS,需要执行的js | |||
msg["parameters"][i]["JSWaitTime"] = 0; //JS等待时间 | |||
msg["parameters"][i]["afterJS"] = ""; //执行后执行的js | |||
msg["parameters"][i]["afterJSWaitTime"] = 0; //执行后js等待时间 | |||
msg["parameters"][i]["downloadPic"] = 0; //是否下载图片 | |||
} | |||
function extractTitle(html) { | |||
var match = html.match(/<title[^>]*>([^<]+)<\/title>/i); | |||
if (match && match[1]) { | |||
return "采集" + match[1]; | |||
} else { | |||
return "采集新Web页面"; | |||
} | |||
} | |||
function handleAddElement(msg) { | |||
if (msg["type"] == "openPage") { | |||
addElement(1, msg); | |||
} else if (msg["type"] == "singleClick") { | |||
addElement(2, msg); | |||
} else if (msg["type"] == "inputText") { | |||
addElement(4, msg); | |||
} else if (msg["type"] == "changeOption"){ | |||
addElement(6, msg); | |||
} else if (msg["type"] == "mouseMove") { | |||
addElement(7, msg); | |||
} else if (msg["type"] == "loopMouseMove") { | |||
addElement(8, msg); | |||
addElement(7, msg); | |||
} else if (msg["type"] == "loopClickSingle") { | |||
addElement(8, msg); | |||
addElement(2, msg); | |||
app._data.nowArrow["position"] = -1; //循环点击单个元素,下一个要插入的位置一般在元素上方 | |||
} else if (msg["type"] == "loopClickEvery") { | |||
addElement(8, msg); | |||
addElement(2, msg); | |||
} else if (msg["type"] == "singleCollect" || msg["type"] == "multiCollectNoPattern") { | |||
if (app._data.nowNode != null && app._data["nowNode"]["option"] == 3) { //如果现在节点就是提取数据节点,直接在此节点添加参数,而不是生成一个新的提取数据节点 | |||
for (let i = 0; i < msg["parameters"].length; i++) { | |||
changeGetDataParameters(msg, i); | |||
app._data["nowNode"]["parameters"]["paras"].push(msg["parameters"][i]); | |||
} | |||
app._data.paras.parameters = app._data["nowNode"]["parameters"]["paras"]; | |||
} else { | |||
addElement(3, msg); | |||
} | |||
notifyParameterNum(msg["parameters"].length); //通知浏览器端参数的个数变化 | |||
} else if (msg["type"] == "multiCollectWithPattern") { | |||
addElement(8, msg); | |||
addElement(3, msg); | |||
notifyParameterNum(msg["parameters"].length); //通知浏览器端参数的个数变化 | |||
} else if(msg["type"] == "GetCookies"){ | |||
for(let node of nodeList){ | |||
if(node["option"] == 1){ | |||
node["parameters"]["cookies"] = msg["message"]; | |||
$("#pageCookies").val(msg["message"]); | |||
break; | |||
} | |||
} | |||
} | |||
} | |||
function notifyParameterNum(num) { | |||
parameterNum += num; | |||
let message = { | |||
type: 3, //消息类型,3代表元素增加事件 | |||
from: 1, //0代表从浏览器到流程图,1代表从流程图到浏览器 | |||
message: { "pipe": JSON.stringify({ "type": 0, "value": parameterNum }) } // {}全选{BS}退格 | |||
}; | |||
window.ws.send(JSON.stringify(message)); | |||
} | |||
// function isExtract() { //检测当前锚点之前的元素是否为提取数据字段 | |||
// if (app.$data.nowArrow["position"] == -1) { | |||
// return false; | |||
// } else if (nodeList[nodeList[app.$data.nowArrow["pId"]].sequence[app.$data.nowArrow["position"]]]["option"] == 3) { | |||
// return true; | |||
// } else { | |||
// return false; | |||
// } | |||
// } | |||
// 流程图元素点击后的处理逻辑,注意在FlowChart_CN.js中watch的那些数据的加载都需要在这里执行!!! | |||
function handleElement() { | |||
app._data["nowNode"] = nodeList[vueData.nowNodeIndex]; | |||
app._data["nodeType"] = app._data["nowNode"]["option"]; | |||
app._data.useLoop = app._data["nowNode"]["parameters"]["useLoop"]; | |||
if (app._data["nodeType"] == 8) { | |||
app._data.loopType = app._data["nowNode"]["parameters"]["loopType"]; | |||
} else if (app._data["nodeType"] == 3) { | |||
app._data.paraIndex = 0; //参数索引初始化 | |||
app._data.paras.parameters = app._data["nowNode"]["parameters"]["paras"]; | |||
} else if(app._data["nodeType"] == 5){ | |||
app._data.codeMode = app._data["nowNode"]["parameters"]["codeMode"]; | |||
} else if (app._data["nodeType"] == 10) { | |||
app._data.TClass = app._data["nowNode"]["parameters"]["class"]; | |||
} | |||
} | |||
// 新增元素时的默认参数处理 | |||
function addParameters(t) { | |||
t["parameters"] = { | |||
history: 1, | |||
tabIndex: 0, | |||
useLoop: false, //是否使用循环中的元素 | |||
xpath: "", //xpath | |||
iframe: false, //是否在iframe中 | |||
wait: 0, //执行后等待 | |||
waitType: 0, //等待类型,0代表固定时间,1代表随机等待 | |||
beforeJS: "", //执行前执行的js | |||
beforeJSWaitTime: 0, //执行前js等待时间 | |||
afterJS: "", //执行后执行的js | |||
afterJSWaitTime: 0, //执行后js等待时间 | |||
}; //公共参数处理 | |||
if (t.option == 1) { | |||
t["parameters"]["url"] = "about:blank"; | |||
t["parameters"]["links"] = "about:blank"; | |||
t["parameters"]["maxWaitTime"] = 10; //最长等待时间 | |||
t["parameters"]["scrollType"] = 0; //滚动类型,0不滚动,1向下滚动1屏,2滚动到底部 | |||
t["parameters"]["scrollCount"] = 1; //滚动次数 | |||
t["parameters"]["scrollWaitTime"] = 1; //滚动后等待时间 | |||
t["parameters"]["cookies"] = ""; //cookies | |||
} else if (t.option == 2) { //点击元素 | |||
t["parameters"]["scrollType"] = 0; //滚动类型,0不滚动,1向下滚动1屏,2滚动到底部 | |||
t["parameters"]["scrollCount"] = 1; //滚动次数 | |||
t["parameters"]["scrollWaitTime"] = 1; //滚动后等待时间 | |||
t["parameters"]["clickWay"] = 0; //点击方式,0代表selenium点击,1代表js点击 | |||
t["parameters"]["maxWaitTime"] = 10; //最长等待时间 | |||
t["parameters"]["paras"] = []; //默认参数列表 | |||
t["parameters"]["wait"] = 2; //点击后等待时间默认2s | |||
t["parameters"]["beforeJS"] = ""; //执行前执行的js | |||
t["parameters"]["beforeJSWaitTime"] = 0; //执行前js等待时间 | |||
t["parameters"]["afterJS"] = ""; //执行后执行的js | |||
t["parameters"]["afterJSWaitTime"] = 0; //执行后js等待时间 | |||
} else if (t.option == 3) { //提取数据 | |||
t["parameters"]["paras"] = []; //默认参数列表 | |||
} else if (t.option == 4) { //输入文字 | |||
t["parameters"]["value"] = ""; | |||
t["parameters"]["beforeJS"] = ""; //执行前执行的js | |||
t["parameters"]["beforeJSWaitTime"] = 0; //执行前js等待时间 | |||
t["parameters"]["afterJS"] = ""; //执行后执行的js | |||
t["parameters"]["afterJSWaitTime"] = 0; //执行后js等待时间 | |||
} else if(t.option == 5) { //自定义操作 | |||
t["parameters"]["codeMode"] = 0; //代码模式,0代表JS, 2代表系统级别 | |||
t["parameters"]["code"] = ""; | |||
t["parameters"]["waitTime"] = 0; //最长等待时间 | |||
t["parameters"]["recordASField"] = 0; //是否记录脚本输出 | |||
t["parameters"]["paraType"] = "text"; //记录脚本输出的字段索引 | |||
} else if (t.option == 8) { //循环 | |||
t["parameters"]["scrollType"] = 0; //滚动类型,0不滚动,1向下滚动1屏,2滚动到底部 | |||
t["parameters"]["scrollCount"] = 1; //滚动次数 | |||
t["parameters"]["scrollWaitTime"] = 1; //滚动后等待时间 | |||
t["parameters"]["loopType"] = 0; //默认循环类型 | |||
t["parameters"]["xpath"] = ""; | |||
t["parameters"]["pathList"] = ""; | |||
t["parameters"]["textList"] = ""; | |||
t["parameters"]["code"] = ""; //执行的代码 | |||
t["parameters"]["waitTime"] = 0; //最长等待时间 | |||
t["parameters"]["exitCount"] = 0; //执行多少次后退出循环,0代表不设置此条件 | |||
t["parameters"]["historyWait"] = 2; //历史记录回退时间,用于循环点击每个链接的情况下点击链接后不打开新标签页的情况 | |||
t["parameters"]["breakMode"] = 0; //break类型,0代表JS,2代表系统命令 | |||
t["parameters"]["breakCode"] = ""; //break条件 | |||
t["parameters"]["breakCodeWaitTime"] = 0; //break条件等待时间 | |||
} else if (t.option == 9) { //条件 | |||
} else if (t.option == 10) { //条件分支 | |||
t["parameters"]["class"] = 0; //0代表什么条件都没有,1代表当前页面包括文本,2代表当前页面包括元素,3代表当前循环包括文本,4代表当前循环包括元素 | |||
t["parameters"]["value"] = ""; //相关值 | |||
t["parameters"]["code"] = ""; //code | |||
t["parameters"]["waitTime"] = 0; //最长等待时间 | |||
} | |||
} | |||
//修改元素参数,注意所有socket传过来的参数都需要在这里赋值给操作 | |||
function modifyParameters(t, para) { | |||
t["parameters"]["history"] = para["history"]; | |||
t["parameters"]["tabIndex"] = para["tabIndex"]; | |||
t["parameters"]["iframe"] = para["iframe"]; | |||
if (t.option == 1) { | |||
t["parameters"]["url"] = para["url"]; | |||
t["parameters"]["links"] = para["links"]; | |||
$("#serviceDescription").val(para["url"]); | |||
$("#url").val(para["url"]); | |||
} else if (t.option == 2) { //鼠标点击事件 | |||
t["parameters"]["xpath"] = para["xpath"]; | |||
t["parameters"]["useLoop"] = para["useLoop"]; | |||
t["parameters"]["allXPaths"] = para["allXPaths"]; | |||
} else if (t.option == 4) { //输入文字事件 | |||
t["parameters"]["value"] = para["value"]; | |||
t["parameters"]["xpath"] = para["xpath"]; | |||
t["parameters"]["allXPaths"] = para["allXPaths"]; | |||
} else if(t.option == 6){ | |||
t["parameters"]["xpath"] = para["xpath"]; | |||
t["parameters"]["allXPaths"] = para["allXPaths"]; | |||
t["parameters"]["optionMode"] = para["optionMode"]; | |||
t["parameters"]["optionValue"] = para["optionValue"]; | |||
} else if(t.option == 7){ | |||
t["parameters"]["xpath"] = para["xpath"]; | |||
t["parameters"]["useLoop"] = para["useLoop"]; | |||
t["parameters"]["allXPaths"] = para["allXPaths"]; | |||
} else if (t.option == 8) { //循环事件 | |||
t["parameters"]["loopType"] = para["loopType"]; | |||
t["parameters"]["xpath"] = para["xpath"]; | |||
t["parameters"]["allXPaths"] = para["allXPaths"]; | |||
if (para["nextPage"]) { //循环点击下一页的情况下 | |||
t["title"] = "循环点击下一页" | |||
} else { | |||
t["title"] = "循环" | |||
} | |||
if (para["loopType"] == 2) //如果是固定元素列表 | |||
{ | |||
t["parameters"]["pathList"] = para["pathList"].join("\n"); | |||
} | |||
} else if (t.option == 3) { //采集数据 | |||
for (let i = 0; i < para["parameters"].length; i++) { | |||
changeGetDataParameters(para, i); | |||
} | |||
t["parameters"]["paras"] = para["parameters"]; | |||
} | |||
} | |||
function updateUI() { | |||
refresh(false); | |||
app.$data.nowArrow["num"]++; //改变元素的值,通知画图,重新对锚点画图 | |||
let tnodes = document.getElementsByClassName("clk"); | |||
let position = nodeList[vueData.nowNodeIndex]["position"]; | |||
let pid = nodeList[vueData.nowNodeIndex]["parentId"]; | |||
for (let i = 0; i < tnodes.length; i++) { | |||
if (position == tnodes[i].getAttribute("position") && pid == tnodes[i].getAttribute("pId")) { | |||
tnodes[i].style.borderColor = "blue"; // 点击了确定按钮之后需要重新对选中的颜色画框 | |||
nowNode = tnodes[i]; | |||
break; | |||
} | |||
} | |||
} | |||
//点击确定按钮时的处理 | |||
$("#confirm").mousedown(updateUI); | |||
//获取url中的参数 | |||
function getUrlParam(name) { | |||
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象 | |||
var r = window.location.search.substr(1).match(reg); //匹配目标参数 | |||
if (r != null) return unescape(r[2]); | |||
return ""; | |||
} | |||
var sId = getUrlParam('id'); | |||
var backEndAddressServiceWrapper = getUrlParam("backEndAddressServiceWrapper"); | |||
let mobile = getUrlParam("mobile"); | |||
if (mobile == "true") { | |||
$("#environment").val(1); | |||
} | |||
function isValidMySQLTableName(tableName) { | |||
// 正则表达式:以字母或汉字开头,后接字母、数字、下划线或汉字的字符串,长度为1到64字符 | |||
const pattern = /^[\u4e00-\u9fa5a-zA-Z][\u4e00-\u9fa5a-zA-Z0-9_]{0,63}$/; | |||
return pattern.test(tableName); | |||
} | |||
function saveService(type) { | |||
let serviceId = $("#serviceId").val(); | |||
let text = "确认要保存任务吗(不能用鼠标点击时,请按键盘回车键)?"; | |||
if (type == 1) { //任务另存为 | |||
serviceId = -1; | |||
text = "确认要另存为任务吗(不能用鼠标点击时,请按键盘回车键)?"; | |||
} | |||
// if (confirm(text)) { | |||
let serviceName = $("#serviceName").val(); | |||
let url = $("#url").val(); | |||
let serviceDescription = $("#serviceDescription").val(); | |||
let inputParameters = []; | |||
let outputParameters = []; | |||
let outputNames = []; | |||
let inputIndex = 0; | |||
let outputIndex = 0; | |||
let links = ""; //记录所有的link | |||
let containJudge = false; //是否含有判断语句 | |||
let saveThreshold = parseInt($("#saveThreshold").val()); | |||
let cloudflare = parseInt($("#cloudflare").val()); | |||
let environment = parseInt($("#environment").val()); | |||
for (let i = 1; i < nodeList.length; i++) { | |||
if (nodeList[i]["id"] != -1) { //已经被删除的节点不进行统计 | |||
if (nodeList[i]["option"] == 1) //打开网页操作,统计输入框输入操作 | |||
{ | |||
if (!nodeList[i]["parameters"]["useLoop"]) //如果不是使用循环里的文本 | |||
{ | |||
inputParameters.push({ | |||
id: inputIndex, | |||
name: "urlList_" + inputIndex++, | |||
nodeId: i, //记录操作位于的节点位置,重要!!! | |||
nodeName: nodeList[i]["title"], | |||
value: nodeList[i]["parameters"]["links"], | |||
desc: "要采集的网址列表,多行以\\n分开", | |||
type: "text", | |||
exampleValue: nodeList[i]["parameters"]["links"] | |||
}); | |||
links = nodeList[i]["parameters"]["links"]; | |||
} | |||
} else if (nodeList[i]["option"] == 4) //输入文字操作 | |||
{ | |||
if (!nodeList[i]["parameters"]["useLoop"]) //如果不是使用循环里的文本 | |||
{ | |||
inputParameters.push({ | |||
id: inputIndex, | |||
name: "inputText_" + inputIndex++, | |||
nodeName: nodeList[i]["title"], | |||
nodeId: i, | |||
desc: "要输入的文本,如京东搜索框输入:电脑", | |||
type: "text", | |||
exampleValue: nodeList[i]["parameters"]["value"], | |||
value: nodeList[i]["parameters"]["value"], | |||
}); | |||
} | |||
} else if (nodeList[i]["option"] == 8) //循环操作 | |||
{ | |||
if (parseInt(nodeList[i]["parameters"]["loopType"]) > 2 && parseInt(nodeList[i]["parameters"]["loopType"]) < 5) { //循环中的循环输入文本或循环输入网址 | |||
inputParameters.push({ | |||
id: inputIndex, | |||
name: "loopText_" + inputIndex++, | |||
nodeId: i, | |||
nodeName: nodeList[i]["title"], | |||
desc: "要输入的文本/网址,多行以\\n分开", | |||
type: "text", | |||
exampleValue: nodeList[i]["parameters"]["textList"], | |||
value: nodeList[i]["parameters"]["textList"], | |||
}); | |||
} else if (parseInt(nodeList[i]["parameters"]["loopType"]) == 0) { | |||
inputParameters.push({ | |||
id: inputIndex, | |||
name: "loopTimes_" + nodeList[i]["title"] + "_" + inputIndex++, | |||
nodeId: i, | |||
nodeName: nodeList[i]["title"], | |||
desc: "循环" + nodeList[i]["title"] + "执行的次数(0代表无限循环)", | |||
type: "int", | |||
exampleValue: nodeList[i]["parameters"]["exitCount"], | |||
value: nodeList[i]["parameters"]["exitCount"], | |||
}); | |||
} | |||
} else if (nodeList[i]["option"] == 3) //提取数据操作 | |||
{ | |||
for (let j = 0; j < nodeList[i]["parameters"]["paras"].length; j++) { | |||
if (outputNames.indexOf(nodeList[i]["parameters"]["paras"][j]["name"]) < 0) { //参数名称还未被添加 | |||
outputNames.push(nodeList[i]["parameters"]["paras"][j]["name"]); | |||
outputParameters.push({ | |||
id: outputIndex++, | |||
name: nodeList[i]["parameters"]["paras"][j]["name"], | |||
desc: nodeList[i]["parameters"]["paras"][j]["desc"], | |||
type: nodeList[i]["parameters"]["paras"][j]["paraType"], | |||
recordASField: nodeList[i]["parameters"]["paras"][j]["recordASField"], | |||
exampleValue: nodeList[i]["parameters"]["paras"][j]["exampleValues"][0]["value"], | |||
}); | |||
} | |||
} | |||
} else if (nodeList[i]["option"] == 5) //自定义操作 | |||
{ | |||
// if (nodeList[i]["parameters"]["recordASField"] == 1) { | |||
let id = outputIndex++; | |||
let title = nodeList[i]["title"]; | |||
// if (outputNames.indexOf(title) >= 0) { //参数名称已经被添加 | |||
// $('#myModal').modal('hide'); | |||
// $("#tip2").slideDown(); //提示框 | |||
// fadeout = setTimeout(function() { | |||
// $("#tip2").slideUp(); | |||
// }, 5000); | |||
// return; | |||
// } | |||
outputNames.push(title); | |||
outputParameters.push({ | |||
id: id, | |||
name: title, | |||
desc: "自定义操作返回的数据", | |||
type: nodeList[i]["parameters"]["paraType"], | |||
recordASField: nodeList[i]["parameters"]["recordASField"], | |||
exampleValue: "", | |||
}); | |||
// } | |||
} else if (nodeList[i]["option"] == 9) //条件判断 | |||
{ | |||
containJudge = true; | |||
} | |||
} | |||
} | |||
let serviceInfo = { | |||
"id": parseInt(serviceId), | |||
"name": serviceName, | |||
"url": url, | |||
"links": links, | |||
"create_time": new Date().toLocaleString(), | |||
"version": "0.3.5", | |||
"saveThreshold": saveThreshold, | |||
"cloudflare": cloudflare, | |||
"environment": environment, | |||
"maxViewLength": parseInt($("#maxViewLength").val()), | |||
"outputFormat": $("#outputFormat").val(), | |||
"saveName": $("#saveName").val(), | |||
"containJudge": containJudge, | |||
"desc": serviceDescription, | |||
"inputParameters": inputParameters, | |||
"outputParameters": outputParameters, | |||
"graph": nodeList, //图结构要存储下来 | |||
}; | |||
if(serviceInfo.outputFormat=="mysql"){ | |||
if(!isValidMySQLTableName(serviceInfo.saveName)) { | |||
$('#myModal').modal('hide'); | |||
$("#tipMySQL").slideDown(); //提示框 | |||
let fadeout = setTimeout(function() { | |||
$("#tipMySQL").slideUp(); | |||
}, 4000); | |||
return; | |||
} | |||
} | |||
$.post(backEndAddressServiceWrapper + "/manageTask", { paras: JSON.stringify(serviceInfo) }, | |||
function(result) { $("#serviceId").val(parseInt(result)) }); | |||
// alert("保存成功!"); | |||
$('#myModal').modal('hide'); | |||
$("#tip").slideDown(); //提示框 | |||
let fadeout = setTimeout(function() { | |||
$("#tip").slideUp(); | |||
}, 2000); | |||
// } | |||
} | |||
//点击保存任务按钮时的处理 | |||
$("#saveButton").mousedown(function() { | |||
saveService(0); | |||
}); | |||
//点击另存为任务按钮时的处理 | |||
$("#saveAsButton").mousedown(function() { | |||
saveService(1); | |||
}); | |||
if (sId != null && sId != -1) //加载任务 | |||
{ | |||
$.get(backEndAddressServiceWrapper + "/queryTask?id=" + sId, function(result) { | |||
nodeList = result["graph"]; | |||
app.$data.list.nl = nodeList; | |||
for(let node of nodeList){ //兼容旧版本 | |||
if(node["option"] == 1){ | |||
if(!("cookies" in node["parameters"])) { | |||
node["parameters"]["cookies"] = ""; | |||
} | |||
} | |||
} | |||
$("#serviceName").val(result["name"]); | |||
$("#serviceId").val(result["id"]); | |||
$("#url").val(result["url"]); | |||
$("#serviceDescription").val(result["desc"]); | |||
for(let key of Object.keys(result)){ | |||
try{ | |||
$("#"+key).val(result[key]); | |||
} catch(e){ | |||
console.log(e); | |||
} | |||
} | |||
refresh(); | |||
}); | |||
} else { | |||
refresh(); //新增任务 | |||
} |
@ -0,0 +1 @@ | |||
{"id":155,"name":"京东全球版-专业的综合网上购物商城","url":"https://www.jd.com","links":"https://www.jd.com","create_time":"7/8/2023, 4:15:43 AM","update_time":"7/8/2023, 4:25:42 AM","version":"0.3.5","saveThreshold":10,"cloudflare":0,"environment":0,"maxViewLength":15,"outputFormat":"mysql","saveName":"current_time","containJudge":false,"desc":"https://www.jd.com","inputParameters":[{"id":0,"name":"urlList_0","nodeId":1,"nodeName":"打开网页","value":"https://www.jd.com","desc":"要采集的网址列表,多行以\\n分开","type":"text","exampleValue":"https://www.jd.com"}],"outputParameters":[],"graph":[{"index":0,"id":0,"parentId":0,"type":-1,"option":0,"title":"root","sequence":[1,2],"parameters":{"history":1,"tabIndex":0,"useLoop":false,"xpath":"","wait":0,"waitType":0},"isInLoop":false},{"id":1,"index":1,"parentId":0,"type":0,"option":1,"title":"打开网页","sequence":[],"isInLoop":false,"position":0,"parameters":{"useLoop":false,"xpath":"","wait":0,"waitType":0,"beforeJS":"","beforeJSWaitTime":0,"afterJS":"","afterJSWaitTime":0,"url":"https://www.jd.com","links":"https://www.jd.com","maxWaitTime":10,"scrollType":0,"scrollCount":1,"scrollWaitTime":1,"cookies":""}},{"id":2,"index":2,"parentId":0,"type":0,"option":2,"title":"点击元素","sequence":[],"isInLoop":false,"position":1,"parameters":{"history":1,"tabIndex":0,"useLoop":false,"xpath":"","iframe":false,"wait":2,"waitType":0,"beforeJS":"","beforeJSWaitTime":0,"afterJS":"","afterJSWaitTime":0,"scrollType":0,"scrollCount":1,"scrollWaitTime":1,"clickWay":0,"maxWaitTime":10,"paras":[]}}]} |