New version
7
.gitignore
vendored
@ -1,2 +1,9 @@
|
|||||||
.idea/
|
.idea/
|
||||||
node_modules/
|
node_modules/
|
||||||
|
ServiceWrapper/
|
||||||
|
Data/
|
||||||
|
/GPUCache
|
||||||
|
*.exe
|
||||||
|
*.ini
|
||||||
|
*.7z
|
||||||
|
*.mp4
|
2
ExcuteStage/.gitignore
vendored
@ -7,3 +7,5 @@ dist/
|
|||||||
build/
|
build/
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.spec
|
*.spec
|
||||||
|
Chrome/
|
||||||
|
Data/
|
||||||
|
2
ExcuteStage/Readme.md
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
pyinstaller -F --icon=favicon.ico ServiceWrapper_ExcuteStage.py
|
||||||
|
出现permission denied请关闭杀毒软件
|
@ -1,4 +1,5 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
import atexit # 遇到错误退出时应执行的代码
|
||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
@ -17,14 +18,23 @@ from selenium.webdriver.common.by import By
|
|||||||
from selenium.common.exceptions import NoSuchElementException
|
from selenium.common.exceptions import NoSuchElementException
|
||||||
from selenium.common.exceptions import TimeoutException
|
from selenium.common.exceptions import TimeoutException
|
||||||
from selenium.common.exceptions import StaleElementReferenceException
|
from selenium.common.exceptions import StaleElementReferenceException
|
||||||
|
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
|
||||||
import random
|
import random
|
||||||
import numpy
|
import numpy
|
||||||
import csv
|
import csv
|
||||||
import os
|
import os
|
||||||
|
from selenium.webdriver.common.by import By
|
||||||
|
|
||||||
|
|
||||||
|
saveName, log, OUTPUT, browser, SAVED = None, "", "", None, False
|
||||||
|
|
||||||
|
desired_capabilities = DesiredCapabilities.CHROME
|
||||||
|
desired_capabilities["pageLoadStrategy"] = "none"
|
||||||
|
|
||||||
|
|
||||||
class Time:
|
class Time:
|
||||||
def __init__(self,type1=""):
|
def __init__(self, type1=""):
|
||||||
self.t = int(round(time.time() * 1000))
|
self.t = int(round(time.time() * 1000))
|
||||||
self.type = type1
|
self.type = type1
|
||||||
|
|
||||||
def end(self):
|
def end(self):
|
||||||
@ -32,6 +42,8 @@ class Time:
|
|||||||
Log(str(self.type)+":"+str(at-self.t))
|
Log(str(self.type)+":"+str(at-self.t))
|
||||||
|
|
||||||
# 记录log
|
# 记录log
|
||||||
|
|
||||||
|
|
||||||
def recordLog(str=""):
|
def recordLog(str=""):
|
||||||
global log
|
global log
|
||||||
log = log + str + "\n"
|
log = log + str + "\n"
|
||||||
@ -43,17 +55,48 @@ def Log(text, text2=""):
|
|||||||
if switch:
|
if switch:
|
||||||
print(text, text2)
|
print(text, text2)
|
||||||
|
|
||||||
|
# 屏幕滚动函数
|
||||||
|
|
||||||
|
|
||||||
|
def scrollDown(para, rt=""):
|
||||||
|
try:
|
||||||
|
if para["scrollType"] != 0 and para["scrollCount"] > 0: # 控制屏幕向下滚动
|
||||||
|
for i in range(para["scrollCount"]):
|
||||||
|
time.sleep(1) # 下拉完等1秒
|
||||||
|
Log("下拉完等待1秒")
|
||||||
|
body = browser.find_element_by_css_selector("body")
|
||||||
|
if para["scrollType"] == 1:
|
||||||
|
body.send_keys(Keys.PGDN)
|
||||||
|
else:
|
||||||
|
body.send_keys(Keys.END)
|
||||||
|
except TimeoutException:
|
||||||
|
Log('time out after 10 seconds when scrolling. ')
|
||||||
|
recordLog('time out after 10 seconds when scrolling')
|
||||||
|
browser.execute_script('window.stop()')
|
||||||
|
if para["scrollType"] != 0 and para["scrollCount"] > 0: # 控制屏幕向下滚动
|
||||||
|
for i in range(para["scrollCount"]):
|
||||||
|
time.sleep(1) # 下拉完等1秒
|
||||||
|
Log("下拉完等待1秒")
|
||||||
|
body = browser.find_element_by_css_selector("body")
|
||||||
|
if para["scrollType"] == 1:
|
||||||
|
body.send_keys(Keys.PGDN)
|
||||||
|
else:
|
||||||
|
body.send_keys(Keys.END)
|
||||||
|
if rt != "":
|
||||||
|
rt.end()
|
||||||
|
|
||||||
|
|
||||||
# 执行节点关键函数部分
|
# 执行节点关键函数部分
|
||||||
def excuteNode(nodeId, loopValue="", clickPath="", index=0):
|
def excuteNode(nodeId, loopValue="", clickPath="", index=0):
|
||||||
node = procedure[nodeId]
|
node = procedure[nodeId]
|
||||||
WebDriverWait(browser, 10).until
|
WebDriverWait(browser, 10).until
|
||||||
(EC.visibility_of_element_located((By.XPATH, node["parameters"]["xpath"]))) # 等待元素出现才进行操作,10秒内未出现则报错
|
# 等待元素出现才进行操作,10秒内未出现则报错
|
||||||
|
(EC.visibility_of_element_located((By.XPATH, node["parameters"]["xpath"])))
|
||||||
|
|
||||||
# 根据不同选项执行不同操作
|
# 根据不同选项执行不同操作
|
||||||
if node["option"] == 0 or node["option"] == 10: # root操作,条件分支操作
|
if node["option"] == 0 or node["option"] == 10: # root操作,条件分支操作
|
||||||
for i in node["sequence"]: # 从根节点开始向下读取
|
for i in node["sequence"]: # 从根节点开始向下读取
|
||||||
excuteNode(i, loopValue,clickPath,index)
|
excuteNode(i, loopValue, clickPath, index)
|
||||||
elif node["option"] == 1: # 打开网页操作
|
elif node["option"] == 1: # 打开网页操作
|
||||||
recordLog("openPage")
|
recordLog("openPage")
|
||||||
openPage(node["parameters"], loopValue)
|
openPage(node["parameters"], loopValue)
|
||||||
@ -67,10 +110,10 @@ def excuteNode(nodeId, loopValue="", clickPath="", index=0):
|
|||||||
inputInfo(node["parameters"], loopValue)
|
inputInfo(node["parameters"], loopValue)
|
||||||
elif node["option"] == 8: # 循环
|
elif node["option"] == 8: # 循环
|
||||||
recordLog("loop")
|
recordLog("loop")
|
||||||
loopExcute(node, loopValue,clickPath,index) # 执行循环
|
loopExcute(node, loopValue, clickPath, index) # 执行循环
|
||||||
elif node["option"] == 9: # 条件分支
|
elif node["option"] == 9: # 条件分支
|
||||||
recordLog("judge")
|
recordLog("judge")
|
||||||
judgeExcute(node, loopValue,clickPath,index)
|
judgeExcute(node, loopValue, clickPath, index)
|
||||||
|
|
||||||
# 执行完之后进行等待
|
# 执行完之后进行等待
|
||||||
if node["option"] != 0:
|
if node["option"] != 0:
|
||||||
@ -82,7 +125,7 @@ def excuteNode(nodeId, loopValue="", clickPath="", index=0):
|
|||||||
|
|
||||||
|
|
||||||
# 对判断条件的处理
|
# 对判断条件的处理
|
||||||
def judgeExcute(node, loopElement,clickPath="",index=0):
|
def judgeExcute(node, loopElement, clickPath="", index=0):
|
||||||
rt = Time("条件判断")
|
rt = Time("条件判断")
|
||||||
global bodyText # 引入bodyText
|
global bodyText # 引入bodyText
|
||||||
excuteBranchId = 0 # 要执行的BranchId
|
excuteBranchId = 0 # 要执行的BranchId
|
||||||
@ -101,7 +144,7 @@ def judgeExcute(node, loopElement,clickPath="",index=0):
|
|||||||
continue
|
continue
|
||||||
elif tType == 2: # 当前页面包含元素
|
elif tType == 2: # 当前页面包含元素
|
||||||
try:
|
try:
|
||||||
if browser.find_element_by_xpath(cnode["parameters"]["value"]):
|
if browser.find_element(By.XPATH, cnode["parameters"]["value"]):
|
||||||
excuteBranchId = i
|
excuteBranchId = i
|
||||||
break
|
break
|
||||||
except: # 找不到元素或者xpath写错了,下一个条件
|
except: # 找不到元素或者xpath写错了,下一个条件
|
||||||
@ -115,22 +158,23 @@ def judgeExcute(node, loopElement,clickPath="",index=0):
|
|||||||
continue
|
continue
|
||||||
elif tType == 4: # 当前循环元素包括元素
|
elif tType == 4: # 当前循环元素包括元素
|
||||||
try:
|
try:
|
||||||
if loopElement.find_element_by_xpath(cnode["parameters"]["value"][1:]):
|
if loopElement.find_element(By.XPATH, cnode["parameters"]["value"][1:]):
|
||||||
excuteBranchId = i
|
excuteBranchId = i
|
||||||
break
|
break
|
||||||
except: # 找不到元素或者xpath写错了,下一个条件
|
except: # 找不到元素或者xpath写错了,下一个条件
|
||||||
continue
|
continue
|
||||||
rt.end()
|
rt.end()
|
||||||
excuteNode(excuteBranchId, loopElement,clickPath,index)
|
excuteNode(excuteBranchId, loopElement, clickPath, index)
|
||||||
|
|
||||||
|
|
||||||
# 对循环的处理
|
# 对循环的处理
|
||||||
def loopExcute(node, loopValue,clickPath="",index=0):
|
def loopExcute(node, loopValue, clickPath="", index=0):
|
||||||
time.sleep(0.1) # 第一次执行循环的时候强制等待1秒
|
time.sleep(0.1) # 第一次执行循环的时候强制等待1秒
|
||||||
Log("循环执行前等待0.1秒")
|
Log("循环执行前等待0.1秒")
|
||||||
global history
|
global history
|
||||||
thisHandle = browser.current_window_handle # 记录本次循环内的标签页的ID
|
thisHandle = browser.current_window_handle # 记录本次循环内的标签页的ID
|
||||||
thisHistoryLength = browser.execute_script('return history.length') # 记录本次循环内的history的length
|
thisHistoryLength = browser.execute_script(
|
||||||
|
'return history.length') # 记录本次循环内的history的length
|
||||||
history["index"] = thisHistoryLength
|
history["index"] = thisHistoryLength
|
||||||
history["handle"] = thisHandle
|
history["handle"] = thisHandle
|
||||||
|
|
||||||
@ -139,9 +183,10 @@ def loopExcute(node, loopValue,clickPath="",index=0):
|
|||||||
count = 0 # 执行次数
|
count = 0 # 执行次数
|
||||||
while True: # do while循环
|
while True: # do while循环
|
||||||
try:
|
try:
|
||||||
element = browser.find_element_by_xpath(node["parameters"]["xpath"])
|
element = browser.find_element(By.XPATH,
|
||||||
|
node["parameters"]["xpath"])
|
||||||
for i in node["sequence"]: # 挨个执行操作
|
for i in node["sequence"]: # 挨个执行操作
|
||||||
excuteNode(i, element, node["parameters"]["xpath"],0)
|
excuteNode(i, element, node["parameters"]["xpath"], 0)
|
||||||
Log("click: ", node["parameters"]["xpath"])
|
Log("click: ", node["parameters"]["xpath"])
|
||||||
recordLog("click:" + node["parameters"]["xpath"])
|
recordLog("click:" + node["parameters"]["xpath"])
|
||||||
except NoSuchElementException:
|
except NoSuchElementException:
|
||||||
@ -153,14 +198,17 @@ def loopExcute(node, loopValue,clickPath="",index=0):
|
|||||||
count = count + 1
|
count = count + 1
|
||||||
Log("页数:", count)
|
Log("页数:", count)
|
||||||
recordLog("页数:" + str(count))
|
recordLog("页数:" + str(count))
|
||||||
|
# print(node["parameters"]["exitCount"], "-------")
|
||||||
if node["parameters"]["exitCount"] == count: # 如果达到设置的退出循环条件的话
|
if node["parameters"]["exitCount"] == count: # 如果达到设置的退出循环条件的话
|
||||||
break
|
break
|
||||||
elif int(node["parameters"]["loopType"]) == 1: # 不固定元素列表
|
elif int(node["parameters"]["loopType"]) == 1: # 不固定元素列表
|
||||||
try:
|
try:
|
||||||
elements = browser.find_elements_by_xpath(node["parameters"]["xpath"])
|
elements = browser.find_elements(By.XPATH,
|
||||||
|
node["parameters"]["xpath"])
|
||||||
for index in range(len(elements)):
|
for index in range(len(elements)):
|
||||||
for i in node["sequence"]: # 挨个执行操作
|
for i in node["sequence"]: # 挨个执行操作
|
||||||
excuteNode(i, elements[index], node["parameters"]["xpath"], index)
|
excuteNode(i, elements[index],
|
||||||
|
node["parameters"]["xpath"], index)
|
||||||
if browser.current_window_handle != thisHandle: # 如果执行完一次循环之后标签页的位置发生了变化
|
if browser.current_window_handle != thisHandle: # 如果执行完一次循环之后标签页的位置发生了变化
|
||||||
while True: # 一直关闭窗口直到当前标签页
|
while True: # 一直关闭窗口直到当前标签页
|
||||||
browser.close() # 关闭使用完的标签页
|
browser.close() # 关闭使用完的标签页
|
||||||
@ -168,9 +216,11 @@ def loopExcute(node, loopValue,clickPath="",index=0):
|
|||||||
if browser.current_window_handle == thisHandle:
|
if browser.current_window_handle == thisHandle:
|
||||||
break
|
break
|
||||||
if history["index"] != thisHistoryLength and history[
|
if history["index"] != thisHistoryLength and history[
|
||||||
"handle"] == browser.current_window_handle: # 如果执行完一次循环之后历史记录发生了变化,注意当前页面的判断
|
"handle"] == browser.current_window_handle: # 如果执行完一次循环之后历史记录发生了变化,注意当前页面的判断
|
||||||
difference = thisHistoryLength - history["index"] # 计算历史记录变化差值
|
difference = thisHistoryLength - \
|
||||||
browser.execute_script('history.go(' + str(difference) + ')') # 回退历史记录
|
history["index"] # 计算历史记录变化差值
|
||||||
|
browser.execute_script(
|
||||||
|
'history.go(' + str(difference) + ')') # 回退历史记录
|
||||||
if node["parameters"]["historyWait"] > 2: # 回退后要等待的时间
|
if node["parameters"]["historyWait"] > 2: # 回退后要等待的时间
|
||||||
time.sleep(node["parameters"]["historyWait"])
|
time.sleep(node["parameters"]["historyWait"])
|
||||||
else:
|
else:
|
||||||
@ -186,7 +236,7 @@ def loopExcute(node, loopValue,clickPath="",index=0):
|
|||||||
elif int(node["parameters"]["loopType"]) == 2: # 固定元素列表
|
elif int(node["parameters"]["loopType"]) == 2: # 固定元素列表
|
||||||
for path in node["parameters"]["pathList"].split("\n"): # 千万不要忘了分割!!
|
for path in node["parameters"]["pathList"].split("\n"): # 千万不要忘了分割!!
|
||||||
try:
|
try:
|
||||||
element = browser.find_element_by_xpath(path)
|
element = browser.find_element(By.XPATH, path)
|
||||||
for i in node["sequence"]: # 挨个执行操作
|
for i in node["sequence"]: # 挨个执行操作
|
||||||
excuteNode(i, element, path, 0)
|
excuteNode(i, element, path, 0)
|
||||||
if browser.current_window_handle != thisHandle: # 如果执行完一次循环之后标签页的位置发生了变化
|
if browser.current_window_handle != thisHandle: # 如果执行完一次循环之后标签页的位置发生了变化
|
||||||
@ -196,9 +246,11 @@ def loopExcute(node, loopValue,clickPath="",index=0):
|
|||||||
if browser.current_window_handle == thisHandle:
|
if browser.current_window_handle == thisHandle:
|
||||||
break
|
break
|
||||||
if history["index"] != thisHistoryLength and history[
|
if history["index"] != thisHistoryLength and history[
|
||||||
"handle"] == browser.current_window_handle: # 如果执行完一次循环之后历史记录发生了变化,注意当前页面的判断
|
"handle"] == browser.current_window_handle: # 如果执行完一次循环之后历史记录发生了变化,注意当前页面的判断
|
||||||
difference = thisHistoryLength - history["index"] # 计算历史记录变化差值
|
difference = thisHistoryLength - \
|
||||||
browser.execute_script('history.go(' + str(difference) + ')') # 回退历史记录
|
history["index"] # 计算历史记录变化差值
|
||||||
|
browser.execute_script(
|
||||||
|
'history.go(' + str(difference) + ')') # 回退历史记录
|
||||||
if node["parameters"]["historyWait"] > 2: # 回退后要等待的时间
|
if node["parameters"]["historyWait"] > 2: # 回退后要等待的时间
|
||||||
time.sleep(node["parameters"]["historyWait"])
|
time.sleep(node["parameters"]["historyWait"])
|
||||||
else:
|
else:
|
||||||
@ -216,16 +268,18 @@ def loopExcute(node, loopValue,clickPath="",index=0):
|
|||||||
for text in textList:
|
for text in textList:
|
||||||
recordLog("input: " + text)
|
recordLog("input: " + text)
|
||||||
for i in node["sequence"]: # 挨个执行操作
|
for i in node["sequence"]: # 挨个执行操作
|
||||||
excuteNode(i, text, "",0)
|
excuteNode(i, text, "", 0)
|
||||||
elif int(node["parameters"]["loopType"]) == 4: # 固定网址列表
|
elif int(node["parameters"]["loopType"]) == 4: # 固定网址列表
|
||||||
pass # 以后再做
|
pass # 以后再做
|
||||||
history["index"] = thisHistoryLength
|
history["index"] = thisHistoryLength
|
||||||
history["handle"] = browser.current_window_handle
|
history["handle"] = browser.current_window_handle
|
||||||
|
scrollDown(node["parameters"])
|
||||||
|
|
||||||
|
|
||||||
# 打开网页事件
|
# 打开网页事件
|
||||||
def openPage(para, loopValue):
|
def openPage(para, loopValue):
|
||||||
rt = Time("打开网页")
|
rt = Time("打开网页")
|
||||||
|
time.sleep(2) # 打开网页后强行等待至少2秒
|
||||||
global links
|
global links
|
||||||
global urlId
|
global urlId
|
||||||
global history
|
global history
|
||||||
@ -248,18 +302,7 @@ def openPage(para, loopValue):
|
|||||||
browser.execute_script('window.stop()')
|
browser.execute_script('window.stop()')
|
||||||
history["index"] = browser.execute_script("return history.length")
|
history["index"] = browser.execute_script("return history.length")
|
||||||
rt.end()
|
rt.end()
|
||||||
try:
|
scrollDown(para, rt) # 控制屏幕向下滚动
|
||||||
if para["scrollType"] != 0 and para["scrollCount"] > 0: # 控制屏幕向下滚动
|
|
||||||
for i in range(para["scrollCount"]):
|
|
||||||
time.sleep(1) # 下拉完等1秒
|
|
||||||
Log("下拉等待1秒")
|
|
||||||
body = browser.find_element_by_css_selector("body")
|
|
||||||
body.send_keys(Keys.END)
|
|
||||||
except TimeoutException:
|
|
||||||
Log('time out after 10 seconds when loading page: ' + url)
|
|
||||||
recordLog('time out after 10 seconds when loading page: ' + url)
|
|
||||||
browser.execute_script('window.stop()')
|
|
||||||
rt.end()
|
|
||||||
if containJudge:
|
if containJudge:
|
||||||
global bodyText # 每次执行点击,输入元素和打开网页操作后,需要更新bodyText
|
global bodyText # 每次执行点击,输入元素和打开网页操作后,需要更新bodyText
|
||||||
try:
|
try:
|
||||||
@ -285,7 +328,7 @@ def inputInfo(para, loopValue):
|
|||||||
Log("输入前等待1秒")
|
Log("输入前等待1秒")
|
||||||
rt = Time("输入文字")
|
rt = Time("输入文字")
|
||||||
try:
|
try:
|
||||||
textbox = browser.find_element_by_xpath(para["xpath"])
|
textbox = browser.find_element(By.XPATH, para["xpath"])
|
||||||
except:
|
except:
|
||||||
Log("找不到输入框元素:" + para["xpath"] + "请尝试执行前等待")
|
Log("找不到输入框元素:" + para["xpath"] + "请尝试执行前等待")
|
||||||
recordLog("找不到输入框元素:" + para["xpath"] + "请尝试执行前等待")
|
recordLog("找不到输入框元素:" + para["xpath"] + "请尝试执行前等待")
|
||||||
@ -313,7 +356,8 @@ def clickElement(para, loopElement=None, clickPath="", index=0):
|
|||||||
path = para["xpath"] # 不然使用元素定义的xpath
|
path = para["xpath"] # 不然使用元素定义的xpath
|
||||||
tempHandleNum = len(browser.window_handles) # 记录之前的窗口位置
|
tempHandleNum = len(browser.window_handles) # 记录之前的窗口位置
|
||||||
try:
|
try:
|
||||||
script = 'var result = document.evaluate(`' + path + '`, document, null, XPathResult.ANY_TYPE, null);for(let i=0;i<arguments[0];i++){result.iterateNext();} result.iterateNext().click();'
|
script = 'var result = document.evaluate(`' + path + \
|
||||||
|
'`, document, null, XPathResult.ANY_TYPE, null);for(let i=0;i<arguments[0];i++){result.iterateNext();} result.iterateNext().click();'
|
||||||
browser.execute_script(script, str(index)) # 用js的点击方法
|
browser.execute_script(script, str(index)) # 用js的点击方法
|
||||||
|
|
||||||
except TimeoutException:
|
except TimeoutException:
|
||||||
@ -343,24 +387,7 @@ def clickElement(para, loopElement=None, clickPath="", index=0):
|
|||||||
history["index"] = browser.execute_script("return history.length")
|
history["index"] = browser.execute_script("return history.length")
|
||||||
rt.end()
|
rt.end()
|
||||||
# 如果打开了新窗口,切换到新窗口
|
# 如果打开了新窗口,切换到新窗口
|
||||||
try:
|
scrollDown(para, rt) # 根据参数配置向下滚动
|
||||||
if para["scrollType"] != 0 and para["scrollCount"] > 0: # 控制屏幕向下滚动
|
|
||||||
for i in range(para["scrollCount"]):
|
|
||||||
time.sleep(1) # 下拉完等1秒
|
|
||||||
Log("下拉完等待1秒")
|
|
||||||
body = browser.find_element_by_css_selector("body")
|
|
||||||
body.send_keys(Keys.END)
|
|
||||||
except TimeoutException:
|
|
||||||
Log('time out after 10 seconds when scrolling. ')
|
|
||||||
recordLog('time out after 10 seconds when scrolling')
|
|
||||||
browser.execute_script('window.stop()')
|
|
||||||
if para["scrollType"] != 0 and para["scrollCount"] > 0: # 控制屏幕向下滚动
|
|
||||||
for i in range(para["scrollCount"]):
|
|
||||||
time.sleep(1) # 下拉完等1秒
|
|
||||||
Log("下拉完等待1秒")
|
|
||||||
body = browser.find_element_by_css_selector("body")
|
|
||||||
body.send_keys(Keys.END)
|
|
||||||
rt.end()
|
|
||||||
if containJudge: # 有判断语句才执行以下操作
|
if containJudge: # 有判断语句才执行以下操作
|
||||||
global bodyText # 每次执行点击,输入元素和打开网页操作后,需要更新bodyText
|
global bodyText # 每次执行点击,输入元素和打开网页操作后,需要更新bodyText
|
||||||
try:
|
try:
|
||||||
@ -393,13 +420,19 @@ def getData(para, loopElement, isInLoop=True):
|
|||||||
if p["relativeXpath"] == "": # 相对xpath有时候就是元素本身,不需要二次查找
|
if p["relativeXpath"] == "": # 相对xpath有时候就是元素本身,不需要二次查找
|
||||||
element = loopElement
|
element = loopElement
|
||||||
else:
|
else:
|
||||||
element = loopElement.find_element_by_xpath(p["relativeXpath"][1:])
|
element = loopElement.find_element(By.XPATH,
|
||||||
|
p["relativeXpath"][1:])
|
||||||
else:
|
else:
|
||||||
element = browser.find_element_by_xpath(p["relativeXpath"])
|
element = browser.find_element(By.XPATH, p["relativeXpath"])
|
||||||
except NoSuchElementException: # 找不到元素的时候,使用默认值
|
except NoSuchElementException: # 找不到元素的时候,使用默认值
|
||||||
outputParameters[p["name"]] = p["default"]
|
# print(p)
|
||||||
Log('Element not found,use default')
|
try:
|
||||||
recordLog('Element not found,use default')
|
content = p["default"]
|
||||||
|
except Exception as e:
|
||||||
|
content = ""
|
||||||
|
outputParameters[p["name"]] = content
|
||||||
|
Log('Element %s not found,use default' % p["relativeXpath"])
|
||||||
|
recordLog('Element %s not found, use default' % p["relativeXpath"])
|
||||||
continue
|
continue
|
||||||
except TimeoutException: # 超时的时候设置超时值
|
except TimeoutException: # 超时的时候设置超时值
|
||||||
Log('time out after 10 seconds when getting data')
|
Log('time out after 10 seconds when getting data')
|
||||||
@ -409,9 +442,10 @@ def getData(para, loopElement, isInLoop=True):
|
|||||||
if p["relativeXpath"] == "": # 相对xpath有时候就是元素本身,不需要二次查找
|
if p["relativeXpath"] == "": # 相对xpath有时候就是元素本身,不需要二次查找
|
||||||
element = loopElement
|
element = loopElement
|
||||||
else:
|
else:
|
||||||
element = loopElement.find_element_by_xpath(p["relativeXpath"][1:])
|
element = loopElement.find_element(By.XPATH,
|
||||||
|
p["relativeXpath"][1:])
|
||||||
else:
|
else:
|
||||||
element = browser.find_element_by_xpath(p["relativeXpath"])
|
element = browser.find_element(By.XPATH, p["relativeXpath"])
|
||||||
rt.end()
|
rt.end()
|
||||||
try:
|
try:
|
||||||
if p["contentType"] == 2:
|
if p["contentType"] == 2:
|
||||||
@ -428,7 +462,8 @@ def getData(para, loopElement, isInLoop=True):
|
|||||||
}\
|
}\
|
||||||
var str = arr.join(" "); \
|
var str = arr.join(" "); \
|
||||||
return str;'
|
return str;'
|
||||||
content = browser.execute_script(command, element).replace("\n", "").replace("\\s+", " ")
|
content = browser.execute_script(command, element).replace(
|
||||||
|
"\n", "").replace("\\s+", " ")
|
||||||
if p["nodeType"] == 2:
|
if p["nodeType"] == 2:
|
||||||
if element.get_attribute("href") != None:
|
if element.get_attribute("href") != None:
|
||||||
content = element.get_attribute("href")
|
content = element.get_attribute("href")
|
||||||
@ -461,7 +496,7 @@ def getData(para, loopElement, isInLoop=True):
|
|||||||
content = element.get_attribute("src")
|
content = element.get_attribute("src")
|
||||||
else:
|
else:
|
||||||
content = ""
|
content = ""
|
||||||
except StaleElementReferenceException: #发生找不到元素的异常后,等待几秒重新查找
|
except StaleElementReferenceException: # 发生找不到元素的异常后,等待几秒重新查找
|
||||||
recordLog('StaleElementReferenceException:'+p["relativeXpath"])
|
recordLog('StaleElementReferenceException:'+p["relativeXpath"])
|
||||||
time.sleep(3)
|
time.sleep(3)
|
||||||
try:
|
try:
|
||||||
@ -470,10 +505,13 @@ def getData(para, loopElement, isInLoop=True):
|
|||||||
element = loopElement
|
element = loopElement
|
||||||
recordLog('StaleElementReferenceException:loopElement')
|
recordLog('StaleElementReferenceException:loopElement')
|
||||||
else:
|
else:
|
||||||
element = loopElement.find_element_by_xpath(p["relativeXpath"][1:])
|
element = loopElement.find_element(By.XPATH,
|
||||||
recordLog('StaleElementReferenceException:loopElement+relativeXPath')
|
p["relativeXpath"][1:])
|
||||||
|
recordLog(
|
||||||
|
'StaleElementReferenceException:loopElement+relativeXPath')
|
||||||
else:
|
else:
|
||||||
element = browser.find_element_by_xpath(p["relativeXpath"])
|
element = browser.find_element(
|
||||||
|
By.XPATH, p["relativeXpath"])
|
||||||
recordLog('StaleElementReferenceException:relativeXpath')
|
recordLog('StaleElementReferenceException:relativeXpath')
|
||||||
if p["contentType"] == 2:
|
if p["contentType"] == 2:
|
||||||
content = element.get_attribute('innerHTML')
|
content = element.get_attribute('innerHTML')
|
||||||
@ -489,7 +527,8 @@ def getData(para, loopElement, isInLoop=True):
|
|||||||
}\
|
}\
|
||||||
var str = arr.join(" "); \
|
var str = arr.join(" "); \
|
||||||
return str;'
|
return str;'
|
||||||
content = browser.execute_script(command, element).replace("\n", "").replace("\\s+", " ")
|
content = browser.execute_script(command, element).replace(
|
||||||
|
"\n", "").replace("\\s+", " ")
|
||||||
if p["nodeType"] == 2:
|
if p["nodeType"] == 2:
|
||||||
if element.get_attribute("href") != None:
|
if element.get_attribute("href") != None:
|
||||||
content = element.get_attribute("href")
|
content = element.get_attribute("href")
|
||||||
@ -524,7 +563,7 @@ def getData(para, loopElement, isInLoop=True):
|
|||||||
content = ""
|
content = ""
|
||||||
except StaleElementReferenceException:
|
except StaleElementReferenceException:
|
||||||
recordLog('StaleElementReferenceException:'+p["relativeXpath"])
|
recordLog('StaleElementReferenceException:'+p["relativeXpath"])
|
||||||
continue # 再出现类似问题直接跳过
|
continue # 再出现类似问题直接跳过
|
||||||
outputParameters[p["name"]] = content
|
outputParameters[p["name"]] = content
|
||||||
global OUTPUT
|
global OUTPUT
|
||||||
line = []
|
line = []
|
||||||
@ -541,13 +580,12 @@ def isnull(s):
|
|||||||
return len(s) != 0
|
return len(s) != 0
|
||||||
|
|
||||||
|
|
||||||
import atexit #遇到错误退出时应执行的代码
|
|
||||||
@atexit.register
|
@atexit.register
|
||||||
def clean():
|
def clean():
|
||||||
global saveName,log, OUTPUT,browser,SAVED
|
global saveName, log, OUTPUT, browser, SAVED
|
||||||
if not SAVED:
|
if not SAVED:
|
||||||
print('清理环境保存数据')
|
print('清理环境保存数据')
|
||||||
with open("Data/"+saveName + '_log.txt', 'w',encoding='utf-8-sig') as file_obj:
|
with open("Data/"+saveName + '_log.txt', 'w', encoding='utf-8-sig') as file_obj:
|
||||||
file_obj.write(log)
|
file_obj.write(log)
|
||||||
file_obj.close()
|
file_obj.close()
|
||||||
with open("Data/"+saveName + '.csv', 'w', encoding='utf-8-sig', newline="") as f:
|
with open("Data/"+saveName + '.csv', 'w', encoding='utf-8-sig', newline="") as f:
|
||||||
@ -557,42 +595,53 @@ def clean():
|
|||||||
f.close()
|
f.close()
|
||||||
browser.quit()
|
browser.quit()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
options = Options()
|
options = Options()
|
||||||
|
exe_path = "chromedriver.exe"
|
||||||
if os.path.exists(os.getcwd()+"/ServiceWrapper"):
|
if os.path.exists(os.getcwd()+"/ServiceWrapper"):
|
||||||
options.binary_location="ServiceWrapper/Chrome/chrome.exe" #指定chrome位置
|
options.binary_location = "ServiceWrapper/Chrome/chrome.exe" # 指定chrome位置
|
||||||
|
exe_path = "ServiceWrapper/Chrome/chromedriver.exe"
|
||||||
elif os.path.exists(os.getcwd()+"/Debug"):
|
elif os.path.exists(os.getcwd()+"/Debug"):
|
||||||
options.binary_location="Debug/Chrome/chrome.exe" #指定chrome位置
|
options.binary_location = "Debug/Chrome/chrome.exe" # 指定chrome位置
|
||||||
elif os.getcwd().find("ExcuteStage") >= 0: #如果直接执行
|
exe_path = "Debug/Chrome/chromedriver.exe"
|
||||||
options.binary_location = "../../bin/x64/Debug/Chrome/chrome.exe" # 指定chrome位置
|
elif os.getcwd().find("ExcuteStage") >= 0: # 如果直接执行
|
||||||
|
options.binary_location = "./Chrome/chrome.exe" # 指定chrome位置
|
||||||
|
exe_path = "./Chrome/chromedriver.exe"
|
||||||
else:
|
else:
|
||||||
options.binary_location="chrome.exe" #指定chrome位置
|
options.binary_location = "chrome.exe" # 指定chrome位置
|
||||||
browser = webdriver.Chrome(chrome_options=options)
|
browser = webdriver.Chrome(options=options, executable_path=exe_path)
|
||||||
browser.get('about:blank')
|
browser.get('about:blank')
|
||||||
browser.set_page_load_timeout(10) # 加载页面最大超时时间
|
browser.set_page_load_timeout(10) # 加载页面最大超时时间
|
||||||
if len(sys.argv)>1:
|
browser.set_script_timeout(10)
|
||||||
id = int(sys.argv[1]) #taskId这里修改
|
if len(sys.argv) > 1:
|
||||||
|
id = int(sys.argv[1]) # taskId这里修改
|
||||||
else:
|
else:
|
||||||
id = 7 #设置默认值
|
id = 7 # 设置默认值
|
||||||
print("id:",id)
|
print("id:", id)
|
||||||
if len(sys.argv)>2:
|
if len(sys.argv) > 2:
|
||||||
saveName = "task_" + str(id) + "_" + sys.argv[2] # 保存文件的名字
|
backEndAddress = sys.argv[2]
|
||||||
else:
|
else:
|
||||||
saveName = "task_" + str(id) + "_" + str(random.randint(0, 999999999)) # 保存文件的名字
|
backEndAddress = "http://servicewrapper.naibo.wang"
|
||||||
content = requests.get("http://183.129.170.180:8041/backEnd/queryTask?id=" + str(id))
|
if len(sys.argv) > 3:
|
||||||
|
saveName = "task_" + str(id) + "_" + sys.argv[3] # 保存文件的名字
|
||||||
|
else:
|
||||||
|
saveName = "task_" + str(id) + "_" + \
|
||||||
|
str(random.randint(0, 999999999)) # 保存文件的名字
|
||||||
|
content = requests.get(backEndAddress + "/backEnd/queryTask?id=" + str(id))
|
||||||
service = json.loads(content.text) # 加载服务信息
|
service = json.loads(content.text) # 加载服务信息
|
||||||
print("name:",service["name"])
|
print("name:", service["name"])
|
||||||
procedure = service["graph"] # 程序执行流程
|
procedure = service["graph"] # 程序执行流程
|
||||||
links = list(filter(isnull, service["links"].split("\n"))) # 要执行的link的列表
|
links = list(filter(isnull, service["links"].split("\n"))) # 要执行的link的列表
|
||||||
OUTPUT = [] # 采集的数据
|
OUTPUT = [] # 采集的数据
|
||||||
OUTPUT.append([]) # 添加表头
|
OUTPUT.append([]) # 添加表头
|
||||||
containJudge = service["containJudge"] #是否含有判断语句
|
containJudge = service["containJudge"] # 是否含有判断语句
|
||||||
bodyText = "" # 记录bodyText
|
bodyText = "" # 记录bodyText
|
||||||
tOut = service["outputParameters"] # 生成输出参数对象
|
tOut = service["outputParameters"] # 生成输出参数对象
|
||||||
outputParameters = {}
|
outputParameters = {}
|
||||||
log = "" # 记下现在总共开了多少个标签页
|
log = "" # 记下现在总共开了多少个标签页
|
||||||
history = {"index":0,"handle":None} #记录页面现在所以在的历史记录的位置
|
history = {"index": 0, "handle": None} # 记录页面现在所以在的历史记录的位置
|
||||||
SAVED=False #记录是否已经存储了
|
SAVED = False # 记录是否已经存储了
|
||||||
for para in tOut:
|
for para in tOut:
|
||||||
outputParameters[para["name"]] = ""
|
outputParameters[para["name"]] = ""
|
||||||
OUTPUT[0].append(para["name"])
|
OUTPUT[0].append(para["name"])
|
||||||
@ -604,7 +653,7 @@ if __name__ == '__main__':
|
|||||||
print("执行完成!")
|
print("执行完成!")
|
||||||
recordLog("Done!")
|
recordLog("Done!")
|
||||||
# dataPath = os.path.abspath(os.path.join(os.getcwd(), "../Data"))
|
# dataPath = os.path.abspath(os.path.join(os.getcwd(), "../Data"))
|
||||||
with open("Data/"+saveName + '_log.txt', 'w',encoding='utf-8-sig') as file_obj:
|
with open("Data/"+saveName + '_log.txt', 'w', encoding='utf-8-sig') as file_obj:
|
||||||
file_obj.write(log)
|
file_obj.write(log)
|
||||||
file_obj.close()
|
file_obj.close()
|
||||||
with open("Data/"+saveName + '.csv', 'w', encoding='utf-8-sig', newline="") as f:
|
with open("Data/"+saveName + '.csv', 'w', encoding='utf-8-sig', newline="") as f:
|
||||||
|
@ -1,28 +1,28 @@
|
|||||||
-----BEGIN PRIVATE KEY-----
|
-----BEGIN PRIVATE KEY-----
|
||||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCuAZmXoS3RN1dQ
|
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCr3o0YTuz2UMy7
|
||||||
IWpPjMZMX08JQRiR9XF8fPuZ4r/aauafNKncQmC2FEFylAcBMaRVSjAsZlXVqTlE
|
qolwd4CWXet3SjJL0XawKKgp3ZRo78zER1Z/LQ5/rZqc6DISBPCycAoOCBk2EcBZ
|
||||||
s1LRtt9PiJEiDv73alerwznzNfuN0Dqrj2YpvKlck/sdFDeJNGi3dAl4kWZOKlE0
|
IlPKQFxq1PMj10ccyswjjb+4mf4ZRVveeflBqT9I4khrzwk9gymSZiD7TbkDc4fp
|
||||||
kpHXO6BQBKB9t9Up5qBku0epGYNZ6/foCl82U5bw8bBaZ5p0F2hhE4/PWP0p/MED
|
oxoHCv2f7VMR5m/IwsnXEsm7QyuRSA6ETbhp2Faa2CIGI4l6r+gtuVYkUSGEN/0H
|
||||||
HR7yvnr5qO0B6qQia/59q4opxH6sswa6XAc3mgU1Yq8m1cXRctmvxCBt7biU7Gpw
|
0dk3kfh6rcjwvroLSzWcGJnhyOLDYxnV1kTHZDUBzGj0UOqL0fdpAuyXxSikadxa
|
||||||
jLB4Qdgikq02hWxn1YUbGAjHRjLrNxOIFBP6Sx2SNllM664bUmzwchnEzsLILyDQ
|
Ec4BZ4s3GHIlFR5N7itrwYN28IInLObxUQXJ3unEdnon/T/XhC5KsdjMp8D6Xb8/
|
||||||
jzKlafobAgMBAAECggEAGdp7APXIYkbKs56DYSvAECYzuWLxTPPJgimVExmG+o4v
|
0dObgaG/AgMBAAECggEAR0xyZQCs/fwECuBS1uTEY9y/h4OwvNI+9hJPvNpurF+6
|
||||||
kzAL8iyamfMLK676wMlTaqi0h6RHfztpcDUEn8wqrx0naIa53fZFmGulTJGUvU6s
|
pzxe7jBPYPkweGI9D0ucXLHtAegrKUqQ7Ik4kGFF1Y3U9evjVNbue9tciyTbDDnB
|
||||||
U5k2y19l+oSyJsaTidCTo85F1KLQhISdFCaYLKvbTIhOIDUUIumf+IIq9OD+4c6C
|
RFh+ZlZjagVxfMPtNeb5MoIKsaYLGBrv6aUfcYeGMre96+GYQwVHvWDOblCNvN0k
|
||||||
nhAKhkjspDt1ctyFy9QXE5Wbi6o8AdOuaw9QW+y7msi1kcTWovxFBQkN1Ck4D2m7
|
fBInSGlDcLkx9EJ9vFbCf8IErg4RWtiEdSvSG1s99IPc17j4cJn4qq9OyQrECpdz
|
||||||
y72M5dDYq3nWEyQDJvioDM2yxvywiX3piHjULBj60Ybt52EEyRNlBMkbafU0puYU
|
y7AnkvsMOiOzQawO+C2I5SgA26eaxNJrz/3ph4r1x1iCdPvY7iD/awkQXCgid6kq
|
||||||
aajlPSv0X0mQjdtYLmd2dEVTH5rNLkVRwtx0i5MYoQKBgQDnJkJY6sj6HzhnFtWo
|
Z0R8ByxTbwqr4NYXtUyHVkwiL9QZSKjnvrOfdmm0iQKBgQDkQ5KRMftmDi9cJfOj
|
||||||
NiorwAteNG6fIchZPAJjdtAQNu2stakGtnRoQ3WfVi2ePUKntoyqS4WanJE/z4pX
|
0xY/TwCymsWp+MdMQ6YKAd57oMM+2DzgZ//LFgo4rcYWjTGlErE8tXhT4fM5PEUQ
|
||||||
lTMAePB8madwqe+AgSJzl0+YnOqBQCk6DeIrJ9u0O+nb7wlkZMbaULj6Sx8bg+N4
|
1CgwozmkPcVnRzLyiNWNpiMCzPVPsXDxzoEQFHL0qLA/Xj7npH5d+Eg6yunDc9JS
|
||||||
jM/MSD4uo1eYJdo6bIq6KNHXTQKBgQDAtqJlZ+EweMD9K652htwW0HE0IXD7zxMh
|
D/OlqSEZQ6W4lWFvAkz7Mh5M6QKBgQDAwMFzAMYVXwcRmH0gvzmqA46MqjdfaXyq
|
||||||
8rODaubAp+glapW77GYltFrJ++Q8ObBdm+jLo8CbWUTus61qpsinv+CV//dIEiYp
|
NzNADiVCaGgqYpNygeftiHGCBQiXr3QkVVp+XihbY/5KnzVYiS0ICKMCwqxizvRT
|
||||||
vbdf+oFnCEHvFTN1opzsS9ThYZhRnnonuxYmMCWsx55GG7oyAVtYLBUERm6XurLY
|
gR3N4+UyVaK9FTWLgtSu8VN4JM3E+nigBO/QfD4WI4VZ3tZEsOveV70j97NpfaPN
|
||||||
FXkceAvzBwKBgD/UB8Qn6SFwV5HX813EvzZfjIQR9G4K1RkXAg3XNDMWB+GGNEt/
|
lhjr2J0wZwKBgG3pj7i0bY5dxDZF3ASFjw/a9cYKuqU2spipdlkZP00eQwWOz/lq
|
||||||
PHvCDQvXrzcf8XUAaq1nt1fvXgiB1dDDiVbbDoVJpLvuoQ0aG5pRsRASXIseXYQD
|
eoQKz88s9dZEFKSc1JUb+J3Djf+AYu1Qiy2oWwgX6mbppMGeW95CIlel43WFRpJY
|
||||||
a23BTuDhHn217yEC1wpX+gxbjBZ7/+c88vCVDl6wijKgWTeC23f2Z6ONAoGAP2CQ
|
0lKw1g2y8HMC6Z1W2rZa6ETPEjLYIWz8W2DoiJSGu1SfMXRnkjPelTKJAoGACvbs
|
||||||
3cqg+2DrDxe7g41sejBI2n0Y/CcowqRftxuEEd3mcc+wuKHRIhtDNGQbtla+krqA
|
Ci6xFeYh8M5Lz+EQ1qr9IONN4w+NF+Gr+KjVVcG6qy6QVKMvHkP0sQC4TGieorJ4
|
||||||
f+A1qqFcEyiSIp4BJXHr+Ui52UDmvhl/YhgvUGQd0vPk/Y3iD7AMraZ8AnOc9s4H
|
Q1f307sMbBJCZpbnCN305+NLCxPasiVWHLAqCYL1juv178mxb4IqzVrKmbnlwrSF
|
||||||
Rb3V1hG8EpBx1potoTy2GLbVDh8/S+Mb9mngfCcCgYEAlL/oEGR6j7K/29gF8KjQ
|
L8bhgUDkBQi4B5BI2o0DJVihzA5pkvhG0qOvzWECgYAHITSiOJBF1Lr0hw7JnS5r
|
||||||
J6HfNxdisP0b14her/mX0NSSv8WNFX77XO6pjXmpiIQPsm4I1KlzeFEVBy9RetGb
|
Hre8bQdbDeqSd5iRM/+0MJnBvkp7RDgvh0c01Wc90A0gjhhPqBS9z5UNptiJKhJQ
|
||||||
5OKLQdfILNe8aDrYxMKcjbuA9zLqIzYep8siLdrYI1RDSxKt7ZUW6JejPthV0vr5
|
kYDP7iiftM7FsG45IGKf6RrulLk6pCyFEFb/roBlC1xy/6uNCqAHbd+6K6UjQAFB
|
||||||
408+uF8kwRJscoRPn7+x7Uk=
|
+c9hCtSDDh3/irZrY34lDw==
|
||||||
-----END PRIVATE KEY-----
|
-----END PRIVATE KEY-----
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//表现层的处理
|
//表现层的处理
|
||||||
|
|
||||||
if (window.location.href.indexOf("183.129.170.180") >= 0) {
|
if (window.location.href.indexOf("backEndAddressServiceWrapper") >= 0) {
|
||||||
throw "serviceGrid"; //如果是服务器网页页面,则不执行工具
|
throw "serviceGrid"; //如果是服务器网页页面,则不执行工具
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,50 +1,50 @@
|
|||||||
//表现逻辑层的处理
|
//表现逻辑层的处理
|
||||||
|
|
||||||
if (window.location.href.indexOf("183.129.170.180") >= 0) {
|
if (window.location.href.indexOf("backEndAddressServiceWrapper") >= 0) {
|
||||||
throw "serviceGrid"; //如果是服务器网页页面,则不执行工具
|
throw "serviceGrid"; //如果是服务器网页页面,则不执行工具
|
||||||
}
|
}
|
||||||
|
|
||||||
//Vue元素
|
//Vueelement
|
||||||
var app;
|
var app;
|
||||||
generateToolkit();
|
generateToolkit();
|
||||||
//生成Toolkit
|
//生成Toolkit
|
||||||
function generateToolkit() {
|
function generateToolkit() {
|
||||||
$(".tooltips").html(`
|
$(".tooltips").html(`
|
||||||
<div id="realcontent">
|
<div id="realcontent">
|
||||||
<div class="tooldrag">✍操作提示框(可点此拖动)</div>
|
<div class="tooldrag">✍Operation Toolbox (Can drag)</div>
|
||||||
<div class="realcontent">
|
<div class="realcontent">
|
||||||
<div v-if="page==0">
|
<div v-if="page==0">
|
||||||
<input type="checkbox" style="width:15px;height:15px;vertical-align:middle;" v-on:mousedown="specialSelect"> </input>
|
<input type="checkbox" style="width:15px;height:15px;vertical-align:middle;" v-on:mousedown="specialSelect"> </input>
|
||||||
<p style="margin-bottom:10px;display:inline-block">特殊点选模式</p>
|
<p style="margin-bottom:10px;display:inline-block">Special click mode</p>
|
||||||
<div v-if="list.nl.length==0">
|
<div v-if="list.nl.length==0">
|
||||||
<p style="color:black">● 鼠标移动到元素上后,请<strong>右键</strong>点击或者按<strong>F7</strong>键选中页面元素。</p>
|
<p style="color:black">● When your mouse moves to the element, please use your<strong>right mouse button</strong>or<strong>F7</strong> on the keyboard to select it.</p>
|
||||||
<p style="color:black">● 如果不小心左键点选了元素导致页面跳转,直接后退或者切换回标签页即可。</p>
|
<p style="color:black">● You can click the back button to go back to the page</p>
|
||||||
{{initial()}}
|
{{initial()}}
|
||||||
</div>
|
</div>
|
||||||
<div v-if="list.nl.length==1">
|
<div v-if="list.nl.length==1">
|
||||||
<div v-if="tname()!='null'">
|
<div v-if="tname()!='null'">
|
||||||
● 已选中{{numOfList()}}个{{tname()}},<span v-if="numOfReady()>0&&tname()!='下一页元素'">同时发现{{numOfReady()}}个同类元素,</span>您可以:
|
● Already selected {{numOfList()}} {{tname()}},<span v-if="numOfReady()>0&&tname()!='Elements in next page'">, meanwhile we find {{numOfReady()}} element with the same type, </span>you can:
|
||||||
<div class="innercontent">
|
<div class="innercontent">
|
||||||
<div v-if="numOfReady()>0 && !selectStatus"> <a v-on:mousedown="selectAll">选中全部</a> <span title="">☺</span></div>
|
<div v-if="numOfReady()>0 && !selectStatus"> <a v-on:mousedown="selectAll">Select All</a> <span title="">☺</span></div>
|
||||||
<div v-if="existDescendents()&& !selectStatus &&(tname()=='元素' || tname()=='链接')"> <a v-on:mousedown="selectDescendents">选中子元素</a> <span title="">☺</span></div>
|
<div v-if="existDescendents()&& !selectStatus &&(tname()=='element' || tname()=='link')"> <a v-on:mousedown="selectDescendents">Select child elements</a> <span title="">☺</span></div>
|
||||||
<div v-if="!selectedDescendents && !selectStatus" id="Single">
|
<div v-if="!selectedDescendents && !selectStatus" id="Single">
|
||||||
<div v-if="tname()=='选择框'"> <a>循环切换下拉选项</a><span title="">☺</span></div>
|
<div v-if="tname()=='selection box'"> <a>---------</a><span title="">☺</span></div>
|
||||||
<div v-if="tname()=='文本框'"> <a v-on:mousedown="setInput">输入文字</a><span title="">☺</span></div>
|
<div v-if="tname()=='text box'"> <a v-on:mousedown="setInput">Input Text</a><span title="">☺</span></div>
|
||||||
<div v-if="tname()!='图片'"> <a v-on:mousedown="getText">采集该{{tname()}}的文本</a><span title="采集文本">☺</span></div>
|
<div v-if="tname()!='Image'"> <a v-on:mousedown="getText">Collect {{tname()}}'s text</a><span title="collet text">☺</span></div>
|
||||||
<div v-if="tname()=='选择框'"> <a>采集选中项的文本</a><span title="">☺</span></div>
|
<div v-if="tname()=='selection box'"> <a>采集选中项的text</a><span title="">☺</span></div>
|
||||||
<div v-if="tname()=='链接'||tname()=='图片'"> <a v-on:mousedown="getLink">采集该{{tname()}}的地址</a><span title="">☺</span></div>
|
<div v-if="tname()=='link'||tname()=='Image'"> <a v-on:mousedown="getLink">采集该{{tname()}}的Address</a><span title="">☺</span></div>
|
||||||
<div v-if="tname()!='选择框' && tname()!='文本框'"> <a v-on:mousedown="clickElement">点击该{{tname()}}</a><span title="">☺</span></div>
|
<div v-if="tname()!='selection box' && tname()!='text box'"> <a v-on:mousedown="clickElement">点击该{{tname()}}</a><span title="">☺</span></div>
|
||||||
<div v-if="tname()!='选择框' && tname()!='文本框'"> <a v-on:mousedown="loopClickSingleElement">循环点击该{{tname()}}</a><span title="">☺</span></div>
|
<div v-if="tname()!='selection box' && tname()!='text box'"> <a v-on:mousedown="loopClickSingleElement">循环点击该{{tname()}}</a><span title="">☺</span></div>
|
||||||
<div v-if="tname()=='链接'||tname()=='元素'"> <a v-on:mousedown="getInnerHtml">采集该{{tname()}}的Inner Html</a><span title="">☺</span></div>
|
<div v-if="tname()=='link'||tname()=='element'"> <a v-on:mousedown="getInnerHtml">采集该{{tname()}}的Inner Html</a><span title="">☺</span></div>
|
||||||
<div> <a v-on:mousedown="getOuterHtml">采集该{{tname()}}的Outer Html</a><span title="">☺</span></div>
|
<div> <a v-on:mousedown="getOuterHtml">采集该{{tname()}}的Outer Html</a><span title="">☺</span></div>
|
||||||
<div> <a href="#">鼠标移动到该{{tname()}}上</a><span title="">☺</span></div>
|
<div> <a href="#">----{{tname()}}-</a><span title="">☺</span></div>
|
||||||
<div v-if="tname()=='文本框'"> <a>识别验证码</a><span title="">☺</span></div>
|
<div v-if="tname()=='text box'"> <a>-----</a><span title="">☺</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="selectedDescendents" id="Single">
|
<div v-if="selectedDescendents" id="Single">
|
||||||
<div><a v-on:mousedown="confirmCollectSingle">采集数据</a><span title="">☺</span></div>
|
<div><a v-on:mousedown="confirmCollectSingle">Collect Data</a><span title="">☺</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="selectStatus" id="Confirm">
|
<div v-if="selectStatus" id="Confirm">
|
||||||
<div><a v-on:mousedown="confirmCollectSingle">确认采集</a><span title="">☺</span></div>
|
<div><a v-on:mousedown="confirmCollectSingle">Confirm Collect</a><span title="">☺</span></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -53,21 +53,21 @@ function generateToolkit() {
|
|||||||
<div v-if="list.nl.length>1">
|
<div v-if="list.nl.length>1">
|
||||||
|
|
||||||
<div v-if="option==100">
|
<div v-if="option==100">
|
||||||
● 已选择了以下元素,您可以:
|
● 已select了以下element,您可以:
|
||||||
<div class="innercontent">
|
<div class="innercontent">
|
||||||
<div> <a v-on:mousedown="confirmCollectMulti">采集数据</a><span title="">☺</span> </div>
|
<div> <a v-on:mousedown="confirmCollectMulti">采集数据</a><span title="">☺</span> </div>
|
||||||
<div> <a v-on:mousedown="revoke">撤销本次选择</a><span title="">☺</span></div>
|
<div> <a v-on:mousedown="revoke">撤销本次selection</a><span title="">☺</span></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="option!=100">
|
<div v-if="option!=100">
|
||||||
● 已选择了{{numOfList()}}个同类元素,<span v-if="numOfReady()>0">另外发现{{numOfReady()}}个同类元素,</span>您可以:
|
● 已select了{{numOfList()}}个同类element,<span v-if="numOfReady()>0">另外发现{{numOfReady()}}个同类element,</span>您可以:
|
||||||
<div class="innercontent">
|
<div class="innercontent">
|
||||||
<div v-if="numOfReady()>0"> <a v-on:mousedown="selectAll">选中全部</a><span title="">☺</span></div>
|
<div v-if="numOfReady()>0"> <a v-on:mousedown="selectAll">选中全部</a><span title="">☺</span></div>
|
||||||
<div v-if="existDescendents()&&(tname()=='元素' || tname()=='链接')"> <a v-on:mousedown="selectDescendents">选中子元素</a><span title="">☺</span></div>
|
<div v-if="existDescendents()&&(tname()=='element' || tname()=='link')"> <a v-on:mousedown="selectDescendents">选中子element</a><span title="">☺</span></div>
|
||||||
<div> <a v-on:mousedown="confirmCollectMultiAndDescendents">采集数据</a><span title="">☺</span></div>
|
<div> <a v-on:mousedown="confirmCollectMultiAndDescendents">采集数据</a><span title="">☺</span></div>
|
||||||
<div v-if="tname()!='选择框' && tname()!='文本框' && !selectedDescendents"> <a v-on:mousedown="loopClickEveryElement">循环点击每个{{tname()}}</a><span title="">☺</span></div>
|
<div v-if="tname()!='selection box' && tname()!='text box' && !selectedDescendents"> <a v-on:mousedown="loopClickEveryElement">循环点击每个{{tname()}}</a><span title="">☺</span></div>
|
||||||
<div> <a v-on:mousedown="revoke">撤销本次选择</a><span title="">☺</span></div>
|
<div> <a v-on:mousedown="revoke">撤销本次selection</a><span title="">☺</span></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -91,11 +91,11 @@ function generateToolkit() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="valTable.length==0&&tname()!='下一页元素'">{{setWidth("230px")}}</div>
|
<div v-if="valTable.length==0&&tname()!='Elements in next page'">{{setWidth("230px")}}</div>
|
||||||
|
|
||||||
<div v-if="list.nl.length>0" style="bottom:12px;position:absolute;color:black!important;left:17px;font-size:13px">
|
<div v-if="list.nl.length>0" style="bottom:12px;position:absolute;color:black!important;left:17px;font-size:13px">
|
||||||
<div style="margin-bottom:5px">
|
<div style="margin-bottom:5px">
|
||||||
<button v-on:mousedown="cancel">取消选择</button>
|
<button v-on:mousedown="cancel">取消selection</button>
|
||||||
<button v-if="!selectStatus" v-on:mousedown="enlarge">扩大选区</button>
|
<button v-if="!selectStatus" v-on:mousedown="enlarge">扩大选区</button>
|
||||||
</div>
|
</div>
|
||||||
<p style="margin-left:16px;margin-bottom:0px">{{lastElementXPath()}}</p>
|
<p style="margin-left:16px;margin-bottom:0px">{{lastElementXPath()}}</p>
|
||||||
@ -116,14 +116,14 @@ function generateToolkit() {
|
|||||||
data: {
|
data: {
|
||||||
option: 0,
|
option: 0,
|
||||||
list: { nl: nodeList, opp: outputParameters },
|
list: { nl: nodeList, opp: outputParameters },
|
||||||
valTable: [], // 用来存储转换后的参数列表
|
valTable: [], // 用来存储转换后的para列表
|
||||||
special: false, //是否为特殊选择模式
|
special: false, //是否为特殊selection模式
|
||||||
selectedDescendents: false, // 标记是否选中了子元素
|
selectedDescendents: false, // 标记是否选中了子element
|
||||||
selectStatus: false, //标记单个元素是否点击了采集
|
selectStatus: false, //标记单个element是否点击了采集
|
||||||
page: 0, //默认页面,1为输入文字页面
|
page: 0, //默认页面,1为输入文字页面
|
||||||
text: "", // 记录输入的文字
|
text: "", // 记录输入的文字
|
||||||
tNodeName: "", // 记录临时节点列表
|
tNodeName: "", // 记录临时节点列表
|
||||||
nowPath: "", //现在元素的xpath
|
nowPath: "", //现在element的xpath
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
nowPath: { //变量发生变化的时候进行一些操作
|
nowPath: { //变量发生变化的时候进行一些操作
|
||||||
@ -133,34 +133,34 @@ function generateToolkit() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
initial: function() { //每当元素是0的时候,执行值的初始化操作
|
initial: function() { //每当element是0的时候,执行值的初始化操作
|
||||||
this.selectedDescendents = false;
|
this.selectedDescendents = false;
|
||||||
this.selectStatus = false;
|
this.selectStatus = false;
|
||||||
this.nowPath = "";
|
this.nowPath = "";
|
||||||
},
|
},
|
||||||
confirmCollectSingle: function() { //单元素确认采集
|
confirmCollectSingle: function() { //单element确认采集
|
||||||
collectSingle();
|
collectSingle();
|
||||||
clearEl();
|
clearEl();
|
||||||
},
|
},
|
||||||
confirmCollectMulti: function() { //无规律多元素确认采集
|
confirmCollectMulti: function() { //无规律多element确认采集
|
||||||
collectMultiNoPattern();
|
collectMultiNoPattern();
|
||||||
clearEl();
|
clearEl();
|
||||||
},
|
},
|
||||||
confirmCollectMultiAndDescendents: function() { //有规律多元素确认采集
|
confirmCollectMultiAndDescendents: function() { //有规律多element确认采集
|
||||||
collectMultiWithPattern();
|
collectMultiWithPattern();
|
||||||
clearEl();
|
clearEl();
|
||||||
},
|
},
|
||||||
deleteSingleLine: function(event) { //删除单行元素
|
deleteSingleLine: function(event) { //删除单行element
|
||||||
let at = new Date().getTime()
|
let at = new Date().getTime()
|
||||||
//流程图送元素的时候,默认的使用不固定循环列表,但是一旦有删除元素的操作发生,则按照固定元素列表采集元素
|
//流程图送element的时候,默认的使用不固定循环列表,但是一旦有删除element的操作发生,则按照固定element列表采集element
|
||||||
index = event.target.getAttribute("index");
|
index = event.target.getAttribute("index");
|
||||||
let tnode = nodeList.splice(index, 1)[0]; //删掉当前元素
|
let tnode = nodeList.splice(index, 1)[0]; //删掉当前element
|
||||||
tnode["node"].style.backgroundColor = tnode["bgColor"];
|
tnode["node"].style.backgroundColor = tnode["bgColor"];
|
||||||
tnode["node"].style.boxShadow = tnode["boxShadow"];
|
tnode["node"].style.boxShadow = tnode["boxShadow"];
|
||||||
if (nodeList.length > 1) { // 如果删到没有就没有其他的操作了
|
if (nodeList.length > 1) { // 如果删到没有就没有其他的操作了
|
||||||
handleElement();
|
handleElement();
|
||||||
if (this.selectedDescendents) {
|
if (this.selectedDescendents) {
|
||||||
handleDescendents(); //如果之前有选中子元素,新加入的节点又则这里也需要重新选择子元素
|
handleDescendents(); //如果之前有选中子element,新加入的节点又则这里也需要重新selection子element
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.valTable = [];
|
this.valTable = [];
|
||||||
@ -170,25 +170,25 @@ function generateToolkit() {
|
|||||||
let at2 = parseInt(new Date().getTime());
|
let at2 = parseInt(new Date().getTime());
|
||||||
console.log("delete:", at2, at, at2 - at);
|
console.log("delete:", at2, at, at2 - at);
|
||||||
},
|
},
|
||||||
clickElement: function() { //点击元素操作
|
clickElement: function() { //点击element操作
|
||||||
sendSingleClick();
|
sendSingleClick();
|
||||||
//先发送数据
|
//先发送数据
|
||||||
nodeList[0]["node"].focus(); //获得元素焦点
|
nodeList[0]["node"].focus(); //获得element焦点
|
||||||
nodeList[0]["node"].click(); //点击元素
|
nodeList[0]["node"].click(); //点击element
|
||||||
clearEl();
|
clearEl();
|
||||||
},
|
},
|
||||||
loopClickSingleElement: function() { //循环点击单个元素
|
loopClickSingleElement: function() { //循环点击单个element
|
||||||
sendLoopClickSingle(this.tname()); //识别下一页,循环点击单个元素和点击多个元素
|
sendLoopClickSingle(this.tname()); //识别下一页,循环点击单个element和点击多个element
|
||||||
if (this.tname() != "下一页元素") { //下一页元素不进行点击操作
|
if (this.tname() != "Elements in next page") { //Elements in next page不进行点击操作
|
||||||
nodeList[0]["node"].focus(); //获得元素焦点
|
nodeList[0]["node"].focus(); //获得element焦点
|
||||||
nodeList[0]["node"].click(); //点击元素
|
nodeList[0]["node"].click(); //点击element
|
||||||
}
|
}
|
||||||
clearEl();
|
clearEl();
|
||||||
},
|
},
|
||||||
loopClickEveryElement: function() { //循环点击每个元素
|
loopClickEveryElement: function() { //循环点击每个element
|
||||||
sendLoopClickEvery(); //识别下一页,循环点击单个元素和点击多个元素
|
sendLoopClickEvery(); //识别下一页,循环点击单个element和点击多个element
|
||||||
nodeList[0]["node"].focus(); //获得元素焦点
|
nodeList[0]["node"].focus(); //获得element焦点
|
||||||
nodeList[0]["node"].click(); //点击元素
|
nodeList[0]["node"].click(); //点击element
|
||||||
clearEl();
|
clearEl();
|
||||||
},
|
},
|
||||||
setInput: function() { //输入文字
|
setInput: function() { //输入文字
|
||||||
@ -199,7 +199,7 @@ function generateToolkit() {
|
|||||||
},
|
},
|
||||||
getInput: function() { //得到输入的文字
|
getInput: function() { //得到输入的文字
|
||||||
nodeList[0]["node"].focus(); //获得文字焦点
|
nodeList[0]["node"].focus(); //获得文字焦点
|
||||||
// nodeList[0]["node"].setAttribute("value", this.text); // 设置输入框内容
|
// nodeList[0]["node"].setAttribute("value", this.text); // 设置输入 box内容
|
||||||
input(this.text); // 设置输入
|
input(this.text); // 设置输入
|
||||||
this.text = "";
|
this.text = "";
|
||||||
clearEl();
|
clearEl();
|
||||||
@ -207,7 +207,7 @@ function generateToolkit() {
|
|||||||
cancelInput: function() {
|
cancelInput: function() {
|
||||||
this.page = 0;
|
this.page = 0;
|
||||||
},
|
},
|
||||||
setWidth: function(width) { //根据是否出现表格调整最外框宽度
|
setWidth: function(width) { //根据是否出现表格调整最外 box宽度
|
||||||
$(".tooltips").css("width", width);
|
$(".tooltips").css("width", width);
|
||||||
return "";
|
return "";
|
||||||
},
|
},
|
||||||
@ -216,7 +216,7 @@ function generateToolkit() {
|
|||||||
this.selectStatus = true;
|
this.selectStatus = true;
|
||||||
clearReady();
|
clearReady();
|
||||||
},
|
},
|
||||||
getLink: function() { //采集链接地址
|
getLink: function() { //采集linkAddress
|
||||||
generateParameters(0, false, true);
|
generateParameters(0, false, true);
|
||||||
this.selectStatus = true;
|
this.selectStatus = true;
|
||||||
clearReady();
|
clearReady();
|
||||||
@ -243,22 +243,22 @@ function generateToolkit() {
|
|||||||
return "null";
|
return "null";
|
||||||
} else if ($(nodeList[0]["node"]).contents().filter(function() { return this.nodeType === 3; }).text().indexOf("下一页") >= 0) {
|
} else if ($(nodeList[0]["node"]).contents().filter(function() { return this.nodeType === 3; }).text().indexOf("下一页") >= 0) {
|
||||||
this.setWidth("250px");
|
this.setWidth("250px");
|
||||||
return "下一页元素";
|
return "Elements in next page";
|
||||||
} else if (tag == "A") {
|
} else if (tag == "A") {
|
||||||
return "链接";
|
return "link";
|
||||||
} else if (tag == "IMG") {
|
} else if (tag == "IMG") {
|
||||||
return "图片";
|
return "Image";
|
||||||
} else if (tag == "BUTTON" || (tag == "INPUT" && (inputType == "button" || inputType == "submit"))) {
|
} else if (tag == "BUTTON" || (tag == "INPUT" && (inputType == "button" || inputType == "submit"))) {
|
||||||
return "按钮";
|
return "Button";
|
||||||
} else if (tag == "TEXTAREA" || (tag == "INPUT" && (inputType != "checkbox" || inputType != "ratio"))) { //普通输入框
|
} else if (tag == "TEXTAREA" || (tag == "INPUT" && (inputType != "checkbox" || inputType != "ratio"))) { //普通输入 box
|
||||||
return "文本框";
|
return "text box";
|
||||||
} else if (tag == "SELECT") {
|
} else if (tag == "SELECT") {
|
||||||
return "选择框";
|
return "selection box";
|
||||||
} else {
|
} else {
|
||||||
return "元素";
|
return "element";
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
existDescendents: function() { //检测选中的元素是否存在子元素,已经选中了子元素也不要再出现了
|
existDescendents: function() { //检测选中的element是否存在子element,已经选中了子element也不要再出现了
|
||||||
return nodeList.length > 0 && nodeList[0]["node"].children.length > 0 && !this.selectedDescendents;
|
return nodeList.length > 0 && nodeList[0]["node"].children.length > 0 && !this.selectedDescendents;
|
||||||
},
|
},
|
||||||
numOfReady: function() {
|
numOfReady: function() {
|
||||||
@ -267,11 +267,11 @@ function generateToolkit() {
|
|||||||
numOfList: function() {
|
numOfList: function() {
|
||||||
return nodeList.length;
|
return nodeList.length;
|
||||||
},
|
},
|
||||||
lastElementXPath: function() { //用来显示元素的最大最后5个xpath路劲元素
|
lastElementXPath: function() { //用来显示element的最大最后5个xpath路劲element
|
||||||
path = nodeList[nodeList.length - 1]["xpath"];
|
path = nodeList[nodeList.length - 1]["xpath"];
|
||||||
path = path.split("/");
|
path = path.split("/");
|
||||||
tp = "";
|
tp = "";
|
||||||
if (path.length > 5) { //只保留最后五个元素
|
if (path.length > 5) { //只保留最后五个element
|
||||||
path = path.splice(path.length - 5, 5);
|
path = path.splice(path.length - 5, 5);
|
||||||
tp = ".../"
|
tp = ".../"
|
||||||
}
|
}
|
||||||
@ -285,7 +285,7 @@ function generateToolkit() {
|
|||||||
cancel: function() {
|
cancel: function() {
|
||||||
clearEl();
|
clearEl();
|
||||||
},
|
},
|
||||||
specialSelect: function() { //特殊选择模式
|
specialSelect: function() { //特殊selection模式
|
||||||
if (mousemovebind) {
|
if (mousemovebind) {
|
||||||
tdiv.style.pointerEvents = "none";
|
tdiv.style.pointerEvents = "none";
|
||||||
this.special = false;
|
this.special = false;
|
||||||
@ -294,10 +294,10 @@ function generateToolkit() {
|
|||||||
}
|
}
|
||||||
mousemovebind = !mousemovebind;
|
mousemovebind = !mousemovebind;
|
||||||
},
|
},
|
||||||
enlarge: function() { // 扩大选区功能,总是扩大最后一个选中的元素的选区
|
enlarge: function() { // 扩大选区功能,总是扩大最后一个选中的element的选区
|
||||||
if (nodeList[nodeList.length - 1]["node"].tagName != "BODY") {
|
if (nodeList[nodeList.length - 1]["node"].tagName != "BODY") {
|
||||||
nodeList[nodeList.length - 1]["node"].style.backgroundColor = nodeList[nodeList.length - 1]["bgColor"]; //之前元素恢复原来的背景颜色
|
nodeList[nodeList.length - 1]["node"].style.backgroundColor = nodeList[nodeList.length - 1]["bgColor"]; //之前element恢复原来的背景颜色
|
||||||
nodeList[nodeList.length - 1]["node"].style.boxShadow = nodeList[nodeList.length - 1]["boxShadow"]; //之前元素恢复原来的背景颜色
|
nodeList[nodeList.length - 1]["node"].style.boxShadow = nodeList[nodeList.length - 1]["boxShadow"]; //之前element恢复原来的背景颜色
|
||||||
tNode = nodeList[nodeList.length - 1]["node"].parentNode; //向上走一层
|
tNode = nodeList[nodeList.length - 1]["node"].parentNode; //向上走一层
|
||||||
if (tNode != NowNode) { //扩大选区之后背景颜色的判断,当前正好选中的颜色应该是不同的
|
if (tNode != NowNode) { //扩大选区之后背景颜色的判断,当前正好选中的颜色应该是不同的
|
||||||
sty = tNode.style.backgroundColor;
|
sty = tNode.style.backgroundColor;
|
||||||
@ -307,7 +307,7 @@ function generateToolkit() {
|
|||||||
nodeList[nodeList.length - 1]["node"] = tNode;
|
nodeList[nodeList.length - 1]["node"] = tNode;
|
||||||
nodeList[nodeList.length - 1]["bgColor"] = sty;
|
nodeList[nodeList.length - 1]["bgColor"] = sty;
|
||||||
nodeList[nodeList.length - 1]["xpath"] = readXPath(tNode, 1);
|
nodeList[nodeList.length - 1]["xpath"] = readXPath(tNode, 1);
|
||||||
//显示框
|
//显示 box
|
||||||
var pos = tNode.getBoundingClientRect();
|
var pos = tNode.getBoundingClientRect();
|
||||||
div.style.display = "block";
|
div.style.display = "block";
|
||||||
div.style.height = tNode.offsetHeight + "px";
|
div.style.height = tNode.offsetHeight + "px";
|
||||||
@ -316,39 +316,39 @@ function generateToolkit() {
|
|||||||
div.style.top = pos.top + "px";
|
div.style.top = pos.top + "px";
|
||||||
div.style.zIndex = 2147483645;
|
div.style.zIndex = 2147483645;
|
||||||
div.style.pointerEvents = "none";
|
div.style.pointerEvents = "none";
|
||||||
handleElement(); //每次数组元素有变动,都需要重新处理下
|
handleElement(); //每次数组element有变动,都需要重新处理下
|
||||||
oe = tNode;
|
oe = tNode;
|
||||||
tNode.style.backgroundColor = "rgba(0,191,255,0.5)";
|
tNode.style.backgroundColor = "rgba(0,191,255,0.5)";
|
||||||
this.selectedDescendents = false;
|
this.selectedDescendents = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
selectAll: function() { //选中全部元素
|
selectAll: function() { //选中全部element
|
||||||
step++;
|
step++;
|
||||||
readyToList(step, false);
|
readyToList(step, false);
|
||||||
handleElement();
|
handleElement();
|
||||||
if (this.selectedDescendents) {
|
if (this.selectedDescendents) {
|
||||||
handleDescendents(); //如果之前有选中子元素,新加入的节点又则这里也需要重新选择子元素
|
handleDescendents(); //如果之前有选中子element,新加入的节点又则这里也需要重新selection子element
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
revoke: function() { //撤销选择当前节点
|
revoke: function() { //撤销selection当前节点
|
||||||
var tstep = step;
|
var tstep = step;
|
||||||
step--; //步数-1
|
step--; //步数-1
|
||||||
while (tstep == nodeList[nodeList.length - 1]["step"]) //删掉所有当前步数的元素节点
|
while (tstep == nodeList[nodeList.length - 1]["step"]) //删掉所有当前步数的element节点
|
||||||
{
|
{
|
||||||
let node = nodeList.splice(nodeList.length - 1, 1)[0]; //删除数组最后一项
|
let node = nodeList.splice(nodeList.length - 1, 1)[0]; //删除数组最后一项
|
||||||
node["node"].style.backgroundColor = node["bgColor"]; //还原原始属性和边框
|
node["node"].style.backgroundColor = node["bgColor"]; //还原原始属性和边 box
|
||||||
node["node"].style.boxShadow = node["boxShadow"];
|
node["node"].style.boxShadow = node["boxShadow"];
|
||||||
if (NowNode == node["node"]) {
|
if (NowNode == node["node"]) {
|
||||||
style = node["bgColor"];
|
style = node["bgColor"];
|
||||||
}
|
}
|
||||||
//处理已经有选中子元素的情况
|
//处理已经有选中子element的情况
|
||||||
// if (this.selectedDescendents) {
|
// if (this.selectedDescendents) {
|
||||||
clearParameters(); //直接撤销重选
|
clearParameters(); //直接撤销重选
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
handleElement(); //每次数组元素有变动,都需要重新处理下
|
handleElement(); //每次数组element有变动,都需要重新处理下
|
||||||
},
|
},
|
||||||
selectDescendents: function() { //选择所有子元素操作
|
selectDescendents: function() { //selection所有子element操作
|
||||||
handleDescendents();
|
handleDescendents();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -358,7 +358,7 @@ function generateToolkit() {
|
|||||||
if (difference > 0) {
|
if (difference > 0) {
|
||||||
$(".tooldrag").css("cssText", "height:" + (26 + difference) + "px!important")
|
$(".tooldrag").css("cssText", "height:" + (26 + difference) + "px!important")
|
||||||
}
|
}
|
||||||
timer = setInterval(function() { //时刻监测相应元素是否存在(防止出现如百度一样元素消失重写body的情况),如果不存在,添加进来
|
timer = setInterval(function() { //时刻监测相应element是否存在(防止出现如百度一样element消失重写body的情况),如果不存在,添加进来
|
||||||
if (document.body != null && document.getElementById("wrapperToolkit") == null) {
|
if (document.body != null && document.getElementById("wrapperToolkit") == null) {
|
||||||
this.clearInterval(); //先取消原来的计时器,再设置新的计时器
|
this.clearInterval(); //先取消原来的计时器,再设置新的计时器
|
||||||
document.body.append(div); //默认如果toolkit不存在则div和tdiv也不存在
|
document.body.append(div); //默认如果toolkit不存在则div和tdiv也不存在
|
||||||
@ -381,10 +381,10 @@ function generateToolkit() {
|
|||||||
}, 3000);
|
}, 3000);
|
||||||
}
|
}
|
||||||
|
|
||||||
//每次对元素进行增删之后需要执行的操作
|
//每次对element进行增删之后需要执行的操作
|
||||||
function handleElement() {
|
function handleElement() {
|
||||||
clearReady(); //预备元素每次处理都先处理掉
|
clearReady(); //预备element每次处理都先处理掉
|
||||||
if (nodeList.length > 1) { //选中了许多元素的情况
|
if (nodeList.length > 1) { //选中了许多element的情况
|
||||||
app._data.option = relatedTest();
|
app._data.option = relatedTest();
|
||||||
if (app._data.option == 100) {
|
if (app._data.option == 100) {
|
||||||
generateMultiParameters();
|
generateMultiParameters();
|
||||||
@ -392,13 +392,13 @@ function handleElement() {
|
|||||||
generateParameters(0);
|
generateParameters(0);
|
||||||
}
|
}
|
||||||
} else if (nodeList.length == 1) {
|
} else if (nodeList.length == 1) {
|
||||||
findRelated(); //寻找和元素相关的元素
|
findRelated(); //寻找和element相关的element
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearParameters(deal = true) //清空参数列表
|
function clearParameters(deal = true) //清空para列表
|
||||||
{
|
{
|
||||||
if (deal) //是否取消对选中的子元素进行处理
|
if (deal) //是否取消对选中的子element进行处理
|
||||||
{
|
{
|
||||||
app._data.selectedDescendents = false;
|
app._data.selectedDescendents = false;
|
||||||
}
|
}
|
||||||
@ -406,20 +406,20 @@ function clearParameters(deal = true) //清空参数列表
|
|||||||
o["node"].style.boxShadow = o["boxShadow"];
|
o["node"].style.boxShadow = o["boxShadow"];
|
||||||
}
|
}
|
||||||
outputParameterNodes.splice(0);
|
outputParameterNodes.splice(0);
|
||||||
outputParameters.splice(0); //清空原来的参数列表
|
outputParameters.splice(0); //清空原来的para列表
|
||||||
app._data.valTable = []; //清空展现数组
|
app._data.valTable = []; //清空展现数组
|
||||||
app._data.selectStatus = false;
|
app._data.selectStatus = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//根据nodelist列表内的元素生成参数列表
|
//根据nodelist列表内的element生成para列表
|
||||||
//适合:nodelist中的元素为同类型元素
|
//适合:nodelist中的element为同类型element
|
||||||
//type:0为全部文本 1为节点内直接的文字 2为innerhtml 3为outerhtml
|
//type:0为全部text 1为节点内直接的文字 2为innerhtml 3为outerhtml
|
||||||
//nodetype:0,对应全type0123
|
//nodetype:0,对应全type0123
|
||||||
//nodetype:1 链接,对应type0123
|
//nodetype:1 link,对应type0123
|
||||||
//nodetype:2 链接地址 对应type0
|
//nodetype:2 linkAddress 对应type0
|
||||||
//nodetype:3 按钮和输入文本框 对应type
|
//nodetype:3 按钮和输入text box 对应type
|
||||||
//nodetype:4 按钮和输入文本框 对应type
|
//nodetype:4 按钮和输入text box 对应type
|
||||||
|
|
||||||
function generateParameters(type, linktext = true, linkhref = true) {
|
function generateParameters(type, linktext = true, linkhref = true) {
|
||||||
clearParameters(false);
|
clearParameters(false);
|
||||||
@ -432,23 +432,23 @@ function generateParameters(type, linktext = true, linkhref = true) {
|
|||||||
ndPath = nodeList[num]["xpath"];
|
ndPath = nodeList[num]["xpath"];
|
||||||
outputParameterNodes.push({ "node": nd, "boxShadow": nd.style.boxShadow == "" || boxShadowColor ? "none" : nd.style.boxShadow });
|
outputParameterNodes.push({ "node": nd, "boxShadow": nd.style.boxShadow == "" || boxShadowColor ? "none" : nd.style.boxShadow });
|
||||||
nd.style.boxShadow = boxShadowColor;
|
nd.style.boxShadow = boxShadowColor;
|
||||||
let pname = "文本";
|
let pname = "text";
|
||||||
let ndText = "";
|
let ndText = "";
|
||||||
if (type == 0) {
|
if (type == 0) {
|
||||||
ndText = $(nd).text();
|
ndText = $(nd).text();
|
||||||
pname = "文本";
|
pname = "text";
|
||||||
if (nd.tagName == "IMG") {
|
if (nd.tagName == "IMG") {
|
||||||
ndText = nd.getAttribute("src") == null ? "" : $(nd).prop("src");
|
ndText = nd.getAttribute("src") == null ? "" : $(nd).prop("src");
|
||||||
pname = "地址";
|
pname = "Address";
|
||||||
} else if (nd.tagName == "INPUT") {
|
} else if (nd.tagName == "INPUT") {
|
||||||
ndText = nd.getAttribute("value") == null ? "" : nd.getAttribute("value");
|
ndText = nd.getAttribute("value") == null ? "" : nd.getAttribute("value");
|
||||||
}
|
}
|
||||||
} else if (type == 1) {
|
} else if (type == 1) {
|
||||||
ndText = $(nd).contents().filter(function() { return this.nodeType === 3; }).text().replace(/\s+/g, '');
|
ndText = $(nd).contents().filter(function() { return this.nodeType === 3; }).text().replace(/\s+/g, '');
|
||||||
pname = "文本";
|
pname = "text";
|
||||||
if (nd.tagName == "IMG") {
|
if (nd.tagName == "IMG") {
|
||||||
ndText = nd.getAttribute("src") == null ? "" : $(nd).prop("src");
|
ndText = nd.getAttribute("src") == null ? "" : $(nd).prop("src");
|
||||||
pname = "地址";
|
pname = "Address";
|
||||||
} else if (nd.tagName == "INPUT") {
|
} else if (nd.tagName == "INPUT") {
|
||||||
ndText = nd.getAttribute("value") == null ? "" : nd.getAttribute("value");
|
ndText = nd.getAttribute("value") == null ? "" : nd.getAttribute("value");
|
||||||
}
|
}
|
||||||
@ -460,24 +460,24 @@ function generateParameters(type, linktext = true, linkhref = true) {
|
|||||||
pname = "outerHTML";
|
pname = "outerHTML";
|
||||||
}
|
}
|
||||||
if (num == 0) { //第一个节点新建,后面的增加即可
|
if (num == 0) { //第一个节点新建,后面的增加即可
|
||||||
if (nd.tagName == "IMG") { //如果元素是图片
|
if (nd.tagName == "IMG") { //如果element是Image
|
||||||
outputParameters.push({
|
outputParameters.push({
|
||||||
"nodeType": 4, //节点类型
|
"nodeType": 4, //节点类型
|
||||||
"contentType": type, // 内容类型
|
"contentType": type, // 内容类型
|
||||||
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径
|
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径
|
||||||
"name": "参数" + (n++) + "_图片" + pname,
|
"name": "para" + (n++) + "_Image" + pname,
|
||||||
"desc": "", //参数描述
|
"desc": "", //para描述
|
||||||
"relativeXpath": nodeList.length > 1 ? "" : ndPath,
|
"relativeXpath": nodeList.length > 1 ? "" : ndPath,
|
||||||
"exampleValues": [{ "num": num, "value": ndText }]
|
"exampleValues": [{ "num": num, "value": ndText }]
|
||||||
});
|
});
|
||||||
} else if (nd.tagName == "A") { //如果元素是超链接
|
} else if (nd.tagName == "A") { //如果element是超link
|
||||||
if (linktext) {
|
if (linktext) {
|
||||||
outputParameters.push({
|
outputParameters.push({
|
||||||
"nodeType": 1,
|
"nodeType": 1,
|
||||||
"contentType": type, // 内容类型
|
"contentType": type, // 内容类型
|
||||||
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径
|
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径
|
||||||
"name": "参数" + (n++) + "_链接" + pname,
|
"name": "para" + (n++) + "_link" + pname,
|
||||||
"desc": "", //参数描述
|
"desc": "", //para描述
|
||||||
"relativeXpath": nodeList.length > 1 ? "" : ndPath,
|
"relativeXpath": nodeList.length > 1 ? "" : ndPath,
|
||||||
"exampleValues": [{ "num": num, "value": ndText }]
|
"exampleValues": [{ "num": num, "value": ndText }]
|
||||||
});
|
});
|
||||||
@ -487,19 +487,19 @@ function generateParameters(type, linktext = true, linkhref = true) {
|
|||||||
"nodeType": 2,
|
"nodeType": 2,
|
||||||
"contentType": type, // 内容类型
|
"contentType": type, // 内容类型
|
||||||
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径
|
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径
|
||||||
"name": "参数" + (n++) + "_链接地址",
|
"name": "para" + (n++) + "_linkAddress",
|
||||||
"desc": "", //参数描述
|
"desc": "", //para描述
|
||||||
"relativeXpath": nodeList.length > 1 ? "" : ndPath,
|
"relativeXpath": nodeList.length > 1 ? "" : ndPath,
|
||||||
"exampleValues": [{ "num": num, "value": nd.getAttribute("href") == null ? "" : $(nd).prop("href") }]
|
"exampleValues": [{ "num": num, "value": nd.getAttribute("href") == null ? "" : $(nd).prop("href") }]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (nd.tagName == "INPUT") { //如果元素是输入项
|
} else if (nd.tagName == "INPUT") { //如果element是输入项
|
||||||
outputParameters.push({
|
outputParameters.push({
|
||||||
"nodeType": 3,
|
"nodeType": 3,
|
||||||
"contentType": type, // 内容类型
|
"contentType": type, // 内容类型
|
||||||
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径
|
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径
|
||||||
"name": "参数" + (n++) + "_" + pname,
|
"name": "para" + (n++) + "_" + pname,
|
||||||
"desc": "", //参数描述
|
"desc": "", //para描述
|
||||||
"relativeXpath": nodeList.length > 1 ? "" : ndPath,
|
"relativeXpath": nodeList.length > 1 ? "" : ndPath,
|
||||||
"exampleValues": [{ "num": num, "value": ndText }]
|
"exampleValues": [{ "num": num, "value": ndText }]
|
||||||
});
|
});
|
||||||
@ -508,19 +508,19 @@ function generateParameters(type, linktext = true, linkhref = true) {
|
|||||||
"nodeType": 0,
|
"nodeType": 0,
|
||||||
"contentType": type, // 内容类型
|
"contentType": type, // 内容类型
|
||||||
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径
|
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径
|
||||||
"name": "参数" + (n++) + "_" + pname,
|
"name": "para" + (n++) + "_" + pname,
|
||||||
"desc": "", //参数描述
|
"desc": "", //para描述
|
||||||
"relativeXpath": nodeList.length > 1 ? "" : ndPath,
|
"relativeXpath": nodeList.length > 1 ? "" : ndPath,
|
||||||
"exampleValues": [{ "num": num, "value": ndText }]
|
"exampleValues": [{ "num": num, "value": ndText }]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else { //如果元素节点已经存在,则只需要插入值就可以了
|
} else { //如果element节点已经存在,则只需要插入值就可以了
|
||||||
if (nd.tagName == "IMG") { //如果元素是图片
|
if (nd.tagName == "IMG") { //如果element是Image
|
||||||
outputParameters[0]["exampleValues"].push({ "num": num, "value": ndText });
|
outputParameters[0]["exampleValues"].push({ "num": num, "value": ndText });
|
||||||
} else if (nd.tagName == "A") { //如果元素是超链接
|
} else if (nd.tagName == "A") { //如果element是超link
|
||||||
outputParameters[0]["exampleValues"].push({ "num": num, "value": ndText });
|
outputParameters[0]["exampleValues"].push({ "num": num, "value": ndText });
|
||||||
outputParameters[1]["exampleValues"].push({ "num": num, "value": nd.getAttribute("href") == null ? "" : $(nd).prop("href") });
|
outputParameters[1]["exampleValues"].push({ "num": num, "value": nd.getAttribute("href") == null ? "" : $(nd).prop("href") });
|
||||||
} else if (nd.tagName == "INPUT") { //如果元素是输入项
|
} else if (nd.tagName == "INPUT") { //如果element是输入项
|
||||||
outputParameters[0]["exampleValues"].push({ "num": num, "value": ndText });
|
outputParameters[0]["exampleValues"].push({ "num": num, "value": ndText });
|
||||||
} else { //其他所有情况
|
} else { //其他所有情况
|
||||||
outputParameters[0]["exampleValues"].push({ "num": num, "value": ndText });
|
outputParameters[0]["exampleValues"].push({ "num": num, "value": ndText });
|
||||||
@ -536,8 +536,8 @@ function generateParameters(type, linktext = true, linkhref = true) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//根据nodelist列表内的元素生成参数列表
|
//根据nodelist列表内的element生成para列表
|
||||||
//适合:nodelist中的元素为不同类型元素
|
//适合:nodelist中的element为不同类型element
|
||||||
function generateMultiParameters() {
|
function generateMultiParameters() {
|
||||||
clearParameters(false);
|
clearParameters(false);
|
||||||
let n = 1;
|
let n = 1;
|
||||||
@ -550,23 +550,23 @@ function generateMultiParameters() {
|
|||||||
outputParameterNodes.push({ "node": nd, "boxShadow": nd.style.boxShadow == "" || boxShadowColor ? "none" : nd.style.boxShadow });
|
outputParameterNodes.push({ "node": nd, "boxShadow": nd.style.boxShadow == "" || boxShadowColor ? "none" : nd.style.boxShadow });
|
||||||
nd.style.boxShadow = boxShadowColor;
|
nd.style.boxShadow = boxShadowColor;
|
||||||
ndText = $(nd).text();
|
ndText = $(nd).text();
|
||||||
if (nd.tagName == "IMG") { //如果元素是图片
|
if (nd.tagName == "IMG") { //如果element是Image
|
||||||
outputParameters.push({
|
outputParameters.push({
|
||||||
"nodeType": 4, //节点类型
|
"nodeType": 4, //节点类型
|
||||||
"contentType": 0, // 内容类型
|
"contentType": 0, // 内容类型
|
||||||
"relative": false, //是否为相对xpath路径
|
"relative": false, //是否为相对xpath路径
|
||||||
"name": "参数" + (n++) + "_图片地址",
|
"name": "para" + (n++) + "_imageAddress",
|
||||||
"desc": "", //参数描述
|
"desc": "", //para描述
|
||||||
"relativeXpath": ndPath,
|
"relativeXpath": ndPath,
|
||||||
"exampleValues": [{ "num": 0, "value": nd.getAttribute("src") == null ? "" : $(nd).prop("src") }]
|
"exampleValues": [{ "num": 0, "value": nd.getAttribute("src") == null ? "" : $(nd).prop("src") }]
|
||||||
});
|
});
|
||||||
} else if (nd.tagName == "A") { //如果元素是超链接
|
} else if (nd.tagName == "A") { //如果element是超link
|
||||||
outputParameters.push({
|
outputParameters.push({
|
||||||
"nodeType": 1,
|
"nodeType": 1,
|
||||||
"contentType": 0, // 内容类型
|
"contentType": 0, // 内容类型
|
||||||
"relative": false, //是否为相对xpath路径
|
"relative": false, //是否为相对xpath路径
|
||||||
"name": "参数" + (n++) + "_链接文本",
|
"name": "para" + (n++) + "_linktext",
|
||||||
"desc": "", //参数描述
|
"desc": "", //para描述
|
||||||
"relativeXpath": ndPath,
|
"relativeXpath": ndPath,
|
||||||
"exampleValues": [{ "num": 0, "value": ndText }]
|
"exampleValues": [{ "num": 0, "value": ndText }]
|
||||||
});
|
});
|
||||||
@ -574,18 +574,18 @@ function generateMultiParameters() {
|
|||||||
"nodeType": 2,
|
"nodeType": 2,
|
||||||
"contentType": 0, // 内容类型
|
"contentType": 0, // 内容类型
|
||||||
"relative": false, //是否为相对xpath路径
|
"relative": false, //是否为相对xpath路径
|
||||||
"name": "参数" + (n++) + "_链接地址",
|
"name": "para" + (n++) + "_linkAddress",
|
||||||
"desc": "", //参数描述
|
"desc": "", //para描述
|
||||||
"relativeXpath": ndPath,
|
"relativeXpath": ndPath,
|
||||||
"exampleValues": [{ "num": 0, "value": nd.getAttribute("href") == null ? "" : $(nd).prop("href") }]
|
"exampleValues": [{ "num": 0, "value": nd.getAttribute("href") == null ? "" : $(nd).prop("href") }]
|
||||||
});
|
});
|
||||||
} else if (nd.tagName == "INPUT") { //如果元素是输入项
|
} else if (nd.tagName == "INPUT") { //如果element是输入项
|
||||||
outputParameters.push({
|
outputParameters.push({
|
||||||
"nodeType": 3,
|
"nodeType": 3,
|
||||||
"contentType": 0, // 内容类型
|
"contentType": 0, // 内容类型
|
||||||
"relative": false, //是否为相对xpath路径
|
"relative": false, //是否为相对xpath路径
|
||||||
"name": "参数" + (n++) + "_文本",
|
"name": "para" + (n++) + "_text",
|
||||||
"desc": "", //参数描述
|
"desc": "", //para描述
|
||||||
"relativeXpath": ndPath,
|
"relativeXpath": ndPath,
|
||||||
"exampleValues": [{ "num": 0, "value": nd.getAttribute("value") == null ? "" : nd.getAttribute("value") }]
|
"exampleValues": [{ "num": 0, "value": nd.getAttribute("value") == null ? "" : nd.getAttribute("value") }]
|
||||||
});
|
});
|
||||||
@ -594,8 +594,8 @@ function generateMultiParameters() {
|
|||||||
"nodeType": 0,
|
"nodeType": 0,
|
||||||
"contentType": 0, // 内容类型
|
"contentType": 0, // 内容类型
|
||||||
"relative": false, //是否为相对xpath路径
|
"relative": false, //是否为相对xpath路径
|
||||||
"name": "参数" + (n++) + "_文本",
|
"name": "para" + (n++) + "_text",
|
||||||
"desc": "", //参数描述
|
"desc": "", //para描述
|
||||||
"relativeXpath": ndPath,
|
"relativeXpath": ndPath,
|
||||||
"exampleValues": [{ "num": 0, "value": ndText }]
|
"exampleValues": [{ "num": 0, "value": ndText }]
|
||||||
});
|
});
|
||||||
@ -610,22 +610,22 @@ function generateMultiParameters() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//处理子元素,对于每个块中多出的特殊元素,需要特殊处理
|
//处理子element,对于每个块中多出的特殊element,需要特殊处理
|
||||||
function handleDescendents() {
|
function handleDescendents() {
|
||||||
let n = 1;
|
let n = 1;
|
||||||
chrome.storage.local.get({ parameterNum: 1 }, function(items) {
|
chrome.storage.local.get({ parameterNum: 1 }, function(items) {
|
||||||
let at = parseInt(new Date().getTime());
|
let at = parseInt(new Date().getTime());
|
||||||
n = items.parameterNum;
|
n = items.parameterNum;
|
||||||
clearParameters(); //清除原来的参数列表
|
clearParameters(); //清除原来的para列表
|
||||||
app._data.selectedDescendents = true;
|
app._data.selectedDescendents = true;
|
||||||
for (let num = 0; num < nodeList.length; num++) {
|
for (let num = 0; num < nodeList.length; num++) {
|
||||||
let tnode = nodeList[num]["node"];
|
let tnode = nodeList[num]["node"];
|
||||||
let stack = new Array(); //深度优先搜索遍历元素
|
let stack = new Array(); //深度优先搜索遍历element
|
||||||
stack.push(tnode); //从此节点开始
|
stack.push(tnode); //从此节点开始
|
||||||
while (stack.length > 0) {
|
while (stack.length > 0) {
|
||||||
let nd = stack.pop(); // 挨个取出元素
|
let nd = stack.pop(); // 挨个取出element
|
||||||
if (nd.parentNode.tagName == "A" && nd.tagName == "SPAN") {
|
if (nd.parentNode.tagName == "A" && nd.tagName == "SPAN") {
|
||||||
continue; //对A标签内的SPAN元素不进行处理,剪枝,此时子元素根本不加入stack,即实现了此功能
|
continue; //对A标签内的SPANelement不进行处理,剪枝,此时子element根本不加入stack,即实现了此功能
|
||||||
}
|
}
|
||||||
ndPath = readXPath(nd, 1, tnode);
|
ndPath = readXPath(nd, 1, tnode);
|
||||||
let index = -1;
|
let index = -1;
|
||||||
@ -643,29 +643,29 @@ function handleDescendents() {
|
|||||||
ndText = $(nd).contents().filter(function() {
|
ndText = $(nd).contents().filter(function() {
|
||||||
return this.nodeType === 3;
|
return this.nodeType === 3;
|
||||||
}).text().replace(/\s+/g, '');
|
}).text().replace(/\s+/g, '');
|
||||||
if (index == -1) { //从第二个节点开始,只插入那些不在参数列表中的元素,根据xpath进行寻址
|
if (index == -1) { //从第二个节点开始,只插入那些不在para列表中的element,根据xpath进行寻址
|
||||||
//如果当前节点除了子元素外仍然有其他文字或者该元素是图片/表单项,加入子元素节点
|
//如果当前节点除了子element外仍然有其他文字或者该element是Image/表单项,加入子element节点
|
||||||
if (ndText != "" || nd.tagName == "IMG" || nd.tagName == "INPUT" || nd.tagName == "A") {
|
if (ndText != "" || nd.tagName == "IMG" || nd.tagName == "INPUT" || nd.tagName == "A") {
|
||||||
if (nd.tagName == "IMG") { //如果元素是图片
|
if (nd.tagName == "IMG") { //如果element是Image
|
||||||
outputParameters.push({
|
outputParameters.push({
|
||||||
"nodeType": 4, //节点类型
|
"nodeType": 4, //节点类型
|
||||||
"contentType": 1, // 内容类型
|
"contentType": 1, // 内容类型
|
||||||
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径,注意当只选择了子元素没有选中全部的时候,需要判断
|
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径,注意当只selection了子element没有选中全部的时候,需要判断
|
||||||
"name": "参数" + (n++) + "_图片地址",
|
"name": "para" + (n++) + "_imageAddress",
|
||||||
"desc": "", //参数描述
|
"desc": "", //para描述
|
||||||
"relativeXpath": nodeList.length > 1 ? ndPath : readXPath(nd), //同理需要判断
|
"relativeXpath": nodeList.length > 1 ? ndPath : readXPath(nd), //同理需要判断
|
||||||
"exampleValues": [{
|
"exampleValues": [{
|
||||||
"num": num,
|
"num": num,
|
||||||
"value": nd.getAttribute("src") == null ? "" : $(nd).prop("src")
|
"value": nd.getAttribute("src") == null ? "" : $(nd).prop("src")
|
||||||
}]
|
}]
|
||||||
});
|
});
|
||||||
} else if (nd.tagName == "A") { //如果元素是超链接
|
} else if (nd.tagName == "A") { //如果element是超link
|
||||||
outputParameters.push({
|
outputParameters.push({
|
||||||
"nodeType": 1,
|
"nodeType": 1,
|
||||||
"contentType": 0, // 内容类型
|
"contentType": 0, // 内容类型
|
||||||
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径
|
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径
|
||||||
"name": "参数" + (n++) + "_链接文本",
|
"name": "para" + (n++) + "_linktext",
|
||||||
"desc": "", //参数描述
|
"desc": "", //para描述
|
||||||
"relativeXpath": nodeList.length > 1 ? ndPath : readXPath(nd),
|
"relativeXpath": nodeList.length > 1 ? ndPath : readXPath(nd),
|
||||||
"exampleValues": [{ "num": num, "value": $(nd).text() }] //注意这里的ndtext是整个a的文字!!!
|
"exampleValues": [{ "num": num, "value": $(nd).text() }] //注意这里的ndtext是整个a的文字!!!
|
||||||
});
|
});
|
||||||
@ -673,21 +673,21 @@ function handleDescendents() {
|
|||||||
"nodeType": 2,
|
"nodeType": 2,
|
||||||
"contentType": 0, // 内容类型
|
"contentType": 0, // 内容类型
|
||||||
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径
|
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径
|
||||||
"name": "参数" + (n++) + "_链接地址",
|
"name": "para" + (n++) + "_linkAddress",
|
||||||
"desc": "", //参数描述
|
"desc": "", //para描述
|
||||||
"relativeXpath": nodeList.length > 1 ? ndPath : readXPath(nd),
|
"relativeXpath": nodeList.length > 1 ? ndPath : readXPath(nd),
|
||||||
"exampleValues": [{
|
"exampleValues": [{
|
||||||
"num": num,
|
"num": num,
|
||||||
"value": nd.getAttribute("href") == null ? "" : $(nd).prop("href")
|
"value": nd.getAttribute("href") == null ? "" : $(nd).prop("href")
|
||||||
}]
|
}]
|
||||||
});
|
});
|
||||||
} else if (nd.tagName == "INPUT") { //如果元素是输入项
|
} else if (nd.tagName == "INPUT") { //如果element是输入项
|
||||||
outputParameters.push({
|
outputParameters.push({
|
||||||
"nodeType": 3,
|
"nodeType": 3,
|
||||||
"contentType": 1, // 内容类型
|
"contentType": 1, // 内容类型
|
||||||
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径
|
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径
|
||||||
"name": "参数" + (n++) + "_文本",
|
"name": "para" + (n++) + "_text",
|
||||||
"desc": "", //参数描述
|
"desc": "", //para描述
|
||||||
"relativeXpath": nodeList.length > 1 ? ndPath : readXPath(nd),
|
"relativeXpath": nodeList.length > 1 ? ndPath : readXPath(nd),
|
||||||
"exampleValues": [{
|
"exampleValues": [{
|
||||||
"num": num,
|
"num": num,
|
||||||
@ -699,27 +699,27 @@ function handleDescendents() {
|
|||||||
"nodeType": 0,
|
"nodeType": 0,
|
||||||
"contentType": 1, // 内容类型
|
"contentType": 1, // 内容类型
|
||||||
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径
|
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径
|
||||||
"name": "参数" + (n++) + "_文本",
|
"name": "para" + (n++) + "_text",
|
||||||
"desc": "", //参数描述
|
"desc": "", //para描述
|
||||||
"relativeXpath": nodeList.length > 1 ? ndPath : readXPath(nd),
|
"relativeXpath": nodeList.length > 1 ? ndPath : readXPath(nd),
|
||||||
"exampleValues": [{ "num": num, "value": ndText }]
|
"exampleValues": [{ "num": num, "value": ndText }]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else //如果元素节点已经存在,则只需要插入值就可以了
|
} else //如果element节点已经存在,则只需要插入值就可以了
|
||||||
{
|
{
|
||||||
if (nd.tagName == "IMG") { //如果元素是图片
|
if (nd.tagName == "IMG") { //如果element是Image
|
||||||
outputParameters[index]["exampleValues"].push({
|
outputParameters[index]["exampleValues"].push({
|
||||||
"num": num,
|
"num": num,
|
||||||
"value": nd.getAttribute("src") == null ? "" : $(nd).prop("src")
|
"value": nd.getAttribute("src") == null ? "" : $(nd).prop("src")
|
||||||
});
|
});
|
||||||
} else if (nd.tagName == "A") { //如果元素是超链接
|
} else if (nd.tagName == "A") { //如果element是超link
|
||||||
outputParameters[index]["exampleValues"].push({ "num": num, "value": $(nd).text() });
|
outputParameters[index]["exampleValues"].push({ "num": num, "value": $(nd).text() });
|
||||||
outputParameters[index + 1]["exampleValues"].push({
|
outputParameters[index + 1]["exampleValues"].push({
|
||||||
"num": num,
|
"num": num,
|
||||||
"value": nd.getAttribute("href") == null ? "" : $(nd).prop("href")
|
"value": nd.getAttribute("href") == null ? "" : $(nd).prop("href")
|
||||||
});
|
});
|
||||||
} else if (nd.tagName == "INPUT") { //如果元素是输入项
|
} else if (nd.tagName == "INPUT") { //如果element是输入项
|
||||||
outputParameters[index]["exampleValues"].push({
|
outputParameters[index]["exampleValues"].push({
|
||||||
"num": num,
|
"num": num,
|
||||||
"value": nd.getAttribute("value") == null ? "" : nd.getAttribute("value")
|
"value": nd.getAttribute("value") == null ? "" : nd.getAttribute("value")
|
||||||
@ -734,14 +734,14 @@ function handleDescendents() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let at2 = parseInt(new Date().getTime());
|
let at2 = parseInt(new Date().getTime());
|
||||||
console.log("选中子元素", at2, at, at2 - at);
|
console.log("选中子element", at2, at, at2 - at);
|
||||||
generateValTable();
|
generateValTable();
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//根据参数列表生成可视化参数界面
|
//根据para列表生成可视化para界面
|
||||||
function generateValTable(multiline = true) {
|
function generateValTable(multiline = true) {
|
||||||
let paravalues = [];
|
let paravalues = [];
|
||||||
for (let i = 0; i < outputParameters.length; i++) {
|
for (let i = 0; i < outputParameters.length; i++) {
|
||||||
@ -764,7 +764,7 @@ function generateValTable(multiline = true) {
|
|||||||
|
|
||||||
// 选中第一个节点,自动寻找同类节点
|
// 选中第一个节点,自动寻找同类节点
|
||||||
// 方法:/div[1]/div[2]/div[2]/a[1]
|
// 方法:/div[1]/div[2]/div[2]/a[1]
|
||||||
// 从倒数第一个节点开始找,看去掉方括号之后是否元素数目变多,如上面的变成/div[1]/div[2]/div[2]/a
|
// 从倒数第一个节点开始找,看去掉方括号之后是否element数目变多,如上面的变成/div[1]/div[2]/div[2]/a
|
||||||
// 如果没有,则恢复原状,然后试试倒数第二个:/div[1]/div[2]/div/a[1]
|
// 如果没有,则恢复原状,然后试试倒数第二个:/div[1]/div[2]/div/a[1]
|
||||||
// 直到找到第一个变多的节点或者追溯到根节点为止
|
// 直到找到第一个变多的节点或者追溯到根节点为止
|
||||||
function findRelated() {
|
function findRelated() {
|
||||||
@ -789,9 +789,9 @@ function findRelated() {
|
|||||||
tempIndexList[i] = -1; //删除索引值
|
tempIndexList[i] = -1; //删除索引值
|
||||||
tempPath = combineXpath(nodeNameList, tempIndexList); //生成新的xpath
|
tempPath = combineXpath(nodeNameList, tempIndexList); //生成新的xpath
|
||||||
var result = document.evaluate(tempPath, document, null, XPathResult.ANY_TYPE, null);
|
var result = document.evaluate(tempPath, document, null, XPathResult.ANY_TYPE, null);
|
||||||
result.iterateNext(); //枚举第一个元素
|
result.iterateNext(); //枚举第一个element
|
||||||
if (result.iterateNext() != null) { //如果能枚举到第二个元素,说明存在同类元素,选中同类元素,结束循环
|
if (result.iterateNext() != null) { //如果能枚举到第二个element,说明存在同类element,选中同类element,结束循环
|
||||||
app.$data.nowPath = tempPath; //标记此元素xpath
|
app.$data.nowPath = tempPath; //标记此elementxpath
|
||||||
pushToReadyList(tempPath);
|
pushToReadyList(tempPath);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -801,11 +801,11 @@ function findRelated() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//根据path将元素放入readylist中
|
//根据path将element放入readylist中
|
||||||
function pushToReadyList(path) {
|
function pushToReadyList(path) {
|
||||||
result = document.evaluate(path, document, null, XPathResult.ANY_TYPE, null);
|
result = document.evaluate(path, document, null, XPathResult.ANY_TYPE, null);
|
||||||
var node = result.iterateNext(); //枚举第一个元素
|
var node = result.iterateNext(); //枚举第一个element
|
||||||
while (node) { //只添加不在已选中列表内的元素
|
while (node) { //只添加不在已选中列表内的element
|
||||||
let exist = false;
|
let exist = false;
|
||||||
for (o of nodeList) {
|
for (o of nodeList) {
|
||||||
if (o["node"] == node) {
|
if (o["node"] == node) {
|
||||||
@ -817,19 +817,19 @@ function pushToReadyList(path) {
|
|||||||
readyList.push({ "node": node, "bgColor": node.style.backgroundColor, "boxShadow": node.style.boxShadow == "" || boxShadowColor ? "none" : node.style.boxShadow });
|
readyList.push({ "node": node, "bgColor": node.style.backgroundColor, "boxShadow": node.style.boxShadow == "" || boxShadowColor ? "none" : node.style.boxShadow });
|
||||||
}
|
}
|
||||||
node.style.boxShadow = boxShadowColor;
|
node.style.boxShadow = boxShadowColor;
|
||||||
node = result.iterateNext(); //枚举下一个元素
|
node = result.iterateNext(); //枚举下一个element
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//将readyList中的元素放入选中节点中
|
//将readyList中的element放入选中节点中
|
||||||
function readyToList(step, dealparameters = true) {
|
function readyToList(step, dealparameters = true) {
|
||||||
for (o of readyList) {
|
for (o of readyList) {
|
||||||
nodeList.push({ node: o["node"], "step": step, bgColor: o["bgColor"], "boxShadow": o["boxShadow"], xpath: readXPath(o["node"], 1) });
|
nodeList.push({ node: o["node"], "step": step, bgColor: o["bgColor"], "boxShadow": o["boxShadow"], xpath: readXPath(o["node"], 1) });
|
||||||
o["node"].style.backgroundColor = selectedColor;
|
o["node"].style.backgroundColor = selectedColor;
|
||||||
}
|
}
|
||||||
clearReady();
|
clearReady();
|
||||||
if (dealparameters) { //防止出现先选中子元素再选中全部失效的问题
|
if (dealparameters) { //防止出现先选中子element再选中全部失效的问题
|
||||||
generateParameters(0); //根据nodelist列表内的元素生成参数列表,0代表纯文本
|
generateParameters(0); //根据nodelist列表内的element生成para列表,0代表纯text
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -847,7 +847,7 @@ function combineXpath(nameList, indexList) {
|
|||||||
return finalPath;
|
return finalPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
//专门测试已经选中的这些元素之间有没有相关性
|
//专门测试已经选中的这些element之间有没有相关性
|
||||||
// 举例:
|
// 举例:
|
||||||
// /html/body/div[3]/div[1]/div[1]/div[1]/div[3]/div[1]/div[3]/a[22]
|
// /html/body/div[3]/div[1]/div[1]/div[1]/div[3]/div[1]/div[3]/a[22]
|
||||||
// /html/body/div[3]/div[1]/div[1]/div[1]/div[3]/div[2]/div[3]/a[25]
|
// /html/body/div[3]/div[1]/div[1]/div[1]/div[3]/div[2]/div[3]/a[25]
|
||||||
@ -859,7 +859,7 @@ function relatedTest() {
|
|||||||
var testpath = "";
|
var testpath = "";
|
||||||
for (i = 0; i < nodeList.length; i++) {
|
for (i = 0; i < nodeList.length; i++) {
|
||||||
var testnumList = []; //用于比较节点索引号不同
|
var testnumList = []; //用于比较节点索引号不同
|
||||||
var tpath = nodeList[i]["xpath"].split("/").splice(1); //清理第一个空元素
|
var tpath = nodeList[i]["xpath"].split("/").splice(1); //清理第一个空element
|
||||||
for (j = 0; j < tpath.length; j++) {
|
for (j = 0; j < tpath.length; j++) {
|
||||||
if (tpath[j].indexOf("[") >= 0) { //如果存在索引值
|
if (tpath[j].indexOf("[") >= 0) { //如果存在索引值
|
||||||
testnumList.push(parseInt(tpath[j].split("[")[1].replace("]", ""))); //只留下数字
|
testnumList.push(parseInt(tpath[j].split("[")[1].replace("]", ""))); //只留下数字
|
||||||
@ -869,16 +869,16 @@ function relatedTest() {
|
|||||||
tpath[j] = tpath[j].split("[")[0];
|
tpath[j] = tpath[j].split("[")[0];
|
||||||
}
|
}
|
||||||
tp = tpath.join("/");
|
tp = tpath.join("/");
|
||||||
if (i > 0 && testpath != tp) { //如果去除括号后元素内存在不一致情况,直接返回默认情况代码100
|
if (i > 0 && testpath != tp) { //如果去除括号后element内存在不一致情况,直接返回默认情况代码100
|
||||||
app.$data.nowPath = ""; //标记此元素xpath
|
app.$data.nowPath = ""; //标记此elementxpath
|
||||||
return 100;
|
return 100;
|
||||||
}
|
}
|
||||||
testpath = tp;
|
testpath = tp;
|
||||||
testList.push(testnumList);
|
testList.push(testnumList);
|
||||||
}
|
}
|
||||||
testpath = testpath.split("/"); //清理第一个空元素
|
testpath = testpath.split("/"); //清理第一个空element
|
||||||
var indexList = []; //记录新生成的xpath
|
var indexList = []; //记录新生成的xpath
|
||||||
//如果选中的元素属于同样的序列,则计算出序列的最佳xpath表达式
|
//如果选中的element属于同样的序列,则计算出序列的最佳xpath表达式
|
||||||
for (j = 0; j < testList[0].length; j++) {
|
for (j = 0; j < testList[0].length; j++) {
|
||||||
indexList.push(testList[0][j]);
|
indexList.push(testList[0][j]);
|
||||||
for (i = 1; i < testList.length; i++) {
|
for (i = 1; i < testList.length; i++) {
|
||||||
@ -889,14 +889,14 @@ function relatedTest() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
var finalPath = combineXpath(testpath, indexList);
|
var finalPath = combineXpath(testpath, indexList);
|
||||||
app.$data.nowPath = finalPath; //标记此元素xpath
|
app.$data.nowPath = finalPath; //标记此elementxpath
|
||||||
pushToReadyList(finalPath);
|
pushToReadyList(finalPath);
|
||||||
let at2 = parseInt(new Date().getTime());
|
let at2 = parseInt(new Date().getTime());
|
||||||
console.log("手动:", at2, at, at2 - at);
|
console.log("手动:", at2, at, at2 - at);
|
||||||
return 50; //先返回给默认码
|
return 50; //先返回给默认码
|
||||||
}
|
}
|
||||||
|
|
||||||
//实现提示框拖拽功能
|
//实现提示 box拖拽功能
|
||||||
$('.tooldrag').mousedown(function(e) {
|
$('.tooldrag').mousedown(function(e) {
|
||||||
// e.pageX
|
// e.pageX
|
||||||
var positionDiv = $(this).offset();
|
var positionDiv = $(this).offset();
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//实现与后台和流程图部分的交互
|
//实现与后台和流程图部分的交互
|
||||||
|
|
||||||
if (window.location.href.indexOf("183.129.170.180") >= 0) {
|
if (window.location.href.indexOf("backEndAddressServiceWrapper") >= 0) {
|
||||||
throw "serviceGrid"; //如果是服务器网页页面,则不执行工具
|
throw "serviceGrid"; //如果是服务器网页页面,则不执行工具
|
||||||
}
|
}
|
||||||
|
|
||||||
|
674
LICENSE
Normal file
@ -0,0 +1,674 @@
|
|||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The GNU General Public License is a free, copyleft license for
|
||||||
|
software and other kinds of works.
|
||||||
|
|
||||||
|
The licenses for most software and other practical works are designed
|
||||||
|
to take away your freedom to share and change the works. By contrast,
|
||||||
|
the GNU General Public License is intended to guarantee your freedom to
|
||||||
|
share and change all versions of a program--to make sure it remains free
|
||||||
|
software for all its users. We, the Free Software Foundation, use the
|
||||||
|
GNU General Public License for most of our software; it applies also to
|
||||||
|
any other work released this way by its authors. You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
them if you wish), that you receive source code or can get it if you
|
||||||
|
want it, that you can change the software or use pieces of it in new
|
||||||
|
free programs, and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to prevent others from denying you
|
||||||
|
these rights or asking you to surrender the rights. Therefore, you have
|
||||||
|
certain responsibilities if you distribute copies of the software, or if
|
||||||
|
you modify it: responsibilities to respect the freedom of others.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must pass on to the recipients the same
|
||||||
|
freedoms that you received. You must make sure that they, too, receive
|
||||||
|
or can get the source code. And you must show them these terms so they
|
||||||
|
know their rights.
|
||||||
|
|
||||||
|
Developers that use the GNU GPL protect your rights with two steps:
|
||||||
|
(1) assert copyright on the software, and (2) offer you this License
|
||||||
|
giving you legal permission to copy, distribute and/or modify it.
|
||||||
|
|
||||||
|
For the developers' and authors' protection, the GPL clearly explains
|
||||||
|
that there is no warranty for this free software. For both users' and
|
||||||
|
authors' sake, the GPL requires that modified versions be marked as
|
||||||
|
changed, so that their problems will not be attributed erroneously to
|
||||||
|
authors of previous versions.
|
||||||
|
|
||||||
|
Some devices are designed to deny users access to install or run
|
||||||
|
modified versions of the software inside them, although the manufacturer
|
||||||
|
can do so. This is fundamentally incompatible with the aim of
|
||||||
|
protecting users' freedom to change the software. The systematic
|
||||||
|
pattern of such abuse occurs in the area of products for individuals to
|
||||||
|
use, which is precisely where it is most unacceptable. Therefore, we
|
||||||
|
have designed this version of the GPL to prohibit the practice for those
|
||||||
|
products. If such problems arise substantially in other domains, we
|
||||||
|
stand ready to extend this provision to those domains in future versions
|
||||||
|
of the GPL, as needed to protect the freedom of users.
|
||||||
|
|
||||||
|
Finally, every program is threatened constantly by software patents.
|
||||||
|
States should not allow patents to restrict development and use of
|
||||||
|
software on general-purpose computers, but in those that do, we wish to
|
||||||
|
avoid the special danger that patents applied to a free program could
|
||||||
|
make it effectively proprietary. To prevent this, the GPL assures that
|
||||||
|
patents cannot be used to render the program non-free.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
0. Definitions.
|
||||||
|
|
||||||
|
"This License" refers to version 3 of the GNU General Public License.
|
||||||
|
|
||||||
|
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||||
|
works, such as semiconductor masks.
|
||||||
|
|
||||||
|
"The Program" refers to any copyrightable work licensed under this
|
||||||
|
License. Each licensee is addressed as "you". "Licensees" and
|
||||||
|
"recipients" may be individuals or organizations.
|
||||||
|
|
||||||
|
To "modify" a work means to copy from or adapt all or part of the work
|
||||||
|
in a fashion requiring copyright permission, other than the making of an
|
||||||
|
exact copy. The resulting work is called a "modified version" of the
|
||||||
|
earlier work or a work "based on" the earlier work.
|
||||||
|
|
||||||
|
A "covered work" means either the unmodified Program or a work based
|
||||||
|
on the Program.
|
||||||
|
|
||||||
|
To "propagate" a work means to do anything with it that, without
|
||||||
|
permission, would make you directly or secondarily liable for
|
||||||
|
infringement under applicable copyright law, except executing it on a
|
||||||
|
computer or modifying a private copy. Propagation includes copying,
|
||||||
|
distribution (with or without modification), making available to the
|
||||||
|
public, and in some countries other activities as well.
|
||||||
|
|
||||||
|
To "convey" a work means any kind of propagation that enables other
|
||||||
|
parties to make or receive copies. Mere interaction with a user through
|
||||||
|
a computer network, with no transfer of a copy, is not conveying.
|
||||||
|
|
||||||
|
An interactive user interface displays "Appropriate Legal Notices"
|
||||||
|
to the extent that it includes a convenient and prominently visible
|
||||||
|
feature that (1) displays an appropriate copyright notice, and (2)
|
||||||
|
tells the user that there is no warranty for the work (except to the
|
||||||
|
extent that warranties are provided), that licensees may convey the
|
||||||
|
work under this License, and how to view a copy of this License. If
|
||||||
|
the interface presents a list of user commands or options, such as a
|
||||||
|
menu, a prominent item in the list meets this criterion.
|
||||||
|
|
||||||
|
1. Source Code.
|
||||||
|
|
||||||
|
The "source code" for a work means the preferred form of the work
|
||||||
|
for making modifications to it. "Object code" means any non-source
|
||||||
|
form of a work.
|
||||||
|
|
||||||
|
A "Standard Interface" means an interface that either is an official
|
||||||
|
standard defined by a recognized standards body, or, in the case of
|
||||||
|
interfaces specified for a particular programming language, one that
|
||||||
|
is widely used among developers working in that language.
|
||||||
|
|
||||||
|
The "System Libraries" of an executable work include anything, other
|
||||||
|
than the work as a whole, that (a) is included in the normal form of
|
||||||
|
packaging a Major Component, but which is not part of that Major
|
||||||
|
Component, and (b) serves only to enable use of the work with that
|
||||||
|
Major Component, or to implement a Standard Interface for which an
|
||||||
|
implementation is available to the public in source code form. A
|
||||||
|
"Major Component", in this context, means a major essential component
|
||||||
|
(kernel, window system, and so on) of the specific operating system
|
||||||
|
(if any) on which the executable work runs, or a compiler used to
|
||||||
|
produce the work, or an object code interpreter used to run it.
|
||||||
|
|
||||||
|
The "Corresponding Source" for a work in object code form means all
|
||||||
|
the source code needed to generate, install, and (for an executable
|
||||||
|
work) run the object code and to modify the work, including scripts to
|
||||||
|
control those activities. However, it does not include the work's
|
||||||
|
System Libraries, or general-purpose tools or generally available free
|
||||||
|
programs which are used unmodified in performing those activities but
|
||||||
|
which are not part of the work. For example, Corresponding Source
|
||||||
|
includes interface definition files associated with source files for
|
||||||
|
the work, and the source code for shared libraries and dynamically
|
||||||
|
linked subprograms that the work is specifically designed to require,
|
||||||
|
such as by intimate data communication or control flow between those
|
||||||
|
subprograms and other parts of the work.
|
||||||
|
|
||||||
|
The Corresponding Source need not include anything that users
|
||||||
|
can regenerate automatically from other parts of the Corresponding
|
||||||
|
Source.
|
||||||
|
|
||||||
|
The Corresponding Source for a work in source code form is that
|
||||||
|
same work.
|
||||||
|
|
||||||
|
2. Basic Permissions.
|
||||||
|
|
||||||
|
All rights granted under this License are granted for the term of
|
||||||
|
copyright on the Program, and are irrevocable provided the stated
|
||||||
|
conditions are met. This License explicitly affirms your unlimited
|
||||||
|
permission to run the unmodified Program. The output from running a
|
||||||
|
covered work is covered by this License only if the output, given its
|
||||||
|
content, constitutes a covered work. This License acknowledges your
|
||||||
|
rights of fair use or other equivalent, as provided by copyright law.
|
||||||
|
|
||||||
|
You may make, run and propagate covered works that you do not
|
||||||
|
convey, without conditions so long as your license otherwise remains
|
||||||
|
in force. You may convey covered works to others for the sole purpose
|
||||||
|
of having them make modifications exclusively for you, or provide you
|
||||||
|
with facilities for running those works, provided that you comply with
|
||||||
|
the terms of this License in conveying all material for which you do
|
||||||
|
not control copyright. Those thus making or running the covered works
|
||||||
|
for you must do so exclusively on your behalf, under your direction
|
||||||
|
and control, on terms that prohibit them from making any copies of
|
||||||
|
your copyrighted material outside their relationship with you.
|
||||||
|
|
||||||
|
Conveying under any other circumstances is permitted solely under
|
||||||
|
the conditions stated below. Sublicensing is not allowed; section 10
|
||||||
|
makes it unnecessary.
|
||||||
|
|
||||||
|
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||||
|
|
||||||
|
No covered work shall be deemed part of an effective technological
|
||||||
|
measure under any applicable law fulfilling obligations under article
|
||||||
|
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||||
|
similar laws prohibiting or restricting circumvention of such
|
||||||
|
measures.
|
||||||
|
|
||||||
|
When you convey a covered work, you waive any legal power to forbid
|
||||||
|
circumvention of technological measures to the extent such circumvention
|
||||||
|
is effected by exercising rights under this License with respect to
|
||||||
|
the covered work, and you disclaim any intention to limit operation or
|
||||||
|
modification of the work as a means of enforcing, against the work's
|
||||||
|
users, your or third parties' legal rights to forbid circumvention of
|
||||||
|
technological measures.
|
||||||
|
|
||||||
|
4. Conveying Verbatim Copies.
|
||||||
|
|
||||||
|
You may convey verbatim copies of the Program's source code as you
|
||||||
|
receive it, in any medium, provided that you conspicuously and
|
||||||
|
appropriately publish on each copy an appropriate copyright notice;
|
||||||
|
keep intact all notices stating that this License and any
|
||||||
|
non-permissive terms added in accord with section 7 apply to the code;
|
||||||
|
keep intact all notices of the absence of any warranty; and give all
|
||||||
|
recipients a copy of this License along with the Program.
|
||||||
|
|
||||||
|
You may charge any price or no price for each copy that you convey,
|
||||||
|
and you may offer support or warranty protection for a fee.
|
||||||
|
|
||||||
|
5. Conveying Modified Source Versions.
|
||||||
|
|
||||||
|
You may convey a work based on the Program, or the modifications to
|
||||||
|
produce it from the Program, in the form of source code under the
|
||||||
|
terms of section 4, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The work must carry prominent notices stating that you modified
|
||||||
|
it, and giving a relevant date.
|
||||||
|
|
||||||
|
b) The work must carry prominent notices stating that it is
|
||||||
|
released under this License and any conditions added under section
|
||||||
|
7. This requirement modifies the requirement in section 4 to
|
||||||
|
"keep intact all notices".
|
||||||
|
|
||||||
|
c) You must license the entire work, as a whole, under this
|
||||||
|
License to anyone who comes into possession of a copy. This
|
||||||
|
License will therefore apply, along with any applicable section 7
|
||||||
|
additional terms, to the whole of the work, and all its parts,
|
||||||
|
regardless of how they are packaged. This License gives no
|
||||||
|
permission to license the work in any other way, but it does not
|
||||||
|
invalidate such permission if you have separately received it.
|
||||||
|
|
||||||
|
d) If the work has interactive user interfaces, each must display
|
||||||
|
Appropriate Legal Notices; however, if the Program has interactive
|
||||||
|
interfaces that do not display Appropriate Legal Notices, your
|
||||||
|
work need not make them do so.
|
||||||
|
|
||||||
|
A compilation of a covered work with other separate and independent
|
||||||
|
works, which are not by their nature extensions of the covered work,
|
||||||
|
and which are not combined with it such as to form a larger program,
|
||||||
|
in or on a volume of a storage or distribution medium, is called an
|
||||||
|
"aggregate" if the compilation and its resulting copyright are not
|
||||||
|
used to limit the access or legal rights of the compilation's users
|
||||||
|
beyond what the individual works permit. Inclusion of a covered work
|
||||||
|
in an aggregate does not cause this License to apply to the other
|
||||||
|
parts of the aggregate.
|
||||||
|
|
||||||
|
6. Conveying Non-Source Forms.
|
||||||
|
|
||||||
|
You may convey a covered work in object code form under the terms
|
||||||
|
of sections 4 and 5, provided that you also convey the
|
||||||
|
machine-readable Corresponding Source under the terms of this License,
|
||||||
|
in one of these ways:
|
||||||
|
|
||||||
|
a) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by the
|
||||||
|
Corresponding Source fixed on a durable physical medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
b) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by a
|
||||||
|
written offer, valid for at least three years and valid for as
|
||||||
|
long as you offer spare parts or customer support for that product
|
||||||
|
model, to give anyone who possesses the object code either (1) a
|
||||||
|
copy of the Corresponding Source for all the software in the
|
||||||
|
product that is covered by this License, on a durable physical
|
||||||
|
medium customarily used for software interchange, for a price no
|
||||||
|
more than your reasonable cost of physically performing this
|
||||||
|
conveying of source, or (2) access to copy the
|
||||||
|
Corresponding Source from a network server at no charge.
|
||||||
|
|
||||||
|
c) Convey individual copies of the object code with a copy of the
|
||||||
|
written offer to provide the Corresponding Source. This
|
||||||
|
alternative is allowed only occasionally and noncommercially, and
|
||||||
|
only if you received the object code with such an offer, in accord
|
||||||
|
with subsection 6b.
|
||||||
|
|
||||||
|
d) Convey the object code by offering access from a designated
|
||||||
|
place (gratis or for a charge), and offer equivalent access to the
|
||||||
|
Corresponding Source in the same way through the same place at no
|
||||||
|
further charge. You need not require recipients to copy the
|
||||||
|
Corresponding Source along with the object code. If the place to
|
||||||
|
copy the object code is a network server, the Corresponding Source
|
||||||
|
may be on a different server (operated by you or a third party)
|
||||||
|
that supports equivalent copying facilities, provided you maintain
|
||||||
|
clear directions next to the object code saying where to find the
|
||||||
|
Corresponding Source. Regardless of what server hosts the
|
||||||
|
Corresponding Source, you remain obligated to ensure that it is
|
||||||
|
available for as long as needed to satisfy these requirements.
|
||||||
|
|
||||||
|
e) Convey the object code using peer-to-peer transmission, provided
|
||||||
|
you inform other peers where the object code and Corresponding
|
||||||
|
Source of the work are being offered to the general public at no
|
||||||
|
charge under subsection 6d.
|
||||||
|
|
||||||
|
A separable portion of the object code, whose source code is excluded
|
||||||
|
from the Corresponding Source as a System Library, need not be
|
||||||
|
included in conveying the object code work.
|
||||||
|
|
||||||
|
A "User Product" is either (1) a "consumer product", which means any
|
||||||
|
tangible personal property which is normally used for personal, family,
|
||||||
|
or household purposes, or (2) anything designed or sold for incorporation
|
||||||
|
into a dwelling. In determining whether a product is a consumer product,
|
||||||
|
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||||
|
product received by a particular user, "normally used" refers to a
|
||||||
|
typical or common use of that class of product, regardless of the status
|
||||||
|
of the particular user or of the way in which the particular user
|
||||||
|
actually uses, or expects or is expected to use, the product. A product
|
||||||
|
is a consumer product regardless of whether the product has substantial
|
||||||
|
commercial, industrial or non-consumer uses, unless such uses represent
|
||||||
|
the only significant mode of use of the product.
|
||||||
|
|
||||||
|
"Installation Information" for a User Product means any methods,
|
||||||
|
procedures, authorization keys, or other information required to install
|
||||||
|
and execute modified versions of a covered work in that User Product from
|
||||||
|
a modified version of its Corresponding Source. The information must
|
||||||
|
suffice to ensure that the continued functioning of the modified object
|
||||||
|
code is in no case prevented or interfered with solely because
|
||||||
|
modification has been made.
|
||||||
|
|
||||||
|
If you convey an object code work under this section in, or with, or
|
||||||
|
specifically for use in, a User Product, and the conveying occurs as
|
||||||
|
part of a transaction in which the right of possession and use of the
|
||||||
|
User Product is transferred to the recipient in perpetuity or for a
|
||||||
|
fixed term (regardless of how the transaction is characterized), the
|
||||||
|
Corresponding Source conveyed under this section must be accompanied
|
||||||
|
by the Installation Information. But this requirement does not apply
|
||||||
|
if neither you nor any third party retains the ability to install
|
||||||
|
modified object code on the User Product (for example, the work has
|
||||||
|
been installed in ROM).
|
||||||
|
|
||||||
|
The requirement to provide Installation Information does not include a
|
||||||
|
requirement to continue to provide support service, warranty, or updates
|
||||||
|
for a work that has been modified or installed by the recipient, or for
|
||||||
|
the User Product in which it has been modified or installed. Access to a
|
||||||
|
network may be denied when the modification itself materially and
|
||||||
|
adversely affects the operation of the network or violates the rules and
|
||||||
|
protocols for communication across the network.
|
||||||
|
|
||||||
|
Corresponding Source conveyed, and Installation Information provided,
|
||||||
|
in accord with this section must be in a format that is publicly
|
||||||
|
documented (and with an implementation available to the public in
|
||||||
|
source code form), and must require no special password or key for
|
||||||
|
unpacking, reading or copying.
|
||||||
|
|
||||||
|
7. Additional Terms.
|
||||||
|
|
||||||
|
"Additional permissions" are terms that supplement the terms of this
|
||||||
|
License by making exceptions from one or more of its conditions.
|
||||||
|
Additional permissions that are applicable to the entire Program shall
|
||||||
|
be treated as though they were included in this License, to the extent
|
||||||
|
that they are valid under applicable law. If additional permissions
|
||||||
|
apply only to part of the Program, that part may be used separately
|
||||||
|
under those permissions, but the entire Program remains governed by
|
||||||
|
this License without regard to the additional permissions.
|
||||||
|
|
||||||
|
When you convey a copy of a covered work, you may at your option
|
||||||
|
remove any additional permissions from that copy, or from any part of
|
||||||
|
it. (Additional permissions may be written to require their own
|
||||||
|
removal in certain cases when you modify the work.) You may place
|
||||||
|
additional permissions on material, added by you to a covered work,
|
||||||
|
for which you have or can give appropriate copyright permission.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, for material you
|
||||||
|
add to a covered work, you may (if authorized by the copyright holders of
|
||||||
|
that material) supplement the terms of this License with terms:
|
||||||
|
|
||||||
|
a) Disclaiming warranty or limiting liability differently from the
|
||||||
|
terms of sections 15 and 16 of this License; or
|
||||||
|
|
||||||
|
b) Requiring preservation of specified reasonable legal notices or
|
||||||
|
author attributions in that material or in the Appropriate Legal
|
||||||
|
Notices displayed by works containing it; or
|
||||||
|
|
||||||
|
c) Prohibiting misrepresentation of the origin of that material, or
|
||||||
|
requiring that modified versions of such material be marked in
|
||||||
|
reasonable ways as different from the original version; or
|
||||||
|
|
||||||
|
d) Limiting the use for publicity purposes of names of licensors or
|
||||||
|
authors of the material; or
|
||||||
|
|
||||||
|
e) Declining to grant rights under trademark law for use of some
|
||||||
|
trade names, trademarks, or service marks; or
|
||||||
|
|
||||||
|
f) Requiring indemnification of licensors and authors of that
|
||||||
|
material by anyone who conveys the material (or modified versions of
|
||||||
|
it) with contractual assumptions of liability to the recipient, for
|
||||||
|
any liability that these contractual assumptions directly impose on
|
||||||
|
those licensors and authors.
|
||||||
|
|
||||||
|
All other non-permissive additional terms are considered "further
|
||||||
|
restrictions" within the meaning of section 10. If the Program as you
|
||||||
|
received it, or any part of it, contains a notice stating that it is
|
||||||
|
governed by this License along with a term that is a further
|
||||||
|
restriction, you may remove that term. If a license document contains
|
||||||
|
a further restriction but permits relicensing or conveying under this
|
||||||
|
License, you may add to a covered work material governed by the terms
|
||||||
|
of that license document, provided that the further restriction does
|
||||||
|
not survive such relicensing or conveying.
|
||||||
|
|
||||||
|
If you add terms to a covered work in accord with this section, you
|
||||||
|
must place, in the relevant source files, a statement of the
|
||||||
|
additional terms that apply to those files, or a notice indicating
|
||||||
|
where to find the applicable terms.
|
||||||
|
|
||||||
|
Additional terms, permissive or non-permissive, may be stated in the
|
||||||
|
form of a separately written license, or stated as exceptions;
|
||||||
|
the above requirements apply either way.
|
||||||
|
|
||||||
|
8. Termination.
|
||||||
|
|
||||||
|
You may not propagate or modify a covered work except as expressly
|
||||||
|
provided under this License. Any attempt otherwise to propagate or
|
||||||
|
modify it is void, and will automatically terminate your rights under
|
||||||
|
this License (including any patent licenses granted under the third
|
||||||
|
paragraph of section 11).
|
||||||
|
|
||||||
|
However, if you cease all violation of this License, then your
|
||||||
|
license from a particular copyright holder is reinstated (a)
|
||||||
|
provisionally, unless and until the copyright holder explicitly and
|
||||||
|
finally terminates your license, and (b) permanently, if the copyright
|
||||||
|
holder fails to notify you of the violation by some reasonable means
|
||||||
|
prior to 60 days after the cessation.
|
||||||
|
|
||||||
|
Moreover, your license from a particular copyright holder is
|
||||||
|
reinstated permanently if the copyright holder notifies you of the
|
||||||
|
violation by some reasonable means, this is the first time you have
|
||||||
|
received notice of violation of this License (for any work) from that
|
||||||
|
copyright holder, and you cure the violation prior to 30 days after
|
||||||
|
your receipt of the notice.
|
||||||
|
|
||||||
|
Termination of your rights under this section does not terminate the
|
||||||
|
licenses of parties who have received copies or rights from you under
|
||||||
|
this License. If your rights have been terminated and not permanently
|
||||||
|
reinstated, you do not qualify to receive new licenses for the same
|
||||||
|
material under section 10.
|
||||||
|
|
||||||
|
9. Acceptance Not Required for Having Copies.
|
||||||
|
|
||||||
|
You are not required to accept this License in order to receive or
|
||||||
|
run a copy of the Program. Ancillary propagation of a covered work
|
||||||
|
occurring solely as a consequence of using peer-to-peer transmission
|
||||||
|
to receive a copy likewise does not require acceptance. However,
|
||||||
|
nothing other than this License grants you permission to propagate or
|
||||||
|
modify any covered work. These actions infringe copyright if you do
|
||||||
|
not accept this License. Therefore, by modifying or propagating a
|
||||||
|
covered work, you indicate your acceptance of this License to do so.
|
||||||
|
|
||||||
|
10. Automatic Licensing of Downstream Recipients.
|
||||||
|
|
||||||
|
Each time you convey a covered work, the recipient automatically
|
||||||
|
receives a license from the original licensors, to run, modify and
|
||||||
|
propagate that work, subject to this License. You are not responsible
|
||||||
|
for enforcing compliance by third parties with this License.
|
||||||
|
|
||||||
|
An "entity transaction" is a transaction transferring control of an
|
||||||
|
organization, or substantially all assets of one, or subdividing an
|
||||||
|
organization, or merging organizations. If propagation of a covered
|
||||||
|
work results from an entity transaction, each party to that
|
||||||
|
transaction who receives a copy of the work also receives whatever
|
||||||
|
licenses to the work the party's predecessor in interest had or could
|
||||||
|
give under the previous paragraph, plus a right to possession of the
|
||||||
|
Corresponding Source of the work from the predecessor in interest, if
|
||||||
|
the predecessor has it or can get it with reasonable efforts.
|
||||||
|
|
||||||
|
You may not impose any further restrictions on the exercise of the
|
||||||
|
rights granted or affirmed under this License. For example, you may
|
||||||
|
not impose a license fee, royalty, or other charge for exercise of
|
||||||
|
rights granted under this License, and you may not initiate litigation
|
||||||
|
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||||
|
any patent claim is infringed by making, using, selling, offering for
|
||||||
|
sale, or importing the Program or any portion of it.
|
||||||
|
|
||||||
|
11. Patents.
|
||||||
|
|
||||||
|
A "contributor" is a copyright holder who authorizes use under this
|
||||||
|
License of the Program or a work on which the Program is based. The
|
||||||
|
work thus licensed is called the contributor's "contributor version".
|
||||||
|
|
||||||
|
A contributor's "essential patent claims" are all patent claims
|
||||||
|
owned or controlled by the contributor, whether already acquired or
|
||||||
|
hereafter acquired, that would be infringed by some manner, permitted
|
||||||
|
by this License, of making, using, or selling its contributor version,
|
||||||
|
but do not include claims that would be infringed only as a
|
||||||
|
consequence of further modification of the contributor version. For
|
||||||
|
purposes of this definition, "control" includes the right to grant
|
||||||
|
patent sublicenses in a manner consistent with the requirements of
|
||||||
|
this License.
|
||||||
|
|
||||||
|
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||||
|
patent license under the contributor's essential patent claims, to
|
||||||
|
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||||
|
propagate the contents of its contributor version.
|
||||||
|
|
||||||
|
In the following three paragraphs, a "patent license" is any express
|
||||||
|
agreement or commitment, however denominated, not to enforce a patent
|
||||||
|
(such as an express permission to practice a patent or covenant not to
|
||||||
|
sue for patent infringement). To "grant" such a patent license to a
|
||||||
|
party means to make such an agreement or commitment not to enforce a
|
||||||
|
patent against the party.
|
||||||
|
|
||||||
|
If you convey a covered work, knowingly relying on a patent license,
|
||||||
|
and the Corresponding Source of the work is not available for anyone
|
||||||
|
to copy, free of charge and under the terms of this License, through a
|
||||||
|
publicly available network server or other readily accessible means,
|
||||||
|
then you must either (1) cause the Corresponding Source to be so
|
||||||
|
available, or (2) arrange to deprive yourself of the benefit of the
|
||||||
|
patent license for this particular work, or (3) arrange, in a manner
|
||||||
|
consistent with the requirements of this License, to extend the patent
|
||||||
|
license to downstream recipients. "Knowingly relying" means you have
|
||||||
|
actual knowledge that, but for the patent license, your conveying the
|
||||||
|
covered work in a country, or your recipient's use of the covered work
|
||||||
|
in a country, would infringe one or more identifiable patents in that
|
||||||
|
country that you have reason to believe are valid.
|
||||||
|
|
||||||
|
If, pursuant to or in connection with a single transaction or
|
||||||
|
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||||
|
covered work, and grant a patent license to some of the parties
|
||||||
|
receiving the covered work authorizing them to use, propagate, modify
|
||||||
|
or convey a specific copy of the covered work, then the patent license
|
||||||
|
you grant is automatically extended to all recipients of the covered
|
||||||
|
work and works based on it.
|
||||||
|
|
||||||
|
A patent license is "discriminatory" if it does not include within
|
||||||
|
the scope of its coverage, prohibits the exercise of, or is
|
||||||
|
conditioned on the non-exercise of one or more of the rights that are
|
||||||
|
specifically granted under this License. You may not convey a covered
|
||||||
|
work if you are a party to an arrangement with a third party that is
|
||||||
|
in the business of distributing software, under which you make payment
|
||||||
|
to the third party based on the extent of your activity of conveying
|
||||||
|
the work, and under which the third party grants, to any of the
|
||||||
|
parties who would receive the covered work from you, a discriminatory
|
||||||
|
patent license (a) in connection with copies of the covered work
|
||||||
|
conveyed by you (or copies made from those copies), or (b) primarily
|
||||||
|
for and in connection with specific products or compilations that
|
||||||
|
contain the covered work, unless you entered into that arrangement,
|
||||||
|
or that patent license was granted, prior to 28 March 2007.
|
||||||
|
|
||||||
|
Nothing in this License shall be construed as excluding or limiting
|
||||||
|
any implied license or other defenses to infringement that may
|
||||||
|
otherwise be available to you under applicable patent law.
|
||||||
|
|
||||||
|
12. No Surrender of Others' Freedom.
|
||||||
|
|
||||||
|
If conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot convey a
|
||||||
|
covered work so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you may
|
||||||
|
not convey it at all. For example, if you agree to terms that obligate you
|
||||||
|
to collect a royalty for further conveying from those to whom you convey
|
||||||
|
the Program, the only way you could satisfy both those terms and this
|
||||||
|
License would be to refrain entirely from conveying the Program.
|
||||||
|
|
||||||
|
13. Use with the GNU Affero General Public License.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, you have
|
||||||
|
permission to link or combine any covered work with a work licensed
|
||||||
|
under version 3 of the GNU Affero General Public License into a single
|
||||||
|
combined work, and to convey the resulting work. The terms of this
|
||||||
|
License will continue to apply to the part which is the covered work,
|
||||||
|
but the special requirements of the GNU Affero General Public License,
|
||||||
|
section 13, concerning interaction through a network will apply to the
|
||||||
|
combination as such.
|
||||||
|
|
||||||
|
14. Revised Versions of this License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the GNU General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Program specifies that a certain numbered version of the GNU General
|
||||||
|
Public License "or any later version" applies to it, you have the
|
||||||
|
option of following the terms and conditions either of that numbered
|
||||||
|
version or of any later version published by the Free Software
|
||||||
|
Foundation. If the Program does not specify a version number of the
|
||||||
|
GNU General Public License, you may choose any version ever published
|
||||||
|
by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Program specifies that a proxy can decide which future
|
||||||
|
versions of the GNU General Public License can be used, that proxy's
|
||||||
|
public statement of acceptance of a version permanently authorizes you
|
||||||
|
to choose that version for the Program.
|
||||||
|
|
||||||
|
Later license versions may give you additional or different
|
||||||
|
permissions. However, no additional obligations are imposed on any
|
||||||
|
author or copyright holder as a result of your choosing to follow a
|
||||||
|
later version.
|
||||||
|
|
||||||
|
15. Disclaimer of Warranty.
|
||||||
|
|
||||||
|
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||||
|
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||||
|
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||||
|
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||||
|
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||||
|
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. Limitation of Liability.
|
||||||
|
|
||||||
|
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||||
|
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||||
|
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||||
|
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||||
|
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||||
|
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||||
|
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGES.
|
||||||
|
|
||||||
|
17. Interpretation of Sections 15 and 16.
|
||||||
|
|
||||||
|
If the disclaimer of warranty and limitation of liability provided
|
||||||
|
above cannot be given local legal effect according to their terms,
|
||||||
|
reviewing courts shall apply local law that most closely approximates
|
||||||
|
an absolute waiver of all civil liability in connection with the
|
||||||
|
Program, unless a warranty or assumption of liability accompanies a
|
||||||
|
copy of the Program in return for a fee.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
state the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program does terminal interaction, make it output a short
|
||||||
|
notice like this when it starts in an interactive mode:
|
||||||
|
|
||||||
|
<program> Copyright (C) <year> <name of author>
|
||||||
|
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, your program's commands
|
||||||
|
might be different; for a GUI interface, you would use an "about box".
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or school,
|
||||||
|
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||||
|
For more information on this, and how to apply and follow the GNU GPL, see
|
||||||
|
<https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The GNU General Public License does not permit incorporating your program
|
||||||
|
into proprietary programs. If your program is a subroutine library, you
|
||||||
|
may consider it more useful to permit linking proprietary applications with
|
||||||
|
the library. If this is what you want to do, use the GNU Lesser General
|
||||||
|
Public License instead of this License. But first, please read
|
||||||
|
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
144
Readme.md
@ -1,31 +1,155 @@
|
|||||||
|
# 请您Star Please Star
|
||||||
|
|
||||||
|
如果你觉得此工具不错,请轻轻点击此页面右上角**Star**按钮增加项目曝光度,谢谢!
|
||||||
|
|
||||||
|
If you think this tool is good, please gently click the **Star** button in the upper right corner at this page to increase the project exposure, thank you!
|
||||||
|
|
||||||
|
# 无代码服务可视化Web数据采集爬虫器 Code-Free Visual Web Data Crawler/Spider (Service Wrapper)
|
||||||
|
|
||||||
|
一个可以可视化无代码设计和执行的面向服务架构的爬虫软件(服务包装器)。
|
||||||
|
A service oriented architecture GUI visual code-free web crawler/spider (service wrapper).
|
||||||
|
|
||||||
|
|
||||||
# 发布版本
|
# 发布版本
|
||||||
## Windows版本可执行程序:<http://naibo.wang/exe/ServiceWrapper.7z>
|
## Windows版本可执行程序:<https://github.com/NaiboWang/ServiceWrapper/releases/download/v0.5.0/ServiceWrapper.7z>
|
||||||
打开压缩包内的ServiceWrapper.exe即可在Windows10系统执行,无需配置环境。
|
打开压缩包内的ServiceWrapper.exe即可在Windows10/11或以上系统执行,无需配置环境(其余Windows系统需手动安装.net Framework 4.5)。
|
||||||
数据存储后放在Data/文件夹内
|
数据存储后放在Data/文件夹内
|
||||||
## 视频教程:<http://naibo.wang/exe/tutorial.mp4>
|
## 中文视频教程:<https://github.com/NaiboWang/ServiceWrapper/releases/download/v0.5.0/tutorial_CN.mp4>
|
||||||
|
|
||||||
# 服务包装手动版程序结构
|
|
||||||
## Chrome插件部分
|
|
||||||
|
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||||
|
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||||
|
# 目录
|
||||||
|
注:文档待完善
|
||||||
|
- [请您Star Please Star](#请您star-please-star)
|
||||||
|
- [无代码服务可视化Web数据采集爬虫器 Code-Free Visual Web Data Crawler/Spider (Service Wrapper)](#无代码服务可视化web数据采集爬虫器-code-free-visual-web-data-crawlerspider-service-wrapper)
|
||||||
|
- [发布版本](#发布版本)
|
||||||
|
- [Windows版本可执行程序:<https://github.com/NaiboWang/ServiceWrapper/releases/download/v0.5.0/ServiceWrapper.7z>](#windows版本可执行程序httpsgithubcomnaibowangservicewrapperreleasesdownloadv050servicewrapper7z)
|
||||||
|
- [中文视频教程:<https://github.com/NaiboWang/ServiceWrapper/releases/download/v0.5.0/tutorial_CN.mp4>](#中文视频教程httpsgithubcomnaibowangservicewrapperreleasesdownloadv050tutorial_cnmp4)
|
||||||
|
- [目录](#目录)
|
||||||
|
- [界面截图](#界面截图)
|
||||||
|
- [软件界面示例](#软件界面示例)
|
||||||
|
- [块和子块及表单定义](#块和子块及表单定义)
|
||||||
|
- [已选中和待选择示例](#已选中和待选择示例)
|
||||||
|
- [京东商品块选择示例:](#京东商品块选择示例)
|
||||||
|
- [京东商品标题自动匹配选择示例](#京东商品标题自动匹配选择示例)
|
||||||
|
- [分块选择所有子元素示例](#分块选择所有子元素示例)
|
||||||
|
- [同类型元素自动和手动匹配示例](#同类型元素自动和手动匹配示例)
|
||||||
|
- [四种选择方式示例](#四种选择方式示例)
|
||||||
|
- [输入文字示例](#输入文字示例)
|
||||||
|
- [循环点击58同城房屋标题以进入详情页采集示例](#循环点击58同城房屋标题以进入详情页采集示例)
|
||||||
|
- [采集元素文本示例](#采集元素文本示例)
|
||||||
|
- [流程图界面介绍](#流程图界面介绍)
|
||||||
|
- [循环选项示例](#循环选项示例)
|
||||||
|
- [循环点击下一页示例](#循环点击下一页示例)
|
||||||
|
- [条件分支示例](#条件分支示例)
|
||||||
|
- [完整采集流程图示例](#完整采集流程图示例)
|
||||||
|
- [完整采集流程图转换为常规流程图示例](#完整采集流程图转换为常规流程图示例)
|
||||||
|
- [服务信息示例](#服务信息示例)
|
||||||
|
- [服务调用示例](#服务调用示例)
|
||||||
|
- [58 同城房源信息采集服务部分采集结果展示](#58-同城房源信息采集服务部分采集结果展示)
|
||||||
|
- [服务包装手动版程序结构](#服务包装手动版程序结构)
|
||||||
|
- [Chrome插件部分](#chrome插件部分)
|
||||||
|
- [后台流程图部分](#后台流程图部分)
|
||||||
|
- [服务展示部分](#服务展示部分)
|
||||||
|
- [C#部分](#c部分)
|
||||||
|
- [后台服务页面](#后台服务页面)
|
||||||
|
- [服务执行](#服务执行)
|
||||||
|
|
||||||
|
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||||
|
|
||||||
|
## 界面截图
|
||||||
|
|
||||||
|
#### 软件界面示例
|
||||||
|
|
||||||
|

|
||||||
|
#### 块和子块及表单定义
|
||||||
|
|
||||||
|

|
||||||
|
#### 已选中和待选择示例
|
||||||
|
|
||||||
|

|
||||||
|
#### 京东商品块选择示例:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
#### 京东商品标题自动匹配选择示例
|
||||||
|
|
||||||
|

|
||||||
|
#### 分块选择所有子元素示例
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
#### 同类型元素自动和手动匹配示例
|
||||||
|
|
||||||
|

|
||||||
|
#### 四种选择方式示例
|
||||||
|
|
||||||
|

|
||||||
|
#### 输入文字示例
|
||||||
|
|
||||||
|

|
||||||
|
#### 循环点击58同城房屋标题以进入详情页采集示例
|
||||||
|
|
||||||
|

|
||||||
|
#### 采集元素文本示例
|
||||||
|
|
||||||
|

|
||||||
|
#### 流程图界面介绍
|
||||||
|
|
||||||
|

|
||||||
|
#### 循环选项示例
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
#### 循环点击下一页示例
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
#### 条件分支示例
|
||||||
|
|
||||||
|

|
||||||
|
#### 完整采集流程图示例
|
||||||
|
|
||||||
|

|
||||||
|
#### 完整采集流程图转换为常规流程图示例
|
||||||
|
|
||||||
|

|
||||||
|
#### 服务信息示例
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
#### 服务调用示例
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
#### 58 同城房源信息采集服务部分采集结果展示
|
||||||
|

|
||||||
|
|
||||||
|
## 服务包装手动版程序结构
|
||||||
|
### Chrome插件部分
|
||||||
* Extension/app内的文件
|
* Extension/app内的文件
|
||||||
|
|
||||||
## 后台流程图部分
|
### 后台流程图部分
|
||||||
* ServiceGrid/frontEnd/FlowChart.html
|
* ServiceGrid/frontEnd/FlowChart.html
|
||||||
* ServiceGrid/frontEnd/FlowChart.js
|
* ServiceGrid/frontEnd/FlowChart.js
|
||||||
* ServiceGrid/frontEnd/FlowChart.css
|
* ServiceGrid/frontEnd/FlowChart.css
|
||||||
* ServiceGrid/frontEnd/logic.css
|
* ServiceGrid/frontEnd/logic.css
|
||||||
|
|
||||||
## 服务展示部分
|
### 服务展示部分
|
||||||
* 服务列表:ServiceGrid/frontEnd/serviceList.html
|
* 服务列表:ServiceGrid/frontEnd/serviceList.html
|
||||||
* 服务信息:ServiceGrid/frontEnd/serviceInfo.html
|
* 服务信息:ServiceGrid/frontEnd/serviceInfo.html
|
||||||
* 新服务:ServiceGrid/frontEnd/newService.html
|
* 新服务:ServiceGrid/frontEnd/newService.html
|
||||||
* 调用服务:ServiceGrid/frontEnd/invokeService.html
|
* 调用服务:ServiceGrid/frontEnd/invokeService.html
|
||||||
|
|
||||||
## C#部分
|
### C#部分
|
||||||
* C#/内的文件
|
* C#/内的文件
|
||||||
|
|
||||||
## 后台服务页面
|
### 后台服务页面
|
||||||
* Django后台:ServiceGrid/backEnd/*
|
* Django后台:ServiceGrid/backEnd/*
|
||||||
|
|
||||||
## 服务执行
|
### 服务执行
|
||||||
* ExcuteStage/ServiceWrapper_ExcuteStage.py
|
* ExcuteStage/ServiceWrapper_ExcuteStage.py
|
||||||
|
3
ServiceGrid/backEnd/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
__pycache__/
|
||||||
|
nohup.out
|
||||||
|
*.pid
|
1
ServiceGrid/backEnd/backEnd/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
dbconfig.py
|
@ -38,6 +38,7 @@ INSTALLED_APPS = [
|
|||||||
'django.contrib.messages',
|
'django.contrib.messages',
|
||||||
'corsheaders',
|
'corsheaders',
|
||||||
'django.contrib.staticfiles',
|
'django.contrib.staticfiles',
|
||||||
|
'sslserver',
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
|
@ -27,6 +27,4 @@ urlpatterns = [
|
|||||||
path('backEnd/invokeService',view.invokeService), #调用服务接口
|
path('backEnd/invokeService',view.invokeService), #调用服务接口
|
||||||
path('backEnd/queryTask',view.queryTask), #调用服务接口
|
path('backEnd/queryTask',view.queryTask), #调用服务接口
|
||||||
path('backEnd/queryTasks',view.queryTasks), #调用服务接口
|
path('backEnd/queryTasks',view.queryTasks), #调用服务接口
|
||||||
path('backEnd/dongcang/insertInfo',view.insertInfo),
|
|
||||||
path('backEnd/dongcang/queryInfos',view.queryInfos),
|
|
||||||
]
|
]
|
||||||
|
@ -3,49 +3,49 @@ from django.http import HttpResponse
|
|||||||
import pymongo
|
import pymongo
|
||||||
import json
|
import json
|
||||||
from bson import json_util
|
from bson import json_util
|
||||||
|
from dbconfig import myclient, mycol, taskcol
|
||||||
|
"""
|
||||||
|
uncomment this to deploy database
|
||||||
|
"""
|
||||||
|
# myclient = pymongo.MongoClient('mongodb://username:password@localhost:27017/')
|
||||||
|
# mydb = myclient['service']
|
||||||
|
# mycol = mydb["services"]
|
||||||
|
# taskcol = mydb["tasks"] # 生成新任务并返回ID
|
||||||
|
|
||||||
"""
|
|
||||||
高分服务器地址:192.168.14.113
|
|
||||||
用户名:root
|
|
||||||
密码:zju.edu.cn
|
|
||||||
ftp用户:naibowang
|
|
||||||
密码:qq
|
|
||||||
程序位置:/root/servicewrapper
|
|
||||||
"""
|
|
||||||
|
|
||||||
def hello(request):
|
def hello(request):
|
||||||
return HttpResponse("Hello world ! ")
|
return HttpResponse("Hello world ! ")
|
||||||
|
|
||||||
|
|
||||||
myclient = pymongo.MongoClient('mongodb://localhost:27017/')
|
|
||||||
mydb = myclient['service']
|
|
||||||
mycol = mydb["services"]
|
|
||||||
taskcol = mydb["tasks"] #生成新任务并返回ID
|
|
||||||
|
|
||||||
def queryServices(request):
|
def queryServices(request):
|
||||||
result = mycol.find({"id" : { "$ne" : -2 }},{ "name": 1, "id": 1, "url": 1, "_id": 0 }) #查询id不为-2的元素
|
result = mycol.find({"id": {"$ne": -2}}, {"name": 1,
|
||||||
|
"id": 1, "url": 1, "_id": 0}) # 查询id不为-2的元素
|
||||||
return HttpResponse(json.dumps(list(result)), content_type="application/json")
|
return HttpResponse(json.dumps(list(result)), content_type="application/json")
|
||||||
|
|
||||||
|
|
||||||
def queryTasks(request):
|
def queryTasks(request):
|
||||||
result = taskcol.find({"id" : { "$ne" : -2 }},{ "name": 1, "id": 1, "url": 1, "_id": 0 }) #查询id不为-2的元素
|
result = taskcol.find(
|
||||||
|
{"id": {"$ne": -2}}, {"name": 1, "id": 1, "url": 1, "_id": 0}) # 查询id不为-2的元素
|
||||||
return HttpResponse(json.dumps(list(result)), content_type="application/json")
|
return HttpResponse(json.dumps(list(result)), content_type="application/json")
|
||||||
|
|
||||||
|
|
||||||
def queryService(request):
|
def queryService(request):
|
||||||
if 'id' in request.GET:
|
if 'id' in request.GET:
|
||||||
tid = request.GET['id']
|
tid = request.GET['id']
|
||||||
else:
|
else:
|
||||||
tid = "0"
|
tid = "0"
|
||||||
result = mycol.find({"id":int(tid)},{"_id":0})
|
result = mycol.find({"id": int(tid)}, {"_id": 0})
|
||||||
r = list(result)[0]
|
r = list(result)[0]
|
||||||
return HttpResponse(json.dumps(r), content_type="application/json")
|
return HttpResponse(json.dumps(r), content_type="application/json")
|
||||||
|
|
||||||
|
|
||||||
def queryTask(request):
|
def queryTask(request):
|
||||||
if 'id' in request.GET:
|
if 'id' in request.GET:
|
||||||
tid = request.GET['id']
|
tid = request.GET['id']
|
||||||
else:
|
else:
|
||||||
tid = "0"
|
tid = "0"
|
||||||
|
|
||||||
result = taskcol.find({"id":int(tid)},{"_id":0})
|
result = taskcol.find({"id": int(tid)}, {"_id": 0})
|
||||||
r = list(result)[0]
|
r = list(result)[0]
|
||||||
return HttpResponse(json.dumps(r), content_type="application/json")
|
return HttpResponse(json.dumps(r), content_type="application/json")
|
||||||
|
|
||||||
@ -54,45 +54,57 @@ def manageService(request):
|
|||||||
data = request.POST['paras']
|
data = request.POST['paras']
|
||||||
data = json.loads(data)
|
data = json.loads(data)
|
||||||
if int(data["id"]) == -1:
|
if int(data["id"]) == -1:
|
||||||
count = mycol.find({}).count()
|
count = mycol.count_documents({})
|
||||||
data["id"] = count #修改id
|
data["id"] = count # 修改id
|
||||||
mycol.insert_one(data)
|
mycol.insert_one(data)
|
||||||
else:
|
else:
|
||||||
mycol.delete_one({"id":int(data["id"])})
|
mycol.delete_one({"id": int(data["id"])})
|
||||||
mycol.insert_one(data)
|
mycol.insert_one(data)
|
||||||
return HttpResponse(data["id"])
|
return HttpResponse(data["id"])
|
||||||
|
|
||||||
|
|
||||||
def deleteService(request):
|
def deleteService(request):
|
||||||
if 'id' in request.GET:
|
if 'id' in request.GET:
|
||||||
tid = request.GET['id']
|
tid = request.GET['id']
|
||||||
myquery = { "id": int(tid) }
|
myquery = {"id": int(tid)}
|
||||||
newvalues = { "$set": { "id": -2 } } #删除就是将服务id变成-2,并没有真正删除
|
newvalues = {"$set": {"id": -2}} # 删除就是将服务id变成-2,并没有真正删除
|
||||||
mycol.update_one(myquery, newvalues)
|
mycol.update_one(myquery, newvalues)
|
||||||
return HttpResponse("Done!")
|
return HttpResponse("Done!")
|
||||||
|
|
||||||
# 调用服务
|
# 调用服务
|
||||||
|
|
||||||
|
|
||||||
def invokeService(request):
|
def invokeService(request):
|
||||||
tid = request.POST['id']
|
tid = request.POST['id']
|
||||||
data = json.loads(request.POST['paras'])
|
data = json.loads(request.POST['paras'])
|
||||||
result = mycol.find({"id":int(tid)},{"_id":0})
|
result = mycol.find({"id": int(tid)}, {"_id": 0})
|
||||||
service = list(result)[0]
|
service = list(result)[0]
|
||||||
for key,value in data.items():
|
try:
|
||||||
|
service["links"] = data["urlList_0"]
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
for key, value in data.items():
|
||||||
for i in range(len(service["inputParameters"])):
|
for i in range(len(service["inputParameters"])):
|
||||||
if key == service["inputParameters"][i]["name"]: #能调用
|
if key == service["inputParameters"][i]["name"]: # 能调用
|
||||||
nodeId = int(service["inputParameters"][i]["nodeId"])
|
nodeId = int(service["inputParameters"][i]["nodeId"])
|
||||||
node = service["graph"][nodeId]
|
node = service["graph"][nodeId]
|
||||||
if node["option"] == 1:
|
if node["option"] == 1:
|
||||||
node["parameters"]["links"] = value
|
node["parameters"]["links"] = value
|
||||||
elif node["option"] == 4:
|
elif node["option"] == 4:
|
||||||
node["parameters"]["value"] = value
|
node["parameters"]["value"] = value
|
||||||
|
elif node["option"] == 8 and node["parameters"]["loopType"] == 0:
|
||||||
|
# print("loopType 0", value)
|
||||||
|
node["parameters"]["exitCount"] = int(value)
|
||||||
|
# print(node)
|
||||||
elif node["option"] == 8:
|
elif node["option"] == 8:
|
||||||
node["parameters"]["textList"] = value
|
node["parameters"]["textList"] = value
|
||||||
break
|
break
|
||||||
count = taskcol.find({}).count()
|
count = taskcol.count_documents({})
|
||||||
service["id"] = count #修改id
|
service["id"] = count # 修改id
|
||||||
taskcol.insert_one(service)
|
taskcol.insert_one(service)
|
||||||
return HttpResponse(count)
|
return HttpResponse(count)
|
||||||
|
|
||||||
|
|
||||||
def insertInfo(request):
|
def insertInfo(request):
|
||||||
request.GET = request.GET.copy()
|
request.GET = request.GET.copy()
|
||||||
data = request.GET
|
data = request.GET
|
||||||
@ -101,6 +113,7 @@ def insertInfo(request):
|
|||||||
cold.insert_one(data)
|
cold.insert_one(data)
|
||||||
return HttpResponse("200")
|
return HttpResponse("200")
|
||||||
|
|
||||||
|
|
||||||
def queryInfos(request):
|
def queryInfos(request):
|
||||||
dbd = myclient['dongcang']
|
dbd = myclient['dongcang']
|
||||||
cold = dbd["redirect"]
|
cold = dbd["redirect"]
|
||||||
|
40
ServiceGrid/backEnd/server.conf
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
|
||||||
|
server_name servicewrapper.naibo.wang;
|
||||||
|
|
||||||
|
#ssl_certificate cert/5640170_naibo.wang.pem;
|
||||||
|
#ssl_certificate_key cert/5640170_naibo.wang.key;
|
||||||
|
ssl_certificate /etc/letsencrypt/live/servicewrapper.naibo.wang/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/servicewrapper.naibo.wang/privkey.pem;
|
||||||
|
|
||||||
|
ssl_session_timeout 5m;
|
||||||
|
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
|
||||||
|
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #表示使用的TLS协议的类型。
|
||||||
|
ssl_prefer_server_ciphers on;
|
||||||
|
|
||||||
|
root /home/naibo/server/ServiceWrapper/ServiceGrid/frontEnd;
|
||||||
|
index serviceList.html;
|
||||||
|
|
||||||
|
|
||||||
|
location /backEnd {
|
||||||
|
include uwsgi_params;
|
||||||
|
uwsgi_connect_timeout 30;
|
||||||
|
uwsgi_pass 127.0.0.1:8072;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /static {
|
||||||
|
autoindex on;
|
||||||
|
autoindex_localtime on;
|
||||||
|
alias /home/naibo/static;
|
||||||
|
try_files $uri $uri/ =404;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
server_name xtra3090.d2.comp.nus.edu.sg naibo.wang gui.naibo.wang servicewrapper.naibo.wang; #需要将yourdomain.com替换成证书绑定的域名。
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
}
|
@ -16,29 +16,29 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div id="tip" class="alert alert-success alert-dismissible fade show" style="position: fixed; width:100%;display: none;">
|
<div id="tip" class="alert alert-success alert-dismissible fade show" style="position: fixed; width:100%;display: none;">
|
||||||
<button type="button" class="close" data-dismiss="alert">×</button> 提示:保存成功!
|
<button type="button" class="close" data-dismiss="alert">×</button> Hint: Save Successfully!
|
||||||
</div>
|
</div>
|
||||||
<div style="display:flex">
|
<div style="display:flex">
|
||||||
<div style="width: 200px;float:left">
|
<div style="width: 200px;float:left">
|
||||||
<div class="toolbox" style="text-align:center;margin: 20px;border-radius:10px;border:navy solid;background-color:rgb(242,243,245);z-index: 9999;">
|
<div class="toolbox" style="text-align:center;margin: 20px;border-radius:10px;border:navy solid;background-color:rgb(242,243,245);z-index: 9999;">
|
||||||
<div style="padding: 10px;border-radius:10px;font-size: 20px;">工具箱</div>
|
<div style="padding: 10px;border-radius:10px;font-size: 20px;">Toolbox</div>
|
||||||
<button type="button" id="save" data-toggle="modal" data-target="#myModal" onmousedown="$('#myModal').modal('show');" class="btn btn-primary">保存服务</button>
|
<button type="button" id="save" data-toggle="modal" data-target="#myModal" onmousedown="$('#myModal').modal('show');" class="btn btn-primary">Save Service</button>
|
||||||
<!-- <button type="button" data=1 class="btn btn-outline-primary options">打开网页</button> -->
|
<!-- <button type="button" data=1 class="btn btn-outline-primary options">打开网页</button> -->
|
||||||
<button type="button" data=2 class="btn btn-outline-primary options">点击元素</button>
|
<button type="button" data=2 class="btn btn-outline-primary options">Click Element</button>
|
||||||
<button type="button" data=3 class="btn btn-outline-primary options">提取数据</button>
|
<button type="button" data=3 class="btn btn-outline-primary options">Extract Data</button>
|
||||||
<button type="button" data=4 class="btn btn-outline-primary options">输入文字</button>
|
<button type="button" data=4 class="btn btn-outline-primary options">Input Text</button>
|
||||||
<button type="button" data=5 class="btn btn-outline-primary options">识别验证码</button>
|
<!-- <button type="button" data=5 class="btn btn-outline-primary options">-</button> -->
|
||||||
<button type="button" data=6 style="font-size: 14px!important;" class="btn btn-outline-primary options">切换下拉选项</button>
|
<!-- <button type="button" data=6 style="font-size: 14px!important;" class="btn btn-outline-primary options">Change Option</button> -->
|
||||||
<button type="button" data=7 class="btn btn-outline-primary options">移动到元素</button>
|
<!-- <button type="button" data=7 class="btn btn-outline-primary options">-</button> -->
|
||||||
<button type="button" data=8 class="btn btn-outline-primary options">循环</button>
|
<button type="button" data=8 class="btn btn-outline-primary options">Loop</button>
|
||||||
<button type="button" data=9 class="btn btn-outline-primary options">判断条件</button>
|
<button type="button" data=9 class="btn btn-outline-primary options">If Condition</button>
|
||||||
<div>-----------------</div>
|
<div>-----------------</div>
|
||||||
<button type="button" data=13 class="btn btn-outline-primary options" title="调整下一个要插入的节点的位置">调整锚点</button>
|
<button type="button" data=13 class="btn btn-outline-primary options" title="调整下一个要插入的节点的位置">Set Anchor</button>
|
||||||
<button type="button" data=10 class="btn btn-outline-primary options">剪切元素</button>
|
<button type="button" data=10 class="btn btn-outline-primary options">Cut Element</button>
|
||||||
<button type="button" data=11 class="btn btn-outline-primary options">复制元素</button>
|
<button type="button" data=11 class="btn btn-outline-primary options">Copy Element</button>
|
||||||
<button type="button" data=12 class="btn btn-outline-primary options">删除元素</button>
|
<button type="button" data=12 class="btn btn-outline-primary options">Del Element</button>
|
||||||
<button type="button" data=0 class="btn btn-outline-primary2 options">取消操作</button>
|
<button type="button" data=0 class="btn btn-outline-primary2 options">Cancel</button>
|
||||||
<div style="text-align: left;margin: 10px;font-size:15px!important">提示:点击上方操作按钮后点击要放置元素的位置处的箭头,可按取消操作按钮取消。</div>
|
<div style="text-align: left;margin: 10px;font-size:15px!important"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-top:20px;border: solid;height:850px;overflow: auto;width:58%;float:right">
|
<div style="margin-top:20px;border: solid;height:850px;overflow: auto;width:58%;float:right">
|
||||||
@ -54,47 +54,47 @@
|
|||||||
</div> -->
|
</div> -->
|
||||||
<div class="Modify" id="app">
|
<div class="Modify" id="app">
|
||||||
<div>
|
<div>
|
||||||
<label>选项名称:</label>
|
<label>Option Name:</label>
|
||||||
<input onkeydown="inputDelete(event)" class="form-control" v-model='list.nl[index.nowNodeIndex]["title"]'></input>
|
<input onkeydown="inputDelete(event)" class="form-control" v-model='list.nl[index.nowNodeIndex]["title"]'></input>
|
||||||
</div>
|
</div>
|
||||||
<!-- 下面是10种不同类型操作选项的不同的配置页面 -->
|
<!-- 下面是10种不同类型操作选项的不同的配置页面 -->
|
||||||
<div class="elements" v-if="nodeType==1">
|
<div class="elements" v-if="nodeType==1">
|
||||||
<div v-if="nowNode['isInLoop']">
|
<div v-if="nowNode['isInLoop']">
|
||||||
<!-- 如果在循环内且循环内是固定文本才显示此行元素 -->
|
<!-- 如果在循环内且循环内是固定文本才显示此行元素 -->
|
||||||
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='useLoop'></input>使用循环内的链接</p>
|
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='useLoop'></input>Use link inside the Loop</p>
|
||||||
</div>
|
</div>
|
||||||
<div v-if='!useLoop'>
|
<div v-if='!useLoop'>
|
||||||
<label>url:</label>
|
<label>url:</label>
|
||||||
<input onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["url"]'></input>
|
<input onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["url"]'></input>
|
||||||
<label>填入的全部链接:</label>
|
<label>All links filled:</label>
|
||||||
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["links"]'></textarea>
|
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["links"]'></textarea>
|
||||||
</div>
|
</div>
|
||||||
<label>执行完是否向下滚动:</label>
|
<label>After executed, whether scroll down:</label>
|
||||||
<select v-model='nowNode["parameters"]["scrollType"]' class="form-control">
|
<select v-model='nowNode["parameters"]["scrollType"]' class="form-control">
|
||||||
<option value = 0>不滚动</option>
|
<option value = 0>No</option>
|
||||||
<option value = 1>向下滚动一屏</option>
|
<option value = 1>Scroll one screen</option>
|
||||||
<option value = 2>滚动到底部</option>
|
<option value = 2>Scroll to the end</option>
|
||||||
</select>
|
</select>
|
||||||
<label>滚动次数:</label>
|
<label>Scroll Times:</label>
|
||||||
<input onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['scrollCount']" type="number" required></input>
|
<input onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['scrollCount']" type="number" required></input>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="elements" v-if="nodeType==2">
|
<div class="elements" v-if="nodeType==2">
|
||||||
<div v-if="nowNode['isInLoop']">
|
<div v-if="nowNode['isInLoop']">
|
||||||
<!-- 如果在循环内才显示此行元素 -->
|
<!-- 如果在循环内才显示此行元素 -->
|
||||||
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='useLoop'></input>使用循环内的元素</p>
|
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='useLoop'></input>Use element inside the Loop</p>
|
||||||
</div>
|
</div>
|
||||||
<div v-if='!useLoop'>
|
<div v-if='!useLoop'>
|
||||||
<label>XPath: <span style="font-size: 30px!important;" title="相对XPATH写法:以/开头,如循环项XPATH为/html/body/div[1],您的输入为/*[@id='tab-customer'],则最终寻址的xpath为:/html/body/div[1]/*[@id='tab-customer']">☺</span></label>
|
<label>XPath: <span style="font-size: 30px!important;" title="相对XPATH写法:以/开头,如循环项XPATH为/html/body/div[1],您的输入为/*[@id='tab-customer'],则最终寻址的xpath为:/html/body/div[1]/*[@id='tab-customer']">☺</span></label>
|
||||||
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["xpath"]'></textarea>
|
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["xpath"]'></textarea>
|
||||||
</div>
|
</div>
|
||||||
<label>执行完是否向下滚动:</label>
|
<label>After executed, whether scroll down:</label>
|
||||||
<select v-model='nowNode["parameters"]["scrollType"]' class="form-control">
|
<select v-model='nowNode["parameters"]["scrollType"]' class="form-control">
|
||||||
<option value = 0>不滚动</option>
|
<option value = 0>No</option>
|
||||||
<option value = 1>向下滚动一屏</option>
|
<option value = 1>Scroll one screen</option>
|
||||||
<option value = 2>滚动到底部</option>
|
<option value = 2>Scroll to the end</option>
|
||||||
</select>
|
</select>
|
||||||
<label>滚动次数:</label>
|
<label>Scroll Times:</label>
|
||||||
<input onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['scrollCount']" type="number" required></input>
|
<input onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['scrollCount']" type="number" required></input>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -103,9 +103,9 @@
|
|||||||
<div class="toolkitcontain">
|
<div class="toolkitcontain">
|
||||||
<table class="toolkittb2" cellspacing="0">
|
<table class="toolkittb2" cellspacing="0">
|
||||||
<tbody>
|
<tbody>
|
||||||
<th>字段名</th>
|
<th>Field Name</th>
|
||||||
<th style="width:200px">示例值</th>
|
<th style="width:200px">Example Value</th>
|
||||||
<th>操作</th>
|
<th>Operations</th>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<table class="toolkittb4" cellspacing="0">
|
<table class="toolkittb4" cellspacing="0">
|
||||||
@ -115,22 +115,37 @@
|
|||||||
</td>
|
</td>
|
||||||
<td style="width:200px">{{paras.parameters[i-1]["exampleValues"][0]["value"]}}</td>
|
<td style="width:200px">{{paras.parameters[i-1]["exampleValues"][0]["value"]}}</td>
|
||||||
<td>
|
<td>
|
||||||
<a v-on:mousedown="modifyParas(i-1)">修改</a>
|
<a v-on:mousedown="modifyParas(i-1)">Modify</a>
|
||||||
<a v-on:mousedown="deleteParas(i-1)">删除</a>
|
<a v-on:mousedown="deleteParas(i-1)">Delete</a>
|
||||||
<a v-on:mousedown="upParas(i-1)">上移</a>
|
<a v-on:mousedown="upParas(i-1)">Up</a>
|
||||||
<a v-on:mousedown="downParas(i-1)">下移</a>
|
<a v-on:mousedown="downParas(i-1)">Down</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div style="font-size: 13px;" v-if="paraIndex<paras.parameters.length">
|
<div style="font-size: 13px;" v-if="paraIndex<paras.parameters.length">
|
||||||
<label>当前编辑参数名: <strong>{{paras.parameters[paraIndex]["name"]}}</strong></label>
|
<label>Current parameter name: <strong>{{paras.parameters[paraIndex]["name"]}}</strong></label>
|
||||||
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='paras.parameters[paraIndex]["relative"]'></input>使用相对循环内的XPATH</p>
|
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='paras.parameters[paraIndex]["relative"]'></input>Use relative XPATH</p>
|
||||||
<label>XPATH: <span style="font-size: 30px!important;" title="相对XPATH写法:以/开头,如循环项XPATH为/html/body/div[1],您的输入为/*[@id='tab-customer'],则最终寻址的xpath为:/html/body/div[1]/*[@id='tab-customer']">☺</span></label>
|
<label>XPATH: <span style="font-size: 30px!important;" title="相对XPATH写法:以/开头,如循环项XPATH为/html/body/div[1],您的输入为/*[@id='tab-customer'],则最终寻址的xpath为:/html/body/div[1]/*[@id='tab-customer']">☺</span></label>
|
||||||
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='paras.parameters[paraIndex]["relativeXpath"]'></textarea>
|
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='paras.parameters[paraIndex]["relativeXpath"]'></textarea>
|
||||||
<label>参数描述:</label>
|
<label>Extraction Type</label>
|
||||||
|
<select v-model='paras.parameters[paraIndex]["contentType"]' class="form-control">
|
||||||
|
<option :value = 0>Text (include child element)</option>
|
||||||
|
<option :value = 1>Text (exclude child element)</option>
|
||||||
|
<option :value = 2>innerHTML</option>
|
||||||
|
<option :value = 3>outerHTML</option>
|
||||||
|
</select>
|
||||||
|
<label>Node Type</label>
|
||||||
|
<select v-model='paras.parameters[paraIndex]["nodeType"]' class="form-control">
|
||||||
|
<option :value = 0>Ordinary Node</option>
|
||||||
|
<option :value = 1>Link Text</option>
|
||||||
|
<option :value = 2>Link Address</option>
|
||||||
|
<option :value = 3>Form Value</option>
|
||||||
|
<option :value = 4>Image Address</option>
|
||||||
|
</select>
|
||||||
|
<label>Parameter Description:</label>
|
||||||
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='paras.parameters[paraIndex]["desc"]'></textarea>
|
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='paras.parameters[paraIndex]["desc"]'></textarea>
|
||||||
<label>元素找不到时的值:</label>
|
<label>Absent value when cannot find the element:</label>
|
||||||
<input onkeydown="inputDelete(event)" class="form-control" v-model='paras.parameters[paraIndex]["default"]'></textarea>
|
<input onkeydown="inputDelete(event)" class="form-control" v-model='paras.parameters[paraIndex]["default"]'></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -140,10 +155,10 @@
|
|||||||
<div class="elements" v-if="nodeType==4">
|
<div class="elements" v-if="nodeType==4">
|
||||||
<div v-if="nowNode['isInLoop']">
|
<div v-if="nowNode['isInLoop']">
|
||||||
<!-- 如果在循环内且循环内是固定文本才显示此行元素 -->
|
<!-- 如果在循环内且循环内是固定文本才显示此行元素 -->
|
||||||
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='useLoop'></input>使用循环内的文本</p>
|
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='useLoop'></input>Use text inside the Loop</p>
|
||||||
</div>
|
</div>
|
||||||
<div v-if='!useLoop'>
|
<div v-if='!useLoop'>
|
||||||
<label>输入值:</label>
|
<label>Input Value:</label>
|
||||||
<input onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["value"]'></input>
|
<input onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["value"]'></input>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -165,31 +180,40 @@
|
|||||||
|
|
||||||
<div class="elements" v-if="nodeType==8">
|
<div class="elements" v-if="nodeType==8">
|
||||||
<!-- 循环选项 -->
|
<!-- 循环选项 -->
|
||||||
<label>循环类型:</label>
|
<label>Loop Type:</label>
|
||||||
<select v-model='loopType' class="form-control">
|
<select v-model='loopType' class="form-control">
|
||||||
<option value = 0>单个元素</option>
|
<option value = 0>Single Element</option>
|
||||||
<option value = 1>不固定元素列表</option>
|
<option value = 1>Unfixed Element List</option>
|
||||||
<option value = 2>固定元素列表</option>
|
<option value = 2>Fixed Element List</option>
|
||||||
<option value = 3>文本列表</option>
|
<option value = 3>Text List</option>
|
||||||
<option value = 4>网址列表</option>
|
<option value = 4>Weblink List</option>
|
||||||
</select>
|
</select>
|
||||||
<div v-if='parseInt(loopType) < 2'>
|
<div v-if='parseInt(loopType) < 2'>
|
||||||
<label>XPath: <span style="font-size: 30px!important;" title="相对XPATH写法:以/开头,如循环项XPATH为/html/body/div[1],您的输入为/*[@id='tab-customer'],则最终寻址的xpath为:/html/body/div[1]/*[@id='tab-customer']">☺</span></label>
|
<label>XPath: <span style="font-size: 30px!important;" title="相对XPATH写法:以/开头,如循环项XPATH为/html/body/div[1],您的输入为/*[@id='tab-customer'],则最终寻址的xpath为:/html/body/div[1]/*[@id='tab-customer']">☺</span></label>
|
||||||
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["xpath"]'></textarea>
|
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["xpath"]'></textarea>
|
||||||
</div>
|
</div>
|
||||||
<div v-if='parseInt(loopType) == 2'>
|
<div v-if='parseInt(loopType) == 2'>
|
||||||
<label>XPath列表:</label>
|
<label>XPath List:</label>
|
||||||
<textarea onkeydown="inputDelete(event)" class="form-control" rows="3" v-model='nowNode["parameters"]["pathList"]'></textarea>
|
<textarea onkeydown="inputDelete(event)" class="form-control" rows="3" v-model='nowNode["parameters"]["pathList"]'></textarea>
|
||||||
</div>
|
</div>
|
||||||
<div v-if='parseInt(loopType) > 2'>
|
<div v-if='parseInt(loopType) > 2'>
|
||||||
<label>内容列表:</label>
|
<label>Content List:</label>
|
||||||
<textarea onkeydown="inputDelete(event)" class="form-control" rows="3" v-model='nowNode["parameters"]["textList"]'></textarea>
|
<textarea onkeydown="inputDelete(event)" class="form-control" rows="3" v-model='nowNode["parameters"]["textList"]'></textarea>
|
||||||
</div>
|
</div>
|
||||||
<!-- 这里添加退出循环条件,找不到元素肯定退出循环 -->
|
<!-- 这里添加退出循环条件,找不到元素肯定退出循环 -->
|
||||||
<label v-if='parseInt(loopType) == 0'>最多执行循环次数(0代表不设置):</label>
|
<label v-if='parseInt(loopType) == 0'>Max Loop time(0 means infinite):</label>
|
||||||
<input onkeydown="inputDelete(event)" required v-if='parseInt(loopType) == 0' class="form-control" type="number" v-model.number='nowNode["parameters"]["exitCount"]'></input>
|
<input onkeydown="inputDelete(event)" required v-if='parseInt(loopType) == 0' class="form-control" type="number" v-model.number='nowNode["parameters"]["exitCount"]'></input>
|
||||||
<label><b>历史记录回退后</b>等待秒数:</label>
|
<label><b>History back</b> wait time:</label>
|
||||||
<input onkeydown="inputDelete(event)" required type="number" class="form-control" v-model.number='list.nl[index.nowNodeIndex]["parameters"]["historyWait"]'></input>
|
<input onkeydown="inputDelete(event)" required type="number" class="form-control" v-model.number='list.nl[index.nowNodeIndex]["parameters"]["historyWait"]'></input>
|
||||||
|
<label>After executed, whether scroll down:</label>
|
||||||
|
<select v-model='nowNode["parameters"]["scrollType"]' class="form-control">
|
||||||
|
<option value = 0>No</option>
|
||||||
|
<option value = 1>Scroll one screen</option>
|
||||||
|
<option value = 2>Scroll to the end</option>
|
||||||
|
</select>
|
||||||
|
<label>Scroll Times:</label>
|
||||||
|
<input onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['scrollCount']" type="number" required></input>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="elements" v-if="nodeType==9">
|
<div class="elements" v-if="nodeType==9">
|
||||||
@ -197,22 +221,22 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="elements" v-if="nodeType==10">
|
<div class="elements" v-if="nodeType==10">
|
||||||
<label>条件类型:</label>
|
<label>Condition Type:</label>
|
||||||
<select v-model='TClass' class="form-control">
|
<select v-model='TClass' class="form-control">
|
||||||
<option value = 0>无条件</option>
|
<option value = 0>No Condition</option>
|
||||||
<option value = 1>当前页面包括文本</option>
|
<option value = 1>Text inside current page</option>
|
||||||
<option value = 2>当前页面包括元素</option>
|
<option value = 2>Element inside current page</option>
|
||||||
<option v-if="nowNode['isInLoop']" value = 3>当前循环项包括文本</option>
|
<option v-if="nowNode['isInLoop']" value = 3>Text inside current loop</option>
|
||||||
<option v-if="nowNode['isInLoop']" value = 4>当前循环项包括元素</option>
|
<option v-if="nowNode['isInLoop']" value = 4>Element inside current loop</option>
|
||||||
</select>
|
</select>
|
||||||
<label v-if='TClass'>包含的文字/元素XPATH: <span style="font-size: 30px!important;" title="相对XPATH写法:以/开头,如循环项XPATH为/html/body/div[1],您的输入为/*[@id='tab-customer'],则最终寻址的xpath为:/html/body/div[1]/*[@id='tab-customer']">☺</span></label>
|
<label v-if='TClass'>Text/Xpath of Element: <span style="font-size: 30px!important;" title="相对XPATH写法:以/开头,如循环项XPATH为/html/body/div[1],您的输入为/*[@id='tab-customer'],则最终寻址的xpath为:/html/body/div[1]/*[@id='tab-customer']">☺</span></label>
|
||||||
<textarea onkeydown="inputDelete(event)" required placeholder="如果是当前循环包含元素,则输入相对元素的xpath。" v-if='TClass' class="form-control" rows="3" v-model='nowNode["parameters"]["value"]'></textarea>
|
<textarea onkeydown="inputDelete(event)" required placeholder="如果是当前循环包含元素,则输入相对元素的xpath。" v-if='TClass' class="form-control" rows="3" v-model='nowNode["parameters"]["value"]'></textarea>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-top:5px">
|
<div style="margin-top:5px">
|
||||||
<label><b>执行后</b>等待秒数:</label>
|
<label>Seconds <b>after executed</b>:</label>
|
||||||
<input onkeydown="inputDelete(event)" required type="number" class="form-control" v-model.number='list.nl[index.nowNodeIndex]["parameters"]["wait"]'></input>
|
<input onkeydown="inputDelete(event)" required type="number" class="form-control" v-model.number='list.nl[index.nowNodeIndex]["parameters"]["wait"]'></input>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-outline-primary" style="margin-top: 20px;" id="confirm">确定</button>
|
<button class="btn btn-outline-primary" style="margin-top: 20px;" id="confirm">Confirm</button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -225,20 +249,20 @@
|
|||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h4 class="modal-title" id="myModalLabel">保存服务</h4>
|
<h4 class="modal-title" id="myModalLabel">Save Service</h4>
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<input onkeydown="inputDelete(event)" id="serviceId" type="hidden" name="serviceId" value="-1"></input>
|
<input onkeydown="inputDelete(event)" id="serviceId" type="hidden" name="serviceId" value="-1"></input>
|
||||||
<input onkeydown="inputDelete(event)" id="url" type="hidden" name="url" value="about:blank"></input>
|
<input onkeydown="inputDelete(event)" id="url" type="hidden" name="url" value="about:blank"></input>
|
||||||
<label>服务名称:</label>
|
<label>Service Name:</label>
|
||||||
<input onkeydown="inputDelete(event)" required name="serviceName" value="新web服务" id="serviceName" class="form-control"></input>
|
<input onkeydown="inputDelete(event)" required name="serviceName" value="新web服务" id="serviceName" class="form-control"></input>
|
||||||
<label>服务描述:</label>
|
<label>Service Description:</label>
|
||||||
<textarea onkeydown="inputDelete(event)" id="serviceDescription" name="serviceDescription" class="form-control" rows="3"></textarea>
|
<textarea onkeydown="inputDelete(event)" id="serviceDescription" name="serviceDescription" class="form-control" rows="3"></textarea>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" id="saveAsButton" class="btn btn-outline-primary">另存为</button>
|
<button type="button" id="saveAsButton" class="btn btn-outline-primary">Save as</button>
|
||||||
<button type="button" id="saveButton" class="btn btn-primary">保存</button>
|
<button type="button" id="saveButton" class="btn btn-primary">Save</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- /.modal-content -->
|
<!-- /.modal-content -->
|
||||||
|
@ -116,13 +116,13 @@ var app = new Vue({
|
|||||||
return "OuterHTML";
|
return "OuterHTML";
|
||||||
}
|
}
|
||||||
if (nodeType == 2) {
|
if (nodeType == 2) {
|
||||||
return "链接地址";
|
return "Link Address";
|
||||||
} else if (nodeType == 1) {
|
} else if (nodeType == 1) {
|
||||||
return "链接文本";
|
return "Link Text";
|
||||||
} else if (nodeType == 4) {
|
} else if (nodeType == 4) {
|
||||||
return "图片地址";
|
return "Image Address";
|
||||||
} else {
|
} else {
|
||||||
return "文本";
|
return "Text";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -160,7 +160,7 @@ function newNode(node) {
|
|||||||
{
|
{
|
||||||
return `<div class="loop clk" dataType=${type} data="${id}" position=${node["position"]} pId=${node["parentId"]}>
|
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 style="background:#d6d6d6;text-align:left;padding:2px">${title}</p>
|
||||||
<p class="branchAdd" data="${id}">点击此处在最左边增加条件分支</p>
|
<p class="branchAdd" data="${id}">Click here to add a new condition to the left most</p>
|
||||||
<div class="judge" id = "${id}">
|
<div class="judge" id = "${id}">
|
||||||
</div></div>
|
</div></div>
|
||||||
<p class="arrow" data = "${id}" position=${node["position"]} pId=${node["parentId"]}>↓</p></div>`;
|
<p class="arrow" data = "${id}" position=${node["position"]} pId=${node["parentId"]}>↓</p></div>`;
|
||||||
@ -199,7 +199,7 @@ function branchMouseDown(e) {
|
|||||||
parentId: 0,
|
parentId: 0,
|
||||||
type: 3,
|
type: 3,
|
||||||
option: 10,
|
option: 10,
|
||||||
title: "条件分支",
|
title: "Condition",
|
||||||
sequence: [],
|
sequence: [],
|
||||||
isInLoop: false,
|
isInLoop: false,
|
||||||
};
|
};
|
||||||
@ -232,7 +232,7 @@ function branchClick(e) {
|
|||||||
parentId: 0,
|
parentId: 0,
|
||||||
type: 3,
|
type: 3,
|
||||||
option: 10,
|
option: 10,
|
||||||
title: "条件分支",
|
title: "Condition",
|
||||||
sequence: [],
|
sequence: [],
|
||||||
isInLoop: false,
|
isInLoop: false,
|
||||||
};
|
};
|
||||||
@ -269,7 +269,7 @@ function arrowClick(e) {
|
|||||||
function addElement(op, para) {
|
function addElement(op, para) {
|
||||||
option = op;
|
option = op;
|
||||||
if (option == 1) { //打开网页选项
|
if (option == 1) { //打开网页选项
|
||||||
title = "打开网页";
|
title = "Open Page";
|
||||||
} else {
|
} else {
|
||||||
title = $(".options")[option - 2].innerHTML; //获取新增操作名称
|
title = $(".options")[option - 2].innerHTML; //获取新增操作名称
|
||||||
}
|
}
|
||||||
@ -287,7 +287,7 @@ function toolBoxKernel(e, para = null) {
|
|||||||
if (nowNode == null) {
|
if (nowNode == null) {
|
||||||
e.stopPropagation(); //防止冒泡
|
e.stopPropagation(); //防止冒泡
|
||||||
} else if (nowNode.getAttribute("dataType") > 0) {
|
} else if (nowNode.getAttribute("dataType") > 0) {
|
||||||
alert("循环和判断、条件分支不可复制!");
|
alert("Cannot copy loop, if and condition!");
|
||||||
e.stopPropagation(); //防止冒泡
|
e.stopPropagation(); //防止冒泡
|
||||||
} else {
|
} else {
|
||||||
let position = parseInt(nowNode.getAttribute('position'));
|
let position = parseInt(nowNode.getAttribute('position'));
|
||||||
@ -309,7 +309,7 @@ function toolBoxKernel(e, para = null) {
|
|||||||
if (nowNode == null) {
|
if (nowNode == null) {
|
||||||
e.stopPropagation(); //防止冒泡
|
e.stopPropagation(); //防止冒泡
|
||||||
} else if ($(nowNode).is(".branch")) {
|
} else if ($(nowNode).is(".branch")) {
|
||||||
alert("判断分支不可移动!");
|
alert("Cannot move condition branch!");
|
||||||
e.stopPropagation(); //防止冒泡
|
e.stopPropagation(); //防止冒泡
|
||||||
} else {
|
} else {
|
||||||
let position = parseInt(nowNode.getAttribute('position'));
|
let position = parseInt(nowNode.getAttribute('position'));
|
||||||
@ -341,7 +341,7 @@ function toolBoxKernel(e, para = null) {
|
|||||||
app._data.nowArrow = { "position": nodeList[element[0]]["position"], "pId": nodeList[element[0]]["parentId"], "num": 0 };
|
app._data.nowArrow = { "position": nodeList[element[0]]["position"], "pId": nodeList[element[0]]["parentId"], "num": 0 };
|
||||||
$("#" + nodeList[element[0]]["id"]).click();
|
$("#" + nodeList[element[0]]["id"]).click();
|
||||||
} else {
|
} else {
|
||||||
alert("自己不能移动到自己的节点里!");
|
alert("Cannot move inside self!");
|
||||||
}
|
}
|
||||||
e.stopPropagation(); //防止冒泡
|
e.stopPropagation(); //防止冒泡
|
||||||
}
|
}
|
||||||
@ -371,7 +371,7 @@ function toolBoxKernel(e, para = null) {
|
|||||||
index: l + 1,
|
index: l + 1,
|
||||||
type: 3,
|
type: 3,
|
||||||
option: 10,
|
option: 10,
|
||||||
title: "条件分支",
|
title: "Condition",
|
||||||
sequence: [],
|
sequence: [],
|
||||||
isInLoop: false,
|
isInLoop: false,
|
||||||
};
|
};
|
||||||
@ -381,7 +381,7 @@ function toolBoxKernel(e, para = null) {
|
|||||||
index: l + 2,
|
index: l + 2,
|
||||||
type: 3,
|
type: 3,
|
||||||
option: 10,
|
option: 10,
|
||||||
title: "条件分支",
|
title: "Condition",
|
||||||
sequence: [],
|
sequence: [],
|
||||||
isInLoop: false,
|
isInLoop: false,
|
||||||
};
|
};
|
||||||
@ -426,7 +426,7 @@ $(".options").mousedown(function() {
|
|||||||
option = parseInt(this.getAttribute("data"));
|
option = parseInt(this.getAttribute("data"));
|
||||||
title = this.innerHTML;
|
title = this.innerHTML;
|
||||||
if (option >= 10 && option <= 12 && (nowNode == null || nowNode.getAttribute("id") == 0)) {
|
if (option >= 10 && option <= 12 && (nowNode == null || nowNode.getAttribute("id") == 0)) {
|
||||||
alert("目前未选中元素");
|
alert("No element is selected now!");
|
||||||
} else if (option == 12) {
|
} else if (option == 12) {
|
||||||
deleteElement();
|
deleteElement();
|
||||||
$(".options")[12].click();
|
$(".options")[12].click();
|
||||||
@ -501,13 +501,13 @@ function refresh(nowArrowReset = true) {
|
|||||||
|
|
||||||
function deleteElement() {
|
function deleteElement() {
|
||||||
if (nowNode.getAttribute("id") == 0) {
|
if (nowNode.getAttribute("id") == 0) {
|
||||||
alert("当前未选中元素!"); //root
|
alert("No element is selected now!"); //root
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (nodeList[actionSequence[nowNode.getAttribute("data")]]["option"] == 1) {
|
|
||||||
alert("打开网页操作不可删除!");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// if (nodeList[actionSequence[nowNode.getAttribute("data")]]["option"] == 1) {
|
||||||
|
// alert("Cannot delete the element of Open Page!");
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
let position = parseInt(nowNode.getAttribute('position'));
|
let position = parseInt(nowNode.getAttribute('position'));
|
||||||
let pId = nowNode.getAttribute('pId');
|
let pId = nowNode.getAttribute('pId');
|
||||||
let tnode = nodeList[actionSequence[pId]]["sequence"].splice(position, 1); //在相应位置删除元素
|
let tnode = nodeList[actionSequence[pId]]["sequence"].splice(position, 1); //在相应位置删除元素
|
||||||
@ -539,7 +539,7 @@ document.oncontextmenu = function() {
|
|||||||
//删除元素
|
//删除元素
|
||||||
document.onkeydown = function(e) {
|
document.onkeydown = function(e) {
|
||||||
if (nowNode != null && e.keyCode == 46) {
|
if (nowNode != null && e.keyCode == 46) {
|
||||||
if (confirm("确定要删除元素吗?")) {
|
if (confirm("Do you really want to delete the selected element?")) {
|
||||||
deleteElement();
|
deleteElement();
|
||||||
}
|
}
|
||||||
} else { //ctrl+s保存服务
|
} else { //ctrl+s保存服务
|
||||||
|
277
ServiceGrid/frontEnd/FlowChart_CN.html
Normal file
@ -0,0 +1,277 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<script src="jquery-3.4.1.min.js"></script>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
|
<script src="bootstrap/js/bootstrap.js"></script>
|
||||||
|
<script src="vue.js"></script>
|
||||||
|
<link rel="stylesheet" href="bootstrap/css/bootstrap.css"></link>
|
||||||
|
<link rel="stylesheet" href="FlowChart.css"></link>
|
||||||
|
<title>设计流程</title>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="tip" class="alert alert-success alert-dismissible fade show" style="position: fixed; width:100%;display: none;">
|
||||||
|
<button type="button" class="close" data-dismiss="alert">×</button> 提示:保存成功!
|
||||||
|
</div>
|
||||||
|
<div style="display:flex">
|
||||||
|
<div style="width: 200px;float:left">
|
||||||
|
<div class="toolbox" style="text-align:center;margin: 20px;border-radius:10px;border:navy solid;background-color:rgb(242,243,245);z-index: 9999;">
|
||||||
|
<div style="padding: 10px;border-radius:10px;font-size: 20px;">工具箱</div>
|
||||||
|
<button type="button" id="save" data-toggle="modal" data-target="#myModal" onmousedown="$('#myModal').modal('show');" class="btn btn-primary">保存服务</button>
|
||||||
|
<!-- <button type="button" data=1 class="btn btn-outline-primary options">打开网页</button> -->
|
||||||
|
<button type="button" data=2 class="btn btn-outline-primary options">点击元素</button>
|
||||||
|
<button type="button" data=3 class="btn btn-outline-primary options">提取数据</button>
|
||||||
|
<button type="button" data=4 class="btn btn-outline-primary options">输入文字</button>
|
||||||
|
<button type="button" data=5 class="btn btn-outline-primary options">识别验证码</button>
|
||||||
|
<button type="button" data=6 style="font-size: 14px!important;" class="btn btn-outline-primary options">切换下拉选项</button>
|
||||||
|
<button type="button" data=7 class="btn btn-outline-primary options">移动到元素</button>
|
||||||
|
<button type="button" data=8 class="btn btn-outline-primary options">循环</button>
|
||||||
|
<button type="button" data=9 class="btn btn-outline-primary options">判断条件</button>
|
||||||
|
<div>-----------------</div>
|
||||||
|
<button type="button" data=13 class="btn btn-outline-primary options" title="调整下一个要插入的节点的位置">调整锚点</button>
|
||||||
|
<button type="button" data=10 class="btn btn-outline-primary options">剪切元素</button>
|
||||||
|
<button type="button" data=11 class="btn btn-outline-primary options">复制元素</button>
|
||||||
|
<button type="button" data=12 class="btn btn-outline-primary options">删除元素</button>
|
||||||
|
<button type="button" data=0 class="btn btn-outline-primary2 options">取消操作</button>
|
||||||
|
<div style="text-align: left;margin: 10px;font-size:15px!important">提示:点击上方操作按钮后点击要放置元素的位置处的箭头,可按取消操作按钮取消。</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style="margin-top:20px;border: solid;height:850px;overflow: auto;width:58%;float:right">
|
||||||
|
<div id="0" class="clk" data="0">
|
||||||
|
</div>
|
||||||
|
<div style="border-radius: 50%;width: 40px;height: 40px;border:solid black;margin: 5px auto;background-color:lightcyan">
|
||||||
|
<p style="font-size: 22px!important;text-align: center;margin-left: 1px;">■</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style="margin-top:20px;border: solid navy;height:850px;overflow: auto;margin-left:10px;width:30%;float:right;min-width:300px">
|
||||||
|
<!-- <div style="display: inline-block;border-bottom:solid 2px;width:100%">
|
||||||
|
<input style="float:left;margin-left:10px;margin-top:10px;margin-bottom:10px" type="button" class="btn-primary" value="保存服务"></input>
|
||||||
|
</div> -->
|
||||||
|
<div class="Modify" id="app">
|
||||||
|
<div>
|
||||||
|
<label>选项名称:</label>
|
||||||
|
<input onkeydown="inputDelete(event)" class="form-control" v-model='list.nl[index.nowNodeIndex]["title"]'></input>
|
||||||
|
</div>
|
||||||
|
<!-- 下面是10种不同类型操作选项的不同的配置页面 -->
|
||||||
|
<div class="elements" v-if="nodeType==1">
|
||||||
|
<div v-if="nowNode['isInLoop']">
|
||||||
|
<!-- 如果在循环内且循环内是固定文本才显示此行元素 -->
|
||||||
|
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='useLoop'></input>使用循环内的链接</p>
|
||||||
|
</div>
|
||||||
|
<div v-if='!useLoop'>
|
||||||
|
<label>url:</label>
|
||||||
|
<input onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["url"]'></input>
|
||||||
|
<label>填入的全部链接:</label>
|
||||||
|
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["links"]'></textarea>
|
||||||
|
</div>
|
||||||
|
<label>执行完是否向下滚动:</label>
|
||||||
|
<select v-model='nowNode["parameters"]["scrollType"]' class="form-control">
|
||||||
|
<option value = 0>不滚动</option>
|
||||||
|
<option value = 1>向下滚动一屏</option>
|
||||||
|
<option value = 2>滚动到底部</option>
|
||||||
|
</select>
|
||||||
|
<label>滚动次数:</label>
|
||||||
|
<input onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['scrollCount']" type="number" required></input>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="elements" v-if="nodeType==2">
|
||||||
|
<div v-if="nowNode['isInLoop']">
|
||||||
|
<!-- 如果在循环内才显示此行元素 -->
|
||||||
|
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='useLoop'></input>使用循环内的元素</p>
|
||||||
|
</div>
|
||||||
|
<div v-if='!useLoop'>
|
||||||
|
<label>XPath: <span style="font-size: 30px!important;" title="相对XPATH写法:以/开头,如循环项XPATH为/html/body/div[1],您的输入为/*[@id='tab-customer'],则最终寻址的xpath为:/html/body/div[1]/*[@id='tab-customer']">☺</span></label>
|
||||||
|
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["xpath"]'></textarea>
|
||||||
|
</div>
|
||||||
|
<label>执行完是否向下滚动:</label>
|
||||||
|
<select v-model='nowNode["parameters"]["scrollType"]' class="form-control">
|
||||||
|
<option value = 0>不滚动</option>
|
||||||
|
<option value = 1>向下滚动一屏</option>
|
||||||
|
<option value = 2>滚动到底部</option>
|
||||||
|
</select>
|
||||||
|
<label>滚动次数:</label>
|
||||||
|
<input onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['scrollCount']" type="number" required></input>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="elements" v-if="nodeType==3">
|
||||||
|
<div class="toolkitcontain">
|
||||||
|
<table class="toolkittb2" cellspacing="0">
|
||||||
|
<tbody>
|
||||||
|
<th>字段名</th>
|
||||||
|
<th style="width:200px">示例值</th>
|
||||||
|
<th>操作</th>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<table class="toolkittb4" cellspacing="0">
|
||||||
|
<tbody>
|
||||||
|
<tr v-for="i in paras.parameters.length">
|
||||||
|
<td style="padding-left:0px"><input onkeydown="inputDelete(event)" style='padding-left:2px;font-size:13px!important;height:100%' v-model='paras.parameters[i-1]["name"]'></input>
|
||||||
|
</td>
|
||||||
|
<td style="width:200px">{{paras.parameters[i-1]["exampleValues"][0]["value"]}}</td>
|
||||||
|
<td>
|
||||||
|
<a v-on:mousedown="modifyParas(i-1)">修改</a>
|
||||||
|
<a v-on:mousedown="deleteParas(i-1)">删除</a>
|
||||||
|
<a v-on:mousedown="upParas(i-1)">上移</a>
|
||||||
|
<a v-on:mousedown="downParas(i-1)">下移</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div style="font-size: 13px;" v-if="paraIndex<paras.parameters.length">
|
||||||
|
<label>当前编辑参数名: <strong>{{paras.parameters[paraIndex]["name"]}}</strong></label>
|
||||||
|
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='paras.parameters[paraIndex]["relative"]'></input>使用相对循环内的XPATH</p>
|
||||||
|
<label>XPATH: <span style="font-size: 30px!important;" title="相对XPATH写法:以/开头,如循环项XPATH为/html/body/div[1],您的输入为/*[@id='tab-customer'],则最终寻址的xpath为:/html/body/div[1]/*[@id='tab-customer']">☺</span></label>
|
||||||
|
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='paras.parameters[paraIndex]["relativeXpath"]'></textarea>
|
||||||
|
<label>采集内容类型</label>
|
||||||
|
<select v-model='paras.parameters[paraIndex]["contentType"]' class="form-control">
|
||||||
|
<option :value = 0>文本(包括子元素)</option>
|
||||||
|
<option :value = 1>文本(不包括子元素)</option>
|
||||||
|
<option :value = 2>innerHTML</option>
|
||||||
|
<option :value = 3>outerHTML</option>
|
||||||
|
</select>
|
||||||
|
<label>节点类型</label>
|
||||||
|
<select v-model='paras.parameters[paraIndex]["nodeType"]' class="form-control">
|
||||||
|
<option :value = 0>普通节点</option>
|
||||||
|
<option :value = 1>链接文本</option>
|
||||||
|
<option :value = 2>链接地址</option>
|
||||||
|
<option :value = 3>表单值</option>
|
||||||
|
<option :value = 4>图片地址</option>
|
||||||
|
</select>
|
||||||
|
<label>参数描述:</label>
|
||||||
|
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='paras.parameters[paraIndex]["desc"]'></textarea>
|
||||||
|
<label>元素找不到时的值:</label>
|
||||||
|
<input onkeydown="inputDelete(event)" class="form-control" v-model='paras.parameters[paraIndex]["default"]'></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="elements" v-if="nodeType==4">
|
||||||
|
<div v-if="nowNode['isInLoop']">
|
||||||
|
<!-- 如果在循环内且循环内是固定文本才显示此行元素 -->
|
||||||
|
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='useLoop'></input>使用循环内的文本</p>
|
||||||
|
</div>
|
||||||
|
<div v-if='!useLoop'>
|
||||||
|
<label>输入值:</label>
|
||||||
|
<input onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["value"]'></input>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<label>XPath: <span style="font-size: 30px!important;" title="相对XPATH写法:以/开头,如循环项XPATH为/html/body/div[1],您的输入为/*[@id='tab-customer'],则最终寻址的xpath为:/html/body/div[1]/*[@id='tab-customer']">☺</span></label>
|
||||||
|
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["xpath"]'></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="elements" v-if="nodeType==5">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="elements" v-if="nodeType==6">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="elements" v-if="nodeType==7">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="elements" v-if="nodeType==8">
|
||||||
|
<!-- 循环选项 -->
|
||||||
|
<label>循环类型:</label>
|
||||||
|
<select v-model='loopType' class="form-control">
|
||||||
|
<option value = 0>单个元素</option>
|
||||||
|
<option value = 1>不固定元素列表</option>
|
||||||
|
<option value = 2>固定元素列表</option>
|
||||||
|
<option value = 3>文本列表</option>
|
||||||
|
<option value = 4>网址列表</option>
|
||||||
|
</select>
|
||||||
|
<div v-if='parseInt(loopType) < 2'>
|
||||||
|
<label>XPath: <span style="font-size: 30px!important;" title="相对XPATH写法:以/开头,如循环项XPATH为/html/body/div[1],您的输入为/*[@id='tab-customer'],则最终寻址的xpath为:/html/body/div[1]/*[@id='tab-customer']">☺</span></label>
|
||||||
|
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["xpath"]'></textarea>
|
||||||
|
</div>
|
||||||
|
<div v-if='parseInt(loopType) == 2'>
|
||||||
|
<label>XPath列表:</label>
|
||||||
|
<textarea onkeydown="inputDelete(event)" class="form-control" rows="3" v-model='nowNode["parameters"]["pathList"]'></textarea>
|
||||||
|
</div>
|
||||||
|
<div v-if='parseInt(loopType) > 2'>
|
||||||
|
<label>内容列表:</label>
|
||||||
|
<textarea onkeydown="inputDelete(event)" class="form-control" rows="3" v-model='nowNode["parameters"]["textList"]'></textarea>
|
||||||
|
</div>
|
||||||
|
<!-- 这里添加退出循环条件,找不到元素肯定退出循环 -->
|
||||||
|
<label v-if='parseInt(loopType) == 0'>最多执行循环次数(0代表不设置):</label>
|
||||||
|
<input onkeydown="inputDelete(event)" required v-if='parseInt(loopType) == 0' class="form-control" type="number" v-model.number='nowNode["parameters"]["exitCount"]'></input>
|
||||||
|
<label><b>历史记录回退后</b>等待秒数:</label>
|
||||||
|
<input onkeydown="inputDelete(event)" required type="number" class="form-control" v-model.number='list.nl[index.nowNodeIndex]["parameters"]["historyWait"]'></input>
|
||||||
|
<label>执行完是否向下滚动:</label>
|
||||||
|
<select v-model='nowNode["parameters"]["scrollType"]' class="form-control">
|
||||||
|
<option value = 0>不滚动</option>
|
||||||
|
<option value = 1>向下滚动一屏</option>
|
||||||
|
<option value = 2>滚动到底部</option>
|
||||||
|
</select>
|
||||||
|
<label>滚动次数:</label>
|
||||||
|
<input onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['scrollCount']" type="number" required></input>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="elements" v-if="nodeType==9">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="elements" v-if="nodeType==10">
|
||||||
|
<label>条件类型:</label>
|
||||||
|
<select v-model='TClass' class="form-control">
|
||||||
|
<option value = 0>无条件</option>
|
||||||
|
<option value = 1>当前页面包括文本</option>
|
||||||
|
<option value = 2>当前页面包括元素</option>
|
||||||
|
<option v-if="nowNode['isInLoop']" value = 3>当前循环项包括文本</option>
|
||||||
|
<option v-if="nowNode['isInLoop']" value = 4>当前循环项包括元素</option>
|
||||||
|
</select>
|
||||||
|
<label v-if='TClass'>包含的文字/元素XPATH: <span style="font-size: 30px!important;" title="相对XPATH写法:以/开头,如循环项XPATH为/html/body/div[1],您的输入为/*[@id='tab-customer'],则最终寻址的xpath为:/html/body/div[1]/*[@id='tab-customer']">☺</span></label>
|
||||||
|
<textarea onkeydown="inputDelete(event)" required placeholder="如果是当前循环包含元素,则输入相对元素的xpath。" v-if='TClass' class="form-control" rows="3" v-model='nowNode["parameters"]["value"]'></textarea>
|
||||||
|
</div>
|
||||||
|
<div style="margin-top:5px">
|
||||||
|
<label><b>执行后</b>等待秒数:</label>
|
||||||
|
<input onkeydown="inputDelete(event)" required type="number" class="form-control" v-model.number='list.nl[index.nowNodeIndex]["parameters"]["wait"]'></input>
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-outline-primary" style="margin-top: 20px;" id="confirm">确定</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 class="modal-title" id="myModalLabel">保存服务</h4>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<input onkeydown="inputDelete(event)" id="serviceId" type="hidden" name="serviceId" value="-1"></input>
|
||||||
|
<input onkeydown="inputDelete(event)" id="url" type="hidden" name="url" value="about:blank"></input>
|
||||||
|
<label>服务名称:</label>
|
||||||
|
<input onkeydown="inputDelete(event)" required name="serviceName" value="新web服务" id="serviceName" class="form-control"></input>
|
||||||
|
<label>服务描述:</label>
|
||||||
|
<textarea onkeydown="inputDelete(event)" id="serviceDescription" name="serviceDescription" class="form-control" rows="3"></textarea>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" id="saveAsButton" class="btn btn-outline-primary">另存为</button>
|
||||||
|
<button type="button" id="saveButton" class="btn btn-primary">保存</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /.modal-content -->
|
||||||
|
</div>
|
||||||
|
<!-- /.modal -->
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
<script src="FlowChart_CN.js"></script>
|
||||||
|
<script src="logic_CN.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</html>
|
561
ServiceGrid/frontEnd/FlowChart_CN.js
Normal file
@ -0,0 +1,561 @@
|
|||||||
|
//处理表现层
|
||||||
|
var nodeList = Array(); //所有新生成的节点全部存储在这里,并且有唯一索引号,所有的定位均通过index进行,即将图保存下来了
|
||||||
|
var 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,
|
||||||
|
},
|
||||||
|
isInLoop: false, //是否处于循环内
|
||||||
|
};
|
||||||
|
nodeList.push(root);
|
||||||
|
var queue = new Array();
|
||||||
|
var actionSequence = new Array(); //存储图结构,每个元素为在nodelist里面的索引值,下面的id和pid根据此数组进行索引,然后再在nodelist里找
|
||||||
|
var nowNode = null; //存储现在所在的节点
|
||||||
|
var vueData = { nowNodeIndex: 0 }; //存储目前所在节点的索引号,不能直接使用变量而需要用对象包起来
|
||||||
|
var option = 0; //工具箱选项
|
||||||
|
var title = "";
|
||||||
|
var parameterNum = 1; //记录目前的参数个数
|
||||||
|
|
||||||
|
//处理逻辑层
|
||||||
|
var app = new Vue({
|
||||||
|
el: '#app',
|
||||||
|
data: {
|
||||||
|
list: { nl: nodeList },
|
||||||
|
index: vueData,
|
||||||
|
nodeType: 0, // 当前元素的类型
|
||||||
|
nowNode: null, // 用来临时存储元素的节点
|
||||||
|
loopType: -1, //点击循环时候用来循环选项
|
||||||
|
useLoop: false, //记录是否使用循环内元素
|
||||||
|
nowArrow: { "position": -1, "pId": 0, "num": 0 },
|
||||||
|
paras: { "parameters": [] }, //提取数据的参数列表
|
||||||
|
TClass: -1, //条件分支的条件类别
|
||||||
|
paraIndex: 0, //当前参数的index
|
||||||
|
},
|
||||||
|
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"];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
modifyParas: function(i) { //修改第i个参数
|
||||||
|
this.paraIndex = i;
|
||||||
|
},
|
||||||
|
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;
|
||||||
|
var cpObj = obj instanceof Array ? [] : {};
|
||||||
|
for (var 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 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 branchMouseDown(e) {
|
||||||
|
if (e.button == 2) //右键点击
|
||||||
|
{
|
||||||
|
let judgeId = this.getAttribute('data');
|
||||||
|
var l = nodeList.length;
|
||||||
|
var 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');
|
||||||
|
var l = nodeList.length;
|
||||||
|
var 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 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 - 2].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');
|
||||||
|
var tt = nodeList[nodeList[actionSequence[pId]]["sequence"][position]]; //在相应位置添加新元素
|
||||||
|
t = DeepClone(tt); //浅复制元素
|
||||||
|
var l = nodeList.length;
|
||||||
|
t.index = l;
|
||||||
|
nodeList.push(t);
|
||||||
|
var position2 = parseInt(app._data.nowArrow['position']);
|
||||||
|
var 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');
|
||||||
|
var position2 = parseInt(app._data.nowArrow['position']);
|
||||||
|
var pId2 = app._data.nowArrow['pId'];
|
||||||
|
var id = nowNode.getAttribute('data');
|
||||||
|
var pidt = pId2;
|
||||||
|
var 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) { //新增操作
|
||||||
|
var l = nodeList.length;
|
||||||
|
var 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;
|
||||||
|
// 增加两个分支
|
||||||
|
var nt = {
|
||||||
|
id: 0,
|
||||||
|
parentId: 0,
|
||||||
|
index: l + 1,
|
||||||
|
type: 3,
|
||||||
|
option: 10,
|
||||||
|
title: "条件分支",
|
||||||
|
sequence: [],
|
||||||
|
isInLoop: false,
|
||||||
|
};
|
||||||
|
var 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);
|
||||||
|
var idd = 1;
|
||||||
|
queue.push(0);
|
||||||
|
actionSequence.push(0);
|
||||||
|
while (queue.length != 0) {
|
||||||
|
var nd = queue.shift(); //取出父元素并建立对子元素的链接
|
||||||
|
for (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": -1, "pId": 0, "num": 0 }; //设置默认要添加的位置是元素流程最开头处
|
||||||
|
}
|
||||||
|
//第一个元素不渲染
|
||||||
|
for (i = 1; i < actionSequence.length; i++) {
|
||||||
|
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保存服务
|
||||||
|
var currKey = 0,
|
||||||
|
e = e || event || window.event;
|
||||||
|
currKey = e.keyCode || e.which || e.charCode;
|
||||||
|
if (currKey == 83 && (e.ctrlKey || e.metaKey)) {
|
||||||
|
$('#save').click();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function inputDelete(e) {
|
||||||
|
if (e.keyCode == 46) {
|
||||||
|
e.stopPropagation(); //输入框按delete应该正常运行
|
||||||
|
}
|
||||||
|
}
|
@ -8,7 +8,7 @@
|
|||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
<script src="vue.js"></script>
|
<script src="vue.js"></script>
|
||||||
<link rel="stylesheet" href="bootstrap/css/bootstrap.css"></link>
|
<link rel="stylesheet" href="bootstrap/css/bootstrap.css"></link>
|
||||||
<title>服务调用</title>
|
<title>Service Invoke</title>
|
||||||
<style>
|
<style>
|
||||||
table {
|
table {
|
||||||
table-layout: auto;
|
table-layout: auto;
|
||||||
@ -35,20 +35,20 @@
|
|||||||
<body>
|
<body>
|
||||||
<div class="row" style="margin-top: 40px;">
|
<div class="row" style="margin-top: 40px;">
|
||||||
<div class="col-md-6" style="margin:0 auto" id="serviceList" v-if="show">
|
<div class="col-md-6" style="margin:0 auto" id="serviceList" v-if="show">
|
||||||
<h4 style="text-align: center;">服务信息</h4>
|
<h4 style="text-align: center;">Service Information</h4>
|
||||||
<p>服务名称:{{service["name"]}}</p>
|
<p>Service Name: {{service["name"]}}</p>
|
||||||
<p style="word-wrap: break-word;word-break: break-all;overflow: hidden;max-height: 100px;">服务描述:{{service["desc"]}}</p>
|
<p style="word-wrap: break-word;word-break: break-all;overflow: hidden;max-height: 100px;">Service Description: {{service["desc"]}}</p>
|
||||||
<p style="word-wrap: break-word;word-break: break-all;overflow: hidden;max-height: 100px;">任务号调用URL:http://183.129.170.180:8041/backEnd/invokeService?id={{service["id"]}}</p>
|
<p style="word-wrap: break-word;word-break: break-all;overflow: hidden;max-height: 100px;">URL: {{backEndAddressServiceWrapper}}/backEnd/invokeService?id={{service["id"]}}</p>
|
||||||
<p>请输入参数:</p>
|
<p>Please Input Parameters: </p>
|
||||||
<form id="form">
|
<form id="form">
|
||||||
<table class="table table-bordered">
|
<table class="table table-bordered">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<th style="min-width: 50px;">ID</th>
|
<th style="min-width: 50px;">ID</th>
|
||||||
<th>参数名称</th>
|
<th>Parameter Name</th>
|
||||||
<th>调用名称</th>
|
<th>Invoke Name</th>
|
||||||
<th>参数类型</th>
|
<th>Parameter Type</th>
|
||||||
<th>参数值</th>
|
<th>Parameter Value</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr v-if="service.inputParameters.length>0" v-for="i in service.inputParameters.length">
|
<tr v-if="service.inputParameters.length>0" v-for="i in service.inputParameters.length">
|
||||||
@ -62,16 +62,16 @@
|
|||||||
</table>
|
</table>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<button style="margin-left: 5px;" v-on:click="localExcuteInstant" class="btn btn-primary">直接本地执行</button>
|
<button style="margin-left: 5px;" v-on:click="localExcuteInstant" class="btn btn-primary">Directly Run locally</button>
|
||||||
<button style="margin-left: 5px;" v-on:click="remoteExcuteInstant" class="btn btn-primary">直接远程执行</button>
|
<button style="margin-left: 5px;" v-on:click="remoteExcuteInstant" class="btn btn-primary">Directly Run Remotely</button>
|
||||||
<div style="margin-bottom: 10px;">
|
<div style="margin-bottom: 10px;">
|
||||||
<label style="margin-top: 10px;">任务ID:</label>
|
<label style="margin-top: 10px;">Task ID:</label>
|
||||||
<input class="form-control" v-model="ID"></input>
|
<input class="form-control" v-model="ID"></input>
|
||||||
<p></p>
|
<p></p>
|
||||||
<p>提示:点击下方按钮获得任务ID,然后根据此ID进行服务执行;也可自己POST调用接口得到ID,具体参照POST调用文档。</p>
|
<p>提示:点击下方按钮获得任务ID,然后根据此ID进行服务执行;也可自己POST调用接口得到ID,具体参照POST调用文档。</p>
|
||||||
<a href="javascript:void(0)" v-on:click="invokeService" class="btn btn-primary">获得任务ID</a>
|
<a href="javascript:void(0)" v-on:click="invokeService" class="btn btn-primary">Get Task ID</a>
|
||||||
<button v-on:click="localExcute" style="margin-left: 8px;" class="btn btn-primary">本地执行任务</button>
|
<button v-on:click="localExcute" style="margin-left: 8px;" class="btn btn-primary">Run locally</button>
|
||||||
<button v-on:click="remoteExcute" style="margin-left: 8px;" class="btn btn-primary">远程执行任务</button></div>
|
<button v-on:click="remoteExcute" style="margin-left: 8px;" class="btn btn-primary">Run remotely</button></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -85,7 +85,7 @@
|
|||||||
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象
|
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象
|
||||||
var r = window.location.search.substr(1).match(reg); //匹配目标参数
|
var r = window.location.search.substr(1).match(reg); //匹配目标参数
|
||||||
if (r != null) return unescape(r[2]);
|
if (r != null) return unescape(r[2]);
|
||||||
return null; //返回参数值
|
return ""; //返回参数值,默认后台地址
|
||||||
}
|
}
|
||||||
|
|
||||||
var sId = getUrlParam('id');
|
var sId = getUrlParam('id');
|
||||||
@ -95,6 +95,7 @@
|
|||||||
service: {},
|
service: {},
|
||||||
show: false, //是否渲染
|
show: false, //是否渲染
|
||||||
ID: "暂无",
|
ID: "暂无",
|
||||||
|
backEndAddressServiceWrapper: getUrlParam("backEndAddressServiceWrapper"),
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
invokeService: function() {
|
invokeService: function() {
|
||||||
@ -104,7 +105,7 @@
|
|||||||
t.forEach(function(item, index) {
|
t.forEach(function(item, index) {
|
||||||
para[item.name] = item.value;
|
para[item.name] = item.value;
|
||||||
});
|
});
|
||||||
$.post("http://183.129.170.180:8041/backEnd/invokeService?id=" + sId, {
|
$.post(app.$data.backEndAddressServiceWrapper + "/backEnd/invokeService?id=" + sId, {
|
||||||
id: this.service.id,
|
id: this.service.id,
|
||||||
paras: JSON.stringify(para)
|
paras: JSON.stringify(para)
|
||||||
}, function(result) {
|
}, function(result) {
|
||||||
@ -149,7 +150,7 @@
|
|||||||
t.forEach(function(item, index) {
|
t.forEach(function(item, index) {
|
||||||
para[item.name] = item.value;
|
para[item.name] = item.value;
|
||||||
});
|
});
|
||||||
$.post("http://183.129.170.180:8041/backEnd/invokeService?id=" + sId, {
|
$.post(app.$data.backEndAddressServiceWrapper + "/backEnd/invokeService?id=" + sId, {
|
||||||
id: this.service.id,
|
id: this.service.id,
|
||||||
paras: JSON.stringify(para)
|
paras: JSON.stringify(para)
|
||||||
}, function(result) {
|
}, function(result) {
|
||||||
@ -170,7 +171,7 @@
|
|||||||
t.forEach(function(item, index) {
|
t.forEach(function(item, index) {
|
||||||
para[item.name] = item.value;
|
para[item.name] = item.value;
|
||||||
});
|
});
|
||||||
$.post("http://183.129.170.180:8041/backEnd/invokeService?id=" + sId, {
|
$.post(app.$data.backEndAddressServiceWrapper + "/backEnd/invokeService?id=" + sId, {
|
||||||
id: this.service.id,
|
id: this.service.id,
|
||||||
paras: JSON.stringify(para)
|
paras: JSON.stringify(para)
|
||||||
}, function(result) {
|
}, function(result) {
|
||||||
@ -180,7 +181,7 @@
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$.get("http://183.129.170.180:8041/backEnd/queryService?id=" + sId, function(result) {
|
$.get(app.$data.backEndAddressServiceWrapper + "/backEnd/queryService?id=" + sId, function(result) {
|
||||||
app.$data.service = result;
|
app.$data.service = result;
|
||||||
app.$data.show = true;
|
app.$data.show = true;
|
||||||
});
|
});
|
||||||
|
@ -125,6 +125,8 @@ function addParameters(t) {
|
|||||||
} else if (t.option == 4) { //输入文字
|
} else if (t.option == 4) { //输入文字
|
||||||
t["parameters"]["value"] = "";
|
t["parameters"]["value"] = "";
|
||||||
} else if (t.option == 8) { //循环
|
} else if (t.option == 8) { //循环
|
||||||
|
t["parameters"]["scrollType"] = 0; //滚动类型,0不滚动,1向下滚动1屏,2滚动到底部
|
||||||
|
t["parameters"]["scrollCount"] = 0; //滚动次数
|
||||||
t["parameters"]["loopType"] = 0; //默认循环类型
|
t["parameters"]["loopType"] = 0; //默认循环类型
|
||||||
t["parameters"]["xpath"] = "";
|
t["parameters"]["xpath"] = "";
|
||||||
t["parameters"]["pathList"] = "";
|
t["parameters"]["pathList"] = "";
|
||||||
@ -158,9 +160,9 @@ function modifyParameters(t, para) {
|
|||||||
t["parameters"]["loopType"] = para["loopType"];
|
t["parameters"]["loopType"] = para["loopType"];
|
||||||
t["parameters"]["xpath"] = para["xpath"];
|
t["parameters"]["xpath"] = para["xpath"];
|
||||||
if (para["nextPage"]) { //循环点击下一页的情况下
|
if (para["nextPage"]) { //循环点击下一页的情况下
|
||||||
t["title"] = "循环点击下一页"
|
t["title"] = "Loop click next page"
|
||||||
} else {
|
} else {
|
||||||
t["title"] = "循环"
|
t["title"] = "Loop"
|
||||||
}
|
}
|
||||||
if (para["loopType"] == 2) //如果是固定元素列表
|
if (para["loopType"] == 2) //如果是固定元素列表
|
||||||
{
|
{
|
||||||
@ -190,12 +192,23 @@ $("#confirm").mousedown(function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//获取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");
|
||||||
|
|
||||||
function saveService(type) {
|
function saveService(type) {
|
||||||
var serviceId = $("#serviceId").val();
|
var serviceId = $("#serviceId").val();
|
||||||
var text = "确认要保存服务吗?";
|
var text = "Confirm to save service?";
|
||||||
if (type == 1) { //服务另存为
|
if (type == 1) { //服务另存为
|
||||||
serviceId = -1;
|
serviceId = -1;
|
||||||
text = "确认要另存为服务吗?";
|
text = "Confirm to save as service?";
|
||||||
}
|
}
|
||||||
if (confirm(text)) {
|
if (confirm(text)) {
|
||||||
let serviceName = $("#serviceName").val();
|
let serviceName = $("#serviceName").val();
|
||||||
@ -222,7 +235,7 @@ function saveService(type) {
|
|||||||
value: nodeList[i]["parameters"]["links"],
|
value: nodeList[i]["parameters"]["links"],
|
||||||
desc: "要采集的网址列表,多行以\\n分开",
|
desc: "要采集的网址列表,多行以\\n分开",
|
||||||
type: "string",
|
type: "string",
|
||||||
exampleValue: "https://www.jd.com"
|
exampleValue: nodeList[i]["parameters"]["links"]
|
||||||
});
|
});
|
||||||
links = nodeList[i]["parameters"]["links"];
|
links = nodeList[i]["parameters"]["links"];
|
||||||
}
|
}
|
||||||
@ -243,17 +256,30 @@ function saveService(type) {
|
|||||||
}
|
}
|
||||||
} else if (nodeList[i]["option"] == 8) //循环操作
|
} else if (nodeList[i]["option"] == 8) //循环操作
|
||||||
{
|
{
|
||||||
if (parseInt(nodeList[i]["parameters"]["loopType"]) > 2) //循环中的循环输入文本或循环输入网址
|
if (parseInt(nodeList[i]["parameters"]["loopType"]) > 2) {
|
||||||
inputParameters.push({
|
inputParameters.push({
|
||||||
id: inputIndex,
|
id: inputIndex,
|
||||||
name: "loopText_" + inputIndex++,
|
name: "loopText_" + inputIndex++,
|
||||||
nodeId: i,
|
nodeId: i,
|
||||||
nodeName: nodeList[i]["title"],
|
nodeName: nodeList[i]["title"],
|
||||||
desc: "要输入的文本/网址,多行以\\n分开",
|
desc: "要输入的文本/网址,多行以\\n分开",
|
||||||
type: "string",
|
type: "string",
|
||||||
exampleValue: nodeList[i]["parameters"]["textList"],
|
exampleValue: nodeList[i]["parameters"]["textList"],
|
||||||
value: 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) //提取数据操作
|
} else if (nodeList[i]["option"] == 3) //提取数据操作
|
||||||
{
|
{
|
||||||
for (let j = 0; j < nodeList[i]["parameters"]["paras"].length; j++) {
|
for (let j = 0; j < nodeList[i]["parameters"]["paras"].length; j++) {
|
||||||
@ -285,7 +311,7 @@ function saveService(type) {
|
|||||||
"outputParameters": outputParameters,
|
"outputParameters": outputParameters,
|
||||||
"graph": nodeList, //图结构要存储下来
|
"graph": nodeList, //图结构要存储下来
|
||||||
};
|
};
|
||||||
$.post("http://183.129.170.180:8041/backEnd/manageService", { paras: JSON.stringify(serviceInfo) }, function(result) { $("#serviceId").val(parseInt(result)) });
|
$.post(backEndAddressServiceWrapper + "/backEnd/manageService", { paras: JSON.stringify(serviceInfo) }, function(result) { $("#serviceId").val(parseInt(result)) });
|
||||||
// alert("保存成功!");
|
// alert("保存成功!");
|
||||||
$('#myModal').modal('hide');
|
$('#myModal').modal('hide');
|
||||||
$("#tip").slideDown(); //提示框
|
$("#tip").slideDown(); //提示框
|
||||||
@ -305,19 +331,10 @@ $("#saveAsButton").mousedown(function() {
|
|||||||
saveService(1);
|
saveService(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
//获取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 null; //返回参数值
|
|
||||||
}
|
|
||||||
|
|
||||||
var sId = getUrlParam('id');
|
|
||||||
|
|
||||||
if (sId != null && sId != -1) //加载服务
|
if (sId != null && sId != -1) //加载服务
|
||||||
{
|
{
|
||||||
$.get("http://183.129.170.180:8041/backEnd/queryService?id=" + sId, function(result) {
|
$.get(backEndAddressServiceWrapper + "/backEnd/queryService?id=" + sId, function(result) {
|
||||||
nodeList = result["graph"];
|
nodeList = result["graph"];
|
||||||
app.$data.list.nl = nodeList;
|
app.$data.list.nl = nodeList;
|
||||||
$("#serviceName").val(result["name"]);
|
$("#serviceName").val(result["name"]);
|
||||||
|
335
ServiceGrid/frontEnd/logic_CN.js
Normal file
@ -0,0 +1,335 @@
|
|||||||
|
exampleMsg = { //示例消息
|
||||||
|
"type": 0, //消息类型,1代表增加操作
|
||||||
|
"data": {
|
||||||
|
"option": 1, //增加选项
|
||||||
|
"parameters": { //传入的参数
|
||||||
|
"url": "https://www.baidu.com"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(JSON.stringify(exampleMsg));
|
||||||
|
ws = new WebSocket("ws://localhost:8084");
|
||||||
|
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("连接已关闭...");
|
||||||
|
};
|
||||||
|
var ttt;
|
||||||
|
ws.onmessage = function(evt) {
|
||||||
|
evt = JSON.parse(evt.data);
|
||||||
|
console.log(evt);
|
||||||
|
if (evt["type"] == "special") { //如果不是特殊处理的话,默认全部是增加元素操作
|
||||||
|
|
||||||
|
} else {
|
||||||
|
handleAddElement(evt); //处理增加元素操作
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
function handleAddElement(msg) {
|
||||||
|
if (msg["type"] == "openPage") {
|
||||||
|
addElement(1, msg);
|
||||||
|
} else if (msg["type"] == "InputText") {
|
||||||
|
addElement(4, msg);
|
||||||
|
} else if (msg["type"] == "singleClick") {
|
||||||
|
addElement(2, 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++) {
|
||||||
|
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); //通知浏览器端参数的个数变化
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 流程图元素点击后的处理逻辑
|
||||||
|
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"] == 10) {
|
||||||
|
app._data.TClass = app._data["nowNode"]["parameters"]["class"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增元素时的默认参数处理
|
||||||
|
function addParameters(t) {
|
||||||
|
t["parameters"] = {
|
||||||
|
history: 1,
|
||||||
|
tabIndex: 0,
|
||||||
|
useLoop: false, //是否使用循环中的元素
|
||||||
|
xpath: "", //xpath
|
||||||
|
wait: 0, //执行后等待
|
||||||
|
}; //公共参数处理
|
||||||
|
if (t.option == 1) {
|
||||||
|
t["parameters"]["url"] = "about:blank";
|
||||||
|
t["parameters"]["links"] = "about:blank";
|
||||||
|
t["parameters"]["scrollType"] = 0; //滚动类型,0不滚动,1向下滚动1屏,2滚动到底部
|
||||||
|
t["parameters"]["scrollCount"] = 0; //滚动次数
|
||||||
|
} else if (t.option == 2) { //点击元素
|
||||||
|
t["parameters"]["scrollType"] = 0; //滚动类型,0不滚动,1向下滚动1屏,2滚动到底部
|
||||||
|
t["parameters"]["scrollCount"] = 0; //滚动次数
|
||||||
|
t["parameters"]["paras"] = []; //默认参数列表
|
||||||
|
} else if (t.option == 3) { //提取数据
|
||||||
|
t["parameters"]["paras"] = []; //默认参数列表
|
||||||
|
} else if (t.option == 4) { //输入文字
|
||||||
|
t["parameters"]["value"] = "";
|
||||||
|
} else if (t.option == 8) { //循环
|
||||||
|
t["parameters"]["scrollType"] = 0; //滚动类型,0不滚动,1向下滚动1屏,2滚动到底部
|
||||||
|
t["parameters"]["scrollCount"] = 0; //滚动次数
|
||||||
|
t["parameters"]["loopType"] = 0; //默认循环类型
|
||||||
|
t["parameters"]["xpath"] = "";
|
||||||
|
t["parameters"]["pathList"] = "";
|
||||||
|
t["parameters"]["textList"] = "";
|
||||||
|
t["parameters"]["exitCount"] = 0; //执行多少次后退出循环,0代表不设置此条件
|
||||||
|
t["parameters"]["historyWait"] = 2; //历史记录回退时间,用于循环点击每个链接的情况下点击链接后不打开新标签页的情况
|
||||||
|
} else if (t.option == 9) { //条件
|
||||||
|
|
||||||
|
} else if (t.option == 10) { //条件分支
|
||||||
|
t["parameters"]["class"] = 0; //0代表什么条件都没有,1代表当前页面包括文本,2代表当前页面包括元素,3代表当前循环包括文本,4代表当前循环包括元素
|
||||||
|
t["parameters"]["value"] = ""; //相关值
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//修改元素参数
|
||||||
|
function modifyParameters(t, para) {
|
||||||
|
t["parameters"]["history"] = para["history"];
|
||||||
|
t["parameters"]["tabIndex"] = para["tabIndex"];
|
||||||
|
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 == 4) { //输入文字事件
|
||||||
|
t["parameters"]["value"] = para["value"];
|
||||||
|
t["parameters"]["xpath"] = para["xpath"];
|
||||||
|
} else if (t.option == 2) { //鼠标点击事件
|
||||||
|
t["parameters"]["xpath"] = para["xpath"];
|
||||||
|
t["parameters"]["useLoop"] = para["useLoop"];
|
||||||
|
} else if (t.option == 8) { //循环事件
|
||||||
|
t["parameters"]["loopType"] = para["loopType"];
|
||||||
|
t["parameters"]["xpath"] = para["xpath"];
|
||||||
|
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++) {
|
||||||
|
para["parameters"][i]["default"] = ""; //找不到元素时候的默认值
|
||||||
|
}
|
||||||
|
t["parameters"]["paras"] = para["parameters"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//点击确定按钮时的处理
|
||||||
|
$("#confirm").mousedown(function() {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//获取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");
|
||||||
|
|
||||||
|
function saveService(type) {
|
||||||
|
var serviceId = $("#serviceId").val();
|
||||||
|
var 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; //是否含有判断语句
|
||||||
|
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: "string",
|
||||||
|
exampleValue: "https://www.jd.com"
|
||||||
|
});
|
||||||
|
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: "string",
|
||||||
|
exampleValue: nodeList[i]["parameters"]["value"],
|
||||||
|
value: nodeList[i]["parameters"]["value"],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else if (nodeList[i]["option"] == 8) //循环操作
|
||||||
|
{
|
||||||
|
if (parseInt(nodeList[i]["parameters"]["loopType"]) > 2) //循环中的循环输入文本或循环输入网址
|
||||||
|
inputParameters.push({
|
||||||
|
id: inputIndex,
|
||||||
|
name: "loopText_" + inputIndex++,
|
||||||
|
nodeId: i,
|
||||||
|
nodeName: nodeList[i]["title"],
|
||||||
|
desc: "要输入的文本/网址,多行以\\n分开",
|
||||||
|
type: "string",
|
||||||
|
exampleValue: nodeList[i]["parameters"]["textList"],
|
||||||
|
value: nodeList[i]["parameters"]["textList"],
|
||||||
|
});
|
||||||
|
} 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: "string",
|
||||||
|
exampleValue: nodeList[i]["parameters"]["paras"][j]["exampleValues"][0]["value"],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (nodeList[i]["option"] == 9) //条件判断
|
||||||
|
{
|
||||||
|
containJudge = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let serviceInfo = {
|
||||||
|
"id": parseInt(serviceId),
|
||||||
|
"name": serviceName,
|
||||||
|
"url": url,
|
||||||
|
"links": links,
|
||||||
|
"containJudge": containJudge,
|
||||||
|
"desc": serviceDescription,
|
||||||
|
"inputParameters": inputParameters,
|
||||||
|
"outputParameters": outputParameters,
|
||||||
|
"graph": nodeList, //图结构要存储下来
|
||||||
|
};
|
||||||
|
$.post(backEndAddressServiceWrapper + "/backEnd/manageService", { paras: JSON.stringify(serviceInfo) }, function(result) { $("#serviceId").val(parseInt(result)) });
|
||||||
|
// alert("保存成功!");
|
||||||
|
$('#myModal').modal('hide');
|
||||||
|
$("#tip").slideDown(); //提示框
|
||||||
|
fadeout = setTimeout(function() {
|
||||||
|
$("#tip").slideUp();
|
||||||
|
}, 2000);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//点击保存服务按钮时的处理
|
||||||
|
$("#saveButton").mousedown(function() {
|
||||||
|
saveService(0);
|
||||||
|
});
|
||||||
|
//点击另存为服务按钮时的处理
|
||||||
|
$("#saveAsButton").mousedown(function() {
|
||||||
|
saveService(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
if (sId != null && sId != -1) //加载服务
|
||||||
|
{
|
||||||
|
$.get(backEndAddressServiceWrapper + "/backEnd/queryService?id=" + sId, function(result) {
|
||||||
|
nodeList = result["graph"];
|
||||||
|
app.$data.list.nl = nodeList;
|
||||||
|
$("#serviceName").val(result["name"]);
|
||||||
|
$("#serviceId").val(result["id"]);
|
||||||
|
$("#url").val(result["url"]);
|
||||||
|
$("#serviceDescription").val(result["desc"]);
|
||||||
|
refresh();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
refresh(); //新增服务
|
||||||
|
}
|
@ -8,20 +8,20 @@
|
|||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
<script src="bootstrap/js/bootstrap.js"></script>
|
<script src="bootstrap/js/bootstrap.js"></script>
|
||||||
<link rel="stylesheet" href="bootstrap/css/bootstrap.css"></link>
|
<link rel="stylesheet" href="bootstrap/css/bootstrap.css"></link>
|
||||||
<title>新服务</title>
|
<title>New Service</title>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div class="row" style="margin-top: 40px;">
|
<div class="row" style="margin-top: 40px;">
|
||||||
<div class="col-md-6" style="margin:0 auto" style="text-align: center;">
|
<div class="col-md-6" style="margin:0 auto" style="text-align: center;">
|
||||||
<h4 style="text-align: center;">新服务</h4>
|
<h4 style="text-align: center;">New Service</h4>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="exampleInputEmail1">输入要执行的网址(带http或https):</label>
|
<label for="exampleInputEmail1">URL(http or https):</label>
|
||||||
<textarea class="form-control" id="links" placeholder="links" style="min-height: 200px;">https://www.jd.com</textarea>
|
<textarea class="form-control" id="links" placeholder="links" style="min-height: 200px;">https://www.jd.com</textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button type="submit" id="send" class="btn btn-primary">开始包装</button>
|
<button type="submit" id="send" class="btn btn-primary">Start Wrapping</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
<script src="vue.js"></script>
|
<script src="vue.js"></script>
|
||||||
<link rel="stylesheet" href="bootstrap/css/bootstrap.css"></link>
|
<link rel="stylesheet" href="bootstrap/css/bootstrap.css"></link>
|
||||||
<title>服务信息</title>
|
<title>Service Information</title>
|
||||||
<style>
|
<style>
|
||||||
table {
|
table {
|
||||||
table-layout: auto;
|
table-layout: auto;
|
||||||
@ -35,20 +35,20 @@
|
|||||||
<body>
|
<body>
|
||||||
<div class="row" style="margin-top: 40px;">
|
<div class="row" style="margin-top: 40px;">
|
||||||
<div class="col-md-6" style="margin:0 auto" id="serviceList" v-if="show">
|
<div class="col-md-6" style="margin:0 auto" id="serviceList" v-if="show">
|
||||||
<h4 style="text-align: center;">服务信息</h4>
|
<h4 style="text-align: center;">Service Information</h4>
|
||||||
<p>服务名称:{{service["name"]}}</p>
|
<p>Service Name: {{service["name"]}}</p>
|
||||||
<p style="word-wrap: break-word;word-break: break-all;overflow: hidden;max-height: 100px;">服务描述:{{service["desc"]}}</p>
|
<p style="word-wrap: break-word;word-break: break-all;overflow: hidden;max-height: 100px;">Service Description: {{service["desc"]}}</p>
|
||||||
<p style="word-wrap: break-word;word-break: break-all;overflow: hidden;max-height: 100px;">服务示例URL:{{service["url"]}}</p>
|
<p style="word-wrap: break-word;word-break: break-all;overflow: hidden;max-height: 100px;">Example URL: {{service["url"]}}</p>
|
||||||
<p>输入参数:</p>
|
<p>Input Parameters:</p>
|
||||||
<table class="table table-bordered">
|
<table class="table table-bordered">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<th style="min-width: 50px;">ID</th>
|
<th style="min-width: 50px;">ID</th>
|
||||||
<th>参数名称</th>
|
<th>Parameter Name</th>
|
||||||
<th>调用名称</th>
|
<th>Invoke Name</th>
|
||||||
<th>参数类型</th>
|
<th>Parameter Type</th>
|
||||||
<th>示例值</th>
|
<th>Example Value</th>
|
||||||
<th>参数描述</th>
|
<th>Parameter Description</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr v-if="service.inputParameters.length>0" v-for="i in service.inputParameters.length">
|
<tr v-if="service.inputParameters.length>0" v-for="i in service.inputParameters.length">
|
||||||
<td style="min-width: 50px;">{{i}}</td>
|
<td style="min-width: 50px;">{{i}}</td>
|
||||||
@ -59,12 +59,12 @@
|
|||||||
<td>{{service.inputParameters[i-1]["desc"]}}</td>
|
<td>{{service.inputParameters[i-1]["desc"]}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr v-if="service.inputParameters.length==0">
|
<tr v-if="service.inputParameters.length==0">
|
||||||
<td>暂无</td>
|
<td>Empty</td>
|
||||||
<td>暂无</td>
|
<td>Empty</td>
|
||||||
<td>暂无</td>
|
<td>Empty</td>
|
||||||
<td>暂无</td>
|
<td>Empty</td>
|
||||||
<td>暂无</td>
|
<td>Empty</td>
|
||||||
<td>暂无</td>
|
<td>Empty</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@ -73,10 +73,10 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<th style="min-width: 50px;">ID</th>
|
<th style="min-width: 50px;">ID</th>
|
||||||
<th>参数名称</th>
|
<th>Parameter Name</th>
|
||||||
<th>参数类型</th>
|
<th>Parameter Type</th>
|
||||||
<th>示例值</th>
|
<th>Example Value</th>
|
||||||
<th>参数描述</th>
|
<th>Parameter Description</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr v-if="service.outputParameters.length>0" v-for="i in service.outputParameters.length">
|
<tr v-if="service.outputParameters.length>0" v-for="i in service.outputParameters.length">
|
||||||
<td style="min-width: 50px;">{{i}}</td>
|
<td style="min-width: 50px;">{{i}}</td>
|
||||||
@ -86,16 +86,16 @@
|
|||||||
<td>{{service.outputParameters[i-1]["desc"]}}</td>
|
<td>{{service.outputParameters[i-1]["desc"]}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr v-if="service.outputParameters.length==0">
|
<tr v-if="service.outputParameters.length==0">
|
||||||
<td style="min-width: 50px;">暂无</td>
|
<td style="min-width: 50px;">Empty</td>
|
||||||
<td>暂无</td>
|
<td>Empty</td>
|
||||||
<td>暂无</td>
|
<td>Empty</td>
|
||||||
<td>暂无</td>
|
<td>Empty</td>
|
||||||
<td>暂无</td>
|
<td>Empty</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<a style="margin-top: 5px;" href="javascript:void(0)" v-on:click="modifyService(service['id'],service['url'])" class="btn btn-primary">修改服务</a>
|
<a style="margin-top: 5px;" href="javascript:void(0)" v-on:click="modifyService(service['id'],service['url'])" class="btn btn-primary">Modify Service</a>
|
||||||
<a style="margin-top: 5px;" href="javascript:void(0)" v-on:click="invokeService(service['id'],service['url'])" class="btn btn-primary">调用服务</a>
|
<a style="margin-top: 5px;" href="javascript:void(0)" v-on:click="invokeService(service['id'],service['url'])" class="btn btn-primary">Invoke Service</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -107,7 +107,7 @@
|
|||||||
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象
|
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象
|
||||||
var r = window.location.search.substr(1).match(reg); //匹配目标参数
|
var r = window.location.search.substr(1).match(reg); //匹配目标参数
|
||||||
if (r != null) return unescape(r[2]);
|
if (r != null) return unescape(r[2]);
|
||||||
return null; //返回参数值
|
return ""; //返回参数值,默认后台地址
|
||||||
}
|
}
|
||||||
|
|
||||||
var sId = getUrlParam('id');
|
var sId = getUrlParam('id');
|
||||||
@ -116,6 +116,7 @@
|
|||||||
data: {
|
data: {
|
||||||
service: {},
|
service: {},
|
||||||
show: false, //是否渲染
|
show: false, //是否渲染
|
||||||
|
backEndAddressServiceWrapper: getUrlParam("backEndAddressServiceWrapper"),
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
modifyService: function(id, url) {
|
modifyService: function(id, url) {
|
||||||
@ -127,14 +128,14 @@
|
|||||||
};
|
};
|
||||||
// ws.send(JSON.stringify(message));
|
// ws.send(JSON.stringify(message));
|
||||||
// window.location.href = url; //跳转链接
|
// window.location.href = url; //跳转链接
|
||||||
window.location.href = "FlowChart.html?id=" + id;
|
window.location.href = "FlowChart.html?id=" + id + "&backEndAddressServiceWrapper="+ app.$data.backEndAddressServiceWrapper
|
||||||
},
|
},
|
||||||
invokeService: function(id) {
|
invokeService: function(id) {
|
||||||
window.location.href = "invokeService.html?id=" + id;
|
window.location.href = "invokeService.html?id=" + id + "&backEndAddressServiceWrapper="+ app.$data.backEndAddressServiceWrapper;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$.get("http://183.129.170.180:8041/backEnd/queryService?id=" + sId, function(result) {
|
$.get(app.$data.backEndAddressServiceWrapper + "/backEnd/queryService?id=" + sId, function(result) {
|
||||||
app.$data.service = result;
|
app.$data.service = result;
|
||||||
app.$data.show = true;
|
app.$data.show = true;
|
||||||
});
|
});
|
||||||
|
@ -8,22 +8,22 @@
|
|||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
<script src="vue.js"></script>
|
<script src="vue.js"></script>
|
||||||
<link rel="stylesheet" href="bootstrap/css/bootstrap.css"></link>
|
<link rel="stylesheet" href="bootstrap/css/bootstrap.css"></link>
|
||||||
<title>开始使用</title>
|
<title>Start</title>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div class="row" style="margin-top: 40px;">
|
<div class="row" style="margin-top: 40px;">
|
||||||
<div style="margin:0 auto;width: 60%;min-width: 500px;" id="serviceList">
|
<div style="margin:0 auto;width: 60%;min-width: 500px;" id="serviceList">
|
||||||
<h4 style="text-align: center;">服务列表</h4>
|
<h4 style="text-align: center;">Service List</h4>
|
||||||
<div style="max-height: 700px;overflow: auto;margin-bottom: 10px">
|
<div style="max-height: 700px;overflow: auto;margin-bottom: 10px">
|
||||||
<table style="table-layout: fixed;" class="table table-hover">
|
<table style="table-layout: fixed;" class="table table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>ID</th>
|
<th>ID</th>
|
||||||
<th>服务名称</th>
|
<th>Service Name</th>
|
||||||
<th>URL</th>
|
<th>URL</th>
|
||||||
<th v-bind:colspan="type">操作</th>
|
<th v-bind:colspan="type">Operations</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@ -31,14 +31,14 @@
|
|||||||
<td>{{i}}</td>
|
<td>{{i}}</td>
|
||||||
<td style="overflow: hidden;">{{list[i-1]["name"]}}</td>
|
<td style="overflow: hidden;">{{list[i-1]["name"]}}</td>
|
||||||
<td style="height: 30px;white-space: nowrap;overflow: hidden;">{{list[i-1]["url"]}}</td>
|
<td style="height: 30px;white-space: nowrap;overflow: hidden;">{{list[i-1]["url"]}}</td>
|
||||||
<td><a href="javascript:void(0)" v-on:click="browseService(list[i-1]['id'])">查看服务信息</a></td>
|
<td><a href="javascript:void(0)" v-on:click="browseService(list[i-1]['id'])">Service Information</a></td>
|
||||||
<td v-if="type==3"><a href="javascript:void(0)" v-on:click="modifyService(list[i-1]['id'],list[i-1]['url'])">修改服务</a></td>
|
<td v-if="type==3"><a href="javascript:void(0)" v-on:click="modifyService(list[i-1]['id'],list[i-1]['url'])">Modify Service</a></td>
|
||||||
<td><a href="javascript:void(0)" v-on:click="deleteService(list[i-1]['id'])">删除服务</a></td>
|
<td><a href="javascript:void(0)" v-on:click="deleteService(list[i-1]['id'])">Delete Service</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<a v-if="type==3" href="newService.html" class="btn btn-primary">新服务</a>
|
<a v-if="type==3" href="javascript:void(0)" v-on:click="newService" class="btn btn-primary">New Service</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -50,7 +50,7 @@
|
|||||||
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象
|
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象
|
||||||
var r = window.location.search.substr(1).match(reg); //匹配目标参数
|
var r = window.location.search.substr(1).match(reg); //匹配目标参数
|
||||||
if (r != null) return unescape(r[2]);
|
if (r != null) return unescape(r[2]);
|
||||||
return null; //返回参数值
|
return ""; //返回参数值,默认后台地址
|
||||||
}
|
}
|
||||||
|
|
||||||
var app = new Vue({
|
var app = new Vue({
|
||||||
@ -58,8 +58,12 @@
|
|||||||
data: {
|
data: {
|
||||||
list: [],
|
list: [],
|
||||||
type: 3, //记录服务行为
|
type: 3, //记录服务行为
|
||||||
|
backEndAddressServiceWrapper: getUrlParam("backEndAddressServiceWrapper"),
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
newService: function (){
|
||||||
|
window.location.href = "newService.html?backEndAddressServiceWrapper="+ app.$data.backEndAddressServiceWrapper;;
|
||||||
|
},
|
||||||
modifyService: function(id, url) {
|
modifyService: function(id, url) {
|
||||||
let message = { //显示flowchart
|
let message = { //显示flowchart
|
||||||
type: 1, //消息类型,传递链接
|
type: 1, //消息类型,传递链接
|
||||||
@ -71,12 +75,12 @@
|
|||||||
window.location.href = url; //跳转链接
|
window.location.href = url; //跳转链接
|
||||||
},
|
},
|
||||||
browseService: function(id) {
|
browseService: function(id) {
|
||||||
window.location.href = "serviceInfo.html?id=" + id; //跳转链接
|
window.location.href = "serviceInfo.html?id=" + id + "&backEndAddressServiceWrapper="+ app.$data.backEndAddressServiceWrapper; //跳转链接
|
||||||
},
|
},
|
||||||
deleteService: function(id) {
|
deleteService: function(id) {
|
||||||
if (confirm("确定要删除服务吗?")) {
|
if (confirm("确定要删除服务吗?")) {
|
||||||
$.get("http://183.129.170.180:8041/backEnd/deleteService?id=" + id, function(res) {
|
$.get(app.$data.backEndAddressServiceWrapper + "/backEnd/deleteService?id=" + id, function(res) {
|
||||||
$.get("http://183.129.170.180:8041/backEnd/queryServices", function(re) {
|
$.get(app.$data.backEndAddressServiceWrapper + "/backEnd/queryServices", function(re) {
|
||||||
result = re.sort(desc);
|
result = re.sort(desc);
|
||||||
app.$data.list = result;
|
app.$data.list = result;
|
||||||
});
|
});
|
||||||
@ -90,7 +94,7 @@
|
|||||||
var desc = function(x, y) {
|
var desc = function(x, y) {
|
||||||
return (x["id"] < y["id"]) ? 1 : -1
|
return (x["id"] < y["id"]) ? 1 : -1
|
||||||
}
|
}
|
||||||
$.get("http://183.129.170.180:8041/backEnd/queryServices", function(re) {
|
$.get(app.$data.backEndAddressServiceWrapper + "/backEnd/queryServices", function(re) {
|
||||||
result = re.sort(desc);
|
result = re.sort(desc);
|
||||||
app.$data.list = result;
|
app.$data.list = result;
|
||||||
if (getUrlParam("type") == "1") {
|
if (getUrlParam("type") == "1") {
|
||||||
|
1
ServiceGrid/static/.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
ServiceWrapper.7z filter=lfs diff=lfs merge=lfs -text
|
2
ServiceWrapperEntry/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
.vs
|
||||||
|
packages
|
11
ServiceWrapperEntry/Readme.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# 客户端开发编译方式
|
||||||
|
|
||||||
|
0. 安装VS2019或以上版本,勾选windows应用程序开发(.Net Framework 4.7.2版本及以上)。
|
||||||
|
|
||||||
|
1. 拷贝客户端(可执行程序)servicewrapper文件夹内所有文件到\ServiceWrapperEntry\bin\x64\Debug文件夹(包括Chrome文件夹)
|
||||||
|
|
||||||
|
2. 打开sln文件,右键点击解决方案,点击“清理解决方案”后,再点击“还原Nuget包”。
|
||||||
|
|
||||||
|
3. 右键点击项目,点击“清理”后,再点击“重新生成项目”。
|
||||||
|
|
||||||
|
4. 编译即成功。
|
25
ServiceWrapperEntry/ServiceWrapperEntry.sln
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 16
|
||||||
|
VisualStudioVersion = 16.0.29728.190
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceWrapperEntry", "ServiceWrapperEntry\ServiceWrapperEntry.csproj", "{8FF781CB-5C33-4C3F-872D-1FE0E114A8D0}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{8FF781CB-5C33-4C3F-872D-1FE0E114A8D0}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{8FF781CB-5C33-4C3F-872D-1FE0E114A8D0}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{8FF781CB-5C33-4C3F-872D-1FE0E114A8D0}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{8FF781CB-5C33-4C3F-872D-1FE0E114A8D0}.Release|x64.Build.0 = Release|x64
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {F3EC44B3-E8DF-40FA-ABEB-9F5BAC89A723}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
1
ServiceWrapperEntry/ServiceWrapperEntry/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
obj/*
|
6
ServiceWrapperEntry/ServiceWrapperEntry/App.config
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<configuration>
|
||||||
|
<startup>
|
||||||
|
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
|
||||||
|
</startup>
|
||||||
|
</configuration>
|
174
ServiceWrapperEntry/ServiceWrapperEntry/Class1.cs
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
using CefSharp;
|
||||||
|
using CefSharp.Internals;
|
||||||
|
using CefSharp.Web;
|
||||||
|
using CefSharp.WinForms;
|
||||||
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace ServiceWrapper
|
||||||
|
{
|
||||||
|
public class MouseHelper
|
||||||
|
{
|
||||||
|
[System.Runtime.InteropServices.DllImport("user32")]
|
||||||
|
public static extern int mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);
|
||||||
|
//移动鼠标
|
||||||
|
public const int MOUSEEVENTF_MOVE = 0x0001;
|
||||||
|
//模拟鼠标左键按下
|
||||||
|
public const int MOUSEEVENTF_LEFTDOWN = 0x0002;
|
||||||
|
//模拟鼠标左键抬起
|
||||||
|
public const int MOUSEEVENTF_LEFTUP = 0x0004;
|
||||||
|
//模拟鼠标右键按下
|
||||||
|
public const int MOUSEEVENTF_RIGHTDOWN = 0x0008;
|
||||||
|
//模拟鼠标右键抬起
|
||||||
|
public const int MOUSEEVENTF_RIGHTUP = 0x0010;
|
||||||
|
//模拟鼠标中键按下
|
||||||
|
public const int MOUSEEVENTF_MIDDLEDOWN = 0x0020;
|
||||||
|
//模拟鼠标中键抬起
|
||||||
|
public const int MOUSEEVENTF_MIDDLEUP = 0x0040;
|
||||||
|
//标示是否采用绝对坐标
|
||||||
|
public const int MOUSEEVENTF_ABSOLUTE = 0x8000;
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern bool SetCursorPos(int X, int Y);
|
||||||
|
}
|
||||||
|
public class Parameters
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public string url { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Data
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public int option { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public Parameters parameters { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class FlowMessage
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public int type { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public Data data { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Message
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public int id { get; set; }
|
||||||
|
public string links { get; set; }
|
||||||
|
public string link { get; set; }
|
||||||
|
//键盘输入的值
|
||||||
|
public string keyboardStr { get; set; }
|
||||||
|
//直接转接流程图的消息
|
||||||
|
public string pipe { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class Msg
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public int type { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 从哪里来
|
||||||
|
/// </summary>
|
||||||
|
public int from { get; set; }
|
||||||
|
public Message message { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RequestContextHandler : IRequestContextHandler
|
||||||
|
{
|
||||||
|
public IResourceRequestHandler GetResourceRequestHandler(IBrowser browser, IFrame frame, IRequest request, bool isNavigation, bool isDownload, string requestInitiator, ref bool disableDefaultHandling)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool OnBeforePluginLoad(string mimeType, string url, bool isMainFrame, string topOriginUrl, WebPluginInfo pluginInfo, ref PluginPolicy pluginPolicy)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnRequestContextInitialized(IRequestContext requestContext)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//加载窗口时的事件设置
|
||||||
|
public class RenderProcessMessageHandler : IRenderProcessMessageHandler
|
||||||
|
{
|
||||||
|
public void OnContextReleased(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame)
|
||||||
|
{
|
||||||
|
//throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnFocusedNodeChanged(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IDomNode node)
|
||||||
|
{
|
||||||
|
//throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnUncaughtException(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, JavascriptException exception)
|
||||||
|
{
|
||||||
|
//throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for the underlying JavaScript Context to be created. This is only called for the main frame.
|
||||||
|
// If the page has no JavaScript, no context will be created.
|
||||||
|
void IRenderProcessMessageHandler.OnContextCreated(IWebBrowser browserControl, IBrowser browser, IFrame frame)
|
||||||
|
{
|
||||||
|
//MessageBox.Show("zhixing");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 在自己窗口打开链接
|
||||||
|
/// </summary>
|
||||||
|
internal class OpenPageSelf : ILifeSpanHandler
|
||||||
|
{
|
||||||
|
public bool DoClose(IWebBrowser browserControl, IBrowser browser)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnAfterCreated(IWebBrowser browserControl, IBrowser browser)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnBeforeClose(IWebBrowser browserControl, IBrowser browser)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool OnBeforePopup(IWebBrowser browserControl, IBrowser browser, IFrame frame, string targetUrl,
|
||||||
|
string targetFrameName, WindowOpenDisposition targetDisposition, bool userGesture, IPopupFeatures popupFeatures,
|
||||||
|
IWindowInfo windowInfo, IBrowserSettings browserSettings, ref bool noJavascriptAccess, out IWebBrowser newBrowser)
|
||||||
|
{
|
||||||
|
newBrowser = null;
|
||||||
|
var chromiumWebBrowser = (ChromiumWebBrowser)browserControl;
|
||||||
|
chromiumWebBrowser.Load(targetUrl);
|
||||||
|
return true; //Return true to cancel the popup creation copyright by codebye.com.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
88
ServiceWrapperEntry/ServiceWrapperEntry/Flow.Designer.cs
generated
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
namespace ServiceWrapper
|
||||||
|
{
|
||||||
|
partial class Flow
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 必需的设计器变量。
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清理所有正在使用的资源。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows 窗体设计器生成的代码
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设计器支持所需的方法 - 不要修改
|
||||||
|
/// 使用代码编辑器修改此方法的内容。
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Flow));
|
||||||
|
this.panel1 = new System.Windows.Forms.Panel();
|
||||||
|
this.button1 = new System.Windows.Forms.Button();
|
||||||
|
this.SuspendLayout();
|
||||||
|
//
|
||||||
|
// panel1
|
||||||
|
//
|
||||||
|
this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||||
|
| System.Windows.Forms.AnchorStyles.Left)
|
||||||
|
| System.Windows.Forms.AnchorStyles.Right)));
|
||||||
|
this.panel1.AutoSize = true;
|
||||||
|
this.panel1.Location = new System.Drawing.Point(4, 6);
|
||||||
|
this.panel1.Margin = new System.Windows.Forms.Padding(6);
|
||||||
|
this.panel1.Name = "panel1";
|
||||||
|
this.panel1.Size = new System.Drawing.Size(1846, 1352);
|
||||||
|
this.panel1.TabIndex = 0;
|
||||||
|
//
|
||||||
|
// button1
|
||||||
|
//
|
||||||
|
this.button1.AutoSize = true;
|
||||||
|
this.button1.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||||
|
this.button1.Font = new System.Drawing.Font("宋体", 16.125F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
|
||||||
|
this.button1.Location = new System.Drawing.Point(0, 1373);
|
||||||
|
this.button1.Name = "button1";
|
||||||
|
this.button1.Size = new System.Drawing.Size(1862, 53);
|
||||||
|
this.button1.TabIndex = 1;
|
||||||
|
this.button1.Text = "←";
|
||||||
|
this.button1.UseVisualStyleBackColor = true;
|
||||||
|
this.button1.Visible = false;
|
||||||
|
this.button1.Click += new System.EventHandler(this.button1_Click);
|
||||||
|
//
|
||||||
|
// Flow
|
||||||
|
//
|
||||||
|
this.AutoScaleDimensions = new System.Drawing.SizeF(12F, 24F);
|
||||||
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
|
this.ClientSize = new System.Drawing.Size(1862, 1426);
|
||||||
|
this.Controls.Add(this.button1);
|
||||||
|
this.Controls.Add(this.panel1);
|
||||||
|
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||||
|
this.Margin = new System.Windows.Forms.Padding(6);
|
||||||
|
this.Name = "Flow";
|
||||||
|
this.Text = "服务包装手动版";
|
||||||
|
this.Load += new System.EventHandler(this.Flow_Load);
|
||||||
|
this.ResumeLayout(false);
|
||||||
|
this.PerformLayout();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private System.Windows.Forms.Panel panel1;
|
||||||
|
private System.Windows.Forms.Button button1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
119
ServiceWrapperEntry/ServiceWrapperEntry/Flow.cs
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Data;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using CefSharp;
|
||||||
|
using CefSharp.WinForms;
|
||||||
|
using System.Runtime.InteropServices; //引用此名称空间,简化后面的代码
|
||||||
|
using System.Net;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace ServiceWrapper
|
||||||
|
{
|
||||||
|
|
||||||
|
public partial class Flow : Form, IMessageFilter
|
||||||
|
{
|
||||||
|
public ChromiumWebBrowser chromeBrowser;
|
||||||
|
public bool ChromeNow = false; //标记现在所在窗口是否为chrome
|
||||||
|
public static string flowChartUrl = PublicVariable.frontEndAddress + "/FlowChart.html?id="; //流程图所在的位置
|
||||||
|
public string url = flowChartUrl + "-1&backEndAddressServiceWrapper=" + PublicVariable.backEndAddress;
|
||||||
|
public Flow()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
public Flow(string link)
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
url = link;
|
||||||
|
button1.Show();
|
||||||
|
}
|
||||||
|
// P/Invoke declarations
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern IntPtr GetForegroundWindow();
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
private extern static bool SwapMouseButton(bool fSwap);
|
||||||
|
[System.Runtime.InteropServices.DllImport("user32.dll")]
|
||||||
|
public static extern int SetForegroundWindow(IntPtr hwnd);
|
||||||
|
public const int WM_CLOSE = 0x10;
|
||||||
|
public bool closedriver = true;
|
||||||
|
[DllImport("user32.dll", EntryPoint = "SendMessage")]
|
||||||
|
private static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
|
||||||
|
|
||||||
|
public bool PreFilterMessage(ref System.Windows.Forms.Message SystemMessage)
|
||||||
|
{
|
||||||
|
if (SystemMessage.Msg >= 513 && SystemMessage.Msg <= 515)
|
||||||
|
{//不响应鼠标左键消息
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
private void Flow_Load(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
InitializeChromium();
|
||||||
|
PublicVariable.isInitialized = true;
|
||||||
|
//保证并排平铺
|
||||||
|
int width = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Size.Width;
|
||||||
|
int height = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Size.Height;
|
||||||
|
StartPosition = FormStartPosition.Manual; //窗体的位置由Location属性决定
|
||||||
|
Location = (Point)new Size(0, 0); //窗体的起始位置为(x,y)
|
||||||
|
Width = width;
|
||||||
|
Height = Convert.ToInt32(height * 0.8);
|
||||||
|
FormClosing += Flow_FormClosing;
|
||||||
|
}
|
||||||
|
|
||||||
|
//初始化浏览器并启动
|
||||||
|
public void InitializeChromium()
|
||||||
|
{
|
||||||
|
if (!PublicVariable.isInitialized)//只初始化一次
|
||||||
|
{
|
||||||
|
CefSettings settings = new CefSettings();
|
||||||
|
Cef.Initialize(settings);
|
||||||
|
}
|
||||||
|
// Create a browser component
|
||||||
|
chromeBrowser = new ChromiumWebBrowser(url);
|
||||||
|
//跨域访问允许
|
||||||
|
chromeBrowser.BrowserSettings.FileAccessFromFileUrls = CefState.Enabled;
|
||||||
|
chromeBrowser.BrowserSettings.UniversalAccessFromFileUrls = CefState.Enabled;
|
||||||
|
//textBox1.Text = url;
|
||||||
|
// Add it to the form and fill it to the form window.
|
||||||
|
panel1.Controls.Add(chromeBrowser);
|
||||||
|
chromeBrowser.Dock = DockStyle.Fill;
|
||||||
|
chromeBrowser.RenderProcessMessageHandler = new RenderProcessMessageHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
//窗体关闭时,记得停止浏览器
|
||||||
|
private void Flow_FormClosing(object sender, FormClosingEventArgs e)
|
||||||
|
{
|
||||||
|
if(closedriver)
|
||||||
|
{
|
||||||
|
//Cef.Shutdown();//关掉内嵌控件
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//PublicVariable.chrome.Kill();//关掉chrome
|
||||||
|
//SendMessage(Start.chromeId, WM_CLOSE, 0, 0);//关掉chrome
|
||||||
|
Start.browser.Quit();//关掉chromedriver
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PublicVariable.start.Show(); //重新显示初始框
|
||||||
|
}
|
||||||
|
|
||||||
|
private void panel1_Paint(object sender, PaintEventArgs e)
|
||||||
|
{
|
||||||
|
SetForegroundWindow(Start.chromeId); //打开流程图窗口后将chrome窗口显示到最前方
|
||||||
|
}
|
||||||
|
|
||||||
|
private void button1_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
chromeBrowser.Back();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
408
ServiceWrapperEntry/ServiceWrapperEntry/Flow.resx
Normal file
@ -0,0 +1,408 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||||
|
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>
|
||||||
|
AAABAAEAQEAAAAEAIAAoQgAAFgAAACgAAABAAAAAgAAAAAEAIAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAD/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////7+/v/+/v7//v7+///////+/v7//v7+////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////////////////////////////////////v7+//7+/v/+/v7/////////
|
||||||
|
/////////////////////////v7+//7+/v//////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////////////////////////////////////7+
|
||||||
|
/v/+/v7//v7+///////+/v7//v7+//////////////////7+/v/+/v7//v7+////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////+/v7//v7+/////////////v7+//7+/v/+/v7////////////+/v7//v7+//7+
|
||||||
|
/v//////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////v7+////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////+/v7//v7+////
|
||||||
|
/////////v7+//7+/v//////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////7+/v//////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/////////v7+//7+/v//////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////v7+//7+/v/+/v7////////////////////////////+/v7/+vr6/5eX
|
||||||
|
l/+YmJj/+vr6//7+/v//////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////7+/v/+/v7/////////////////////////
|
||||||
|
///9/f3/4uLi/0lJSf8AAAD/AAAA/0lJSf/j4+P//f39////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////9/f3/ubm5/xkZGf8BAQH/AAAA/wAAAP8BAQH/GRkZ/7m5uf/+/v7//v7+////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////9/f3/kpKS/wYGBv8AAAD/AAAA/wAAAP8AAAD/AAAA/wEB
|
||||||
|
Af8GBgb/kpKS//7+/v/+/v7/////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////9/f3/hoaG/wICAv8AAAD/AAAA/wAA
|
||||||
|
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wICAv+FhYX//f39////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////////////////////7+/v/+/v7/q6ur/wQE
|
||||||
|
BP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AgIC/6ysrP/+/v7/////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///+/v7/9PT0/x8fH/8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wEB
|
||||||
|
Af8dHR3/9fX1////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////v7+/7W1tf8AAAD/AAAA/wICAv8aGhr/AwMD/wAAAP8AAAD/AAAA/wAA
|
||||||
|
AP8EBAT/Ghoa/wICAv8AAAD/AAAA/7a2tv//////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////7+/v+RkZH/AAAA/wAAAP8gICD/+/v7/9fX
|
||||||
|
1/9UVFT/AgIC/wICAv9VVVX/2NjY//v7+/8fHx//AAAA/wAAAP+SkpL/////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////+/v7/mpqa/wAA
|
||||||
|
AP8AAAD/Nzc3//7+/v/+/v7/ysrK/8TExP/Dw8P/ycnJ//7+/v/9/f3/ODg4/wAAAP8AAAD/mpqa////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/////////v7+/8PDw/8AAAD/AAAA/zU1Nf/+/v7//v7+/83Nzf+Wlpb/lpaW/87Ozv/+/v7//f39/zU1
|
||||||
|
Nf8AAAD/AAAA/8PDw///////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////7+/v/19fX/EBAQ/wAAAP8YGBj/4uLi/6mpqf8tLS3/AgIC/wEB
|
||||||
|
Af8tLS3/qqqq/+Hh4f8YGBj/AAAA/xAQEP/19fX/////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////////////////////v7+//7+/v/+/v7//v7+/1lZWf8AAAD/AQEB/wMD
|
||||||
|
A/8DAwP/Li4u/2xsbP9vb2//NDQ0/wICAv8DAwP/AAAA/wAAAP9ZWVn//f39////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////////////////////7+/v/+/v7/////////
|
||||||
|
//+0tLT/AAAA/wAAAP8JCQn/np6e/+/v7/+1tbX/srKy/+7u7v+qqqr/DAwM/wAAAP8BAQH/tLS0////
|
||||||
|
//////////////7+/v/+/v7/////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///+/v7//v7+////////////+Pj4/x4eHv8CAgL/mJiY/8XFxf8fHx//AQEB/wAAAP8aGhr/vr6+/6Wl
|
||||||
|
pf8BAQH/HR0d//j4+P/////////////////+/v7//v7+////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////7+/v99fX3/LS0t/+bm5v8YGBj/AAAA/wAA
|
||||||
|
AP8AAAD/AAAA/xQUFP/j4+P/MjIy/319ff/9/f3/////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////+/v7/3t7e/4GB
|
||||||
|
gf+BgYH/AQEB/wAAAP8AAAD/AAAA/wAAAP8AAAD/enp6/4WFhf/e3t7//v7+////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////39/f/n5+f/MzMz/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/zIyMv/o6Oj//f39////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////+/v7//v7+////
|
||||||
|
///////////////////////////////////+/v7/7+/v/wcHB/8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
|
||||||
|
AP8HBwf/8fHx//7+/v//////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/////////v7+//7+/v///////////////////////////////////////f39/9jY2P+IiIj/fX19/zEx
|
||||||
|
Mf8ICAj/CAgI/y4uLv99fX3/iIiI/9nZ2f/+/v7/////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////////////////////////////////////Hx
|
||||||
|
8f9mZmb/KSkp/zY2Nv+ioqL/QUFB/z09Pf+kpKT/PDw8/ygoKP9oaGj/8fHx//7+/v//////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///+/v7//v7+//7+/v+CgoL/BwcH/wcHB/8BAQH/DQ0N/7Gxsf+rq6v/Dg4O/wEBAf8GBgb/BwcH/4OD
|
||||||
|
g//9/f3//v7+////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///+/v7//v7+//7+/v/+/v7//v7+//j4+P/29vb/LCws/wcHB/8HBwf/AAAA/wMDA/9lZWX/Y2Nj/wAA
|
||||||
|
AP8AAAD/BgYG/wcHB/8sLCz/9fX1//f39//+/v7//v7+//7+/v/+/v7//v7+////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////v7+//Pz8//X19f/vr6+/4iIiP8yMjL/srKy/wEBAf8GBgb/BAQE/wEB
|
||||||
|
Af8nJyf/aGho/2FhYf8lJSX/AQEB/wcHB/8HBwf/AQEB/7Kysv80NDT/iIiI/729vf/X19f/8vLy//7+
|
||||||
|
/v//////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////6Ojo/1RUVP8FBQX/AAAA/wAAAP8AAAD/AgIC/6Cg
|
||||||
|
oP/V1dX/rq6u/62trf+rq6v/ioqK/05OTv9QUFD/kJCQ/7CwsP+pqan/rq6u/9XV1f+fn5//AwMD/wAA
|
||||||
|
AP8AAAD/AAAA/wYGBv9UVFT/6enp//7+/v//////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////+vr6/z8/P/8BAQH/AAAA/wAA
|
||||||
|
AP8AAAD/AAAA/wcHB/+vr6//+fn5/xQUFP8ICAj/CAgI/wcHB/8JCQn/CAgI/wcHB/8HBwf/CAgI/xQU
|
||||||
|
FP/4+Pj/sLCw/wYGBv8AAAD/AAAA/wAAAP8AAAD/AAAA/0BAQP/6+vr/////////////////////////
|
||||||
|
/////////////////////////v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////+/v7//v7+/6am
|
||||||
|
pv8AAAD/AAAA/wAAAP8AAAD/AAAA/wEBAf+Li4v//v7+//z8/P++vr7/v7+//4ODg/95eXn/2NjY/9LS
|
||||||
|
0v9ycnL/eXl5/8DAwP+9vb3//Pz8//39/f+Li4v/AQEB/wAAAP8AAAD/AAAA/wAAAP8AAAD/p6en//7+
|
||||||
|
/v////////////////////////////////////////////7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+
|
||||||
|
/v//////////////////////////////////////////////////////////////////////////////
|
||||||
|
/////////v7+//z8/P86Ojr/AAAA/wAAAP8AAAD/AAAA/wEBAf9QUFD/+/v7//7+/v/q6ur/GBgY/wkJ
|
||||||
|
Cf+ampr//f39//7+/v/+/v7//f39/5mZmf8ICAj/GBgY/+vr6//+/v7/+vr6/09PT/8BAQH/AAAA/wAA
|
||||||
|
AP8AAAD/AAAA/zo6Ov/8/Pz/////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////7+/v/c3Nz/BQUF/wAAAP8AAAD/AAAA/wgICP9nZ2f/8vLy//7+
|
||||||
|
/v/+/v7/pqam/wAAAP8BAQH/m5ub//7+/v////////////////+ampr/AAAA/wEBAf+mpqb//v7+//7+
|
||||||
|
/v/y8vL/Z2dn/wgICP8BAQH/AAAA/wAAAP8EBAT/3Nzc////////////////////////////////////
|
||||||
|
///////////////////////////////////+/v7//v7+////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////+/v7/+fn5/93d3f/Gxsb/vLy8/8nJ
|
||||||
|
yf/v7+///f39//7+/v///////f39/0RERP8AAAD/AgIC/+Dg4P//////////////////////39/f/wEB
|
||||||
|
Af8AAAD/Q0ND//39/f/+/v7//v7+//39/f/v7+//ycnJ/729vf/Gxsb/3Nzc//n5+f//////////////
|
||||||
|
/////////////////////////////////////////////////////////v7+//7+/v//////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////+/v7//v7+/7y8vP8BAQH/AAAA/zMzM//9/f3/////////
|
||||||
|
//////////////39/f80NDT/AAAA/wICAv+8vLz//v7+////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////7+/v/+/v7//v7+/+jo6P8lJSX/AAAA/wEB
|
||||||
|
Af+Dg4P//v7+///////////////////////+/v7/g4OD/wEBAf8AAAD/JCQk/+rq6v/+/v7/////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////+/v7//f39/+np
|
||||||
|
6f89PT3/AAAA/wAAAP8AAAD/y8vL//7+/v///////////////////////////8vLy/8AAAD/AAAA/wAA
|
||||||
|
AP86Ojr/6enp////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///+/v7//f39/8jIyP8oKCj/AAAA/wEBAf8sLCz/DQ0N//j4+P/+/v7//v7+//7+/v//////////////
|
||||||
|
///39/f/Dg4O/ywsLP8CAgL/AAAA/ykpKf/IyMj//v7+//7+/v////////////7+/v/+/v7/////////
|
||||||
|
//////////////////////////////////////////////////////////////7+/v/+/v7/////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////7+/v/9/f3/5+fn/29vb/8HBwf/AAAA/wEBAf9NTU3/2NjY/ysrK//+/v7///////7+
|
||||||
|
/v/+/v7//////////////////f39/ysrK//Y2Nj/TU1N/wEBAf8AAAD/BgYG/25ubv/o6Oj//f39//7+
|
||||||
|
/v/+/v7//v7+/////////////v7+//7+/v/+/v7//v7+/////////////v7+//7+/v/+/v7/////////
|
||||||
|
///+/v7//v7+//7+/v//////////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////39/f/q6ur/fHx8/xAQEP8BAQH/AgIC/xISEv8qKir/9vb2//T0
|
||||||
|
9P86Ojr//v7+///////+/v7//v7+//////////////////39/f85OTn/8/Pz//X19f8qKir/ExMT/wEB
|
||||||
|
Af8AAAD/EBAQ/3x8fP/q6ur//v7+//7+/v////////////7+/v/+/v7//v7+//7+/v////////////7+
|
||||||
|
/v/+/v7//v7+//////////////////7+/v/+/v7/////////////////////////////////////////
|
||||||
|
///////////////////////////////////+/v7//f39//Ly8v+CgoL/EhIS/wICAv8BAQH/CAgI/62t
|
||||||
|
rf+rq6v/cXFx//7+/v/9/f3/QUFB//39/f/+/v7////////////////////////////9/f3/QUFB//39
|
||||||
|
/f/+/v7/cXFx/6urq/+tra3/CAgI/wEBAf8CAgL/ExMT/4KCgv/x8fH//f39////////////////////
|
||||||
|
///////////////////+/v7//v7+//7+/v//////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////+/v7//f39/7S0tP8iIiL/AQEB/y4u
|
||||||
|
Lv9mZmb/AgIC/2ZmZv/9/f3/3t7e/7a2tv/+/v7//f39/4uLi//8/Pz//v7+////////////////////
|
||||||
|
/////////Pz8/4uLi//9/f3//v7+/7e3t//e3t7//f39/2ZmZv8CAgL/ZmZm/y4uLv8CAgL/IiIi/7Oz
|
||||||
|
s//9/f3//v7+//7+/v///////////////////////v7+//7+/v/+/v7/////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////+/v7/+vr6/3t7
|
||||||
|
e/8FBQX/ExMT/6Kiov/5+fn/ZWVl/wQEBP/U1NT//v7+//7+/v/+/v7//v7+//7+/v/9/f3//f39////
|
||||||
|
//////////////////////////////7+/v/9/f3//v7+//7+/v/+/v7//v7+///////U1NT/BAQE/2Vl
|
||||||
|
Zf/5+fn/oqKi/xISEv8FBQX/enp6//r6+v/+/v7//v7+////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///+/v7/+/v7/2xsbP8CAgL/BQUF/8HBwf/9/f3/9/f3/xYWFv83Nzf//f39////////////////////
|
||||||
|
///+/v7//v7+////////////////////////////////////////////////////////////////////
|
||||||
|
/////////Pz8/zg4OP8YGBj/+Pj4//7+/v/BwcH/BwcH/wMDA/9sbGz//Pz8//7+/v//////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////f39/5WVlf8RERH/YWFh/1JSUv/+/v7//v7+/9LS0v8BAQH/fn5+//39
|
||||||
|
/f//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////////9+fn7/AgIC/9LS0v///////v7+/1NTU/9iYmL/ExMT/5SU
|
||||||
|
lP/9/f3///////////////////////////////////////////////////////////////////////7+
|
||||||
|
/v/+/v7//v7+/////////////////////////////////9/f3/8VFRX/vLy8/5aWlv+Ojo7//v7+//7+
|
||||||
|
/v+qqqr/AQEB/6qqqv/+/v7/////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////qamp/wEBAf+rq6v///////7+
|
||||||
|
/v+Ojo7/lpaW/7y8vP8WFhb/39/f//39/f//////////////////////////////////////////////
|
||||||
|
//////////////7+/v/+/v7//v7+//7+/v////////////////////////////39/f9oaGj/dnZ2//z8
|
||||||
|
/P+cnJz/n5+f////////////lZWV/wAAAP+4uLj/////////////////////////////////////////
|
||||||
|
/////////////////////////////////////////////////////////////////////////////7e3
|
||||||
|
t/8AAAD/lpaW///////+/v7/n5+f/5ycnP/9/f3/dnZ2/2hoaP/9/f3/////////////////////////
|
||||||
|
///////////////////////////////////+/v7//v7+//7+/v/+/v7/////////////////////////
|
||||||
|
///9/f3/Xl5e/+rq6v/+/v7/sbGx/5eXl////////////5OTk/8BAQH/oKCg//39/f//////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////////+hoaH/AQEB/5OTk//+/v7//v7+/5aWlv+wsLD//v7+/+np6f9eXl7//f39////
|
||||||
|
///////////////////////////////////////////////////+/v7//v7+//7+/v//////////////
|
||||||
|
/////////////////////////v7+//39/f/9/f3//v7+/+3t7f/Z2dn///////////+enp7/Hh4e/11d
|
||||||
|
Xf/9/f3///////7+/v/+/v7//v7+////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////9/f3/XV1d/x4eHv+fn5///v7+//7+/v/Z2dn/7e3t//7+
|
||||||
|
/v/+/v7//f39//7+/v///////////////////////////////////////////////////////v7+//7+
|
||||||
|
/v/+/v7//v7+//7+/v/+/v7////////////////////////////////////////////+/v7//v7+////
|
||||||
|
////////t7e3/3R0dP9LS0v/0dHR//7+/v/+/v7//v7+//7+/v//////////////////////////////
|
||||||
|
//////////////////////////////////////////////7+/v/+/v7/0dHR/0tLS/9zc3P/t7e3////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////7+/v/+/v7//v7+//7+/v/+/v7//v7+////////////////////////////////////
|
||||||
|
/////////////////////////////9ra2v9ra2v/5+fn/1RUVP/c3Nz//v7+////////////////////
|
||||||
|
//////////////////////////////////////////////////////////////7+/v/9/f3/3Nzc/1RU
|
||||||
|
VP/o6Oj/a2tr/9ra2v//////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////+/v7//v7+//7+/v/+/v7//v7+////////////////////
|
||||||
|
///////////////////////////////////////////////////4+Pj/XV1d//z8/P/r6+v/bGxs/9HR
|
||||||
|
0f//////////////////////////////////////////////////////////////////////////////
|
||||||
|
///+/v7/0dHR/2tra//r6+v//f39/1xcXP/4+Pj/////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////+/v7//v7+//7+
|
||||||
|
/v///////////////////////////////////////////////////////////////////////v7+/19f
|
||||||
|
X//8/Pz///////7+/v/8/Pz/////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////v7+//z8/P/8/Pz//v7+//v7+/9gYGD//f39////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/////////v7+//7+/v/+/v7///////////////////////////////////////7+/v/+/v7//v7+////
|
||||||
|
//////////////7+/v+4uLj/+fn5///////+/v7//v7+////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////+/v7//v7+//7+/v/5+fn/t7e3//39
|
||||||
|
/f//////////////////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////////////////////////////////////v7+//7+/v/+/v7//v7+//7+
|
||||||
|
/v/+/v7//v7+//7+/v/////////////////+/v7//v7+//7+/v//////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/////////v7+//7+/v/+/v7/////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////////////////////////////////////7+
|
||||||
|
/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v//////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////+/v7//v7+//7+/v/+/v7//v7+//7+
|
||||||
|
/v/+/v7/////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/////////v7+//7+/v/+/v7/////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////7+/v/+/v7//v7+//7+/v/+/v7//v7+////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///+/v7//v7+////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////+/v7//v7+//7+/v/+/v7/////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////v7+//7+/v//////////////////////////////////////////////
|
||||||
|
////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
|
||||||
|
</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
99
ServiceWrapperEntry/ServiceWrapperEntry/Program.cs
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace ServiceWrapper
|
||||||
|
{
|
||||||
|
static class Program
|
||||||
|
{
|
||||||
|
[DllImport("kernel32")]
|
||||||
|
private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
|
||||||
|
|
||||||
|
[DllImport("kernel32")]
|
||||||
|
private static extern int GetPrivateProfileString(string lpAppName, string lpKeyName, string lpDefault, StringBuilder lpReturnedString, int nSize, string lpFileName);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
|
||||||
|
private static extern uint GetPrivateProfileSection(string lpAppName, IntPtr lpReturnedString, uint nSize, string lpFileName);
|
||||||
|
|
||||||
|
private static string ReadString(string section, string key, string def, string filePath)
|
||||||
|
{
|
||||||
|
StringBuilder temp = new StringBuilder(1024);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
GetPrivateProfileString(section, key, def, temp, 1024, filePath);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{ }
|
||||||
|
return temp.ToString();
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 根据section取所有key
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="section"></param>
|
||||||
|
/// <param name="filePath"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string[] ReadIniAllKeys(string section, string filePath)
|
||||||
|
{
|
||||||
|
UInt32 MAX_BUFFER = 32767;
|
||||||
|
|
||||||
|
string[] items = new string[0];
|
||||||
|
|
||||||
|
IntPtr pReturnedString = Marshal.AllocCoTaskMem((int)MAX_BUFFER * sizeof(char));
|
||||||
|
|
||||||
|
UInt32 bytesReturned = GetPrivateProfileSection(section, pReturnedString, MAX_BUFFER, filePath);
|
||||||
|
|
||||||
|
if (!(bytesReturned == MAX_BUFFER - 2) || (bytesReturned == 0))
|
||||||
|
{
|
||||||
|
string returnedString = Marshal.PtrToStringAuto(pReturnedString, (int)bytesReturned);
|
||||||
|
|
||||||
|
items = returnedString.Split(new char[] { '\0' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
}
|
||||||
|
|
||||||
|
Marshal.FreeCoTaskMem(pReturnedString);
|
||||||
|
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据section,key取值
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="section"></param>
|
||||||
|
/// <param name="keys"></param>
|
||||||
|
/// <param name="filePath">ini文件路径</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string ReadIniKeys(string section, string keys, string filePath)
|
||||||
|
{
|
||||||
|
return ReadString(section, keys, "", filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 保存ini
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="section"></param>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <param name="filePath">ini文件路径</param>
|
||||||
|
public static void WriteIniKeys(string section, string key, string value, string filePath)
|
||||||
|
{
|
||||||
|
WritePrivateProfileString(section, key, value, filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 应用程序的主入口点。
|
||||||
|
/// </summary>
|
||||||
|
[STAThread]
|
||||||
|
static void Main()
|
||||||
|
{
|
||||||
|
Application.EnableVisualStyles();
|
||||||
|
Application.SetCompatibleTextRenderingDefault(false);
|
||||||
|
PublicVariable.frontEndAddress = ReadIniKeys("serverAddress", "frontEndAddress", "./config.ini");
|
||||||
|
PublicVariable.backEndAddress = ReadIniKeys("serverAddress", "backEndAddress", "./config.ini");
|
||||||
|
Application.Run(new Start());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// 有关程序集的一般信息由以下
|
||||||
|
// 控制。更改这些特性值可修改
|
||||||
|
// 与程序集关联的信息。
|
||||||
|
[assembly: AssemblyTitle("ServiceWrapper")]
|
||||||
|
[assembly: AssemblyDescription("服务包装手动版")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("浙江大学")]
|
||||||
|
[assembly: AssemblyProduct("服务包装器")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © 2020")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// 将 ComVisible 设置为 false 会使此程序集中的类型
|
||||||
|
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
|
||||||
|
//请将此类型的 ComVisible 特性设置为 true。
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
|
||||||
|
[assembly: Guid("8ff781cb-5c33-4c3f-872d-1fe0e114a8d0")]
|
||||||
|
|
||||||
|
// 程序集的版本信息由下列四个值组成:
|
||||||
|
//
|
||||||
|
// 主版本
|
||||||
|
// 次版本
|
||||||
|
// 生成号
|
||||||
|
// 修订号
|
||||||
|
//
|
||||||
|
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
|
||||||
|
//通过使用 "*",如下所示:
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
63
ServiceWrapperEntry/ServiceWrapperEntry/Properties/Resources.Designer.cs
generated
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// 此代码由工具生成。
|
||||||
|
// 运行时版本:4.0.30319.42000
|
||||||
|
//
|
||||||
|
// 对此文件的更改可能会导致不正确的行为,并且如果
|
||||||
|
// 重新生成代码,这些更改将会丢失。
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace ServiceWrapper.Properties {
|
||||||
|
using System;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 一个强类型的资源类,用于查找本地化的字符串等。
|
||||||
|
/// </summary>
|
||||||
|
// 此类是由 StronglyTypedResourceBuilder
|
||||||
|
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
|
||||||
|
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
|
||||||
|
// (以 /str 作为命令选项),或重新生成 VS 项目。
|
||||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
|
internal class Resources {
|
||||||
|
|
||||||
|
private static global::System.Resources.ResourceManager resourceMan;
|
||||||
|
|
||||||
|
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||||
|
|
||||||
|
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||||
|
internal Resources() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回此类使用的缓存的 ResourceManager 实例。
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||||
|
get {
|
||||||
|
if (object.ReferenceEquals(resourceMan, null)) {
|
||||||
|
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ServiceWrapper.Properties.Resources", typeof(Resources).Assembly);
|
||||||
|
resourceMan = temp;
|
||||||
|
}
|
||||||
|
return resourceMan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 重写当前线程的 CurrentUICulture 属性
|
||||||
|
/// 重写当前线程的 CurrentUICulture 属性。
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static global::System.Globalization.CultureInfo Culture {
|
||||||
|
get {
|
||||||
|
return resourceCulture;
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
resourceCulture = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,117 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
26
ServiceWrapperEntry/ServiceWrapperEntry/Properties/Settings.Designer.cs
generated
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// 此代码由工具生成。
|
||||||
|
// 运行时版本:4.0.30319.42000
|
||||||
|
//
|
||||||
|
// 对此文件的更改可能会导致不正确的行为,并且如果
|
||||||
|
// 重新生成代码,这些更改将会丢失。
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace ServiceWrapper.Properties {
|
||||||
|
|
||||||
|
|
||||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.4.0.0")]
|
||||||
|
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||||
|
|
||||||
|
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||||
|
|
||||||
|
public static Settings Default {
|
||||||
|
get {
|
||||||
|
return defaultInstance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
|
||||||
|
<Profiles>
|
||||||
|
<Profile Name="(Default)" />
|
||||||
|
</Profiles>
|
||||||
|
<Settings />
|
||||||
|
</SettingsFile>
|
32
ServiceWrapperEntry/ServiceWrapperEntry/PublicVariable.cs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Data;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using OpenQA.Selenium;
|
||||||
|
using OpenQA.Selenium.Chrome;
|
||||||
|
using OpenQA.Selenium.Interactions;
|
||||||
|
using OpenQA.Selenium.Internal;
|
||||||
|
using OpenQA.Selenium.Support;
|
||||||
|
using Fleck;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace ServiceWrapper
|
||||||
|
{
|
||||||
|
class PublicVariable
|
||||||
|
{
|
||||||
|
public static bool isInitialized = false;
|
||||||
|
public static double ratio = 0.5; //上面流程图窗口所占的大小比率
|
||||||
|
public static Start start = null;
|
||||||
|
public static Flow fr = null;
|
||||||
|
public static Process chrome = null;
|
||||||
|
public static string frontEndAddress = "http://183.129.170.180:8041/frontEnd";
|
||||||
|
public static string backEndAddress = "http://183.129.170.180:8041";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,179 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="..\packages\CefSharp.WinForms.79.1.350\build\CefSharp.WinForms.props" Condition="Exists('..\packages\CefSharp.WinForms.79.1.350\build\CefSharp.WinForms.props')" />
|
||||||
|
<Import Project="..\packages\CefSharp.Common.79.1.350\build\CefSharp.Common.props" Condition="Exists('..\packages\CefSharp.Common.79.1.350\build\CefSharp.Common.props')" />
|
||||||
|
<Import Project="..\packages\cef.redist.x86.79.1.35\build\cef.redist.x86.props" Condition="Exists('..\packages\cef.redist.x86.79.1.35\build\cef.redist.x86.props')" />
|
||||||
|
<Import Project="..\packages\cef.redist.x64.79.1.35\build\cef.redist.x64.props" Condition="Exists('..\packages\cef.redist.x64.79.1.35\build\cef.redist.x64.props')" />
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{8FF781CB-5C33-4C3F-872D-1FE0E114A8D0}</ProjectGuid>
|
||||||
|
<OutputType>WinExe</OutputType>
|
||||||
|
<RootNamespace>ServiceWrapper</RootNamespace>
|
||||||
|
<AssemblyName>ServiceWrapper</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||||
|
<Deterministic>true</Deterministic>
|
||||||
|
<NuGetPackageImportStamp>
|
||||||
|
</NuGetPackageImportStamp>
|
||||||
|
<PublishUrl>publish\</PublishUrl>
|
||||||
|
<Install>true</Install>
|
||||||
|
<InstallFrom>Disk</InstallFrom>
|
||||||
|
<UpdateEnabled>false</UpdateEnabled>
|
||||||
|
<UpdateMode>Foreground</UpdateMode>
|
||||||
|
<UpdateInterval>7</UpdateInterval>
|
||||||
|
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||||
|
<UpdatePeriodically>false</UpdatePeriodically>
|
||||||
|
<UpdateRequired>false</UpdateRequired>
|
||||||
|
<MapFileExtensions>true</MapFileExtensions>
|
||||||
|
<ApplicationRevision>0</ApplicationRevision>
|
||||||
|
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||||
|
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||||
|
<UseApplicationTrust>false</UseApplicationTrust>
|
||||||
|
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<LangVersion>7.3</LangVersion>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<Prefer32Bit>true</Prefer32Bit>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||||
|
<OutputPath>bin\x64\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<LangVersion>7.3</LangVersion>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<Prefer32Bit>true</Prefer32Bit>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<ApplicationIcon>favicon.ico</ApplicationIcon>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="Fleck, Version=1.1.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\Fleck.1.1.0\lib\net45\Fleck.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Deployment" />
|
||||||
|
<Reference Include="System.Drawing" />
|
||||||
|
<Reference Include="System.Net.Http" />
|
||||||
|
<Reference Include="System.Windows.Forms" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
<Reference Include="WebDriver, Version=3.141.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\Selenium.WebDriver.3.141.0\lib\net45\WebDriver.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Class1.cs" />
|
||||||
|
<Compile Include="Flow.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Flow.Designer.cs">
|
||||||
|
<DependentUpon>Flow.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Program.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="PublicVariable.cs" />
|
||||||
|
<Compile Include="Start.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Start.Designer.cs">
|
||||||
|
<DependentUpon>Start.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<EmbeddedResource Include="Flow.resx">
|
||||||
|
<DependentUpon>Flow.cs</DependentUpon>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="Properties\Resources.resx">
|
||||||
|
<Generator>ResXFileCodeGenerator</Generator>
|
||||||
|
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<Compile Include="Properties\Resources.Designer.cs">
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>Resources.resx</DependentUpon>
|
||||||
|
<DesignTime>True</DesignTime>
|
||||||
|
</Compile>
|
||||||
|
<EmbeddedResource Include="Start.resx">
|
||||||
|
<DependentUpon>Start.cs</DependentUpon>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<None Include="packages.config" />
|
||||||
|
<None Include="Properties\Settings.settings">
|
||||||
|
<Generator>SettingsSingleFileGenerator</Generator>
|
||||||
|
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||||
|
</None>
|
||||||
|
<Compile Include="Properties\Settings.Designer.cs">
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>Settings.settings</DependentUpon>
|
||||||
|
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="App.config" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="favicon.ico" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<BootstrapperPackage Include=".NETFramework,Version=v4.7.2">
|
||||||
|
<Visible>False</Visible>
|
||||||
|
<ProductName>Microsoft .NET Framework 4.7.2 %28x86 和 x64%29</ProductName>
|
||||||
|
<Install>true</Install>
|
||||||
|
</BootstrapperPackage>
|
||||||
|
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||||
|
<Visible>False</Visible>
|
||||||
|
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||||
|
<Install>false</Install>
|
||||||
|
</BootstrapperPackage>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||||
|
<PropertyGroup>
|
||||||
|
<ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Error Condition="!Exists('..\packages\cef.redist.x64.79.1.35\build\cef.redist.x64.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\cef.redist.x64.79.1.35\build\cef.redist.x64.props'))" />
|
||||||
|
<Error Condition="!Exists('..\packages\cef.redist.x86.79.1.35\build\cef.redist.x86.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\cef.redist.x86.79.1.35\build\cef.redist.x86.props'))" />
|
||||||
|
<Error Condition="!Exists('..\packages\CefSharp.Common.79.1.350\build\CefSharp.Common.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\CefSharp.Common.79.1.350\build\CefSharp.Common.props'))" />
|
||||||
|
<Error Condition="!Exists('..\packages\CefSharp.Common.79.1.350\build\CefSharp.Common.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\CefSharp.Common.79.1.350\build\CefSharp.Common.targets'))" />
|
||||||
|
<Error Condition="!Exists('..\packages\CefSharp.WinForms.79.1.350\build\CefSharp.WinForms.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\CefSharp.WinForms.79.1.350\build\CefSharp.WinForms.props'))" />
|
||||||
|
<Error Condition="!Exists('..\packages\CefSharp.WinForms.79.1.350\build\CefSharp.WinForms.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\CefSharp.WinForms.79.1.350\build\CefSharp.WinForms.targets'))" />
|
||||||
|
</Target>
|
||||||
|
<Import Project="..\packages\CefSharp.Common.79.1.350\build\CefSharp.Common.targets" Condition="Exists('..\packages\CefSharp.Common.79.1.350\build\CefSharp.Common.targets')" />
|
||||||
|
<Import Project="..\packages\CefSharp.WinForms.79.1.350\build\CefSharp.WinForms.targets" Condition="Exists('..\packages\CefSharp.WinForms.79.1.350\build\CefSharp.WinForms.targets')" />
|
||||||
|
</Project>
|
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<PublishUrlHistory>publish\</PublishUrlHistory>
|
||||||
|
<InstallUrlHistory />
|
||||||
|
<SupportUrlHistory />
|
||||||
|
<UpdateUrlHistory />
|
||||||
|
<BootstrapperUrlHistory />
|
||||||
|
<ErrorReportUrlHistory />
|
||||||
|
<FallbackCulture>zh-CN</FallbackCulture>
|
||||||
|
<VerifyUploadedFiles>false</VerifyUploadedFiles>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
107
ServiceWrapperEntry/ServiceWrapperEntry/Start.Designer.cs
generated
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
namespace ServiceWrapper
|
||||||
|
{
|
||||||
|
partial class Start
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Start));
|
||||||
|
this.button1 = new System.Windows.Forms.Button();
|
||||||
|
this.label1 = new System.Windows.Forms.Label();
|
||||||
|
this.State = new System.Windows.Forms.Label();
|
||||||
|
this.button2 = new System.Windows.Forms.Button();
|
||||||
|
this.SuspendLayout();
|
||||||
|
//
|
||||||
|
// button1
|
||||||
|
//
|
||||||
|
this.button1.Location = new System.Drawing.Point(60, 66);
|
||||||
|
this.button1.Margin = new System.Windows.Forms.Padding(4);
|
||||||
|
this.button1.Name = "button1";
|
||||||
|
this.button1.Size = new System.Drawing.Size(196, 75);
|
||||||
|
this.button1.TabIndex = 1;
|
||||||
|
this.button1.Text = "包装/修改/查看服务";
|
||||||
|
this.button1.UseVisualStyleBackColor = true;
|
||||||
|
this.button1.Click += new System.EventHandler(this.button1_Click);
|
||||||
|
//
|
||||||
|
// label1
|
||||||
|
//
|
||||||
|
this.label1.AutoSize = true;
|
||||||
|
this.label1.Location = new System.Drawing.Point(15, 29);
|
||||||
|
this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||||
|
this.label1.Name = "label1";
|
||||||
|
this.label1.Size = new System.Drawing.Size(88, 16);
|
||||||
|
this.label1.TabIndex = 2;
|
||||||
|
this.label1.Text = "程序状态:";
|
||||||
|
//
|
||||||
|
// State
|
||||||
|
//
|
||||||
|
this.State.AutoSize = true;
|
||||||
|
this.State.Location = new System.Drawing.Point(102, 29);
|
||||||
|
this.State.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||||
|
this.State.Name = "State";
|
||||||
|
this.State.Size = new System.Drawing.Size(200, 16);
|
||||||
|
this.State.TabIndex = 3;
|
||||||
|
this.State.Text = "请点击相应操作按钮使用。";
|
||||||
|
//
|
||||||
|
// button2
|
||||||
|
//
|
||||||
|
this.button2.Location = new System.Drawing.Point(60, 163);
|
||||||
|
this.button2.Margin = new System.Windows.Forms.Padding(4);
|
||||||
|
this.button2.Name = "button2";
|
||||||
|
this.button2.Size = new System.Drawing.Size(196, 75);
|
||||||
|
this.button2.TabIndex = 4;
|
||||||
|
this.button2.Text = "查看/调用/删除服务";
|
||||||
|
this.button2.UseVisualStyleBackColor = true;
|
||||||
|
this.button2.Click += new System.EventHandler(this.button2_Click);
|
||||||
|
//
|
||||||
|
// Start
|
||||||
|
//
|
||||||
|
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
|
||||||
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
|
this.ClientSize = new System.Drawing.Size(340, 260);
|
||||||
|
this.Controls.Add(this.button2);
|
||||||
|
this.Controls.Add(this.State);
|
||||||
|
this.Controls.Add(this.label1);
|
||||||
|
this.Controls.Add(this.button1);
|
||||||
|
this.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
|
||||||
|
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||||
|
this.Margin = new System.Windows.Forms.Padding(4);
|
||||||
|
this.MaximizeBox = false;
|
||||||
|
this.Name = "Start";
|
||||||
|
this.Text = "面向Web资源的服务封装系统";
|
||||||
|
this.Load += new System.EventHandler(this.Start_Load);
|
||||||
|
this.ResumeLayout(false);
|
||||||
|
this.PerformLayout();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
private System.Windows.Forms.Button button1;
|
||||||
|
private System.Windows.Forms.Label label1;
|
||||||
|
private System.Windows.Forms.Label State;
|
||||||
|
private System.Windows.Forms.Button button2;
|
||||||
|
}
|
||||||
|
}
|
256
ServiceWrapperEntry/ServiceWrapperEntry/Start.cs
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Data;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using OpenQA.Selenium;
|
||||||
|
using OpenQA.Selenium.Chrome;
|
||||||
|
using OpenQA.Selenium.Interactions;
|
||||||
|
using OpenQA.Selenium.Internal;
|
||||||
|
using OpenQA.Selenium.Support;
|
||||||
|
using Fleck;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
namespace ServiceWrapper
|
||||||
|
{
|
||||||
|
public partial class Start : Form
|
||||||
|
{
|
||||||
|
public static IWebDriver browser;
|
||||||
|
public static IWebSocketConnection socket_start; //输入网址页面的socket
|
||||||
|
public static IWebSocketConnection socket_window; //正式使用的窗口的socket
|
||||||
|
public static IWebSocketConnection socket_flowchart; //流程图的socket
|
||||||
|
public static WebSocketServer server;
|
||||||
|
public static IntPtr chromeId;
|
||||||
|
public static string[] links;
|
||||||
|
public Flow fr;
|
||||||
|
public string serviceListUrl = PublicVariable.frontEndAddress + "/serviceList.html?backEndAddressServiceWrapper=" + PublicVariable.backEndAddress;
|
||||||
|
|
||||||
|
[System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint = "MoveWindow")]
|
||||||
|
public static extern bool MoveWindow(System.IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern IntPtr GetForegroundWindow();
|
||||||
|
[System.Runtime.InteropServices.DllImport("user32.dll")]
|
||||||
|
public static extern int SetForegroundWindow(IntPtr hwnd);
|
||||||
|
|
||||||
|
[DllImport("user32", EntryPoint = "GetWindowThreadProcessId")]
|
||||||
|
private static extern int GetWindowThreadProcessId(IntPtr hwnd, out int pid);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", EntryPoint = "SendMessage", SetLastError = true, CharSet = CharSet.Auto)]
|
||||||
|
private static extern int SendMessage(IntPtr hwnd, uint wMsg, int wParam, int lParam);
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
private extern static bool SwapMouseButton(bool fSwap);
|
||||||
|
[DllImport("user32.dll", SetLastError = true)]
|
||||||
|
static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", EntryPoint = "ShowWindow", CharSet = CharSet.Auto)]
|
||||||
|
public static extern int ShowWindow(IntPtr hwnd, int nCmdShow);
|
||||||
|
|
||||||
|
const int WM_SYSCOMMAND = 0x0112;
|
||||||
|
const int SC_CLOSE = 0xF060;
|
||||||
|
const int SC_MINIMIZE = 0xF020;
|
||||||
|
const int SC_MAXIMIZE = 0xF030;
|
||||||
|
const int SC_RESTORE = 0xF120;
|
||||||
|
|
||||||
|
public Start()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
PublicVariable.start = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Start_Load(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
//string title = (string)Scripts().ExecuteScript("return document.title");
|
||||||
|
server = new WebSocketServer("ws://0.0.0.0:8084");
|
||||||
|
server.Start(socke =>
|
||||||
|
{
|
||||||
|
socke.OnOpen = () =>
|
||||||
|
{
|
||||||
|
BeginInvoke(new ConnectionChange(ModifyState), new object[] { "与浏览器连接已建立,请使用。" });
|
||||||
|
};
|
||||||
|
socke.OnClose = () =>
|
||||||
|
{
|
||||||
|
//BeginInvoke(new ConnectionChange(ModifyState), new object[] { "与浏览器连接已断开。" });
|
||||||
|
};
|
||||||
|
socke.OnMessage = message =>
|
||||||
|
{
|
||||||
|
|
||||||
|
Msg msg = JsonConvert.DeserializeObject<Msg>(message);//result为上面的Json数据
|
||||||
|
//处理连接操作
|
||||||
|
if (msg.type == 0)//如果是第一次连接操作,设定socket
|
||||||
|
{
|
||||||
|
if (msg.message.id == 0)
|
||||||
|
{
|
||||||
|
socket_window = socke;
|
||||||
|
Console.WriteLine("Socket Window Connected.");
|
||||||
|
}
|
||||||
|
else if (msg.message.id == 1)
|
||||||
|
{
|
||||||
|
socket_start = socke;
|
||||||
|
Console.WriteLine("Socket Start Connected.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
socket_flowchart = socke;
|
||||||
|
Console.WriteLine("Socket Flowchart Connected.");
|
||||||
|
//发送打开网页指令
|
||||||
|
//FlowMessage fmsg = JsonConvert.DeserializeObject<FlowMessage>("{\"type\":0,\"data\":{\"option\":1,\"parameters\":{\"url\":\"https://www.baidu.com\"}}}");
|
||||||
|
//fmsg.data.parameters.url = links[0];
|
||||||
|
//string json = JsonConvert.SerializeObject(fmsg);
|
||||||
|
//socket_flowchart.Send(json);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else //其他情况放在进程外处理
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
BeginInvoke(new GetMessage(HandleEvent), new object[] { message });
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
});
|
||||||
|
try
|
||||||
|
{
|
||||||
|
SendKeys.Send("+");
|
||||||
|
SendKeys.Send("+"); //测试是否能正常使用输入模块
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
MessageBox.Show("输入模块初始化失败,请退出360之类的安全软件!");
|
||||||
|
Application.Exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate void ConnectionChange(object input);//委托
|
||||||
|
delegate void GetMessage(object input);
|
||||||
|
|
||||||
|
//正式处理程序入口
|
||||||
|
public void HandleEvent(object input)
|
||||||
|
{
|
||||||
|
|
||||||
|
Msg msg = JsonConvert.DeserializeObject<Msg>(input.ToString());//result为上面的Json数据
|
||||||
|
if (msg.type == 1) //开始的时候输入网址
|
||||||
|
{
|
||||||
|
chromeId = GetForegroundWindow(); //记录下所在浏览器的进程Id号
|
||||||
|
Console.WriteLine(chromeId);
|
||||||
|
Console.WriteLine();
|
||||||
|
//links = msg.message.links.Split(new string[] { "\n" }, StringSplitOptions.None);
|
||||||
|
//List<string> list = links.ToList();
|
||||||
|
//int l = links.Length;
|
||||||
|
//if (links[l - 1].Length == 0)//如果最后一行是空行则删掉
|
||||||
|
//{
|
||||||
|
// list.RemoveAt(l - 1);
|
||||||
|
//}
|
||||||
|
//links = list.ToArray();
|
||||||
|
//if (browser != null)
|
||||||
|
//{
|
||||||
|
// browser.Navigate().GoToUrl(links[0]);
|
||||||
|
//}
|
||||||
|
int width = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Size.Width;
|
||||||
|
int height = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Size.Height;
|
||||||
|
SendMessage(chromeId, WM_SYSCOMMAND, SC_RESTORE, 0); // 最大化
|
||||||
|
MoveWindow(chromeId, 0, Convert.ToInt32(height * PublicVariable.ratio) - 120, width, 120 + Convert.ToInt32(height * (1.0 - PublicVariable.ratio)), true);
|
||||||
|
if(fr!=null)
|
||||||
|
{
|
||||||
|
if (msg.message.id != -1) //读取服务流程,不是新增的时候
|
||||||
|
{
|
||||||
|
fr.chromeBrowser.Load(Flow.flowChartUrl + msg.message.id.ToString() + "&backEndAddressServiceWrapper=" + PublicVariable.backEndAddress);
|
||||||
|
}
|
||||||
|
//SwapMouseButton(true);
|
||||||
|
fr.Show();
|
||||||
|
}
|
||||||
|
Hide();
|
||||||
|
//SwitchToThisWindow(chromeId,true);
|
||||||
|
//ShowWindow(System.UIntPtr(browser.CurrentWindowHandle),2);
|
||||||
|
SetForegroundWindow(Start.chromeId); //打开流程图窗口后将chrome窗口显示到最前方
|
||||||
|
SetForegroundWindow(Handle); //打开流程图窗口后将chrome窗口显示到最前方
|
||||||
|
SetForegroundWindow(Start.chromeId); //打开流程图窗口后将chrome窗口显示到最前方
|
||||||
|
//MouseHelper.SetCursorPos(400, Convert.ToInt32(height * PublicVariable.ratio) - 110);
|
||||||
|
//MouseHelper.mouse_event(MouseHelper.MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0);
|
||||||
|
//Thread.Sleep(50);
|
||||||
|
//MouseHelper.mouse_event(MouseHelper.MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
else if (msg.type == 2)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
SendKeys.Send(msg.message.keyboardStr);
|
||||||
|
SendKeys.Send("+");
|
||||||
|
SendKeys.Send("+"); //两个shift是为了防止有人按用中文输入法输入了英文按了回车,这样切换两次输入法就可以达到效果
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
MessageBox.Show("输入失败,请退出360之类的安全软件!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (msg.type == 3)
|
||||||
|
{
|
||||||
|
if (msg.from == 0)
|
||||||
|
{
|
||||||
|
socket_flowchart.Send(msg.message.pipe); //直接把消息转接
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
socket_window.Send(msg.message.pipe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (msg.type == 5)
|
||||||
|
{
|
||||||
|
string FileName = Application.StartupPath + @"/Chrome/ServiceWrapper_ExcuteStage.exe"; //启动的应用程序名称
|
||||||
|
string arguments = msg.message.id.ToString() + " " + PublicVariable.backEndAddress;
|
||||||
|
Process.Start(FileName, arguments); //启动执行程序
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ModifyState(object input)
|
||||||
|
{
|
||||||
|
State.Text = (string)input;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static IJavaScriptExecutor Scripts()
|
||||||
|
{
|
||||||
|
return (IJavaScriptExecutor)browser;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void button1_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
fr = new Flow(); //先创造流程图界面,暂时隐藏不显示
|
||||||
|
fr.Show();
|
||||||
|
fr.Hide();
|
||||||
|
State.Text = "加载中……";
|
||||||
|
ChromeOptions options = new ChromeOptions();
|
||||||
|
options.AddExtension(Application.StartupPath + @"/ServiceWrapper.crx");
|
||||||
|
browser = new ChromeDriver(Application.StartupPath +@"/Chrome", options);
|
||||||
|
browser.Navigate().GoToUrl(serviceListUrl); //默认可以修改服务
|
||||||
|
//ProcessStartInfo startInfo = new ProcessStartInfo();
|
||||||
|
//startInfo.FileName = Application.StartupPath + @"/Chrome/chrome.exe"; //启动的应用程序名称
|
||||||
|
//SwapMouseButton(false);//此时此刻的鼠标应该是默认状态
|
||||||
|
//PublicVariable.chrome = Process.Start(startInfo);
|
||||||
|
//browser.Navigate().GoToUrl("file:///Start.html");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void button2_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
Flow fr2 = new Flow(serviceListUrl+"&type=1"); //加载的页面不可增加和修改服务
|
||||||
|
fr2.closedriver = false;
|
||||||
|
fr2.WindowState = FormWindowState.Maximized; //最大化窗口
|
||||||
|
fr2.Show();
|
||||||
|
Hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
408
ServiceWrapperEntry/ServiceWrapperEntry/Start.resx
Normal file
@ -0,0 +1,408 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||||
|
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>
|
||||||
|
AAABAAEAQEAAAAEAIAAoQgAAFgAAACgAAABAAAAAgAAAAAEAIAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAD/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////7+/v/+/v7//v7+///////+/v7//v7+////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////////////////////////////////////v7+//7+/v/+/v7/////////
|
||||||
|
/////////////////////////v7+//7+/v//////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////////////////////////////////////7+
|
||||||
|
/v/+/v7//v7+///////+/v7//v7+//////////////////7+/v/+/v7//v7+////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////+/v7//v7+/////////////v7+//7+/v/+/v7////////////+/v7//v7+//7+
|
||||||
|
/v//////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////v7+////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////+/v7//v7+////
|
||||||
|
/////////v7+//7+/v//////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////7+/v//////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/////////v7+//7+/v//////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////v7+//7+/v/+/v7////////////////////////////+/v7/+vr6/5eX
|
||||||
|
l/+YmJj/+vr6//7+/v//////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////7+/v/+/v7/////////////////////////
|
||||||
|
///9/f3/4uLi/0lJSf8AAAD/AAAA/0lJSf/j4+P//f39////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////9/f3/ubm5/xkZGf8BAQH/AAAA/wAAAP8BAQH/GRkZ/7m5uf/+/v7//v7+////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////9/f3/kpKS/wYGBv8AAAD/AAAA/wAAAP8AAAD/AAAA/wEB
|
||||||
|
Af8GBgb/kpKS//7+/v/+/v7/////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////9/f3/hoaG/wICAv8AAAD/AAAA/wAA
|
||||||
|
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wICAv+FhYX//f39////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////////////////////7+/v/+/v7/q6ur/wQE
|
||||||
|
BP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AgIC/6ysrP/+/v7/////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///+/v7/9PT0/x8fH/8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wEB
|
||||||
|
Af8dHR3/9fX1////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////v7+/7W1tf8AAAD/AAAA/wICAv8aGhr/AwMD/wAAAP8AAAD/AAAA/wAA
|
||||||
|
AP8EBAT/Ghoa/wICAv8AAAD/AAAA/7a2tv//////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////7+/v+RkZH/AAAA/wAAAP8gICD/+/v7/9fX
|
||||||
|
1/9UVFT/AgIC/wICAv9VVVX/2NjY//v7+/8fHx//AAAA/wAAAP+SkpL/////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////+/v7/mpqa/wAA
|
||||||
|
AP8AAAD/Nzc3//7+/v/+/v7/ysrK/8TExP/Dw8P/ycnJ//7+/v/9/f3/ODg4/wAAAP8AAAD/mpqa////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/////////v7+/8PDw/8AAAD/AAAA/zU1Nf/+/v7//v7+/83Nzf+Wlpb/lpaW/87Ozv/+/v7//f39/zU1
|
||||||
|
Nf8AAAD/AAAA/8PDw///////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////7+/v/19fX/EBAQ/wAAAP8YGBj/4uLi/6mpqf8tLS3/AgIC/wEB
|
||||||
|
Af8tLS3/qqqq/+Hh4f8YGBj/AAAA/xAQEP/19fX/////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////////////////////v7+//7+/v/+/v7//v7+/1lZWf8AAAD/AQEB/wMD
|
||||||
|
A/8DAwP/Li4u/2xsbP9vb2//NDQ0/wICAv8DAwP/AAAA/wAAAP9ZWVn//f39////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////////////////////7+/v/+/v7/////////
|
||||||
|
//+0tLT/AAAA/wAAAP8JCQn/np6e/+/v7/+1tbX/srKy/+7u7v+qqqr/DAwM/wAAAP8BAQH/tLS0////
|
||||||
|
//////////////7+/v/+/v7/////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///+/v7//v7+////////////+Pj4/x4eHv8CAgL/mJiY/8XFxf8fHx//AQEB/wAAAP8aGhr/vr6+/6Wl
|
||||||
|
pf8BAQH/HR0d//j4+P/////////////////+/v7//v7+////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////7+/v99fX3/LS0t/+bm5v8YGBj/AAAA/wAA
|
||||||
|
AP8AAAD/AAAA/xQUFP/j4+P/MjIy/319ff/9/f3/////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////+/v7/3t7e/4GB
|
||||||
|
gf+BgYH/AQEB/wAAAP8AAAD/AAAA/wAAAP8AAAD/enp6/4WFhf/e3t7//v7+////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////39/f/n5+f/MzMz/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/zIyMv/o6Oj//f39////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////+/v7//v7+////
|
||||||
|
///////////////////////////////////+/v7/7+/v/wcHB/8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
|
||||||
|
AP8HBwf/8fHx//7+/v//////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/////////v7+//7+/v///////////////////////////////////////f39/9jY2P+IiIj/fX19/zEx
|
||||||
|
Mf8ICAj/CAgI/y4uLv99fX3/iIiI/9nZ2f/+/v7/////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////////////////////////////////////Hx
|
||||||
|
8f9mZmb/KSkp/zY2Nv+ioqL/QUFB/z09Pf+kpKT/PDw8/ygoKP9oaGj/8fHx//7+/v//////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///+/v7//v7+//7+/v+CgoL/BwcH/wcHB/8BAQH/DQ0N/7Gxsf+rq6v/Dg4O/wEBAf8GBgb/BwcH/4OD
|
||||||
|
g//9/f3//v7+////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///+/v7//v7+//7+/v/+/v7//v7+//j4+P/29vb/LCws/wcHB/8HBwf/AAAA/wMDA/9lZWX/Y2Nj/wAA
|
||||||
|
AP8AAAD/BgYG/wcHB/8sLCz/9fX1//f39//+/v7//v7+//7+/v/+/v7//v7+////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////v7+//Pz8//X19f/vr6+/4iIiP8yMjL/srKy/wEBAf8GBgb/BAQE/wEB
|
||||||
|
Af8nJyf/aGho/2FhYf8lJSX/AQEB/wcHB/8HBwf/AQEB/7Kysv80NDT/iIiI/729vf/X19f/8vLy//7+
|
||||||
|
/v//////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////6Ojo/1RUVP8FBQX/AAAA/wAAAP8AAAD/AgIC/6Cg
|
||||||
|
oP/V1dX/rq6u/62trf+rq6v/ioqK/05OTv9QUFD/kJCQ/7CwsP+pqan/rq6u/9XV1f+fn5//AwMD/wAA
|
||||||
|
AP8AAAD/AAAA/wYGBv9UVFT/6enp//7+/v//////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////+vr6/z8/P/8BAQH/AAAA/wAA
|
||||||
|
AP8AAAD/AAAA/wcHB/+vr6//+fn5/xQUFP8ICAj/CAgI/wcHB/8JCQn/CAgI/wcHB/8HBwf/CAgI/xQU
|
||||||
|
FP/4+Pj/sLCw/wYGBv8AAAD/AAAA/wAAAP8AAAD/AAAA/0BAQP/6+vr/////////////////////////
|
||||||
|
/////////////////////////v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////+/v7//v7+/6am
|
||||||
|
pv8AAAD/AAAA/wAAAP8AAAD/AAAA/wEBAf+Li4v//v7+//z8/P++vr7/v7+//4ODg/95eXn/2NjY/9LS
|
||||||
|
0v9ycnL/eXl5/8DAwP+9vb3//Pz8//39/f+Li4v/AQEB/wAAAP8AAAD/AAAA/wAAAP8AAAD/p6en//7+
|
||||||
|
/v////////////////////////////////////////////7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+
|
||||||
|
/v//////////////////////////////////////////////////////////////////////////////
|
||||||
|
/////////v7+//z8/P86Ojr/AAAA/wAAAP8AAAD/AAAA/wEBAf9QUFD/+/v7//7+/v/q6ur/GBgY/wkJ
|
||||||
|
Cf+ampr//f39//7+/v/+/v7//f39/5mZmf8ICAj/GBgY/+vr6//+/v7/+vr6/09PT/8BAQH/AAAA/wAA
|
||||||
|
AP8AAAD/AAAA/zo6Ov/8/Pz/////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////7+/v/c3Nz/BQUF/wAAAP8AAAD/AAAA/wgICP9nZ2f/8vLy//7+
|
||||||
|
/v/+/v7/pqam/wAAAP8BAQH/m5ub//7+/v////////////////+ampr/AAAA/wEBAf+mpqb//v7+//7+
|
||||||
|
/v/y8vL/Z2dn/wgICP8BAQH/AAAA/wAAAP8EBAT/3Nzc////////////////////////////////////
|
||||||
|
///////////////////////////////////+/v7//v7+////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////+/v7/+fn5/93d3f/Gxsb/vLy8/8nJ
|
||||||
|
yf/v7+///f39//7+/v///////f39/0RERP8AAAD/AgIC/+Dg4P//////////////////////39/f/wEB
|
||||||
|
Af8AAAD/Q0ND//39/f/+/v7//v7+//39/f/v7+//ycnJ/729vf/Gxsb/3Nzc//n5+f//////////////
|
||||||
|
/////////////////////////////////////////////////////////v7+//7+/v//////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////+/v7//v7+/7y8vP8BAQH/AAAA/zMzM//9/f3/////////
|
||||||
|
//////////////39/f80NDT/AAAA/wICAv+8vLz//v7+////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////7+/v/+/v7//v7+/+jo6P8lJSX/AAAA/wEB
|
||||||
|
Af+Dg4P//v7+///////////////////////+/v7/g4OD/wEBAf8AAAD/JCQk/+rq6v/+/v7/////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////+/v7//f39/+np
|
||||||
|
6f89PT3/AAAA/wAAAP8AAAD/y8vL//7+/v///////////////////////////8vLy/8AAAD/AAAA/wAA
|
||||||
|
AP86Ojr/6enp////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///+/v7//f39/8jIyP8oKCj/AAAA/wEBAf8sLCz/DQ0N//j4+P/+/v7//v7+//7+/v//////////////
|
||||||
|
///39/f/Dg4O/ywsLP8CAgL/AAAA/ykpKf/IyMj//v7+//7+/v////////////7+/v/+/v7/////////
|
||||||
|
//////////////////////////////////////////////////////////////7+/v/+/v7/////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////7+/v/9/f3/5+fn/29vb/8HBwf/AAAA/wEBAf9NTU3/2NjY/ysrK//+/v7///////7+
|
||||||
|
/v/+/v7//////////////////f39/ysrK//Y2Nj/TU1N/wEBAf8AAAD/BgYG/25ubv/o6Oj//f39//7+
|
||||||
|
/v/+/v7//v7+/////////////v7+//7+/v/+/v7//v7+/////////////v7+//7+/v/+/v7/////////
|
||||||
|
///+/v7//v7+//7+/v//////////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////39/f/q6ur/fHx8/xAQEP8BAQH/AgIC/xISEv8qKir/9vb2//T0
|
||||||
|
9P86Ojr//v7+///////+/v7//v7+//////////////////39/f85OTn/8/Pz//X19f8qKir/ExMT/wEB
|
||||||
|
Af8AAAD/EBAQ/3x8fP/q6ur//v7+//7+/v////////////7+/v/+/v7//v7+//7+/v////////////7+
|
||||||
|
/v/+/v7//v7+//////////////////7+/v/+/v7/////////////////////////////////////////
|
||||||
|
///////////////////////////////////+/v7//f39//Ly8v+CgoL/EhIS/wICAv8BAQH/CAgI/62t
|
||||||
|
rf+rq6v/cXFx//7+/v/9/f3/QUFB//39/f/+/v7////////////////////////////9/f3/QUFB//39
|
||||||
|
/f/+/v7/cXFx/6urq/+tra3/CAgI/wEBAf8CAgL/ExMT/4KCgv/x8fH//f39////////////////////
|
||||||
|
///////////////////+/v7//v7+//7+/v//////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////+/v7//f39/7S0tP8iIiL/AQEB/y4u
|
||||||
|
Lv9mZmb/AgIC/2ZmZv/9/f3/3t7e/7a2tv/+/v7//f39/4uLi//8/Pz//v7+////////////////////
|
||||||
|
/////////Pz8/4uLi//9/f3//v7+/7e3t//e3t7//f39/2ZmZv8CAgL/ZmZm/y4uLv8CAgL/IiIi/7Oz
|
||||||
|
s//9/f3//v7+//7+/v///////////////////////v7+//7+/v/+/v7/////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////+/v7/+vr6/3t7
|
||||||
|
e/8FBQX/ExMT/6Kiov/5+fn/ZWVl/wQEBP/U1NT//v7+//7+/v/+/v7//v7+//7+/v/9/f3//f39////
|
||||||
|
//////////////////////////////7+/v/9/f3//v7+//7+/v/+/v7//v7+///////U1NT/BAQE/2Vl
|
||||||
|
Zf/5+fn/oqKi/xISEv8FBQX/enp6//r6+v/+/v7//v7+////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///+/v7/+/v7/2xsbP8CAgL/BQUF/8HBwf/9/f3/9/f3/xYWFv83Nzf//f39////////////////////
|
||||||
|
///+/v7//v7+////////////////////////////////////////////////////////////////////
|
||||||
|
/////////Pz8/zg4OP8YGBj/+Pj4//7+/v/BwcH/BwcH/wMDA/9sbGz//Pz8//7+/v//////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////f39/5WVlf8RERH/YWFh/1JSUv/+/v7//v7+/9LS0v8BAQH/fn5+//39
|
||||||
|
/f//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////////9+fn7/AgIC/9LS0v///////v7+/1NTU/9iYmL/ExMT/5SU
|
||||||
|
lP/9/f3///////////////////////////////////////////////////////////////////////7+
|
||||||
|
/v/+/v7//v7+/////////////////////////////////9/f3/8VFRX/vLy8/5aWlv+Ojo7//v7+//7+
|
||||||
|
/v+qqqr/AQEB/6qqqv/+/v7/////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////qamp/wEBAf+rq6v///////7+
|
||||||
|
/v+Ojo7/lpaW/7y8vP8WFhb/39/f//39/f//////////////////////////////////////////////
|
||||||
|
//////////////7+/v/+/v7//v7+//7+/v////////////////////////////39/f9oaGj/dnZ2//z8
|
||||||
|
/P+cnJz/n5+f////////////lZWV/wAAAP+4uLj/////////////////////////////////////////
|
||||||
|
/////////////////////////////////////////////////////////////////////////////7e3
|
||||||
|
t/8AAAD/lpaW///////+/v7/n5+f/5ycnP/9/f3/dnZ2/2hoaP/9/f3/////////////////////////
|
||||||
|
///////////////////////////////////+/v7//v7+//7+/v/+/v7/////////////////////////
|
||||||
|
///9/f3/Xl5e/+rq6v/+/v7/sbGx/5eXl////////////5OTk/8BAQH/oKCg//39/f//////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////////+hoaH/AQEB/5OTk//+/v7//v7+/5aWlv+wsLD//v7+/+np6f9eXl7//f39////
|
||||||
|
///////////////////////////////////////////////////+/v7//v7+//7+/v//////////////
|
||||||
|
/////////////////////////v7+//39/f/9/f3//v7+/+3t7f/Z2dn///////////+enp7/Hh4e/11d
|
||||||
|
Xf/9/f3///////7+/v/+/v7//v7+////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////9/f3/XV1d/x4eHv+fn5///v7+//7+/v/Z2dn/7e3t//7+
|
||||||
|
/v/+/v7//f39//7+/v///////////////////////////////////////////////////////v7+//7+
|
||||||
|
/v/+/v7//v7+//7+/v/+/v7////////////////////////////////////////////+/v7//v7+////
|
||||||
|
////////t7e3/3R0dP9LS0v/0dHR//7+/v/+/v7//v7+//7+/v//////////////////////////////
|
||||||
|
//////////////////////////////////////////////7+/v/+/v7/0dHR/0tLS/9zc3P/t7e3////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////7+/v/+/v7//v7+//7+/v/+/v7//v7+////////////////////////////////////
|
||||||
|
/////////////////////////////9ra2v9ra2v/5+fn/1RUVP/c3Nz//v7+////////////////////
|
||||||
|
//////////////////////////////////////////////////////////////7+/v/9/f3/3Nzc/1RU
|
||||||
|
VP/o6Oj/a2tr/9ra2v//////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////+/v7//v7+//7+/v/+/v7//v7+////////////////////
|
||||||
|
///////////////////////////////////////////////////4+Pj/XV1d//z8/P/r6+v/bGxs/9HR
|
||||||
|
0f//////////////////////////////////////////////////////////////////////////////
|
||||||
|
///+/v7/0dHR/2tra//r6+v//f39/1xcXP/4+Pj/////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////+/v7//v7+//7+
|
||||||
|
/v///////////////////////////////////////////////////////////////////////v7+/19f
|
||||||
|
X//8/Pz///////7+/v/8/Pz/////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////v7+//z8/P/8/Pz//v7+//v7+/9gYGD//f39////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/////////v7+//7+/v/+/v7///////////////////////////////////////7+/v/+/v7//v7+////
|
||||||
|
//////////////7+/v+4uLj/+fn5///////+/v7//v7+////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////+/v7//v7+//7+/v/5+fn/t7e3//39
|
||||||
|
/f//////////////////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////////////////////////////////////v7+//7+/v/+/v7//v7+//7+
|
||||||
|
/v/+/v7//v7+//7+/v/////////////////+/v7//v7+//7+/v//////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/////////v7+//7+/v/+/v7/////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////////////////////////////////////7+
|
||||||
|
/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v//////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////+/v7//v7+//7+/v/+/v7//v7+//7+
|
||||||
|
/v/+/v7/////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/////////v7+//7+/v/+/v7/////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////7+/v/+/v7//v7+//7+/v/+/v7//v7+////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///+/v7//v7+////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////+/v7//v7+//7+/v/+/v7/////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////v7+//7+/v//////////////////////////////////////////////
|
||||||
|
////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
|
||||||
|
</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
2
ServiceWrapperEntry/ServiceWrapperEntry/bin/x64/Debug/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
*
|
||||||
|
!.gitignore
|
BIN
ServiceWrapperEntry/ServiceWrapperEntry/favicon.ico
Normal file
After Width: | Height: | Size: 17 KiB |
10
ServiceWrapperEntry/ServiceWrapperEntry/packages.config
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<packages>
|
||||||
|
<package id="cef.redist.x64" version="79.1.35" targetFramework="net472" />
|
||||||
|
<package id="cef.redist.x86" version="79.1.35" targetFramework="net472" />
|
||||||
|
<package id="CefSharp.Common" version="79.1.350" targetFramework="net472" />
|
||||||
|
<package id="CefSharp.WinForms" version="79.1.350" targetFramework="net472" />
|
||||||
|
<package id="Fleck" version="1.1.0" targetFramework="net472" />
|
||||||
|
<package id="Newtonsoft.Json" version="12.0.3" targetFramework="net472" />
|
||||||
|
<package id="Selenium.WebDriver" version="3.141.0" targetFramework="net472" />
|
||||||
|
</packages>
|
BIN
media/Picture.png
Normal file
After Width: | Height: | Size: 364 KiB |
BIN
media/Picture1.png
Normal file
After Width: | Height: | Size: 1.3 MiB |
BIN
media/Picture10.png
Normal file
After Width: | Height: | Size: 95 KiB |
BIN
media/Picture11.png
Normal file
After Width: | Height: | Size: 62 KiB |
BIN
media/Picture12.png
Normal file
After Width: | Height: | Size: 339 KiB |
BIN
media/Picture13.png
Normal file
After Width: | Height: | Size: 97 KiB |
BIN
media/Picture14.png
Normal file
After Width: | Height: | Size: 202 KiB |
BIN
media/Picture15.png
Normal file
After Width: | Height: | Size: 429 KiB |
BIN
media/Picture16.png
Normal file
After Width: | Height: | Size: 152 KiB |
BIN
media/Picture17.png
Normal file
After Width: | Height: | Size: 193 KiB |
BIN
media/Picture18.png
Normal file
After Width: | Height: | Size: 328 KiB |
BIN
media/Picture2.png
Normal file
After Width: | Height: | Size: 2.8 MiB |
BIN
media/Picture4.png
Normal file
After Width: | Height: | Size: 204 KiB |
BIN
media/Picture5.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
BIN
media/Picture6.png
Normal file
After Width: | Height: | Size: 868 KiB |
BIN
media/Picture7.png
Normal file
After Width: | Height: | Size: 240 KiB |
BIN
media/Picture8.png
Normal file
After Width: | Height: | Size: 147 KiB |
BIN
media/Picture9.png
Normal file
After Width: | Height: | Size: 102 KiB |
BIN
media/Picture90.png
Normal file
After Width: | Height: | Size: 212 KiB |
BIN
media/Picture91.png
Normal file
After Width: | Height: | Size: 172 KiB |