feat: 优化

This commit is contained in:
meilin.huang
2023-02-15 21:28:01 +08:00
parent 8c501c90cd
commit f22badb861
11 changed files with 123 additions and 66 deletions

View File

@@ -111,14 +111,24 @@ function buildDocker() {
echo_yellow "-------------------构建docker镜像结束-------------------" echo_yellow "-------------------构建docker镜像结束-------------------"
} }
function buildxDocker() {
echo_yellow "-------------------docker buildx构建镜像开始-------------------"
imageVersion=$1
cd ${server_folder}
imageName="mayflygo/mayfly-go:${imageVersion}"
docker buildx build --push --platform linux/amd64,linux/arm64 -t "${imageName}" .
echo_green "docker多版本镜像构建完成->[${imageName}]"
echo_yellow "-------------------docker buildx构建镜像结束-------------------"
}
function runBuild() { function runBuild() {
read -p "请选择构建版本[0|其他->全部 1->linux-amd64 2->linux-arm64 3->windows 4->mac 5->docker]: " buildType read -p "请选择构建版本[0|其他->除docker镜像外其他 1->linux-amd64 2->linux-arm64 3->windows 4->mac 5->docker 6->docker buildx]: " buildType
toPath="." toPath="."
imageVersion="latest" imageVersion="latest"
copyDocScript="1" copyDocScript="1"
if [ "${buildType}" != "5" ] ; then if [[ "${buildType}" != "5" ]] && [[ "${buildType}" != "6" ]] ; then
# 构建结果的目的路径 # 构建结果的目的路径
read -p "请输入构建产物输出目录[默认当前路径]: " toPath read -p "请输入构建产物输出目录[默认当前路径]: " toPath
if [ ! -d ${toPath} ] ; then if [ ! -d ${toPath} ] ; then
@@ -139,7 +149,7 @@ function runBuild() {
toPath=`pwd` toPath=`pwd`
fi fi
if [[ "${buildType}" == "5" ]] || [[ "${buildType}" == "0" ]] ; then if [[ "${buildType}" == "5" ]] || [[ "${buildType}" == "0" ]] || [[ "${buildType}" == "6" ]] ; then
read -p "请输入docker镜像版本号[默认latest]: " imageVersion read -p "请输入docker镜像版本号[默认latest]: " imageVersion
if [ "${imageVersion}" == "" ] ; then if [ "${imageVersion}" == "" ] ; then
@@ -169,12 +179,14 @@ function runBuild() {
"5") "5")
buildDocker ${imageVersion} buildDocker ${imageVersion}
;; ;;
"6")
buildxDocker ${imageVersion}
;;
*) *)
buildLinuxAmd64 ${toPath} ${copyDocScript} buildLinuxAmd64 ${toPath} ${copyDocScript}
buildLinuxArm64 ${toPath} ${copyDocScript} buildLinuxArm64 ${toPath} ${copyDocScript}
buildWindows ${toPath} ${copyDocScript} buildWindows ${toPath} ${copyDocScript}
buildMac ${toPath} ${copyDocScript} buildMac ${toPath} ${copyDocScript}
buildDocker ${imageVersion}
;; ;;
esac esac

View File

@@ -11,7 +11,7 @@ const config = {
baseWsUrl: `${(window as any).globalConfig.BaseWsUrl || `${location.protocol == 'https:' ? 'wss:' : 'ws:'}//${getBaseApiUrl()}`}/api`, baseWsUrl: `${(window as any).globalConfig.BaseWsUrl || `${location.protocol == 'https:' ? 'wss:' : 'ws:'}//${getBaseApiUrl()}`}/api`,
// 系统版本 // 系统版本
version: 'v1.3.1' version: 'v1.4.0'
} }
export default config export default config

View File

@@ -1,5 +1,6 @@
<template> <template>
<div style="display: inline-flex; justify-content: center; align-items: center; cursor: pointer;"> <div
style="display: inline-flex; justify-content: center; align-items: center; cursor: pointer;vertical-align: middle;">
<el-popover @show="showTagInfo" placement="right-end" title="标签信息" :width="300" trigger="hover"> <el-popover @show="showTagInfo" placement="right-end" title="标签信息" :width="300" trigger="hover">
<template #reference> <template #reference>
<el-icon> <el-icon>

View File

@@ -1,18 +1,34 @@
<template> <template>
<div> <div>
<el-row type="flex"> <el-row>
<el-col :span="24"> <el-col :span="4">
<el-button type="primary" icon="plus" <el-button type="primary" icon="plus" @click="addQueryTab({ id: nowDbInst.id }, state.db)"
@click="addQueryTab({ id: state.dbId, type: state.dbType }, state.db)"
size="small">新建查询</el-button> size="small">新建查询</el-button>
</el-col> </el-col>
<el-col :span="20" v-if="state.db">
<el-descriptions :column="4" size="small" border style="height: 10px">
<el-descriptions-item label-align="right" label="tag">{{ nowDbInst.tagPath }}</el-descriptions-item>
<el-descriptions-item label="实例" label-align="right">
{{ nowDbInst.id }}
<el-divider direction="vertical" border-style="dashed" />
{{ nowDbInst.type }}
<el-divider direction="vertical" border-style="dashed" />
{{ nowDbInst.name }}
</el-descriptions-item>
<el-descriptions-item label="库名" label-align="right">{{ state.db }}</el-descriptions-item>
</el-descriptions>
</el-col>
</el-row>
<el-row type="flex">
<el-col :span="4" style="border-left: 1px solid #eee; margin-top: 10px"> <el-col :span="4" style="border-left: 1px solid #eee; margin-top: 10px">
<InstanceTree ref="instanceTreeRef" @change-instance="changeInstance" @change-schema="changeSchema" <InstanceTree ref="instanceTreeRef" @change-instance="changeInstance" @change-schema="changeSchema"
@clickSqlName="onClickSqlName" @clickSchemaTable="loadTableData" /> @clickSqlName="onClickSqlName" @clickSchemaTable="loadTableData" />
</el-col> </el-col>
<el-col :span="20"> <el-col :span="20">
<el-container id="data-exec" style="border-left: 1px solid #eee; margin-top: 10px"> <el-container id="data-exec" style="border-left: 1px solid #eee; margin-top: 10px">
<el-tabs @tab-remove="remoteTab" @tab-click="onDataTabClick" style="width: 100%" <el-tabs @tab-remove="onRemoveTab" @tab-change="onTabChange" style="width: 100%"
v-model="state.activeName"> v-model="state.activeName">
<el-tab-pane closable v-for="dt in state.tabs.values()" :key="dt.key" :label="dt.key" <el-tab-pane closable v-for="dt in state.tabs.values()" :key="dt.key" :label="dt.key"
@@ -37,7 +53,7 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, reactive, ref, Ref } from 'vue'; import { onMounted, reactive, ref, Ref, toRefs } from 'vue';
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import { language as sqlLanguage } from 'monaco-editor/esm/vs/basic-languages/mysql/mysql.js'; import { language as sqlLanguage } from 'monaco-editor/esm/vs/basic-languages/mysql/mysql.js';
@@ -53,8 +69,10 @@ const instanceTreeRef = ref(null) as Ref;
const tabs: Map<string, TabInfo> = new Map(); const tabs: Map<string, TabInfo> = new Map();
const state = reactive({ const state = reactive({
dbId: null, // 当前选中操作的数据库实例 /**
dbType: '', * 当前操作的数据库实例
*/
nowDbInst: {} as DbInst,
db: '', // 当前操作的数据库 db: '', // 当前操作的数据库
activeName: 'Query', activeName: 'Query',
tabs, tabs,
@@ -66,6 +84,10 @@ const state = reactive({
}, },
}); });
const {
nowDbInst,
} = toRefs(state);
onMounted(() => { onMounted(() => {
self.completionItemProvider?.dispose() self.completionItemProvider?.dispose()
setHeight(); setHeight();
@@ -85,15 +107,13 @@ const setHeight = () => {
// 选择数据库实例 // 选择数据库实例
const changeInstance = (inst: any, fn?: Function) => { const changeInstance = (inst: any, fn?: Function) => {
state.dbId = inst.id
state.dbType = inst.type
fn && fn() fn && fn()
} }
// 选择数据库 // 选择数据库
const changeSchema = (inst: any, schema: string) => { const changeSchema = (inst: any, schema: string) => {
changeInstance(inst) state.nowDbInst = DbInst.getOrNewInst(inst);
state.db = schema state.db = schema;
} }
// 加载选中的表数据即新增表数据操作tab // 加载选中的表数据即新增表数据操作tab
@@ -113,7 +133,6 @@ const loadTableData = async (inst: any, schema: string, tableName: string) => {
tab = new TabInfo(); tab = new TabInfo();
tab.key = label; tab.key = label;
tab.dbId = inst.id; tab.dbId = inst.id;
tab.dbType = inst.type;
tab.db = schema; tab.db = schema;
tab.type = TabType.TableData; tab.type = TabType.TableData;
tab.params = { tab.params = {
@@ -124,8 +143,8 @@ const loadTableData = async (inst: any, schema: string, tableName: string) => {
// 新建查询panel // 新建查询panel
const addQueryTab = async (inst: any, db: string, sqlName: string = '') => { const addQueryTab = async (inst: any, db: string, sqlName: string = '') => {
if (!db) { if (!db || !inst.id) {
ElMessage.warning('请选择schema') ElMessage.warning('请选择数据库实例及对应的schema')
return return
} }
const dbId = inst.id; const dbId = inst.id;
@@ -150,7 +169,6 @@ const addQueryTab = async (inst: any, db: string, sqlName: string = '') => {
tab = new TabInfo(); tab = new TabInfo();
tab.key = label; tab.key = label;
tab.dbId = dbId; tab.dbId = dbId;
tab.dbType = inst.type;
tab.db = db; tab.db = db;
tab.type = TabType.Query; tab.type = TabType.Query;
tab.params = { tab.params = {
@@ -161,7 +179,7 @@ const addQueryTab = async (inst: any, db: string, sqlName: string = '') => {
registerSqlCompletionItemProvider(); registerSqlCompletionItemProvider();
} }
const remoteTab = (targetName: string) => { const onRemoveTab = (targetName: string) => {
let activeName = state.activeName; let activeName = state.activeName;
const tabNames = [...state.tabs.keys()] const tabNames = [...state.tabs.keys()]
for (let i = 0; i < tabNames.length; i++) { for (let i = 0; i < tabNames.length; i++) {
@@ -172,19 +190,22 @@ const remoteTab = (targetName: string) => {
const nextTab = tabNames[i + 1] || tabNames[i - 1]; const nextTab = tabNames[i + 1] || tabNames[i - 1];
if (nextTab) { if (nextTab) {
activeName = nextTab; activeName = nextTab;
} else {
activeName = '';
} }
state.tabs.delete(targetName); state.tabs.delete(targetName);
state.activeName = activeName; state.activeName = activeName;
break;
} }
}; };
/** const onTabChange = () => {
* 数据tab点击 if (!state.activeName) {
*/ state.nowDbInst = {} as DbInst;
const onDataTabClick = (tab: any) => { state.db = '';
state.activeName = tab.props.name; return;
}; }
state.nowDbInst = DbInst.getInst(state.tabs.get(state.activeName)?.dbId);
}
const onGenerateInsertSql = async (sql: string) => { const onGenerateInsertSql = async (sql: string) => {
state.genSqlDialog.sql = sql; state.genSqlDialog.sql = sql;
@@ -201,7 +222,7 @@ const reloadSqls = (dbId: number, db: string) => {
const deleteSqlScript = (ti: TabInfo) => { const deleteSqlScript = (ti: TabInfo) => {
instanceTreeRef.value.reloadSqls({ id: ti.dbId }, ti.db); instanceTreeRef.value.reloadSqls({ id: ti.dbId }, ti.db);
remoteTab(ti.key); onRemoveTab(ti.key);
} }
const registerSqlCompletionItemProvider = () => { const registerSqlCompletionItemProvider = () => {
@@ -214,8 +235,8 @@ const registerSqlCompletionItemProvider = () => {
if (!nowTab) { if (!nowTab) {
return; return;
} }
const { db, dbId, dbType } = nowTab; const { db, dbId } = nowTab;
const dbInst = DbInst.getInst(dbId, dbType); const dbInst = DbInst.getInst(dbId);
const { lineNumber, column } = position const { lineNumber, column } = position
const { startColumn, endColumn } = word const { startColumn, endColumn } = word
@@ -266,8 +287,8 @@ const registerSqlCompletionItemProvider = () => {
// 如果是.触发代码提示,则进行【 库.表名联想 】 或 【 表别名.表字段联想 】 // 如果是.触发代码提示,则进行【 库.表名联想 】 或 【 表别名.表字段联想 】
let str = lastToken.substring(0, lastToken.lastIndexOf('.')) let str = lastToken.substring(0, lastToken.lastIndexOf('.'))
// 库.表名联想 // 库.表名联想
if (dbs.filter((a:any)=>a.name === str)?.length > 0) { if (dbs.filter((a: any) => a.name === str)?.length > 0) {
let tables = await dbInst.loadTables(str) let tables = await dbInst.loadTables(str)
let suggestions: languages.CompletionItem[] = [] let suggestions: languages.CompletionItem[] = []
for (let item of tables) { for (let item of tables) {

View File

@@ -306,7 +306,7 @@ const getNowDb = () => {
} }
const getNowDbInst = () => { const getNowDbInst = () => {
return DbInst.getInst(state.dbId, state.dbType); return DbInst.getInst(state.dbId);
} }
defineExpose({ defineExpose({

View File

@@ -207,7 +207,7 @@ const loadSchemaTables = async (inst: any, schema: string) => {
state.loading[key] = true state.loading[key] = true
try { try {
let { id } = inst let { id } = inst
let tables = await DbInst.getInst(id, inst.type).loadTables(schema); let tables = await DbInst.getInst(id).loadTables(schema);
tables && tables.forEach((a: any) => a.show = true) tables && tables.forEach((a: any) => a.show = true)
state.tables[key] = tables; state.tables[key] = tables;
changeSchema(inst, schema); changeSchema(inst, schema);

View File

@@ -62,7 +62,7 @@
style="font-size: 12px">取消</span></el-link> style="font-size: 12px">取消</span></el-link>
</span> </span>
</el-row> </el-row>
<db-table ref="dbTableRef" :db-id="state.ti.dbId" :db-type="state.ti.dbType" :db="state.ti.db" <db-table ref="dbTableRef" :db-id="state.ti.dbId" :db="state.ti.db"
:data="execRes.data" :table="state.table" :column-names="execRes.tableColumn" :loading="loading" :data="execRes.data" :table="state.table" :column-names="execRes.tableColumn" :loading="loading"
height="250" empty-text="tips: select *开头的单表查询或点击表名默认查询的数据,可双击数据在线修改" height="250" empty-text="tips: select *开头的单表查询或点击表名默认查询的数据,可双击数据在线修改"
@selection-change="onDataSelectionChange" @change-updated-field="changeUpdatedField"></db-table> @selection-change="onDataSelectionChange" @change-updated-field="changeUpdatedField"></db-table>

View File

@@ -64,7 +64,7 @@
</el-col> </el-col>
</el-row> </el-row>
<db-table ref="dbTableRef" :db-id="state.ti.dbId" :db-type="state.ti.dbType" :db="state.ti.db" :data="datas" <db-table ref="dbTableRef" :db-id="state.ti.dbId" :db="state.ti.db" :data="datas"
:table="state.table" :column-names="columnNames" :loading="loading" :height="tableHeight" :table="state.table" :column-names="columnNames" :loading="loading" :height="tableHeight"
:show-column-tip="true" :sortable="'custom'" @sort-change="(sort: any) => onTableSortChange(sort)" :show-column-tip="true" :sortable="'custom'" @sort-change="(sort: any) => onTableSortChange(sort)"
@selection-change="onDataSelectionChange" @change-updated-field="changeUpdatedField"></db-table> @selection-change="onDataSelectionChange" @change-updated-field="changeUpdatedField"></db-table>

View File

@@ -5,11 +5,21 @@ import SqlExecBox from './component/SqlExecBox';
const dbInstCache: Map<number, DbInst> = new Map(); const dbInstCache: Map<number, DbInst> = new Map();
export class DbInst { export class DbInst {
/**
* 标签路径
*/
tagPath: string
/** /**
* 实例id * 实例id
*/ */
id: number id: number
/**
* 实例名
*/
name: string
/** /**
* 数据库类型, mysql postgres * 数据库类型, mysql postgres
*/ */
@@ -183,26 +193,45 @@ export class DbInst {
}); });
}; };
/**
* 获取或新建dbInst如果缓存中不存在则新建否则直接返回
* @param inst 数据库实例,后端返回的列表接口中的信息
* @returns DbInst
*/
static getOrNewInst(inst: any) {
if (!inst) {
throw new Error('inst不能为空')
}
let dbInst = dbInstCache.get(inst.id);
if (dbInst) {
return dbInst;
}
console.info(`new dbInst: ${inst.id}, tagPath: ${inst.tagPath}`);
dbInst = new DbInst();
dbInst.tagPath = inst.tagPath;
dbInst.id = inst.id;
dbInst.name = inst.name;
dbInst.type = inst.type;
dbInstCache.set(dbInst.id, dbInst);
return dbInst;
}
/** /**
* 获取数据库实例id若不存在则新建一个并缓存 * 获取数据库实例id若不存在则新建一个并缓存
* @param dbId 数据库实例id * @param dbId 数据库实例id
* @param dbType 第一次获取时为必传项,即第一次创建时 * @param dbType 第一次获取时为必传项,即第一次创建时
* @returns 数据库实例 * @returns 数据库实例
*/ */
static getInst(dbId: number, dbType?: string): DbInst { static getInst(dbId?: number): DbInst {
if (!dbId) {
throw new Error('dbId不能为空');
}
let dbInst = dbInstCache.get(dbId); let dbInst = dbInstCache.get(dbId);
if (dbInst) { if (dbInst) {
return dbInst; return dbInst;
} }
if (!dbType) { throw new Error('dbInst不存在! 请在合适调用点使用DbInst.newInst()新建该实例');
throw new Error('DbInst不存在, dbType为必传项')
}
console.log(`new dbInst -> dbId: ${dbId}, dbType: ${dbType}`);
dbInst = new DbInst();
dbInst.id = dbId;
dbInst.type = dbType;
dbInstCache.set(dbInst.id, dbInst);
return dbInst;
} }
/** /**
@@ -387,11 +416,6 @@ export class TabInfo {
*/ */
dbId: number dbId: number
/**
* 数据库类型
*/
dbType: string
/** /**
* 库名 * 库名
*/ */
@@ -408,10 +432,7 @@ export class TabInfo {
params: any params: any
getNowDbInst() { getNowDbInst() {
if (!this.dbType) { return DbInst.getInst(this.dbId);
throw new Error('dbType不能为空')
}
return DbInst.getInst(this.dbId, this.dbType);
} }
getNowDb() { getNowDb() {

View File

@@ -12,14 +12,16 @@
v-model="state.activeName"> v-model="state.activeName">
<el-tab-pane closable v-for="dt in state.dataTabs" :key="dt.key" :label="dt.label" <el-tab-pane closable v-for="dt in state.dataTabs" :key="dt.key" :label="dt.label"
:name="dt.key"> :name="dt.key">
<el-row class="mt5 mb5"> <el-row>
<el-col :span="2"> <el-col :span="2">
<el-link @click="findCommand(state.activeName)" icon="refresh" :underline="false" <div>
class=""> <el-link @click="findCommand(state.activeName)" icon="refresh"
</el-link> :underline="false" class="">
<el-link @click="showInsertDocDialog" class="" type="primary" icon="plus" </el-link>
:underline="false"> <el-link @click="showInsertDocDialog" class="ml5" type="primary" icon="plus"
</el-link> :underline="false">
</el-link>
</div>
</el-col> </el-col>
<el-col :span="22"> <el-col :span="22">
<el-input ref="findParamInputRef" v-model="dt.findParamStr" placeholder="点击输入相应查询条件" <el-input ref="findParamInputRef" v-model="dt.findParamStr" placeholder="点击输入相应查询条件"

View File

@@ -4,7 +4,7 @@ import "fmt"
const ( const (
AppName = "mayfly-go" AppName = "mayfly-go"
Version = "v1.3.1" Version = "v1.4.0"
) )
func GetAppInfo() string { func GetAppInfo() string {