mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-11-03 16:00:25 +08:00
refactor: 列表操作按钮调整
This commit is contained in:
@@ -56,10 +56,10 @@
|
|||||||
{{ `${data.host}:${data.port}` }}
|
{{ `${data.host}:${data.port}` }}
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #database="{ data }">
|
<template #action="{ data }">
|
||||||
<el-popover placement="right" trigger="click" :width="300">
|
<el-popover placement="left" trigger="click" :width="300">
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<el-link type="primary" :underline="false" plain @click="selectDb(data.dbs)">查看 </el-link>
|
<el-button type="primary" @click="selectDb(data.dbs)" link>库操作</el-button>
|
||||||
</template>
|
</template>
|
||||||
<el-input v-model="filterDb.param" @keyup="filterSchema" class="w-50 m-2" placeholder="搜索" size="small">
|
<el-input v-model="filterDb.param" @keyup="filterSchema" class="w-50 m-2" placeholder="搜索" size="small">
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
@@ -80,16 +80,28 @@
|
|||||||
</el-link>
|
</el-link>
|
||||||
</div>
|
</div>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</template>
|
|
||||||
|
|
||||||
<template #more="{ data }">
|
<el-divider direction="vertical" border-style="dashed" />
|
||||||
<el-button @click="showInfo(data)" link>详情</el-button>
|
<el-button type="primary" @click="onShowSqlExec(data)" link>SQL记录</el-button>
|
||||||
<el-button class="ml5" type="primary" @click="onShowSqlExec(data)" link>SQL执行记录</el-button>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template #action="{ data }">
|
<el-divider direction="vertical" border-style="dashed" />
|
||||||
<el-button v-if="actionBtns[perms.saveDb]" @click="editDb(data)" type="primary" link>编辑</el-button>
|
<el-dropdown @command="handleMoreActionCommand">
|
||||||
<el-button v-if="data.type == 'mysql'" class="ml5" type="primary" @click="onDumpDbs(data)" link>导出</el-button>
|
<span class="el-dropdown-link-more">
|
||||||
|
更多
|
||||||
|
<el-icon class="el-icon--right">
|
||||||
|
<arrow-down />
|
||||||
|
</el-icon>
|
||||||
|
</span>
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu>
|
||||||
|
<el-dropdown-item :command="{ type: 'detail', data }"> 详情 </el-dropdown-item>
|
||||||
|
|
||||||
|
<el-dropdown-item :command="{ type: 'edit', data }" v-if="actionBtns[perms.saveDb]"> 编辑 </el-dropdown-item>
|
||||||
|
|
||||||
|
<el-dropdown-item :command="{ type: 'dumpDb', data }" v-if="data.type == 'mysql'"> 导出 </el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
</template>
|
</template>
|
||||||
</page-table>
|
</page-table>
|
||||||
|
|
||||||
@@ -204,14 +216,12 @@ const columns = ref([
|
|||||||
TableColumn.new('host', 'ip:port').isSlot().setAddWidth(40),
|
TableColumn.new('host', 'ip:port').isSlot().setAddWidth(40),
|
||||||
TableColumn.new('username', 'username'),
|
TableColumn.new('username', 'username'),
|
||||||
TableColumn.new('name', '名称'),
|
TableColumn.new('name', '名称'),
|
||||||
TableColumn.new('database', '数据库').isSlot().setMinWidth(70),
|
|
||||||
TableColumn.new('remark', '备注'),
|
TableColumn.new('remark', '备注'),
|
||||||
TableColumn.new('more', '更多').isSlot().setMinWidth(180).fixedRight(),
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// 该用户拥有的的操作列按钮权限
|
// 该用户拥有的的操作列按钮权限
|
||||||
const actionBtns = hasPerms([perms.base, perms.saveDb]);
|
const actionBtns = hasPerms([perms.base, perms.saveDb]);
|
||||||
const actionColumn = TableColumn.new('action', '操作').isSlot().setMinWidth(150).fixedRight().alignCenter();
|
const actionColumn = TableColumn.new('action', '操作').isSlot().setMinWidth(220).fixedRight().alignCenter();
|
||||||
|
|
||||||
const pageTableRef: any = ref(null);
|
const pageTableRef: any = ref(null);
|
||||||
|
|
||||||
@@ -338,6 +348,24 @@ const getInstances = async (instanceName = '') => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleMoreActionCommand = (commond: any) => {
|
||||||
|
const data = commond.data;
|
||||||
|
const type = commond.type;
|
||||||
|
switch (type) {
|
||||||
|
case 'detail': {
|
||||||
|
showInfo(data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case 'edit': {
|
||||||
|
editDb(data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case 'dumpDb': {
|
||||||
|
onDumpDbs(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const editDb = async (data: any) => {
|
const editDb = async (data: any) => {
|
||||||
if (!data) {
|
if (!data) {
|
||||||
state.dbEditDialog.data = null;
|
state.dbEditDialog.data = null;
|
||||||
@@ -452,4 +480,12 @@ const filterSchema = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss"></style>
|
<style lang="scss">
|
||||||
|
.el-dropdown-link-more {
|
||||||
|
cursor: pointer;
|
||||||
|
color: var(--el-color-primary);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 6px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -40,7 +40,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item prop="remark" label="备注">
|
<el-form-item prop="remark" label="备注">
|
||||||
<el-input v-model.trim="form.remark" auto-complete="off" type="textarea"></el-input>
|
<el-input v-model="form.remark" auto-complete="off" type="textarea"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
|
|||||||
@@ -20,11 +20,8 @@
|
|||||||
>
|
>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #more="{ data }">
|
|
||||||
<el-button @click="showInfo(data)" link>详情</el-button>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template #action="{ data }">
|
<template #action="{ data }">
|
||||||
|
<el-button @click="showInfo(data)" link>详情</el-button>
|
||||||
<el-button v-if="actionBtns[perms.saveInstance]" @click="editInstance(data)" type="primary" link>编辑</el-button>
|
<el-button v-if="actionBtns[perms.saveInstance]" @click="editInstance(data)" type="primary" link>编辑</el-button>
|
||||||
</template>
|
</template>
|
||||||
</page-table>
|
</page-table>
|
||||||
@@ -81,11 +78,11 @@ const queryConfig = [TableQuery.text('name', '名称')];
|
|||||||
|
|
||||||
const columns = ref([
|
const columns = ref([
|
||||||
TableColumn.new('name', '名称'),
|
TableColumn.new('name', '名称'),
|
||||||
TableColumn.new('host', 'host:port').setFormatFunc((data: any, _prop: string) => `${data.host}:${data.port}`),
|
|
||||||
TableColumn.new('type', '类型'),
|
TableColumn.new('type', '类型'),
|
||||||
|
TableColumn.new('host', 'host:port').setFormatFunc((data: any) => `${data.host}:${data.port}`),
|
||||||
TableColumn.new('username', '用户名'),
|
TableColumn.new('username', '用户名'),
|
||||||
|
TableColumn.new('params', '连接参数'),
|
||||||
TableColumn.new('remark', '备注'),
|
TableColumn.new('remark', '备注'),
|
||||||
TableColumn.new('more', '更多').isSlot().setMinWidth(50).fixedRight(),
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// 该用户拥有的的操作列按钮权限
|
// 该用户拥有的的操作列按钮权限
|
||||||
@@ -173,7 +170,9 @@ const deleteInstance = async () => {
|
|||||||
await dbApi.deleteInstance.request({ id: state.selectionData.map((x: any) => x.id).join(',') });
|
await dbApi.deleteInstance.request({ id: state.selectionData.map((x: any) => x.id).join(',') });
|
||||||
ElMessage.success('删除成功');
|
ElMessage.success('删除成功');
|
||||||
search();
|
search();
|
||||||
} catch (err) {}
|
} catch (err) {
|
||||||
|
//
|
||||||
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss"></style>
|
<style lang="scss"></style>
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ const columns = ref([
|
|||||||
TableColumn.new('uri', '连接uri'),
|
TableColumn.new('uri', '连接uri'),
|
||||||
TableColumn.new('createTime', '创建时间').isTime(),
|
TableColumn.new('createTime', '创建时间').isTime(),
|
||||||
TableColumn.new('creator', '创建人'),
|
TableColumn.new('creator', '创建人'),
|
||||||
TableColumn.new('action', '操作').isSlot().setMinWidth(145).fixedRight().alignCenter(),
|
TableColumn.new('action', '操作').isSlot().setMinWidth(170).fixedRight().alignCenter(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
@@ -126,7 +126,9 @@ const deleteMongo = async () => {
|
|||||||
await mongoApi.deleteMongo.request({ id: state.selectionData.map((x: any) => x.id).join(',') });
|
await mongoApi.deleteMongo.request({ id: state.selectionData.map((x: any) => x.id).join(',') });
|
||||||
ElMessage.success('删除成功');
|
ElMessage.success('删除成功');
|
||||||
search();
|
search();
|
||||||
} catch (err) {}
|
} catch (err) {
|
||||||
|
//
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const search = async () => {
|
const search = async () => {
|
||||||
|
|||||||
@@ -31,14 +31,11 @@
|
|||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #more="{ data }">
|
<template #action="{ data }">
|
||||||
<el-button @click="showDetail(data)" link>详情</el-button>
|
|
||||||
|
|
||||||
<el-button v-if="data.mode === 'standalone' || data.mode === 'sentinel'" type="primary" @click="showInfoDialog(data)" link>单机信息</el-button>
|
<el-button v-if="data.mode === 'standalone' || data.mode === 'sentinel'" type="primary" @click="showInfoDialog(data)" link>单机信息</el-button>
|
||||||
<el-button @click="onShowClusterInfo(data)" v-if="data.mode === 'cluster'" type="primary" link>集群信息</el-button>
|
<el-button @click="onShowClusterInfo(data)" v-if="data.mode === 'cluster'" type="primary" link>集群信息</el-button>
|
||||||
</template>
|
|
||||||
|
|
||||||
<template #action="{ data }">
|
<el-button @click="showDetail(data)" link>详情</el-button>
|
||||||
<el-button type="primary" link @click="editRedis(data)">编辑</el-button>
|
<el-button type="primary" link @click="editRedis(data)">编辑</el-button>
|
||||||
</template>
|
</template>
|
||||||
</page-table>
|
</page-table>
|
||||||
@@ -183,8 +180,7 @@ const columns = ref([
|
|||||||
TableColumn.new('host', 'host:port'),
|
TableColumn.new('host', 'host:port'),
|
||||||
TableColumn.new('mode', 'mode'),
|
TableColumn.new('mode', 'mode'),
|
||||||
TableColumn.new('remark', '备注'),
|
TableColumn.new('remark', '备注'),
|
||||||
TableColumn.new('more', '更多').isSlot().setMinWidth(155).fixedRight(),
|
TableColumn.new('action', '操作').isSlot().setMinWidth(200).fixedRight().alignCenter(),
|
||||||
TableColumn.new('action', '操作').isSlot().setMinWidth(65).fixedRight().alignCenter(),
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
@@ -246,7 +242,9 @@ const deleteRedis = async () => {
|
|||||||
await redisApi.delRedis.request({ id: state.selectionData.map((x: any) => x.id).join(',') });
|
await redisApi.delRedis.request({ id: state.selectionData.map((x: any) => x.id).join(',') });
|
||||||
ElMessage.success('删除成功');
|
ElMessage.success('删除成功');
|
||||||
search();
|
search();
|
||||||
} catch (err) {}
|
} catch (err) {
|
||||||
|
//
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const showInfoDialog = async (redis: any) => {
|
const showInfoDialog = async (redis: any) => {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ require (
|
|||||||
github.com/go-playground/universal-translator v0.18.1
|
github.com/go-playground/universal-translator v0.18.1
|
||||||
github.com/go-playground/validator/v10 v10.14.0
|
github.com/go-playground/validator/v10 v10.14.0
|
||||||
github.com/go-sql-driver/mysql v1.7.1
|
github.com/go-sql-driver/mysql v1.7.1
|
||||||
github.com/golang-jwt/jwt/v5 v5.0.0
|
github.com/golang-jwt/jwt/v5 v5.1.0
|
||||||
github.com/gorilla/websocket v1.5.0
|
github.com/gorilla/websocket v1.5.0
|
||||||
github.com/kanzihuang/vitess/go/vt/sqlparser v0.0.0-20231018071450-ac8d9f0167e9
|
github.com/kanzihuang/vitess/go/vt/sqlparser v0.0.0-20231018071450-ac8d9f0167e9
|
||||||
github.com/lib/pq v1.10.9
|
github.com/lib/pq v1.10.9
|
||||||
@@ -25,8 +25,8 @@ require (
|
|||||||
github.com/robfig/cron/v3 v3.0.1 // 定时任务
|
github.com/robfig/cron/v3 v3.0.1 // 定时任务
|
||||||
github.com/stretchr/testify v1.8.4
|
github.com/stretchr/testify v1.8.4
|
||||||
go.mongodb.org/mongo-driver v1.12.1 // mongo
|
go.mongodb.org/mongo-driver v1.12.1 // mongo
|
||||||
golang.org/x/crypto v0.14.0 // ssh
|
golang.org/x/crypto v0.15.0 // ssh
|
||||||
golang.org/x/oauth2 v0.13.0
|
golang.org/x/oauth2 v0.14.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
// gorm
|
// gorm
|
||||||
gorm.io/driver/mysql v1.5.2
|
gorm.io/driver/mysql v1.5.2
|
||||||
@@ -77,10 +77,10 @@ require (
|
|||||||
golang.org/x/arch v0.3.0 // indirect
|
golang.org/x/arch v0.3.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20230519143937-03e91628a987 // indirect
|
golang.org/x/exp v0.0.0-20230519143937-03e91628a987 // indirect
|
||||||
golang.org/x/image v0.0.0-20220302094943-723b81ca9867 // indirect
|
golang.org/x/image v0.0.0-20220302094943-723b81ca9867 // indirect
|
||||||
golang.org/x/net v0.16.0 // indirect
|
golang.org/x/net v0.18.0 // indirect
|
||||||
golang.org/x/sync v0.1.0 // indirect
|
golang.org/x/sync v0.1.0 // indirect
|
||||||
golang.org/x/sys v0.13.0 // indirect
|
golang.org/x/sys v0.14.0 // indirect
|
||||||
golang.org/x/text v0.13.0 // indirect
|
golang.org/x/text v0.14.0 // indirect
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
google.golang.org/genproto v0.0.0-20230131230820-1c016267d619 // indirect
|
google.golang.org/genproto v0.0.0-20230131230820-1c016267d619 // indirect
|
||||||
google.golang.org/grpc v1.52.3 // indirect
|
google.golang.org/grpc v1.52.3 // indirect
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ type DbSqlExec struct {
|
|||||||
|
|
||||||
func (d *DbSqlExec) DbSqlExecs(rc *req.Ctx) {
|
func (d *DbSqlExec) DbSqlExecs(rc *req.Ctx) {
|
||||||
queryCond, page := ginx.BindQueryAndPage(rc.GinCtx, new(entity.DbSqlExecQuery))
|
queryCond, page := ginx.BindQueryAndPage(rc.GinCtx, new(entity.DbSqlExecQuery))
|
||||||
queryCond.CreatorId = rc.GetLoginAccount().Id
|
|
||||||
res, err := d.DbSqlExecApp.GetPageList(queryCond, page, new([]entity.DbSqlExec))
|
res, err := d.DbSqlExecApp.GetPageList(queryCond, page, new([]entity.DbSqlExec))
|
||||||
biz.ErrIsNil(err)
|
biz.ErrIsNil(err)
|
||||||
rc.ResData = res
|
rc.ResData = res
|
||||||
|
|||||||
@@ -46,7 +46,8 @@ func (c *Cli) GetSession() (*ssh.Session, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
// 获取session失败,则关闭cli,重试
|
// 获取session失败,则关闭cli,重试
|
||||||
DeleteCli(c.Info.Id)
|
DeleteCli(c.Info.Id)
|
||||||
return nil, errorx.NewBiz("请重试...")
|
logx.Errorf("获取机器客户端session失败: %s", err.Error())
|
||||||
|
return nil, errorx.NewBiz("获取会话失败, 请重试...")
|
||||||
}
|
}
|
||||||
return session, nil
|
return session, nil
|
||||||
}
|
}
|
||||||
@@ -69,11 +70,15 @@ func (c *Cli) Run(shell string) (string, error) {
|
|||||||
|
|
||||||
// 获取机器的所有状态信息
|
// 获取机器的所有状态信息
|
||||||
func (c *Cli) GetAllStats() *Stats {
|
func (c *Cli) GetAllStats() *Stats {
|
||||||
res, _ := c.Run(StatsShell)
|
|
||||||
infos := strings.Split(res, "-----")
|
|
||||||
stats := new(Stats)
|
stats := new(Stats)
|
||||||
|
res, err := c.Run(StatsShell)
|
||||||
|
if err != nil {
|
||||||
|
logx.Errorf("执行机器[id=%d, name=%s]运行状态信息脚本失败: %s", c.Info.Id, c.Info.Name, err.Error())
|
||||||
|
return stats
|
||||||
|
}
|
||||||
|
|
||||||
|
infos := strings.Split(res, "-----")
|
||||||
if len(infos) < 8 {
|
if len(infos) < 8 {
|
||||||
logx.Warnf("获取机器[id=%d, name=%s]的状态信息失败", c.Info.Id, c.Info.Name)
|
|
||||||
return stats
|
return stats
|
||||||
}
|
}
|
||||||
getUptime(infos[0], stats)
|
getUptime(infos[0], stats)
|
||||||
|
|||||||
Reference in New Issue
Block a user