lrf před 3 roky
rodič
revize
4cce9ad0a0

+ 2 - 0
.eslintrc.js

@@ -29,6 +29,8 @@ module.exports = {
     'vue/no-v-for-template-key': 'off',
     'vue/no-template-key': 'off',
     'vue/no-v-model-argument': 'off',
+    'vue/no-mutating-props': 'off',
+    'vue/no-unused-vars': 'off',
   },
   parserOptions: {
     parser: 'babel-eslint',

+ 25 - 0
src/api/options.js

@@ -0,0 +1,25 @@
+import { ref } from 'vue';
+import { ElMessage } from 'element-plus';
+
+// 一般是指项目路由的前缀部分
+const prefix = '/api/util/dbInit/';
+// 确定具体接口位置
+const target = 'options';
+// 拼装成全路由,如果需要再拼接,自己到方法里去拼
+const route = `${prefix}${target}`;
+/**
+ * api初始化函数
+ * @return {Object} 返回该api自带的变量与函数
+ * @property {Array} list 查询列表的数组结果
+ * @property {Number} total 查询列表符合条件的总数
+ */
+const init = function () {
+  const query = async function (query) {
+    const res = await this.$axios.$post(`${route}`, query);
+    if (this.$checkRes(res)) {
+      return res.data;
+    }
+  };
+  return { query };
+};
+export default init;

+ 14 - 1
src/api/table.js

@@ -92,6 +92,19 @@ const init = function () {
       console.error(res.errmsg);
     }
   };
-  return { list, total, query, create, fetch, update, destory };
+  /**
+   * 导出
+   * @param {Object} data 数据,id列表
+   */
+  const exportData = async function (data) {
+    const res = await this.$axios.$post(`${route}/export`, data);
+    if (this.$checkRes(res)) {
+      return res.data;
+    } else {
+      console.error(`${target}-error:`);
+      console.error(res.errmsg);
+    }
+  };
+  return { list, total, query, create, fetch, update, destory, exportData };
 };
 export default init;

+ 1 - 1
src/views/index.vue

@@ -5,7 +5,7 @@
         <project v-model:value="project" />
       </el-aside>
       <el-main>
-        <el-header>
+        <el-header style="height: 10vh">
           <el-alert type="success" effect="dark" center :closable="false">
             <el-row style="height: 60px">
               <el-col :span="24" style="font-size: 20px">当前项目为:</el-col>

+ 88 - 0
src/views/project/column.vue

@@ -0,0 +1,88 @@
+<template>
+  <div id="column">
+    <el-row>
+      <el-col :span="23" style="text-align: right; padding: 10px 0">
+        <el-button type="primary" size="mini" @click="toAdd">添加字段</el-button>
+      </el-col>
+    </el-row>
+    <el-table :data="value" style="width: 100%" stripe border fit>
+      <el-table-column align="center" prop="title" label="字段名">
+        <template #default="{ row }">
+          <el-input v-model="row.title"></el-input>
+        </template>
+      </el-table-column>
+      <el-table-column align="center" label="字段类型">
+        <template #default="{ row }">
+          <el-select v-model="row.type" placeholder="请选择字段类型">
+            <el-option v-for="(i, index) in columnType" :key="`type-${index}`" :label="i.label" :value="i.value"></el-option>
+          </el-select>
+        </template>
+      </el-table-column>
+      <el-table-column align="center" label="是否必填">
+        <template #default="{ row }">
+          <el-radio-group v-model="row.required">
+            <el-radio v-for="(i, index) in required" :key="`req-${index}`" :label="i.value">{{ i.label }}</el-radio>
+          </el-radio-group>
+        </template>
+      </el-table-column>
+      <el-table-column align="center" label="描述">
+        <template #default="{ row }">
+          <el-input type="textarea" :autosize="{ minRows: 2, maxRows: 2 }" v-model="row.desc"></el-input>
+        </template>
+      </el-table-column>
+
+      <el-table-column align="center" label="操作">
+        <template #default="{ $index }">
+          <el-row justify="space-around">
+            <el-col :span="8">
+              <el-link :underline="false" size="mini" type="danger" @click="toDelete($index)">删除</el-link>
+            </el-col>
+          </el-row>
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+
+<script>
+import optionQuery from '@/api/options';
+const _ = require('lodash');
+import { defineComponent } from 'vue';
+export default defineComponent({
+  name: 'column',
+  components: {},
+  props: {
+    value: Array,
+  },
+  emits: ['update:value'],
+  data() {
+    return {
+      columnType: [],
+      required: [],
+    };
+  },
+  setup(props, context) {
+    return optionQuery();
+  },
+  created() {
+    this.init();
+  },
+  methods: {
+    toAdd() {
+      this.$emit('update:value', [...this.value, { required: false }]);
+    },
+    async init() {
+      const arr = ['columnType', 'required'];
+      const res = await this.query(arr);
+      for (const i of arr) {
+        this[i] = res[i];
+      }
+    },
+    toDelete(index) {
+      this.value.splice(index, 1);
+    },
+  },
+});
+</script>
+
+<style lang="less" scoped></style>

