New version
7
.gitignore
vendored
@ -1,2 +1,9 @@
|
||||
.idea/
|
||||
node_modules/
|
||||
ServiceWrapper/
|
||||
Data/
|
||||
/GPUCache
|
||||
*.exe
|
||||
*.ini
|
||||
*.7z
|
||||
*.mp4
|
2
ExcuteStage/.gitignore
vendored
@ -7,3 +7,5 @@ dist/
|
||||
build/
|
||||
__pycache__/
|
||||
*.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 -*-
|
||||
import atexit # 遇到错误退出时应执行的代码
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
@ -17,14 +18,23 @@ from selenium.webdriver.common.by import By
|
||||
from selenium.common.exceptions import NoSuchElementException
|
||||
from selenium.common.exceptions import TimeoutException
|
||||
from selenium.common.exceptions import StaleElementReferenceException
|
||||
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
|
||||
import random
|
||||
import numpy
|
||||
import csv
|
||||
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:
|
||||
def __init__(self,type1=""):
|
||||
self.t = int(round(time.time() * 1000))
|
||||
def __init__(self, type1=""):
|
||||
self.t = int(round(time.time() * 1000))
|
||||
self.type = type1
|
||||
|
||||
def end(self):
|
||||
@ -32,6 +42,8 @@ class Time:
|
||||
Log(str(self.type)+":"+str(at-self.t))
|
||||
|
||||
# 记录log
|
||||
|
||||
|
||||
def recordLog(str=""):
|
||||
global log
|
||||
log = log + str + "\n"
|
||||
@ -43,17 +55,48 @@ def Log(text, text2=""):
|
||||
if switch:
|
||||
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):
|
||||
node = procedure[nodeId]
|
||||
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操作,条件分支操作
|
||||
for i in node["sequence"]: # 从根节点开始向下读取
|
||||
excuteNode(i, loopValue,clickPath,index)
|
||||
excuteNode(i, loopValue, clickPath, index)
|
||||
elif node["option"] == 1: # 打开网页操作
|
||||
recordLog("openPage")
|
||||
openPage(node["parameters"], loopValue)
|
||||
@ -67,10 +110,10 @@ def excuteNode(nodeId, loopValue="", clickPath="", index=0):
|
||||
inputInfo(node["parameters"], loopValue)
|
||||
elif node["option"] == 8: # 循环
|
||||
recordLog("loop")
|
||||
loopExcute(node, loopValue,clickPath,index) # 执行循环
|
||||
loopExcute(node, loopValue, clickPath, index) # 执行循环
|
||||
elif node["option"] == 9: # 条件分支
|
||||
recordLog("judge")
|
||||
judgeExcute(node, loopValue,clickPath,index)
|
||||
judgeExcute(node, loopValue, clickPath, index)
|
||||
|
||||
# 执行完之后进行等待
|
||||
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("条件判断")
|
||||
global bodyText # 引入bodyText
|
||||
excuteBranchId = 0 # 要执行的BranchId
|
||||
@ -101,7 +144,7 @@ def judgeExcute(node, loopElement,clickPath="",index=0):
|
||||
continue
|
||||
elif tType == 2: # 当前页面包含元素
|
||||
try:
|
||||
if browser.find_element_by_xpath(cnode["parameters"]["value"]):
|
||||
if browser.find_element(By.XPATH, cnode["parameters"]["value"]):
|
||||
excuteBranchId = i
|
||||
break
|
||||
except: # 找不到元素或者xpath写错了,下一个条件
|
||||
@ -115,22 +158,23 @@ def judgeExcute(node, loopElement,clickPath="",index=0):
|
||||
continue
|
||||
elif tType == 4: # 当前循环元素包括元素
|
||||
try:
|
||||
if loopElement.find_element_by_xpath(cnode["parameters"]["value"][1:]):
|
||||
if loopElement.find_element(By.XPATH, cnode["parameters"]["value"][1:]):
|
||||
excuteBranchId = i
|
||||
break
|
||||
except: # 找不到元素或者xpath写错了,下一个条件
|
||||
continue
|
||||
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秒
|
||||
Log("循环执行前等待0.1秒")
|
||||
global history
|
||||
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["handle"] = thisHandle
|
||||
|
||||
@ -139,9 +183,10 @@ def loopExcute(node, loopValue,clickPath="",index=0):
|
||||
count = 0 # 执行次数
|
||||
while True: # do while循环
|
||||
try:
|
||||
element = browser.find_element_by_xpath(node["parameters"]["xpath"])
|
||||
element = browser.find_element(By.XPATH,
|
||||
node["parameters"]["xpath"])
|
||||
for i in node["sequence"]: # 挨个执行操作
|
||||
excuteNode(i, element, node["parameters"]["xpath"],0)
|
||||
excuteNode(i, element, node["parameters"]["xpath"], 0)
|
||||
Log("click: ", node["parameters"]["xpath"])
|
||||
recordLog("click:" + node["parameters"]["xpath"])
|
||||
except NoSuchElementException:
|
||||
@ -153,14 +198,17 @@ def loopExcute(node, loopValue,clickPath="",index=0):
|
||||
count = count + 1
|
||||
Log("页数:", count)
|
||||
recordLog("页数:" + str(count))
|
||||
# print(node["parameters"]["exitCount"], "-------")
|
||||
if node["parameters"]["exitCount"] == count: # 如果达到设置的退出循环条件的话
|
||||
break
|
||||
elif int(node["parameters"]["loopType"]) == 1: # 不固定元素列表
|
||||
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 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: # 如果执行完一次循环之后标签页的位置发生了变化
|
||||
while True: # 一直关闭窗口直到当前标签页
|
||||
browser.close() # 关闭使用完的标签页
|
||||
@ -168,9 +216,11 @@ def loopExcute(node, loopValue,clickPath="",index=0):
|
||||
if browser.current_window_handle == thisHandle:
|
||||
break
|
||||
if history["index"] != thisHistoryLength and history[
|
||||
"handle"] == browser.current_window_handle: # 如果执行完一次循环之后历史记录发生了变化,注意当前页面的判断
|
||||
difference = thisHistoryLength - history["index"] # 计算历史记录变化差值
|
||||
browser.execute_script('history.go(' + str(difference) + ')') # 回退历史记录
|
||||
"handle"] == browser.current_window_handle: # 如果执行完一次循环之后历史记录发生了变化,注意当前页面的判断
|
||||
difference = thisHistoryLength - \
|
||||
history["index"] # 计算历史记录变化差值
|
||||
browser.execute_script(
|
||||
'history.go(' + str(difference) + ')') # 回退历史记录
|
||||
if node["parameters"]["historyWait"] > 2: # 回退后要等待的时间
|
||||
time.sleep(node["parameters"]["historyWait"])
|
||||
else:
|
||||
@ -186,7 +236,7 @@ def loopExcute(node, loopValue,clickPath="",index=0):
|
||||
elif int(node["parameters"]["loopType"]) == 2: # 固定元素列表
|
||||
for path in node["parameters"]["pathList"].split("\n"): # 千万不要忘了分割!!
|
||||
try:
|
||||
element = browser.find_element_by_xpath(path)
|
||||
element = browser.find_element(By.XPATH, path)
|
||||
for i in node["sequence"]: # 挨个执行操作
|
||||
excuteNode(i, element, path, 0)
|
||||
if browser.current_window_handle != thisHandle: # 如果执行完一次循环之后标签页的位置发生了变化
|
||||
@ -196,9 +246,11 @@ def loopExcute(node, loopValue,clickPath="",index=0):
|
||||
if browser.current_window_handle == thisHandle:
|
||||
break
|
||||
if history["index"] != thisHistoryLength and history[
|
||||
"handle"] == browser.current_window_handle: # 如果执行完一次循环之后历史记录发生了变化,注意当前页面的判断
|
||||
difference = thisHistoryLength - history["index"] # 计算历史记录变化差值
|
||||
browser.execute_script('history.go(' + str(difference) + ')') # 回退历史记录
|
||||
"handle"] == browser.current_window_handle: # 如果执行完一次循环之后历史记录发生了变化,注意当前页面的判断
|
||||
difference = thisHistoryLength - \
|
||||
history["index"] # 计算历史记录变化差值
|
||||
browser.execute_script(
|
||||
'history.go(' + str(difference) + ')') # 回退历史记录
|
||||
if node["parameters"]["historyWait"] > 2: # 回退后要等待的时间
|
||||
time.sleep(node["parameters"]["historyWait"])
|
||||
else:
|
||||
@ -216,16 +268,18 @@ def loopExcute(node, loopValue,clickPath="",index=0):
|
||||
for text in textList:
|
||||
recordLog("input: " + text)
|
||||
for i in node["sequence"]: # 挨个执行操作
|
||||
excuteNode(i, text, "",0)
|
||||
excuteNode(i, text, "", 0)
|
||||
elif int(node["parameters"]["loopType"]) == 4: # 固定网址列表
|
||||
pass # 以后再做
|
||||
history["index"] = thisHistoryLength
|
||||
history["handle"] = browser.current_window_handle
|
||||
scrollDown(node["parameters"])
|
||||
|
||||
|
||||
# 打开网页事件
|
||||
def openPage(para, loopValue):
|
||||
rt = Time("打开网页")
|
||||
time.sleep(2) # 打开网页后强行等待至少2秒
|
||||
global links
|
||||
global urlId
|
||||
global history
|
||||
@ -248,18 +302,7 @@ def openPage(para, loopValue):
|
||||
browser.execute_script('window.stop()')
|
||||
history["index"] = browser.execute_script("return history.length")
|
||||
rt.end()
|
||||
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")
|
||||
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()
|
||||
scrollDown(para, rt) # 控制屏幕向下滚动
|
||||
if containJudge:
|
||||
global bodyText # 每次执行点击,输入元素和打开网页操作后,需要更新bodyText
|
||||
try:
|
||||
@ -285,7 +328,7 @@ def inputInfo(para, loopValue):
|
||||
Log("输入前等待1秒")
|
||||
rt = Time("输入文字")
|
||||
try:
|
||||
textbox = browser.find_element_by_xpath(para["xpath"])
|
||||
textbox = browser.find_element(By.XPATH, para["xpath"])
|
||||
except:
|
||||
Log("找不到输入框元素:" + para["xpath"] + "请尝试执行前等待")
|
||||
recordLog("找不到输入框元素:" + para["xpath"] + "请尝试执行前等待")
|
||||
@ -313,7 +356,8 @@ def clickElement(para, loopElement=None, clickPath="", index=0):
|
||||
path = para["xpath"] # 不然使用元素定义的xpath
|
||||
tempHandleNum = len(browser.window_handles) # 记录之前的窗口位置
|
||||
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的点击方法
|
||||
|
||||
except TimeoutException:
|
||||
@ -343,24 +387,7 @@ def clickElement(para, loopElement=None, clickPath="", index=0):
|
||||
history["index"] = browser.execute_script("return history.length")
|
||||
rt.end()
|
||||
# 如果打开了新窗口,切换到新窗口
|
||||
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")
|
||||
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()
|
||||
scrollDown(para, rt) # 根据参数配置向下滚动
|
||||
if containJudge: # 有判断语句才执行以下操作
|
||||
global bodyText # 每次执行点击,输入元素和打开网页操作后,需要更新bodyText
|
||||
try:
|
||||
@ -393,13 +420,19 @@ def getData(para, loopElement, isInLoop=True):
|
||||
if p["relativeXpath"] == "": # 相对xpath有时候就是元素本身,不需要二次查找
|
||||
element = loopElement
|
||||
else:
|
||||
element = loopElement.find_element_by_xpath(p["relativeXpath"][1:])
|
||||
element = loopElement.find_element(By.XPATH,
|
||||
p["relativeXpath"][1:])
|
||||
else:
|
||||
element = browser.find_element_by_xpath(p["relativeXpath"])
|
||||
element = browser.find_element(By.XPATH, p["relativeXpath"])
|
||||
except NoSuchElementException: # 找不到元素的时候,使用默认值
|
||||
outputParameters[p["name"]] = p["default"]
|
||||
Log('Element not found,use default')
|
||||
recordLog('Element not found,use default')
|
||||
# print(p)
|
||||
try:
|
||||
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
|
||||
except TimeoutException: # 超时的时候设置超时值
|
||||
Log('time out after 10 seconds when getting data')
|
||||
@ -409,9 +442,10 @@ def getData(para, loopElement, isInLoop=True):
|
||||
if p["relativeXpath"] == "": # 相对xpath有时候就是元素本身,不需要二次查找
|
||||
element = loopElement
|
||||
else:
|
||||
element = loopElement.find_element_by_xpath(p["relativeXpath"][1:])
|
||||
element = loopElement.find_element(By.XPATH,
|
||||
p["relativeXpath"][1:])
|
||||
else:
|
||||
element = browser.find_element_by_xpath(p["relativeXpath"])
|
||||
element = browser.find_element(By.XPATH, p["relativeXpath"])
|
||||
rt.end()
|
||||
try:
|
||||
if p["contentType"] == 2:
|
||||
@ -428,7 +462,8 @@ def getData(para, loopElement, isInLoop=True):
|
||||
}\
|
||||
var str = arr.join(" "); \
|
||||
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 element.get_attribute("href") != None:
|
||||
content = element.get_attribute("href")
|
||||
@ -461,7 +496,7 @@ def getData(para, loopElement, isInLoop=True):
|
||||
content = element.get_attribute("src")
|
||||
else:
|
||||
content = ""
|
||||
except StaleElementReferenceException: #发生找不到元素的异常后,等待几秒重新查找
|
||||
except StaleElementReferenceException: # 发生找不到元素的异常后,等待几秒重新查找
|
||||
recordLog('StaleElementReferenceException:'+p["relativeXpath"])
|
||||
time.sleep(3)
|
||||
try:
|
||||
@ -470,10 +505,13 @@ def getData(para, loopElement, isInLoop=True):
|
||||
element = loopElement
|
||||
recordLog('StaleElementReferenceException:loopElement')
|
||||
else:
|
||||
element = loopElement.find_element_by_xpath(p["relativeXpath"][1:])
|
||||
recordLog('StaleElementReferenceException:loopElement+relativeXPath')
|
||||
element = loopElement.find_element(By.XPATH,
|
||||
p["relativeXpath"][1:])
|
||||
recordLog(
|
||||
'StaleElementReferenceException:loopElement+relativeXPath')
|
||||
else:
|
||||
element = browser.find_element_by_xpath(p["relativeXpath"])
|
||||
element = browser.find_element(
|
||||
By.XPATH, p["relativeXpath"])
|
||||
recordLog('StaleElementReferenceException:relativeXpath')
|
||||
if p["contentType"] == 2:
|
||||
content = element.get_attribute('innerHTML')
|
||||
@ -489,7 +527,8 @@ def getData(para, loopElement, isInLoop=True):
|
||||
}\
|
||||
var str = arr.join(" "); \
|
||||
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 element.get_attribute("href") != None:
|
||||
content = element.get_attribute("href")
|
||||
@ -524,7 +563,7 @@ def getData(para, loopElement, isInLoop=True):
|
||||
content = ""
|
||||
except StaleElementReferenceException:
|
||||
recordLog('StaleElementReferenceException:'+p["relativeXpath"])
|
||||
continue # 再出现类似问题直接跳过
|
||||
continue # 再出现类似问题直接跳过
|
||||
outputParameters[p["name"]] = content
|
||||
global OUTPUT
|
||||
line = []
|
||||
@ -541,13 +580,12 @@ def isnull(s):
|
||||
return len(s) != 0
|
||||
|
||||
|
||||
import atexit #遇到错误退出时应执行的代码
|
||||
@atexit.register
|
||||
def clean():
|
||||
global saveName,log, OUTPUT,browser,SAVED
|
||||
global saveName, log, OUTPUT, browser, SAVED
|
||||
if not SAVED:
|
||||
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.close()
|
||||
with open("Data/"+saveName + '.csv', 'w', encoding='utf-8-sig', newline="") as f:
|
||||
@ -557,42 +595,53 @@ def clean():
|
||||
f.close()
|
||||
browser.quit()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
options = Options()
|
||||
exe_path = "chromedriver.exe"
|
||||
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"):
|
||||
options.binary_location="Debug/Chrome/chrome.exe" #指定chrome位置
|
||||
elif os.getcwd().find("ExcuteStage") >= 0: #如果直接执行
|
||||
options.binary_location = "../../bin/x64/Debug/Chrome/chrome.exe" # 指定chrome位置
|
||||
options.binary_location = "Debug/Chrome/chrome.exe" # 指定chrome位置
|
||||
exe_path = "Debug/Chrome/chromedriver.exe"
|
||||
elif os.getcwd().find("ExcuteStage") >= 0: # 如果直接执行
|
||||
options.binary_location = "./Chrome/chrome.exe" # 指定chrome位置
|
||||
exe_path = "./Chrome/chromedriver.exe"
|
||||
else:
|
||||
options.binary_location="chrome.exe" #指定chrome位置
|
||||
browser = webdriver.Chrome(chrome_options=options)
|
||||
options.binary_location = "chrome.exe" # 指定chrome位置
|
||||
browser = webdriver.Chrome(options=options, executable_path=exe_path)
|
||||
browser.get('about:blank')
|
||||
browser.set_page_load_timeout(10) # 加载页面最大超时时间
|
||||
if len(sys.argv)>1:
|
||||
id = int(sys.argv[1]) #taskId这里修改
|
||||
browser.set_page_load_timeout(10) # 加载页面最大超时时间
|
||||
browser.set_script_timeout(10)
|
||||
if len(sys.argv) > 1:
|
||||
id = int(sys.argv[1]) # taskId这里修改
|
||||
else:
|
||||
id = 7 #设置默认值
|
||||
print("id:",id)
|
||||
if len(sys.argv)>2:
|
||||
saveName = "task_" + str(id) + "_" + sys.argv[2] # 保存文件的名字
|
||||
id = 7 # 设置默认值
|
||||
print("id:", id)
|
||||
if len(sys.argv) > 2:
|
||||
backEndAddress = sys.argv[2]
|
||||
else:
|
||||
saveName = "task_" + str(id) + "_" + str(random.randint(0, 999999999)) # 保存文件的名字
|
||||
content = requests.get("http://183.129.170.180:8041/backEnd/queryTask?id=" + str(id))
|
||||
backEndAddress = "http://servicewrapper.naibo.wang"
|
||||
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) # 加载服务信息
|
||||
print("name:",service["name"])
|
||||
print("name:", service["name"])
|
||||
procedure = service["graph"] # 程序执行流程
|
||||
links = list(filter(isnull, service["links"].split("\n"))) # 要执行的link的列表
|
||||
OUTPUT = [] # 采集的数据
|
||||
OUTPUT.append([]) # 添加表头
|
||||
containJudge = service["containJudge"] #是否含有判断语句
|
||||
containJudge = service["containJudge"] # 是否含有判断语句
|
||||
bodyText = "" # 记录bodyText
|
||||
tOut = service["outputParameters"] # 生成输出参数对象
|
||||
outputParameters = {}
|
||||
log = "" # 记下现在总共开了多少个标签页
|
||||
history = {"index":0,"handle":None} #记录页面现在所以在的历史记录的位置
|
||||
SAVED=False #记录是否已经存储了
|
||||
history = {"index": 0, "handle": None} # 记录页面现在所以在的历史记录的位置
|
||||
SAVED = False # 记录是否已经存储了
|
||||
for para in tOut:
|
||||
outputParameters[para["name"]] = ""
|
||||
OUTPUT[0].append(para["name"])
|
||||
@ -604,7 +653,7 @@ if __name__ == '__main__':
|
||||
print("执行完成!")
|
||||
recordLog("Done!")
|
||||
# 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.close()
|
||||
with open("Data/"+saveName + '.csv', 'w', encoding='utf-8-sig', newline="") as f:
|
||||
|
@ -1,28 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCuAZmXoS3RN1dQ
|
||||
IWpPjMZMX08JQRiR9XF8fPuZ4r/aauafNKncQmC2FEFylAcBMaRVSjAsZlXVqTlE
|
||||
s1LRtt9PiJEiDv73alerwznzNfuN0Dqrj2YpvKlck/sdFDeJNGi3dAl4kWZOKlE0
|
||||
kpHXO6BQBKB9t9Up5qBku0epGYNZ6/foCl82U5bw8bBaZ5p0F2hhE4/PWP0p/MED
|
||||
HR7yvnr5qO0B6qQia/59q4opxH6sswa6XAc3mgU1Yq8m1cXRctmvxCBt7biU7Gpw
|
||||
jLB4Qdgikq02hWxn1YUbGAjHRjLrNxOIFBP6Sx2SNllM664bUmzwchnEzsLILyDQ
|
||||
jzKlafobAgMBAAECggEAGdp7APXIYkbKs56DYSvAECYzuWLxTPPJgimVExmG+o4v
|
||||
kzAL8iyamfMLK676wMlTaqi0h6RHfztpcDUEn8wqrx0naIa53fZFmGulTJGUvU6s
|
||||
U5k2y19l+oSyJsaTidCTo85F1KLQhISdFCaYLKvbTIhOIDUUIumf+IIq9OD+4c6C
|
||||
nhAKhkjspDt1ctyFy9QXE5Wbi6o8AdOuaw9QW+y7msi1kcTWovxFBQkN1Ck4D2m7
|
||||
y72M5dDYq3nWEyQDJvioDM2yxvywiX3piHjULBj60Ybt52EEyRNlBMkbafU0puYU
|
||||
aajlPSv0X0mQjdtYLmd2dEVTH5rNLkVRwtx0i5MYoQKBgQDnJkJY6sj6HzhnFtWo
|
||||
NiorwAteNG6fIchZPAJjdtAQNu2stakGtnRoQ3WfVi2ePUKntoyqS4WanJE/z4pX
|
||||
lTMAePB8madwqe+AgSJzl0+YnOqBQCk6DeIrJ9u0O+nb7wlkZMbaULj6Sx8bg+N4
|
||||
jM/MSD4uo1eYJdo6bIq6KNHXTQKBgQDAtqJlZ+EweMD9K652htwW0HE0IXD7zxMh
|
||||
8rODaubAp+glapW77GYltFrJ++Q8ObBdm+jLo8CbWUTus61qpsinv+CV//dIEiYp
|
||||
vbdf+oFnCEHvFTN1opzsS9ThYZhRnnonuxYmMCWsx55GG7oyAVtYLBUERm6XurLY
|
||||
FXkceAvzBwKBgD/UB8Qn6SFwV5HX813EvzZfjIQR9G4K1RkXAg3XNDMWB+GGNEt/
|
||||
PHvCDQvXrzcf8XUAaq1nt1fvXgiB1dDDiVbbDoVJpLvuoQ0aG5pRsRASXIseXYQD
|
||||
a23BTuDhHn217yEC1wpX+gxbjBZ7/+c88vCVDl6wijKgWTeC23f2Z6ONAoGAP2CQ
|
||||
3cqg+2DrDxe7g41sejBI2n0Y/CcowqRftxuEEd3mcc+wuKHRIhtDNGQbtla+krqA
|
||||
f+A1qqFcEyiSIp4BJXHr+Ui52UDmvhl/YhgvUGQd0vPk/Y3iD7AMraZ8AnOc9s4H
|
||||
Rb3V1hG8EpBx1potoTy2GLbVDh8/S+Mb9mngfCcCgYEAlL/oEGR6j7K/29gF8KjQ
|
||||
J6HfNxdisP0b14her/mX0NSSv8WNFX77XO6pjXmpiIQPsm4I1KlzeFEVBy9RetGb
|
||||
5OKLQdfILNe8aDrYxMKcjbuA9zLqIzYep8siLdrYI1RDSxKt7ZUW6JejPthV0vr5
|
||||
408+uF8kwRJscoRPn7+x7Uk=
|
||||
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCr3o0YTuz2UMy7
|
||||
qolwd4CWXet3SjJL0XawKKgp3ZRo78zER1Z/LQ5/rZqc6DISBPCycAoOCBk2EcBZ
|
||||
IlPKQFxq1PMj10ccyswjjb+4mf4ZRVveeflBqT9I4khrzwk9gymSZiD7TbkDc4fp
|
||||
oxoHCv2f7VMR5m/IwsnXEsm7QyuRSA6ETbhp2Faa2CIGI4l6r+gtuVYkUSGEN/0H
|
||||
0dk3kfh6rcjwvroLSzWcGJnhyOLDYxnV1kTHZDUBzGj0UOqL0fdpAuyXxSikadxa
|
||||
Ec4BZ4s3GHIlFR5N7itrwYN28IInLObxUQXJ3unEdnon/T/XhC5KsdjMp8D6Xb8/
|
||||
0dObgaG/AgMBAAECggEAR0xyZQCs/fwECuBS1uTEY9y/h4OwvNI+9hJPvNpurF+6
|
||||
pzxe7jBPYPkweGI9D0ucXLHtAegrKUqQ7Ik4kGFF1Y3U9evjVNbue9tciyTbDDnB
|
||||
RFh+ZlZjagVxfMPtNeb5MoIKsaYLGBrv6aUfcYeGMre96+GYQwVHvWDOblCNvN0k
|
||||
fBInSGlDcLkx9EJ9vFbCf8IErg4RWtiEdSvSG1s99IPc17j4cJn4qq9OyQrECpdz
|
||||
y7AnkvsMOiOzQawO+C2I5SgA26eaxNJrz/3ph4r1x1iCdPvY7iD/awkQXCgid6kq
|
||||
Z0R8ByxTbwqr4NYXtUyHVkwiL9QZSKjnvrOfdmm0iQKBgQDkQ5KRMftmDi9cJfOj
|
||||
0xY/TwCymsWp+MdMQ6YKAd57oMM+2DzgZ//LFgo4rcYWjTGlErE8tXhT4fM5PEUQ
|
||||
1CgwozmkPcVnRzLyiNWNpiMCzPVPsXDxzoEQFHL0qLA/Xj7npH5d+Eg6yunDc9JS
|
||||
D/OlqSEZQ6W4lWFvAkz7Mh5M6QKBgQDAwMFzAMYVXwcRmH0gvzmqA46MqjdfaXyq
|
||||
NzNADiVCaGgqYpNygeftiHGCBQiXr3QkVVp+XihbY/5KnzVYiS0ICKMCwqxizvRT
|
||||
gR3N4+UyVaK9FTWLgtSu8VN4JM3E+nigBO/QfD4WI4VZ3tZEsOveV70j97NpfaPN
|
||||
lhjr2J0wZwKBgG3pj7i0bY5dxDZF3ASFjw/a9cYKuqU2spipdlkZP00eQwWOz/lq
|
||||
eoQKz88s9dZEFKSc1JUb+J3Djf+AYu1Qiy2oWwgX6mbppMGeW95CIlel43WFRpJY
|
||||
0lKw1g2y8HMC6Z1W2rZa6ETPEjLYIWz8W2DoiJSGu1SfMXRnkjPelTKJAoGACvbs
|
||||
Ci6xFeYh8M5Lz+EQ1qr9IONN4w+NF+Gr+KjVVcG6qy6QVKMvHkP0sQC4TGieorJ4
|
||||
Q1f307sMbBJCZpbnCN305+NLCxPasiVWHLAqCYL1juv178mxb4IqzVrKmbnlwrSF
|
||||
L8bhgUDkBQi4B5BI2o0DJVihzA5pkvhG0qOvzWECgYAHITSiOJBF1Lr0hw7JnS5r
|
||||
Hre8bQdbDeqSd5iRM/+0MJnBvkp7RDgvh0c01Wc90A0gjhhPqBS9z5UNptiJKhJQ
|
||||
kYDP7iiftM7FsG45IGKf6RrulLk6pCyFEFb/roBlC1xy/6uNCqAHbd+6K6UjQAFB
|
||||
+c9hCtSDDh3/irZrY34lDw==
|
||||
-----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"; //如果是服务器网页页面,则不执行工具
|
||||
}
|
||||
|
||||
|
@ -1,50 +1,50 @@
|
||||
//表现逻辑层的处理
|
||||
|
||||
if (window.location.href.indexOf("183.129.170.180") >= 0) {
|
||||
if (window.location.href.indexOf("backEndAddressServiceWrapper") >= 0) {
|
||||
throw "serviceGrid"; //如果是服务器网页页面,则不执行工具
|
||||
}
|
||||
|
||||
//Vue元素
|
||||
//Vueelement
|
||||
var app;
|
||||
generateToolkit();
|
||||
//生成Toolkit
|
||||
function generateToolkit() {
|
||||
$(".tooltips").html(`
|
||||
<div id="realcontent">
|
||||
<div class="tooldrag">✍操作提示框(可点此拖动)</div>
|
||||
<div class="tooldrag">✍Operation Toolbox (Can drag)</div>
|
||||
<div class="realcontent">
|
||||
<div v-if="page==0">
|
||||
<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">
|
||||
<p style="color:black">● 鼠标移动到元素上后,请<strong>右键</strong>点击或者按<strong>F7</strong>键选中页面元素。</p>
|
||||
<p style="color:black">● 如果不小心左键点选了元素导致页面跳转,直接后退或者切换回标签页即可。</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">● You can click the back button to go back to the page</p>
|
||||
{{initial()}}
|
||||
</div>
|
||||
<div v-if="list.nl.length==1">
|
||||
<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 v-if="numOfReady()>0 && !selectStatus"> <a v-on:mousedown="selectAll">选中全部</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="numOfReady()>0 && !selectStatus"> <a v-on:mousedown="selectAll">Select All</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="tname()=='选择框'"> <a>循环切换下拉选项</a><span title="">☺</span></div>
|
||||
<div v-if="tname()=='文本框'"> <a v-on:mousedown="setInput">输入文字</a><span title="">☺</span></div>
|
||||
<div v-if="tname()!='图片'"> <a v-on:mousedown="getText">采集该{{tname()}}的文本</a><span title="采集文本">☺</span></div>
|
||||
<div v-if="tname()=='选择框'"> <a>采集选中项的文本</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()!='选择框' && tname()!='文本框'"> <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()=='链接'||tname()=='元素'"> <a v-on:mousedown="getInnerHtml">采集该{{tname()}}的Inner Html</a><span title="">☺</span></div>
|
||||
<div v-if="tname()=='selection box'"> <a>---------</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()!='Image'"> <a v-on:mousedown="getText">Collect {{tname()}}'s text</a><span title="collet text">☺</span></div>
|
||||
<div v-if="tname()=='selection box'"> <a>采集选中项的text</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()!='selection box' && tname()!='text box'"> <a v-on:mousedown="clickElement">点击该{{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()=='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 href="#">鼠标移动到该{{tname()}}上</a><span title="">☺</span></div>
|
||||
<div v-if="tname()=='文本框'"> <a>识别验证码</a><span title="">☺</span></div>
|
||||
<div> <a href="#">----{{tname()}}-</a><span title="">☺</span></div>
|
||||
<div v-if="tname()=='text box'"> <a>-----</a><span title="">☺</span></div>
|
||||
</div>
|
||||
<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 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>
|
||||
@ -53,21 +53,21 @@ function generateToolkit() {
|
||||
<div v-if="list.nl.length>1">
|
||||
|
||||
<div v-if="option==100">
|
||||
● 已选择了以下元素,您可以:
|
||||
● 已select了以下element,您可以:
|
||||
<div class="innercontent">
|
||||
<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 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 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 v-if="tname()!='选择框' && tname()!='文本框' && !selectedDescendents"> <a v-on:mousedown="loopClickEveryElement">循环点击每个{{tname()}}</a><span title="">☺</span></div>
|
||||
<div> <a v-on:mousedown="revoke">撤销本次选择</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">撤销本次selection</a><span title="">☺</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -91,11 +91,11 @@ function generateToolkit() {
|
||||
</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 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>
|
||||
</div>
|
||||
<p style="margin-left:16px;margin-bottom:0px">{{lastElementXPath()}}</p>
|
||||
@ -116,14 +116,14 @@ function generateToolkit() {
|
||||
data: {
|
||||
option: 0,
|
||||
list: { nl: nodeList, opp: outputParameters },
|
||||
valTable: [], // 用来存储转换后的参数列表
|
||||
special: false, //是否为特殊选择模式
|
||||
selectedDescendents: false, // 标记是否选中了子元素
|
||||
selectStatus: false, //标记单个元素是否点击了采集
|
||||
valTable: [], // 用来存储转换后的para列表
|
||||
special: false, //是否为特殊selection模式
|
||||
selectedDescendents: false, // 标记是否选中了子element
|
||||
selectStatus: false, //标记单个element是否点击了采集
|
||||
page: 0, //默认页面,1为输入文字页面
|
||||
text: "", // 记录输入的文字
|
||||
tNodeName: "", // 记录临时节点列表
|
||||
nowPath: "", //现在元素的xpath
|
||||
nowPath: "", //现在element的xpath
|
||||
},
|
||||
watch: {
|
||||
nowPath: { //变量发生变化的时候进行一些操作
|
||||
@ -133,34 +133,34 @@ function generateToolkit() {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initial: function() { //每当元素是0的时候,执行值的初始化操作
|
||||
initial: function() { //每当element是0的时候,执行值的初始化操作
|
||||
this.selectedDescendents = false;
|
||||
this.selectStatus = false;
|
||||
this.nowPath = "";
|
||||
},
|
||||
confirmCollectSingle: function() { //单元素确认采集
|
||||
confirmCollectSingle: function() { //单element确认采集
|
||||
collectSingle();
|
||||
clearEl();
|
||||
},
|
||||
confirmCollectMulti: function() { //无规律多元素确认采集
|
||||
confirmCollectMulti: function() { //无规律多element确认采集
|
||||
collectMultiNoPattern();
|
||||
clearEl();
|
||||
},
|
||||
confirmCollectMultiAndDescendents: function() { //有规律多元素确认采集
|
||||
confirmCollectMultiAndDescendents: function() { //有规律多element确认采集
|
||||
collectMultiWithPattern();
|
||||
clearEl();
|
||||
},
|
||||
deleteSingleLine: function(event) { //删除单行元素
|
||||
deleteSingleLine: function(event) { //删除单行element
|
||||
let at = new Date().getTime()
|
||||
//流程图送元素的时候,默认的使用不固定循环列表,但是一旦有删除元素的操作发生,则按照固定元素列表采集元素
|
||||
//流程图送element的时候,默认的使用不固定循环列表,但是一旦有删除element的操作发生,则按照固定element列表采集element
|
||||
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.boxShadow = tnode["boxShadow"];
|
||||
if (nodeList.length > 1) { // 如果删到没有就没有其他的操作了
|
||||
handleElement();
|
||||
if (this.selectedDescendents) {
|
||||
handleDescendents(); //如果之前有选中子元素,新加入的节点又则这里也需要重新选择子元素
|
||||
handleDescendents(); //如果之前有选中子element,新加入的节点又则这里也需要重新selection子element
|
||||
}
|
||||
} else {
|
||||
this.valTable = [];
|
||||
@ -170,25 +170,25 @@ function generateToolkit() {
|
||||
let at2 = parseInt(new Date().getTime());
|
||||
console.log("delete:", at2, at, at2 - at);
|
||||
},
|
||||
clickElement: function() { //点击元素操作
|
||||
clickElement: function() { //点击element操作
|
||||
sendSingleClick();
|
||||
//先发送数据
|
||||
nodeList[0]["node"].focus(); //获得元素焦点
|
||||
nodeList[0]["node"].click(); //点击元素
|
||||
nodeList[0]["node"].focus(); //获得element焦点
|
||||
nodeList[0]["node"].click(); //点击element
|
||||
clearEl();
|
||||
},
|
||||
loopClickSingleElement: function() { //循环点击单个元素
|
||||
sendLoopClickSingle(this.tname()); //识别下一页,循环点击单个元素和点击多个元素
|
||||
if (this.tname() != "下一页元素") { //下一页元素不进行点击操作
|
||||
nodeList[0]["node"].focus(); //获得元素焦点
|
||||
nodeList[0]["node"].click(); //点击元素
|
||||
loopClickSingleElement: function() { //循环点击单个element
|
||||
sendLoopClickSingle(this.tname()); //识别下一页,循环点击单个element和点击多个element
|
||||
if (this.tname() != "Elements in next page") { //Elements in next page不进行点击操作
|
||||
nodeList[0]["node"].focus(); //获得element焦点
|
||||
nodeList[0]["node"].click(); //点击element
|
||||
}
|
||||
clearEl();
|
||||
},
|
||||
loopClickEveryElement: function() { //循环点击每个元素
|
||||
sendLoopClickEvery(); //识别下一页,循环点击单个元素和点击多个元素
|
||||
nodeList[0]["node"].focus(); //获得元素焦点
|
||||
nodeList[0]["node"].click(); //点击元素
|
||||
loopClickEveryElement: function() { //循环点击每个element
|
||||
sendLoopClickEvery(); //识别下一页,循环点击单个element和点击多个element
|
||||
nodeList[0]["node"].focus(); //获得element焦点
|
||||
nodeList[0]["node"].click(); //点击element
|
||||
clearEl();
|
||||
},
|
||||
setInput: function() { //输入文字
|
||||
@ -199,7 +199,7 @@ function generateToolkit() {
|
||||
},
|
||||
getInput: function() { //得到输入的文字
|
||||
nodeList[0]["node"].focus(); //获得文字焦点
|
||||
// nodeList[0]["node"].setAttribute("value", this.text); // 设置输入框内容
|
||||
// nodeList[0]["node"].setAttribute("value", this.text); // 设置输入 box内容
|
||||
input(this.text); // 设置输入
|
||||
this.text = "";
|
||||
clearEl();
|
||||
@ -207,7 +207,7 @@ function generateToolkit() {
|
||||
cancelInput: function() {
|
||||
this.page = 0;
|
||||
},
|
||||
setWidth: function(width) { //根据是否出现表格调整最外框宽度
|
||||
setWidth: function(width) { //根据是否出现表格调整最外 box宽度
|
||||
$(".tooltips").css("width", width);
|
||||
return "";
|
||||
},
|
||||
@ -216,7 +216,7 @@ function generateToolkit() {
|
||||
this.selectStatus = true;
|
||||
clearReady();
|
||||
},
|
||||
getLink: function() { //采集链接地址
|
||||
getLink: function() { //采集linkAddress
|
||||
generateParameters(0, false, true);
|
||||
this.selectStatus = true;
|
||||
clearReady();
|
||||
@ -243,22 +243,22 @@ function generateToolkit() {
|
||||
return "null";
|
||||
} else if ($(nodeList[0]["node"]).contents().filter(function() { return this.nodeType === 3; }).text().indexOf("下一页") >= 0) {
|
||||
this.setWidth("250px");
|
||||
return "下一页元素";
|
||||
return "Elements in next page";
|
||||
} else if (tag == "A") {
|
||||
return "链接";
|
||||
return "link";
|
||||
} else if (tag == "IMG") {
|
||||
return "图片";
|
||||
return "Image";
|
||||
} else if (tag == "BUTTON" || (tag == "INPUT" && (inputType == "button" || inputType == "submit"))) {
|
||||
return "按钮";
|
||||
} else if (tag == "TEXTAREA" || (tag == "INPUT" && (inputType != "checkbox" || inputType != "ratio"))) { //普通输入框
|
||||
return "文本框";
|
||||
return "Button";
|
||||
} else if (tag == "TEXTAREA" || (tag == "INPUT" && (inputType != "checkbox" || inputType != "ratio"))) { //普通输入 box
|
||||
return "text box";
|
||||
} else if (tag == "SELECT") {
|
||||
return "选择框";
|
||||
return "selection box";
|
||||
} else {
|
||||
return "元素";
|
||||
return "element";
|
||||
}
|
||||
},
|
||||
existDescendents: function() { //检测选中的元素是否存在子元素,已经选中了子元素也不要再出现了
|
||||
existDescendents: function() { //检测选中的element是否存在子element,已经选中了子element也不要再出现了
|
||||
return nodeList.length > 0 && nodeList[0]["node"].children.length > 0 && !this.selectedDescendents;
|
||||
},
|
||||
numOfReady: function() {
|
||||
@ -267,11 +267,11 @@ function generateToolkit() {
|
||||
numOfList: function() {
|
||||
return nodeList.length;
|
||||
},
|
||||
lastElementXPath: function() { //用来显示元素的最大最后5个xpath路劲元素
|
||||
lastElementXPath: function() { //用来显示element的最大最后5个xpath路劲element
|
||||
path = nodeList[nodeList.length - 1]["xpath"];
|
||||
path = path.split("/");
|
||||
tp = "";
|
||||
if (path.length > 5) { //只保留最后五个元素
|
||||
if (path.length > 5) { //只保留最后五个element
|
||||
path = path.splice(path.length - 5, 5);
|
||||
tp = ".../"
|
||||
}
|
||||
@ -285,7 +285,7 @@ function generateToolkit() {
|
||||
cancel: function() {
|
||||
clearEl();
|
||||
},
|
||||
specialSelect: function() { //特殊选择模式
|
||||
specialSelect: function() { //特殊selection模式
|
||||
if (mousemovebind) {
|
||||
tdiv.style.pointerEvents = "none";
|
||||
this.special = false;
|
||||
@ -294,10 +294,10 @@ function generateToolkit() {
|
||||
}
|
||||
mousemovebind = !mousemovebind;
|
||||
},
|
||||
enlarge: function() { // 扩大选区功能,总是扩大最后一个选中的元素的选区
|
||||
enlarge: function() { // 扩大选区功能,总是扩大最后一个选中的element的选区
|
||||
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.boxShadow = nodeList[nodeList.length - 1]["boxShadow"]; //之前元素恢复原来的背景颜色
|
||||
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"]; //之前element恢复原来的背景颜色
|
||||
tNode = nodeList[nodeList.length - 1]["node"].parentNode; //向上走一层
|
||||
if (tNode != NowNode) { //扩大选区之后背景颜色的判断,当前正好选中的颜色应该是不同的
|
||||
sty = tNode.style.backgroundColor;
|
||||
@ -307,7 +307,7 @@ function generateToolkit() {
|
||||
nodeList[nodeList.length - 1]["node"] = tNode;
|
||||
nodeList[nodeList.length - 1]["bgColor"] = sty;
|
||||
nodeList[nodeList.length - 1]["xpath"] = readXPath(tNode, 1);
|
||||
//显示框
|
||||
//显示 box
|
||||
var pos = tNode.getBoundingClientRect();
|
||||
div.style.display = "block";
|
||||
div.style.height = tNode.offsetHeight + "px";
|
||||
@ -316,39 +316,39 @@ function generateToolkit() {
|
||||
div.style.top = pos.top + "px";
|
||||
div.style.zIndex = 2147483645;
|
||||
div.style.pointerEvents = "none";
|
||||
handleElement(); //每次数组元素有变动,都需要重新处理下
|
||||
handleElement(); //每次数组element有变动,都需要重新处理下
|
||||
oe = tNode;
|
||||
tNode.style.backgroundColor = "rgba(0,191,255,0.5)";
|
||||
this.selectedDescendents = false;
|
||||
}
|
||||
},
|
||||
selectAll: function() { //选中全部元素
|
||||
selectAll: function() { //选中全部element
|
||||
step++;
|
||||
readyToList(step, false);
|
||||
handleElement();
|
||||
if (this.selectedDescendents) {
|
||||
handleDescendents(); //如果之前有选中子元素,新加入的节点又则这里也需要重新选择子元素
|
||||
handleDescendents(); //如果之前有选中子element,新加入的节点又则这里也需要重新selection子element
|
||||
}
|
||||
},
|
||||
revoke: function() { //撤销选择当前节点
|
||||
revoke: function() { //撤销selection当前节点
|
||||
var tstep = step;
|
||||
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]; //删除数组最后一项
|
||||
node["node"].style.backgroundColor = node["bgColor"]; //还原原始属性和边框
|
||||
node["node"].style.backgroundColor = node["bgColor"]; //还原原始属性和边 box
|
||||
node["node"].style.boxShadow = node["boxShadow"];
|
||||
if (NowNode == node["node"]) {
|
||||
style = node["bgColor"];
|
||||
}
|
||||
//处理已经有选中子元素的情况
|
||||
//处理已经有选中子element的情况
|
||||
// if (this.selectedDescendents) {
|
||||
clearParameters(); //直接撤销重选
|
||||
// }
|
||||
}
|
||||
handleElement(); //每次数组元素有变动,都需要重新处理下
|
||||
handleElement(); //每次数组element有变动,都需要重新处理下
|
||||
},
|
||||
selectDescendents: function() { //选择所有子元素操作
|
||||
selectDescendents: function() { //selection所有子element操作
|
||||
handleDescendents();
|
||||
}
|
||||
},
|
||||
@ -358,7 +358,7 @@ function generateToolkit() {
|
||||
if (difference > 0) {
|
||||
$(".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) {
|
||||
this.clearInterval(); //先取消原来的计时器,再设置新的计时器
|
||||
document.body.append(div); //默认如果toolkit不存在则div和tdiv也不存在
|
||||
@ -381,10 +381,10 @@ function generateToolkit() {
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
//每次对元素进行增删之后需要执行的操作
|
||||
//每次对element进行增删之后需要执行的操作
|
||||
function handleElement() {
|
||||
clearReady(); //预备元素每次处理都先处理掉
|
||||
if (nodeList.length > 1) { //选中了许多元素的情况
|
||||
clearReady(); //预备element每次处理都先处理掉
|
||||
if (nodeList.length > 1) { //选中了许多element的情况
|
||||
app._data.option = relatedTest();
|
||||
if (app._data.option == 100) {
|
||||
generateMultiParameters();
|
||||
@ -392,13 +392,13 @@ function handleElement() {
|
||||
generateParameters(0);
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
@ -406,20 +406,20 @@ function clearParameters(deal = true) //清空参数列表
|
||||
o["node"].style.boxShadow = o["boxShadow"];
|
||||
}
|
||||
outputParameterNodes.splice(0);
|
||||
outputParameters.splice(0); //清空原来的参数列表
|
||||
outputParameters.splice(0); //清空原来的para列表
|
||||
app._data.valTable = []; //清空展现数组
|
||||
app._data.selectStatus = false;
|
||||
}
|
||||
|
||||
|
||||
//根据nodelist列表内的元素生成参数列表
|
||||
//适合:nodelist中的元素为同类型元素
|
||||
//type:0为全部文本 1为节点内直接的文字 2为innerhtml 3为outerhtml
|
||||
//根据nodelist列表内的element生成para列表
|
||||
//适合:nodelist中的element为同类型element
|
||||
//type:0为全部text 1为节点内直接的文字 2为innerhtml 3为outerhtml
|
||||
//nodetype:0,对应全type0123
|
||||
//nodetype:1 链接,对应type0123
|
||||
//nodetype:2 链接地址 对应type0
|
||||
//nodetype:3 按钮和输入文本框 对应type
|
||||
//nodetype:4 按钮和输入文本框 对应type
|
||||
//nodetype:1 link,对应type0123
|
||||
//nodetype:2 linkAddress 对应type0
|
||||
//nodetype:3 按钮和输入text box 对应type
|
||||
//nodetype:4 按钮和输入text box 对应type
|
||||
|
||||
function generateParameters(type, linktext = true, linkhref = true) {
|
||||
clearParameters(false);
|
||||
@ -432,23 +432,23 @@ function generateParameters(type, linktext = true, linkhref = true) {
|
||||
ndPath = nodeList[num]["xpath"];
|
||||
outputParameterNodes.push({ "node": nd, "boxShadow": nd.style.boxShadow == "" || boxShadowColor ? "none" : nd.style.boxShadow });
|
||||
nd.style.boxShadow = boxShadowColor;
|
||||
let pname = "文本";
|
||||
let pname = "text";
|
||||
let ndText = "";
|
||||
if (type == 0) {
|
||||
ndText = $(nd).text();
|
||||
pname = "文本";
|
||||
pname = "text";
|
||||
if (nd.tagName == "IMG") {
|
||||
ndText = nd.getAttribute("src") == null ? "" : $(nd).prop("src");
|
||||
pname = "地址";
|
||||
pname = "Address";
|
||||
} else if (nd.tagName == "INPUT") {
|
||||
ndText = nd.getAttribute("value") == null ? "" : nd.getAttribute("value");
|
||||
}
|
||||
} else if (type == 1) {
|
||||
ndText = $(nd).contents().filter(function() { return this.nodeType === 3; }).text().replace(/\s+/g, '');
|
||||
pname = "文本";
|
||||
pname = "text";
|
||||
if (nd.tagName == "IMG") {
|
||||
ndText = nd.getAttribute("src") == null ? "" : $(nd).prop("src");
|
||||
pname = "地址";
|
||||
pname = "Address";
|
||||
} else if (nd.tagName == "INPUT") {
|
||||
ndText = nd.getAttribute("value") == null ? "" : nd.getAttribute("value");
|
||||
}
|
||||
@ -460,24 +460,24 @@ function generateParameters(type, linktext = true, linkhref = true) {
|
||||
pname = "outerHTML";
|
||||
}
|
||||
if (num == 0) { //第一个节点新建,后面的增加即可
|
||||
if (nd.tagName == "IMG") { //如果元素是图片
|
||||
if (nd.tagName == "IMG") { //如果element是Image
|
||||
outputParameters.push({
|
||||
"nodeType": 4, //节点类型
|
||||
"contentType": type, // 内容类型
|
||||
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径
|
||||
"name": "参数" + (n++) + "_图片" + pname,
|
||||
"desc": "", //参数描述
|
||||
"name": "para" + (n++) + "_Image" + pname,
|
||||
"desc": "", //para描述
|
||||
"relativeXpath": nodeList.length > 1 ? "" : ndPath,
|
||||
"exampleValues": [{ "num": num, "value": ndText }]
|
||||
});
|
||||
} else if (nd.tagName == "A") { //如果元素是超链接
|
||||
} else if (nd.tagName == "A") { //如果element是超link
|
||||
if (linktext) {
|
||||
outputParameters.push({
|
||||
"nodeType": 1,
|
||||
"contentType": type, // 内容类型
|
||||
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径
|
||||
"name": "参数" + (n++) + "_链接" + pname,
|
||||
"desc": "", //参数描述
|
||||
"name": "para" + (n++) + "_link" + pname,
|
||||
"desc": "", //para描述
|
||||
"relativeXpath": nodeList.length > 1 ? "" : ndPath,
|
||||
"exampleValues": [{ "num": num, "value": ndText }]
|
||||
});
|
||||
@ -487,19 +487,19 @@ function generateParameters(type, linktext = true, linkhref = true) {
|
||||
"nodeType": 2,
|
||||
"contentType": type, // 内容类型
|
||||
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径
|
||||
"name": "参数" + (n++) + "_链接地址",
|
||||
"desc": "", //参数描述
|
||||
"name": "para" + (n++) + "_linkAddress",
|
||||
"desc": "", //para描述
|
||||
"relativeXpath": nodeList.length > 1 ? "" : ndPath,
|
||||
"exampleValues": [{ "num": num, "value": nd.getAttribute("href") == null ? "" : $(nd).prop("href") }]
|
||||
});
|
||||
}
|
||||
} else if (nd.tagName == "INPUT") { //如果元素是输入项
|
||||
} else if (nd.tagName == "INPUT") { //如果element是输入项
|
||||
outputParameters.push({
|
||||
"nodeType": 3,
|
||||
"contentType": type, // 内容类型
|
||||
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径
|
||||
"name": "参数" + (n++) + "_" + pname,
|
||||
"desc": "", //参数描述
|
||||
"name": "para" + (n++) + "_" + pname,
|
||||
"desc": "", //para描述
|
||||
"relativeXpath": nodeList.length > 1 ? "" : ndPath,
|
||||
"exampleValues": [{ "num": num, "value": ndText }]
|
||||
});
|
||||
@ -508,19 +508,19 @@ function generateParameters(type, linktext = true, linkhref = true) {
|
||||
"nodeType": 0,
|
||||
"contentType": type, // 内容类型
|
||||
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径
|
||||
"name": "参数" + (n++) + "_" + pname,
|
||||
"desc": "", //参数描述
|
||||
"name": "para" + (n++) + "_" + pname,
|
||||
"desc": "", //para描述
|
||||
"relativeXpath": nodeList.length > 1 ? "" : ndPath,
|
||||
"exampleValues": [{ "num": num, "value": ndText }]
|
||||
});
|
||||
}
|
||||
} else { //如果元素节点已经存在,则只需要插入值就可以了
|
||||
if (nd.tagName == "IMG") { //如果元素是图片
|
||||
} else { //如果element节点已经存在,则只需要插入值就可以了
|
||||
if (nd.tagName == "IMG") { //如果element是Image
|
||||
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[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 });
|
||||
} else { //其他所有情况
|
||||
outputParameters[0]["exampleValues"].push({ "num": num, "value": ndText });
|
||||
@ -536,8 +536,8 @@ function generateParameters(type, linktext = true, linkhref = true) {
|
||||
|
||||
}
|
||||
|
||||
//根据nodelist列表内的元素生成参数列表
|
||||
//适合:nodelist中的元素为不同类型元素
|
||||
//根据nodelist列表内的element生成para列表
|
||||
//适合:nodelist中的element为不同类型element
|
||||
function generateMultiParameters() {
|
||||
clearParameters(false);
|
||||
let n = 1;
|
||||
@ -550,23 +550,23 @@ function generateMultiParameters() {
|
||||
outputParameterNodes.push({ "node": nd, "boxShadow": nd.style.boxShadow == "" || boxShadowColor ? "none" : nd.style.boxShadow });
|
||||
nd.style.boxShadow = boxShadowColor;
|
||||
ndText = $(nd).text();
|
||||
if (nd.tagName == "IMG") { //如果元素是图片
|
||||
if (nd.tagName == "IMG") { //如果element是Image
|
||||
outputParameters.push({
|
||||
"nodeType": 4, //节点类型
|
||||
"contentType": 0, // 内容类型
|
||||
"relative": false, //是否为相对xpath路径
|
||||
"name": "参数" + (n++) + "_图片地址",
|
||||
"desc": "", //参数描述
|
||||
"name": "para" + (n++) + "_imageAddress",
|
||||
"desc": "", //para描述
|
||||
"relativeXpath": ndPath,
|
||||
"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({
|
||||
"nodeType": 1,
|
||||
"contentType": 0, // 内容类型
|
||||
"relative": false, //是否为相对xpath路径
|
||||
"name": "参数" + (n++) + "_链接文本",
|
||||
"desc": "", //参数描述
|
||||
"name": "para" + (n++) + "_linktext",
|
||||
"desc": "", //para描述
|
||||
"relativeXpath": ndPath,
|
||||
"exampleValues": [{ "num": 0, "value": ndText }]
|
||||
});
|
||||
@ -574,18 +574,18 @@ function generateMultiParameters() {
|
||||
"nodeType": 2,
|
||||
"contentType": 0, // 内容类型
|
||||
"relative": false, //是否为相对xpath路径
|
||||
"name": "参数" + (n++) + "_链接地址",
|
||||
"desc": "", //参数描述
|
||||
"name": "para" + (n++) + "_linkAddress",
|
||||
"desc": "", //para描述
|
||||
"relativeXpath": ndPath,
|
||||
"exampleValues": [{ "num": 0, "value": nd.getAttribute("href") == null ? "" : $(nd).prop("href") }]
|
||||
});
|
||||
} else if (nd.tagName == "INPUT") { //如果元素是输入项
|
||||
} else if (nd.tagName == "INPUT") { //如果element是输入项
|
||||
outputParameters.push({
|
||||
"nodeType": 3,
|
||||
"contentType": 0, // 内容类型
|
||||
"relative": false, //是否为相对xpath路径
|
||||
"name": "参数" + (n++) + "_文本",
|
||||
"desc": "", //参数描述
|
||||
"name": "para" + (n++) + "_text",
|
||||
"desc": "", //para描述
|
||||
"relativeXpath": ndPath,
|
||||
"exampleValues": [{ "num": 0, "value": nd.getAttribute("value") == null ? "" : nd.getAttribute("value") }]
|
||||
});
|
||||
@ -594,8 +594,8 @@ function generateMultiParameters() {
|
||||
"nodeType": 0,
|
||||
"contentType": 0, // 内容类型
|
||||
"relative": false, //是否为相对xpath路径
|
||||
"name": "参数" + (n++) + "_文本",
|
||||
"desc": "", //参数描述
|
||||
"name": "para" + (n++) + "_text",
|
||||
"desc": "", //para描述
|
||||
"relativeXpath": ndPath,
|
||||
"exampleValues": [{ "num": 0, "value": ndText }]
|
||||
});
|
||||
@ -610,22 +610,22 @@ function generateMultiParameters() {
|
||||
}
|
||||
|
||||
|
||||
//处理子元素,对于每个块中多出的特殊元素,需要特殊处理
|
||||
//处理子element,对于每个块中多出的特殊element,需要特殊处理
|
||||
function handleDescendents() {
|
||||
let n = 1;
|
||||
chrome.storage.local.get({ parameterNum: 1 }, function(items) {
|
||||
let at = parseInt(new Date().getTime());
|
||||
n = items.parameterNum;
|
||||
clearParameters(); //清除原来的参数列表
|
||||
clearParameters(); //清除原来的para列表
|
||||
app._data.selectedDescendents = true;
|
||||
for (let num = 0; num < nodeList.length; num++) {
|
||||
let tnode = nodeList[num]["node"];
|
||||
let stack = new Array(); //深度优先搜索遍历元素
|
||||
let stack = new Array(); //深度优先搜索遍历element
|
||||
stack.push(tnode); //从此节点开始
|
||||
while (stack.length > 0) {
|
||||
let nd = stack.pop(); // 挨个取出元素
|
||||
let nd = stack.pop(); // 挨个取出element
|
||||
if (nd.parentNode.tagName == "A" && nd.tagName == "SPAN") {
|
||||
continue; //对A标签内的SPAN元素不进行处理,剪枝,此时子元素根本不加入stack,即实现了此功能
|
||||
continue; //对A标签内的SPANelement不进行处理,剪枝,此时子element根本不加入stack,即实现了此功能
|
||||
}
|
||||
ndPath = readXPath(nd, 1, tnode);
|
||||
let index = -1;
|
||||
@ -643,29 +643,29 @@ function handleDescendents() {
|
||||
ndText = $(nd).contents().filter(function() {
|
||||
return this.nodeType === 3;
|
||||
}).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 (nd.tagName == "IMG") { //如果元素是图片
|
||||
if (nd.tagName == "IMG") { //如果element是Image
|
||||
outputParameters.push({
|
||||
"nodeType": 4, //节点类型
|
||||
"contentType": 1, // 内容类型
|
||||
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径,注意当只选择了子元素没有选中全部的时候,需要判断
|
||||
"name": "参数" + (n++) + "_图片地址",
|
||||
"desc": "", //参数描述
|
||||
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径,注意当只selection了子element没有选中全部的时候,需要判断
|
||||
"name": "para" + (n++) + "_imageAddress",
|
||||
"desc": "", //para描述
|
||||
"relativeXpath": nodeList.length > 1 ? ndPath : readXPath(nd), //同理需要判断
|
||||
"exampleValues": [{
|
||||
"num": num,
|
||||
"value": nd.getAttribute("src") == null ? "" : $(nd).prop("src")
|
||||
}]
|
||||
});
|
||||
} else if (nd.tagName == "A") { //如果元素是超链接
|
||||
} else if (nd.tagName == "A") { //如果element是超link
|
||||
outputParameters.push({
|
||||
"nodeType": 1,
|
||||
"contentType": 0, // 内容类型
|
||||
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径
|
||||
"name": "参数" + (n++) + "_链接文本",
|
||||
"desc": "", //参数描述
|
||||
"name": "para" + (n++) + "_linktext",
|
||||
"desc": "", //para描述
|
||||
"relativeXpath": nodeList.length > 1 ? ndPath : readXPath(nd),
|
||||
"exampleValues": [{ "num": num, "value": $(nd).text() }] //注意这里的ndtext是整个a的文字!!!
|
||||
});
|
||||
@ -673,21 +673,21 @@ function handleDescendents() {
|
||||
"nodeType": 2,
|
||||
"contentType": 0, // 内容类型
|
||||
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径
|
||||
"name": "参数" + (n++) + "_链接地址",
|
||||
"desc": "", //参数描述
|
||||
"name": "para" + (n++) + "_linkAddress",
|
||||
"desc": "", //para描述
|
||||
"relativeXpath": nodeList.length > 1 ? ndPath : readXPath(nd),
|
||||
"exampleValues": [{
|
||||
"num": num,
|
||||
"value": nd.getAttribute("href") == null ? "" : $(nd).prop("href")
|
||||
}]
|
||||
});
|
||||
} else if (nd.tagName == "INPUT") { //如果元素是输入项
|
||||
} else if (nd.tagName == "INPUT") { //如果element是输入项
|
||||
outputParameters.push({
|
||||
"nodeType": 3,
|
||||
"contentType": 1, // 内容类型
|
||||
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径
|
||||
"name": "参数" + (n++) + "_文本",
|
||||
"desc": "", //参数描述
|
||||
"name": "para" + (n++) + "_text",
|
||||
"desc": "", //para描述
|
||||
"relativeXpath": nodeList.length > 1 ? ndPath : readXPath(nd),
|
||||
"exampleValues": [{
|
||||
"num": num,
|
||||
@ -699,27 +699,27 @@ function handleDescendents() {
|
||||
"nodeType": 0,
|
||||
"contentType": 1, // 内容类型
|
||||
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径
|
||||
"name": "参数" + (n++) + "_文本",
|
||||
"desc": "", //参数描述
|
||||
"name": "para" + (n++) + "_text",
|
||||
"desc": "", //para描述
|
||||
"relativeXpath": nodeList.length > 1 ? ndPath : readXPath(nd),
|
||||
"exampleValues": [{ "num": num, "value": ndText }]
|
||||
});
|
||||
}
|
||||
}
|
||||
} else //如果元素节点已经存在,则只需要插入值就可以了
|
||||
} else //如果element节点已经存在,则只需要插入值就可以了
|
||||
{
|
||||
if (nd.tagName == "IMG") { //如果元素是图片
|
||||
if (nd.tagName == "IMG") { //如果element是Image
|
||||
outputParameters[index]["exampleValues"].push({
|
||||
"num": num,
|
||||
"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 + 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[index]["exampleValues"].push({
|
||||
"num": num,
|
||||
"value": nd.getAttribute("value") == null ? "" : nd.getAttribute("value")
|
||||
@ -734,14 +734,14 @@ function handleDescendents() {
|
||||
}
|
||||
}
|
||||
let at2 = parseInt(new Date().getTime());
|
||||
console.log("选中子元素", at2, at, at2 - at);
|
||||
console.log("选中子element", at2, at, at2 - at);
|
||||
generateValTable();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
//根据参数列表生成可视化参数界面
|
||||
//根据para列表生成可视化para界面
|
||||
function generateValTable(multiline = true) {
|
||||
let paravalues = [];
|
||||
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
|
||||
// 从倒数第一个节点开始找,看去掉方括号之后是否element数目变多,如上面的变成/div[1]/div[2]/div[2]/a
|
||||
// 如果没有,则恢复原状,然后试试倒数第二个:/div[1]/div[2]/div/a[1]
|
||||
// 直到找到第一个变多的节点或者追溯到根节点为止
|
||||
function findRelated() {
|
||||
@ -789,9 +789,9 @@ function findRelated() {
|
||||
tempIndexList[i] = -1; //删除索引值
|
||||
tempPath = combineXpath(nodeNameList, tempIndexList); //生成新的xpath
|
||||
var result = document.evaluate(tempPath, document, null, XPathResult.ANY_TYPE, null);
|
||||
result.iterateNext(); //枚举第一个元素
|
||||
if (result.iterateNext() != null) { //如果能枚举到第二个元素,说明存在同类元素,选中同类元素,结束循环
|
||||
app.$data.nowPath = tempPath; //标记此元素xpath
|
||||
result.iterateNext(); //枚举第一个element
|
||||
if (result.iterateNext() != null) { //如果能枚举到第二个element,说明存在同类element,选中同类element,结束循环
|
||||
app.$data.nowPath = tempPath; //标记此elementxpath
|
||||
pushToReadyList(tempPath);
|
||||
break;
|
||||
}
|
||||
@ -801,11 +801,11 @@ function findRelated() {
|
||||
}
|
||||
|
||||
|
||||
//根据path将元素放入readylist中
|
||||
//根据path将element放入readylist中
|
||||
function pushToReadyList(path) {
|
||||
result = document.evaluate(path, document, null, XPathResult.ANY_TYPE, null);
|
||||
var node = result.iterateNext(); //枚举第一个元素
|
||||
while (node) { //只添加不在已选中列表内的元素
|
||||
var node = result.iterateNext(); //枚举第一个element
|
||||
while (node) { //只添加不在已选中列表内的element
|
||||
let exist = false;
|
||||
for (o of nodeList) {
|
||||
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 });
|
||||
}
|
||||
node.style.boxShadow = boxShadowColor;
|
||||
node = result.iterateNext(); //枚举下一个元素
|
||||
node = result.iterateNext(); //枚举下一个element
|
||||
}
|
||||
}
|
||||
|
||||
//将readyList中的元素放入选中节点中
|
||||
//将readyList中的element放入选中节点中
|
||||
function readyToList(step, dealparameters = true) {
|
||||
for (o of readyList) {
|
||||
nodeList.push({ node: o["node"], "step": step, bgColor: o["bgColor"], "boxShadow": o["boxShadow"], xpath: readXPath(o["node"], 1) });
|
||||
o["node"].style.backgroundColor = selectedColor;
|
||||
}
|
||||
clearReady();
|
||||
if (dealparameters) { //防止出现先选中子元素再选中全部失效的问题
|
||||
generateParameters(0); //根据nodelist列表内的元素生成参数列表,0代表纯文本
|
||||
if (dealparameters) { //防止出现先选中子element再选中全部失效的问题
|
||||
generateParameters(0); //根据nodelist列表内的element生成para列表,0代表纯text
|
||||
}
|
||||
|
||||
}
|
||||
@ -847,7 +847,7 @@ function combineXpath(nameList, indexList) {
|
||||
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[2]/div[3]/a[25]
|
||||
@ -859,7 +859,7 @@ function relatedTest() {
|
||||
var testpath = "";
|
||||
for (i = 0; i < nodeList.length; i++) {
|
||||
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++) {
|
||||
if (tpath[j].indexOf("[") >= 0) { //如果存在索引值
|
||||
testnumList.push(parseInt(tpath[j].split("[")[1].replace("]", ""))); //只留下数字
|
||||
@ -869,16 +869,16 @@ function relatedTest() {
|
||||
tpath[j] = tpath[j].split("[")[0];
|
||||
}
|
||||
tp = tpath.join("/");
|
||||
if (i > 0 && testpath != tp) { //如果去除括号后元素内存在不一致情况,直接返回默认情况代码100
|
||||
app.$data.nowPath = ""; //标记此元素xpath
|
||||
if (i > 0 && testpath != tp) { //如果去除括号后element内存在不一致情况,直接返回默认情况代码100
|
||||
app.$data.nowPath = ""; //标记此elementxpath
|
||||
return 100;
|
||||
}
|
||||
testpath = tp;
|
||||
testList.push(testnumList);
|
||||
}
|
||||
testpath = testpath.split("/"); //清理第一个空元素
|
||||
testpath = testpath.split("/"); //清理第一个空element
|
||||
var indexList = []; //记录新生成的xpath
|
||||
//如果选中的元素属于同样的序列,则计算出序列的最佳xpath表达式
|
||||
//如果选中的element属于同样的序列,则计算出序列的最佳xpath表达式
|
||||
for (j = 0; j < testList[0].length; j++) {
|
||||
indexList.push(testList[0][j]);
|
||||
for (i = 1; i < testList.length; i++) {
|
||||
@ -889,14 +889,14 @@ function relatedTest() {
|
||||
}
|
||||
}
|
||||
var finalPath = combineXpath(testpath, indexList);
|
||||
app.$data.nowPath = finalPath; //标记此元素xpath
|
||||
app.$data.nowPath = finalPath; //标记此elementxpath
|
||||
pushToReadyList(finalPath);
|
||||
let at2 = parseInt(new Date().getTime());
|
||||
console.log("手动:", at2, at, at2 - at);
|
||||
return 50; //先返回给默认码
|
||||
}
|
||||
|
||||
//实现提示框拖拽功能
|
||||
//实现提示 box拖拽功能
|
||||
$('.tooldrag').mousedown(function(e) {
|
||||
// e.pageX
|
||||
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"; //如果是服务器网页页面,则不执行工具
|
||||
}
|
||||
|
||||
|
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>
|
||||
打开压缩包内的ServiceWrapper.exe即可在Windows10系统执行,无需配置环境。
|
||||
## Windows版本可执行程序:<https://github.com/NaiboWang/ServiceWrapper/releases/download/v0.5.0/ServiceWrapper.7z>
|
||||
打开压缩包内的ServiceWrapper.exe即可在Windows10/11或以上系统执行,无需配置环境(其余Windows系统需手动安装.net Framework 4.5)。
|
||||
数据存储后放在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内的文件
|
||||
|
||||
## 后台流程图部分
|
||||
### 后台流程图部分
|
||||
* ServiceGrid/frontEnd/FlowChart.html
|
||||
* ServiceGrid/frontEnd/FlowChart.js
|
||||
* ServiceGrid/frontEnd/FlowChart.css
|
||||
* ServiceGrid/frontEnd/logic.css
|
||||
|
||||
## 服务展示部分
|
||||
### 服务展示部分
|
||||
* 服务列表:ServiceGrid/frontEnd/serviceList.html
|
||||
* 服务信息:ServiceGrid/frontEnd/serviceInfo.html
|
||||
* 新服务:ServiceGrid/frontEnd/newService.html
|
||||
* 调用服务:ServiceGrid/frontEnd/invokeService.html
|
||||
|
||||
## C#部分
|
||||
### C#部分
|
||||
* C#/内的文件
|
||||
|
||||
## 后台服务页面
|
||||
### 后台服务页面
|
||||
* Django后台:ServiceGrid/backEnd/*
|
||||
|
||||
## 服务执行
|
||||
### 服务执行
|
||||
* 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',
|
||||
'corsheaders',
|
||||
'django.contrib.staticfiles',
|
||||
'sslserver',
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
|
@ -27,6 +27,4 @@ urlpatterns = [
|
||||
path('backEnd/invokeService',view.invokeService), #调用服务接口
|
||||
path('backEnd/queryTask',view.queryTask), #调用服务接口
|
||||
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 json
|
||||
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):
|
||||
return HttpResponse("Hello world ! ")
|
||||
|
||||
|
||||
myclient = pymongo.MongoClient('mongodb://localhost:27017/')
|
||||
mydb = myclient['service']
|
||||
mycol = mydb["services"]
|
||||
taskcol = mydb["tasks"] #生成新任务并返回ID
|
||||
|
||||
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")
|
||||
|
||||
|
||||
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")
|
||||
|
||||
|
||||
def queryService(request):
|
||||
if 'id' in request.GET:
|
||||
tid = request.GET['id']
|
||||
else:
|
||||
tid = "0"
|
||||
result = mycol.find({"id":int(tid)},{"_id":0})
|
||||
result = mycol.find({"id": int(tid)}, {"_id": 0})
|
||||
r = list(result)[0]
|
||||
return HttpResponse(json.dumps(r), content_type="application/json")
|
||||
|
||||
|
||||
def queryTask(request):
|
||||
if 'id' in request.GET:
|
||||
tid = request.GET['id']
|
||||
else:
|
||||
tid = "0"
|
||||
|
||||
result = taskcol.find({"id":int(tid)},{"_id":0})
|
||||
result = taskcol.find({"id": int(tid)}, {"_id": 0})
|
||||
r = list(result)[0]
|
||||
return HttpResponse(json.dumps(r), content_type="application/json")
|
||||
|
||||
@ -54,45 +54,57 @@ def manageService(request):
|
||||
data = request.POST['paras']
|
||||
data = json.loads(data)
|
||||
if int(data["id"]) == -1:
|
||||
count = mycol.find({}).count()
|
||||
data["id"] = count #修改id
|
||||
count = mycol.count_documents({})
|
||||
data["id"] = count # 修改id
|
||||
mycol.insert_one(data)
|
||||
else:
|
||||
mycol.delete_one({"id":int(data["id"])})
|
||||
mycol.delete_one({"id": int(data["id"])})
|
||||
mycol.insert_one(data)
|
||||
return HttpResponse(data["id"])
|
||||
|
||||
|
||||
def deleteService(request):
|
||||
if 'id' in request.GET:
|
||||
tid = request.GET['id']
|
||||
myquery = { "id": int(tid) }
|
||||
newvalues = { "$set": { "id": -2 } } #删除就是将服务id变成-2,并没有真正删除
|
||||
myquery = {"id": int(tid)}
|
||||
newvalues = {"$set": {"id": -2}} # 删除就是将服务id变成-2,并没有真正删除
|
||||
mycol.update_one(myquery, newvalues)
|
||||
return HttpResponse("Done!")
|
||||
|
||||
# 调用服务
|
||||
|
||||
|
||||
def invokeService(request):
|
||||
tid = request.POST['id']
|
||||
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]
|
||||
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"])):
|
||||
if key == service["inputParameters"][i]["name"]: #能调用
|
||||
if key == service["inputParameters"][i]["name"]: # 能调用
|
||||
nodeId = int(service["inputParameters"][i]["nodeId"])
|
||||
node = service["graph"][nodeId]
|
||||
if node["option"] == 1:
|
||||
node["parameters"]["links"] = value
|
||||
elif node["option"] == 4:
|
||||
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:
|
||||
node["parameters"]["textList"] = value
|
||||
break
|
||||
count = taskcol.find({}).count()
|
||||
service["id"] = count #修改id
|
||||
count = taskcol.count_documents({})
|
||||
service["id"] = count # 修改id
|
||||
taskcol.insert_one(service)
|
||||
return HttpResponse(count)
|
||||
|
||||
|
||||
def insertInfo(request):
|
||||
request.GET = request.GET.copy()
|
||||
data = request.GET
|
||||
@ -101,6 +113,7 @@ def insertInfo(request):
|
||||
cold.insert_one(data)
|
||||
return HttpResponse("200")
|
||||
|
||||
|
||||
def queryInfos(request):
|
||||
dbd = myclient['dongcang']
|
||||
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>
|
||||
<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 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>
|
||||
<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">Save Service</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>
|
||||
<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">Extract Data</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=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=8 class="btn btn-outline-primary options">Loop</button>
|
||||
<button type="button" data=9 class="btn btn-outline-primary options">If Condition</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>
|
||||
<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">Cut Element</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">Del Element</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>
|
||||
</div>
|
||||
<div style="margin-top:20px;border: solid;height:850px;overflow: auto;width:58%;float:right">
|
||||
@ -54,47 +54,47 @@
|
||||
</div> -->
|
||||
<div class="Modify" id="app">
|
||||
<div>
|
||||
<label>选项名称:</label>
|
||||
<label>Option Name:</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>
|
||||
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='useLoop'></input>Use link inside the Loop</p>
|
||||
</div>
|
||||
<div v-if='!useLoop'>
|
||||
<label>url:</label>
|
||||
<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>
|
||||
</div>
|
||||
<label>执行完是否向下滚动:</label>
|
||||
<label>After executed, whether scroll down:</label>
|
||||
<select v-model='nowNode["parameters"]["scrollType"]' class="form-control">
|
||||
<option value = 0>不滚动</option>
|
||||
<option value = 1>向下滚动一屏</option>
|
||||
<option value = 2>滚动到底部</option>
|
||||
<option value = 0>No</option>
|
||||
<option value = 1>Scroll one screen</option>
|
||||
<option value = 2>Scroll to the end</option>
|
||||
</select>
|
||||
<label>滚动次数:</label>
|
||||
<label>Scroll Times:</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>
|
||||
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='useLoop'></input>Use element inside the Loop</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>
|
||||
<label>After executed, whether scroll down:</label>
|
||||
<select v-model='nowNode["parameters"]["scrollType"]' class="form-control">
|
||||
<option value = 0>不滚动</option>
|
||||
<option value = 1>向下滚动一屏</option>
|
||||
<option value = 2>滚动到底部</option>
|
||||
<option value = 0>No</option>
|
||||
<option value = 1>Scroll one screen</option>
|
||||
<option value = 2>Scroll to the end</option>
|
||||
</select>
|
||||
<label>滚动次数:</label>
|
||||
<label>Scroll Times:</label>
|
||||
<input onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['scrollCount']" type="number" required></input>
|
||||
|
||||
</div>
|
||||
@ -103,9 +103,9 @@
|
||||
<div class="toolkitcontain">
|
||||
<table class="toolkittb2" cellspacing="0">
|
||||
<tbody>
|
||||
<th>字段名</th>
|
||||
<th style="width:200px">示例值</th>
|
||||
<th>操作</th>
|
||||
<th>Field Name</th>
|
||||
<th style="width:200px">Example Value</th>
|
||||
<th>Operations</th>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="toolkittb4" cellspacing="0">
|
||||
@ -115,22 +115,37 @@
|
||||
</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>
|
||||
<a v-on:mousedown="modifyParas(i-1)">Modify</a>
|
||||
<a v-on:mousedown="deleteParas(i-1)">Delete</a>
|
||||
<a v-on:mousedown="upParas(i-1)">Up</a>
|
||||
<a v-on:mousedown="downParas(i-1)">Down</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>Current parameter name: <strong>{{paras.parameters[paraIndex]["name"]}}</strong></label>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
</div>
|
||||
|
||||
@ -140,10 +155,10 @@
|
||||
<div class="elements" v-if="nodeType==4">
|
||||
<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 v-if='!useLoop'>
|
||||
<label>输入值:</label>
|
||||
<label>Input Value:</label>
|
||||
<input onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["value"]'></input>
|
||||
</div>
|
||||
|
||||
@ -165,31 +180,40 @@
|
||||
|
||||
<div class="elements" v-if="nodeType==8">
|
||||
<!-- 循环选项 -->
|
||||
<label>循环类型:</label>
|
||||
<label>Loop Type:</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>
|
||||
<option value = 0>Single Element</option>
|
||||
<option value = 1>Unfixed Element List</option>
|
||||
<option value = 2>Fixed Element List</option>
|
||||
<option value = 3>Text List</option>
|
||||
<option value = 4>Weblink List</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>
|
||||
<label>XPath List:</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>
|
||||
<label>Content List:</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>
|
||||
<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>
|
||||
<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>
|
||||
<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 class="elements" v-if="nodeType==9">
|
||||
@ -197,22 +221,22 @@
|
||||
</div>
|
||||
|
||||
<div class="elements" v-if="nodeType==10">
|
||||
<label>条件类型:</label>
|
||||
<label>Condition Type:</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>
|
||||
<option value = 0>No Condition</option>
|
||||
<option value = 1>Text inside current page</option>
|
||||
<option value = 2>Element inside current page</option>
|
||||
<option v-if="nowNode['isInLoop']" value = 3>Text inside current loop</option>
|
||||
<option v-if="nowNode['isInLoop']" value = 4>Element inside current loop</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>
|
||||
<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>
|
||||
</div>
|
||||
<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>
|
||||
</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>
|
||||
|
||||
@ -225,20 +249,20 @@
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<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>
|
||||
</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>
|
||||
<label>Service Name:</label>
|
||||
<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>
|
||||
</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>
|
||||
<button type="button" id="saveAsButton" class="btn btn-outline-primary">Save as</button>
|
||||
<button type="button" id="saveButton" class="btn btn-primary">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.modal-content -->
|
||||
|
@ -116,13 +116,13 @@ var app = new Vue({
|
||||
return "OuterHTML";
|
||||
}
|
||||
if (nodeType == 2) {
|
||||
return "链接地址";
|
||||
return "Link Address";
|
||||
} else if (nodeType == 1) {
|
||||
return "链接文本";
|
||||
return "Link Text";
|
||||
} else if (nodeType == 4) {
|
||||
return "图片地址";
|
||||
return "Image Address";
|
||||
} 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"]}>
|
||||
<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></div>
|
||||
<p class="arrow" data = "${id}" position=${node["position"]} pId=${node["parentId"]}>↓</p></div>`;
|
||||
@ -199,7 +199,7 @@ function branchMouseDown(e) {
|
||||
parentId: 0,
|
||||
type: 3,
|
||||
option: 10,
|
||||
title: "条件分支",
|
||||
title: "Condition",
|
||||
sequence: [],
|
||||
isInLoop: false,
|
||||
};
|
||||
@ -232,7 +232,7 @@ function branchClick(e) {
|
||||
parentId: 0,
|
||||
type: 3,
|
||||
option: 10,
|
||||
title: "条件分支",
|
||||
title: "Condition",
|
||||
sequence: [],
|
||||
isInLoop: false,
|
||||
};
|
||||
@ -269,7 +269,7 @@ function arrowClick(e) {
|
||||
function addElement(op, para) {
|
||||
option = op;
|
||||
if (option == 1) { //打开网页选项
|
||||
title = "打开网页";
|
||||
title = "Open Page";
|
||||
} else {
|
||||
title = $(".options")[option - 2].innerHTML; //获取新增操作名称
|
||||
}
|
||||
@ -287,7 +287,7 @@ function toolBoxKernel(e, para = null) {
|
||||
if (nowNode == null) {
|
||||
e.stopPropagation(); //防止冒泡
|
||||
} else if (nowNode.getAttribute("dataType") > 0) {
|
||||
alert("循环和判断、条件分支不可复制!");
|
||||
alert("Cannot copy loop, if and condition!");
|
||||
e.stopPropagation(); //防止冒泡
|
||||
} else {
|
||||
let position = parseInt(nowNode.getAttribute('position'));
|
||||
@ -309,7 +309,7 @@ function toolBoxKernel(e, para = null) {
|
||||
if (nowNode == null) {
|
||||
e.stopPropagation(); //防止冒泡
|
||||
} else if ($(nowNode).is(".branch")) {
|
||||
alert("判断分支不可移动!");
|
||||
alert("Cannot move condition branch!");
|
||||
e.stopPropagation(); //防止冒泡
|
||||
} else {
|
||||
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 };
|
||||
$("#" + nodeList[element[0]]["id"]).click();
|
||||
} else {
|
||||
alert("自己不能移动到自己的节点里!");
|
||||
alert("Cannot move inside self!");
|
||||
}
|
||||
e.stopPropagation(); //防止冒泡
|
||||
}
|
||||
@ -371,7 +371,7 @@ function toolBoxKernel(e, para = null) {
|
||||
index: l + 1,
|
||||
type: 3,
|
||||
option: 10,
|
||||
title: "条件分支",
|
||||
title: "Condition",
|
||||
sequence: [],
|
||||
isInLoop: false,
|
||||
};
|
||||
@ -381,7 +381,7 @@ function toolBoxKernel(e, para = null) {
|
||||
index: l + 2,
|
||||
type: 3,
|
||||
option: 10,
|
||||
title: "条件分支",
|
||||
title: "Condition",
|
||||
sequence: [],
|
||||
isInLoop: false,
|
||||
};
|
||||
@ -426,7 +426,7 @@ $(".options").mousedown(function() {
|
||||
option = parseInt(this.getAttribute("data"));
|
||||
title = this.innerHTML;
|
||||
if (option >= 10 && option <= 12 && (nowNode == null || nowNode.getAttribute("id") == 0)) {
|
||||
alert("目前未选中元素");
|
||||
alert("No element is selected now!");
|
||||
} else if (option == 12) {
|
||||
deleteElement();
|
||||
$(".options")[12].click();
|
||||
@ -501,13 +501,13 @@ function refresh(nowArrowReset = true) {
|
||||
|
||||
function deleteElement() {
|
||||
if (nowNode.getAttribute("id") == 0) {
|
||||
alert("当前未选中元素!"); //root
|
||||
return;
|
||||
}
|
||||
if (nodeList[actionSequence[nowNode.getAttribute("data")]]["option"] == 1) {
|
||||
alert("打开网页操作不可删除!");
|
||||
alert("No element is selected now!"); //root
|
||||
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 pId = nowNode.getAttribute('pId');
|
||||
let tnode = nodeList[actionSequence[pId]]["sequence"].splice(position, 1); //在相应位置删除元素
|
||||
@ -539,7 +539,7 @@ document.oncontextmenu = function() {
|
||||
//删除元素
|
||||
document.onkeydown = function(e) {
|
||||
if (nowNode != null && e.keyCode == 46) {
|
||||
if (confirm("确定要删除元素吗?")) {
|
||||
if (confirm("Do you really want to delete the selected element?")) {
|
||||
deleteElement();
|
||||
}
|
||||
} 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">
|
||||
<script src="vue.js"></script>
|
||||
<link rel="stylesheet" href="bootstrap/css/bootstrap.css"></link>
|
||||
<title>服务调用</title>
|
||||
<title>Service Invoke</title>
|
||||
<style>
|
||||
table {
|
||||
table-layout: auto;
|
||||
@ -35,20 +35,20 @@
|
||||
<body>
|
||||
<div class="row" style="margin-top: 40px;">
|
||||
<div class="col-md-6" style="margin:0 auto" id="serviceList" v-if="show">
|
||||
<h4 style="text-align: center;">服务信息</h4>
|
||||
<p>服务名称:{{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;">任务号调用URL:http://183.129.170.180:8041/backEnd/invokeService?id={{service["id"]}}</p>
|
||||
<p>请输入参数:</p>
|
||||
<h4 style="text-align: center;">Service Information</h4>
|
||||
<p>Service Name: {{service["name"]}}</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: {{backEndAddressServiceWrapper}}/backEnd/invokeService?id={{service["id"]}}</p>
|
||||
<p>Please Input Parameters: </p>
|
||||
<form id="form">
|
||||
<table class="table table-bordered">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th style="min-width: 50px;">ID</th>
|
||||
<th>参数名称</th>
|
||||
<th>调用名称</th>
|
||||
<th>参数类型</th>
|
||||
<th>参数值</th>
|
||||
<th>Parameter Name</th>
|
||||
<th>Invoke Name</th>
|
||||
<th>Parameter Type</th>
|
||||
<th>Parameter Value</th>
|
||||
</tr>
|
||||
|
||||
<tr v-if="service.inputParameters.length>0" v-for="i in service.inputParameters.length">
|
||||
@ -62,16 +62,16 @@
|
||||
</table>
|
||||
</form>
|
||||
|
||||
<button style="margin-left: 5px;" v-on:click="localExcuteInstant" class="btn btn-primary">直接本地执行</button>
|
||||
<button style="margin-left: 5px;" v-on:click="remoteExcuteInstant" 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">Directly Run Remotely</button>
|
||||
<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>
|
||||
<p></p>
|
||||
<p>提示:点击下方按钮获得任务ID,然后根据此ID进行服务执行;也可自己POST调用接口得到ID,具体参照POST调用文档。</p>
|
||||
<a href="javascript:void(0)" v-on:click="invokeService" class="btn btn-primary">获得任务ID</a>
|
||||
<button v-on:click="localExcute" style="margin-left: 8px;" class="btn btn-primary">本地执行任务</button>
|
||||
<button v-on:click="remoteExcute" style="margin-left: 8px;" class="btn btn-primary">远程执行任务</button></div>
|
||||
<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">Run locally</button>
|
||||
<button v-on:click="remoteExcute" style="margin-left: 8px;" class="btn btn-primary">Run remotely</button></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@ -85,7 +85,7 @@
|
||||
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象
|
||||
var r = window.location.search.substr(1).match(reg); //匹配目标参数
|
||||
if (r != null) return unescape(r[2]);
|
||||
return null; //返回参数值
|
||||
return ""; //返回参数值,默认后台地址
|
||||
}
|
||||
|
||||
var sId = getUrlParam('id');
|
||||
@ -95,6 +95,7 @@
|
||||
service: {},
|
||||
show: false, //是否渲染
|
||||
ID: "暂无",
|
||||
backEndAddressServiceWrapper: getUrlParam("backEndAddressServiceWrapper"),
|
||||
},
|
||||
methods: {
|
||||
invokeService: function() {
|
||||
@ -104,7 +105,7 @@
|
||||
t.forEach(function(item, index) {
|
||||
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,
|
||||
paras: JSON.stringify(para)
|
||||
}, function(result) {
|
||||
@ -149,7 +150,7 @@
|
||||
t.forEach(function(item, index) {
|
||||
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,
|
||||
paras: JSON.stringify(para)
|
||||
}, function(result) {
|
||||
@ -170,7 +171,7 @@
|
||||
t.forEach(function(item, index) {
|
||||
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,
|
||||
paras: JSON.stringify(para)
|
||||
}, 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.show = true;
|
||||
});
|
||||
|
@ -125,6 +125,8 @@ function addParameters(t) {
|
||||
} 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"] = "";
|
||||
@ -158,9 +160,9 @@ function modifyParameters(t, para) {
|
||||
t["parameters"]["loopType"] = para["loopType"];
|
||||
t["parameters"]["xpath"] = para["xpath"];
|
||||
if (para["nextPage"]) { //循环点击下一页的情况下
|
||||
t["title"] = "循环点击下一页"
|
||||
t["title"] = "Loop click next page"
|
||||
} else {
|
||||
t["title"] = "循环"
|
||||
t["title"] = "Loop"
|
||||
}
|
||||
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) {
|
||||
var serviceId = $("#serviceId").val();
|
||||
var text = "确认要保存服务吗?";
|
||||
var text = "Confirm to save service?";
|
||||
if (type == 1) { //服务另存为
|
||||
serviceId = -1;
|
||||
text = "确认要另存为服务吗?";
|
||||
text = "Confirm to save as service?";
|
||||
}
|
||||
if (confirm(text)) {
|
||||
let serviceName = $("#serviceName").val();
|
||||
@ -222,7 +235,7 @@ function saveService(type) {
|
||||
value: nodeList[i]["parameters"]["links"],
|
||||
desc: "要采集的网址列表,多行以\\n分开",
|
||||
type: "string",
|
||||
exampleValue: "https://www.jd.com"
|
||||
exampleValue: nodeList[i]["parameters"]["links"]
|
||||
});
|
||||
links = nodeList[i]["parameters"]["links"];
|
||||
}
|
||||
@ -243,17 +256,30 @@ function saveService(type) {
|
||||
}
|
||||
} else if (nodeList[i]["option"] == 8) //循环操作
|
||||
{
|
||||
if (parseInt(nodeList[i]["parameters"]["loopType"]) > 2) //循环中的循环输入文本或循环输入网址
|
||||
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"],
|
||||
});
|
||||
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 (parseInt(nodeList[i]["parameters"]["loopType"]) == 0) {
|
||||
inputParameters.push({
|
||||
id: inputIndex,
|
||||
name: "loopTimes_" + nodeList[i]["title"] + "_" + inputIndex++,
|
||||
nodeId: i,
|
||||
nodeName: nodeList[i]["title"],
|
||||
desc: "循环" + nodeList[i]["title"] + "执行的次数(0代表无限循环)",
|
||||
type: "int",
|
||||
exampleValue: nodeList[i]["parameters"]["exitCount"],
|
||||
value: nodeList[i]["parameters"]["exitCount"],
|
||||
});
|
||||
}
|
||||
} else if (nodeList[i]["option"] == 3) //提取数据操作
|
||||
{
|
||||
for (let j = 0; j < nodeList[i]["parameters"]["paras"].length; j++) {
|
||||
@ -285,7 +311,7 @@ function saveService(type) {
|
||||
"outputParameters": outputParameters,
|
||||
"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("保存成功!");
|
||||
$('#myModal').modal('hide');
|
||||
$("#tip").slideDown(); //提示框
|
||||
@ -305,19 +331,10 @@ $("#saveAsButton").mousedown(function() {
|
||||
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) //加载服务
|
||||
{
|
||||
$.get("http://183.129.170.180:8041/backEnd/queryService?id=" + sId, function(result) {
|
||||
$.get(backEndAddressServiceWrapper + "/backEnd/queryService?id=" + sId, function(result) {
|
||||
nodeList = result["graph"];
|
||||
app.$data.list.nl = nodeList;
|
||||
$("#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">
|
||||
<script src="bootstrap/js/bootstrap.js"></script>
|
||||
<link rel="stylesheet" href="bootstrap/css/bootstrap.css"></link>
|
||||
<title>新服务</title>
|
||||
<title>New Service</title>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="row" style="margin-top: 40px;">
|
||||
<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">
|
||||
<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>
|
||||
</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>
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<script src="vue.js"></script>
|
||||
<link rel="stylesheet" href="bootstrap/css/bootstrap.css"></link>
|
||||
<title>服务信息</title>
|
||||
<title>Service Information</title>
|
||||
<style>
|
||||
table {
|
||||
table-layout: auto;
|
||||
@ -35,20 +35,20 @@
|
||||
<body>
|
||||
<div class="row" style="margin-top: 40px;">
|
||||
<div class="col-md-6" style="margin:0 auto" id="serviceList" v-if="show">
|
||||
<h4 style="text-align: center;">服务信息</h4>
|
||||
<p>服务名称:{{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;">服务示例URL:{{service["url"]}}</p>
|
||||
<p>输入参数:</p>
|
||||
<h4 style="text-align: center;">Service Information</h4>
|
||||
<p>Service Name: {{service["name"]}}</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;">Example URL: {{service["url"]}}</p>
|
||||
<p>Input Parameters:</p>
|
||||
<table class="table table-bordered">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th style="min-width: 50px;">ID</th>
|
||||
<th>参数名称</th>
|
||||
<th>调用名称</th>
|
||||
<th>参数类型</th>
|
||||
<th>示例值</th>
|
||||
<th>参数描述</th>
|
||||
<th>Parameter Name</th>
|
||||
<th>Invoke Name</th>
|
||||
<th>Parameter Type</th>
|
||||
<th>Example Value</th>
|
||||
<th>Parameter Description</th>
|
||||
</tr>
|
||||
<tr v-if="service.inputParameters.length>0" v-for="i in service.inputParameters.length">
|
||||
<td style="min-width: 50px;">{{i}}</td>
|
||||
@ -59,12 +59,12 @@
|
||||
<td>{{service.inputParameters[i-1]["desc"]}}</td>
|
||||
</tr>
|
||||
<tr v-if="service.inputParameters.length==0">
|
||||
<td>暂无</td>
|
||||
<td>暂无</td>
|
||||
<td>暂无</td>
|
||||
<td>暂无</td>
|
||||
<td>暂无</td>
|
||||
<td>暂无</td>
|
||||
<td>Empty</td>
|
||||
<td>Empty</td>
|
||||
<td>Empty</td>
|
||||
<td>Empty</td>
|
||||
<td>Empty</td>
|
||||
<td>Empty</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@ -73,10 +73,10 @@
|
||||
<tbody>
|
||||
<tr>
|
||||
<th style="min-width: 50px;">ID</th>
|
||||
<th>参数名称</th>
|
||||
<th>参数类型</th>
|
||||
<th>示例值</th>
|
||||
<th>参数描述</th>
|
||||
<th>Parameter Name</th>
|
||||
<th>Parameter Type</th>
|
||||
<th>Example Value</th>
|
||||
<th>Parameter Description</th>
|
||||
</tr>
|
||||
<tr v-if="service.outputParameters.length>0" v-for="i in service.outputParameters.length">
|
||||
<td style="min-width: 50px;">{{i}}</td>
|
||||
@ -86,16 +86,16 @@
|
||||
<td>{{service.outputParameters[i-1]["desc"]}}</td>
|
||||
</tr>
|
||||
<tr v-if="service.outputParameters.length==0">
|
||||
<td style="min-width: 50px;">暂无</td>
|
||||
<td>暂无</td>
|
||||
<td>暂无</td>
|
||||
<td>暂无</td>
|
||||
<td>暂无</td>
|
||||
<td style="min-width: 50px;">Empty</td>
|
||||
<td>Empty</td>
|
||||
<td>Empty</td>
|
||||
<td>Empty</td>
|
||||
<td>Empty</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</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="invokeService(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">Invoke Service</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -107,7 +107,7 @@
|
||||
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象
|
||||
var r = window.location.search.substr(1).match(reg); //匹配目标参数
|
||||
if (r != null) return unescape(r[2]);
|
||||
return null; //返回参数值
|
||||
return ""; //返回参数值,默认后台地址
|
||||
}
|
||||
|
||||
var sId = getUrlParam('id');
|
||||
@ -116,6 +116,7 @@
|
||||
data: {
|
||||
service: {},
|
||||
show: false, //是否渲染
|
||||
backEndAddressServiceWrapper: getUrlParam("backEndAddressServiceWrapper"),
|
||||
},
|
||||
methods: {
|
||||
modifyService: function(id, url) {
|
||||
@ -127,14 +128,14 @@
|
||||
};
|
||||
// ws.send(JSON.stringify(message));
|
||||
// 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) {
|
||||
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.show = true;
|
||||
});
|
||||
|
@ -8,22 +8,22 @@
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<script src="vue.js"></script>
|
||||
<link rel="stylesheet" href="bootstrap/css/bootstrap.css"></link>
|
||||
<title>开始使用</title>
|
||||
<title>Start</title>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="row" style="margin-top: 40px;">
|
||||
<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">
|
||||
<table style="table-layout: fixed;" class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>服务名称</th>
|
||||
<th>Service Name</th>
|
||||
<th>URL</th>
|
||||
<th v-bind:colspan="type">操作</th>
|
||||
<th v-bind:colspan="type">Operations</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -31,14 +31,14 @@
|
||||
<td>{{i}}</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><a href="javascript:void(0)" v-on:click="browseService(list[i-1]['id'])">查看服务信息</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><a href="javascript:void(0)" v-on:click="deleteService(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'])">Modify Service</a></td>
|
||||
<td><a href="javascript:void(0)" v-on:click="deleteService(list[i-1]['id'])">Delete Service</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</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>
|
||||
|
||||
@ -50,7 +50,7 @@
|
||||
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象
|
||||
var r = window.location.search.substr(1).match(reg); //匹配目标参数
|
||||
if (r != null) return unescape(r[2]);
|
||||
return null; //返回参数值
|
||||
return ""; //返回参数值,默认后台地址
|
||||
}
|
||||
|
||||
var app = new Vue({
|
||||
@ -58,8 +58,12 @@
|
||||
data: {
|
||||
list: [],
|
||||
type: 3, //记录服务行为
|
||||
backEndAddressServiceWrapper: getUrlParam("backEndAddressServiceWrapper"),
|
||||
},
|
||||
methods: {
|
||||
newService: function (){
|
||||
window.location.href = "newService.html?backEndAddressServiceWrapper="+ app.$data.backEndAddressServiceWrapper;;
|
||||
},
|
||||
modifyService: function(id, url) {
|
||||
let message = { //显示flowchart
|
||||
type: 1, //消息类型,传递链接
|
||||
@ -71,12 +75,12 @@
|
||||
window.location.href = url; //跳转链接
|
||||
},
|
||||
browseService: function(id) {
|
||||
window.location.href = "serviceInfo.html?id=" + id; //跳转链接
|
||||
window.location.href = "serviceInfo.html?id=" + id + "&backEndAddressServiceWrapper="+ app.$data.backEndAddressServiceWrapper; //跳转链接
|
||||
},
|
||||
deleteService: function(id) {
|
||||
if (confirm("确定要删除服务吗?")) {
|
||||
$.get("http://183.129.170.180:8041/backEnd/deleteService?id=" + id, function(res) {
|
||||
$.get("http://183.129.170.180:8041/backEnd/queryServices", function(re) {
|
||||
$.get(app.$data.backEndAddressServiceWrapper + "/backEnd/deleteService?id=" + id, function(res) {
|
||||
$.get(app.$data.backEndAddressServiceWrapper + "/backEnd/queryServices", function(re) {
|
||||
result = re.sort(desc);
|
||||
app.$data.list = result;
|
||||
});
|
||||
@ -90,7 +94,7 @@
|
||||
var desc = function(x, y) {
|
||||
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);
|
||||
app.$data.list = result;
|
||||
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 |