lowerCodeHelper

低代码平台助手

当前为 2024-01-28 提交的版本,查看 最新版本

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