+ 122 - 6
src/views/project/table.vue

@@ -1,14 +1,70 @@
 <template>
-  <div id="table" style="padding: 20px"></div>
+  <div id="table" style="margin: 20px">
+    <div v-show="view === 'table'">
+      <el-row>
+        <el-col :span="23" style="text-align: right; padding: 10px 0">
+          <el-button type="primary" :disabled="!(project && project.id)" @click="toAdd">添加表</el-button>
+        </el-col>
+        <el-col :span="24">
+          <el-table :data="list" style="width: 100%" stripe border fit>
+            <el-table-column align="center" prop="name" label="表名" />
+            <el-table-column align="center" prop="remark" label="备注" />
+            <el-table-column align="center" label="操作">
+              <template #default="{ row }">
+                <el-row>
+                  <el-col :span="8">
+                    <el-link :underline="false" size="mini" type="primary" @click="toEdit(row.id)">修改</el-link>
+                  </el-col>
+                  <el-col :span="8">
+                    <el-link :underline="false" size="mini" type="warning" @click="toExport(row.id)">导出</el-link>
+                  </el-col>
+                  <el-col :span="8">
+                    <el-link :underline="false" size="mini" type="danger" @click="toDelete(row.id)">删除</el-link>
+                  </el-col>
+                </el-row>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-col>
+      </el-row>
+    </div>
+    <el-card v-show="view !== 'table'" class="backCard">
+      <el-affix target=".backCard" :offset="0">
+        <el-row style="margin: 20px 0; background: #abc">
+          <el-col :span="7" style="text-align: center">
+            <el-button @click="toReturn">返回</el-button>
+          </el-col>
+          <el-col :span="8" style="text-align: center">
+            <el-button type="primary" @click="submit()">提交</el-button>
+          </el-col>
+          <el-col :span="8" style="text-align: center">
+            <el-button @click="resetForm()">重置</el-button>
+          </el-col>
+        </el-row>
+      </el-affix>
+      <el-form ref="form" :model="form" label-position="left" label-width="120px">
+        <el-form-item label="表名" prop="name" :required="true">
+          <el-input v-model="form.name"></el-input>
+        </el-form-item>
+        <el-form-item label="备注" prop="remark">
+          <el-input type="textarea" :autosize="{ minRows: 4, maxRows: 4 }" v-model="form.remark"></el-input>
+        </el-form-item>
+        <el-form-item label="字段列表">
+          <column-table v-model:value="form.columns"></column-table>
+        </el-form-item>
+      </el-form>
+    </el-card>
+  </div>
 </template>
 
 <script>
 import table from '@/api/table';
+import columnTable from './column.vue';
 const _ = require('lodash');
-import { defineComponent } from 'vue';
+import { defineComponent, defineAsyncComponent } from 'vue';
 export default defineComponent({
   name: 'tables',
-  components: {},
+  components: { columnTable },
   props: {
     project: Object,
   },
@@ -17,18 +73,78 @@ export default defineComponent({
   },
   data() {
     return {
-      table: undefined,
+      view: 'table',
+      form: {
+        columns: [],
+      },
     };
   },
   methods: {
     async toSearch({ skip = 0, limit = 10, ...condition } = {}) {
-      await this.query({ skip, limit, ...condition });
+      await this.query({ skip, limit, ...condition, project: _.get(this.project, 'id') });
+    },
+    async toEdit(id) {
+      if (!id) {
+        this.$message.error('没有选择要修改的表');
+        return false;
+      }
+      const data = await this.fetch(id);
+      this.form = data;
+      this.view = 'form';
+    },
+    async toDelete(id) {
+      if (!id) {
+        this.$message.error('没有选择要删除的表');
+        return false;
+      }
+      this.$confirm('确认删除该数据?', '提示', {
+        confirmButtonText: '确认删除',
+        cancelButtonText: '取消',
+        type: 'warning',
+      }).then(async () => {
+        const data = await this.destory(id);
+        if (data) await this.query();
+      });
+    },
+    async submit() {
+      this.$refs.form.validate(async (valid) => {
+        if (valid) {
+          let res;
+          const data = _.cloneDeep(this.form);
+          if (!_.get(data, 'id')) res = await this.create(data);
+          else res = await this.update(data);
+          if (res) {
+            this.view = 'table';
+            await this.query();
+          }
+        } else {
+          console.log('error submit!!');
+          return false;
+        }
+      });
+    },
+
+    async toExport(id) {
+      const res = await this.exportData({ ids: [id] });
+      console.log(JSON.parse(res));
+    },
+    toAdd() {
+      this.view = 'form';
+      this.form.project = _.get(this.project, 'id');
+      this.resetForm();
+    },
+    toReturn() {
+      this.view = 'table';
+      this.form = { columns: [] };
+    },
+    resetForm() {
+      this.$refs.form.resetFields();
     },
   },
   watch: {
     project: {
       handler(val, oval) {
-        if (_.get(val, 'id')) this.toSearch({ skip: 0, limit: 10, project: _.get(val, 'id') });
+        if (_.get(val, 'id')) this.toSearch({ skip: 0, limit: 10 });
       },
       deep: true,
     },