Parcourir la source

Merge branch 'master' of http://39.98.38.2:13000/dumingliang/sh-model-platform

ZhuDeKang il y a 5 mois
Parent
commit
424fe4556c

+ 13 - 0
ruoyi-ui/src/api/register/regCom.js

@@ -293,3 +293,16 @@ export function delFen(id) {
     method: 'delete'
   })
 }
+export function testDatasource(id) {
+  return request({
+    url: '/meta/datasource/testConnection/' + id,
+    method: 'get'
+  })
+}
+export function dataJisql(data) {
+  return request({
+    url: "/meta/datasource/query",
+    method: 'post',
+    data:data
+  });
+}

+ 2 - 2
ruoyi-ui/src/layout/components/editModel.vue

@@ -1054,7 +1054,7 @@ function saveAddNextLevel(){
    formRefLev.value.validate((valid) => {
     if(valid){
       var par = formLev.value
-      par.treeType = parTree.value.nodeType
+      par.treeType = 'MODEL'
       par.treePid = parTree.value.id
       addTree(par).then(res=>{
         if(res.code===200){
@@ -1074,7 +1074,7 @@ function saveAdd1Level(){
   formRefLev.value.validate((valid) => {
     if(valid){
       var par = formLev.value
-      par.treeType = parTree.value.nodeType
+      par.treeType = 'MODEL'
       par.treePid = parTree.value.pid
       addTree(par).then(res=>{
         if(res.code===200){

+ 2 - 1
ruoyi-ui/src/views/index.vue

@@ -1,5 +1,6 @@
 <template>
-  
+    <div>
+    </div>
 </template>
 <script setup>
 import { ref } from 'vue';

+ 1 - 0
ruoyi-ui/src/views/platform/plugin/index.vue

@@ -1184,6 +1184,7 @@ async function submit(){
         }
         delete formJi.value.msort
         formJi.value.devkind = 'SYS'
+        formJi.value.cateid = 'eec8aee5-d859-4b44-b0a1-56a22e0c29bb'
         addModel(formJi.value).then(res=>{
         if(res.code===200){
           proxy.$modal.msgSuccess("新增成功");

+ 2 - 1
ruoyi-ui/src/views/register/componentReg/index.vue

@@ -1181,8 +1181,9 @@ async function submit(){
         if(formJi.value.devlang==='1'){
           formJi.value.devlang = elseLan.value
         }
-        delete formJi.value.msort
+        delete formJi.value.msort 
         formJi.value.devkind = 'APP'
+        formJi.value.cateid = '776eba74-eaeb-47ca-8436-e05ed87b68ec'
         addModel(formJi.value).then(res=>{
         if(res.code===200){
           proxy.$modal.msgSuccess("新增成功");

+ 110 - 7
ruoyi-ui/src/views/register/modelData/dataJi.vue

@@ -4,6 +4,9 @@
       <template #header>
       <div class="card-header" style="display: flex;align-items: center;justify-content: space-between;">
         <span>目录:</span>
+        <div>
+          <el-icon @click="addDir" style="cursor: pointer;color: #409EFF;"><Plus /></el-icon>
+        </div>
       </div>
     </template>
       <el-tree :expand-on-click-node="false" ref="treeRef" :filter-node-method="filterNode" :current-node-key="currentNodeKey" class="treeLeft" 
@@ -149,7 +152,7 @@
       </div>
       <div style="width: 15%;">
         <el-select
-        v-model="valueDs"
+        v-model="dsCodeSql"
         size="mini"
         style="width: 100%;margin-left: 1%;"
         >
@@ -164,7 +167,7 @@
     </div>
     <div style="border: solid  1px #e9e9eb;margin-top:1%;">
       <Codemirror 
-      v-model:value="code" 
+      v-model:value="codeSQl" 
       :options="cmOptions" 
       height="100px"
       ref="cmRef"
@@ -175,7 +178,7 @@
       <div style="display: flex;justify-content: space-between;align-items: center;">
         
       </div>
-      <el-button style="margin-top: 2%;left: 92%;z-index:555;position: absolute;" type="info" plain size="mini">测试</el-button>
+      <el-button @click="testSql" style="margin-top: -3%;left: 93%;z-index:555;position: absolute;" type="info" plain size="mini">测试</el-button>
       <el-tabs
         v-model="activeName"
         type="card"
@@ -320,7 +323,7 @@
         </el-tab-pane>
         <el-tab-pane label="预览" name="third">
           <div style="overflow: auto;height: 20vh;margin-top: -1%;">
-            <el-input placeholder="" :rows="8" type="textarea" v-model="JsonAdd" size="mini" text style="margin-top: 1%;width: 98%;" ></el-input>
+            <el-input placeholder="" :rows="8" type="textarea" v-model="testSqlResult" size="mini" text style="margin-top: 1%;width: 98%;" ></el-input>
           </div>
         </el-tab-pane>
       </el-tabs>
@@ -346,6 +349,21 @@
       <el-form-item label="说明:" prop="itemNotes">
         <el-input v-model="formTree.itemNotes" style="width: 75%;" placeholder=""  resize="none"/>
       </el-form-item>
+      <el-form-item label="节点:" prop="itemNotes" v-if="byNode">
+        <el-tree-select
+          v-model="valueNode"
+          :data="data"
+           check-strictly
+          :render-after-expand="true"
+          style="width: 75%;"
+        />
+      </el-form-item>
+      <el-form-item label="级别:" prop="itemNotes" v-if="byNode">
+        <el-radio-group v-model="radioLev" class="ml-4">
+          <el-radio label="1" size="small">同级</el-radio>
+          <el-radio label="2" size="small">子级</el-radio>
+        </el-radio-group>
+      </el-form-item>
       <el-form-item label="排序:" prop="itemNo">
         <el-input-number v-model="formTree.itemNo" :min="1" style="width: 50%;"/>
       </el-form-item>
@@ -637,7 +655,7 @@
 import { reactive } from 'vue'
 import { Plus } from '@element-plus/icons-vue'
 import { modelTreeSelect } from "@/api/service/info";
-import { cateTree,addCate,delCate,fieldAll,addSet,dataSetList,editSet,fieldAdd,delField,getDataSourceList,delSet  } from "@/api/register/regCom.js";
+import { cateTree,addCate,delCate,fieldAll,addSet,dataSetList,editSet,fieldAdd,delField,getDataSourceList,delSet,dataJisql  } from "@/api/register/regCom.js";
 import { ref, onMounted, onUnmounted, nextTick } from 'vue';
 import Codemirror from 'codemirror-editor-vue3';
 import { getToken } from "@/utils/auth";
@@ -681,6 +699,9 @@ const optionsShuLei = ref([
     value:'文件数据集'
   },
 ])
+const valueNode = ref('')
+const radioLev = ref('1')
+const dsCodeSql = ref('')
 const activeName = ref('first')
 const uploadRef = ref(null);
 const dialogVisibleApi = ref(false)
@@ -704,6 +725,7 @@ const treeId = ref('');
 const dcName =ref() 
 const parDel = ref({})
 const parTree = ref(null)
+const codeSQl = ref('')
 const formZu = ref({
   cateId:'',
   dcName:'',
@@ -711,7 +733,9 @@ const formZu = ref({
   dcSort:1,
   dcNote:''
 });
+const byNode = ref(false)
 const optionsDs = ref([])
+const testSqlResult = ref('')
 const currentNodeKey = ref('')
 const rulesZu = reactive({
   dcName: [{ required: true, message: '必填', trigger: 'blur' }],
@@ -734,7 +758,33 @@ const rulesTree = reactive({
 const formRefTree = ref();
 const parDscode = ref('')
 const parLev = ref(1)
-
+const parAr = ref([])
+function addDir() {
+  byNode.value = true
+  valueNode.value = data.value[0].value
+  dialogVisibleData.value = true
+}
+function testSql(){
+  if(!dsCodeSql.value){
+    proxy.$modal.msgWarning("数据源编码不能为空");
+  }
+  else if(!codeSQl.value){
+    proxy.$modal.msgWarning("sql语句不能为空");
+  }
+  else{
+    var par = {
+      dsCode:dsCodeSql.value,
+      sql:codeSQl.value
+    }
+    dataJisql(par).then(res=>{
+      if(res.code===200){
+        proxy.$modal.msgSuccess(res.msg);
+        testSqlResult.value = res.msg
+      }
+    })
+  }
+  
+}
 async function getTreeSel(){
   await modelTreeSelect().then(res=>{
     dataSel.value = res.data
@@ -785,7 +835,55 @@ function delAll(){
         proxy.$modal.msgSuccess("删除成功");
     }).catch(() => {});
 }
+function addValueField(nodes) {
+  if (!Array.isArray(nodes)) return;
+  
+  for (const node of nodes) {
+    // 添加value字段,其值等于id
+    node.value = node.id;
+    
+    // 如果存在子节点,递归处理
+    if (node.children && Array.isArray(node.children)) {
+      addValueField(node.children);
+    }
+  }
+}
+const flattenTree = (nodes) => {
+  const result = [];
+  const stack = [...nodes];
+  while (stack.length) {
+    const node = stack.pop();
+    result.push({ id: node.id, pid: node.pid }); // 只提取 id 和 pid
+    if (node.children && node.children.length) {
+      stack.push(...node.children);
+    }
+  }
+  return result;
+};
 function addataXiang(){
+  console.log(data.value)
+  if(byNode.value===true){
+    if(radioLev.value==='2'){
+      formTree.value.catePid = valueNode.value
+    }
+    else{
+      var par = ''
+      parAr.value.forEach(item => {
+        if (item.id === valueNode.value) {
+          par = item.pid
+        }
+      })
+      formTree.value.catePid = par
+    }
+    addCate(formTree.value).then(res=>{
+        if(res.code===200){
+            proxy.$modal.msgSuccess("修改成功");
+            getTree()
+            dialogVisibleData.value = false
+        }
+    })
+  }
+  else{
     if(parLev.value===1){
         formTree.value.catePid = parTree.value.pid
     }
@@ -799,12 +897,15 @@ function addataXiang(){
             dialogVisibleData.value = false
         }
     })
+  }
 }
 function add1Level(){
+    byNode.value = false
     parLev.value = 1
     dialogVisibleData.value = true
 }
 function addNextLevel(){
+    byNode.value = false
     parLev.value = 2
     dialogVisibleData.value = true
 }
@@ -945,7 +1046,9 @@ function getTree(){
       item.value = item.id
       item.id = item.id
     })
-  }) 
+    addValueField(data.value)
+    parAr.value = flattenTree(data.value);
+  })
 }
 function addTa(){
   formRefZu.value.validate(async (valid) => {

+ 63 - 4
ruoyi-ui/src/views/register/modelData/dataSource.vue

@@ -28,9 +28,10 @@
         </el-table-column>
         <el-table-column prop="dsNode" label="说明" width="140">
         </el-table-column>
-        <el-table-column prop="address" label="操作" width="140">
+        <el-table-column prop="address" label="操作" width="200">
             <template #default="scope">
                 <div style="display: flex;justify-content: space-between;width: 100%;">
+                    <el-button type="info" @click="test(scope.row)" size="mini" text style="margin-left: 1%;">测试</el-button>
                     <el-button type="primary" @click="showEdit(scope.row)" size="mini" text style="margin-left: 1%;">编辑</el-button>
                     <el-button @click="delRow(scope.row)" type="danger" text size="mini" style="margin-left: 1%;">删除</el-button>
                 </div>
@@ -56,9 +57,22 @@
         <el-input v-model="formZu.dsTitle" style="width: 75%;" placeholder=""  resize="none"/>
       </el-form-item>
       <el-form-item label="数据源类型:" prop="dsType" style="">
-        <el-input v-model="formZu.dsType" style="width: 75%;" placeholder=""  resize="none"/>
+        <el-select
+          v-model="formZu.dsType"
+          class="noBorSel"
+          placeholder=""
+          style="width: 75%;margin-left: 0%;"
+          >
+              <el-option
+              v-for="item in sourceTypes"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+              />
+        </el-select>
+        <!-- <el-input v-model="formZu.dsType" style="width: 75%;" placeholder=""  resize="none"/> -->
       </el-form-item>
-      <el-form-item label="数据库文名:" prop="dsDbname" style="">
+      <el-form-item label="数据库实例:" prop="dsDbname" style="">
         <el-input v-model="formZu.dsDbname" style="width: 75%;" placeholder=""  resize="none"/>
       </el-form-item>
       <el-form-item label="数据库IP:" prop="dsIp" style="">
@@ -95,7 +109,7 @@
 </template>
 <script   setup>
 import { reactive } from 'vue'
-import { getDataSourceList,addDataSource,delDataSource,editDataSource,getDataSourceDe } from "@/api/register/regCom.js";
+import { getDataSourceList,addDataSource,delDataSource,editDataSource,getDataSourceDe,testDatasource } from "@/api/register/regCom.js";
 import { ref, onMounted, onUnmounted, nextTick } from 'vue';
 const { proxy } = getCurrentInstance();
 const props = defineProps({
@@ -115,6 +129,44 @@ const data =  ref([
         value:'dataUn'
     },
 ])
+const sourceTypes = ref([
+  {
+    label: 'mysql',
+    value: 'mysql'
+  },
+  {
+    label: 'oracle',
+    value: 'oracle'
+  },
+  {
+    label: 'sqlserver',
+    value: 'sqlserver'
+  },
+  {
+    label: 'postgresql',
+    value: 'postgresql'
+  },
+  {
+    label: 'db2',
+    value: 'db2'
+  },
+  {
+    label: 'sqlite',
+    value: 'sqlite'
+  },
+  {
+    label: 'h2',
+    value: 'h2'
+  },
+  {
+    label: 'mariadb',
+    value: 'mariadb'
+  },
+  {
+    label: 'dm',
+    value: 'dm'
+  },
+])
 const title =  ref([])
 const titleTree =  ref([])
 const currentPage =  ref(1)
@@ -170,6 +222,13 @@ function clearForm(){
     sort:1
   }
 }
+function test(row){
+  testDatasource(row.dsCode).then(res=>{
+    if(res.code===200){
+        proxy.$modal.msgSuccess(res.msg);
+    }
+  })
+}
 function getTable(){
   var par = {
     dsTitle:dsTitle.value

+ 2 - 2
ruoyi-ui/src/views/service/info/index.vue

@@ -796,7 +796,7 @@ function saveAddNextLevel(){
    formRefLev.value.validate((valid) => {
     if(valid){
       var par = formLev.value
-      par.treeType = parTree.value.nodeType
+      par.treeType = 'MODEL'
       par.treePid = parTree.value.id
       addTree(par).then(res=>{
         if(res.code===200){
@@ -816,7 +816,7 @@ function saveAdd1Level(){
   formRefLev.value.validate((valid) => {
     if(valid){
       var par = formLev.value
-      par.treeType = parTree.value.nodeType
+      par.treeType = 'MODEL'
       par.treePid = parTree.value.pid
       addTree(par).then(res=>{
         if(res.code===200){

+ 47 - 16
ruoyi-ui/src/views/standardization/modeling/index.vue

@@ -6,6 +6,7 @@
       <el-button @click="delWholeFlow" style="margin-left: auto;" type="danger" size="mini">删除</el-button>
       <el-button style="margin-left: 1%;" type="info" size="mini" plain @click="toImage">导出为图片</el-button>
       <el-button style="margin-left: 1%;" type="primary" size="mini" @click="saveFlow">保存</el-button>
+      <el-button style="margin-left: 1%;" type="primary" size="mini" @click="showData">ceshi</el-button>
     </div>
     <div v-if="nodeDeSer" style="height: 85vh;width: 20vw;position: absolute;float: right;z-index: 1000;right: 1%;top: 1%;border: 0.1px solid #dedfe0;border-radius: 6px;background-color: white;">
       <div style="display: flex;margin-left: 3%;margin-top: 3%;align-items: center;justify-content: space-between;width: 95%;">
@@ -63,7 +64,16 @@
             <el-input-number  v-model="form.retryCount" :min="1" style="width: 50%" :max="30"/>
           </el-form-item>
           <el-form-item  label="输出">
-            <el-input  v-model="form.output" style="width: 100%" type="textarea" />
+            <el-table :data="tableDataCanOut" border style="width: 100%">
+              <el-table-column prop="paramCode" label="参数名" width="" />
+              <el-table-column prop="paramValue" label="参数值" width="">
+                <template #default="scope">
+                  <div style="width: 100%;">
+                      <el-input placeholder="" type="primary" class="noBor" v-model="scope.row.paramValue" size="mini" text style="margin-left: 0%;"></el-input>
+                  </div>
+                </template>
+              </el-table-column>
+            </el-table>
           </el-form-item>
         </el-form>
       </div>
@@ -80,9 +90,8 @@
         <el-tree :expand-on-click-node="false" ref="treeRef" :filter-node-method="filterNode" :current-node-key="currentNodeKey" class="treeLeft" :data="dataTree" 
         @node-click="handleNodeClick" node-key="id" style="margin-left: 5%;margin-top: 3%;width: 90%;background-color: transparent;" default-expand-all :key="valueKet">
           <template #default="{ node, data }">
-            <span  style="justify-content: space-between;display: flex;width: 100%;align-items: center;">
-              <div class="custom-tree-node":draggable="true"
-                @dragstart="onDragStart($event,data)">
+            <span  style="justify-content: space-between;display: flex;width: 100%;align-items: center;" :draggable="true" @dragstart="onDragStart($event,data)">
+              <div class="custom-tree-node">
                   <!-- <el-tag v-if="data.nodeType=='MODEL'" class="ml-2" type="warning">模型</el-tag> -->
                    <svg-icon icon-class="model2" style="color: #eebe77;" v-if="data.nodeType=='MODEL'"/>
                   <!-- <el-tag  class="ml-2">
@@ -97,7 +106,7 @@
         </el-tree>
       </div>
       <div ref="flowContainer" style="width: 80%;">
-        <VueFlow  style="background-color: #EFEFF4;margin-top: 0.5%;" :nodes="nodes" :viewport="zoom" :edges="edges" @drop="onDrop" @dragover="onDragOver" @dragleave="onDragLeave"
+        <VueFlow  ref="vueFlowRef" style="background-color: #EFEFF4;margin-top: 0.5%;" :nodes="nodes" :viewport="zoom" :edges="edges" @drop="onDrop" @dragover="onDragOver" @dragleave="onDragLeave"
           @node-click="onNodeClick"   @connect="onConnect" fit-view-on-init>
           <Controls :showInteractive="false" :showFitView="false"/>
           <template #node-special="specialNodeProps">
@@ -127,11 +136,13 @@
               style="border: 0.5px solid #c8c9cc;border-radius: 6px;border-radius: 6px;min-height: 8vh;min-width: 13vw">
                 <div style='width:100%;font-size:10px;display:flex;align-items:flex-end;height: 10px;margin-top: 2%;justify-content: space-between;'>
                   <img style="width: 15px;height:15px;border-radius: 12px;" src="@/assets/images/icon-HTTP.png" alt="">
-                  <div style="margin-left:3%;font-weight: 500;">
-                    {{ specialNodeProps.data.label   }}
+                  <div style="margin-left:3%;font-weight: 500;"> 
+                    <el-input class="custom-no-border" placeholder="" type="primary" v-model="specialNodeProps.data.label" size="mini" text 
+                    style="margin-left: 0%;font-size: 10px;height: 15px;width: 150%;" ></el-input>
+                    <!-- {{ specialNodeProps.data.label}} -->
                   </div>
                   <el-icon style="cursor: pointer;margin-left: auto;"><CaretRight /></el-icon>
-                  <el-icon @click.stop="delNode(specialNodeProps.data)" style="cursor: pointer;color: #F56C6C;margin-left: 2%;"><Delete /></el-icon>
+                  <el-icon @click.stop="delNode(specialNodeProps)" style="cursor: pointer;color: #F56C6C;margin-left: 2%;"><Delete /></el-icon>
                 </div>
                 <div style="display: flex;margin-top: 3%;">
                   <el-tag class="ml-2" style="width: 35px;height: 20px;font-size: 10px;" type="warning">服务</el-tag>
@@ -173,7 +184,7 @@ import '@vue-flow/core/dist/theme-default.css';
 import { Plus,Search } from '@element-plus/icons-vue'
 import DynamicMap from '@/components/DynamicMap/index.vue'
 import {Promotion} from '@element-plus/icons-vue'
-import { onMounted, ref } from 'vue'
+import { onMounted, ref,onBeforeUnmount } from 'vue'
 import {useVueFlow, VueFlow ,MarkerType } from '@vue-flow/core'
 import SpecialNode from './components/SpecialNode.vue'
 import SpecialEdge from './components/SpecialEdge.vue'
@@ -190,6 +201,7 @@ const {
   addEdges,
   onEdgeClick,
   addNodes,
+  removeNodes,
   screenToFlowCoordinate,
   onNodesInitialized,
   updateNode,
@@ -200,10 +212,13 @@ const {
   getEdges,
 } = useVueFlow()
 snapToGrid.value = true
+const vueFlowModel = ref();
+const tableDataCanOut = ref([]);
 const flowContainer = ref(null);
 const status = ref('就绪');
 const zoom = ref();
 const inputNode = ref('');
+const vueFlowRef = ref(null);
 const treeRef = ref(null);
 const servieName = ref()
 const serviceRqtype = ref()
@@ -260,6 +275,9 @@ const store = useStore();
 watch(inputNode, (val) => {
   treeRef.value?.filter(val); // 调用树的过滤方法
 });
+function showData(){
+  console.log(nodes.value)
+}
 function delWholeFlow(){
   proxy.$confirm('是否删除该模型流程?', '提示', {
         confirmButtonText: '确定',
@@ -304,10 +322,10 @@ const toImage = async () => {
     console.error('导出错误:', error);
   }
 };
-function delNode(node){
-  console.log(node)
-  console.log(nodes.value)
-  nodes.value = nodes.value.filter(item => item.data.label !== node.label)
+async function delNode(node){
+  removeNodes([node])
+  await nextTick()
+  
 }
 onEdgeClick(({ edge }) => {
   console.log(edges.value,edge)
@@ -364,6 +382,7 @@ onNodeClick(({event, node}) => {
       serviceRqtype.value = res.data.ptService.rqtype
       servieName.value = res.data.ptService.name
       tableDataCan.value = res.data.list
+      tableDataCanOut.value = res.data.returnList
       serviceUrl.value = res.data.ptService.url
       nodeDeSer.value = true
     })
@@ -385,7 +404,7 @@ function onDragStart(event, data) {
 
   draggedData.value = data
   isDragging.value = true
-
+  
   document.addEventListener('drop', onDragEnd)
 }
 function back(){
@@ -397,7 +416,7 @@ function back(){
  */
 function onDragOver(event) {
   event.preventDefault()
-
+  
   if (draggedData.value) {
     isDragOver.value = true
 
@@ -413,6 +432,9 @@ function onDragOver(event) {
  */
 
 function onDrop(event) {
+  getSerDe(draggedData.value.id).then(res=>{
+    draggedData.value = res.data.ptService
+  })
   const position = screenToFlowCoordinate({
     x: event.clientX,
     y: event.clientY,
@@ -524,7 +546,16 @@ watch(nodes, (newNodes) => {
 @import '@vue-flow/core/dist/theme-default.css';
 </style>
 <style scoped>
-
+.custom-no-border :deep(.el-input__wrapper) {
+  box-shadow: none !important; /* 移除默认阴影(即边框) */
+  border: none !important;     /* 双重保障 */
+}
+/* 处理悬停和聚焦状态 */
+.custom-no-border :deep(.el-input__wrapper:hover),
+.custom-no-border :deep(.el-input__wrapper:focus-within) {
+  box-shadow: none !important;
+  border: none !important;
+}
 :deep(.treeLeft) .el-tree-node__content {
   display: flex !important;
   height: 28px;                  /* 按设计稿调整高度 */