| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- <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" v-if="execHistory.size > 0">
- <ElCol :span="4" height="600px">
- <div
- :class="['list-item', active === key?'active':'']"
- v-for="key in [...execHistory.keys()].reverse()"
- :key="key"
- @click="switchRecord(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>
- <template v-if="showTable">
- <pre>{{b}}</pre>
- <table>
- <tr v-for="(row, i) in content" :key="i">
- <td v-for="(cell,j) in row" :key="j">{{cell}}</td>
- </tr>
- </table>
- </template>
- <template v-else>
- <pre>{{activeRecord.result}}</pre>
- </template>
- </ElCol>
- </ElRow>
- <ElEmpty v-else description="暂无记录"></ElEmpty>
- </template>
- <script>
- import { SQLExecAPI } from '@/api';
- export default {
- name: 'Database',
- data() {
- return {
- dbs: [],
- execHistory: new Map(),
- active: -1,
- showTable: true,
- form: {
- db: '',
- deploymentId: null,
- password: '',
- sql: '',
- username: 'root',
- },
- b: '',
- content: '',
- };
- },
- async mounted() {
- this.dbs = await SQLExecAPI.getDatabaseInstances(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.switchRecord(this.execHistory.size);
- },
- switchRecord(key) {
- this.active = key;
- const { b, content } = this.process(this.activeRecord.result);
- if (typeof content === 'string') {
- this.showTable = false;
- } else {
- this.showTable = true;
- }
- this.b = b;
- this.content = content;
- },
- process(result) {
- const i = result.indexOf('\n');
- const b = result.substr(0, i);
- let content = result.substr(i + 1);
- if (!content.startsWith('[[')) {
- return {
- b,
- content,
- };
- }
- content = content.substring(1, content.length - 1);
- const recordList = content.match(/\[.*?\]/g);
- content = [];
- recordList.forEach((_record) => content.push(_record.substring(1, _record.length - 1).split(',').map((val) => val.trim())));
- return {
- b,
- content,
- };
- },
- },
- };
- </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;
- }
- table {
- margin-top: 24px;
- color: #333333;
- border-width: 1px;
- border-color: #666666;
- border-collapse: collapse;
- td {
- border-width: 1px;
- padding: 8px 12px;
- border-style: solid;
- border-color: #666666;
- background-color: #ffffff;
- white-space: nowrap;
- }
- }
- </style>
|