lph 1 жил өмнө
parent
commit
2647f43f7c

+ 67 - 57
ruoyi-ui/src/views/dataEngine/datamodeling/editTable.vue

@@ -1,15 +1,19 @@
 <template>
   <div class="app-container">
-    <el-card style="margin-bottom: 15px;">
+    <el-card style="margin-bottom: 15px">
       <el-form ref="form" :model="form" label-width="100px">
         <!-- <el-form-item label="数据库名称">
             <el-input v-model="form.dataBaseName" style="width: 600px;"></el-input>
         </el-form-item> -->
         <el-form-item label="数据表名称">
-          <el-input v-model="form.tableName" style="width: 600px;" :disabled="true"></el-input>
+          <el-input
+            v-model="form.tableName"
+            style="width: 600px"
+            :disabled="true"
+          ></el-input>
         </el-form-item>
         <el-form-item label="表描述">
-          <el-input v-model="form.tableComment" style="width: 600px;"></el-input>
+          <el-input v-model="form.tableComment" style="width: 600px"></el-input>
         </el-form-item>
       </el-form>
     </el-card>
@@ -31,7 +35,6 @@
               <el-option label="varchar" value="varchar"></el-option>
             </el-select>
           </template>
-
         </el-table-column>
 
         <el-table-column prop="fieldLength" label="长度" width="200">
@@ -79,7 +82,6 @@
           </template>
         </el-table-column>
 
-
         <el-table-column prop="isPrimary" label="键" width="100">
           <template slot-scope="scope">
             <!-- <el-radio-group v-model="scope.row.isPrimary">
@@ -88,7 +90,10 @@
             </el-radio-group> -->
 
             <!-- <span v-if="scope.$index == 0"></span> -->
-            <el-checkbox v-model="scope.row.isPrimary" @change="hanleCheckbox(scope.$index)"></el-checkbox>
+            <el-checkbox
+              v-model="scope.row.isPrimary"
+              @change="hanleCheckbox(scope.$index)"
+            ></el-checkbox>
           </template>
         </el-table-column>
 
@@ -109,47 +114,54 @@
         </el-table-column>
         <el-table-column prop="operate" label="操作">
           <template slot-scope="scope">
-            <el-button size="mini" type="success" icon="el-icon-save"
+            <!-- <el-button size="mini" type="success" icon="el-icon-save"
                        @click="handlesaveExperience(scope.$index, scope.row)">保存
+            </el-button> -->
+            <el-button
+              size="mini"
+              type="danger"
+              icon="el-icon-delete"
+              @click="handleDeleteExperience(scope.$index, scope.row)"
+              >删除
             </el-button>
-            <el-button size="mini" type="danger" icon="el-icon-delete"
-                       @click="handleDeleteExperience(scope.$index, scope.row)">删除
-            </el-button>
-
           </template>
         </el-table-column>
       </el-table>
       <div>
-        <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAddExperienceline">新增字段
+        <el-button
+          type="primary"
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAddExperienceline"
+          >新增字段
         </el-button>
       </div>
     </el-card>
 
-    <div style="margin-top: 15px;">
+    <div style="margin-top: 15px">
       <el-button @click="edit" type="primary">修改</el-button>
     </div>
   </div>
 </template>
 
 <script>
-import {tableInfo, editTable} from '@/api/dataEngine/index'
+import { tableInfo, editTable } from "@/api/dataEngine/index";
 
 export default {
   name: "Datasheet",
   data() {
     return {
       form: {
-        dataBaseName: '',
-        tableName: '',
-        tableComment: '',
+        dataBaseName: "",
+        tableName: "",
+        tableComment: "",
       },
       experienceData: [],
-      dataBase: {}
-
-    }
+      dataBase: {},
+    };
   },
   created() {
-    this.info()
+    this.info();
   },
   methods: {
     hanleCheckbox(ind) {
@@ -158,10 +170,9 @@ export default {
           item.isPrimary = false;
         }
         if (index == ind) {
-          item.isNull = true
+          item.isNull = true;
         }
-
-      })
+      });
     },
     //增加经验行
     handleAddExperienceline() {
@@ -169,13 +180,13 @@ export default {
         this.experienceData = new Array();
       }
       let obj = {
-        fieldName: '',
-        fieldType: '',
+        fieldName: "",
+        fieldType: "",
         fieldLength: undefined,
         isNull: false,
         isPrimary: false,
-        fieldDescription: '',
-        isAuto: false
+        fieldDescription: "",
+        isAuto: false,
       };
 
       this.experienceData.push(obj);
@@ -188,55 +199,54 @@ export default {
     //删除经验行
     handleDeleteExperience(index) {
       console.log(index);
-      this.experienceData.splice(index, 1)
+      this.experienceData.splice(index, 1);
     },
     info() {
-      const tableName = this.$route.query.tableName
-      const tableComment = this.$route.query.tableComment
+      const tableName = this.$route.query.tableName;
+      const tableComment = this.$route.query.tableComment;
 
       let data = {
         tableName: this.$route.query.tableName,
         databaseType: this.$store.state.user.dataSource.databaseType,
         databaseName: this.$store.state.user.dataSource.databaseName,
-      }
+      };
 
-      tableInfo(data).then(response => {
+      tableInfo(data).then((response) => {
         console.log(response);
-        this.experienceData = response.data
-        this.form.tableName = tableName
-        this.form.tableComment = tableComment
+        this.experienceData = response.data;
+        this.form.tableName = tableName;
+        this.form.tableComment = tableComment;
       });
     },
     edit() {
       this.experienceData.forEach((field) => {
         if (field.fieldLength) {
-          field.fieldType = `${field.fieldType}(${field.fieldLength})`
+          field.fieldType = `${field.fieldType}(${field.fieldLength})`;
         }
-      })
+      });
       let query = {
         databaseType: this.$store.state.user.dataSource.databaseType,
         databaseName: this.$store.state.user.dataSource.databaseName,
         tableName: this.form.tableName,
         tableComment: this.form.tableComment,
-        field: this.experienceData
-      }
-      editTable(query).then(res => {
-
-        this.$modal.msgSuccess(res.msg);
-        if (res.code === 200) {
-          this.visible = false;
-          this.$emit("ok");
-          Object.keys(this.form).forEach(key => (this.form[key] = ''));
-          this.experienceData = []
-
-        }
-      }).catch(err => {
-        console.log(err);
-      })
+        field: this.experienceData,
+      };
+      editTable(query)
+        .then((res) => {
+          this.$modal.msgSuccess(res.msg);
+          if (res.code === 200) {
+            this.visible = false;
+            this.$emit("ok");
+            Object.keys(this.form).forEach((key) => (this.form[key] = ""));
+            this.experienceData = [];
+          }
+        })
+        .catch((err) => {
+          console.log(err);
+        });
       // 关闭当前页面
       this.$tab.closePage();
-    }
-
-  }
-}
+    },
+  },
+};
 </script>

