score.vue 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908
  1. <template>
  2. <!-- 测试devkind = 'APP' -->
  3. <div style="width: 100%;;display: flex;">
  4. <div style="width: 98%;margin-left: 1%;padding-top: 0.5%;" class="tab-container">
  5. <div>
  6. <el-table
  7. :data="tableData"
  8. style="width: 100%;margin-left: 1%;margin-top: 0.5%;"
  9. :cell-style="{ padding:'5px' }"
  10. :header-cell-style="{height: heightAll*0.01+'px',}"
  11. :row-style="{ fontSize: '16px',textAlign:'center'}"
  12. border >
  13. <el-table-column type="index" label="序号" width="80">
  14. <template #default="{ $index }">
  15. <div style="text-align: center;">
  16. {{ $index + 1 }}
  17. </div>
  18. </template>
  19. </el-table-column>
  20. <el-table-column prop="name" label="模型名称" width="200">
  21. <template #default="scope">
  22. <div style="color: #409EFF;cursor: pointer;" @click="showDe(scope.row)">
  23. {{scope.row.name}}
  24. </div>
  25. </template>
  26. </el-table-column>
  27. <el-table-column prop="type" label="评价结果">
  28. </el-table-column>
  29. <el-table-column prop="url" label="评价状态" show-overflow-tooltip/>
  30. <el-table-column prop="rqtype" label="评价日期"/>
  31. <el-table-column prop="address" label="操作" width="150">
  32. <template #default="scope">
  33. <!-- <div style="display: flex;justify-content: space-between;width: 100%;">
  34. <el-button type="danger" text size="mini" style="margin-left: -5%;" @click="handleDelete(scope.row)">注销</el-button>
  35. <el-button @click="showDe(scope.row)" type="primary" text size="mini" style="margin-left: 0%;">查看</el-button>
  36. <el-button @click="testSer(scope.row)" type="primary" text size="mini" style="margin-left: 0%;">测试</el-button>
  37. <el-button @click="testSer(scope.row)" type="primary" text size="mini" style="margin-left: 0%;">审核</el-button>
  38. </div> -->
  39. <div style="display: flex;">
  40. <el-button @click="testSer(scope.row)" type="primary" text size="mini" style="margin-left: 0%;">评价</el-button>
  41. <el-button @click="showLog(scope.row)" type="primary" text size="mini" style="margin-left: 0%;">日志</el-button>
  42. </div>
  43. </template>
  44. </el-table-column>
  45. </el-table>
  46. </div>
  47. <el-dialog @close="clearAdd" v-model="dialogVisible" title="" width="60%" destroy-on-close :key="tableKey">
  48. <div style="display: flex;align-items: center;">
  49. <div v-if="detailJson.rqtype==='GET'">
  50. <el-tag class="ml-2" type="warning">GET</el-tag>
  51. </div>
  52. <div v-if="detailJson.rqtype==='POST'">
  53. <el-tag class="ml-2" type="warning">POST</el-tag>
  54. </div>
  55. <div style="margin-left: 1%;">
  56. {{ detailJson.name }}:
  57. </div>
  58. <div style="margin-left: 1%;">
  59. {{ detailJson.url }}
  60. </div>
  61. </div>
  62. <el-descriptions style="margin-top: 1%;" :column="3" border>
  63. <el-descriptions-item label="接口类型">{{ detailJson.type }}</el-descriptions-item>
  64. <el-descriptions-item label="请求方式">{{ detailJson.rqtype }}</el-descriptions-item>
  65. <el-descriptions-item label="响应类型">{{ detailJson.rptype }}</el-descriptions-item>
  66. <el-descriptions-item label="服务分类">{{ detailJson.cateCode }}</el-descriptions-item>
  67. </el-descriptions>
  68. <div style="margin-top:4%;font-size: 18px;">
  69. 请求参数
  70. </div>
  71. <el-table
  72. style="margin-top: 1%;width: 98%;"
  73. :data="tableDataCan"
  74. :cell-style="{ textAlign: 'center',padding:'2px 0' }"
  75. :header-cell-style="{ textAlign: 'center'}"
  76. :row-style="{ height: heightAll*0.01+'px',fontSize: '16px',textAlign:'center' }"
  77. border >
  78. <el-table-column prop="paramCode" label="参数字段">
  79. </el-table-column>
  80. <el-table-column prop="paramName" label="参数名称">
  81. </el-table-column>
  82. <el-table-column prop="paramType" label="参数类型" width="200">
  83. </el-table-column>
  84. <el-table-column prop="paramValue" label="参数示例">
  85. </el-table-column>
  86. <el-table-column prop="paramNote" label="参数说明" show-overflow-tooltip>
  87. </el-table-column>
  88. </el-table>
  89. <div style="margin-top:4%;font-size: 18px;">
  90. 返回参数
  91. </div>
  92. <el-input readonly placeholder="" :rows="8" type="textarea" v-model="dataJsonXiang" size="mini" text style="margin-top: 1%;width: 98%;" ></el-input>
  93. <template #footer>
  94. <span class="dialog-footer">
  95. <el-button type="primary" @click="dialogVisible = false" size="mini">
  96. 确定
  97. </el-button>
  98. </span>
  99. </template>
  100. </el-dialog>
  101. <el-dialog @close="clearAdd" v-model="dialogVisibleTest" :title="titleTest" width="60%" destroy-on-close :key="tableKey">
  102. <div style="margin-left: 1%;">
  103. {{ detailJson.name }}:
  104. </div>
  105. <div style="display: flex;align-items: center;width: 98%;margin-top: 1%;">
  106. <div v-if="detailJson.rqtype==='GET'">
  107. <el-tag class="ml-2" type="warning">GET</el-tag>
  108. </div>
  109. <div v-if="detailJson.rqtype==='POST'">
  110. <el-tag class="ml-2" type="warning">POST</el-tag>
  111. </div>
  112. <div style="margin-left: 1%;">
  113. {{ detailJson.url }}
  114. </div>
  115. <!-- <svg-icon @click="test" icon-class="startTest" style="margin-left: 1%;width: 50px;height: 25px;cursor: pointer;"/> -->
  116. <el-button @click="test" size="mini" type="primary" style="margin-left: 1%;cursor: pointer;" plain>点击测试</el-button>
  117. </div>
  118. <div style="margin-top:2%;font-size: 18px;">
  119. 请求参数
  120. </div>
  121. <el-table
  122. style="margin-top: 1%;width: 98%;"
  123. :data="tableDataCan"
  124. :cell-style="{ textAlign: 'center',padding:'2px 0' }"
  125. :header-cell-style="{ textAlign: 'center'}"
  126. :row-style="{ height: heightAll*0.01+'px',fontSize: '16px',textAlign:'center' }"
  127. border >
  128. <el-table-column prop="paramCode" label="参数字段">
  129. </el-table-column>
  130. <el-table-column prop="paramName" label="参数名称">
  131. </el-table-column>
  132. <el-table-column prop="paramType" label="参数类型" width="200">
  133. </el-table-column>
  134. <el-table-column prop="paramValue" label="测试值">
  135. <template #default="scope">
  136. <div style="width: 100%;">
  137. <el-input placeholder="请填写" type="primary" class="noBor" v-model="scope.row.paramValue" size="mini" text style="margin-left: 0%;"></el-input>
  138. </div>
  139. </template>
  140. </el-table-column>
  141. <el-table-column prop="paramNote" label="参数说明" show-overflow-tooltip>
  142. </el-table-column>
  143. </el-table>
  144. <div style="margin-top:4%;font-size: 18px;">
  145. 返回参数
  146. </div>
  147. <el-input placeholder="" :rows="8" type="textarea" v-model="dataReturn" size="mini" text style="margin-top: 1%;width: 98%;" ></el-input>
  148. <template #footer>
  149. <span class="dialog-footer">
  150. </span>
  151. </template>
  152. </el-dialog>
  153. <el-dialog @close="clearFromLev" :title="titleTest" draggable v-model="dialogVisibleLevel" width="50%" destroy-on-close :key="tableKey">
  154. <el-table
  155. style="margin-top: 1%;width: 98%;min-height: 500px;"
  156. :data="tableDataLog"
  157. :cell-style="{ textAlign: 'center',padding:'2px 0' }"
  158. :header-cell-style="{ textAlign: 'center'}"
  159. :row-style="{ height: heightAll*0.01+'px',fontSize: '16px',textAlign:'center' }"
  160. border >
  161. <el-table-column prop="createBy" label="名称">
  162. </el-table-column>
  163. <el-table-column prop="runTm" label="评价结果">
  164. </el-table-column>
  165. <el-table-column prop="execTm" label="评价状态" show-overflow-tooltip>
  166. </el-table-column>
  167. <el-table-column prop="returnData" label="评价日期" show-overflow-tooltip>
  168. </el-table-column>
  169. </el-table>
  170. <template #footer>
  171. <span class="dialog-footer">
  172. <el-button type="primary" @click="dialogVisibleLevel = false" size="mini">
  173. 确定
  174. </el-button>
  175. </span>
  176. </template>
  177. </el-dialog>
  178. <el-dialog v-model="dialogVisibleDe" title="风暴潮" width="50%" @close="" destroy-on-close class="custom-dialog-bg">
  179. <el-form size="mini" :key="tableKey" style="margin-top:1%;width: 100%;" :model="formJi" label-position="right"
  180. ref="formRefJi" label-width="120px" :rules="rulesJi">
  181. <el-form-item label="名称:" prop="name" style="">
  182. <el-input v-model="formAdd.intro" style="width: 40%;" resize="none" />
  183. </el-form-item>
  184. <el-row :gutter="48">
  185. <el-col :span="10">
  186. <el-form-item label="评价日期:" prop="url" style="">
  187. <el-date-picker
  188. v-model="value1"
  189. type="date"
  190. style="width: 100%"
  191. placeholder="选择日期"
  192. />
  193. </el-form-item>
  194. </el-col>
  195. <el-col :span="10">
  196. <el-form-item label="评价生效日期:" prop="url" style="">
  197. <div style="width: 100%">
  198. <el-date-picker
  199. v-model="value1"
  200. type="daterange"
  201. style="width: 100%"
  202. range-separator="-"
  203. start-placeholder="开始时间"
  204. end-placeholder="结束时间"
  205. />
  206. </div>
  207. </el-form-item>
  208. </el-col>
  209. </el-row>
  210. <el-row :gutter="48">
  211. <el-col :span="10">
  212. <el-form-item label="质量:" prop="name" style="">
  213. <el-input v-model="formAdd.intro" style="width: 100%;" resize="none" />
  214. </el-form-item>
  215. </el-col>
  216. <el-col :span="10">
  217. <el-form-item label="评分:" prop="name" style="">
  218. <el-input v-model="formAdd.intro" style="width: 100%;" resize="none" />
  219. </el-form-item>
  220. </el-col>
  221. </el-row>
  222. <el-form-item label="说明:" prop="name" style="">
  223. <el-input v-model="formAdd.intro" style="width: 40%;" resize="none" type="textarea"/>
  224. </el-form-item>
  225. </el-form>
  226. </el-dialog>
  227. </div>
  228. </div>
  229. </template>
  230. <script setup>
  231. import {getCatalog} from "@/api/service/catalog";
  232. import { Plus,Search,Filter,Promotion,Check } from '@element-plus/icons-vue'
  233. import { reactive } from 'vue'
  234. import { modelTreeSelect,getSerDe,addService,addServiceParam,delService,addTree,deTree,getServiceInfo,testService,testLog } from "@/api/service/info";
  235. import { ref, onMounted, onUnmounted, nextTick,onBeforeMount } from 'vue';
  236. import JsonViewer from 'vue-json-viewer'
  237. import 'vue-json-viewer/style.css'
  238. import JsonEditorVue from 'json-editor-vue3'
  239. import { cloneDeep } from 'lodash'
  240. import { useClipboard } from "@vueuse/core";
  241. const titleTest = ref('')
  242. const { proxy } = getCurrentInstance();
  243. const JsonAdd= ref(JSON.stringify({ data: "初始值1" }))
  244. const exampleAdd = ref('')
  245. const dialogVisibleLevel = ref(true)
  246. const dialogVisibleDe = ref(true)
  247. const detail = ref({
  248. name:'',
  249. rqtype:'',
  250. rptype:''
  251. })
  252. const tableDataLog = ref([])
  253. const show1Lev = ref(true)
  254. const inputNode =ref('')
  255. const isEdit = ref(true)
  256. const dataReturn = ref('')
  257. const optionsCan = ref([
  258. {
  259. label:"string",
  260. value:'string'
  261. },
  262. {
  263. label:"int",
  264. value:'int'
  265. },
  266. {
  267. label:"boolean",
  268. value:'boolean'
  269. },
  270. {
  271. label:"array",
  272. value:'array'
  273. },
  274. {
  275. label:"object",
  276. value:'object'
  277. },
  278. {
  279. label:"number",
  280. value:'number'
  281. },
  282. {
  283. label:"null",
  284. value:'null'
  285. },
  286. {
  287. label:"any",
  288. value:'any'
  289. },
  290. ])
  291. const currentNodeKey = ref('')
  292. const options = ref([
  293. {label:'开发中',
  294. value:'1'
  295. },
  296. {label:'运行中',
  297. value:'2'
  298. },
  299. ])
  300. const dataJsonXiang = ref([])
  301. const parTree = ref({})
  302. const valueKet = ref(0)
  303. const tableDataCan = ref([
  304. {
  305. itemName:'',
  306. itemCode:'',
  307. paramType:'',
  308. paramNote:''
  309. }
  310. ])
  311. const dialogVisibleTest = ref(false)
  312. const optionsMdid = ref([])
  313. const optionsRqtype = ref([
  314. {label:'GET',
  315. value:'GET'
  316. },
  317. {label:'POST',
  318. value:'POST'
  319. },
  320. ])
  321. const optionsType= ref([
  322. {label:'RESTful',
  323. value:'RESTful'
  324. },
  325. {label:'WebService',
  326. value:'WebService'
  327. },
  328. {label:'HTTP',
  329. value:'HTTP'
  330. },
  331. {label:'WebSocket',
  332. value:'WebSocket'
  333. },
  334. ])
  335. const data = ref([])
  336. const select = ref('1')
  337. const activeName = ref('first')
  338. const title = ref('')
  339. const titleTree = ref('')
  340. const currentPage = ref(1)
  341. const total = ref(1)
  342. const tableData = ref([])
  343. const tableheight = window.innerHeight*0.7
  344. const heightAll = window.innerHeight
  345. const dialogVisible = ref(false)
  346. const dialogVisibleTree = ref(false)
  347. const isAdd = ref(false)
  348. const isAddTa = ref(false)
  349. const treeId = ref('');
  350. const valueSta = ref('1');
  351. const parMdid = ref('')
  352. const example = ref('');
  353. const tableDataCanAdd = ref([
  354. {
  355. itemName:'',
  356. itemCode:'',
  357. paramType:'',
  358. paramNote:''
  359. }
  360. ])
  361. const formZu = ref({
  362. itemName:'',
  363. itemTp:'',
  364. itemEn:'',
  365. itemTp:'',
  366. itemDataTp:'',
  367. itemDefaultVal:'',
  368. itemUnit:'',
  369. itemNotes:'',
  370. });
  371. const parId= ref('')
  372. const formJi = ref({
  373. name:'',
  374. cateCode:'',
  375. type:'',
  376. url:'',
  377. rqtype:'',
  378. rptype:'',
  379. intro:'',
  380. });
  381. const rulesJi = reactive({
  382. name: [{ required: true, message: '必填', trigger: 'blur' }],
  383. url: [{ required: true, message: '必填', trigger: 'blur' }],
  384. cateCode: [{ required: true, message: '必填', trigger: 'blur' }],
  385. });
  386. const formRefJi = ref();
  387. const formAdd = ref({
  388. name:'',
  389. cateCode:'',
  390. type:'',
  391. url:'',
  392. rqtype:'',
  393. rptype:'',
  394. intro:'',
  395. mdid:''
  396. });
  397. const rulesAdd = reactive({
  398. mdid: [{ required: true, message: '必填', trigger: 'blur' }],
  399. name: [{ required: true, message: '必填', trigger: 'blur' }],
  400. url: [{ required: true, message: '必填', trigger: 'blur' }],
  401. cateCode: [{ required: true, message: '必填', trigger: 'blur' }],
  402. });
  403. const formRefAdd = ref();
  404. const treeRef = ref(null);
  405. const formTree = ref({
  406. itemName:'',
  407. catePid:'',
  408. itemNo:'',
  409. itemNotes:''
  410. });
  411. const rulesTree = reactive({
  412. itemNo: [{ required: true, message: '必填', trigger: 'blur' }],
  413. catePid: [{ required: true, message: '必填', trigger: 'blur' }],
  414. itemName: [{ required: true, message: '必填', trigger: 'blur' }],
  415. });
  416. const formRefTree = ref();
  417. const formLev = ref({
  418. itemName:'',
  419. itemNo:'',
  420. itemNotes:'',
  421. });
  422. const rulesLev = reactive({
  423. itemNotes: [{ required: true, message: '必填', trigger: 'blur' }],
  424. itemNo: [{ required: true, message: '必填', trigger: 'blur' }],
  425. itemName: [{ required: true, message: '必填', trigger: 'blur' }],
  426. });
  427. const formRefLev = ref();
  428. const cascaderOptions = ref([])
  429. const props1 = ref({
  430. checkStrictly: true,
  431. })
  432. const detailJson = ref('')
  433. const parOptions = ref([])
  434. watch(inputNode, (val) => {
  435. treeRef.value?.filter(val); // 调用树的过滤方法
  436. });
  437. const filterNode = (value, data) => {
  438. if (!value) return true; // 空搜索时显示所有节点
  439. return data.label.includes(value); // 检查节点标签是否包含关键字
  440. };
  441. const copied = ref(false);
  442. function showLog(row){
  443. dialogVisibleLevel.value = true
  444. var par = {
  445. serId:row.srvId
  446. }
  447. testLog(par).then(res=>{
  448. tableDataLog.value = res.rows
  449. })
  450. }
  451. function test(){
  452. var par = detailJson.value
  453. par.params = tableDataCan.value
  454. testService(par).then(res=>{
  455. console.log(res)
  456. dataReturn.value = res.msg
  457. var par1 = {
  458. data:{id:parMdid.value}
  459. }
  460. handleNodeClick(null,par1,null)
  461. })
  462. }
  463. function testSer(row){
  464. getSerDe(row.srvId).then(res=>{
  465. if(res.code===200){
  466. detailJson.value = res.data.ptService
  467. console.log(detailJson.value)
  468. dialogVisibleTest.value = true
  469. tableDataCan.value = res.data.list
  470. }
  471. })
  472. }
  473. function showDe(row){
  474. getSerDe(row.srvId).then(res=>{
  475. if(res.code===200){
  476. dialogVisibleDe.value = true
  477. parOptions.value.forEach(item=>{
  478. if(res.data.ptService.cateCode === item.cateCode){
  479. res.data.ptService.cateCode = item.cateName
  480. }
  481. })
  482. if(res.data.ptService.rptype === '1'){
  483. res.data.ptService.rptype = 'JSON'
  484. }
  485. if(res.data.ptService.rptype === '2'){
  486. res.data.ptService.rptype = 'XML'
  487. }
  488. if(res.data.ptService.rptype === '3'){
  489. res.data.ptService.rptype = 'HTML'
  490. }
  491. formJi.value = res.data.ptService
  492. }
  493. })
  494. }
  495. function filterModelNodes(nodes) {
  496. if (!Array.isArray(nodes)) return [];
  497. const result = [];
  498. for (const node of nodes) {
  499. // 递归处理子节点(如果有)
  500. const filteredChildren = node.children ? filterModelNodes(node.children) : [];
  501. if (node.nodeType === 'MODEL') {
  502. // 保留当前节点,并更新其子节点
  503. node.value = node.id
  504. result.push({
  505. ...node,
  506. children: filteredChildren
  507. });
  508. } else {
  509. // 删除当前节点,将其子节点提升到当前层级
  510. result.push(...filteredChildren);
  511. }
  512. }
  513. return result;
  514. }
  515. function clearAdd(){
  516. tableDataCan.value = [
  517. ]
  518. dataReturn.value = ''
  519. }
  520. function extractModelNodesDFSIterative(root) {
  521. const result = [];
  522. const stack = root;
  523. while (stack.length > 0) {
  524. const node = stack.pop();
  525. if (node.nodeType === 'MODEL') {
  526. result.push(node);
  527. }
  528. // 子节点逆序入栈(保证从左到右遍历)
  529. if (node.children) {
  530. for (let i = node.children.length - 1; i >= 0; i--) {
  531. stack.push(node.children[i]);
  532. }
  533. }
  534. }
  535. return result;
  536. }
  537. function delAll(){
  538. proxy.$modal.confirm('是否确认删除?').then(function () {
  539. return deTree(parTree.value.id);
  540. }).then(() => {
  541. getTreeLeft();
  542. proxy.$modal.msgSuccess("删除成功");
  543. dialogVisibleLevel.value = false
  544. }).catch(() => {});
  545. }
  546. function clearFromLev(){
  547. tableDataLog.value = []
  548. }
  549. function addNextLevel(){
  550. dialogVisibleLevel.value = true
  551. show1Lev.value = false
  552. }
  553. function saveAddNextLevel(){
  554. formRefLev.value.validate((valid) => {
  555. if(valid){
  556. var par = formLev.value
  557. par.treeType = 'MODEL'
  558. par.treePid = parTree.value.id
  559. addTree(par).then(res=>{
  560. if(res.code===200){
  561. proxy.$modal.msgSuccess("新增成功");
  562. getTreeLeft()
  563. dialogVisibleLevel.value = false
  564. }
  565. })
  566. }
  567. });
  568. }
  569. function add1Level(){
  570. dialogVisibleLevel.value = true
  571. show1Lev.value = true
  572. }
  573. function saveAdd1Level(){
  574. formRefLev.value.validate((valid) => {
  575. if(valid){
  576. var par = formLev.value
  577. par.treeType = 'MODEL'
  578. par.treePid = parTree.value.pid
  579. addTree(par).then(res=>{
  580. if(res.code===200){
  581. proxy.$modal.msgSuccess("新增成功");
  582. getTreeLeft()
  583. dialogVisibleLevel.value = false
  584. }
  585. })
  586. }
  587. });
  588. }
  589. async function delSer(){
  590. proxy.$modal.confirm('是否确认删除?').then(function () {
  591. return delService(parId.value.id);
  592. }).then(() => {
  593. getTreeLeft();
  594. proxy.$modal.msgSuccess("删除成功");
  595. }).catch(() => {});
  596. }
  597. async function addSer(){
  598. console.log(JsonAdd.value)
  599. var valid
  600. await formRefAdd.value.validate((valid1) => {
  601. valid = valid1
  602. });
  603. console.log(valid)
  604. if(valid){
  605. var par = formAdd.value
  606. par.example = exampleAdd.value
  607. par.rpcontent = JsonAdd.value
  608. par.cateCode = par.cateCode[0]
  609. console.log(par)
  610. await addService(par).then(res=>{
  611. if(res.code===200){
  612. var parCan = tableDataCanAdd.value
  613. parCan.srvId = res.data.srvId
  614. addServiceParam(parCan).then(res1=>{
  615. if(res1.code===200){
  616. proxy.$modal.msgSuccess("新增成功");
  617. getTreeLeft()
  618. }
  619. })
  620. }
  621. })
  622. }
  623. }
  624. function showAdd(){
  625. dialogVisible.value = true
  626. }
  627. async function handleNodeClick(node,data,event){
  628. // parTree.value = data.data
  629. // currentNodeKey.value = data.data.id
  630. // isEdit.value = false
  631. // parId.value = data.data
  632. // await getSerDe(data.data.id).then(res=>{
  633. // if(res.data.ptService){
  634. // detail.value = res.data.ptService
  635. // tableDataCan.value = res.data.list
  636. // dataReturn.value = res.data.returnList
  637. // console.log(tableDataCan.value)
  638. // dataJsonXiang.value = res.data.ptService.rpcontent
  639. // formJi.value = res.data.ptService
  640. // example.value = res.data.ptService.example
  641. // }
  642. // })
  643. console.log(data)
  644. titleTest.value = data.data.label
  645. parMdid.value = data.data.id
  646. var par = {
  647. mdid:data.data.id
  648. }
  649. console.log(data.data.id)
  650. await getServiceInfo(par).then(res=>{
  651. if(res.data){
  652. tableData.value = res.data.serviceList
  653. }
  654. })
  655. parOptions.value.forEach(option => {
  656. option.label = option.cateName;
  657. option.value = option.cateCode;
  658. });
  659. console.log(parOptions.value)
  660. for(var i = 0; i < parOptions.value.length; i++){
  661. for(var i1 = 0; i1 < tableData.value.length; i1++){
  662. console.log(i1);
  663. if(parOptions.value[i].value === tableData.value[i1].cateCode){
  664. tableData.value[i1].cateCode = parOptions.value[i].label
  665. }
  666. }
  667. }
  668. var par = [
  669. {
  670. value:'1',
  671. label:'JSON'
  672. },
  673. {
  674. value:'2',
  675. label:'XML'
  676. },
  677. {
  678. value:'3',
  679. label:'HTML'
  680. }
  681. ]
  682. for(var i = 0; i < par.length; i++){
  683. for(var i1 = 0; i1 < tableData.value.length; i1++){
  684. if(par[i].value === tableData.value[i1].rptype){
  685. tableData.value[i1].rptype = par[i].label
  686. }
  687. }
  688. }
  689. }
  690. async function getTreeLeft(){
  691. var par = {
  692. params:{
  693. level:'2',
  694. devkind:'APP'
  695. }
  696. }
  697. await modelTreeSelect(par).then(res=>{
  698. par = res.data
  699. data.value = res.data
  700. })
  701. optionsMdid.value = filterModelNodes(par)
  702. console.log(optionsMdid.value)
  703. }
  704. function renameTreeProperties(tree) {
  705. // 深拷贝避免修改原始数据(可选,根据需求)
  706. const newTree = cloneDeep(tree); // 使用 lodash
  707. // 或:const newTree = JSON.parse(JSON.stringify(tree)); // 原生方法(不兼容函数等)
  708. // 递归处理函数
  709. const processNode = (node) => {
  710. // 重命名属性
  711. if ('cateName' in node) {
  712. node.label = node.cateName;
  713. delete node.cateName;
  714. }
  715. if ('cateCode' in node) {
  716. node.value = node.cateCode;
  717. delete node.cateCode;
  718. }
  719. // 递归处理子节点
  720. if (node.children && node.children.length > 0) {
  721. node.children.forEach(child => processNode(child));
  722. }
  723. };
  724. // 遍历根节点
  725. newTree.forEach(rootNode => processNode(rootNode));
  726. return newTree;
  727. }
  728. function fetchData() {
  729. getCatalog().then((r) => {
  730. parOptions.value = r.data
  731. cascaderOptions.value = renameTreeProperties(buildTree(r.data))
  732. console.log(parOptions.value)
  733. });
  734. }
  735. function buildTree(flatData, rootValue = '0') {
  736. const nodeMap = new Map();
  737. const tree = [];
  738. flatData.forEach(item => {
  739. nodeMap.set(item.cateCode, { ...item, children: [] });
  740. });
  741. for (const [code, node] of nodeMap) {
  742. const parentCode = node.catePcode;
  743. if (parentCode === rootValue || !parentCode) {
  744. tree.push(node);
  745. continue;
  746. }
  747. const parent = nodeMap.get(parentCode);
  748. if (parent) {
  749. parent.children.push(node);
  750. } else {
  751. console.warn(`Orphan node detected: ${code}. Parent ${parentCode} not found`);
  752. }
  753. }
  754. return tree;
  755. }
  756. function addPa(){
  757. var par = {
  758. itemName:''
  759. }
  760. tableDataCan.value.push(par)
  761. }
  762. function delCan(index){
  763. tableDataCan.value.splice(index, 1)
  764. }
  765. function addCanAdd(){
  766. var par = {
  767. parName:''
  768. }
  769. tableDataCanAdd.value.push(par)
  770. }
  771. function delCanAdd(index){
  772. tableDataCanAdd.value.splice(index, 1)
  773. }
  774. onMounted(() => {
  775. fetchData()
  776. getTreeLeft()
  777. });
  778. </script>
  779. <style scoped>
  780. .noBorSel :deep(.el-select__wrapper){
  781. box-shadow: none !important; /* 去除阴影边框 */
  782. border: 1px solid transparent !important; /* 设置透明边框 */
  783. background-color: transparent !important; /* 可选:透明背景 */
  784. }
  785. .noBor :deep(.el-input__wrapper) {
  786. box-shadow: none !important; /* 去除阴影边框 */
  787. border: 1px solid transparent !important; /* 设置透明边框 */
  788. background-color: transparent !important; /* 可选:透明背景 */
  789. }
  790. /* 节点垂直间距 */
  791. :deep(.el-tree-node) {
  792. margin-bottom:5px !important; /* 增大节点间距 */
  793. }
  794. .el-popover.custom-popover {
  795. min-width: 50px;
  796. padding: 8px; /* 可选:调整内边距 */
  797. }
  798. </style>
  799. <style>
  800. .dot {
  801. width: 20px; /* 控制圆点直径 */
  802. height: 20px;
  803. background-color: #333; /* 实心颜色 */
  804. border-radius: 50%; /* 关键属性 */
  805. display: inline-block; /* 确保与其他元素并排 */
  806. }
  807. /* 全局透明样式(不使用 scoped) */
  808. .transparent-select .el-select__wrapper {
  809. background-color: transparent !important;
  810. border-color: transparent !important;
  811. box-shadow: none !important;
  812. }
  813. .transparent-select .el-select__selection {
  814. background-color: transparent;
  815. }
  816. /* 处理悬停和聚焦状态 */
  817. .transparent-select .el-select__wrapper:hover,
  818. .transparent-select .el-select__wrapper.is-focused {
  819. border-color: transparent !important;
  820. box-shadow: none !important;
  821. }
  822. /* 下拉箭头图标 */
  823. .transparent-select .el-select__caret {
  824. color: rgba(0, 0, 0, 0.5); /* 半透明图标 */
  825. }
  826. </style>
  827. <style scoped>
  828. :deep(.treeLeft) .el-tree-node__content {
  829. display: flex !important;
  830. height: 28px; /* 按设计稿调整高度 */
  831. align-items: center;
  832. padding-top: 0 !important;
  833. }
  834. :deep(.treeLeft) .el-tree-node__content:hover {
  835. background-color: #e9e9eb;
  836. }
  837. :deep(.treeLeft) .el-tree-node__content:active {
  838. background-color: rgka(69,157,255,0.1) !important;
  839. }
  840. /* 选中态(Active) */
  841. :deep(.treeLeft) .el-tree-node.is-current > .el-tree-node__content {
  842. background-color: #c6e2ff !important;
  843. }
  844. .tab-container {
  845. height: 100vh; /* 关键:父容器明确高度 */
  846. display: flex;
  847. flex-direction: column;
  848. }
  849. .drag-handle {
  850. cursor: move;
  851. }
  852. .ghost {
  853. opacity: 0.5;
  854. background: #c8ebfb;
  855. }
  856. /* 防止文字选中 */
  857. :deep(.el-table__row) {
  858. user-select: none;
  859. -webkit-user-select: none;
  860. }
  861. </style>
  862. <style scoped lang="scss">
  863. .custom-tree-node {
  864. display: flex; /* 启用 Flex 布局 */
  865. align-items: center; /* 垂直居中 */
  866. gap: 8px; /* 图标与文字间距 */
  867. justify-content: space-between;
  868. }
  869. .el-table .el-table__row td {
  870. height: 60px !important; /* 行高 */
  871. }
  872. .custom-tree-node {
  873. display: flex; /* 启用 Flex 布局 */
  874. align-items: center; /* 垂直居中 */
  875. gap: 8px; /* 图标与文字间距 */
  876. }
  877. </style>