lowerCodeHelper

低代码平台助手

  1. // ==UserScript==
  2. // @name lowerCodeHelper
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.4.0
  5. // @description 低代码平台助手
  6. // @author Ziker
  7. // @match https://ops.iyunquna.com/63008/*
  8. // @match http://localhost:63342/api/file/*
  9. // @require https://code.jquery.com/jquery-3.4.1.min.js
  10. // @icon https://favicon.qqsuu.cn/work.yqn.com
  11. // @note 2023年12月18日20:26:31 V0.3.4 fix RT 显示BUG
  12. // @note 2024年01月04日11:50:57 V0.3.5 支持自定义包名接口打开文件
  13. // @note 2024年01月10日11:00:40 V0.3.6 修复子流程,mq,job 跳转不显示
  14. // @note 2024年01月15日19:46:34 V0.3.7 修复自定义包名 子流程,mq,job 不跳转,MQ 消费RT显示
  15. // @note 2024年01月19日17:22:12 V0.3.8 顶部工具栏按钮新增多个工具按钮
  16. // @note 2024年01月28日18:32:49 V0.3.9 修复Bug
  17. // @note 2024年02月02日19:59:18 V0.4.0 修复导致游览器卡顿的问题
  18. // @grant GM_openInTab
  19. // @grant unsafeWindow
  20. // @grant window.close
  21. // @grant window.focus
  22. // @run-at document-body
  23. // @noframes
  24. // @license AGPL License
  25. // ==/UserScript==
  26.  
  27. window.jq = $.noConflict(true);
  28.  
  29. (function (window) {
  30. window.pageHelper = {
  31. // 等待元素可见
  32. waitElementVisible(visibleTag, fun) {
  33. const observer = new MutationObserver(() => {
  34. // 如果是目标元素存在
  35. if (document.querySelector(visibleTag)) {
  36. observer.disconnect();
  37. fun();
  38. }
  39. });
  40. observer.observe(document.body, {
  41. attributes: true, childList: true, subtree: true, characterData: true
  42. });
  43. },
  44. getCurrentApiId() {
  45. return unsafeWindow.activeKey
  46. },
  47. getAppId() {
  48. return parseInt(new URLSearchParams(window.location.href.split('?')[1]).get('appId'))
  49. },
  50. sleep(duration) {
  51. return new Promise(resolve => {
  52. setTimeout(resolve, duration)
  53. })
  54. },
  55. showToast(msg, duration) {
  56. // 显示提示
  57. duration = isNaN(duration) ? 3000 : duration
  58. const m = document.createElement('div')
  59. m.innerHTML = msg
  60. m.style.cssText = "display: flex;justify-content: center;align-items: center;width:60%; min-width:180px; " +
  61. "background:#000000; opacity:0.98; height:auto;min-height: 50px;font-size:25px; color:#fff; " +
  62. "line-height:30px; text-align:center; border-radius:4px; position:fixed; top:85%; left:20%; z-index:999999;"
  63. document.body.appendChild(m)
  64. setTimeout(function () {
  65. const d = 0.5
  66. m.style.webkitTransition = '-webkit-transform ' + d + 's ease-in, opacity ' + d + 's ease-in'
  67. m.style.opacity = '0'
  68. setTimeout(function () {
  69. document.body.removeChild(m)
  70. }, d * 1000)
  71. }, duration)
  72. },
  73. // 关闭窗口
  74. closeWindow() {
  75. window.opener = null
  76. window.open('', '_self')
  77. window.close()
  78. },
  79. formatString(str, len, padding) {
  80. const diff = len - str.toString().length
  81. if (diff > 0) {
  82. return padding.repeat(diff) + str
  83. } else {
  84. return str
  85. }
  86. },
  87. initSetting() {
  88. const customSetting = document.createElement("div")
  89. document.body.appendChild(customSetting)
  90. customSetting.innerHTML = `
  91. <div id="copy-setting"
  92. style="display: none;position: absolute;top: 0;right: 0;background-color: #fff3f3;padding: 10px;width: 600px;z-index: 9999">
  93. <p>拷贝动作</p>
  94. <p><label>Copy File Id <input type="radio" name="copyValue" value="1" /></label></p>
  95. <p><label>Rest Api Open File <input type="radio" name="copyValue" value="2" checked/></label>&nbsp;&nbsp;&nbsp;较新版本IDEA需要下载 <a target="_blank" href="https://plugins.jetbrains.com/plugin/19991-ide-remote-control">IDE Remote Control </a> 插件</p>
  96. <p><label>ToolBox Open File <input type="radio" name="copyValue" value="3" /></label>&nbsp;&nbsp;&nbsp;需要下载 <a target="_blank" href="https://www.jetbrains.com/toolbox-app/">Jetbrains ToolBox</a> 工具箱软件</p>
  97. <div id="projectPath" style="visibility: visible"><p><label><input name="path" style="width: 100%" type="text" placeholder="项目路径截止到 src 前 E:/yqnProject/yqn-wms/yqn-wms-rest-provider/"/></label></p></div>
  98. <p style="visibility: hidden"><label>同时打开编排IDE <input type="checkbox" name="openIDE" /></label>&nbsp;&nbsp;&nbsp;</p>
  99. <div style="display: flex;margin: 5px;justify-content: space-between">
  100. <button id="save" lang="zh" type="button" class="ant-btn ant-btn-default perf-tracked yqn-button"><span
  101. style="margin-left: 5px;">save</span></button>
  102. <button id="close" lang="zh" type="button" class="ant-btn ant-btn-default perf-tracked yqn-button"><span
  103. style="margin-left: 5px;">close</span></button>
  104. </div>
  105. </div>
  106. `
  107. let copyValue = localStorage.getItem("copyValue")
  108. copyValue = copyValue === null || copyValue === undefined ? 1 : copyValue
  109. document.querySelector('input[name="copyValue"][value="' + copyValue + '"]').checked = true
  110. document.getElementById("projectPath").style.visibility = copyValue === "2" ? "visible" : "hidden"
  111.  
  112. let path = localStorage.getItem("path")
  113. document.querySelector('input[name="path"]').value = path === null || path === undefined ? null : path
  114.  
  115. let openIDE = JSON.parse(localStorage.getItem("openIDE"))
  116. document.querySelector('input[name="openIDE"]').checked = openIDE === null || openIDE === undefined ? false : openIDE
  117.  
  118. const radios = document.querySelectorAll('input[name="copyValue"]')
  119. for (let i = 0; i < radios.length; i++) {
  120. radios[i].onchange = () => {
  121. const remoteRadio = document.querySelector('input[name="copyValue"]:checked')
  122. document.getElementById("projectPath").style.visibility = remoteRadio.value === "2" ? "visible" : "hidden"
  123. }
  124. }
  125. document.getElementById("save").addEventListener("click", () => {
  126. const remoteRadio = document.querySelector('input[name="copyValue"]:checked').value
  127. const pathInput = document.querySelector('input[name="path"]').value
  128. const openIDEValue = document.querySelector('input[name="openIDE"]').checked
  129. if (remoteRadio === '2' && (pathInput === null || pathInput.length === 0)) {
  130. this.showToast("路径不可为空", 1000)
  131. } else {
  132. localStorage.setItem("copyValue", remoteRadio)
  133. localStorage.setItem("path", pathInput)
  134. localStorage.setItem("openIDE", JSON.stringify(openIDEValue))
  135. this.showToast("保存成功", 1000)
  136. }
  137. })
  138. document.getElementById("close").addEventListener("click", () => {
  139. document.getElementById("copy-setting").style.display = "none"
  140. })
  141. }
  142. }
  143. })(window);
  144.  
  145.  
  146. (function () {
  147. let historyTrace = ''
  148. 'use strict';
  149. let appName = null
  150. let packageNameMap = []
  151. let typeMap = []
  152. let mutationObserverApiList = []
  153. jq(document).ready(function () {
  154. // 关闭第二种文件打开方位打开的网页
  155. if (window.location.href.indexOf("localhost:63342/api/file/") >= 0) {
  156. window.pageHelper.closeWindow()
  157. return
  158. }
  159. // 监听api tab变动
  160. waitObserve(".tabs-bar", () => {
  161. // 关闭刚刚加入的所有变动监听
  162. for (let i = 0; i < mutationObserverApiList.length; i++) {
  163. mutationObserverApiList[i].disconnect()
  164. }
  165. mutationObserverApiList = []
  166. // bar切换关闭首页显示
  167. const homePage = document.querySelector(".tab-home-page");
  168. const tabsBar = document.querySelector(".tabs-bar");
  169. if (nonNull(homePage) && nonNull(tabsBar) && nonNull(tabsBar.childNodes) && tabsBar.childNodes.length > 0) {
  170. homePage.style.display = 'none'
  171. }
  172. // 监听属性面板变动
  173. const appPanelTag = ".tab-content-presentation-components.theia-tab-" + window.pageHelper.getCurrentApiId()
  174. waitObserve(appPanelTag + " .p-8", () => {
  175. const p8 = document.querySelector(appPanelTag + " .p-8")
  176. const panel = p8.querySelector(".ant-form.ant-form-vertical.yqn-form")
  177. if (nonNull(panel) && isNull(panel.querySelector(".customScriptInfo"))) {
  178. const div = document.createElement("div")
  179. div.className = "customScriptInfo"
  180. panel.appendChild(div)
  181. // 获取当前 NodeName
  182. const childProcessNode = panel.querySelector("#code")
  183. const codeSpan = p8.querySelector(".dashboard-code span")
  184. if (isNull(childProcessNode) && isNull(codeSpan)) {
  185. return
  186. }
  187. let nodeName = nonNull(childProcessNode) ? childProcessNode.value : codeSpan.textContent
  188. // 获取当前节点信息
  189. getNodeInfo(nodeName, node => {
  190. // 处理信息
  191. const divNode = document.querySelector(appPanelTag + " .customScriptInfo")
  192. if (isNull(divNode)) {
  193. return
  194. }
  195. // 清空显示
  196. divNode.innerHTML = ""
  197. // 脚本
  198. if (nonNull(node.scriptId)) {
  199. divNode.appendChild(createTextButton("脚本:" + node.scriptId, () => copyToClipboard(node.scriptId)))
  200. }
  201. // 入参
  202. let id = node.inputScriptId
  203. const inputScriptIds = node.inputScriptIds
  204. if (nonNull(inputScriptIds)) {
  205. id = nonNull(id) ? id : inputScriptIds.example
  206. id = nonNull(id) ? id : inputScriptIds.record
  207. id = nonNull(id) ? id : inputScriptIds.recordList
  208. id = nonNull(id) ? id : inputScriptIds.condition
  209. id = nonNull(id) ? id : inputScriptIds.id
  210. }
  211. let isJava = true
  212. if (isNull(id) && nonNull(node.dslBulidData)) {
  213. id = node.dslBulidData.dslScriptId
  214. isJava = false
  215. }
  216. if (nonNull(id)) {
  217. divNode.appendChild(createTextButton("入参:" + id, () => copyToClipboard(id, isJava)))
  218. }
  219. // 条件
  220. const executeScriptId = node.executeScriptId
  221. if (nonNull(executeScriptId)) {
  222. divNode.appendChild(createTextButton("条件:" + executeScriptId, () => copyToClipboard(executeScriptId)))
  223. }
  224. // 校验
  225. const assertScriptId = node.assertScriptId
  226. if (nonNull(assertScriptId)) {
  227. divNode.appendChild(createTextButton("校验:" + assertScriptId, () => copyToClipboard(assertScriptId)))
  228. }
  229. })
  230. }
  231. }, true, observe => mutationObserverApiList.push(observe))
  232. // 监听执行历史面板变动
  233. const executeHistoryBodyTag = appPanelTag + " .test-split-item.test-split-item-right .ant-table-body tbody"
  234. waitObserve(executeHistoryBodyTag, () => {
  235. const lines = document.querySelectorAll(executeHistoryBodyTag + " .ant-table-row.ant-table-row-level-0")
  236. if (nonNull(lines) && lines.length > 0 && isNull(lines[0].querySelector(".customer-button-div"))) {
  237. appendFlagNode(lines[0], "customer-button-div")
  238. getExecuteHistory(content => {
  239. for (let i = 0; i < content.length; i++) {
  240. const tds = lines[i].querySelectorAll("td")
  241. const actionCol = tds[tds.length - 1]
  242. const detailButton = actionCol.querySelectorAll("button")[0]
  243. detailButton.style.display = "none"
  244. actionCol.insertBefore(createTextButton("RT:" + content[i].rt, () => {
  245. detailButton.click()
  246. historyTrace = tds[2].innerText
  247. }), detailButton)
  248. }
  249. })
  250. }
  251. }, true, observe => mutationObserverApiList.push(observe))
  252. // 获取接口package
  253. const currentApiId = window.pageHelper.getCurrentApiId();
  254. if (isNull(packageNameMap[currentApiId])) {
  255. getApiPackageName(process => {
  256. packageNameMap[currentApiId] = isNull(process.packageName) || process.packageName === '' ? 'api_' + process.id : process.packageName
  257. const type = isNull(process.type) || process.type === '' ? 'api' : process.type;
  258. if (type === 'childProcess') {
  259. typeMap[currentApiId] = 'api'
  260. } else {
  261. typeMap[currentApiId] = type
  262. }
  263. })
  264. }
  265. }, true)
  266.  
  267. // 监听body变动
  268. waitObserve("body", () => {
  269. // 监听执行日志流程图变动
  270. const processPanelTag = ".node-bpmn #canvas .bjs-container .djs-container .viewport .layer-base"
  271. const processPanel = document.querySelector(processPanelTag)
  272. if (isNull(processPanel)) {
  273. return
  274. }
  275. if (isNull(processPanel.querySelector(".customer-rt"))) {
  276. appendFlagNode(processPanel, "customer-rt")
  277. const oldRtNode = processPanel.querySelectorAll(".bpmn-tiny-label");
  278. if (nonNull(oldRtNode)) {
  279. oldRtNode.forEach(v => v.style.display = "none")
  280. }
  281. getByTraceId(apiNodeLogList => {
  282. for (let i = 0; i < apiNodeLogList.length; i++) {
  283. const log = apiNodeLogList[i]
  284. const textNode = processPanel.querySelector("[data-element-id='" + log.nodeId + "'] text")
  285. if (isNull(textNode)) {
  286. continue
  287. }
  288. const tspan = textNode.querySelector("tspan")
  289. if (nonNull(tspan)) {
  290. const rtNode = tspan.cloneNode(true)
  291. textNode.appendChild(rtNode)
  292. rtNode.setAttribute("x", "65")
  293. rtNode.setAttribute("y", "15")
  294. rtNode.innerHTML = window.pageHelper.formatString(log.rt, 4, '&nbsp;&nbsp;')
  295. }
  296. }
  297. })
  298. }
  299. }, false)
  300. // 工具栏设置按钮
  301. waitObserve(".app-actions", () => {
  302. const buttonLists = document.querySelector(".app-actions")
  303. if (isNull(buttonLists) || nonNull(document.querySelector(".setting-flag"))) {
  304. return
  305. }
  306. appendFlagNode(document.body, "setting-flag")
  307. appendToolBarButton("设置", () => {
  308. const settingPanel = document.getElementById("copy-setting")
  309. settingPanel.style.display = settingPanel.style.display === 'block' ? 'none' : "block"
  310. })
  311. appendToolBarButton("首页", () => {
  312. // 关闭首页显示
  313. const homePage = document.querySelector(".tab-home-page");
  314. const tabsBar = document.querySelector(".tabs-bar");
  315. if (nonNull(homePage) && nonNull(tabsBar) && nonNull(tabsBar.childNodes) && tabsBar.childNodes.length > 0) {
  316. homePage.style.display = homePage.style.display === 'block' ? 'none' : "block"
  317. }
  318. })
  319. appendToolBarButton("需求列表", () => {
  320. getVersionId(versionData => {
  321. if (isNull(versionData) || versionData.length === 0) {
  322. window.pageHelper.showToast("未在YWork查询到当前分支与之对应需求版本,先在YWork发布清单添加当前分支")
  323. } else {
  324. if (versionData.length > 1) {
  325. let name = "";
  326. for (let i = 0; i < versionData.length; i++) {
  327. name += versionData[i].appVersion + " ";
  328. }
  329. window.pageHelper.showToast("当前分支查到了如下 " + name + " 多个版本,不能直接跳转!")
  330. } else {
  331. window.open("https://ops.iyunquna.com/request/list/3?versionId=" + versionData[0].id)
  332. }
  333. }
  334. })
  335. })
  336. appendToolBarButton("全量发布", () => {
  337. window.pageHelper.showToast("正在发布", 3000)
  338. getVersionId(versionData => {
  339. if (isNull(versionData) || versionData.length === 0) {
  340. window.pageHelper.showToast("未在YWork查询到当前分支与之对应版本,先在YWork发布清单添加当前分支")
  341. } else {
  342. if (versionData.length > 1) {
  343. let name = "";
  344. for (let i = 0; i < versionData.length; i++) {
  345. name += versionData[i].appVersion + " ";
  346. }
  347. window.pageHelper.showToast("当前分支查到了如下 " + name + " 多个版本,不能直接发布!")
  348. } else {
  349. getPublishId(versionData[0].id, publishData => {
  350. if (isNull(publishData) || isNull(publishData.publishId)) {
  351. window.pageHelper.showToast("发布清单查询失败")
  352. } else {
  353. publish(publishData.publishId, pushData => {
  354. if (isNull(pushData) || pushData.result !== true) {
  355. window.pageHelper.showToast("发布失败", 2000)
  356. } else {
  357. window.pageHelper.showToast("发布成功", 1500)
  358. }
  359. })
  360. }
  361. })
  362. }
  363. }
  364. })
  365. })
  366. appendToolBarButton("发布记录", () => {
  367. window.open("https://ops.iyunquna.com/release-record/manage?appId=" + window.pageHelper.getAppId())
  368. })
  369. })
  370.  
  371. window.pageHelper.initSetting()
  372. getAppProjectName(data => {
  373. appName = data
  374. console.log("项目名称", data)
  375. })
  376. sync2Idea()
  377. })
  378.  
  379. function sync2Idea() {
  380. const editor = document.getElementById("theia-editor");
  381. if (nonNull(editor)) {
  382. setTimeout(() => {
  383. sync2Idea()
  384. }, 1000 * 60)
  385. jq.ajax({
  386. url: 'http://127.0.0.1:63242/socket.io',
  387. method: 'POST',
  388. xhrFields: {
  389. withCredentials: true
  390. },
  391. crossDomain: true,
  392. contentType: 'application/json',
  393. data: JSON.stringify({
  394. "url": editor.src
  395. }),
  396. })
  397. } else {
  398. window.pageHelper.sleep(500).then(() => sync2Idea())
  399. }
  400. }
  401.  
  402. function nonNull(o) {
  403. return o !== null && o !== undefined
  404. }
  405.  
  406. function isNull(o) {
  407. return o === null || o === undefined
  408. }
  409.  
  410. // 追加标记节点
  411. function appendFlagNode(node, flag) {
  412. const divFlag = document.createElement("div")
  413. node.appendChild(divFlag)
  414. divFlag.className = flag
  415. divFlag.style.display = "none"
  416. }
  417.  
  418. let isProcessing = []
  419.  
  420. // 等待出现并监听变化
  421. function waitObserve(visibleTag, fun, attributes = true, observeFuc = null) {
  422. window.pageHelper.waitElementVisible(visibleTag, () => {
  423. let mutationObserver = new MutationObserver(function () {
  424. if (isProcessing[visibleTag]) {
  425. return;
  426. }
  427. isProcessing[visibleTag] = true
  428. fun()
  429. setTimeout(() => isProcessing[visibleTag] = false, 150)
  430. })
  431. mutationObserver.observe(document.querySelector(visibleTag), {
  432. attributes: attributes, childList: true, subtree: true, characterData: true
  433. })
  434. observeFuc = observeFuc === null || observeFuc === undefined ? () => "" : observeFuc
  435. observeFuc(mutationObserver)
  436. })
  437. }
  438.  
  439. function copyToClipboard(text, isJava = true) {
  440. let copyValue = localStorage.getItem("copyValue")
  441. copyValue = copyValue === null || copyValue === undefined ? '1' : copyValue
  442. if (copyValue === '1') {
  443. let textarea = document.createElement('textarea')
  444. textarea.value = text
  445. document.body.appendChild(textarea)
  446. textarea.select()
  447. document.execCommand('copy')
  448. document.body.removeChild(textarea)
  449. window.pageHelper.showToast("已拷贝 " + text, 1500)
  450. } else if (copyValue === '2') {
  451. let path = localStorage.getItem("path")
  452. path = path === null || path === undefined ? null : (path.endsWith("/") ? path : path + '/')
  453. otherReq("http://127.0.0.1:63342/api/file/" + path + "src/main/java/com/yqn/framework/composer/" + typeMap[window.pageHelper.getCurrentApiId()] +
  454. "/" + packageNameMap[window.pageHelper.getCurrentApiId()] + "/script/Script_" + text + (isJava ? ".java" : ".json"))
  455. window.pageHelper.showToast("已打开文件,如未打开,检查插件是否安装以及path是否正确", 2000)
  456. } else if (copyValue === '3') {
  457. const url = 'jetbrains://idea/navigate/reference?project=' + appName + '&fqn=com.yqn.framework.composer.' + typeMap[window.pageHelper.getCurrentApiId()] +
  458. '.' + packageNameMap[window.pageHelper.getCurrentApiId()] + '.script.Script_' + text;
  459. window.open(url)
  460. window.pageHelper.showToast("已打开文件,如未打开,请确认已安装Jetbrains Toolbox ", 2000)
  461. }
  462. }
  463.  
  464. // 创建按钮
  465. function createTextButton(name, listener) {
  466. const button = document.createElement("button")
  467. button.type = "button"
  468. button.id = name
  469. button.className = "ant-btn ant-btn-link perf-tracked yqn-button yqn-link-no-padding customer-button"
  470. button.style.marginRight = '5px'
  471. button.onclick = listener
  472. const span = document.createElement("span")
  473. span.textContent = name
  474. button.appendChild(span)
  475. return button
  476. }
  477.  
  478. // 创建工具栏按钮
  479. function appendToolBarButton(name, listener) {
  480. const buttonLists = document.querySelector(".app-actions")
  481. const settingButton = document.createElement("div")
  482. settingButton.style.marginLeft = '10px'
  483. const button = document.createElement("button")
  484. button.type = "button"
  485. button.id = name
  486. button.className = "ant-btn ant-btn-default perf-tracked yqn-button"
  487. button.onclick = listener
  488. const span = document.createElement("span")
  489. span.textContent = name
  490. button.appendChild(span)
  491. settingButton.appendChild(button)
  492. buttonLists.appendChild(settingButton)
  493. }
  494.  
  495. // 获取分支YWork版本ID
  496. function getVersionId(fuc) {
  497. remoteReq('/api/42070/yqn_integrate/bg/integrate_app_version/v2/query_application_version', {
  498. "appBranch": localStorage.getItem("defaultBranch")
  499. }, data => {
  500. fuc(data)
  501. })
  502. }
  503.  
  504. // 获取应用清单ID
  505. function getPublishId(versionId, fuc) {
  506. remoteReq('/api/42070/api/call/cicd/publish/get_app_list', {
  507. "appVersionId": versionId
  508. }, data => {
  509. fuc(data)
  510. })
  511. }
  512.  
  513. // 发布
  514. function publish(publishId, fuc) {
  515. remoteReq('/api/42070/api/call/cicd/app/publish', {
  516. "colorTagId": "",
  517. "env": 4,
  518. "ignorePublishClash": 0,
  519. "publishId": publishId,
  520. "appIds": [window.pageHelper.getAppId()],
  521. "ignoreBranchBehind": 0
  522. }, data => {
  523. fuc(data)
  524. })
  525. }
  526.  
  527.  
  528. const addressArr = ['', '/process', '/mq', '/job']
  529.  
  530. function getApiPackageName(fuc, apiMode = 0) {
  531. remoteReq('/api/42080/api' + addressArr[apiMode] + '/details_composer', {
  532. "id": window.pageHelper.getCurrentApiId(),
  533. }, data => {
  534. if (isNull(data)) {
  535. if (apiMode === 0) {
  536. getApiPackageName(fuc, 1)
  537. getApiPackageName(fuc, 2)
  538. getApiPackageName(fuc, 3)
  539. }
  540. return
  541. }
  542. let processDefine = JSON.parse(data.processDefine)
  543. fuc(processDefine.process)
  544. })
  545. }
  546.  
  547. // 拿流程信息
  548. function getNodeInfo(nodeName, fuc, apiMode = 0) {
  549. remoteReq('/api/42080/api' + addressArr[apiMode] + '/details_composer', {
  550. "id": window.pageHelper.getCurrentApiId(),
  551. }, data => {
  552. if (isNull(data)) {
  553. if (apiMode === 0) {
  554. getNodeInfo(nodeName, fuc, 1)
  555. getNodeInfo(nodeName, fuc, 2)
  556. getNodeInfo(nodeName, fuc, 3)
  557. }
  558. return
  559. }
  560. let processDefine = JSON.parse(data.processDefine)
  561. for (let i = 0; i < processDefine.nodes.length; i++) {
  562. if (processDefine.nodes[i].code === nodeName) {
  563. fuc(processDefine.nodes[i])
  564. break
  565. }
  566. }
  567. })
  568. }
  569.  
  570. // 拿历史执行数据
  571. function getExecuteHistory(fuc) {
  572. remoteReq('/api/42086/apiLog/list', {}, data => {
  573. if (nonNull(data) && nonNull(data.content)) {
  574. fuc(data.content)
  575. }
  576. })
  577. }
  578.  
  579. // 拿 trace 执行数据
  580. function getByTraceId(fuc, apiMode = 0) {
  581. const apiType = ['api', 'process', 'consumer', 'job']
  582. remoteReq('/api/42086/apiLog/getByTraceId', {
  583. "traceIdLike": historyTrace,
  584. "testCaseId": null,
  585. "apiTypeCode": apiMode === 0 ? "api" : apiType[apiMode]
  586. }, data => {
  587. if (nonNull(data) && nonNull(data.apiNodeLogList) && data.apiNodeLogList.length !== 0) {
  588. fuc(data.apiNodeLogList)
  589. } else if (apiMode === 0) {
  590. getByTraceId(fuc, 1)
  591. getByTraceId(fuc, 2)
  592. getByTraceId(fuc, 3)
  593. }
  594. })
  595. }
  596.  
  597. // 获取应用名称
  598. function getAppProjectName(fuc) {
  599. remoteReq('/api/42080/application/getById', {}, data => {
  600. if (nonNull(data)) {
  601. fuc(data.appName)
  602. }
  603. })
  604. }
  605.  
  606.  
  607. function remoteReq(url, model, fuc) {
  608. model.apiId = window.pageHelper.getCurrentApiId()
  609. model.appId = window.pageHelper.getAppId()
  610. if (isNull(model.env)) {
  611. model.env = "qa4"
  612. }
  613. model.page = 1
  614. model.size = 20
  615. jq.ajax({
  616. url: 'https://gw-ops.iyunquna.com' + url,
  617. method: 'POST',
  618. xhrFields: {
  619. withCredentials: true
  620. },
  621. crossDomain: true,
  622. contentType: 'application/json',
  623. data: JSON.stringify({
  624. "header": {
  625. "xSourceAppId": "63008",
  626. "guid": "6f87e073-1da1-4017-b2de-c109abcd6d123",
  627. "lang": "zh",
  628. "timezone": "Asia/Shanghai"
  629. },
  630. "model": model
  631. }),
  632. success: function (response) {
  633. if (response.code === 200) {
  634. fuc(response.data)
  635. } else {
  636. fuc(null)
  637. }
  638. },
  639. error: function (xhr, status, error) {
  640. console.log('Request failed:', error)
  641. fuc(null)
  642. }
  643. })
  644. }
  645.  
  646.  
  647. function otherReq(url) {
  648. jq.ajax(url, {
  649. method: "GET",
  650. xhrFields: {
  651. withCredentials: true
  652. },
  653. crossDomain: true
  654. })
  655. }
  656. })();
  657.