Explorar el Código

feat: 添加数据库实例查询功能

Jinyao hace 5 años
padre
commit
a58abef697

+ 1 - 0
src/api/devcloud/prefix.ts

@@ -10,3 +10,4 @@ export const STAGE_PREFIX = '/stages';
 export const COMMIT_PREFIX = '/commits';
 export const FUNCTEST_PREFIX = '/func_test';
 export const AUTOTEST_PREFIX = '/auto_test';
+export const SQL_PREFIX = '/sql';

+ 12 - 0
src/api/devcloud/sql.ts

@@ -0,0 +1,12 @@
+import axios from '@/utils/axios';
+
+import { SQL_PREFIX } from './prefix';
+
+type SQLExecPayload = {
+  db: string;
+  deploymentId: number;
+  password: string;
+  sql: string;
+  username: string;
+}
+export const SQLExec = (SqlExecPayload: SQLExecPayload) => axios.post(`${SQL_PREFIX}/exec`, SqlExecPayload);

+ 2 - 0
src/api/index.ts

@@ -6,6 +6,7 @@ import * as PipelineAPI from './devcloud/pipeline';
 import * as APITestAPI from './devcloud/apitest';
 import * as FuncTestAPI from './devcloud/functest';
 import * as AutoTestAPI from './devcloud/autotest';
+import * as SQLExecAPI from './devcloud/sql';
 import * as PortalAPI from './portal';
 
 export {
@@ -18,4 +19,5 @@ export {
   APITestAPI,
   FuncTestAPI,
   AutoTestAPI,
+  SQLExecAPI,
 };

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
src/assets/icon/database-hover.svg


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
src/assets/icon/database-using.svg


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
src/assets/icon/database.svg


+ 12 - 0
src/components/SideBar.vue

@@ -15,6 +15,9 @@
     <el-menu-item index="pipeline">
       <i class="icon" target="pipeline"></i>
     </el-menu-item>
+    <el-menu-item index="database">
+      <i class="icon" target="database"></i>
+    </el-menu-item>
     <el-menu-item index="apitest">
       <i class="icon" target="apitest"></i>
     </el-menu-item>
@@ -95,6 +98,15 @@ export default {
     background-image: url("../assets/icon/training-using.svg");
   }
 }
+.icon[target=database]{
+  background-image: url("../assets/icon/database.svg");
+  .el-menu-item:hover & {
+    background-image: url("../assets/icon/database-hover.svg");
+  }
+  .el-menu-item.is-active & {
+    background-image: url("../assets/icon/database-using.svg");
+  }
+}
 .icon[target=apitest]{
    background-image: url("../assets/icon/test.svg");
   .el-menu-item:hover & {

+ 4 - 0
src/router/index.ts

@@ -54,6 +54,10 @@ const routes: Array<RouteRecordRaw> = [
         path: 'pipeline',
         component: () => import(/* webpackChunkName: "project" */'@/views/Project/Pipeline.vue'),
       },
+      {
+        path: 'database',
+        component: () => import(/* webpackChunkName: "project" */'@/views/Project/Database.vue'),
+      },
       {
         path: 'apitest',
         component: () => import(/* webpackChunkName: "project" */'@/views/Project/APITest.vue'),

+ 115 - 0
src/views/Project/Database.vue

@@ -0,0 +1,115 @@
+<template>
+  <ElForm inline ref="sql-form" :model="form" label-width="80px">
+    <ElFormItem label="实例">
+      <ElSelect class="input" v-model="form.deploymentId" placeholder="请选择数据库实例">
+        <ElOption v-for="db in dbs" :key="db.id" :label="db.name" :value="db.id"></ElOption>
+      </ElSelect>
+    </ElFormItem>
+    <ElFormItem label="用户名">
+      <ElInput class="input" v-model="form.username" placeholder="请输入用户名"></ElInput>
+    </ElFormItem>
+    <ElFormItem label="密码">
+      <ElInput class="input" v-model="form.password" type="password" placeholder="请输入密码"></ElInput>
+    </ElFormItem>
+    <ElFormItem label="数据库">
+      <ElInput class="input" v-model="form.db" placeholder="请输入数据库名"></ElInput>
+    </ElFormItem>
+    <ElFormItem label="SQL">
+      <ElInput class="sql" v-model="form.sql" :rows="5" type="textarea" clearable></ElInput>
+    </ElFormItem>
+    <ElFormItem>
+      <ElButton type="primary" @click="exec">执行</ElButton>
+    </ElFormItem>
+  </ElForm>
+  <ElDivider content-position="left">当前执行记录</ElDivider>
+  <ElRow type="flex" justify="space-between">
+    <ElCol :span="4" height="600px">
+      <div
+        :class="['list-item', active === key?'active':'']"
+        v-for="key in [...execHistory.keys()].reverse()"
+        :key="key"
+        @click="()=>{active = key}"
+      >{{key}}</div>
+    </ElCol>
+    <ElDivider direction="vertical"></ElDivider>
+    <ElCol :span="18" v-show="active > 0">
+      <ElDivider content-position="left">SQL</ElDivider>
+      <pre>{{activeRecord.sql}}</pre>
+      <ElDivider content-position="left">结果</ElDivider>
+      <pre>{{activeRecord.result}}</pre>
+    </ElCol>
+  </ElRow>
+</template>
+
+<script>
+import { SQLExecAPI, PipelineAPI } from '@/api';
+
+export default {
+  name: 'Database',
+  data() {
+    return {
+      dbs: [],
+      execHistory: new Map(),
+      active: -1,
+      form: {
+        db: '',
+        deploymentId: null,
+        password: '',
+        sql: '',
+        username: 'root',
+      },
+    };
+  },
+  async mounted() {
+    this.dbs = await PipelineAPI.getDeploymentsByProjectId(this.$store.state.workspace.currentProjectId);
+  },
+  computed: {
+    activeRecord() {
+      if (this.active < 0) return {};
+      return this.execHistory.get(this.active);
+    },
+  },
+  methods: {
+    async exec() {
+      const result = await SQLExecAPI.SQLExec(this.form);
+      this.execHistory.set(this.execHistory.size + 1, {
+        sql: this.form.sql,
+        result,
+      });
+      this.active = this.execHistory.size;
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.input {
+  width: 240px;
+}
+.sql {
+  width: 1000px;
+  input {
+    font: 1em monospace;
+  }
+}
+.list-item {
+  height: 32px;
+  line-height: 32px;
+  padding: 4px 4px 4px 32px;
+  width: 80%;
+  &.active {
+    background-color: #ecf5ff;
+    color: #409eff;
+  }
+  &:hover {
+    background-color: #ecf5ff;
+    color: #409eff;
+  }
+}
+
+pre {
+  font-size: 1.2em;
+  word-break: break-word;
+  white-space: pre-wrap;
+}
+</style>

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio