debugging.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. <template>
  2. <div class="content" v-if="interfaceData">
  3. <div class="head">
  4. <Input v-model="interfaceData.url">
  5. <template #prepend>
  6. <Select v-model="interfaceData.method" style="width: 120px">
  7. <Option v-for="(item, index) in requestTypeList" :key="index" :value="item.value">{{ item.label }}</Option>
  8. </Select>
  9. </template>
  10. </Input>
  11. <Button class="ml20" type="primary" @click="requestData">请求</Button>
  12. <Button class="ml10 copy-btn" type="success" @click="insertCopy()">复制</Button>
  13. </div>
  14. <div class="params">
  15. <Tabs class="mt10" v-model="paramsType" @on-click="changeTab">
  16. <TabPane label="Params" name="Params"> </TabPane>
  17. <TabPane label="Body" name="Body"> </TabPane>
  18. <TabPane label="Header" name="Header"> </TabPane>
  19. </Tabs>
  20. <div v-show="paramsType === 'Params'">
  21. <vxe-table
  22. class="mt10"
  23. resizable
  24. show-overflow
  25. keep-source
  26. ref="xTable"
  27. row-id="id"
  28. :print-config="{}"
  29. :export-config="{}"
  30. :tree-config="{ transform: true, rowField: 'id', parentField: 'parentId' }"
  31. :data="interfaceData.request_params"
  32. >
  33. <vxe-column field="attribute" width="150" title="属性" tree-node :edit-render="{}">
  34. <template #default="{ row }">
  35. <vxe-input v-model="row.attribute" type="text"></vxe-input>
  36. </template>
  37. </vxe-column>
  38. <vxe-column field="value" title="参数值" :edit-render="{}">
  39. <template #default="{ row }">
  40. <vxe-input v-model="row.value" type="text"></vxe-input>
  41. </template>
  42. </vxe-column>
  43. <vxe-column field="type" title="类型" width="120" :edit-render="{}">
  44. <template #default="{ row }">
  45. <vxe-select v-model="row.type" transfer>
  46. <vxe-option
  47. v-for="item in typeList"
  48. :key="item.value"
  49. :value="item.value"
  50. :label="item.label"
  51. ></vxe-option>
  52. </vxe-select>
  53. </template>
  54. </vxe-column>
  55. <vxe-column field="must" title="必填" width="50" :edit-render="{}">
  56. <template #default="{ row }">
  57. <span>{{ row.must == '1' ? '是' : '否' }}</span>
  58. </template>
  59. </vxe-column>
  60. <vxe-column field="trip" width="150" title="说明" :edit-render="{}">
  61. <template #default="{ row }">
  62. <vxe-input v-model="row.trip" type="text"></vxe-input>
  63. </template>
  64. </vxe-column>
  65. <vxe-column title="操作" width="120">
  66. <template #default="{ row }">
  67. <vxe-button type="text" v-if="row.type === 'array'" status="primary" @click="insertRow(row, 'xTable')"
  68. >插入</vxe-button
  69. >
  70. <vxe-button type="text" status="primary" @click="removeRow(row, 'xTable')">删除</vxe-button>
  71. </template>
  72. </vxe-column>
  73. </vxe-table>
  74. <Button class="mt10" type="primary" @click="insertEvent('xTable')">添加参数</Button>
  75. </div>
  76. <div v-show="paramsType === 'Body'">
  77. <vxe-table
  78. class="mt10"
  79. resizable
  80. show-overflow
  81. keep-source
  82. ref="yTable"
  83. row-id="id"
  84. :print-config="{}"
  85. :export-config="{}"
  86. :tree-config="{ transform: true, rowField: 'id', parentField: 'parentId' }"
  87. :data="interfaceData.request_body"
  88. >
  89. <vxe-column field="attribute" width="150" title="属性" tree-node :edit-render="{}">
  90. <template #default="{ row }">
  91. <vxe-input v-model="row.attribute" type="text"></vxe-input>
  92. </template>
  93. </vxe-column>
  94. <vxe-column field="value" title="参数值" :edit-render="{}">
  95. <template #default="{ row }">
  96. <vxe-input v-model="row.value" type="text"></vxe-input>
  97. </template>
  98. </vxe-column>
  99. <vxe-column field="type" title="类型" width="120" :edit-render="{}">
  100. <template #default="{ row }">
  101. <vxe-select v-model="row.type" transfer>
  102. <vxe-option
  103. v-for="item in typeList"
  104. :key="item.value"
  105. :value="item.value"
  106. :label="item.label"
  107. ></vxe-option>
  108. </vxe-select>
  109. </template>
  110. </vxe-column>
  111. <vxe-column field="must" title="必填" width="50" :edit-render="{}">
  112. <template #default="{ row }">
  113. <span>{{ row.must == '1' ? '是' : '否' }}</span>
  114. </template>
  115. </vxe-column>
  116. <vxe-column field="trip" title="说明" width="150" :edit-render="{}">
  117. <template #default="{ row }">
  118. <vxe-input v-model="row.trip" type="text"></vxe-input>
  119. </template>
  120. </vxe-column>
  121. <vxe-column title="操作" width="120">
  122. <template #default="{ row }">
  123. <vxe-button type="text" v-if="row.type === 'array'" status="primary" @click="insertRow(row, 'yTable')"
  124. >插入</vxe-button
  125. >
  126. <vxe-button type="text" status="primary" @click="removeRow(row, 'yTable')">删除</vxe-button>
  127. </template>
  128. </vxe-column>
  129. </vxe-table>
  130. <Button class="mt10" type="primary" @click="insertEvent('yTable')">添加参数</Button>
  131. </div>
  132. <div v-show="paramsType === 'Header'">
  133. <vxe-table
  134. class="mt10"
  135. resizable
  136. show-overflow
  137. keep-source
  138. ref="zTable"
  139. row-id="id"
  140. :print-config="{}"
  141. :export-config="{}"
  142. :tree-config="{ transform: true, rowField: 'id', parentField: 'parentId' }"
  143. :data="interfaceData.headerData"
  144. >
  145. <vxe-column field="attribute" width="300" title="属性" tree-node :edit-render="{}">
  146. <template #default="{ row }">
  147. <vxe-input v-model="row.attribute" type="text"></vxe-input>
  148. </template>
  149. </vxe-column>
  150. <vxe-column field="value" title="参数值" :edit-render="{}">
  151. <template #default="{ row }">
  152. <vxe-input v-model="row.value" type="text"></vxe-input>
  153. </template>
  154. </vxe-column>
  155. <vxe-column field="type" title="类型" width="200" :edit-render="{}">
  156. <template #default="{ row }">
  157. <vxe-select v-model="row.type" transfer>
  158. <vxe-option
  159. v-for="item in typeList"
  160. :key="item.value"
  161. :value="item.value"
  162. :label="item.label"
  163. ></vxe-option>
  164. </vxe-select>
  165. </template>
  166. </vxe-column>
  167. <vxe-column title="操作" width="100">
  168. <template #default="{ row }">
  169. <vxe-button type="text" v-if="row.type === 'array'" status="primary" @click="insertRow(row, 'zTable')"
  170. >插入</vxe-button
  171. >
  172. <vxe-button type="text" status="primary" @click="removeRow(row, 'zTable')">删除</vxe-button>
  173. </template>
  174. </vxe-column>
  175. </vxe-table>
  176. <Button class="mt10" type="primary" @click="insertEvent('zTable')">添加参数</Button>
  177. <h4 class="mt10 title">全局Header参数</h4>
  178. <vxe-table
  179. class="mt10"
  180. resizable
  181. show-overflow
  182. keep-source
  183. ref="zaTable"
  184. row-id="id"
  185. :print-config="{}"
  186. :export-config="{}"
  187. :tree-config="{ transform: true, rowField: 'id', parentField: 'parentId' }"
  188. :data="interfaceData.allHeaderData"
  189. >
  190. <vxe-column field="attribute" width="300" title="属性" tree-node :edit-render="{}">
  191. <template #default="{ row }">
  192. <span>{{ row.attribute || '' }}</span>
  193. </template>
  194. </vxe-column>
  195. <vxe-column field="value" title="参数值" :edit-render="{}">
  196. <template #default="{ row }">
  197. <span>{{ row.value || '' }}</span>
  198. </template>
  199. </vxe-column>
  200. <vxe-column field="type" title="类型" width="200" :edit-render="{}">
  201. <template #default="{ row }">
  202. <span>{{ row.type || '' }}</span>
  203. </template>
  204. </vxe-column>
  205. <vxe-column field="trip" title="说明" :edit-render="{}">
  206. <template #default="{ row }">
  207. <span>{{ row.trip || '' }}</span>
  208. </template>
  209. </vxe-column>
  210. </vxe-table>
  211. </div>
  212. </div>
  213. <div class="res mt10 mb10" v-if="codes">
  214. <MonacoEditor :codes="codes" :readOnly="true" />
  215. </div>
  216. </div>
  217. </template>
  218. <script>
  219. import request from './request';
  220. import MonacoEditor from './components/MonacoEditor.vue';
  221. function requestMethod(url, method, params, data, headerItem) {
  222. return request({
  223. url,
  224. method,
  225. params,
  226. data,
  227. headerItem,
  228. });
  229. }
  230. export default {
  231. components: { MonacoEditor },
  232. props: {
  233. formValidate: {
  234. type: Object,
  235. default: () => {
  236. return {};
  237. },
  238. },
  239. requestTypeList: {
  240. type: Array,
  241. default: () => {
  242. return [];
  243. },
  244. },
  245. typeList: {
  246. type: Array,
  247. default: () => {
  248. return [];
  249. },
  250. },
  251. },
  252. data() {
  253. return {
  254. interfaceData: undefined,
  255. paramsType: 'Params',
  256. editor: '', //当前编辑器对象
  257. codes: '',
  258. };
  259. },
  260. created() {
  261. this.interfaceData = this.formValidate;
  262. this.interfaceData.request_body = JSON.parse(JSON.stringify(this.interfaceData.request_params));
  263. console.log(this.interfaceData);
  264. },
  265. mounted() {},
  266. methods: {
  267. insertCopy() {
  268. this.$copyText(this.codes)
  269. .then((message) => {
  270. this.$Message.success('复制成功');
  271. })
  272. .catch((err) => {
  273. this.$Message.error('复制失败');
  274. });
  275. },
  276. async requestData() {
  277. console.log(this.$refs.xTable.getTableData().tableData);
  278. console.log(this.filtersData((await this.$refs.xTable.getTableData().tableData) || []));
  279. let url, method, params, body, headers;
  280. url = this.interfaceData.url;
  281. method = this.interfaceData.method;
  282. params = this.filtersData((await this.$refs.xTable.getTableData().tableData) || []);
  283. body = this.filtersData((await this.$refs.yTable.getTableData().tableData) || []);
  284. let h = this.filtersData((await this.$refs.zTable.getTableData().tableData) || []);
  285. let h1 = this.filtersData((await this.$refs.zaTable.getTableData().tableData) || []);
  286. console.log(this.interfaceData, h, h1);
  287. headers = {
  288. ...h,
  289. ...h1,
  290. };
  291. console.log(url, method, params, body, headers);
  292. requestMethod(url, method, params, body, headers)
  293. .then((res) => {
  294. this.codes = res + '';
  295. })
  296. .catch((err) => {
  297. this.codes = JSON.stringify(err);
  298. });
  299. },
  300. filtersData(arr) {
  301. console.log(arr);
  302. try {
  303. let x = {};
  304. arr.map((e) => {
  305. if (!e.parentId) {
  306. for (let i in e) {
  307. if (i == 'attribute') {
  308. console.log(e);
  309. if (e.type !== 'array') {
  310. x[e[i]] = e.value || '';
  311. } else {
  312. let arr = [];
  313. e.children.map((item, index) => {
  314. arr[index] = this.filtersObj(item);
  315. });
  316. x[e[i]] = arr;
  317. }
  318. }
  319. }
  320. }
  321. });
  322. return x;
  323. } catch (error) {
  324. console.log(error);
  325. }
  326. },
  327. filtersObj(obj) {
  328. let x = {};
  329. for (let i in obj) {
  330. if (i == 'attribute') {
  331. if (obj.type !== 'array') {
  332. x[obj[i]] = obj.value || '';
  333. } else {
  334. let arr = [];
  335. obj.children.map((item, index) => {
  336. arr[index] = this.filtersObj(item);
  337. });
  338. x[obj[i]] = arr;
  339. }
  340. }
  341. }
  342. return x;
  343. },
  344. changeTab(name) {
  345. if (name === 'Header') {
  346. console.log(this.interfaceData.headerData);
  347. if (!this.interfaceData.headerData) {
  348. this.insertEvent('zTable', {
  349. attribute: 'Content-Type',
  350. value: 'application/x-www-form-urlencoded',
  351. });
  352. this.insertEvent('zaTable');
  353. }
  354. }
  355. console.log(this.interfaceData);
  356. },
  357. async insertEvent(type, d) {
  358. const $table = this.$refs[type];
  359. let newRow;
  360. if (type == 'xTable') {
  361. newRow = {
  362. attribute: '',
  363. type: 'string',
  364. must: 0,
  365. value: '',
  366. trip: '',
  367. };
  368. } else if (type == 'yTable') {
  369. newRow = {
  370. attribute: '',
  371. type: 'string',
  372. value: '',
  373. must: 0,
  374. trip: '',
  375. };
  376. } else if (type == 'zTable') {
  377. newRow = {
  378. attribute: '',
  379. type: '',
  380. value: '',
  381. trip: '',
  382. };
  383. newRow = { ...newRow, ...d };
  384. } else if (type == 'zaTable') {
  385. newRow = {
  386. attribute: 'token',
  387. type: 'string',
  388. value: '',
  389. must: 0,
  390. trip: '',
  391. };
  392. } else {
  393. newRow = {
  394. code: '',
  395. value: '',
  396. solution: '',
  397. };
  398. }
  399. const { row: data } = await $table.insertAt(newRow, -1);
  400. await $table.setActiveCell(data, 'name');
  401. },
  402. async insertRow(currRow, type) {
  403. const $table = this.$refs[type];
  404. // 如果 null 则插入到目标节点顶部
  405. // 如果 -1 则插入到目标节点底部
  406. // 如果 row 则有插入到效的目标节点该行的位置
  407. let record;
  408. if (type == 'xTable') {
  409. record = {
  410. attribute: '',
  411. type: 'string',
  412. must: 0,
  413. value: '',
  414. trip: '',
  415. id: Date.now(),
  416. parentId: currRow.id, // 需要指定父节点,自动插入该节点中
  417. };
  418. } else {
  419. record = {
  420. code: '',
  421. value: '',
  422. solution: '',
  423. id: Date.now(),
  424. parentId: currRow.id, // 需要指定父节点,自动插入该节点中
  425. };
  426. }
  427. const { row: newRow } = await $table.insertAt(record, -1);
  428. await $table.setTreeExpand(currRow, true); // 将父节点展开
  429. await $table.setActiveRow(newRow); // 插入子节点
  430. },
  431. async removeRow(row, type) {
  432. const $table = this.$refs[type];
  433. await $table.remove(row);
  434. },
  435. },
  436. };
  437. </script>
  438. <style>
  439. .vxe-select--panel.is--transfer {
  440. z-index: 99999 !important;
  441. }
  442. </style>
  443. <style lang="scss" scoped>
  444. .content {
  445. padding: 12px;
  446. .head {
  447. display: flex;
  448. align-items: center;
  449. .item {
  450. display: flex;
  451. align-items: center;
  452. margin-bottom: 12px;
  453. font-size: 14px;
  454. .title {
  455. margin-right: 14px;
  456. }
  457. }
  458. }
  459. }
  460. .copy-btn {
  461. display: flex;
  462. justify-content: right;
  463. }
  464. </style>