mirror of
https://gitee.com/dromara/mayfly-go
synced 2026-01-12 00:55:48 +08:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aa6ad39b83 |
@@ -11,14 +11,14 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@element-plus/icons-vue": "^2.3.2",
|
||||
"@logicflow/core": "^2.1.4",
|
||||
"@logicflow/extension": "^2.1.6",
|
||||
"@logicflow/core": "^2.1.7",
|
||||
"@logicflow/extension": "^2.1.9",
|
||||
"@vueuse/core": "^14.1.0",
|
||||
"@xterm/addon-fit": "^0.11.0",
|
||||
"@xterm/addon-search": "^0.16.0",
|
||||
"@xterm/addon-web-links": "^0.12.0",
|
||||
"@xterm/xterm": "^6.0.0",
|
||||
"asciinema-player": "^3.13.5",
|
||||
"asciinema-player": "^3.14.0",
|
||||
"axios": "^1.6.2",
|
||||
"clipboard": "^2.0.11",
|
||||
"crypto-js": "^4.2.0",
|
||||
@@ -37,8 +37,8 @@
|
||||
"sql-formatter": "^15.6.12",
|
||||
"trzsz": "^1.1.5",
|
||||
"uuid": "^13.0.0",
|
||||
"vue": "^v3.6.0-beta.1",
|
||||
"vue-i18n": "^11.2.7",
|
||||
"vue": "^v3.6.0-beta.2",
|
||||
"vue-i18n": "^11.2.8",
|
||||
"vue-router": "^4.6.4",
|
||||
"vuedraggable": "^4.1.0",
|
||||
"xlsx": "^0.18.5"
|
||||
|
||||
@@ -15,7 +15,7 @@ const config = {
|
||||
baseWsUrl: `${(window as any).globalConfig.BaseWsUrl || `${location.protocol == 'https:' ? 'wss:' : 'ws:'}//${getBaseApiUrl()}`}/api`,
|
||||
|
||||
// 系统版本
|
||||
version: 'v1.10.4',
|
||||
version: 'v1.10.5',
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
||||
@@ -49,8 +49,9 @@ export default {
|
||||
|
||||
dbms: 'DBMS',
|
||||
dbDataOp: 'Data Operation',
|
||||
dbDataOpBase: 'Base Permission',
|
||||
dbDataOpSqlScriptRun: 'SQL Script Run',
|
||||
dbDataOpBase: 'DB-Base Permission',
|
||||
dbDataOpSqlScriptRun: 'DB-SQL Script Run',
|
||||
dbDataExport: 'DB-Data Export',
|
||||
dbInstance: 'DB Instance',
|
||||
dbInstanceBase: 'Base Permission',
|
||||
dbInstanceSave: 'Save Instance',
|
||||
@@ -77,21 +78,20 @@ export default {
|
||||
dbTransferFileRun: 'Transfer File-Run',
|
||||
|
||||
redis: 'Redis',
|
||||
redisDataOp: 'Data Operation',
|
||||
redisDataOpBase: 'Base Permission',
|
||||
redisDataOpSave: 'Save Data',
|
||||
redisDataOpDelete: 'Delete Data',
|
||||
redisDataOp: 'Redis - Data Operation',
|
||||
redisDataOpBase: 'Redis - Base Permission',
|
||||
redisDataOpSave: 'Redis - Save Data',
|
||||
redisDataOpDelete: 'Redis - Delete Data',
|
||||
redisManage: 'Redis Manage',
|
||||
redisManageBase: 'Base Permission',
|
||||
redisManageBase: 'Redis - Base Permission',
|
||||
|
||||
mongo: 'Mongo',
|
||||
mongoDataOp: 'Data Operation',
|
||||
mongoDataOpBase: 'Base Permission',
|
||||
mongoDataOpSave: 'Save Data',
|
||||
mongoDataOpDelete: 'Delete Data',
|
||||
mongoDataOp: 'Mongo - Data Operation',
|
||||
mongoDataOpBase: 'Mongo - Base Permission',
|
||||
mongoDataOpSave: 'Mongo - Save Data',
|
||||
mongoDataOpDelete: 'Mongo - Delete Data',
|
||||
mongoManage: 'Mongo Manage',
|
||||
mongoManageBase: 'Base Permission',
|
||||
|
||||
mongoManageBase: 'Mongo - Base Permission',
|
||||
containerManageBase: 'Container Manage - Base Permission',
|
||||
|
||||
flow: 'Flow',
|
||||
|
||||
@@ -48,16 +48,17 @@ export default {
|
||||
machineSecurityCmdDelete: '机器-命令配置-删除',
|
||||
|
||||
dbms: 'DBMS',
|
||||
dbDataOp: '数据操作',
|
||||
dbDataOpBase: 'Db-数据操作-基本权限',
|
||||
dbDataOpSqlScriptRun: 'Db-SQL脚本执行',
|
||||
dbDataOp: 'DB-数据操作',
|
||||
dbDataOpBase: 'DB-数据操作-基本权限',
|
||||
dbDataOpSqlScriptRun: 'DB-SQL脚本执行',
|
||||
dbDataExport: 'DB-数据导出',
|
||||
dbInstance: '数据库实例',
|
||||
dbInstanceBase: 'Db-基本权限',
|
||||
dbInstanceSave: 'Db-保存实例',
|
||||
dbInstanceDelete: 'Db-删除实例',
|
||||
dbInstanceBase: 'DB-基本权限',
|
||||
dbInstanceSave: 'DB-保存实例',
|
||||
dbInstanceDelete: 'DB-删除实例',
|
||||
dbBase: '数据库基本权限',
|
||||
dbSave: 'Db-保存数据库',
|
||||
dbDelete: 'Db-删除数据库',
|
||||
dbSave: 'DB-保存数据库',
|
||||
dbDelete: 'DB-删除数据库',
|
||||
dbDataSync: '数据同步',
|
||||
dbDataSyncBase: '基本权限',
|
||||
dbDataSyncSave: '保存同步',
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<div>
|
||||
<div class="card !p-1 flex items-center justify-between">
|
||||
<div class="card p-1! flex items-center justify-between">
|
||||
<div>
|
||||
<el-link @click="onRunSql()" underline="never" class="ml-3.5" icon="VideoPlay"> </el-link>
|
||||
<el-divider direction="vertical" border-style="dashed" />
|
||||
@@ -39,32 +39,32 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-splitter style="height: calc(100vh - 200px)" layout="vertical" @resize-end="onResizeTableHeight">
|
||||
<el-splitter style="height: calc(100vh - 215px)" layout="vertical" @resize-end="onResizeTableHeight">
|
||||
<el-splitter-panel :size="state.editorSize" max="80%">
|
||||
<MonacoEditor ref="monacoEditorRef" class="mt-1" v-model="state.sql" language="sql" height="100%" :id="'MonacoTextarea-' + getKey()" />
|
||||
</el-splitter-panel>
|
||||
|
||||
<el-splitter-panel>
|
||||
<div class="sql-exec-res !h-full">
|
||||
<div class="sql-exec-res h-full!">
|
||||
<el-tabs
|
||||
class="!h-full !w-full"
|
||||
class="h-full! w-full!"
|
||||
v-if="state.execResTabs.length > 0"
|
||||
@tab-remove="onRemoveTab"
|
||||
@tab-change="active"
|
||||
v-model="state.activeTab"
|
||||
>
|
||||
<el-tab-pane class="!h-full" closable v-for="dt in state.execResTabs" :label="dt.id" :name="dt.id" :key="dt.id">
|
||||
<el-tab-pane class="h-full!" closable v-for="dt in state.execResTabs" :label="dt.id" :name="dt.id" :key="dt.id">
|
||||
<template #label>
|
||||
<el-popover :show-after="1000" placement="top-start" :title="$t('db.execInfo')" trigger="hover" :width="300">
|
||||
<template #reference>
|
||||
<div>
|
||||
<span>
|
||||
<span v-if="dt.loading">
|
||||
<SvgIcon class="!mb-0.5 is-loading" name="Loading" color="var(--el-color-primary)" />
|
||||
<SvgIcon class="mb-0.5! is-loading" name="Loading" color="var(--el-color-primary)" />
|
||||
</span>
|
||||
<span v-else>
|
||||
<SvgIcon class="!mb-0.5" v-if="!dt.errorMsg" name="CircleCheck" color="var(--el-color-success)" />
|
||||
<SvgIcon class="!mb-0.5" v-if="dt.errorMsg" name="CircleClose" color="var(--el-color-error)" />
|
||||
<SvgIcon class="mb-0.5!" v-if="!dt.errorMsg" name="CircleCheck" color="var(--el-color-success)" />
|
||||
<SvgIcon class="mb-0.5!" v-if="dt.errorMsg" name="CircleClose" color="var(--el-color-error)" />
|
||||
</span>
|
||||
</span>
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
<span v-if="column.dataTypeSubscript === 'icon-clock'">
|
||||
<SvgIcon :size="9" name="Clock" style="cursor: unset" />
|
||||
</span>
|
||||
<span class="!text-[8px]" v-else>{{ column.dataTypeSubscript }}</span>
|
||||
<span class="text-[8px]!" v-else>{{ column.dataTypeSubscript }}</span>
|
||||
</div>
|
||||
|
||||
<div v-if="showColumnTip">
|
||||
@@ -53,7 +53,7 @@
|
||||
<div
|
||||
v-if="dbConfig.showColumnComment"
|
||||
style="color: var(--el-color-info-light-3)"
|
||||
class="!text-[10px] el-text el-text--small is-truncated"
|
||||
class="text-[10px]! el-text el-text--small is-truncated"
|
||||
>
|
||||
{{ column.columnComment }}
|
||||
</div>
|
||||
@@ -160,7 +160,7 @@
|
||||
<SvgIcon class="is-loading" name="loading" color="var(--el-color-primary)" :size="28" />
|
||||
<el-text class="ml-1" tag="b">{{ $t('db.execTime') }} - {{ state.execTime.toFixed(1) }}s</el-text>
|
||||
</div>
|
||||
<div v-if="loading && abortFn" class="!mt-2">
|
||||
<div v-if="loading && abortFn" class="mt-2!">
|
||||
<el-button @click="cancelLoading" type="info" size="small" plain>{{ $t('common.cancel') }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -303,16 +303,23 @@ const cmDataGenInsertSql = new ContextmenuItem('genInsertSql', 'Insert SQL')
|
||||
|
||||
const cmDataGenJson = new ContextmenuItem('genJson', 'db.genJson').withIcon('tickets').withOnClick(() => onGenerateJson());
|
||||
|
||||
const cmDataExportCsv = new ContextmenuItem('exportCsv', 'db.exportCsv').withIcon('document').withOnClick(() => onExportCsv());
|
||||
const cmDataExportCsv = new ContextmenuItem('exportCsv', 'db.exportCsv')
|
||||
.withIcon('document')
|
||||
.withOnClick(() => onExportCsv())
|
||||
.withPermission('db:data:export');
|
||||
|
||||
const cmDataExportExcel = new ContextmenuItem('exportExcel', 'db.exportExcel').withIcon('document').withOnClick(() => onExportExcel());
|
||||
const cmDataExportExcel = new ContextmenuItem('exportExcel', 'db.exportExcel')
|
||||
.withIcon('document')
|
||||
.withOnClick(() => onExportExcel())
|
||||
.withPermission('db:data:export');
|
||||
|
||||
const cmDataExportSql = new ContextmenuItem('exportSql', 'db.exportSql')
|
||||
.withIcon('document')
|
||||
.withOnClick(() => onExportSql())
|
||||
.withHideFunc(() => {
|
||||
return state.table == '';
|
||||
});
|
||||
})
|
||||
.withPermission('db:data:export');
|
||||
|
||||
class NowUpdateCell {
|
||||
rowIndex: number;
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
<el-row class="mb-1">
|
||||
<el-popover v-model:visible="state.dumpInfo.visible" trigger="click" :width="470" placement="right">
|
||||
<template #reference>
|
||||
<el-button :disabled="state.dumpInfo.tables?.length == 0" class="ml-1" type="success" size="small">{{ $t('db.dump') }}</el-button>
|
||||
<el-button v-auth="'db:data:export'" :disabled="state.dumpInfo.tables?.length == 0" class="ml-1" type="success" size="small">
|
||||
{{ $t('db.dump') }}
|
||||
</el-button>
|
||||
</template>
|
||||
<el-form-item :label="$t('db.exportContent')">
|
||||
<el-radio-group v-model="dumpInfo.type">
|
||||
|
||||
@@ -86,13 +86,13 @@
|
||||
@tab-remove="onRemoveTab"
|
||||
@tab-change="onTabChange"
|
||||
v-model="state.activeName"
|
||||
class="!h-full w-full"
|
||||
class="h-full! w-full"
|
||||
>
|
||||
<el-tab-pane class="!h-full" closable v-for="dt in state.tabs.values()" :label="dt.label" :name="dt.key" :key="dt.key">
|
||||
<el-tab-pane class="h-full!" closable v-for="dt in state.tabs.values()" :label="dt.label" :name="dt.key" :key="dt.key">
|
||||
<template #label>
|
||||
<el-popover :show-after="1000" placement="bottom-start" trigger="hover" :width="250">
|
||||
<template #reference>
|
||||
<span @contextmenu.prevent="onTabContextmenu(dt, $event)" class="!text-[12px]">{{ dt.label }}</span>
|
||||
<span @contextmenu.prevent="onTabContextmenu(dt, $event)" class="text-[12px]!">{{ dt.label }}</span>
|
||||
</template>
|
||||
<template #default>
|
||||
<el-descriptions :column="1" size="small">
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
<template>
|
||||
<div class="file-manage">
|
||||
<el-dialog :title="$t('machine.process')" v-model="dialogVisible" :destroy-on-close="true" :show-close="true" :before-close="handleClose" width="65%">
|
||||
<div class="card !p-1">
|
||||
<div class="card p-1!">
|
||||
<el-row>
|
||||
<el-col :span="4">
|
||||
<el-input size="small" :placeholder="$t('machine.processName')" v-model="params.name" plain clearable></el-input>
|
||||
</el-col>
|
||||
<el-col :span="4" class="ml-1">
|
||||
<el-select class="!w-full" @change="getProcess" size="small" v-model="params.sortType" :placeholder="$t('machine.selectSortType')">
|
||||
<el-select @change="getProcess" size="small" v-model="params.sortType" :placeholder="$t('machine.selectSortType')">
|
||||
<el-option key="cpu" :label="$t('machine.cpuDesc')" value="1"> </el-option>
|
||||
<el-option key="cpu" :label="$t('machine.memDesc')" value="2"> </el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="4" class="ml-1">
|
||||
<el-select class="!w-full" @change="getProcess" size="small" v-model="params.count" :placeholder="$t('machine.selectProcessNum')">
|
||||
<el-select @change="getProcess" size="small" v-model="params.count" :placeholder="$t('machine.selectProcessNum')">
|
||||
<el-option key="10" label="10" value="10"> </el-option>
|
||||
<el-option key="15" label="15" value="15"> </el-option>
|
||||
<el-option key="20" label="20" value="20"> </el-option>
|
||||
@@ -26,7 +26,7 @@
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
<el-table :data="processList" size="small" style="width: 100%">
|
||||
<el-table :data="processList" size="small" :height="500">
|
||||
<el-table-column prop="user" label="USER" :min-width="50"> </el-table-column>
|
||||
<el-table-column prop="pid" label="PID" :min-width="50" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="cpu" label="%CPU" :min-width="40"> </el-table-column>
|
||||
|
||||
@@ -741,7 +741,11 @@ function getParentPath(filePath: string) {
|
||||
|
||||
const deleteFile = async (files: any) => {
|
||||
try {
|
||||
await useI18nDeleteConfirm(files.map((x: any) => `[${x.path}]`).join('\n'));
|
||||
let confirmMsg = files.map((x: any) => `[${x.path}]`).join('\n');
|
||||
if (confirmMsg.length > 400) {
|
||||
confirmMsg = confirmMsg.substring(0, 400) + '...';
|
||||
}
|
||||
await useI18nDeleteConfirm(confirmMsg);
|
||||
state.loading = true;
|
||||
await machineApi.rmFile.request({
|
||||
fileId: props.fileId,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="h-full machine-terminal-tabs">
|
||||
<el-tabs v-if="state.tabs.size > 0" type="card" @tab-remove="onRemoveTab" v-model="state.activeTermName" class="!h-full w-full">
|
||||
<el-tab-pane class="!h-full flex flex-col" closable v-for="dt in state.tabs.values()" :label="dt.label" :name="dt.key" :key="dt.key">
|
||||
<el-tab-pane class="h-full! flex flex-col" closable v-for="dt in state.tabs.values()" :label="dt.label" :name="dt.key" :key="dt.key">
|
||||
<template #label>
|
||||
<el-popconfirm @confirm="handleReconnect(dt, true)" :title="$t('machine.reConnTips')">
|
||||
<template #reference>
|
||||
|
||||
@@ -49,7 +49,7 @@ func (d *DbConn) Ping() error {
|
||||
stats := d.db.Stats()
|
||||
logx.Debugf("[%s] db stats -> open: %d, idle: %d, inUse: %d, maxOpen: %d", d.Info.Name, stats.OpenConnections, stats.Idle, stats.InUse, stats.MaxOpenConnections)
|
||||
if stats.OpenConnections == 0 {
|
||||
return errors.New("no open connections")
|
||||
logx.Info("db stats: no open connections")
|
||||
}
|
||||
|
||||
return d.db.Ping()
|
||||
|
||||
@@ -4,7 +4,7 @@ import "fmt"
|
||||
|
||||
const (
|
||||
AppName = "mayfly-go"
|
||||
Version = "v1.10.4"
|
||||
Version = "v1.10.5"
|
||||
)
|
||||
|
||||
func GetAppInfo() string {
|
||||
|
||||
@@ -47,10 +47,10 @@ func (r *RedisConn) Ping() error {
|
||||
}
|
||||
|
||||
stats := r.Cli.PoolStats()
|
||||
if stats.TotalConns == 0 {
|
||||
return fmt.Errorf("no open connections")
|
||||
}
|
||||
logx.Debugf("[%s] redis stats -> open: %d, idle: %d", r.Info.Name, stats.TotalConns, stats.IdleConns)
|
||||
if stats.TotalConns == 0 {
|
||||
logx.Info("redis stats: no open connections")
|
||||
}
|
||||
|
||||
cmd := r.Cli.Ping(context.Background())
|
||||
if cmd == nil {
|
||||
|
||||
@@ -352,23 +352,18 @@ func V1_10_4() []*gormigrate.Migration {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func V1_10_5() []*gormigrate.Migration {
|
||||
return []*gormigrate.Migration{
|
||||
{
|
||||
ID: "20251207-v1.10.4.1",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
config := &sysentity.Config{}
|
||||
// 查询是否存在该配置
|
||||
result := tx.Model(config).Where("key = ?", "AiModelConfig").First(config)
|
||||
result := tx.Model(config).Where("`key` = ?", "AiModelConfig").First(config)
|
||||
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
|
||||
// 如果不存在,则创建默认配置
|
||||
now := time.Now()
|
||||
aiConfig := &sysentity.Config{
|
||||
Key: "AiModelConfig",
|
||||
Name: "system.sysconf.aiModelConf'",
|
||||
Name: "system.sysconf.aiModelConf",
|
||||
Value: "{}", // 默认空JSON值
|
||||
Params: `[{"model":"modelType","name":"system.sysconf.aiModelType","placeholder":"system.sysconf.aiModelTypePlaceholder","options":"openai"},{"model":"model","name":"system.sysconf.aiModel","placeholder":"system.sysconf.aiModelPlaceholder"},{"model":"baseUrl","name":"system.sysconf.aiBaseUrl","placeholder":"system.sysconf.aiBaseUrlPlaceholder"},{"model":"apiKey","name":"ApiKey","placeholder":"api key"}]`,
|
||||
Permission: "all",
|
||||
@@ -391,3 +386,35 @@ func V1_10_5() []*gormigrate.Migration {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func V1_10_5() []*gormigrate.Migration {
|
||||
return []*gormigrate.Migration{
|
||||
{
|
||||
ID: "20260107-v1.10.5",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
resource := &sysentity.Resource{}
|
||||
// 查询是否存在该配置
|
||||
result := tx.Model(resource).Where("code = ?", "db:data:export").First(resource)
|
||||
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
|
||||
// 如果不存在,则创建默认配置
|
||||
resource = &sysentity.Resource{
|
||||
Code: "db:data:export",
|
||||
Name: "menu.dbDataExport",
|
||||
Type: sysentity.ResourceTypePermission,
|
||||
UiPath: "ocdrUNaa/fo59olyi/",
|
||||
Pid: 1756122788,
|
||||
Status: sysentity.ResourceStatusEnable,
|
||||
}
|
||||
resource.FillBaseInfo(model.IdGenTypeTimestamp, model.SysAccount)
|
||||
resource.Id = 1767788697
|
||||
return tx.Create(resource).Error
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
Rollback: func(tx *gorm.DB) error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user