+ 73 - 24
ruoyi-ui/src/views/dataEngine/datamodeling/index.vue

@@ -1,32 +1,69 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
+    <el-form
+      :model="queryParams"
+      ref="queryForm"
+      size="small"
+      :inline="true"
+      v-show="showSearch"
+      label-width="68px"
+    >
       <el-form-item label="表名称" prop="tableName">
-        <el-input v-model="queryParams.tableName" placeholder="请输入表名称" clearable
-                  @keyup.enter.native="handleQuery"/>
+        <el-input
+          v-model="queryParams.tableName"
+          placeholder="请输入表名称"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
       </el-form-item>
       <el-form-item label="表描述" prop="tableComment">
-        <el-input v-model="queryParams.tableComment" placeholder="请输入表描述" clearable
-                  @keyup.enter.native="handleQuery"/>
+        <el-input
+          v-model="queryParams.tableComment"
+          placeholder="请输入表描述"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
       </el-form-item>
       <el-form-item>
-        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
-        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+        <el-button
+          type="primary"
+          icon="el-icon-search"
+          size="mini"
+          @click="handleQuery"
+          >搜索</el-button
+        >
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
+          >重置</el-button
+        >
       </el-form-item>
     </el-form>
 
     <el-row :gutter="10" class="mb8">
       <el-col :span="1.5">
-        <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">新增</el-button>
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+          >新增</el-button
+        >
       </el-col>
-      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+      <right-toolbar
+        :showSearch.sync="showSearch"
+        @queryTable="getList"
+      ></right-toolbar>
     </el-row>
 
     <el-table v-loading="loading" :data="aaaList">
-      <el-table-column label="表名称" align="center" prop="tableName"/>
-      <el-table-column label="表描述" align="center" prop="tableComment"/>
-      <el-table-column label="创建时间" align="center" prop="createTime"/>
-      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+      <el-table-column label="表名称" align="center" prop="tableName" />
+      <el-table-column label="表描述" align="center" prop="tableComment" />
+      <el-table-column label="创建时间" align="center" prop="createTime" />
+      <el-table-column
+        label="操作"
+        align="center"
+        class-name="small-padding fixed-width"
+      >
         <template slot-scope="scope">
           <el-dropdown>
             <el-button type="warning" plain size="small">
@@ -34,13 +71,21 @@
             </el-button>
             <el-dropdown-menu slot="dropdown">
               <el-dropdown-item>
-                <el-button size="mini" type="text" icon="el-icon-delete"
-                           @click="handleDelete(scope.row)">删除
+                <el-button
+                  size="mini"
+                  type="text"
+                  icon="el-icon-delete"
+                  @click="handleDelete(scope.row)"
+                  >删除
                 </el-button>
               </el-dropdown-item>
               <el-dropdown-item>
-                <el-button size="mini" type="text" icon="el-icon-edit"
-                           @click="handleUpdate(scope.row)">修改
+                <el-button
+                  size="mini"
+                  type="text"
+                  icon="el-icon-edit"
+                  @click="handleUpdate(scope.row)"
+                  >修改
                 </el-button>
               </el-dropdown-item>
             </el-dropdown-menu>
@@ -52,13 +97,18 @@
       </el-table-column>
     </el-table>
 
-    <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
-                @pagination="getList"/>
+    <pagination
+      v-show="total > 0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
   </div>
 </template>
 
 <script>
