Sfoglia il codice sorgente

improve: 代码生成调整优化

From-wh 2 anni fa
parent
commit
49fea71af5

+ 16 - 4
template/admin/src/api/system.js

@@ -406,11 +406,11 @@ export function delFolder(params) {
 
 /**
  * 文件备注
- * @param {*} id 
- * @param {*} params 
- * @returns 
+ * @param {*} id
+ * @param {*} params
+ * @returns
  */
- export function fileMark(params) {
+export function fileMark(params) {
   return request({
     url: `system/file/mark`,
     method: 'get',
@@ -803,6 +803,18 @@ export function updateMark(data) {
     data,
   });
 }
+/**
+ * 文件管理 更新备注
+ * @param {*} data
+ * @returns
+ */
+export function markSave(fileToken, data) {
+  return request({
+    url: `system/file/mark/save?fileToken=${fileToken}`,
+    method: 'post',
+    data,
+  });
+}
 
 /**
  * 定时任务名称及标识

+ 10 - 0
template/admin/src/api/systemCodeGeneration.js

@@ -68,3 +68,13 @@ export function crudDownload(id) {
     method: 'get',
   });
 }
+/**
+ * @description 代码生成 - 文件编辑
+ */
+export function crudSaveFile(id,data) {
+  return request({
+    url: `/system/crud/save_file/${id}`,
+    method: 'post',
+    data
+  });
+}

+ 1 - 1
template/admin/src/libs/util.js

@@ -68,7 +68,7 @@ export const getMenuByRouter = (list, access) => {
  * @returns {Array}
  */
 export const getBreadCrumbList = (route, homeRoute) => {
-  let homeItem = { ...homeRoute, icon: homeRoute.meta.icon };
+  let homeItem = { ...homeRoute, icon: homeRoute.meta?.icon };
   let routeMetched = route.matched;
   if (routeMetched.some((item) => item.name === homeRoute.name)) return [homeItem];
   let res = routeMetched

+ 5 - 82
template/admin/src/pages/system/codeGeneration/components/FoundationFor.vue

@@ -45,17 +45,12 @@
         <div class="tip">模块名称为中文或者英文,用在接口名称前缀、表单头部标题</div>
       </FormItem>
       <FormItem label="表名" prop="tableName">
-        <Input
-          class="form-width"
-          v-model="foundation.tableName"
-          placeholder="请输入表名"
-          @on-blur="initTableName"
-        ></Input>
+        <Input class="form-width" v-model="foundation.tableName" placeholder="请输入表名"></Input>
         <div class="tip">
           用于生成CRUD指定的表名,不需要携带表前缀;对于生成过的表将不能在进行生成;或者可以删除对应的文件重新生成!对应系统中重要的数据表将不允许生成!
         </div>
       </FormItem>
-      <FormItem label="是否存在">
+      <!-- <FormItem label="是否存在">
         <RadioGroup v-model="foundation.isTable" @on-change="changeRadio">
           <Radio :label="1">是</Radio>
           <Radio :label="0">否</Radio>
@@ -63,8 +58,8 @@
         <div class="tip">
           数据库表可以生成系统存在的,也可以选择【否】后手动生成;如果不满足使用需求可以先在数据库中创建表,然后选择【是】再进行操作
         </div>
-      </FormItem>
-      <FormItem label="字段配置">
+      </FormItem> -->
+      <!-- <FormItem label="字段配置">
         <Button type="primary" @click="addRow">{{ foundation.isTable ? '获取字段' : '添加一行' }}</Button>
         <div>
           <Table
@@ -120,7 +115,7 @@
             </template>
           </Table>
         </div>
-      </FormItem>
+      </FormItem> -->
     </Form>
   </div>
 </template>
@@ -268,78 +263,6 @@ export default {
         this.$set(this.tableField[i], 'comment', '添加和修改时间');
       }
     },
-    changeRadio(status) {
-      this.tableField = [];
-      if (status) {
-        this.addRow();
-      }
-    },
-    initTableName() {
-      this.tableField = [];
-    },
-    addRow() {
-      if (!this.foundation.tableName) return this.$Message.warning('请先填写表名');
-      if (!this.tableField.length) {
-        let data = {
-          menuName: this.foundation.menuName,
-          tableName: this.foundation.tableName,
-          isTable: this.foundation.isTable,
-          fromField: [],
-          columnField: [],
-        };
-        this.loading = true;
-        crudFilePath(data)
-          .then((res) => {
-            this.tableField = res.data.tableField.length ? res.data.tableField : [];
-            this.$emit('storageData', res.data.makePath);
-            this.loading = false;
-            if (!this.tableField.length) {
-              this.tableField.push({
-                field: '',
-                field_type: '',
-                default: '',
-                comment: '',
-                required: false,
-                is_table: true,
-                table_name: '',
-                limit: '',
-                from_type: '0',
-              });
-            }
-          })
-          .catch((err) => {
-            this.$Message.warning(err.msg);
-            this.loading = false;
-          });
-      }
-      if (this.foundation.isTable) {
-      } else {
-        console.log(this.tableField);
-        for (let i = 0; i < this.tableField.length; i++) {
-          const el = this.tableField[i];
-          if (
-            (!el.field || !el.field_type || !el.comment) &&
-            !['addTimestamps', 'addSoftDelete'].includes(el.field_type)
-          ) {
-            return this.$Message.warning('请先完善上一条数据');
-          }
-          if (el.is_table && !el.table_name && !['addTimestamps', 'addSoftDelete'].includes(el.field_type)) {
-            return this.$Message.warning('请输入列表名');
-          }
-        }
-        this.tableField.push({
-          field: '',
-          field_type: '',
-          default: '',
-          comment: '',
-          required: false,
-          is_table: true,
-          table_name: '',
-          limit: '',
-          from_type: '0',
-        });
-      }
-    },
     getCrudMenus() {
       crudMenus().then((res) => {
         console.log(res);

+ 306 - 0
template/admin/src/pages/system/codeGeneration/components/TableForm.vue

@@ -0,0 +1,306 @@
+<template>
+  <div class="main">
+    <Button type="primary" @click="addRow">添加一行</Button>
+    <div>
+      <Table
+        ref="selection"
+        :columns="columns"
+        :data="tableField"
+        no-data-text="暂无数据"
+        highlight-row
+        :loading="loading"
+        max-height="600"
+        size="small"
+        no-filtered-data-text="暂无筛选结果"
+      >
+        <template slot-scope="{ row, index }" slot="field">
+          <Input :disabled="disabledInput(index)" v-model="tableField[index].field"></Input>
+        </template>
+        <template slot-scope="{ row, index }" slot="field_type">
+          <Select v-model="tableField[index].field_type" @on-change="changeItemField($event, index)">
+            <Option v-for="item in columnTypeList" :value="item" :key="item">{{ item }}</Option>
+          </Select>
+        </template>
+        <template slot-scope="{ row, index }" slot="limit">
+          <Input v-model="tableField[index].limit" :disabled="disabledInput(index)"></Input>
+        </template>
+        <template slot-scope="{ row, index }" slot="default">
+          <Input v-model="tableField[index].default" :disabled="disabledInput(index)"></Input>
+        </template>
+        <template slot-scope="{ row, index }" slot="comment">
+          <Input v-model="tableField[index].comment" :disabled="disabledInput(index)"></Input>
+        </template>
+        <template slot-scope="{ row, index }" slot="required">
+          <Checkbox v-model="tableField[index].required" :disabled="disabledInput(index)"></Checkbox>
+        </template>
+        <template slot-scope="{ row, index }" slot="is_table">
+          <Checkbox v-model="tableField[index].is_table" :disabled="disabledInput(index)"></Checkbox>
+        </template>
+        <template slot-scope="{ row, index }" slot="table_name">
+          <Input v-model="tableField[index].table_name" :disabled="disabledInput(index)"></Input>
+        </template>
+        <template slot-scope="{ row, index }" slot="from_type">
+          <Select v-model="tableField[index].from_type" :disabled="disabledInput(index)">
+            <Option v-for="item in fromTypeList" :value="item.value" :key="item.value">{{ item.label }}</Option>
+          </Select>
+        </template>
+        <template slot-scope="{ row, index }" slot="options">
+          <div class="table-options" v-if="['select', 'radio'].includes(tableField[index].from_type)">
+            <Select>
+              <Option v-for="item in tableField[index].options" :value="item.value" :key="item.value">{{
+                item.label
+              }}</Option>
+            </Select>
+            <Icon class="create" type="md-create" @click="eidtOptions(index)" />
+          </div>
+          <div v-else>--</div>
+        </template>
+        <template slot-scope="{ row, index }" slot="action">
+          <a v-if="!foundation.isTable" @click="del(row, index)">删除</a>
+          <span v-else>--</span>
+        </template>
+      </Table>
+    </div>
+    <Modal
+      v-model="optionsModal"
+      scrollable
+      title="字典配置"
+      closable
+      :mask-closable="false"
+      width="400px"
+      @on-ok="addOptions"
+      @on-cancel="optionsModal = false"
+    >
+      <div class="options-list">
+        <div class="item" v-for="(item, index) in optionsList" :key="index">
+          <Input class="mr10" v-model="item.label" placeholder="label" style="width: 150px" />
+          <Input class="mr10" v-model="item.value" placeholder="value" style="width: 150px" />
+          <Icon v-if="index == optionsList.length - 1" class="add" type="md-add-circle" @click="addOneOptions" />
+          <Icon v-if="index > 0" class="add" type="md-remove-circle" @click="delOneOptions(index)" />
+        </div>
+      </div>
+    </Modal>
+  </div>
+</template>
+
+<script>
+import { crudMenus, crudColumnType, crudFilePath } from '@/api/systemCodeGeneration';
+
+export default {
+  name: '',
+  props: {
+    foundation: {
+      type: Object,
+      default: () => {
+        return {};
+      },
+    },
+    id: {
+      type: String,
+      default: '',
+    },
+  },
+  data() {
+    return {
+      foundationRules: {},
+      menusList: [],
+      columnTypeList: [],
+      optionsModal: false,
+      columns: [
+        {
+          title: '字段名称',
+          slot: 'field',
+          minWidth: 100,
+        },
+        {
+          title: '字段类型',
+          slot: 'field_type',
+          minWidth: 100,
+        },
+        {
+          title: '长度',
+          slot: 'limit',
+          minWidth: 100,
+        },
+        {
+          title: '默认值',
+          slot: 'default',
+          minWidth: 100,
+        },
+        {
+          title: '字段描述',
+          slot: 'comment',
+          minWidth: 100,
+        },
+        {
+          title: '列表',
+          slot: 'is_table',
+          width: 70,
+          align: 'center',
+        },
+        {
+          title: '列表名',
+          slot: 'table_name',
+          minWidth: 120,
+          align: 'center',
+        },
+        {
+          title: '表单类型',
+          slot: 'from_type',
+          minWidth: 100,
+        },
+        {
+          title: '字典配置',
+          slot: 'options',
+          minWidth: 100,
+        },
+        {
+          title: '必填',
+          slot: 'required',
+          width: 70,
+          align: 'center',
+        },
+        {
+          title: '操作',
+          slot: 'action',
+          width: 70,
+          align: 'center',
+        },
+      ],
+      fromTypeList: [],
+      loading: false,
+      tableField: [],
+      optionsList: [],
+      index: 0,
+    };
+  },
+  created() {
+    this.getCrudMenus();
+  },
+  mounted() {},
+  methods: {
+    disabledInput(index) {
+      let fieldInfo = this.tableField[index];
+      let res = ['addTimestamps', 'addSoftDelete'].includes(this.tableField[index].field_type);
+      if (fieldInfo.primaryKey) {
+        res = true;
+      }
+      if (fieldInfo.field === 'delete_time' && fieldInfo.field_type === 'timestamp') {
+        res = true;
+      }
+      return res;
+    },
+    initfield() {
+      this.tableField = [];
+    },
+    changeItemField(e, i) {
+      if (e === 'addSoftDelete') {
+        this.$set(this.tableField[i], 'comment', '伪删除');
+      }
+      if (e === 'addTimestamps') {
+        this.$set(this.tableField[i], 'comment', '添加和修改时间');
+      }
+    },
+    eidtOptions(i) {
+      this.index = i;
+      this.optionsList = this.tableField[i].options || [{ label: '', value: '' }];
+      this.optionsModal = true;
+    },
+    addOptions() {
+      console.log(this.optionsList);
+      this.$set(this.tableField[this.index], 'options', this.optionsList);
+      // this.tableField[this.index].options = this.optionsList;
+      console.log(this.tableField[this.index].options);
+    },
+    changeRadio(status) {
+      this.tableField = [];
+      if (status) {
+        this.addRow();
+      }
+    },
+    initTableName() {
+      this.tableField = [];
+    },
+    addRow() {
+      for (let i = 0; i < this.tableField.length; i++) {
+        const el = this.tableField[i];
+        if ((!el.field || !el.field_type) && !['addTimestamps', 'addSoftDelete'].includes(el.field_type)) {
+          return this.$Message.warning('请先完善上一条数据');
+        }
+        if (el.is_table && !el.table_name && !['addTimestamps', 'addSoftDelete'].includes(el.field_type)) {
+          return this.$Message.warning('请输入列表名');
+        }
+      }
+      this.tableField.push({
+        field: '',
+        field_type: '',
+        default: '',
+        comment: '',
+        required: false,
+        is_table: true,
+        table_name: '',
+        limit: '',
+        primaryKey: 0,
+        from_type: '0',
+      });
+    },
+    getCrudMenus() {
+      crudMenus().then((res) => {
+        console.log(res);
+        this.menusList = res.data;
+      });
+      crudColumnType().then((res) => {
+        this.columnTypeList = res.data.types;
+        this.fromTypeList = res.data.form;
+      });
+    },
+    del(row, index) {
+      this.tableField.splice(index, 1);
+      if (this.id) {
+        this.deleteField.push(row.field);
+      }
+    },
+    addOneOptions() {
+      this.optionsList.push({
+        label: '',
+        value: '',
+      });
+    },
+    delOneOptions(i) {
+      this.optionsList.splice(i, 1);
+    },
+  },
+};
+</script>
+<style lang="stylus" scoped>
+.form-width {
+  width: 500px;
+}
+.item{
+  display flex
+  margin-bottom 10px
+  .row{
+    width 140px
+    margin-right 10px
+  }
+}
+.table-options{
+  display flex
+  align-items center
+  .create{
+    font-size: 16px;
+    margin-left 10px
+    cursor pointer
+  }
+}
+.options-list{
+  .item{
+    display flex
+    align-items center
+    .add{
+      font-size: 24px
+      color #2d8cf0
+    }
+  }
+}
+</style>

+ 86 - 13
template/admin/src/pages/system/codeGeneration/index.vue

@@ -27,32 +27,47 @@
       </Card>
     </div>
     <div class="pt10" v-show="currentTab == '1'">
+      <Card :bordered="false" dis-hover class="ivu-mt">
+        <TableForm
+          ref="TableForm"
+          :foundation="formItem.foundation"
+          :tableField="tableField"
+          :id="id"
+          @storageData="storageData"
+        />
+      </Card>
+    </div>
+    <div class="pt10" v-show="currentTab == '2'">
       <Card :bordered="false" dis-hover class="ivu-mt">
         <StorageLoc :storage="formItem.storage" />
       </Card>
     </div>
     <Card :bordered="false" class="btn">
       <Button class="mr20" @click="beforeTab">上一步</Button>
-      <Button type="primary" @click="nextTab">{{ currentTab == 1 ? '提交' : '下一步' }}</Button>
+      <Button type="primary" @click="nextTab">{{ currentTab == 2 ? '提交' : '下一步' }}</Button>
     </Card>
   </div>
 </template>
 
 <script>
 import { codeCrud } from '@/api/setting';
-import StorageLoc from './components/StorageLoc.vue';
 import FoundationForm from './components/FoundationFor.vue';
+import TableForm from './components/TableForm.vue';
+import StorageLoc from './components/StorageLoc.vue';
 import { getMenusUnique } from '@/api/systemMenus';
 import { formatFlatteningRoutes } from '@/libs/system';
+import { crudFilePath } from '@/api/systemCodeGeneration';
+import { crudDet } from '@/api/systemCodeGeneration';
 
 export default {
   name: 'system_code_generation',
-  components: { FoundationForm, StorageLoc },
+  components: { FoundationForm, StorageLoc, TableForm },
   data() {
     return {
       currentTab: 0,
       headerList: [
         { label: '基础信息', value: 'foundation' },
+        { label: '字段配置', value: 'table' },
         { label: '存放位置', value: 'storage' },
       ],
       formItem: {
@@ -63,6 +78,7 @@ export default {
           isTable: 1,
           menuName: '',
         },
+        tableForm: {},
         storage: {},
         field: {},
         formItem: {},
@@ -73,27 +89,80 @@ export default {
       tableField: [],
       rowList: [],
       reqloading: false,
+      id: "",
     };
   },
-  created() {},
+  created() {
+    if (this.$route.query.id) {
+      this.id = this.$route.query.id;
+      this.getDetail(this.$route.query.id);
+    }
+  },
   mounted: function () {},
   methods: {
+    getDetail(id) {
+      crudDet(id).then((res) => {
+        console.log(res);
+        let data = res.data.crudInfo.field;
+        this.formItem.foundation.pid = data.pid;
+        this.formItem.foundation.tableName = data.tableName;
+        this.formItem.foundation.modelName = data.modelName;
+        this.formItem.foundation.menuName = data.menuName;
+        this.$refs.TableForm.tableField = data.tableField;
+        this.formItem.storage = data.filePath;
+      });
+    },
     storageData(data) {
       this.formItem.storage = data;
     },
     beforeTab() {
       this.currentTab--;
     },
+    addRow() {
+      console.log(this.formItem);
+      let foundation = this.formItem.foundation;
+      if (!foundation.tableName) return this.$Message.warning('请先填写表名');
+      let data = {
+        menuName: foundation.menuName,
+        tableName: foundation.tableName,
+        // isTable: foundation.isTable,
+        fromField: [],
+        columnField: [],
+      };
+      crudFilePath(data)
+        .then((res) => {
+          this.$refs.TableForm.tableField = res.data.tableField.length ? res.data.tableField : [];
+          this.formItem.storage = res.data.makePath;
+          if (!res.data.tableField.length) {
+            this.$refs.TableForm.tableField.push({
+              field: 'id',
+              field_type: 'int',
+              default: '',
+              comment: '自增ID',
+              required: false,
+              is_table: true,
+              table_name: '',
+              limit: '10',
+              primaryKey: 1,
+              from_type: '0',
+            });
+          }
+          this.currentTab++;
+        })
+        .catch((err) => {
+          this.$Message.warning(err.msg);
+        });
+    },
     nextTab() {
       if (this.currentTab == 0) {
         // if (!this.formItem.foundation.pid) return this.$Message.warning('请选择菜单');
         if (!this.formItem.foundation.tableName) return this.$Message.warning('请输入表名');
         if (!this.formItem.foundation.modelName) return this.$Message.warning('请输入模块名');
         if (!this.formItem.foundation.isTable) {
-          if (!this.$refs.Foundation.tableField.length) return this.$Message.warning('请先添加表数据');
-          if (this.$refs.Foundation.tableField.length)
-            for (let i = 0; i < this.$refs.Foundation.tableField.length; i++) {
-              const el = this.$refs.Foundation.tableField[i];
+          if (!this.$refs.TableForm.tableField.length) return this.$Message.warning('请先添加表数据');
+          if (this.$refs.TableForm.tableField.length)
+            for (let i = 0; i < this.$refs.TableForm.tableField.length; i++) {
+              const el = this.$refs.TableForm.tableField[i];
               if (
                 ['addSoftDelete', 'addTimestamps'].indexOf(el.field_type) === -1 &&
                 (!el.field || !el.field_type || !el.comment)
@@ -101,17 +170,20 @@ export default {
                 return this.$Message.warning('请完善sql表数据');
               }
             }
-        } else {
-          if (!this.$refs.Foundation.tableField.length) return this.$Message.warning('请先生成表数据');
         }
-        this.currentTab++;
-      } else if (this.currentTab == 1) {
+        if (this.id) {
+          return this.currentTab++;
+        }
+        this.addRow();
+      } else if (this.currentTab == 2) {
         if (this.reqloading) return;
         let data = {
           ...this.formItem.foundation,
           filePath: this.formItem.storage,
-          tableField: this.$refs.Foundation.tableField,
+          tableField: this.$refs.TableForm.tableField,
+          deleteField: this.id ? this.$refs.TableForm.deleteField : [],
         };
+        if (this.id) data.id = this.id;
         this.reqloading = true;
         codeCrud(data)
           .then((res) => {
@@ -164,6 +236,7 @@ export default {
   line-height: 26px;
 }
 .code-wapper {
+  min-height: 800px;
   padding-bottom: 90px;
 }
 .btn {

+ 79 - 10
template/admin/src/pages/system/codeGeneration/list.vue

@@ -29,6 +29,8 @@
         <template slot-scope="{ row, index }" slot="action">
           <a @click="edit(row, '编辑')">查看</a>
           <Divider type="vertical" />
+          <a @click="editItem(row)">编辑</a>
+          <Divider type="vertical" />
           <a @click="downLoad(row)">下载</a>
           <Divider type="vertical" />
           <a @click="del(row, '删除', index)">删除</a>
@@ -45,8 +47,16 @@
         />
       </div>
     </Card>
-    <Modal
+    <Drawer
       :class-name="className"
+      title="Create"
+      v-model="modals"
+      width="80%"
+      :mask-closable="false"
+      :styles="styles"
+      :before-close="editModalChange"
+    >
+      <!-- <Modal
       v-model="modals"
       scrollable
       footer-hide
@@ -54,11 +64,14 @@
       :mask-closable="false"
       width="80%"
       :before-close="editModalChange"
-    >
+    > -->
+
       <p slot="header" class="diy-header" ref="diyHeader">
         <span>{{ title }}</span>
       </p>
-      <div style="height: 100%">
+      <div class="file" style="height: 100%">
+        <Button class="save" type="primary" @click="crudSaveFile">保存</Button>
+
         <div class="file-box">
           <div class="file-fix"></div>
           <div class="file-content">
@@ -78,14 +91,23 @@
                 :label="value.title"
                 :icon="value.icon"
               >
-                <div ref="container" :id="'container_' + value.index" style="height: 100%; min-height: 560px"></div>
+                <div
+                  :ref="'container_' + value.index"
+                  :id="'container_' + value.index"
+                  style="height: 100%; min-height: 560px"
+                ></div>
               </TabPane>
             </Tabs>
           </div>
           <Spin size="large" fix v-if="spinShow"></Spin>
         </div>
       </div>
-    </Modal>
+      <!-- </Modal> -->
+      <!-- <div class="demo-drawer-footer">
+        <Button style="margin-right: 8px" @click="modals = false">关闭</Button>
+        <Button type="primary" @click="modals = false">保存</Button>
+      </div> -->
+    </Drawer>
     <Modal
       v-model="buildModals"
       scrollable
@@ -106,7 +128,7 @@
 
 <script>
 import { mapState } from 'vuex';
-import { crudList, crudDet, crudDownload } from '@/api/systemCodeGeneration';
+import { crudList, crudDet, crudDownload, crudSaveFile } from '@/api/systemCodeGeneration';
 import * as monaco from 'monaco-editor';
 import { getCookies, removeCookies } from '@/libs/util';
 import Setting from '@/setting';
@@ -126,6 +148,12 @@ export default {
         limit: 20,
         title: '',
       },
+      styles: {
+        height: 'calc(100% - 55px)',
+        overflow: 'auto',
+        paddingBottom: '53px',
+        position: 'static',
+      },
       loading: false,
       buildModals: false,
       tabList: [],
@@ -185,6 +213,7 @@ export default {
       editor: '', //当前编辑器对象
       editorIndex: [],
       title: '',
+      editId: 0,
     };
   },
   computed: {
@@ -205,6 +234,19 @@ export default {
     }
   },
   methods: {
+    crudSaveFile() {
+      let data = {
+        filepath: this.editorIndex[this.indexEditor].pathname,
+        comment: this.editorList[this.indexEditor].editor.getValue(),
+      };
+      crudSaveFile(this.editId, data)
+        .then((res) => {
+          this.$Message.success(res.msg);
+        })
+        .catch((err) => {
+          this.$Message.error(err.msg);
+        });
+    },
     downLoad(row) {
       crudDownload(row.id).then((res) => {
         window.open(res.data.download_url, '_blank');
@@ -297,17 +339,26 @@ export default {
         this.openfile(row.id, false);
       });
     },
+    editItem(row) {
+      this.$router.push({
+        name: 'system_code_generation',
+        query: {
+          id: row.id,
+        },
+      });
+    },
     //打开文件
     openfile(id) {
       try {
         console.log(id);
+        this.editId = id;
         let that = this;
         this.editorIndex = [];
         this.editorList = [];
         crudDet(id)
           .then(async (res) => {
-            let data = res.data[0];
-            res.data.map((i, index) => {
+            let data = res.data.file[0];
+            res.data.file.map((i, index) => {
               let data = i;
               this.editorIndex.push({
                 tab: true,
@@ -322,7 +373,6 @@ export default {
                 that.editorList[index].path = data.path;
                 that.editorList[index].oldCode = that.content;
                 that.editorIndex[index].title = data.name;
-                console.log('111');
               });
             });
             that.modals = true;
@@ -369,7 +419,7 @@ export default {
             autoIndent: true, // 自动布局
             tabSize: 4, // tab缩进长度
             autoClosingOvertype: 'always',
-            readOnly: true,
+            readOnly: false,
           });
           that.editorList.push({
             editor: that.editor,
@@ -543,4 +593,23 @@ export default {
 >>> .ivu-tabs.ivu-tabs-card > .ivu-tabs-bar .ivu-tabs-nav-container {
   background-color: #fff;
 }
+.demo-drawer-footer {
+  width: 100%;
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  border-top: 1px solid #e8e8e8;
+  padding: 10px 16px;
+  text-align: right;
+  background: #fff;
+}
+.file {
+  position: relative;
+  .save {
+    position: absolute;
+    right: 140px;
+    top: 60px;
+    z-index: 99;
+  }
+}
 </style>

+ 53 - 16
template/admin/src/pages/system/maintain/systemDatabackup/index.vue

@@ -16,15 +16,18 @@
               :columns="columns"
               :data="tabList2"
               :loading="loading"
-              highlight-row
               no-data-text="暂无数据"
               @on-selection-change="onSelectTab"
               size="small"
               no-filtered-data-text="暂无筛选结果"
             >
+              <template slot-scope="{ row, index }" slot="comment">
+                <div class="mark">
+                  <div v-if="row.is_edit" class="table-mark" @click="isEditMark(row)">{{ row.comment }}</div>
+                  <Input ref="mark" v-else v-model="row.comment" @on-blur="isEditBlur(row, 0)"></Input>
+                </div>
+              </template>
               <template slot-scope="{ row }" slot="action">
-                <a @click="editMark(row, 0)">备注</a>
-                <Divider type="vertical" />
                 <a @click="Info(row)">详情</a>
               </template>
             </Table>
@@ -37,13 +40,15 @@
               :data="tabList3"
               :loading="loading2"
               no-data-text="暂无数据"
-              highlight-row
               max-height="600"
               size="small"
               no-filtered-data-text="暂无筛选结果"
             >
-              <template slot-scope="{ row }" slot="action">
-                <a @click="editMark(row, 1)">备注</a>
+              <template slot-scope="{ row, index }" slot="COLUMN_COMMENT">
+                <div class="mark">
+                  <div v-if="row.is_edit" class="table-mark" @click="isEditMark(row)">{{ row.COLUMN_COMMENT }}</div>
+                  <Input ref="mark" v-else v-model="row.COLUMN_COMMENT" @on-blur="isEditBlur(row, 1)"></Input>
+                </div>
               </template>
             </Table>
           </Drawer>
@@ -131,7 +136,7 @@ export default {
           title: '操作',
           slot: 'action',
           fixed: 'right',
-          minWidth: 150,
+          minWidth: 80,
         },
       ],
       tabList2: [],
@@ -149,7 +154,7 @@ export default {
         },
         {
           title: '备注',
-          key: 'comment',
+          slot: 'comment',
           minWidth: 200,
         },
         {
@@ -180,7 +185,7 @@ export default {
           title: '操作',
           slot: 'action',
           fixed: 'right',
-          minWidth: 150,
+          minWidth: 80,
         },
       ],
       selectionList: [],
@@ -208,13 +213,7 @@ export default {
         },
         {
           title: '备注',
-          key: 'COLUMN_COMMENT',
-        },
-        {
-          title: '操作',
-          slot: 'action',
-          fixed: 'right',
-          minWidth: 60,
+          slot: 'COLUMN_COMMENT',
         },
       ],
       rows: {},
@@ -429,6 +428,28 @@ export default {
           this.$Message.error(res.msg);
         });
     },
+    isEditMark(row) {
+      row.is_edit = true;
+      this.$nextTick((e) => {
+        this.$refs.mark.focus();
+      });
+    },
+    isEditBlur(row, type) {
+      row.is_edit = false;
+      this.changeMarkData.table = row.name || row.TABLE_NAME;
+      this.changeMarkData.field = row.COLUMN_NAME || '';
+      this.changeMarkData.type = row.COLUMN_TYPE || '';
+      this.changeMarkData.is_field = type;
+      this.changeMarkData.mark = type ? row.COLUMN_COMMENT : row.comment;
+
+      updateMark(this.changeMarkData)
+        .then((res) => {
+          // this.$Message.success(res.msg);
+        })
+        .catch((err) => {
+          this.$Message.error(err.msg);
+        });
+    },
   },
 };
 </script>
@@ -436,4 +457,20 @@ export default {
 <style scoped lang="stylus">
 .tableBox >>> .ivu-table-header table
    border none !important
+
+.table-mark{
+  cursor: text;
+}
+.table-mark:hover{
+  border:1px solid #c2c2c2;
+  padding: 3px 5px
+}
+.mark /deep/ .ivu-input{
+    background: #fff;
+    border-radius: .39rem;
+}
+.mark /deep/ .ivu-input, .ivu-input:hover, .ivu-input:focus {
+    border: transparent;
+    box-shadow: none;
+}
 </style>

+ 1 - 1
template/admin/src/pages/system/maintain/systemFile/login.vue

@@ -113,7 +113,7 @@ export default {
   align-items: center;
 }
 .trip{
-    width: 400px;
+    width: 450px;
     text-align: left;
     color: #aaa;
 }

+ 54 - 9
template/admin/src/pages/system/maintain/systemFile/opendir.vue

@@ -11,24 +11,30 @@
         :data="tabList"
         :loading="loading"
         no-data-text="暂无数据"
-        highlight-row
         class="mt20"
-        @on-current-change="currentChange"
         no-filtered-data-text="暂无筛选结果"
       >
         <template slot-scope="{ row }" slot="filename">
-          <Icon type="ios-folder-outline" v-if="row.isDir" class="mr5" />
-          <Icon type="ios-document-outline" v-else class="mr5" />
-          <span>{{ row.filename }}</span>
+          <div @click="currentChange(row)">
+            <Icon type="ios-folder-outline" v-if="row.isDir" class="mr5" />
+            <Icon type="ios-document-outline" v-else class="mr5" />
+            <span>{{ row.filename }}</span>
+          </div>
         </template>
         <template slot-scope="{ row }" slot="isWritable">
           <span v-text="row.isWritable ? '是' : '否'"></span>
         </template>
+        <template slot-scope="{ row, index }" slot="mark">
+          <div class="mark">
+            <div v-if="row.is_edit" class="table-mark" @click="isEditMark(row)">{{ row.mark }}</div>
+            <Input ref="mark" v-else v-model="row.mark" @on-blur="isEditBlur(row)"></Input>
+          </div>
+        </template>
         <template slot-scope="{ row, index }" slot="action">
           <a @click="open(row)" v-if="row.isDir">打开</a>
           <a @click="edit(row)" v-else>编辑</a>
-          <Divider type="vertical" />
-          <a @click.stop="mark(row)">备注</a>
+          <!-- <Divider type="vertical" />
+          <a @click.stop="mark(row)">备注</a> -->
         </template>
       </Table>
     </Card>
@@ -147,6 +153,7 @@ import {
   delFolder,
   rename,
   fileMark,
+  markSave,
 } from '@/api/system';
 import CodeMirror from 'codemirror/lib/codemirror';
 import loginFrom from './components/loginFrom';
@@ -210,7 +217,7 @@ export default {
         },
         {
           title: '备注',
-          key: 'mark',
+          slot: 'mark',
           minWidth: 150,
         },
         {
@@ -781,6 +788,30 @@ export default {
       this.code = this.editorList[index].oldCode; //设置文件打开时的代码
       this.editor = this.editorList[index].editor; //设置编辑器实例
     },
+    isEditMark(row) {
+      try {
+        row.is_edit = true;
+        this.$nextTick((e) => {
+          this.$refs.mark.focus();
+        });
+      } catch (error) {
+        console.log(error);
+      }
+    },
+    isEditBlur(row) {
+      row.is_edit = false;
+      let data = {
+        full_path: '/app',
+        mark: row.mark,
+      };
+      markSave(this.fileToken, data)
+        .then((res) => {
+          // this.$Message.success(res.msg);
+        })
+        .catch((err) => {
+          this.$Message.error(err.msg);
+        });
+    },
     handleTabRemove(index) {
       let that = this;
 
@@ -977,7 +1008,21 @@ export default {
   margin: auto;
   background: rgba(0, 0, 0, 0.3);
 }
-
+.table-mark{
+  cursor: text;
+}
+.table-mark:hover{
+  border:1px solid #c2c2c2;
+  padding: 3px 5px
+}
+.mark /deep/ .ivu-input{
+    background: #fff;
+    border-radius: .39rem;
+}
+.mark /deep/ .ivu-input, .ivu-input:hover, .ivu-input:focus {
+    border: transparent;
+    box-shadow: none;
+}
 .diy-from-header {
   height: 30px;
   line-height: 30px;