-import {tableInfoList, removeTable} from "@/api/dataEngine/index";
+import { tableInfoList, removeTable } from "@/api/dataEngine/index";
 
 export default {
   name: "dataModeling",
@@ -112,7 +162,7 @@ export default {
         tableName: row.tableName,
         databaseType: this.$store.state.user.dataSource.databaseType,
         databaseName: this.$store.state.user.dataSource.databaseName,
-      }
+      };
       this.$modal
         .confirm('是否确认删除"' + tableNames + '"表?')
         .then(function () {
@@ -122,12 +172,11 @@ export default {
           this.getList();
           this.$modal.msgSuccess("删除成功");
         })
-        .catch(() => {
-        });
+        .catch(() => {});
     },
     handleUpdate(row) {
       this.$router.push({
-        path: "/datasheet/editTable",
+        path: "/datasheet/mysql",
         query: {
           tableName: row.tableName,
           tableComment: row.tableComment,

+ 179 - 90
ruoyi-ui/src/views/tableMange/index.vue

@@ -32,34 +32,39 @@
               }}</span>
             </el-option>
           </el-select>
+          <!-- <el-form
+            :model="tableFieldList"
+            ref="tableForm"
+            :rules="rules"
+            :inline="false"
+            size="normal"
+          > -->
           <el-table
             :data="tableFieldList"
             border
             ref="dragTable"
-            :max-height="tableHeight"
             row-key="id"
-            :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
+            :max-height="tableHeight"
           >
+            <!-- 
+              
+              :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" 
+            -->
             >
-            <!-- <el-table-column type="selection" width="55" align="center" /> -->
-            <!-- <span v-for="(key, val) in columns" :key="val">
-              <el-table-column :label="key" align="center" :prop="val" />
-            </span> -->
             <el-table-column
               type="index"
               label="序号"
               width="50"
               class-name="allowDrag"
             >
-              <!-- <template slot-scope="scope">
-                <el-input v-model="scope.row.fieldDescription"></el-input>
-              </template> -->
             </el-table-column>
             <el-table-column prop="fieldName" label="数据字段">
             </el-table-column>
             <el-table-column prop="fieldDescription" label="字段描述">
               <template slot-scope="scope">
+                <!-- <el-form-item size="normal" prop="fieldDescription"> -->
                 <el-input v-model="scope.row.fieldDescription"></el-input>
+                <!-- </el-form-item> -->
               </template>
             </el-table-column>
             <el-table-column prop="relationTable" label="关联表">
@@ -92,7 +97,6 @@
                   @change="relationFieldChange(scope.row)"
                   :disabled="!scope.row.disableRelaFieldName"
                   placeholder="关联字段"
-                  clearable
                   filterable
                 >
                   <el-option
@@ -111,7 +115,7 @@
                   v-model="scope.row.relationType"
                   placeholder="请选择关联方式"
                   :disabled="!scope.row.disableRelaType"
-                  clearable
+                  @change="relationTypeChangeHandler(scope.row)"
                   filterable
                 >
                   <el-option
@@ -182,13 +186,7 @@
           </template>
         </el-table-column> -->
           </el-table>
-          <!-- <pagination
-            v-show="total > 0"
-            :total="total"
-            :page.sync="queryParams.pageNum"
-            :limit.sync="queryParams.pageSize"
-            @pagination="pageList"
-          /> -->
+          <!-- </el-form> -->
         </el-card>
       </el-col>
       <el-col :span="6">
@@ -351,7 +349,7 @@
           :key="item.key"
           :label="item.value"
           align="center"
-          :prop="item.key"
+          :prop="toUpperCase(item.key)"
         />
         <el-table-column
           label="操作"
@@ -523,6 +521,9 @@ export default {
         timeFormate: [
           { required: true, message: "请选择时间格式", trigger: "change" },
         ],
+        fieldDescription: [
+          { required: true, message: "请输入字段描述", trigger: "blur" },
+        ],
       },
       menus: [], //路由列表数据
 
@@ -606,19 +607,24 @@ export default {
             isExport: true,
             relationTableList: this.relationTableList,
             tableName: this.tableName,
-            children: [],
+            relationFieldList: [],
           };
         });
       });
     },
     // 关联表变化回调
     async ralationTableChange(row) {
+      this.tableFieldList = this.tableFieldList.filter((item) => {
+        return !row.relationFieldList.some((val) => {
+          return val.id == item.id;
+        });
+      });
+      row.relationFieldName = "";
+      row.relationType = "";
+      row.disableRelaFieldName = false;
+      row.disableRelaType = false;
+      row.relationFieldList = [];
       if (!row.relationTable) {
-        row.relationFieldName = "";
-        row.relationType = "";
-        row.disableRelaFieldName = false;
-        row.disableRelaType = false;
-        row.children = [];
         return;
       }
       // 获取关联表的字段
@@ -628,6 +634,7 @@ export default {
         tableName: row.relationTable,
       };
       let res = await getListName(data);
+      // 关联字段下拉列表数据
       row.relaFieldNameList = res.map((item) => {
         return {
           fieldName: item.fieldName,
@@ -637,7 +644,7 @@ export default {
       let relationTableList = row.relationTableList.filter(
         (item) => row.relationTable != item.tableName
       );
-      row.children = row.relaFieldNameList.map((item, index) => {
+      row.relationFieldList = row.relaFieldNameList.map((item, index) => {
         return {
           id: row.relationTable + " " + item.fieldName,
           fieldName: item.fieldName,
@@ -655,12 +662,17 @@ export default {
           isExport: true,
           relationTableList,
           tableName: row.relationTable,
-          children: [],
+          relationFieldList: [],
           isChildren: true,
         };
       });
+      // this.tableFieldList = [...this.tableFieldList, ...row.relationFieldList];
       row.disableRelaFieldName = true;
     },
+    // 关联类型变化回调
+    relationTypeChangeHandler(row) {
+      this.tableFieldList = [...this.tableFieldList, ...row.relationFieldList];
+    },
     // 关联字段回调
     relationFieldChange(row) {
       if (!row.relationFieldName) {
@@ -732,7 +744,7 @@ export default {
       let res = await getMenuList();
       this.menus = this.handleTree(res.data, "menuId");
     },
-    // 校验字段合法性
+    // 校验字段合法性(递归版)
     validateField(tableFieldList, validateParams) {
       if (!tableFieldList.length) {
         return;
@@ -743,22 +755,61 @@ export default {
           //描述字段不能为空
           validateParams.isFieldDescrib = true;
         }
-        if (temp.children.length) {
-          this.validateField(temp.children, validateParams);
+        if (
+          temp.relationTable &&
+          (!temp.relationFieldName || !temp.relationType)
+        ) {
+          // 关联条件不足
+          validateParams.isRelationFieldAll = true;
+        }
+        if (temp.relationFieldList.length) {
+          this.validateField(temp.relationFieldList, validateParams);
         }
       }
     },
+    // 校验字段合法性(非递归版)
+    validateTableData(tableFieldList) {
+      if (!tableFieldList.length) {
+        return {
+          val: false,
+          meg: "字段个数不能为空",
+        };
+      }
+      for (let i = 0; i < tableFieldList.length; i++) {
+        let temp = tableFieldList[i];
+        if (!temp.fieldDescription.trim() && temp.isShow) {
+          return {
+            val: false,
+            msg: "显示的字段,字段描述不能为空",
+          };
+        }
+        if (
+          temp.relationTable &&
+          (!temp.relationFieldName || !temp.relationType)
+        ) {
+          return {
+            val: false,
+            msg: "关联条件不足,请完善关联条件",
+          };
+        }
+      }
+      if (tableFieldList.filter((item) => item.isShow).length == 0) {
+        return {
+          val: false,
+          msg: "显示的字段数不能为空",
+        };
+      }
+
+      return {
+        val: true,
+        msg: "",
+      };
+    },
     // 递归拼接查询语句
     getSQLString(tableFieldList, fieldArr, tableArr) {
       for (let i = 0; i < tableFieldList.length; i++) {
         let temp = tableFieldList[i];
         if (temp.isShow) {
-          // console.log("字段描述:", temp.fieldDescription);
-          // if (!temp.fieldDescription) {
-          //   console.log("有空的字段描述");
-          //   //字段描述不能为空
-          //   return true;
-          // }
           let tempArr = temp.tableName + "." + temp.fieldName;
           if (temp.isChildren) {
             tempArr += " as " + temp.tableName + "_" + temp.fieldName;
@@ -783,11 +834,12 @@ export default {
               temp.fieldName
           );
         }
-        if (temp.children.length) {
-          this.getSQLString(temp.children, fieldArr, tableArr);
-        }
+        // if (temp.relationFieldList.length) {
+        //   this.getSQLString(temp.relationFieldList, fieldArr, tableArr);
+        // }
       }
     },
+
     // 拼接查询sql语句
     getSQLStr() {
       let sqlType = this.databaseType; //数据库类型
@@ -827,6 +879,14 @@ export default {
       });
       return resArr;
     },
+    // 下划线命名转驼峰命名
+    toUpperCase(str) {
+      let nstr = str.replace(/(?:_)+([^_])/g, function ($0, $1) {
+        return $1.toUpperCase();
+      });
+      nstr = nstr.replace(nstr[0], nstr[0].toLowerCase());
+      return nstr;
+    },
 
     // 递归获取列表信息
     getCol(
@@ -838,49 +898,41 @@ export default {
       if (!tableFieldList.length) return;
       for (let i = 0; i < tableFieldList.length; i++) {
         let temp = tableFieldList[i];
+        let tempFieldName = "";
+        if (temp.isChildren) {
+          tempFieldName = temp.tableName + "_" + temp.fieldName;
+        } else {
+          tempFieldName = temp.fieldName;
+        }
         if (temp.isShow) {
           let tempObj = {};
-          tempObj[temp.fieldName] = temp.fieldDescription;
+          // if (temp.isChildren) {
+          //   tempObj[temp.tableName + "_" + temp.fieldName] =
+          //     temp.fieldDescription;
+          // } else {
+          //   tempObj[temp.fieldName] = temp.fieldDescription;
+          // }
+          tempObj[tempFieldName] = temp.fieldDescription;
           columns.push(tempObj);
         }
         if (temp.isSearch) {
-          searchFieldList.push(temp.fieldName);
+          searchFieldList.push(temp.tableName + "." + temp.fieldName);
         }
         if (temp.isExport) {
-          tableExportField[temp.fieldName] = temp.fieldDescription;
-        }
-        if (temp.children) {
-          this.getCol(
-            temp.children,
-            columns,
-            searchFieldList,
-            tableExportField
-          );
+          tableExportField[tempFieldName] = temp.fieldDescription;
         }
+        // 递归
+        // if (temp.relationFieldList) {
+        //   this.getCol(
+        //     temp.relationFieldList,
+        //     columns,
+        //     searchFieldList,
+        //     tableExportField
+        //   );
+        // }
       }
     },
-    // 获取列表信息
-    getColumns() {
-      let columns = [];
-      this.getCol(this.tableFieldList, columns);
-      // this.tableFieldList.forEach((item) => {
-      //   if (item.isShow) {
-      //     let tempObj = {};
-      //     tempObj[item.fieldName] = item.fieldDescription;
-      //     columns.push(tempObj);
-      //     if (item.children.length) {
-      //       item.children
-      //         .filter((val) => val.isShow)
-      //         .map((child) => {
-      //           let tempObj = {};
-      //           tempObj[child.fieldName] = child.fieldDescription;
-      //           columns.push(tempObj);
-      //         });
-      //     }
-      //   }
-      // });
-      return columns;
-    },
+
     // 预览结果回调
     async previewHandle() {
       this.$refs.formData.validate(async (valid) => {
@@ -891,19 +943,35 @@ export default {
             return;
           }
           // 检验表单合法性
-          let validateParams = {
-            isFieldDescrib: false,
-          };
-          this.validateField(this.tableFieldList, validateParams);
-          console.log(validateParams);
-          if (validateParams.isFieldDescrib) {
-            this.$message.error("需要显示的字段描述不能为空");
+          let validRes = this.validateTableData(this.tableFieldList);
+          if (!validRes.val) {
+            this.$message.error(validRes.msg);
             return;
           }
+          // let validateParams = {
+          //   isFieldDescrib: false,
+          //   isRelationFieldAll: false,
+          // };
+          // this.validateField(this.tableFieldList, validateParams);
+          // console.log(validateParams);
+          // if (validateParams.isFieldDescrib) {
+          //   this.$message.error("需要显示的字段描述不能为空");
+          //   return;
+          // }
+          // if (validateParams.isRelationFieldAll) {
+          //   this.$message.error("请补全关联条件");
+          //   return;
+          // }
           // 拼接预览的sql查询语句
           this.queryParams.basicMap.sql = this.getSQLStr();
           // 获取表头信息
-          let tempColumns = this.getColumns();
+          let tempColumns = [],
+            searchFieldList = [];
+          this.getCol(this.tableFieldList, tempColumns, searchFieldList);
+          if (!searchFieldList.length) {
+            this.$message.warning("请至少选择一个包含查询字段");
+            return false;
+          }
           this.columns = this.columnsHandler(tempColumns);
           this.queryParams.isAsc = this.formData.isAsc;
           // 发送请求获取预览数据
@@ -912,8 +980,6 @@ export default {
           res.rows.forEach((item) => {
             this.tableDataList.push(item.resultMap);
           });
-          console.log(this.tableDataList);
-          console.log(this.columns);
           this.total = res.total;
           this.isShowPreview = true;
         } else {
@@ -921,22 +987,40 @@ export default {
           return false;
         }
       });
+
+      // this.$refs.tableForm.validate((val) => {
+      //   if (val) {
+
+      //   } else {
+      //     this.$message.warning("请完善表单");
+      //     return false;
+      //   }
+      // });
     },
     // 创建回调
     async createHandle() {
       this.$refs.formData.validate(async (valid) => {
         if (valid) {
           // 检验表单合法性
-          let validateParams = {
-            isFieldDescrib: false,
-          };
-          this.validateField(this.tableFieldList, validateParams);
-          console.log(validateParams);
-          if (validateParams.isFieldDescrib) {
-            this.$message.error("需要显示的字段描述不能为空");
+          let validRes = this.validateTableData(this.tableFieldList);
+          if (!validRes.val) {
+            this.$message.error(validRes.msg);
             return;
           }
-
+          // let validateParams = {
+          //   isFieldDescrib: false,
+          //   isRelationFieldAll: false,
+          // };
+          // this.validateField(this.tableFieldList, validateParams);
+          // console.log(validateParams);
+          // if (validateParams.isFieldDescrib) {
+          //   this.$message.error("需要显示的字段描述不能为空");
+          //   return;
+          // }
+          // if (validateParams.isRelationFieldAll) {
+          //   this.$message.error("请补全关联条件");
+          //   return;
+          // }
           let uuid = uuidv4();
           let columns = [],
             searchFieldList = [],
@@ -1043,6 +1127,11 @@ export default {
                 this.$message.warning("创建失败");
               }
             }
+            // 关闭当前页面
+            if (this.tId) {
+              this.$tab.closePage();
+            }
+            this.isShowPreview = false;
           }
         } else {
           this.$message.warning("请完善表单");

+ 256 - 102
ruoyi-ui/src/views/tool/datasheet/index.vue

@@ -1,15 +1,19 @@
 <template>
   <div class="app-container">
-    <el-card style="margin-bottom: 15px;">
+    <el-card style="margin-bottom: 15px">
       <el-form ref="form" :model="form" label-width="100px" :rules="rules">
         <!-- <el-form-item label="数据库名称" prop="dataBaseName">
             <el-input v-model="form.dataBaseName" style="width: 600px;"></el-input>
         </el-form-item> -->
         <el-form-item label="数据表名称" prop="tableName">
-          <el-input v-model="form.tableName" style="width: 600px;"></el-input>
+          <el-input
+            v-model="form.tableName"
+            :disabled="isEdited"
+            style="width: 600px"
+          ></el-input>
         </el-form-item>
         <el-form-item label="表描述">
-          <el-input v-model="form.tableComment" style="width: 600px;"></el-input>
+          <el-input v-model="form.tableComment" style="width: 600px"></el-input>
         </el-form-item>
       </el-form>
     </el-card>
@@ -21,25 +25,46 @@
         <el-table :data="experienceData" stripe style="width: 100%">
           <el-table-column prop="fieldName" label="字段名称" width="200">
             <template slot-scope="scope">
-              <el-form-item :prop="'fieldName' + scope.$index" :name="'fieldName' + scope.$index"
-                            style="margin: 0px;padding: 0px;">
+              <el-form-item
+                :prop="'fieldName' + scope.$index"
+                :name="'fieldName' + scope.$index"
+                style="margin: 0px; padding: 0px"
+              >
                 <el-input v-model="scope.row.fieldName"></el-input>
               </el-form-item>
             </template>
           </el-table-column>
           <el-table-column prop="fieldType" label="字段类型" width="200">
             <template slot-scope="scope">
-              <el-form-item :prop="'fieldType' + scope.$index" :name="'fieldType' + scope.$index"
-                            style="margin: 0px;padding: 0px;">
-                <el-select v-model="scope.row.fieldType" filterable @blur="selectBlur(scope)"
-                           @change="handleSelected(dict.type.mysql_data_type.find(item => item.label === scope.row.fieldType), scope)">
+              <el-form-item
+                :prop="'fieldType' + scope.$index"
+                :name="'fieldType' + scope.$index"
+                style="margin: 0px; padding: 0px"
+              >
+                <el-select
+                  v-model="scope.row.fieldType"
+                  filterable
+                  @blur="selectBlur(scope)"
+                  @change="
+                    handleSelected(
+                      dict.type[databaseType + '_data_type'].find(
+                        (item) => item.label === scope.row.fieldType
+                      ),
+                      scope
+                    )
+                  "
+                >
                   <!-- <el-option v-for="item in list" :key="item" :label="item" :value="item">
                   </el-option> -->
                   <!--
                   <el-option v-for="item in dict.type.mysql_data_type"  :label="item.dictLabel" :value="item.dictValue">
                   </el-option> -->
-                  <el-option v-for="item in dict.type.mysql_data_type" :key="item.value"
-                             :label="item.label" :value="item.value"/>
+                  <el-option
+                    v-for="item in dict.type[databaseType + '_data_type']"
+                    :key="item.value"
+                    :label="item.label"
+                    :value="item.value"
+                  />
                 </el-select>
               </el-form-item>
             </template>
@@ -47,12 +72,17 @@
 
           <el-table-column prop="fieldLength" label="长度" width="200">
             <template slot-scope="scope">
-              <el-form-item :prop="'fieldLength' + scope.$index" :name="'fieldLength' + scope.$index"
-                            style="margin: 0px;padding: 0px;">
+              <el-form-item
+                :prop="'fieldLength' + scope.$index"
+                :name="'fieldLength' + scope.$index"
+                style="margin: 0px; padding: 0px"
+              >
                 <!--                <el-input v-model="scope.row.fieldLength"-->
                 <!--                          :disabled="handleSelected(dict.type.mysql_data_type.find(item => item.label === scope.row.fieldType), scope)"></el-input>-->
-                <el-input v-model="scope.row.fieldLength"
-                          :disabled="changduclick(scope.$index)"></el-input>
+                <el-input
+                  v-model="scope.row.fieldLength"
+                  :disabled="changduclick(scope.$index)"
+                ></el-input>
               </el-form-item>
             </template>
           </el-table-column>
@@ -63,10 +93,12 @@
             </template>
           </el-table-column>
 
-
           <el-table-column prop="isPrimary" label="键" width="100">
             <template slot-scope="scope">
-              <el-checkbox v-model="scope.row.isPrimary" @change="hanleCheckbox(scope.$index)"></el-checkbox>
+              <el-checkbox
+                v-model="scope.row.isPrimary"
+                @change="hanleCheckbox(scope.$index)"
+              ></el-checkbox>
             </template>
           </el-table-column>
 
@@ -86,39 +118,56 @@
               <!-- <el-button size="mini" type="success" icon="el-icon-save"
                   @click="handlesaveExperience(scope.$index, scope.row)">保存
               </el-button> -->
-              <el-button size="mini" type="danger" icon="el-icon-delete"
-                         @click="handleDeleteExperience(scope.$index, scope.row)">删除
+              <el-button
+                size="mini"
+                type="danger"
+                icon="el-icon-delete"
+                @click="handleDeleteExperience(scope.$index, scope.row)"
+                >删除
               </el-button>
-
             </template>
           </el-table-column>
         </el-table>
       </el-form>
       <div>
-        <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAddExperienceline">新增字段
+        <el-button
+          type="primary"
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAddExperienceline"
+          >新增字段
         </el-button>
       </div>
     </el-card>
 
-    <div style="margin-top: 15px;">
-      <el-button @click="add" type="primary">添加</el-button>
+    <div style="margin-top: 15px">
+      <el-button v-if="!isEdited" @click="add" type="primary">添加</el-button>
+      <el-button v-else @click="edit" type="primary">修改</el-button>
     </div>
   </div>
 </template>
 
 <script>
-import {createDatabase} from "@/api/datasheet/index"
-
+import { createDatabase } from "@/api/datasheet/index";
+import { tableInfo, editTable } from "@/api/dataEngine/index";
+import { mapState } from "vuex";
 export default {
   name: "Datasheet",
-  dicts: ['mysql_data_type'],
+  dicts: [
+    "mysql_data_type",
+    "sqlserver_data_type",
+    "dm_data_type",
+    "oracle_data_type",
+    "datasource_type",
+  ],
   data() {
     return {
+      isEdited: false,
       testzidian: null,
       form: {
-        dataBaseName: '',
-        tableName: '',
-        tableComment: '',
+        dataBaseName: "",
+        tableName: "",
+        tableComment: "",
       },
       experienceDataForm: {},
       experienceData: [
@@ -133,43 +182,97 @@ export default {
         // },
       ],
       rules: {
-        dataBaseName: {required: true, message: '请输入数据库名称', trigger: 'blur'},
-        tableName: {required: true, message: '请输入数据库名称', trigger: 'blur'}
-      },
-      tableform:
-        {
-          // fieldName0: { required: true, message: '请输入字段名称', trigger: 'blur' },
-          // fieldType0: { required: true, message: '请选择', trigger: 'change' },
-          // fieldLength0: { required: true, message: '请输入', trigger: 'blur' },
+        dataBaseName: {
+          required: true,
+          message: "请输入数据库名称",
+          trigger: "blur",
         },
-      list: [
-        'int', 'varchar'
-      ],
-      // 长度输入框禁用列数组
-      Inoputdisabled: []
+        tableName: {
+          required: true,
+          message: "请输入数据库名称",
+          trigger: "blur",
+        },
+      },
+      tableform: {
+        // fieldName0: { required: true, message: '请输入字段名称', trigger: 'blur' },
+        // fieldType0: { required: true, message: '请选择', trigger: 'change' },
+        // fieldLength0: { required: true, message: '请输入', trigger: 'blur' },
+      },
+      list: ["int", "varchar"],
+
+      Inoputdisabled: [],
+      // 需要指定长度
+      mysqlAllowLength: ["char", "varchar", "numeric", "decimal"],
+    };
+  },
+  created() {
+    if (this.$route.query.tableName && this.$route.query.tableComment) {
+      this.isEdited = true;
+      this.info();
+    } else {
+      Object.keys(this.dataBaseName).forEach((item) => {
+        this.dataBaseName[item] = "";
+      });
+      this.experienceData = [];
     }
   },
+  computed: {
+    ...mapState({
+      databaseName: (state) => state.user.dataSource.databaseName,
+      databaseType: (state) => state.user.dataSource.databaseType,
+    }),
+  },
   watch: {
     experienceData: {
       handler(n, o) {
         // do something
-        this.experienceDataForm = {}
-        let rulesAdd = {}
+        this.experienceDataForm = {};
+        let rulesAdd = {};
         this.experienceData.forEach((item, index) => {
-          this.$set(this.experienceDataForm, "fieldName" + index, item.fieldName);
-          this.$set(this.experienceDataForm, "fieldType" + index, item.fieldType);
-          this.$set(this.experienceDataForm, "fieldLength" + index, item.fieldLength);
+          this.$set(
+            this.experienceDataForm,
+            "fieldName" + index,
+            item.fieldName
+          );
+          this.$set(
+            this.experienceDataForm,
+            "fieldType" + index,
+            item.fieldType
+          );
+          this.$set(
+            this.experienceDataForm,
+            "fieldLength" + index,
+            item.fieldLength
+          );
           // rulesAdd['' + index] = item.fieldName
           // rulesAdd['fieldType' + index] = item.fieldType
           // rulesAdd['fieldLength' + index] = item.fieldLength
           // this.experienceDataForm = {...rulesAdd}
-        })
+        });
         console.log(this.experienceDataForm);
       },
-      deep: true// 深度监听父组件传过来对象变化
-    }
+      deep: true, // 深度监听父组件传过来对象变化
+    },
   },
   methods: {
+    // 初始化表格数据
+    info() {
+      const tableName = this.$route.query.tableName;
+      const tableComment = this.$route.query.tableComment;
+
+      let data = {
+        tableName: this.$route.query.tableName,
+        databaseType: this.databaseType,
+        databaseName: this.databaseName,
+      };
+
+      tableInfo(data).then((response) => {
+        console.log(response);
+        this.experienceData = response.data;
+        this.form.tableName = tableName;
+        this.form.tableComment = tableComment;
+      });
+    },
     // 处理长度框是否可输入
     changduclick(inputIndex) {
       return this.Inoputdisabled[inputIndex];
@@ -179,43 +282,62 @@ export default {
       if (tem == undefined) return;
       // console.log(this.experienceDataForm)
       // console.log(this.tableform)
-      if (tem.raw.listClass === 'success') {
-        this.Inoputdisabled[scope.$index] = true;// 禁用长度输入框
-        this.tableform['fieldLength' + scope.$index].required = false; // 禁用长度输入框的校验
-        return this.$set(this.experienceDataForm, "fieldType" + scope.$index, scope.row.fieldType);
+      if (tem.raw.listClass === "success") {
+        this.Inoputdisabled[scope.$index] = true; // 禁用长度输入框
+        this.tableform["fieldLength" + scope.$index].required = false; // 禁用长度输入框的校验
+        return this.$set(
+          this.experienceDataForm,
+          "fieldType" + scope.$index,
+          scope.row.fieldType
+        );
       }
-      this.Inoputdisabled[scope.$index] = false;// 解除禁用
-      this.tableform['fieldLength' + scope.$index].required = true; // 启用长度输入框的校验
-      return this.$set(this.experienceDataForm, "fieldType" + scope.$index, scope.row.fieldType);
+      this.Inoputdisabled[scope.$index] = false; // 解除禁用
+      this.tableform["fieldLength" + scope.$index].required = true; // 启用长度输入框的校验
+      return this.$set(
+        this.experienceDataForm,
+        "fieldType" + scope.$index,
+        scope.row.fieldType
+      );
     },
 
     // 下拉选中事件
     selectBlur(aa) {
       if (aa.row.fieldType == "") {
-        aa.row.fieldType = undefined
+        aa.row.fieldType = undefined;
       }
     },
 
-
     // 处理非空校验问题
     handleRules(type, delindex) {
-      if (type == 'add') {
+      if (type == "add") {
         let rulesAdd = {};
         // 得到添加一行的下标
         let index = this.experienceData.length - 1;
-        rulesAdd['fieldName' + index] = {required: true, message: '请输入字段名称', trigger: 'blur'}
-        rulesAdd['fieldType' + index] = {required: true, message: '请选择', trigger: 'change'}
-        rulesAdd['fieldLength' + index] = {required: true, message: '请输入', trigger: 'blur'}
+        rulesAdd["fieldName" + index] = {
+          required: true,
+          message: "请输入字段名称",
+          trigger: "blur",
+        };
+        rulesAdd["fieldType" + index] = {
+          required: true,
+          message: "请选择",
+          trigger: "change",
+        };
+        rulesAdd["fieldLength" + index] = {
+          required: true,
+          message: "请输入",
+          trigger: "blur",
+        };
         // 序列化当前校验规则对象
         this.tableform = {
           ...this.tableform,
-          ...rulesAdd
-        }
-      } else if (type == 'del') {
+          ...rulesAdd,
+        };
+      } else if (type == "del") {
         // 删除校验规则对象中的元素
-        this.$delete(this.tableform, 'fieldName' + delindex);
-        this.$delete(this.tableform, 'fieldType' + delindex);
-        this.$delete(this.tableform, 'fieldLength' + delindex);
+        this.$delete(this.tableform, "fieldName" + delindex);
+        this.$delete(this.tableform, "fieldType" + delindex);
+        this.$delete(this.tableform, "fieldLength" + delindex);
       }
     },
 
@@ -226,9 +348,9 @@ export default {
           item.isPrimary = false;
         }
         if (index == ind && item.isPrimary == true) {
-          item.isNull = true
+          item.isNull = true;
         }
-      })
+      });
     },
     //增加经验行
     handleAddExperienceline() {
@@ -236,17 +358,18 @@ export default {
         this.experienceData = new Array();
       }
       let obj = {
-        fieldName: '',
-        fieldType: '',
+        fieldName: "",
+        fieldType: "",
         fieldLength: undefined,
+        isDisableFieldLength: true,
         isNull: false,
         isPrimary: false,
-        fieldDescription: '',
-        isAuto: false
+        fieldDescription: "",
+        isAuto: false,
       };
       this.experienceData.push(obj);
-      this.handleRules('add');
-      this.Inoputdisabled.push(false)
+      this.handleRules("add");
+      this.Inoputdisabled.push(false);
     },
     //保存经验行
     handlesaveExperience(a, b) {
@@ -255,61 +378,92 @@ export default {
     },
     //删除经验行
     handleDeleteExperience(index) {
-      this.experienceData.splice(index, 1)
-      this.handleRules('del', index);
+      this.experienceData.splice(index, 1);
+      this.handleRules("del", index);
     },
     add() {
       const rule1 = new Promise((resolve, reject) => {
-        this.$refs['form'].validate(valid => {
+        this.$refs["form"].validate((valid) => {
           if (valid) {
-            resolve()
+            resolve();
           } else {
             return false;
           }
-        })
-      })
+        });
+      });
       const rule2 = new Promise((resolve, reject) => {
-        this.$refs['tableform'].validate(valid => {
+        this.$refs["tableform"].validate((valid) => {
           if (valid) {
-            resolve()
+            resolve();
           } else {
             return false;
           }
-        })
-      })
+        });
+      });
       Promise.all([rule1, rule2]).then(() => {
         if (this.experienceData.length == 0) {
-          this.$modal.msgWarning("字段不可为空!")
+          this.$modal.msgWarning("字段不可为空!");
           return;
         }
         this.experienceData.forEach((field) => {
           if (field.fieldLength) {
-            field.fieldType = `${field.fieldType}(${field.fieldLength})`
+            field.fieldType = `${field.fieldType}(${field.fieldLength})`;
           }
-        })
+        });
         let query = {
           databaseType: this.$store.state.user.dataSource.databaseType,
           databaseName: this.$store.state.user.dataSource.databaseName,
           tableName: this.form.tableName,
           tableComment: this.form.tableComment,
-          field: this.experienceData
+          field: this.experienceData,
+        };
+        createDatabase(query)
+          .then((res) => {
+            this.$modal.msgSuccess(res.msg);
+            if (res.code === 200) {
+              this.visible = false;
+              this.$emit("ok");
+              Object.keys(this.form).forEach((key) => (this.form[key] = ""));
+              this.experienceData = [];
+              // 新增成功之后关闭当前页面
+              this.$tab.closePage();
+            }
+          })
+          .catch((err) => {
+            console.log(err);
+          });
+      });
+    },
+    edit() {
+      this.experienceData.forEach((field) => {
+        if (field.fieldLength) {
+          field.fieldType = `${field.fieldType}(${field.fieldLength})`;
         }
-        createDatabase(query).then(res => {
+      });
+      let query = {
+        databaseType: this.$store.state.user.dataSource.databaseType,
+        databaseName: this.$store.state.user.dataSource.databaseName,
+        tableName: this.form.tableName,
+        tableComment: this.form.tableComment,
+        field: this.experienceData,
+      };
+      editTable(query)
+        .then((res) => {
           this.$modal.msgSuccess(res.msg);
           if (res.code === 200) {
             this.visible = false;
             this.$emit("ok");
-            Object.keys(this.form).forEach(key => (this.form[key] = ''));
-            this.experienceData = []
-            // 新增成功之后关闭当前页面
-            this.$tab.closePage();
+            Object.keys(this.form).forEach((key) => (this.form[key] = ""));
+            this.experienceData = [];
           }
-        }).catch(err => {
-          console.log(err);
         })
-      })
-    }
-  }
-}
+        .catch((err) => {
+          console.log(err);
+        });
+      // 关闭当前页面
+      this.$tab.closePage();
+    },
+  },
+};
 </script>
 <style scoped></style>