mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-11-02 07:20:24 +08:00
feat: 统一分页表格组件、修复系统配置无法配置单个属性
This commit is contained in:
@@ -11,7 +11,7 @@ const config = {
|
||||
baseWsUrl: `${(window as any).globalConfig.BaseWsUrl || `${location.protocol == 'https:' ? 'wss:' : 'ws:'}//${getBaseApiUrl()}`}/api`,
|
||||
|
||||
// 系统版本
|
||||
version: 'v1.4.3'
|
||||
version: 'v1.4.4'
|
||||
}
|
||||
|
||||
export default config
|
||||
339
mayfly_go_web/src/components/pagetable/PageTable.vue
Normal file
339
mayfly_go_web/src/components/pagetable/PageTable.vue
Normal file
@@ -0,0 +1,339 @@
|
||||
<template>
|
||||
<div class="page-table">
|
||||
<!--
|
||||
实现:通过我们配置好的 查询条件
|
||||
首先去创建form表单,根据我们配置的查询条件去做一个循环判断,展示出不用类型所对应不同的输入框
|
||||
比如:text对应普通的输入框,select对应下拉选择,dateTime对应日期时间选择器
|
||||
在使用时,父组件会传来一个queryForm空的对象,
|
||||
循环出来的输入框会绑定表格配置中的prop字段绑定在queryForm对象中
|
||||
-->
|
||||
<el-card>
|
||||
<div class="query" ref="queryRef">
|
||||
<div>
|
||||
<div v-if="props.query.length > 0" class="query-head">
|
||||
<div style="display: flex; align-items: center;">
|
||||
<el-form :model="props.queryForm" label-width="70px" style="display: flex;">
|
||||
<el-form-item :label="item.label" style="margin-right: 20px; margin-bottom: 0px;"
|
||||
v-for="item in props.query?.slice(0, defaultQueryCount)" :key="item.prop">
|
||||
<!-- 这里只获取指定个数的筛选条件 -->
|
||||
<el-input v-model="queryForm[item.prop]" :placeholder="'输入' + item.label + '关键字'"
|
||||
clearable v-if="item.type == 'text'"></el-input>
|
||||
|
||||
<el-select-v2 v-model="queryForm[item.prop]" :options="item.options" clearable
|
||||
:placeholder="'选择' + item.label + '关键字'" v-else-if="item.type == 'select'" />
|
||||
|
||||
<el-date-picker v-model="queryForm[item.prop]" clearable type="datetimerange"
|
||||
format="YYYY-MM-DD hh:mm:ss" value-format="x" range-separator="至"
|
||||
start-placeholder="开始时间" end-placeholder="结束时间" v-else-if="item.type == 'date'" />
|
||||
|
||||
<slot :name="item.slot"></slot>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template v-if="props.query?.length > defaultQueryCount">
|
||||
<el-button @click="isOpenMoreQuery = !isOpenMoreQuery" v-if="!isOpenMoreQuery"
|
||||
icon="ArrowDownBold" circle></el-button>
|
||||
<el-button @click="isOpenMoreQuery = !isOpenMoreQuery" v-else icon="ArrowUpBold"
|
||||
circle></el-button>
|
||||
</template>
|
||||
|
||||
<el-button @click="queryData()" type="primary" plain>查询</el-button>
|
||||
<el-button @click="reset()">重置</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 这里做的是一个类似于折叠面板的功能 -->
|
||||
<div class="query-content" :class="isOpenMoreQuery ? 'is-open' : ''">
|
||||
<el-form :model="props.queryForm" label-width="70px" style="display: flex; flex-wrap: wrap;">
|
||||
<el-form-item :label="item.label" style="margin-right: 20px; margin-bottom: 0px;"
|
||||
v-for="item in props.query?.slice(defaultQueryCount)" :key="item.prop">
|
||||
|
||||
<!-- 这里获取除前两个以外所有的筛选条件 -->
|
||||
<el-input v-model="queryForm[item.prop]" :placeholder="'输入' + item.label + '关键字'" clearable
|
||||
v-if="item.type == 'text'"></el-input>
|
||||
|
||||
<el-select-v2 v-model="queryForm[item.prop]" :options="item.options" clearable
|
||||
:placeholder="'选择' + item.label + '关键字'" v-else-if="item.type == 'select'" />
|
||||
|
||||
<el-date-picker v-model="queryForm[item.prop]" clearable type="datetimerange"
|
||||
format="YYYY-MM-DD hh:mm:ss" value-format="x" range-separator="至"
|
||||
start-placeholder="开始时间" end-placeholder="结束时间" v-else-if="item.type == 'date'" />
|
||||
|
||||
<slot :name="item.slot"></slot>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="slot">
|
||||
<!-- 查询栏右侧slot插槽(用来添加表格其他操作,比如,新增数据,删除数据等其他操作) -->
|
||||
<slot name="queryRight"></slot>
|
||||
|
||||
<!--
|
||||
动态表头显示,根据表格每条配置项中的show字段来决定改列是否显示或者隐藏
|
||||
columns 就是我们表格配置的数组对象
|
||||
-->
|
||||
<el-popover placement="bottom" title="表格配置" :width="200" trigger="click">
|
||||
<div v-for="(item, index) in props.columns" :key="index">
|
||||
<el-checkbox v-model="item.show" :label="item.label" :true-label="true" :false-label="false" />
|
||||
</div>
|
||||
<template #reference>
|
||||
<!-- 一个Element Plus中的图标 -->
|
||||
<el-button icon="Operation"></el-button>
|
||||
</template>
|
||||
</el-popover>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-table v-bind="$attrs" max-height="700" @current-change="choose" :data="props.data" border
|
||||
highlight-current-row show-overflow-tooltip>
|
||||
<el-table-column v-if="props.showChooseColumn" label="选择" align="center" width="53px">
|
||||
<template #default="scope">
|
||||
<el-radio v-model="state.chooseId" :label="scope.row.id">
|
||||
<i></i>
|
||||
</el-radio>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<template v-for="(item, index) in columns">
|
||||
<el-table-column :key="index" v-if="item.show" :prop="item.prop" :label="item.label" :fixed="item.fixed"
|
||||
:align="item.align" :show-overflow-tooltip="item.showOverflowTooltip || true"
|
||||
:min-width="item.minWidth" :sortable="item.sortable || false" :type="item.type" :width="item.width">
|
||||
|
||||
<!-- 插槽:预留功能 -->
|
||||
<template #default="scope" v-if="item.slot">
|
||||
<slot :name="item.slot" :data="scope.row"></slot>
|
||||
</template>
|
||||
|
||||
<template #default="scope" v-else>
|
||||
<span>{{ item.formatFunc ? item.formatFunc(scope.row[item.prop]) : scope.row[item.prop]
|
||||
}}</span>
|
||||
</template>
|
||||
|
||||
</el-table-column>
|
||||
</template>
|
||||
</el-table>
|
||||
|
||||
<el-row style="margin-top: 20px" type="flex" justify="end">
|
||||
<el-pagination @current-change="handlePageChange" @size-change="handleSizeChange" style="text-align: right"
|
||||
layout="prev, pager, next, total, sizes, jumper" :total="props.total"
|
||||
v-model:current-page="state.pageNum" v-model:page-size="state.pageSize"
|
||||
:page-sizes="[10, 15, 20, 25]" />
|
||||
</el-row>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang='ts' setup>
|
||||
import { toRefs, watch, reactive, onMounted } from 'vue';
|
||||
import { TableColumn, TableQuery } from './index';
|
||||
|
||||
const emit = defineEmits(['update:queryForm', 'update:pageNum', 'update:pageSize', 'update:chooseData', 'pageChange'])
|
||||
|
||||
const props = defineProps({
|
||||
// 是否显示选择列
|
||||
showChooseColumn: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
// 选择列绑定的主键key字段名
|
||||
chooseDataIdKey: {
|
||||
type: String,
|
||||
default: "id"
|
||||
},
|
||||
// 当前选择的数据
|
||||
chooseData: {
|
||||
type: Object
|
||||
},
|
||||
// 列信息
|
||||
columns: {
|
||||
type: Array<TableColumn>,
|
||||
default: function () {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
// 表格数据
|
||||
data: {
|
||||
type: Array,
|
||||
},
|
||||
total: {
|
||||
type: [Number],
|
||||
default: 0,
|
||||
},
|
||||
pageNum: {
|
||||
type: Number,
|
||||
default: 1,
|
||||
},
|
||||
pageSize: {
|
||||
type: [Number],
|
||||
default: 10,
|
||||
},
|
||||
// 绑定的查询表单
|
||||
queryForm: {
|
||||
type: Object,
|
||||
default: function () {
|
||||
return {};
|
||||
}
|
||||
},
|
||||
// 查询条件配置
|
||||
query: {
|
||||
type: Array<TableQuery>,
|
||||
default: function () {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const state = reactive({
|
||||
pageSize: 10,
|
||||
pageNum: 1,
|
||||
chooseData: null as any,
|
||||
chooseId: 0 as any,
|
||||
isOpenMoreQuery: false,
|
||||
defaultQueryCount: 2, // 默认显示的查询参数个数
|
||||
queryForm: {} as any,
|
||||
})
|
||||
|
||||
const {
|
||||
isOpenMoreQuery,
|
||||
defaultQueryCount,
|
||||
queryForm,
|
||||
} = toRefs(state)
|
||||
|
||||
watch(() => props.queryForm, (newValue: any) => {
|
||||
state.queryForm = newValue
|
||||
})
|
||||
|
||||
watch(() => props.chooseData, (newValue: any) => {
|
||||
state.chooseData = newValue
|
||||
if (newValue) {
|
||||
state.chooseId = state.chooseData[props.chooseDataIdKey]
|
||||
} else {
|
||||
state.chooseId = 0;
|
||||
}
|
||||
})
|
||||
|
||||
watch(() => props.pageNum, (newValue: any) => {
|
||||
state.pageNum = newValue
|
||||
})
|
||||
|
||||
watch(() => props.pageSize, (newValue: any) => {
|
||||
state.pageSize = newValue
|
||||
})
|
||||
|
||||
watch(() => props.data, (newValue: any) => {
|
||||
if (newValue.length > 0) {
|
||||
props.columns.forEach(item => {
|
||||
if (item.autoWidth && item.show) {
|
||||
item.minWidth = TableColumn.flexColumnWidth(item.prop, item.label, props.data) as any
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
state.pageNum = props.pageNum;
|
||||
state.pageSize = props.pageSize;
|
||||
state.queryForm = props.queryForm;
|
||||
})
|
||||
|
||||
// 处理选中了列表中的某一条数据
|
||||
const choose = (item: any) => {
|
||||
if (!item || !props.showChooseColumn) {
|
||||
return;
|
||||
}
|
||||
state.chooseData = item;
|
||||
state.chooseId = item[props.chooseDataIdKey]
|
||||
emit('update:chooseData', state.chooseData)
|
||||
};
|
||||
|
||||
const handlePageChange = () => {
|
||||
emit('update:pageNum', state.pageNum)
|
||||
emit("pageChange")
|
||||
}
|
||||
|
||||
const handleSizeChange = () => {
|
||||
emit('update:pageSize', state.pageSize)
|
||||
emit("pageChange")
|
||||
}
|
||||
|
||||
const queryData = () => {
|
||||
// 触发重新调用查询接口即可
|
||||
emit("pageChange")
|
||||
}
|
||||
|
||||
const reset = () => {
|
||||
// 触发重新调用查询接口即可
|
||||
state.queryForm = {};
|
||||
emit('update:queryForm', state.queryForm)
|
||||
emit("pageChange")
|
||||
}
|
||||
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.page-table {
|
||||
.query {
|
||||
margin-bottom: 10px;
|
||||
overflow: hidden;
|
||||
|
||||
.query-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.query-content {
|
||||
width: 100%;
|
||||
max-height: 0px;
|
||||
transition: all 0.8s;
|
||||
}
|
||||
|
||||
.is-open {
|
||||
padding: 10px 0;
|
||||
max-height: 200px;
|
||||
}
|
||||
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 10px;
|
||||
|
||||
.query-content {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
|
||||
.query-form {
|
||||
.el-form-item {
|
||||
margin: 0px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.slot {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding-right: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.page {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep(.el-form-item__label) {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.el-input {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.el-select-v2 {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
::v-deep(.el-date-editor) {
|
||||
width: 380px !important;
|
||||
}
|
||||
</style>
|
||||
233
mayfly_go_web/src/components/pagetable/index.ts
Normal file
233
mayfly_go_web/src/components/pagetable/index.ts
Normal file
@@ -0,0 +1,233 @@
|
||||
import { dateFormat } from '@/common/utils/date';
|
||||
|
||||
export class TableColumn {
|
||||
|
||||
/**
|
||||
* 属性字段
|
||||
*/
|
||||
prop: string;
|
||||
|
||||
/**
|
||||
* 显示表头
|
||||
*/
|
||||
label: string;
|
||||
|
||||
/**
|
||||
* 是否自动计算宽度
|
||||
*/
|
||||
autoWidth: boolean = true;
|
||||
|
||||
/**
|
||||
* 最小宽度
|
||||
*/
|
||||
minWidth: number | string;
|
||||
|
||||
/**
|
||||
* 插槽名
|
||||
*/
|
||||
slot: string;
|
||||
|
||||
showOverflowTooltip: boolean = true;
|
||||
|
||||
sortable: boolean = false;
|
||||
|
||||
type: string;
|
||||
|
||||
width: number | string;
|
||||
|
||||
fixed: any;
|
||||
|
||||
align: string = "center"
|
||||
|
||||
formatFunc: Function
|
||||
|
||||
show: boolean = true
|
||||
|
||||
constructor(prop: string, label: string) {
|
||||
this.prop = prop;
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
static new(prop: string, label: string): TableColumn {
|
||||
return new TableColumn(prop, label)
|
||||
}
|
||||
|
||||
setMinWidth(minWidth: number | string): TableColumn {
|
||||
this.minWidth = minWidth
|
||||
this.autoWidth = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
setSlot(slot: string): TableColumn {
|
||||
this.slot = slot
|
||||
return this;
|
||||
}
|
||||
|
||||
setFormatFunc(func: Function): TableColumn {
|
||||
this.formatFunc = func;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 为时间字段,则使用默认时间格式函数
|
||||
* @returns this
|
||||
*/
|
||||
isTime(): TableColumn {
|
||||
this.setFormatFunc(dateFormat)
|
||||
return this;
|
||||
}
|
||||
|
||||
fixedRight(): TableColumn {
|
||||
this.fixed = "right";
|
||||
return this;
|
||||
}
|
||||
|
||||
fixedLeft(): TableColumn {
|
||||
this.fixed = "left";
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param str 字符串
|
||||
* @param tableData 表数据
|
||||
* @param label 表头label也参与宽度计算
|
||||
* @returns 列宽度
|
||||
*/
|
||||
static flexColumnWidth = (str: any, label: string, tableData: any) => {
|
||||
// str为该列的字段名(传字符串);tableData为该表格的数据源(传变量);
|
||||
|
||||
str = str + '';
|
||||
let columnContent = '';
|
||||
if (!tableData || !tableData.length || tableData.length === 0 || tableData === undefined) {
|
||||
return;
|
||||
}
|
||||
if (!str || !str.length || str.length === 0 || str === undefined) {
|
||||
return;
|
||||
}
|
||||
// 获取该列中最长的数据(内容)
|
||||
let index = 0;
|
||||
for (let i = 0; i < tableData.length; i++) {
|
||||
if (!tableData[i][str]) {
|
||||
continue;
|
||||
}
|
||||
const now_temp = tableData[i][str] + '';
|
||||
const max_temp = tableData[index][str] + '';
|
||||
if (now_temp.length > max_temp.length) {
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
columnContent = tableData[index][str] + '';
|
||||
const contentWidth: number = TableColumn.getContentWidth(columnContent);
|
||||
// 获取label的宽度,取较大的宽度
|
||||
const columnWidth: number = TableColumn.getContentWidth(label) + 30;
|
||||
const flexWidth: number = contentWidth > columnWidth ? contentWidth : columnWidth;
|
||||
return flexWidth + 'px';
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取内容所需要占用的宽度
|
||||
*/
|
||||
static getContentWidth = (content: any): number => {
|
||||
if (!content) {
|
||||
return 50;
|
||||
}
|
||||
// 以下分配的单位长度可根据实际需求进行调整
|
||||
let flexWidth = 0;
|
||||
for (const char of content) {
|
||||
if (flexWidth > 500) {
|
||||
break;
|
||||
}
|
||||
if ((char >= '0' && char <= '9') || (char >= 'a' && char <= 'z')) {
|
||||
// 小写字母、数字字符
|
||||
flexWidth += 9.3;
|
||||
continue;
|
||||
}
|
||||
if (char >= 'A' && char <= 'Z') {
|
||||
flexWidth += 9;
|
||||
continue;
|
||||
}
|
||||
if (char >= '\u4e00' && char <= '\u9fa5') {
|
||||
// 如果是中文字符,为字符分配16个单位宽度
|
||||
flexWidth += 20;
|
||||
} else {
|
||||
// 其他种类字符
|
||||
flexWidth += 8;
|
||||
}
|
||||
}
|
||||
if (flexWidth > 400) {
|
||||
// 设置最大宽度
|
||||
flexWidth = 400;
|
||||
}
|
||||
return flexWidth;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
export class TableQuery {
|
||||
|
||||
/**
|
||||
* 属性字段
|
||||
*/
|
||||
prop: string;
|
||||
|
||||
/**
|
||||
* 显示表头
|
||||
*/
|
||||
label: string;
|
||||
|
||||
/**
|
||||
* 查询类型,text、select、date
|
||||
*/
|
||||
type: string;
|
||||
|
||||
/**
|
||||
* select可选值
|
||||
*/
|
||||
options: any;
|
||||
|
||||
/**
|
||||
* 插槽名
|
||||
*/
|
||||
slot: string;
|
||||
|
||||
|
||||
constructor(prop: string, label: string) {
|
||||
this.prop = prop;
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
static new(prop: string, label: string): TableQuery {
|
||||
return new TableQuery(prop, label)
|
||||
}
|
||||
|
||||
static text(prop: string, label: string): TableQuery {
|
||||
const tq = new TableQuery(prop, label)
|
||||
tq.type = 'text';
|
||||
return tq;
|
||||
}
|
||||
|
||||
static select(prop: string, label: string): TableQuery {
|
||||
const tq = new TableQuery(prop, label)
|
||||
tq.type = 'select';
|
||||
return tq;
|
||||
}
|
||||
|
||||
static date(prop: string, label: string): TableQuery {
|
||||
const tq = new TableQuery(prop, label)
|
||||
tq.type = 'date';
|
||||
return tq;
|
||||
}
|
||||
|
||||
static slot(prop: string, label: string, slotName: string): TableQuery {
|
||||
const tq = new TableQuery(prop, label)
|
||||
tq.slot = slotName;
|
||||
return tq;
|
||||
}
|
||||
|
||||
setOptions(options: any): TableQuery {
|
||||
this.options = options;
|
||||
return this
|
||||
}
|
||||
}
|
||||
@@ -1,85 +1,66 @@
|
||||
<template>
|
||||
<div class="db-list">
|
||||
<el-card>
|
||||
<el-button v-auth="permissions.saveDb" type="primary" icon="plus" @click="editDb(true)">添加</el-button>
|
||||
<el-button v-auth="permissions.saveDb" :disabled="chooseId == null" @click="editDb(false)" type="primary"
|
||||
icon="edit">编辑</el-button>
|
||||
<el-button v-auth="permissions.delDb" :disabled="chooseId == null" @click="deleteDb(chooseId)" type="danger"
|
||||
icon="delete">删除</el-button>
|
||||
<div style="float: right">
|
||||
<el-select @focus="getTags" v-model="query.tagPath" placeholder="请选择标签" filterable clearable>
|
||||
<page-table :query="state.queryConfig" v-model:query-form="query" :show-choose-column="true"
|
||||
v-model:choose-data="state.chooseData" :data="datas" :columns="state.columns" :total="total"
|
||||
v-model:page-size="query.pageSize" v-model:page-num="query.pageNum" @pageChange="search()">
|
||||
|
||||
<template #tagPathSelect>
|
||||
<el-select @focus="getTags" v-model="query.tagPath" placeholder="请选择标签" @clear="search" filterable clearable
|
||||
style="width: 200px">
|
||||
<el-option v-for="item in tags" :key="item" :label="item" :value="item"> </el-option>
|
||||
</el-select>
|
||||
<el-button type="success" icon="search" @click="search()" class="ml5"></el-button>
|
||||
</div>
|
||||
<el-table :data="datas" ref="table" @current-change="choose" show-overflow-tooltip stripe>
|
||||
<el-table-column label="选择" width="60px">
|
||||
<template #default="scope">
|
||||
<el-radio v-model="chooseId" :label="scope.row.id">
|
||||
<i></i>
|
||||
</el-radio>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="tagPath" label="标签路径" min-width="150" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<tag-info :tag-path="scope.row.tagPath" />
|
||||
<span class="ml5">
|
||||
{{ scope.row.tagPath }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="name" label="名称" min-width="160" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column min-width="170" label="host:port" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
{{ `${scope.row.host}:${scope.row.port}` }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="type" label="类型" min-width="90"></el-table-column>
|
||||
<el-table-column prop="database" label="数据库" min-width="80">
|
||||
<template #default="scope">
|
||||
<el-popover placement="right" trigger="click" :width="300">
|
||||
<template #reference>
|
||||
<el-link type="primary" :underline="false" plain @click="selectDb(scope.row.dbs)">查看
|
||||
</el-link>
|
||||
</template>
|
||||
<el-input v-model="filterDb.param" @keyup="filterSchema" class="w-50 m-2" placeholder="搜索"
|
||||
size="small">
|
||||
<template #prefix>
|
||||
<el-icon class="el-input__icon">
|
||||
<search-icon />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
<div class="el-tag--plain el-tag--success" v-for="db in filterDb.list" :key="db"
|
||||
style="border:1px var(--color-success-light-3) solid; margin-top: 3px;border-radius: 5px; padding: 2px;position: relative">
|
||||
<el-link type="success" plain size="small" :underline="false">{{ db }}</el-link>
|
||||
<el-link type="primary" plain size="small" :underline="false"
|
||||
@click="showTableInfo(scope.row, db)" style="position: absolute; right: 4px">操作
|
||||
</el-link>
|
||||
</div>
|
||||
</el-popover>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="username" label="用户名" min-width="100"></el-table-column>
|
||||
<el-table-column prop="remark" label="备注" min-width="150" show-overflow-tooltip></el-table-column>
|
||||
</template>
|
||||
|
||||
<el-table-column label="操作" min-width="160" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-link plain size="small" :underline="false" @click="showInfo(scope.row)">
|
||||
详情</el-link>
|
||||
<el-divider direction="vertical" border-style="dashed" />
|
||||
<el-link class="ml5" type="primary" plain size="small" :underline="false"
|
||||
@click="onShowSqlExec(scope.row)">
|
||||
SQL执行记录</el-link>
|
||||
<template #queryRight>
|
||||
<el-button v-auth="permissions.saveDb" type="primary" icon="plus" @click="editDb(true)">添加</el-button>
|
||||
<el-button v-auth="permissions.saveDb" :disabled="!chooseData" @click="editDb(false)" type="primary"
|
||||
icon="edit">编辑</el-button>
|
||||
<el-button v-auth="permissions.delDb" :disabled="!chooseData" @click="deleteDb(chooseData.id)" type="danger"
|
||||
icon="delete">删除</el-button>
|
||||
</template>
|
||||
|
||||
<template #tagPath="{ data }">
|
||||
<tag-info :tag-path="data.tagPath" />
|
||||
<span class="ml5">
|
||||
{{ data.tagPath }}
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<template #hostPort="{ data }">
|
||||
{{ `${data.host}:${data.port}` }}
|
||||
</template>
|
||||
|
||||
<template #database="{ data }">
|
||||
<el-popover placement="right" trigger="click" :width="300">
|
||||
<template #reference>
|
||||
<el-link type="primary" :underline="false" plain @click="selectDb(data.dbs)">查看
|
||||
</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-row style="margin-top: 20px" type="flex" justify="end">
|
||||
<el-pagination style="text-align: right" @current-change="handlePageChange" :total="total"
|
||||
layout="prev, pager, next, total, jumper" v-model:current-page="query.pageNum"
|
||||
:page-size="query.pageSize"></el-pagination>
|
||||
</el-row>
|
||||
</el-card>
|
||||
<el-input v-model="filterDb.param" @keyup="filterSchema" class="w-50 m-2" placeholder="搜索" size="small">
|
||||
<template #prefix>
|
||||
<el-icon class="el-input__icon">
|
||||
<search-icon />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
<div class="el-tag--plain el-tag--success" v-for="db in filterDb.list" :key="db"
|
||||
style="border:1px var(--color-success-light-3) solid; margin-top: 3px;border-radius: 5px; padding: 2px;position: relative">
|
||||
<el-link type="success" plain size="small" :underline="false">{{ db }}</el-link>
|
||||
<el-link type="primary" plain size="small" :underline="false" @click="showTableInfo(data, db)"
|
||||
style="position: absolute; right: 4px">操作
|
||||
</el-link>
|
||||
</div>
|
||||
</el-popover>
|
||||
</template>
|
||||
|
||||
<template #action="{ data }">
|
||||
<el-link plain size="small" :underline="false" @click="showInfo(data)">
|
||||
详情</el-link>
|
||||
<el-divider direction="vertical" border-style="dashed" />
|
||||
<el-link class="ml5" type="primary" plain size="small" :underline="false" @click="onShowSqlExec(data)">
|
||||
SQL执行记录</el-link>
|
||||
</template>
|
||||
</page-table>
|
||||
|
||||
<el-dialog width="80%" :title="`${db} 表信息`" :before-close="closeTableInfo" v-model="tableInfoDialog.visible">
|
||||
<el-row class="mb10">
|
||||
@@ -147,8 +128,7 @@
|
||||
<template #default="scope">
|
||||
<el-link @click.prevent="showColumns(scope.row)" type="primary">字段</el-link>
|
||||
<el-link class="ml5" @click.prevent="showTableIndex(scope.row)" type="success">索引</el-link>
|
||||
<el-link class="ml5"
|
||||
v-if="tableCreateDialog.enableEditTypes.indexOf(tableCreateDialog.type) > -1"
|
||||
<el-link class="ml5" v-if="tableCreateDialog.enableEditTypes.indexOf(tableCreateDialog.type) > -1"
|
||||
@click.prevent="openEditTable(scope.row)" type="warning">编辑表</el-link>
|
||||
<el-link class="ml5" @click.prevent="showCreateDdl(scope.row)" type="info">DDL</el-link>
|
||||
</template>
|
||||
@@ -218,8 +198,8 @@
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog width="55%" :title="`还原SQL`" v-model="rollbackSqlDialog.visible">
|
||||
<el-input type="textarea" :autosize="{ minRows: 15, maxRows: 30 }" v-model="rollbackSqlDialog.sql"
|
||||
size="small"> </el-input>
|
||||
<el-input type="textarea" :autosize="{ minRows: 15, maxRows: 30 }" v-model="rollbackSqlDialog.sql" size="small">
|
||||
</el-input>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog width="40%" :title="`${chooseTableName} 字段信息`" v-model="columnDialog.visible">
|
||||
@@ -299,6 +279,8 @@ import { Search as SearchIcon } from '@element-plus/icons-vue'
|
||||
import { tagApi } from '../tag/api';
|
||||
import { dateFormat } from '@/common/utils/date';
|
||||
import TagInfo from '../component/TagInfo.vue';
|
||||
import PageTable from '@/components/pagetable/PageTable.vue'
|
||||
import { TableColumn, TableQuery } from '@/components/pagetable';
|
||||
|
||||
const DbEdit = defineAsyncComponent(() => import('./DbEdit.vue'));
|
||||
const CreateTable = defineAsyncComponent(() => import('./CreateTable.vue'));
|
||||
@@ -313,11 +295,10 @@ const state = reactive({
|
||||
dbId: 0,
|
||||
db: '',
|
||||
tags: [],
|
||||
chooseId: null as any,
|
||||
/**
|
||||
* 选中的数据
|
||||
*/
|
||||
chooseData: null,
|
||||
chooseData: null as any,
|
||||
/**
|
||||
* 查询条件
|
||||
*/
|
||||
@@ -326,6 +307,19 @@ const state = reactive({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
queryConfig: [
|
||||
TableQuery.slot("tagPath", "标签", "tagPathSelect"),
|
||||
],
|
||||
columns: [
|
||||
TableColumn.new("tagPath", "标签路径").setSlot("tagPath"),
|
||||
TableColumn.new("name", "名称"),
|
||||
TableColumn.new("host", "host:port").setSlot("hostPort"),
|
||||
TableColumn.new("type", "类型"),
|
||||
TableColumn.new("database", "数据库").setSlot("database").setMinWidth(60),
|
||||
TableColumn.new("username", "用户名"),
|
||||
TableColumn.new("remark", "备注"),
|
||||
TableColumn.new("action", "操作").setSlot("action").setMinWidth(155).fixedRight(),
|
||||
],
|
||||
datas: [],
|
||||
total: 0,
|
||||
infoDialog: {
|
||||
@@ -408,7 +402,7 @@ const {
|
||||
dbId,
|
||||
db,
|
||||
tags,
|
||||
chooseId,
|
||||
chooseData,
|
||||
query,
|
||||
datas,
|
||||
total,
|
||||
@@ -452,14 +446,6 @@ const filterTableInfos = computed(() => {
|
||||
});
|
||||
});
|
||||
|
||||
const choose = (item: any) => {
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
state.chooseId = item.id;
|
||||
state.chooseData = item;
|
||||
};
|
||||
|
||||
const search = async () => {
|
||||
let res: any = await dbApi.dbs.request(state.query);
|
||||
// 切割数据库
|
||||
@@ -471,11 +457,6 @@ const search = async () => {
|
||||
state.total = res.total;
|
||||
};
|
||||
|
||||
const handlePageChange = (curPage: number) => {
|
||||
state.query.pageNum = curPage;
|
||||
search();
|
||||
};
|
||||
|
||||
const showInfo = (info: any) => {
|
||||
state.infoDialog.data = info;
|
||||
state.infoDialog.visible = true;
|
||||
@@ -498,7 +479,6 @@ const editDb = async (isAdd = false) => {
|
||||
|
||||
const valChange = () => {
|
||||
state.chooseData = null;
|
||||
state.chooseId = null;
|
||||
search();
|
||||
};
|
||||
|
||||
@@ -512,7 +492,6 @@ const deleteDb = async (id: number) => {
|
||||
await dbApi.deleteDb.request({ id });
|
||||
ElMessage.success('删除成功');
|
||||
state.chooseData = null;
|
||||
state.chooseId = null;
|
||||
search();
|
||||
} catch (err) { }
|
||||
};
|
||||
@@ -651,7 +630,7 @@ const closeTableInfo = () => {
|
||||
const showColumns = async (row: any) => {
|
||||
state.chooseTableName = row.tableName;
|
||||
state.columnDialog.columns = await dbApi.columnMetadata.request({
|
||||
id: state.chooseId,
|
||||
id: state.chooseData.id,
|
||||
db: state.db,
|
||||
tableName: row.tableName,
|
||||
});
|
||||
@@ -662,7 +641,7 @@ const showColumns = async (row: any) => {
|
||||
const showTableIndex = async (row: any) => {
|
||||
state.chooseTableName = row.tableName;
|
||||
state.indexDialog.indexs = await dbApi.tableIndex.request({
|
||||
id: state.chooseId,
|
||||
id: state.chooseData.id,
|
||||
db: state.db,
|
||||
tableName: row.tableName,
|
||||
});
|
||||
@@ -673,7 +652,7 @@ const showTableIndex = async (row: any) => {
|
||||
const showCreateDdl = async (row: any) => {
|
||||
state.chooseTableName = row.tableName;
|
||||
const res = await dbApi.tableDdl.request({
|
||||
id: state.chooseId,
|
||||
id: state.chooseData.id,
|
||||
db: state.db,
|
||||
tableName: row.tableName,
|
||||
});
|
||||
@@ -694,10 +673,10 @@ const dropTable = async (row: any) => {
|
||||
});
|
||||
SqlExecBox({
|
||||
sql: `DROP TABLE ${tableName}`,
|
||||
dbId: state.chooseId,
|
||||
dbId: state.chooseData.id,
|
||||
db: state.db,
|
||||
runSuccessCallback: async () => {
|
||||
state.tableInfoDialog.infos = await dbApi.tableInfos.request({ id: state.chooseId, db: state.db });
|
||||
state.tableInfoDialog.infos = await dbApi.tableInfos.request({ id: state.chooseData.id, db: state.db });
|
||||
},
|
||||
});
|
||||
} catch (err) { }
|
||||
@@ -733,12 +712,12 @@ const openEditTable = async (row: any) => {
|
||||
if (row.tableName) {
|
||||
state.tableCreateDialog.title = '修改表'
|
||||
let indexs = await dbApi.tableIndex.request({
|
||||
id: state.chooseId,
|
||||
id: state.chooseData.id,
|
||||
db: state.db,
|
||||
tableName: row.tableName,
|
||||
});
|
||||
let columns = await dbApi.columnMetadata.request({
|
||||
id: state.chooseId,
|
||||
id: state.chooseData.id,
|
||||
db: state.db,
|
||||
tableName: row.tableName,
|
||||
});
|
||||
@@ -746,6 +725,4 @@ const openEditTable = async (row: any) => {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
|
||||
</style>
|
||||
<style lang="scss"></style>
|
||||
|
||||
@@ -1,127 +1,96 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-card>
|
||||
<div>
|
||||
<page-table :query="state.queryConfig" v-model:query-form="params" :show-choose-column="true"
|
||||
v-model:choose-data="state.chooseData" :data="data.list" :columns="state.columns" :total="data.total"
|
||||
v-model:page-size="params.pageSize" v-model:page-num="params.pageNum" @pageChange="search()">
|
||||
|
||||
<template #tagPathSelect>
|
||||
<el-select @focus="getTags" v-model="params.tagPath" placeholder="请选择标签" @clear="search" filterable
|
||||
clearable style="width: 200px">
|
||||
<el-option v-for="item in tags" :key="item" :label="item" :value="item"> </el-option>
|
||||
</el-select>
|
||||
</template>
|
||||
|
||||
<template #queryRight>
|
||||
<el-button v-auth="'machine:add'" type="primary" icon="plus" @click="openFormDialog(false)" plain>添加
|
||||
</el-button>
|
||||
<el-button v-auth="'machine:update'" type="primary" icon="edit" :disabled="!currentId"
|
||||
@click="openFormDialog(currentData)" plain>编辑</el-button>
|
||||
<el-button v-auth="'machine:del'" :disabled="!currentId" @click="deleteMachine(currentId)" type="danger"
|
||||
icon="delete">删除</el-button>
|
||||
<div style="float: right">
|
||||
<el-select @focus="getTags" v-model="params.tagPath" placeholder="请选择标签" @clear="search" filterable
|
||||
clearable>
|
||||
<el-option v-for="item in tags" :key="item" :label="item" :value="item"> </el-option>
|
||||
</el-select>
|
||||
<el-input class="ml5" placeholder="请输入名称" style="width: 150px" v-model="params.name" @clear="search"
|
||||
plain clearable></el-input>
|
||||
<el-input class="ml5" placeholder="请输入ip" style="width: 150px" v-model="params.ip" @clear="search" plain
|
||||
clearable></el-input>
|
||||
<el-button class="ml5" @click="search" type="success" icon="search"></el-button>
|
||||
</div>
|
||||
</div>
|
||||
<el-button v-auth="'machine:update'" type="primary" icon="edit" :disabled="!chooseData"
|
||||
@click="openFormDialog(chooseData)" plain>编辑</el-button>
|
||||
<el-button v-auth="'machine:del'" :disabled="!chooseData" @click="deleteMachine(chooseData.id)"
|
||||
type="danger" icon="delete">删除</el-button>
|
||||
</template>
|
||||
|
||||
<el-table :data="data.list" stripe style="width: 100%" @current-change="choose">
|
||||
<el-table-column label="选择" width="55px">
|
||||
<template #default="scope">
|
||||
<el-radio v-model="currentId" :label="scope.row.id">
|
||||
<i></i>
|
||||
</el-radio>
|
||||
<template #tagPath="{ data }">
|
||||
<tag-info :tag-path="data.tagPath" />
|
||||
<span class="ml5">
|
||||
{{ data.tagPath }}
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<template #ipPort="{ data }">
|
||||
<el-link :disabled="data.status == -1" @click="showMachineStats(data)" type="primary" :underline="false">
|
||||
{{ `${data.ip}:${data.port}` }}
|
||||
</el-link>
|
||||
</template>
|
||||
|
||||
<template #status="{ data }">
|
||||
<el-switch v-auth:disabled="'machine:update'" :width="52" v-model="data.status" :active-value="1"
|
||||
:inactive-value="-1" inline-prompt active-text="启用" inactive-text="停用"
|
||||
style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
|
||||
@change="changeStatus(data)"></el-switch>
|
||||
</template>
|
||||
|
||||
<template #action="{ data }">
|
||||
<span v-auth="'machine:terminal'">
|
||||
<el-link :disabled="data.status == -1" type="primary" @click="showTerminal(data)" plain size="small"
|
||||
:underline="false">终端</el-link>
|
||||
<el-divider direction="vertical" border-style="dashed" />
|
||||
</span>
|
||||
|
||||
<span v-auth="'machine:file'">
|
||||
<el-link type="success" :disabled="data.status == -1" @click="showFileManage(data)" plain size="small"
|
||||
:underline="false">文件</el-link>
|
||||
<el-divider direction="vertical" border-style="dashed" />
|
||||
</span>
|
||||
|
||||
<el-link :disabled="data.status == -1" type="warning" @click="serviceManager(data)" plain size="small"
|
||||
:underline="false">脚本</el-link>
|
||||
<el-divider direction="vertical" border-style="dashed" />
|
||||
|
||||
<el-dropdown>
|
||||
<span class="el-dropdown-link-machine-list">
|
||||
更多
|
||||
<el-icon class="el-icon--right">
|
||||
<arrow-down />
|
||||
</el-icon>
|
||||
</span>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item>
|
||||
<el-link @click="showInfo(data)" plain :underline="false" size="small">详情
|
||||
</el-link>
|
||||
</el-dropdown-item>
|
||||
|
||||
<el-dropdown-item>
|
||||
<el-link @click="showProcess(data)" :disabled="data.status == -1" plain :underline="false"
|
||||
size="small">进程</el-link>
|
||||
</el-dropdown-item>
|
||||
|
||||
<el-dropdown-item v-if="data.enableRecorder == 1">
|
||||
<el-link v-auth="'machine:update'" @click="showRec(data)" plain :underline="false"
|
||||
size="small">终端回放</el-link>
|
||||
</el-dropdown-item>
|
||||
|
||||
<el-dropdown-item>
|
||||
<el-link v-auth="'machine:close-cli'" :disabled="!data.hasCli || data.status == -1"
|
||||
type="danger" @click="closeCli(data)" plain size="small" :underline="false">关闭连接
|
||||
</el-link>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="tagPath" label="标签路径" min-width="150" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<tag-info :tag-path="scope.row.tagPath" />
|
||||
<span class="ml5">
|
||||
{{ scope.row.tagPath }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="name" label="名称" min-width="140" show-overflow-tooltip></el-table-column>
|
||||
|
||||
<el-table-column prop="ip" label="ip:port" min-width="150">
|
||||
<template #default="scope">
|
||||
<el-link :disabled="scope.row.status == -1" @click="showMachineStats(scope.row)" type="primary"
|
||||
:underline="false">
|
||||
{{ `${scope.row.ip}:${scope.row.port}` }}
|
||||
</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="username" label="用户名" min-width="100">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="status" label="状态" min-width="80">
|
||||
<template #default="scope">
|
||||
<el-switch v-auth:disabled="'machine:update'" :width="52" v-model="scope.row.status"
|
||||
:active-value="1" :inactive-value="-1" inline-prompt active-text="启用" inactive-text="停用"
|
||||
style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
|
||||
@change="changeStatus(scope.row)"></el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="remark" label="备注" min-width="250" show-overflow-tooltip></el-table-column>
|
||||
|
||||
<el-table-column label="操作" min-width="235" fixed="right">
|
||||
<template #default="scope">
|
||||
<span v-auth="'machine:terminal'">
|
||||
<el-link :disabled="scope.row.status == -1" type="primary" @click="showTerminal(scope.row)"
|
||||
plain size="small" :underline="false">终端</el-link>
|
||||
<el-divider direction="vertical" border-style="dashed" />
|
||||
</span>
|
||||
|
||||
<span v-auth="'machine:file'">
|
||||
<el-link type="success" :disabled="scope.row.status == -1" @click="showFileManage(scope.row)"
|
||||
plain size="small" :underline="false">文件</el-link>
|
||||
<el-divider direction="vertical" border-style="dashed" />
|
||||
</span>
|
||||
|
||||
<el-link :disabled="scope.row.status == -1" type="warning" @click="serviceManager(scope.row)" plain
|
||||
size="small" :underline="false">脚本</el-link>
|
||||
<el-divider direction="vertical" border-style="dashed" />
|
||||
|
||||
<el-dropdown>
|
||||
<span class="el-dropdown-link-machine-list">
|
||||
更多
|
||||
<el-icon class="el-icon--right">
|
||||
<arrow-down />
|
||||
</el-icon>
|
||||
</span>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item>
|
||||
<el-link @click="showInfo(scope.row)" plain :underline="false" size="small">详情
|
||||
</el-link>
|
||||
</el-dropdown-item>
|
||||
|
||||
<el-dropdown-item>
|
||||
<el-link @click="showProcess(scope.row)" :disabled="scope.row.status == -1" plain
|
||||
:underline="false" size="small">进程</el-link>
|
||||
</el-dropdown-item>
|
||||
|
||||
<el-dropdown-item v-if="scope.row.enableRecorder == 1">
|
||||
<el-link v-auth="'machine:update'" @click="showRec(scope.row)" plain
|
||||
:underline="false" size="small">终端回放</el-link>
|
||||
</el-dropdown-item>
|
||||
|
||||
<el-dropdown-item>
|
||||
<el-link v-auth="'machine:close-cli'"
|
||||
:disabled="!scope.row.hasCli || scope.row.status == -1" type="danger"
|
||||
@click="closeCli(scope.row)" plain size="small" :underline="false">关闭连接
|
||||
</el-link>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-row style="margin-top: 20px" type="flex" justify="end">
|
||||
<el-pagination style="text-align: right" :total="data.total" layout="prev, pager, next, total, jumper"
|
||||
v-model:current-page="params.pageNum" :page-size="params.pageSize"
|
||||
@current-change="handlePageChange"></el-pagination>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
</page-table>
|
||||
|
||||
<el-dialog v-model="infoDialog.visible">
|
||||
<el-descriptions title="详情" :column="3" border>
|
||||
@@ -184,6 +153,8 @@ import { machineApi } from './api';
|
||||
import { tagApi } from '../tag/api';
|
||||
import { dateFormat } from '@/common/utils/date';
|
||||
import TagInfo from '../component/TagInfo.vue';
|
||||
import PageTable from '@/components/pagetable/PageTable.vue'
|
||||
import { TableColumn, TableQuery } from '@/components/pagetable';
|
||||
|
||||
// 组件
|
||||
const MachineEdit = defineAsyncComponent(() => import('./MachineEdit.vue'));
|
||||
@@ -203,6 +174,20 @@ const state = reactive({
|
||||
name: null,
|
||||
tagPath: null,
|
||||
},
|
||||
queryConfig: [
|
||||
TableQuery.slot("tagPath", "标签", "tagPathSelect"),
|
||||
TableQuery.text("ip", "IP"),
|
||||
TableQuery.text("name", "名称"),
|
||||
],
|
||||
columns: [
|
||||
TableColumn.new("tagPath", "标签路径").setSlot("tagPath"),
|
||||
TableColumn.new("name", "名称"),
|
||||
TableColumn.new("ipPort", "ip:port").setSlot("ipPort"),
|
||||
TableColumn.new("username", "用户名"),
|
||||
TableColumn.new("status", "状态").setSlot("status"),
|
||||
TableColumn.new("remark", "备注"),
|
||||
TableColumn.new("action", "操作").setSlot("action").setMinWidth(235).fixedRight(),
|
||||
],
|
||||
// 列表数据
|
||||
data: {
|
||||
list: [],
|
||||
@@ -212,9 +197,8 @@ const state = reactive({
|
||||
visible: false,
|
||||
data: null as any,
|
||||
},
|
||||
// 当前选中数据id
|
||||
currentId: 0,
|
||||
currentData: null,
|
||||
// 当前选中数据
|
||||
chooseData: null as any,
|
||||
serviceDialog: {
|
||||
visible: false,
|
||||
machineId: 0,
|
||||
@@ -252,8 +236,7 @@ const {
|
||||
params,
|
||||
data,
|
||||
infoDialog,
|
||||
currentId,
|
||||
currentData,
|
||||
chooseData,
|
||||
serviceDialog,
|
||||
processDialog,
|
||||
fileDialog,
|
||||
@@ -266,14 +249,6 @@ onMounted(async () => {
|
||||
search();
|
||||
});
|
||||
|
||||
const choose = (item: any) => {
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
state.currentId = item.id;
|
||||
state.currentData = item;
|
||||
};
|
||||
|
||||
const showTerminal = (row: any) => {
|
||||
const { href } = router.resolve({
|
||||
path: `/machine/terminal`,
|
||||
@@ -303,7 +278,7 @@ const getTags = async () => {
|
||||
const openFormDialog = async (machine: any) => {
|
||||
let dialogTitle;
|
||||
if (machine) {
|
||||
state.machineEditDialog.data = state.currentData as any;
|
||||
state.machineEditDialog.data = state.chooseData as any;
|
||||
dialogTitle = '编辑机器';
|
||||
} else {
|
||||
state.machineEditDialog.data = null;
|
||||
@@ -323,8 +298,7 @@ const deleteMachine = async (id: number) => {
|
||||
});
|
||||
await machineApi.del.request({ id });
|
||||
ElMessage.success('操作成功');
|
||||
state.currentId = 0;
|
||||
state.currentData = null;
|
||||
state.chooseData = null;
|
||||
search();
|
||||
} catch (err) { }
|
||||
};
|
||||
@@ -339,6 +313,9 @@ const serviceManager = (row: any) => {
|
||||
* 调整机器状态
|
||||
*/
|
||||
const changeStatus = async (row: any) => {
|
||||
if (!row.id) {
|
||||
return;
|
||||
}
|
||||
await machineApi.changeStatus.request({ id: row.id, status: row.status });
|
||||
};
|
||||
|
||||
@@ -352,15 +329,14 @@ const showMachineStats = async (machine: any) => {
|
||||
};
|
||||
|
||||
const submitSuccess = () => {
|
||||
state.currentId = 0;
|
||||
state.currentData = null;
|
||||
state.chooseData = null;
|
||||
search();
|
||||
};
|
||||
|
||||
const showFileManage = (currentData: any) => {
|
||||
const showFileManage = (chooseData: any) => {
|
||||
state.fileDialog.visible = true;
|
||||
state.fileDialog.machineId = currentData.id;
|
||||
state.fileDialog.title = `${currentData.name} => ${currentData.ip}`;
|
||||
state.fileDialog.machineId = chooseData.id;
|
||||
state.fileDialog.title = `${chooseData.name} => ${chooseData.ip}`;
|
||||
};
|
||||
|
||||
const search = async () => {
|
||||
@@ -368,11 +344,6 @@ const search = async () => {
|
||||
state.data = res;
|
||||
};
|
||||
|
||||
const handlePageChange = (curPage: number) => {
|
||||
state.params.pageNum = curPage;
|
||||
search();
|
||||
};
|
||||
|
||||
const showInfo = (info: any) => {
|
||||
state.infoDialog.data = info;
|
||||
state.infoDialog.visible = true;
|
||||
|
||||
@@ -1,56 +1,23 @@
|
||||
<template>
|
||||
<div class="role-list">
|
||||
<el-card>
|
||||
<div>
|
||||
<div>
|
||||
<page-table :query="state.queryConfig" v-model:query-form="query" :show-choose-column="true"
|
||||
v-model:choose-data="state.chooseData" :data="authcerts" :columns="state.columns" :total="total"
|
||||
v-model:page-size="query.pageSize" v-model:page-num="query.pageNum" @pageChange="search()">
|
||||
|
||||
<template #queryRight>
|
||||
<el-button type="primary" icon="plus" @click="edit(false)">添加</el-button>
|
||||
<el-button :disabled="chooseId == null" @click="edit(chooseData)" type="primary" icon="edit">编辑
|
||||
<el-button :disabled="!chooseData" @click="edit(chooseData)" type="primary" icon="edit">编辑
|
||||
</el-button>
|
||||
<el-button :disabled="chooseId == null" @click="deleteAc(chooseData)" type="danger" icon="delete">删除
|
||||
<el-button :disabled="!chooseData" @click="deleteAc(chooseData)" type="danger" icon="delete">删除
|
||||
</el-button>
|
||||
|
||||
<div style="float: right">
|
||||
<el-input class="ml5" placeholder="请输入凭证名称" style="width: 200px" v-model="query.name" @clear="search"
|
||||
plain clearable></el-input>
|
||||
<el-button class="ml5" @click="search" type="success" icon="search"></el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<el-table :data="authcerts" @current-change="choose" ref="table" style="width: 100%">
|
||||
<el-table-column label="选择" width="55px">
|
||||
<template #default="scope">
|
||||
<el-radio v-model="chooseId" :label="scope.row.id">
|
||||
<i></i>
|
||||
</el-radio>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="name" label="名称" min-width="60px" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="authMethod" label="认证方式" min-width="50px">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.authMethod == 1" type="success" size="small">密码</el-tag>
|
||||
<el-tag v-if="scope.row.authMethod == 2" size="small">密钥</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="remark" label="备注" min-width="100px" show-overflow-tooltip>
|
||||
</el-table-column>
|
||||
<el-table-column prop="creator" label="创建人" min-width="60px"></el-table-column>
|
||||
<el-table-column prop="createTime" label="创建时间" min-width="100px">
|
||||
<template #default="scope">
|
||||
{{ dateFormat(scope.row.createTime) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="modifier" label="修改者" min-width="60px" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="updateTime" label="更新时间" min-width="100px">
|
||||
<template #default="scope">
|
||||
{{ dateFormat(scope.row.updateTime) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-row style="margin-top: 20px" type="flex" justify="end">
|
||||
<el-pagination style="text-align: right" @current-change="handlePageChange" :total="total"
|
||||
layout="prev, pager, next, total, jumper" v-model:current-page="query.pageNum"
|
||||
:page-size="query.pageSize"></el-pagination>
|
||||
</el-row>
|
||||
</el-card>
|
||||
<template #authMethod="{ data }">
|
||||
<el-tag v-if="data.authMethod == 1" type="success" size="small">密码</el-tag>
|
||||
<el-tag v-if="data.authMethod == 2" size="small">密钥</el-tag>
|
||||
</template>
|
||||
</page-table>
|
||||
|
||||
<auth-cert-edit :title="editor.title" v-model:visible="editor.visible" :data="editor.authcert"
|
||||
@val-change="editChange" />
|
||||
@@ -62,19 +29,30 @@ import { toRefs, reactive, onMounted } from 'vue';
|
||||
import AuthCertEdit from './AuthCertEdit.vue';
|
||||
import { authCertApi } from '../api';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import { dateFormat } from '@/common/utils/date';
|
||||
import PageTable from '@/components/pagetable/PageTable.vue'
|
||||
import { TableColumn, TableQuery } from '@/components/pagetable';
|
||||
|
||||
const state = reactive({
|
||||
query: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
name: null,
|
||||
type: null,
|
||||
},
|
||||
queryConfig: [
|
||||
TableQuery.text("name", "凭证名称"),
|
||||
],
|
||||
columns: [
|
||||
TableColumn.new("name", "名称"),
|
||||
TableColumn.new("authMethod", "认证方式").setSlot("authMethod"),
|
||||
TableColumn.new("remark", "备注"),
|
||||
TableColumn.new("creator", "创建人"),
|
||||
TableColumn.new("createTime", "创建时间").isTime(),
|
||||
TableColumn.new("creator", "修改者"),
|
||||
TableColumn.new("createTime", "修改时间").isTime(),
|
||||
],
|
||||
total: 0,
|
||||
authcerts: [],
|
||||
chooseId: null,
|
||||
chooseData: null,
|
||||
chooseData: null as any,
|
||||
paramsDialog: {
|
||||
visible: false,
|
||||
config: null as any,
|
||||
@@ -92,7 +70,6 @@ const {
|
||||
query,
|
||||
total,
|
||||
authcerts,
|
||||
chooseId,
|
||||
chooseData,
|
||||
editor,
|
||||
} = toRefs(state)
|
||||
@@ -107,22 +84,8 @@ const search = async () => {
|
||||
state.total = res.total;
|
||||
};
|
||||
|
||||
const handlePageChange = (curPage: number) => {
|
||||
state.query.pageNum = curPage;
|
||||
search();
|
||||
};
|
||||
|
||||
const choose = (item: any) => {
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
state.chooseId = item.id;
|
||||
state.chooseData = item;
|
||||
};
|
||||
|
||||
const editChange = () => {
|
||||
ElMessage.success('保存成功');
|
||||
state.chooseId = null;
|
||||
state.chooseData = null;
|
||||
search();
|
||||
};
|
||||
@@ -147,7 +110,6 @@ const deleteAc = async (data: any) => {
|
||||
await authCertApi.delete.request({ id: data.id });
|
||||
ElMessage.success('删除成功');
|
||||
state.chooseData = null;
|
||||
state.chooseId = null;
|
||||
search();
|
||||
} catch (err) { }
|
||||
|
||||
|
||||
@@ -1,59 +1,35 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-card>
|
||||
<el-button type="primary" icon="plus" @click="editMongo(true)" plain>添加</el-button>
|
||||
<el-button type="primary" icon="edit" :disabled="currentId == null" @click="editMongo(false)" plain>编辑
|
||||
</el-button>
|
||||
<el-button type="danger" icon="delete" :disabled="currentId == null" @click="deleteMongo" plain>删除
|
||||
</el-button>
|
||||
<div style="float: right">
|
||||
<el-select @focus="getTags" v-model="query.tagPath" placeholder="请选择标签" filterable clearable>
|
||||
<page-table :query="state.queryConfig" v-model:query-form="query" :show-choose-column="true"
|
||||
v-model:choose-data="state.chooseData" :data="list" :columns="state.columns" :total="total"
|
||||
v-model:page-size="query.pageSize" v-model:page-num="query.pageNum" @pageChange="search()">
|
||||
|
||||
<template #tagPathSelect>
|
||||
<el-select @focus="getTags" v-model="query.tagPath" placeholder="请选择标签" @clear="search" filterable clearable
|
||||
style="width: 200px">
|
||||
<el-option v-for="item in tags" :key="item" :label="item" :value="item"> </el-option>
|
||||
</el-select>
|
||||
<el-button class="ml5" @click="search" type="success" icon="search"></el-button>
|
||||
</div>
|
||||
<el-table :data="list" style="width: 100%" @current-change="choose" stripe>
|
||||
<el-table-column label="选择" width="60px">
|
||||
<template #default="scope">
|
||||
<el-radio v-model="currentId" :label="scope.row.id">
|
||||
<i></i>
|
||||
</el-radio>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="tagPath" label="标签路径" min-width="150" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<tag-info :tag-path="scope.row.tagPath" />
|
||||
<span class="ml5">
|
||||
{{ scope.row.tagPath }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="name" label="名称" width></el-table-column>
|
||||
<el-table-column prop="uri" label="连接uri" min-width="150" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
{{ scope.row.uri.split('@')[1] }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="创建时间" min-width="150">
|
||||
<template #default="scope">
|
||||
{{ dateFormat(scope.row.createTime) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="creator" label="创建人"></el-table-column>
|
||||
</template>
|
||||
|
||||
<el-table-column label="操作" width>
|
||||
<template #default="scope">
|
||||
<el-link type="primary" @click="showDatabases(scope.row.id)" plain size="small"
|
||||
:underline="false">数据库</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-row style="margin-top: 20px" type="flex" justify="end">
|
||||
<el-pagination style="text-align: right" @current-change="handlePageChange" :total="total"
|
||||
layout="prev, pager, next, total, jumper" v-model:current-page="query.pageNum"
|
||||
:page-size="query.pageSize"></el-pagination>
|
||||
</el-row>
|
||||
</el-card>
|
||||
<template #queryRight>
|
||||
<el-button type="primary" icon="plus" @click="editMongo(true)" plain>添加</el-button>
|
||||
<el-button type="primary" icon="edit" :disabled="!chooseData" @click="editMongo(false)" plain>编辑
|
||||
</el-button>
|
||||
<el-button type="danger" icon="delete" :disabled="!chooseData" @click="deleteMongo" plain>删除
|
||||
</el-button>
|
||||
</template>
|
||||
|
||||
<template #tagPath="{ data }">
|
||||
<tag-info :tag-path="data.tagPath" />
|
||||
<span class="ml5">
|
||||
{{ data.tagPath }}
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<template #action="{ data }">
|
||||
<el-link type="primary" @click="showDatabases(data.id)" plain size="small" :underline="false">数据库</el-link>
|
||||
</template>
|
||||
</page-table>
|
||||
|
||||
<el-dialog width="800px" :title="databaseDialog.title" v-model="databaseDialog.visible">
|
||||
<el-table :data="databaseDialog.data" size="small">
|
||||
@@ -76,8 +52,7 @@
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-dialog width="700px" :title="databaseDialog.statsDialog.title"
|
||||
v-model="databaseDialog.statsDialog.visible">
|
||||
<el-dialog width="700px" :title="databaseDialog.statsDialog.title" v-model="databaseDialog.statsDialog.visible">
|
||||
<el-descriptions title="库状态信息" :column="3" border size="small">
|
||||
<el-descriptions-item label="db" label-align="right" align="center">
|
||||
{{ databaseDialog.statsDialog.data.db }}
|
||||
@@ -199,8 +174,9 @@ import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import { tagApi } from '../tag/api';
|
||||
import MongoEdit from './MongoEdit.vue';
|
||||
import { formatByteSize } from '@/common/utils/format';
|
||||
import { dateFormat } from '@/common/utils/date';
|
||||
import TagInfo from '../component/TagInfo.vue';
|
||||
import PageTable from '@/components/pagetable/PageTable.vue'
|
||||
import { TableColumn, TableQuery } from '@/components/pagetable';
|
||||
|
||||
const state = reactive({
|
||||
tags: [],
|
||||
@@ -210,13 +186,23 @@ const state = reactive({
|
||||
},
|
||||
list: [],
|
||||
total: 0,
|
||||
currentId: null,
|
||||
currentData: null as any,
|
||||
chooseData: null as any,
|
||||
query: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
tagPath: null,
|
||||
},
|
||||
queryConfig: [
|
||||
TableQuery.slot("tagPath", "标签", "tagPathSelect"),
|
||||
],
|
||||
columns: [
|
||||
TableColumn.new("tagPath", "标签路径").setSlot("tagPath"),
|
||||
TableColumn.new("name", "名称"),
|
||||
TableColumn.new("uri", "连接uri"),
|
||||
TableColumn.new("createTime", "创建时间").isTime(),
|
||||
TableColumn.new("creator", "创建人"),
|
||||
TableColumn.new("action", "操作").setSlot("action").setMinWidth(100).fixedRight(),
|
||||
],
|
||||
mongoEditDialog: {
|
||||
visible: false,
|
||||
data: null as any,
|
||||
@@ -255,7 +241,7 @@ const {
|
||||
tags,
|
||||
list,
|
||||
total,
|
||||
currentId,
|
||||
chooseData,
|
||||
query,
|
||||
mongoEditDialog,
|
||||
databaseDialog,
|
||||
@@ -267,19 +253,6 @@ onMounted(async () => {
|
||||
search();
|
||||
});
|
||||
|
||||
const handlePageChange = (curPage: number) => {
|
||||
state.query.pageNum = curPage;
|
||||
search();
|
||||
};
|
||||
|
||||
const choose = (item: any) => {
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
state.currentId = item.id;
|
||||
state.currentData = item;
|
||||
};
|
||||
|
||||
const showDatabases = async (id: number) => {
|
||||
// state.query.tagPath = row.tagPath
|
||||
state.dbOps.dbId = id
|
||||
@@ -291,7 +264,7 @@ const showDatabases = async (id: number) => {
|
||||
|
||||
const showDatabaseStats = async (dbName: string) => {
|
||||
state.databaseDialog.statsDialog.data = await mongoApi.runCommand.request({
|
||||
id: state.currentId,
|
||||
id: state.chooseData.id,
|
||||
database: dbName,
|
||||
command: {
|
||||
dbStats: 1,
|
||||
@@ -310,7 +283,7 @@ const showCollections = async (database: string) => {
|
||||
};
|
||||
|
||||
const setCollections = async (database: string) => {
|
||||
const res = await mongoApi.collections.request({ id: state.currentId, database });
|
||||
const res = await mongoApi.collections.request({ id: state.chooseData.id, database });
|
||||
const collections = [] as any;
|
||||
for (let r of res) {
|
||||
collections.push({ name: r });
|
||||
@@ -323,7 +296,7 @@ const setCollections = async (database: string) => {
|
||||
*/
|
||||
const showCollectionStats = async (collection: string) => {
|
||||
state.collectionsDialog.statsDialog.data = await mongoApi.runCommand.request({
|
||||
id: state.currentId,
|
||||
id: state.chooseData.id,
|
||||
database: state.collectionsDialog.database,
|
||||
command: {
|
||||
collStats: collection,
|
||||
@@ -338,7 +311,7 @@ const showCollectionStats = async (collection: string) => {
|
||||
*/
|
||||
const onDeleteCollection = async (collection: string) => {
|
||||
await mongoApi.runCommand.request({
|
||||
id: state.currentId,
|
||||
id: state.chooseData.id,
|
||||
database: state.collectionsDialog.database,
|
||||
command: {
|
||||
drop: collection,
|
||||
@@ -355,7 +328,7 @@ const showCreateCollectionDialog = () => {
|
||||
const onCreateCollection = async () => {
|
||||
const form = state.createCollectionDialog.form;
|
||||
await mongoApi.runCommand.request({
|
||||
id: state.currentId,
|
||||
id: state.chooseData.id,
|
||||
database: state.collectionsDialog.database,
|
||||
command: {
|
||||
create: form.name,
|
||||
@@ -374,10 +347,9 @@ const deleteMongo = async () => {
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
});
|
||||
await mongoApi.deleteMongo.request({ id: state.currentId });
|
||||
await mongoApi.deleteMongo.request({ id: state.chooseData.id });
|
||||
ElMessage.success('删除成功');
|
||||
state.currentData = null;
|
||||
state.currentId = null;
|
||||
state.chooseData = null;
|
||||
search();
|
||||
} catch (err) { }
|
||||
};
|
||||
@@ -397,20 +369,17 @@ const editMongo = async (isAdd = false) => {
|
||||
state.mongoEditDialog.data = null;
|
||||
state.mongoEditDialog.title = '新增mongo';
|
||||
} else {
|
||||
state.mongoEditDialog.data = state.currentData;
|
||||
state.mongoEditDialog.data = state.chooseData;
|
||||
state.mongoEditDialog.title = '修改mongo';
|
||||
}
|
||||
state.mongoEditDialog.visible = true;
|
||||
};
|
||||
|
||||
const valChange = () => {
|
||||
state.currentId = null;
|
||||
state.currentData = null;
|
||||
state.chooseData = null;
|
||||
search();
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
<style></style>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-button @click="showEditDialog(null)" icon="plus" size="small" plain type="primary" class="mb10">添加新行</el-button>
|
||||
<el-table size="small" border :data="hashValues" min-height=300 stripe>
|
||||
<el-table size="small" border :data="hashValues" height="450" min-height=300 stripe>
|
||||
<el-table-column type="index" :label="'ID (Total: ' + total + ')'" sortable width="100">
|
||||
</el-table-column>
|
||||
<el-table-column resizable sortable prop="field" label="field" show-overflow-tooltip min-width="100">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-button @click="showEditDialog(null)" icon="plus" size="small" plain type="primary" class="mb10">添加新行</el-button>
|
||||
<el-table size="small" border :data="values" min-height=300 stripe>
|
||||
<el-table size="small" border :data="values" height="450" min-height=300 stripe>
|
||||
<el-table-column type="index" :label="'ID (Total: ' + total + ')'" sortable width="100">
|
||||
</el-table-column>
|
||||
<el-table-column resizable sortable prop="value" label="value" show-overflow-tooltip min-width="200">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-button @click="showEditDialog(null)" icon="plus" size="small" plain type="primary" class="mb10">添加新行</el-button>
|
||||
<el-table size="small" border :data="setDatas" min-height=300 stripe>
|
||||
<el-table size="small" border :data="setDatas" height="450" min-height=300 stripe>
|
||||
<el-table-column type="index" :label="'ID (Total: ' + total + ')'" sortable width="100">
|
||||
</el-table-column>
|
||||
<el-table-column resizable sortable prop="value" label="value" show-overflow-tooltip min-width="200">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-button @click="showEditDialog(null)" icon="plus" size="small" plain type="primary" class="mb10">添加新行</el-button>
|
||||
<el-table size="small" border :data="values" min-height=300 stripe>
|
||||
<el-table size="small" border :data="values" height="450" min-height=300 stripe>
|
||||
<el-table-column type="index" :label="'ID (Total: ' + total + ')'" sortable width="100">
|
||||
</el-table-column>
|
||||
<el-table-column resizable sortable prop="score" label="score" show-overflow-tooltip min-width="100">
|
||||
|
||||
@@ -1,56 +1,41 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-card>
|
||||
<el-button type="primary" icon="plus" @click="editRedis(true)" plain>添加</el-button>
|
||||
<el-button type="primary" icon="edit" :disabled="currentId == null" @click="editRedis(false)" plain>编辑
|
||||
</el-button>
|
||||
<el-button type="danger" icon="delete" :disabled="currentId == null" @click="deleteRedis" plain>删除
|
||||
</el-button>
|
||||
<div style="float: right">
|
||||
<el-select @focus="getTags" v-model="query.tagPath" placeholder="请选择标签" filterable clearable>
|
||||
<page-table :query="state.queryConfig" v-model:query-form="query" :show-choose-column="true"
|
||||
v-model:choose-data="state.chooseData" :data="redisTable" :columns="state.columns" :total="total"
|
||||
v-model:page-size="query.pageSize" v-model:page-num="query.pageNum" @pageChange="search()">
|
||||
|
||||
<template #tagPathSelect>
|
||||
<el-select @focus="getTags" v-model="query.tagPath" placeholder="请选择标签" @clear="search" filterable clearable
|
||||
style="width: 200px">
|
||||
<el-option v-for="item in tags" :key="item" :label="item" :value="item"> </el-option>
|
||||
</el-select>
|
||||
<el-button class="ml5" @click="search" type="success" icon="search"></el-button>
|
||||
</div>
|
||||
<el-table :data="redisTable" @current-change="choose" stripe>
|
||||
<el-table-column label="选择" width="60px">
|
||||
<template #default="scope">
|
||||
<el-radio v-model="currentId" :label="scope.row.id">
|
||||
<i></i>
|
||||
</el-radio>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="tagPath" label="标签路径" min-width="150" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<tag-info :tag-path="scope.row.tagPath" />
|
||||
<span class="ml5">
|
||||
{{ scope.row.tagPath }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="name" label="名称" min-width="100"></el-table-column>
|
||||
<el-table-column prop="host" label="host:port" min-width="150" show-overflow-tooltip> </el-table-column>
|
||||
<el-table-column prop="mode" label="mode" min-width="100"></el-table-column>
|
||||
<el-table-column prop="remark" label="备注" min-width="120" show-overflow-tooltip></el-table-column>
|
||||
</template>
|
||||
|
||||
<el-table-column label="更多" min-width="155" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-link @click="showDetail(scope.row)" :underline="false">详情</el-link>
|
||||
<el-divider direction="vertical" border-style="dashed" />
|
||||
<template #queryRight>
|
||||
<el-button type="primary" icon="plus" @click="editRedis(true)" plain>添加</el-button>
|
||||
<el-button type="primary" icon="edit" :disabled="!chooseData" @click="editRedis(false)" plain>编辑
|
||||
</el-button>
|
||||
<el-button type="danger" icon="delete" :disabled="!chooseData" @click="deleteRedis" plain>删除
|
||||
</el-button>
|
||||
</template>
|
||||
|
||||
<el-link v-if="scope.row.mode === 'standalone' || scope.row.mode === 'sentinel'" type="primary"
|
||||
@click="showInfoDialog(scope.row)" :underline="false">单机信息</el-link>
|
||||
<el-link @click="onShowClusterInfo(scope.row)" v-if="scope.row.mode === 'cluster'"
|
||||
type="primary" :underline="false">集群信息</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-row style="margin-top: 20px" type="flex" justify="end">
|
||||
<el-pagination style="text-align: right" @current-change="handlePageChange" :total="total"
|
||||
layout="prev, pager, next, total, jumper" v-model:current-page="query.pageNum"
|
||||
:page-size="query.pageSize"></el-pagination>
|
||||
</el-row>
|
||||
</el-card>
|
||||
<template #tagPath="{ data }">
|
||||
<tag-info :tag-path="data.tagPath" />
|
||||
<span class="ml5">
|
||||
{{ data.tagPath }}
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<template #more="{ data }">
|
||||
<el-link @click="showDetail(data)" :underline="false">详情</el-link>
|
||||
<el-divider direction="vertical" border-style="dashed" />
|
||||
|
||||
<el-link v-if="data.mode === 'standalone' || data.mode === 'sentinel'" type="primary"
|
||||
@click="showInfoDialog(data)" :underline="false">单机信息</el-link>
|
||||
<el-link @click="onShowClusterInfo(data)" v-if="data.mode === 'cluster'" type="primary"
|
||||
:underline="false">集群信息</el-link>
|
||||
</template>
|
||||
</page-table>
|
||||
|
||||
<info v-model:visible="infoDialog.visible" :title="infoDialog.title" :info="infoDialog.info"></info>
|
||||
|
||||
@@ -81,8 +66,8 @@
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<el-tag @click="showInfoDialog({ id: clusterInfoDialog.redisId, ip: scope.row.ip })"
|
||||
effect="plain" type="success" size="small" style="cursor: pointer">{{ scope.row.ip }}
|
||||
<el-tag @click="showInfoDialog({ id: clusterInfoDialog.redisId, ip: scope.row.ip })" effect="plain"
|
||||
type="success" size="small" style="cursor: pointer">{{ scope.row.ip }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -90,8 +75,8 @@
|
||||
<el-table-column prop="masterSlaveRelation" label="masterSlaveRelation" min-width="300">
|
||||
<template #header>
|
||||
masterSlaveRelation
|
||||
<el-tooltip class="box-item" effect="dark"
|
||||
content="如果节点是slave,并且已知master节点,则为master节点ID;否则为符号'-'" placement="top">
|
||||
<el-tooltip class="box-item" effect="dark" content="如果节点是slave,并且已知master节点,则为master节点ID;否则为符号'-'"
|
||||
placement="top">
|
||||
<el-icon>
|
||||
<question-filled />
|
||||
</el-icon>
|
||||
@@ -112,8 +97,7 @@
|
||||
<template #header>
|
||||
configEpoch
|
||||
<el-tooltip class="box-item" effect="dark"
|
||||
content="节点的epoch值(如果该节点是从节点,则为其主节点的epoch值)。每当节点发生失败切换时,都会创建一个新的,独特的,递增的epoch。"
|
||||
placement="top">
|
||||
content="节点的epoch值(如果该节点是从节点,则为其主节点的epoch值)。每当节点发生失败切换时,都会创建一个新的,独特的,递增的epoch。" placement="top">
|
||||
<el-icon>
|
||||
<question-filled />
|
||||
</el-icon>
|
||||
@@ -164,19 +148,30 @@ import { tagApi } from '../tag/api';
|
||||
import RedisEdit from './RedisEdit.vue';
|
||||
import { dateFormat } from '@/common/utils/date';
|
||||
import TagInfo from '../component/TagInfo.vue';
|
||||
import PageTable from '@/components/pagetable/PageTable.vue'
|
||||
import { TableColumn, TableQuery } from '@/components/pagetable';
|
||||
|
||||
const state = reactive({
|
||||
tags: [],
|
||||
redisTable: [],
|
||||
total: 0,
|
||||
currentId: null,
|
||||
currentData: null,
|
||||
chooseData: null as any,
|
||||
query: {
|
||||
tagPath: null,
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
clusterId: null,
|
||||
},
|
||||
queryConfig: [
|
||||
TableQuery.slot("tagPath", "标签", "tagPathSelect"),
|
||||
],
|
||||
columns: [
|
||||
TableColumn.new("tagPath", "标签路径").setSlot("tagPath"),
|
||||
TableColumn.new("name", "名称"),
|
||||
TableColumn.new("host", "host:port"),
|
||||
TableColumn.new("mode", "mode"),
|
||||
TableColumn.new("remark", "备注"),
|
||||
TableColumn.new("more", "更多").setSlot("more").setMinWidth(155).fixedRight(),
|
||||
],
|
||||
detailDialog: {
|
||||
visible: false,
|
||||
data: null as any,
|
||||
@@ -209,7 +204,7 @@ const {
|
||||
tags,
|
||||
redisTable,
|
||||
total,
|
||||
currentId,
|
||||
chooseData,
|
||||
query,
|
||||
detailDialog,
|
||||
clusterInfoDialog,
|
||||
@@ -221,24 +216,12 @@ onMounted(async () => {
|
||||
search();
|
||||
});
|
||||
|
||||
const handlePageChange = (curPage: number) => {
|
||||
state.query.pageNum = curPage;
|
||||
search();
|
||||
};
|
||||
|
||||
const showDetail = (detail: any) => {
|
||||
state.detailDialog.data = detail;
|
||||
state.detailDialog.visible = true;
|
||||
}
|
||||
|
||||
const choose = (item: any) => {
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
state.currentId = item.id;
|
||||
state.currentData = item;
|
||||
};
|
||||
|
||||
const deleteRedis = async () => {
|
||||
try {
|
||||
await ElMessageBox.confirm(`确定删除该redis?`, '提示', {
|
||||
@@ -246,10 +229,9 @@ const deleteRedis = async () => {
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
});
|
||||
await redisApi.delRedis.request({ id: state.currentId });
|
||||
await redisApi.delRedis.request({ id: state.chooseData.id });
|
||||
ElMessage.success('删除成功');
|
||||
state.currentData = null;
|
||||
state.currentId = null;
|
||||
state.chooseData = null;
|
||||
search();
|
||||
} catch (err) { }
|
||||
};
|
||||
@@ -288,19 +270,16 @@ const editRedis = async (isAdd = false) => {
|
||||
state.redisEditDialog.data = null;
|
||||
state.redisEditDialog.title = '新增redis';
|
||||
} else {
|
||||
state.redisEditDialog.data = state.currentData;
|
||||
state.redisEditDialog.data = state.chooseData;
|
||||
state.redisEditDialog.title = '修改redis';
|
||||
}
|
||||
state.redisEditDialog.visible = true;
|
||||
};
|
||||
|
||||
const valChange = () => {
|
||||
state.currentId = null;
|
||||
state.currentData = null;
|
||||
state.chooseData = null;
|
||||
search();
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
<style></style>
|
||||
|
||||
@@ -1,47 +1,32 @@
|
||||
<template>
|
||||
<div class="role-list">
|
||||
<el-card>
|
||||
<el-button v-auth="'team:save'" type="primary" icon="plus" @click="showSaveTeamDialog(false)">添加</el-button>
|
||||
<el-button v-auth="'team:del'" :disabled="!chooseId" @click="deleteTeam(chooseData)" type="danger"
|
||||
icon="delete">删除</el-button>
|
||||
<div>
|
||||
<page-table :query="state.queryConfig" v-model:query-form="query" :show-choose-column="true"
|
||||
v-model:choose-data="state.chooseData" :data="data" :columns="state.columns" :total="total"
|
||||
v-model:page-size="query.pageSize" v-model:page-num="query.pageNum" @pageChange="search()">
|
||||
|
||||
<div style="float: right">
|
||||
<el-input placeholder="请输入团队名称" class="mr2" style="width: 200px" v-model="query.name" @clear="search"
|
||||
clearable></el-input>
|
||||
<el-button @click="search" type="success" icon="search"></el-button>
|
||||
</div>
|
||||
<el-table :data="data" @current-change="choose" ref="table" style="width: 100%">
|
||||
<el-table-column label="选择" width="55px">
|
||||
<template #default="scope">
|
||||
<el-radio v-model="chooseId" :label="scope.row.id">
|
||||
<i></i>
|
||||
</el-radio>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="name" label="团队名称"></el-table-column>
|
||||
<el-table-column prop="remark" label="备注" min-width="160px" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="createTime" label="创建时间">
|
||||
<template #default="scope">
|
||||
{{ dateFormat(scope.row.createTime) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="creator" label="创建者"> </el-table-column>
|
||||
<el-table-column label="操作" min-width="80px">
|
||||
<template #default="scope">
|
||||
<el-link @click.prevent="showMembers(scope.row)" :underline="false" type="primary">成员</el-link>
|
||||
<el-divider direction="vertical" border-style="dashed" />
|
||||
<el-link @click.prevent="showTags(scope.row)" :underline="false" type="success">标签</el-link>
|
||||
<el-divider v-auth="'team:save'" direction="vertical" border-style="dashed" />
|
||||
<el-link v-auth="'team:save'" @click.prevent="showSaveTeamDialog(scope.row)" :underline="false" type="warning">编辑</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-row style="margin-top: 20px" type="flex" justify="end">
|
||||
<el-pagination style="text-align: right" @current-change="handlePageChange" :total="total"
|
||||
layout="prev, pager, next, total, jumper" v-model:current-page="query.pageNum"
|
||||
:page-size="query.pageSize"></el-pagination>
|
||||
</el-row>
|
||||
</el-card>
|
||||
<template #queryRight>
|
||||
<el-button v-auth="'team:save'" type="primary" icon="plus" @click="showSaveTeamDialog(false)">添加</el-button>
|
||||
<el-button v-auth="'team:del'" :disabled="!chooseData" @click="deleteTeam(chooseData)" type="danger"
|
||||
icon="delete">删除</el-button>
|
||||
|
||||
</template>
|
||||
|
||||
<template #tagPath="{ data }">
|
||||
<tag-info :tag-path="data.tagPath" />
|
||||
<span class="ml5">
|
||||
{{ data.tagPath }}
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<template #action="{ data }">
|
||||
<el-link @click.prevent="showMembers(data)" :underline="false" type="primary">成员</el-link>
|
||||
<el-divider direction="vertical" border-style="dashed" />
|
||||
<el-link @click.prevent="showTags(data)" :underline="false" type="success">标签</el-link>
|
||||
<el-divider v-auth="'team:save'" direction="vertical" border-style="dashed" />
|
||||
<el-link v-auth="'team:save'" @click.prevent="showSaveTeamDialog(data)" :underline="false"
|
||||
type="warning">编辑</el-link>
|
||||
</template>
|
||||
</page-table>
|
||||
|
||||
<el-dialog width="400px" title="团队编辑" :before-close="cancelSaveTeam" v-model="addTeamDialog.visible">
|
||||
<el-form ref="teamForm" :model="addTeamDialog.form" label-width="70px">
|
||||
@@ -66,8 +51,8 @@
|
||||
<el-form-item prop="tag" label="标签:">
|
||||
<el-tree-select ref="tagTreeRef" style="width: 100%" v-model="showTagDialog.tagTreeTeams"
|
||||
:data="showTagDialog.tags" :default-expanded-keys="showTagDialog.tagTreeTeams" multiple
|
||||
:render-after-expand="true" show-checkbox check-strictly node-key="id"
|
||||
:props="showTagDialog.props" @check="tagTreeNodeCheck">
|
||||
:render-after-expand="true" show-checkbox check-strictly node-key="id" :props="showTagDialog.props"
|
||||
@check="tagTreeNodeCheck">
|
||||
<template #default="{ data }">
|
||||
<span class="custom-tree-node">
|
||||
<span style="font-size: 13px">
|
||||
@@ -98,8 +83,8 @@
|
||||
<el-button v-auth="'team:member:del'" @click="deleteMember" :disabled="showMemDialog.chooseId == null"
|
||||
type="danger" icon="delete" size="small">移除</el-button>
|
||||
<div style="float: right">
|
||||
<el-input placeholder="请输入用户名" class="mr2" style="width: 150px"
|
||||
v-model="showMemDialog.query.username" size="small" @clear="search" clearable></el-input>
|
||||
<el-input placeholder="请输入用户名" class="mr2" style="width: 150px" v-model="showMemDialog.query.username"
|
||||
size="small" @clear="search" clearable></el-input>
|
||||
<el-button @click="setMemebers" type="success" icon="search" size="small"></el-button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -153,6 +138,8 @@ import { accountApi } from '../../system/api';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import { dateFormat } from '@/common/utils/date';
|
||||
import { notBlank } from '@/common/assert';
|
||||
import PageTable from '@/components/pagetable/PageTable.vue'
|
||||
import { TableColumn, TableQuery } from '@/components/pagetable';
|
||||
|
||||
const teamForm: any = ref(null);
|
||||
const tagTreeRef: any = ref(null);
|
||||
@@ -168,10 +155,19 @@ const state = reactive({
|
||||
pageSize: 10,
|
||||
name: null,
|
||||
},
|
||||
queryConfig: [
|
||||
TableQuery.text("name", "团队名称"),
|
||||
],
|
||||
columns: [
|
||||
TableColumn.new("name", "团队名称"),
|
||||
TableColumn.new("remark", "备注"),
|
||||
TableColumn.new("createTime", "创建时间").isTime(),
|
||||
TableColumn.new("creator", "创建人"),
|
||||
TableColumn.new("action", "操作").setSlot("action").setMinWidth(100).fixedRight(),
|
||||
],
|
||||
total: 0,
|
||||
data: [],
|
||||
chooseId: 0,
|
||||
chooseData: null,
|
||||
chooseData: null as any,
|
||||
showMemDialog: {
|
||||
visible: false,
|
||||
chooseId: 0,
|
||||
@@ -213,7 +209,6 @@ const {
|
||||
addTeamDialog,
|
||||
total,
|
||||
data,
|
||||
chooseId,
|
||||
chooseData,
|
||||
showMemDialog,
|
||||
showTagDialog,
|
||||
@@ -229,19 +224,6 @@ const search = async () => {
|
||||
state.total = res.total;
|
||||
};
|
||||
|
||||
const handlePageChange = (curPage: number) => {
|
||||
state.query.pageNum = curPage;
|
||||
search();
|
||||
};
|
||||
|
||||
const choose = (item: any) => {
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
state.chooseId = item.id;
|
||||
state.chooseData = item;
|
||||
};
|
||||
|
||||
const showSaveTeamDialog = (data: any) => {
|
||||
if (data) {
|
||||
state.addTeamDialog.form.id = data.id;
|
||||
@@ -278,6 +260,7 @@ const deleteTeam = (data: any) => {
|
||||
}).then(async () => {
|
||||
await tagApi.delTeam.request({ id: data.id });
|
||||
ElMessage.success('删除成功!');
|
||||
state.chooseData = null;
|
||||
search();
|
||||
});
|
||||
};
|
||||
@@ -332,7 +315,7 @@ const showAddMemberDialog = () => {
|
||||
|
||||
const addMember = async () => {
|
||||
const memForm = state.showMemDialog.memForm;
|
||||
memForm.teamId = state.chooseId;
|
||||
memForm.teamId = state.chooseData.id;
|
||||
notBlank(memForm.accountIds, '请先选择账号');
|
||||
|
||||
await tagApi.saveTeamMem.request(memForm);
|
||||
@@ -404,6 +387,4 @@ const tagTreeNodeCheck = () => {
|
||||
// console.log(state.showTagDialog.tagTreeTeams);
|
||||
// }
|
||||
</script>
|
||||
<style lang="scss">
|
||||
|
||||
</style>
|
||||
<style lang="scss"></style>
|
||||
|
||||
@@ -1,76 +1,41 @@
|
||||
<template>
|
||||
<div class="role-list">
|
||||
<el-card>
|
||||
<el-button v-auth="'account:add'" type="primary" icon="plus" @click="editAccount(true)">添加</el-button>
|
||||
<el-button v-auth="'account:add'" :disabled="chooseId == null" @click="editAccount(false)" type="primary"
|
||||
icon="edit">编辑</el-button>
|
||||
<el-button v-auth="'account:saveRoles'" :disabled="chooseId == null" @click="showRoleEdit()" type="success"
|
||||
icon="setting">角色分配</el-button>
|
||||
<el-button v-auth="'account:del'" :disabled="chooseId == null" @click="deleteAccount()" type="danger"
|
||||
icon="delete">删除</el-button>
|
||||
<div style="float: right">
|
||||
<el-input class="mr2" placeholder="请输入账号名" style="width: 200px" v-model="query.username" @clear="search()"
|
||||
clearable></el-input>
|
||||
<el-button @click="search()" type="success" icon="search"></el-button>
|
||||
</div>
|
||||
<el-table :data="datas" ref="table" @current-change="choose" show-overflow-tooltip>
|
||||
<el-table-column label="选择" width="55px">
|
||||
<template #default="scope">
|
||||
<el-radio v-model="chooseId" :label="scope.row.id">
|
||||
<i></i>
|
||||
</el-radio>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="name" label="姓名" min-width="115"></el-table-column>
|
||||
<el-table-column prop="username" label="用户名" min-width="115"></el-table-column>
|
||||
<div>
|
||||
<page-table :query="state.queryConfig" v-model:query-form="query" :show-choose-column="true"
|
||||
v-model:choose-data="state.chooseData" :data="datas" :columns="state.columns" :total="total"
|
||||
v-model:page-size="query.pageSize" v-model:page-num="query.pageNum" @pageChange="search()">
|
||||
|
||||
<el-table-column align="center" prop="status" label="状态" min-width="70">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.status == 1" type="success">正常</el-tag>
|
||||
<el-tag v-if="scope.row.status == -1" type="danger">禁用</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="160" prop="lastLoginTime" label="最后登录时间" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
{{ dateFormat(scope.row.lastLoginTime) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<template #queryRight>
|
||||
<el-button v-auth="'account:add'" type="primary" icon="plus" @click="editAccount(true)">添加</el-button>
|
||||
<el-button v-auth="'account:add'" :disabled="state.chooseData == null" @click="editAccount(false)"
|
||||
type="primary" icon="edit">编辑</el-button>
|
||||
<el-button v-auth="'account:saveRoles'" :disabled="state.chooseData == null" @click="showRoleEdit()"
|
||||
type="success" icon="setting">角色分配</el-button>
|
||||
<el-button v-auth="'account:del'" :disabled="state.chooseData == null" @click="deleteAccount()"
|
||||
type="danger" icon="delete">删除</el-button>
|
||||
</template>
|
||||
|
||||
<el-table-column min-width="115" prop="creator" label="创建账号"></el-table-column>
|
||||
<el-table-column min-width="160" prop="createTime" label="创建时间" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
{{ dateFormat(scope.row.createTime) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<template #status="{ data }">
|
||||
<el-tag v-if="data.status == 1" type="success">正常</el-tag>
|
||||
<el-tag v-if="data.status == -1" type="danger">禁用</el-tag>
|
||||
</template>
|
||||
|
||||
<!-- <el-table-column min-width="120" prop="remark" label="备注" show-overflow-tooltip></el-table-column> -->
|
||||
<el-table-column label="查看更多" min-width="150">
|
||||
<template #default="scope">
|
||||
<el-link @click.prevent="showRoles(scope.row)" type="success">角色</el-link>
|
||||
<template #showmore="{ data }">
|
||||
<el-link @click.prevent="showRoles(data)" type="success">角色</el-link>
|
||||
|
||||
<el-link class="ml5" @click.prevent="showResources(scope.row)" type="info">菜单&权限</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-link class="ml5" @click.prevent="showResources(data)" type="info">菜单&权限</el-link>
|
||||
</template>
|
||||
|
||||
<el-table-column label="操作" min-width="200px">
|
||||
<template #default="scope">
|
||||
<el-button v-auth="'account:changeStatus'" @click="changeStatus(scope.row)"
|
||||
v-if="scope.row.status == 1" type="danger" size="small" plain>禁用</el-button>
|
||||
<template #action="{ data }">
|
||||
<el-button v-auth="'account:changeStatus'" @click="changeStatus(data)" v-if="data.status == 1" type="danger"
|
||||
size="small" plain>禁用</el-button>
|
||||
|
||||
<el-button v-auth="'account:changeStatus'" v-if="scope.row.status == -1" type="success"
|
||||
@click="changeStatus(scope.row)" size="small" plain>启用</el-button>
|
||||
<el-button v-auth="'account:changeStatus'" v-if="data.status == -1" type="success"
|
||||
@click="changeStatus(data)" size="small" plain>启用</el-button>
|
||||
|
||||
<el-button v-auth="'account:add'" :disabled="!scope.row.otpSecret || scope.row.otpSecret == '-'"
|
||||
@click="resetOtpSecret(scope.row)" type="warning" size="small" plain>重置OTP</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-row style="margin-top: 20px" type="flex" justify="end">
|
||||
<el-pagination style="text-align: right" @current-change="handlePageChange" :total="total"
|
||||
layout="prev, pager, next, total, jumper" v-model:current-page="query.pageNum"
|
||||
:page-size="query.pageSize"></el-pagination>
|
||||
</el-row>
|
||||
</el-card>
|
||||
<el-button v-auth="'account:add'" :disabled="!data.otpSecret || data.otpSecret == '-'"
|
||||
@click="resetOtpSecret(data)" type="warning" size="small" plain>重置OTP</el-button>
|
||||
</template>
|
||||
</page-table>
|
||||
|
||||
<el-dialog width="500px" :title="showRoleDialog.title" v-model="showRoleDialog.visible">
|
||||
<el-table border :data="showRoleDialog.accountRoles">
|
||||
@@ -112,13 +77,14 @@ import enums from '../enums';
|
||||
import { accountApi } from '../api';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import { dateFormat } from '@/common/utils/date';
|
||||
import PageTable from '@/components/pagetable/PageTable.vue'
|
||||
import { TableColumn, TableQuery } from '@/components/pagetable';
|
||||
|
||||
const state = reactive({
|
||||
chooseId: null,
|
||||
/**
|
||||
* 选中的数据
|
||||
*/
|
||||
chooseData: null,
|
||||
chooseData: null as any,
|
||||
/**
|
||||
* 查询条件
|
||||
*/
|
||||
@@ -127,6 +93,21 @@ const state = reactive({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
queryConfig: [
|
||||
TableQuery.text("username", "用户名"),
|
||||
],
|
||||
columns: [
|
||||
TableColumn.new("name", "姓名"),
|
||||
TableColumn.new("username", "用户名"),
|
||||
TableColumn.new("status", "状态").setSlot("status"),
|
||||
TableColumn.new("lastLoginTime", "最后登录时间").isTime(),
|
||||
TableColumn.new("showmore", "查看更多").setSlot("showmore").setMinWidth(150),
|
||||
TableColumn.new("creator", "创建账号"),
|
||||
TableColumn.new("createTime", "创建时间").isTime(),
|
||||
TableColumn.new("modifier", "更新账号"),
|
||||
TableColumn.new("updateTime", "更新时间").isTime(),
|
||||
TableColumn.new("action", "操作").setSlot("action").fixedRight().setMinWidth(200),
|
||||
],
|
||||
datas: [],
|
||||
total: 0,
|
||||
showRoleDialog: {
|
||||
@@ -155,7 +136,6 @@ const state = reactive({
|
||||
});
|
||||
|
||||
const {
|
||||
chooseId,
|
||||
query,
|
||||
datas,
|
||||
total,
|
||||
@@ -169,14 +149,6 @@ onMounted(() => {
|
||||
search();
|
||||
});
|
||||
|
||||
const choose = (item: any) => {
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
state.chooseId = item.id;
|
||||
state.chooseData = item;
|
||||
};
|
||||
|
||||
const search = async () => {
|
||||
let res: any = await accountApi.list.request(state.query);
|
||||
state.datas = res.list;
|
||||
@@ -228,7 +200,7 @@ const handlePageChange = (curPage: number) => {
|
||||
};
|
||||
|
||||
const showRoleEdit = () => {
|
||||
if (!state.chooseId) {
|
||||
if (!state.chooseData) {
|
||||
ElMessage.error('请选择账号');
|
||||
}
|
||||
state.roleDialog.visible = true;
|
||||
@@ -262,10 +234,9 @@ const deleteAccount = async () => {
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
});
|
||||
await accountApi.del.request({ id: state.chooseId });
|
||||
await accountApi.del.request({ id: state.chooseData.id });
|
||||
ElMessage.success('删除成功');
|
||||
state.chooseData = null;
|
||||
state.chooseId = null;
|
||||
search();
|
||||
} catch (err) { }
|
||||
};
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<div style="float: left">
|
||||
<el-input placeholder="请输入角色名" style="width: 150px" v-model="query.name" @clear="clear()" clearable>
|
||||
</el-input>
|
||||
<el-button @click="search" type="success" icon="search"></el-button>
|
||||
<el-button class="ml5" @click="search" type="success" icon="search"></el-button>
|
||||
</div>
|
||||
</div>
|
||||
<el-table :data="allRole" border ref="roleTable" @select="select" style="width: 100%">
|
||||
|
||||
@@ -1,42 +1,26 @@
|
||||
<template>
|
||||
<div class="role-list">
|
||||
<el-card>
|
||||
<el-button v-auth="'config:save'" type="primary" icon="plus" @click="editConfig(false)">添加</el-button>
|
||||
<el-button v-auth="'config:save'" :disabled="chooseId == null" @click="editConfig(chooseData)" type="primary"
|
||||
icon="edit">编辑
|
||||
</el-button>
|
||||
<div>
|
||||
<page-table :show-choose-column="true" v-model:choose-data="state.chooseData" :data="configs"
|
||||
:columns="state.columns" :total="total" v-model:page-size="query.pageSize" v-model:page-num="query.pageNum"
|
||||
@pageChange="search()">
|
||||
|
||||
<el-table :data="configs" @current-change="choose" ref="table" style="width: 100%">
|
||||
<el-table-column label="选择" width="55px">
|
||||
<template #default="scope">
|
||||
<el-radio v-model="chooseId" :label="scope.row.id">
|
||||
<i></i>
|
||||
</el-radio>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="name" label="配置项" min-width="100px" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="key" label="配置key" min-width="100px"></el-table-column>
|
||||
<el-table-column prop="value" label="配置值" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="remark" label="备注" min-width="100px" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="updateTime" label="更新时间" min-width="100px">
|
||||
<template #default="scope">
|
||||
{{ dateFormat(scope.row.updateTime) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="modifier" label="修改者" min-width="60px" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column label="操作" min-width="50" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-link :disabled="scope.row.status == -1" type="warning" @click="showSetConfigDialog(scope.row)"
|
||||
plain size="small" :underline="false">配置</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-row style="margin-top: 20px" type="flex" justify="end">
|
||||
<el-pagination style="text-align: right" @current-change="handlePageChange" :total="total"
|
||||
layout="prev, pager, next, total, jumper" v-model:current-page="query.pageNum"
|
||||
:page-size="query.pageSize"></el-pagination>
|
||||
</el-row>
|
||||
</el-card>
|
||||
<template #queryRight>
|
||||
<el-button v-auth="'config:save'" type="primary" icon="plus" @click="editConfig(false)">添加</el-button>
|
||||
<el-button v-auth="'config:save'" :disabled="chooseData == null" @click="editConfig(chooseData)"
|
||||
type="primary" icon="edit">编辑
|
||||
</el-button>
|
||||
</template>
|
||||
|
||||
<template #status="{ data }">
|
||||
<el-tag v-if="data.status == 1" type="success">正常</el-tag>
|
||||
<el-tag v-if="data.status == -1" type="danger">禁用</el-tag>
|
||||
</template>
|
||||
|
||||
<template #action="{ data }">
|
||||
<el-link :disabled="data.status == -1" type="warning" @click="showSetConfigDialog(data)" plain size="small"
|
||||
:underline="false">配置</el-link>
|
||||
</template>
|
||||
</page-table>
|
||||
|
||||
<el-dialog :before-close="closeSetConfigDialog" title="配置项设置" v-model="paramsDialog.visible" width="500px">
|
||||
<el-form v-if="paramsDialog.paramsFormItem.length > 0" ref="paramsFormRef" :model="paramsDialog.params"
|
||||
@@ -76,7 +60,8 @@ import { ref, toRefs, reactive, onMounted } from 'vue';
|
||||
import ConfigEdit from './ConfigEdit.vue';
|
||||
import { configApi } from '../api';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { dateFormat } from '@/common/utils/date';
|
||||
import PageTable from '@/components/pagetable/PageTable.vue'
|
||||
import { TableColumn } from '@/components/pagetable';
|
||||
|
||||
const paramsFormRef: any = ref(null)
|
||||
const state = reactive({
|
||||
@@ -85,10 +70,18 @@ const state = reactive({
|
||||
pageSize: 10,
|
||||
name: null,
|
||||
},
|
||||
columns: [
|
||||
TableColumn.new("name", "配置项"),
|
||||
TableColumn.new("key", "配置key"),
|
||||
TableColumn.new("value", "配置值"),
|
||||
TableColumn.new("remark", "备注"),
|
||||
TableColumn.new("modifier", "更新账号"),
|
||||
TableColumn.new("updateTime", "更新时间").isTime(),
|
||||
TableColumn.new("action", "操作").setSlot("action").fixedRight().setMinWidth(60),
|
||||
],
|
||||
total: 0,
|
||||
configs: [],
|
||||
chooseId: null,
|
||||
chooseData: null,
|
||||
chooseData: null as any,
|
||||
paramsDialog: {
|
||||
visible: false,
|
||||
config: null as any,
|
||||
@@ -106,7 +99,6 @@ const {
|
||||
query,
|
||||
total,
|
||||
configs,
|
||||
chooseId,
|
||||
chooseData,
|
||||
paramsDialog,
|
||||
configEdit,
|
||||
@@ -122,11 +114,6 @@ const search = async () => {
|
||||
state.total = res.total;
|
||||
};
|
||||
|
||||
const handlePageChange = (curPage: number) => {
|
||||
state.query.pageNum = curPage;
|
||||
search();
|
||||
};
|
||||
|
||||
const showSetConfigDialog = (row: any) => {
|
||||
state.paramsDialog.config = row;
|
||||
// 存在配置项则弹窗提示输入对应的配置项
|
||||
@@ -155,30 +142,37 @@ const closeSetConfigDialog = () => {
|
||||
};
|
||||
|
||||
const setConfig = async () => {
|
||||
paramsFormRef.value.validate(async (valid: boolean) => {
|
||||
if (!valid) {
|
||||
return false;
|
||||
}
|
||||
let paramsValue = state.paramsDialog.params;
|
||||
if (state.paramsDialog.paramsFormItem.length > 0) {
|
||||
// 如果配置项删除,则需要将value中对应的字段移除
|
||||
for (let paramKey in paramsValue) {
|
||||
if (!hasParam(paramKey, state.paramsDialog.paramsFormItem)) {
|
||||
delete paramsValue[paramKey];
|
||||
}
|
||||
let paramsValue = state.paramsDialog.params;
|
||||
if (state.paramsDialog.paramsFormItem.length > 0) {
|
||||
await paramsFormRef.value.validate(async (valid: boolean) => {
|
||||
if (!valid) {
|
||||
paramsValue = null as any;
|
||||
return false;
|
||||
}
|
||||
if (state.paramsDialog.paramsFormItem.length > 0) {
|
||||
// 如果配置项删除,则需要将value中对应的字段移除
|
||||
for (let paramKey in paramsValue) {
|
||||
if (!hasParam(paramKey, state.paramsDialog.paramsFormItem)) {
|
||||
delete paramsValue[paramKey];
|
||||
}
|
||||
}
|
||||
paramsValue = JSON.stringify(paramsValue);
|
||||
}
|
||||
paramsValue = JSON.stringify(paramsValue);
|
||||
}
|
||||
await configApi.save.request({
|
||||
id: state.paramsDialog.config.id,
|
||||
key: state.paramsDialog.config.key,
|
||||
name: state.paramsDialog.config.name,
|
||||
value: paramsValue,
|
||||
});
|
||||
ElMessage.success('保存成功');
|
||||
closeSetConfigDialog();
|
||||
search();
|
||||
}
|
||||
// 说明校验失败
|
||||
if (paramsValue == null) {
|
||||
return;
|
||||
}
|
||||
await configApi.save.request({
|
||||
id: state.paramsDialog.config.id,
|
||||
key: state.paramsDialog.config.key,
|
||||
name: state.paramsDialog.config.name,
|
||||
value: paramsValue,
|
||||
});
|
||||
ElMessage.success('保存成功');
|
||||
closeSetConfigDialog();
|
||||
search();
|
||||
|
||||
};
|
||||
|
||||
@@ -191,17 +185,8 @@ const hasParam = (paramKey: string, paramItems: any) => {
|
||||
return false;
|
||||
};
|
||||
|
||||
const choose = (item: any) => {
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
state.chooseId = item.id;
|
||||
state.chooseData = item;
|
||||
};
|
||||
|
||||
const configEditChange = () => {
|
||||
ElMessage.success('保存成功');
|
||||
state.chooseId = null;
|
||||
state.chooseData = null;
|
||||
search();
|
||||
};
|
||||
|
||||
@@ -1,52 +1,28 @@
|
||||
<template>
|
||||
<div class="role-list">
|
||||
<el-card>
|
||||
<el-button v-auth="'role:add'" type="primary" icon="plus" @click="editRole(false)">添加</el-button>
|
||||
<el-button v-auth="'role:update'" :disabled="chooseId == null" @click="editRole(chooseData)" type="primary"
|
||||
icon="edit">编辑</el-button>
|
||||
<el-button v-auth="'role:saveResources'" :disabled="chooseId == null" @click="editResource(chooseData)"
|
||||
type="success" icon="setting">分配菜单&权限</el-button>
|
||||
<el-button v-auth="'role:del'" :disabled="chooseId == null" @click="deleteRole(chooseData)" type="danger"
|
||||
icon="delete">删除</el-button>
|
||||
<div>
|
||||
<page-table :query="state.queryConfig" v-model:query-form="query" :show-choose-column="true"
|
||||
v-model:choose-data="state.chooseData" :data="roles" :columns="state.columns" :total="total"
|
||||
v-model:page-size="query.pageSize" v-model:page-num="query.pageNum" @pageChange="search()">
|
||||
|
||||
<div style="float: right">
|
||||
<el-input placeholder="请输入角色名称" class="mr2" style="width: 200px" v-model="query.name" @clear="search"
|
||||
clearable></el-input>
|
||||
<el-button @click="search" type="success" icon="search"></el-button>
|
||||
</div>
|
||||
<el-table :data="roles" @current-change="choose" ref="table" style="width: 100%">
|
||||
<el-table-column label="选择" width="55px">
|
||||
<template #default="scope">
|
||||
<el-radio v-model="chooseId" :label="scope.row.id">
|
||||
<i></i>
|
||||
</el-radio>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="name" label="角色名称"></el-table-column>
|
||||
<el-table-column prop="code" label="角色code"></el-table-column>
|
||||
<el-table-column prop="remark" label="描述" min-width="160px" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="createTime" label="创建时间">
|
||||
<template #default="scope">
|
||||
{{ dateFormat(scope.row.createTime) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="updateTime" label="修改时间">
|
||||
<template #default="scope">
|
||||
{{ dateFormat(scope.row.updateTime) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="查看更多" min-width="80px">
|
||||
<template #default="scope">
|
||||
<el-link @click.prevent="showResources(scope.row)" type="info">菜单&权限</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-row style="margin-top: 20px" type="flex" justify="end">
|
||||
<el-pagination style="text-align: right" @current-change="handlePageChange" :total="total"
|
||||
layout="prev, pager, next, total, jumper" v-model:current-page="query.pageNum"
|
||||
:page-size="query.pageSize"></el-pagination>
|
||||
</el-row>
|
||||
</el-card>
|
||||
<template #queryRight>
|
||||
<el-button v-auth="'role:add'" type="primary" icon="plus" @click="editRole(false)">添加</el-button>
|
||||
<el-button v-auth="'role:update'" :disabled="chooseData == null" @click="editRole(chooseData)"
|
||||
type="primary" icon="edit">编辑</el-button>
|
||||
<el-button v-auth="'role:saveResources'" :disabled="chooseData == null" @click="editResource(chooseData)"
|
||||
type="success" icon="setting">分配菜单&权限</el-button>
|
||||
<el-button v-auth="'role:del'" :disabled="chooseData == null" @click="deleteRole(chooseData)" type="danger"
|
||||
icon="delete">删除</el-button>
|
||||
</template>
|
||||
|
||||
<template #status="{ data }">
|
||||
<el-tag v-if="data.status == 1" type="success" size="small">正常</el-tag>
|
||||
<el-tag v-if="data.status == -1" type="danger" size="small">禁用</el-tag>
|
||||
</template>
|
||||
|
||||
<template #showmore="{ data }">
|
||||
<el-link @click.prevent="showResources(data)" type="info">菜单&权限</el-link>
|
||||
</template>
|
||||
</page-table>
|
||||
|
||||
<role-edit :title="roleEditDialog.title" v-model:visible="roleEditDialog.visible" :data="roleEditDialog.role"
|
||||
@val-change="roleEditChange" />
|
||||
@@ -65,7 +41,8 @@ import ResourceEdit from './ResourceEdit.vue';
|
||||
import ShowResource from './ShowResource.vue';
|
||||
import { roleApi, resourceApi } from '../api';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import { dateFormat } from '@/common/utils/date';
|
||||
import PageTable from '@/components/pagetable/PageTable.vue'
|
||||
import { TableColumn, TableQuery } from '@/components/pagetable';
|
||||
|
||||
const state = reactive({
|
||||
query: {
|
||||
@@ -73,10 +50,23 @@ const state = reactive({
|
||||
pageSize: 10,
|
||||
name: null,
|
||||
},
|
||||
queryConfig: [
|
||||
TableQuery.text("name", "角色名"),
|
||||
],
|
||||
columns: [
|
||||
TableColumn.new("name", "角色名称"),
|
||||
TableColumn.new("code", "角色code"),
|
||||
TableColumn.new("remark", "备注"),
|
||||
TableColumn.new("status", "状态").setSlot("status"),
|
||||
TableColumn.new("creator", "创建账号"),
|
||||
TableColumn.new("createTime", "创建时间").isTime(),
|
||||
TableColumn.new("modifier", "更新账号"),
|
||||
TableColumn.new("updateTime", "更新时间").isTime(),
|
||||
TableColumn.new("showmore", "查看更多").setSlot("showmore").setMinWidth(150).fixedRight(),
|
||||
],
|
||||
total: 0,
|
||||
roles: [],
|
||||
chooseId: null,
|
||||
chooseData: null,
|
||||
chooseData: null as any,
|
||||
resourceDialog: {
|
||||
visible: false,
|
||||
role: {},
|
||||
@@ -99,7 +89,6 @@ const {
|
||||
query,
|
||||
total,
|
||||
roles,
|
||||
chooseId,
|
||||
chooseData,
|
||||
resourceDialog,
|
||||
roleEditDialog,
|
||||
@@ -116,22 +105,8 @@ const search = async () => {
|
||||
state.total = res.total;
|
||||
};
|
||||
|
||||
const handlePageChange = (curPage: number) => {
|
||||
state.query.pageNum = curPage;
|
||||
search();
|
||||
};
|
||||
|
||||
const choose = (item: any) => {
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
state.chooseId = item.id;
|
||||
state.chooseData = item;
|
||||
};
|
||||
|
||||
const roleEditChange = () => {
|
||||
ElMessage.success('修改成功!');
|
||||
state.chooseId = null;
|
||||
state.chooseData = null;
|
||||
search();
|
||||
};
|
||||
@@ -230,6 +205,4 @@ const cancelEditResources = () => {
|
||||
}, 10);
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
|
||||
</style>
|
||||
<style lang="scss"></style>
|
||||
|
||||
@@ -1,49 +1,29 @@
|
||||
<template>
|
||||
<div class="role-list">
|
||||
<el-card>
|
||||
<div style="float: right">
|
||||
<el-select remote :remote-method="getAccount" v-model="query.creatorId" filterable
|
||||
placeholder="请输入并选择账号" clearable class="mr5">
|
||||
<div>
|
||||
<page-table :query="state.queryConfig" v-model:query-form="query" :data="logs" :columns="state.columns"
|
||||
:total="total" v-model:page-size="query.pageSize" v-model:page-num="query.pageNum" @pageChange="search()">
|
||||
|
||||
<template #selectAccount>
|
||||
<el-select remote :remote-method="getAccount" v-model="query.creatorId" filterable placeholder="请输入并选择账号"
|
||||
clearable class="mr5" style="width: 200px">
|
||||
<el-option v-for="item in accounts" :key="item.id" :label="item.username" :value="item.id">
|
||||
</el-option>
|
||||
</el-select>
|
||||
<el-select v-model="query.type" filterable placeholder="请选择操作结果" clearable class="mr5">
|
||||
<el-option label="成功" :value="1"> </el-option>
|
||||
<el-option label="失败" :value="2"> </el-option>
|
||||
</el-select>
|
||||
<el-button @click="search" type="success" icon="search"></el-button>
|
||||
</div>
|
||||
<el-table :data="logs" style="width: 100%">
|
||||
<el-table-column prop="creator" label="操作人" min-width="100" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="createTime" label="操作时间" min-width="160">
|
||||
<template #default="scope">
|
||||
{{ dateFormat(scope.row.createTime) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="type" label="结果" min-width="65">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.type == 1" type="success" size="small">成功</el-tag>
|
||||
<el-tag v-if="scope.row.type == 2" type="danger" size="small">失败</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="description" label="描述" min-width="160" show-overflow-tooltip></el-table-column>
|
||||
</template>
|
||||
|
||||
<el-table-column prop="reqParam" label="操作信息" min-width="300" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="resp" label="响应信息" min-width="200" show-overflow-tooltip></el-table-column>
|
||||
</el-table>
|
||||
<el-row style="margin-top: 20px" type="flex" justify="end">
|
||||
<el-pagination style="text-align: right" @current-change="handlePageChange" :total="total"
|
||||
layout="prev, pager, next, total, jumper" v-model:current-page="query.pageNum"
|
||||
:page-size="query.pageSize"></el-pagination>
|
||||
</el-row>
|
||||
</el-card>
|
||||
<template #type="{ data }">
|
||||
<el-tag v-if="data.type == 1" type="success" size="small">成功</el-tag>
|
||||
<el-tag v-if="data.type == 2" type="danger" size="small">失败</el-tag>
|
||||
</template>
|
||||
</page-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { toRefs, reactive, onMounted } from 'vue';
|
||||
import { logApi, accountApi } from '../api';
|
||||
import { dateFormat } from '@/common/utils/date';
|
||||
import PageTable from '@/components/pagetable/PageTable.vue'
|
||||
import { TableColumn, TableQuery } from '@/components/pagetable';
|
||||
|
||||
const state = reactive({
|
||||
query: {
|
||||
@@ -51,8 +31,22 @@ const state = reactive({
|
||||
creatorId: null,
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
name: null,
|
||||
},
|
||||
queryConfig: [
|
||||
TableQuery.slot("creatorId", "操作人", "selectAccount"),
|
||||
TableQuery.select("type", "操作结果").setOptions([
|
||||
{ label: "成功", value: 1 },
|
||||
{ label: "失败", value: 2 },
|
||||
]),
|
||||
],
|
||||
columns: [
|
||||
TableColumn.new("creator", "操作人"),
|
||||
TableColumn.new("createTime", "操作时间").isTime(),
|
||||
TableColumn.new("type", "结果").setSlot("type"),
|
||||
TableColumn.new("description", "描述"),
|
||||
TableColumn.new("reqParam", "操作信息"),
|
||||
TableColumn.new("resp", "响应信息"),
|
||||
],
|
||||
total: 0,
|
||||
logs: [],
|
||||
accounts: [] as any,
|
||||
@@ -75,11 +69,6 @@ const search = async () => {
|
||||
state.total = res.total;
|
||||
};
|
||||
|
||||
const handlePageChange = (curPage: number) => {
|
||||
state.query.pageNum = curPage;
|
||||
search();
|
||||
};
|
||||
|
||||
const getAccount = (username: any) => {
|
||||
accountApi.list.request({ username }).then((res) => {
|
||||
state.accounts = res.list;
|
||||
@@ -87,6 +76,4 @@ const getAccount = (username: any) => {
|
||||
};
|
||||
|
||||
</script>
|
||||
<style lang="scss">
|
||||
|
||||
</style>
|
||||
<style lang="scss"></style>
|
||||
|
||||
@@ -2,6 +2,7 @@ package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"mayfly-go/internal/redis/api/form"
|
||||
"mayfly-go/pkg/biz"
|
||||
"mayfly-go/pkg/ginx"
|
||||
@@ -34,6 +35,7 @@ func (r *Redis) Hdel(rc *req.Ctx) {
|
||||
ri, key := r.checkKeyAndGetRedisIns(rc)
|
||||
field := rc.GinCtx.Query("field")
|
||||
|
||||
rc.ReqParam = fmt.Sprintf("key=%s, field=%s", key, field)
|
||||
delRes, err := ri.GetCmdable().HDel(context.TODO(), key, field).Result()
|
||||
biz.ErrIsNilAppendErr(err, "hdel err: %s")
|
||||
rc.ResData = delRes
|
||||
|
||||
@@ -20,7 +20,7 @@ type Role struct {
|
||||
|
||||
func (r *Role) Roles(rc *req.Ctx) {
|
||||
g := rc.GinCtx
|
||||
condition := &entity.Role{}
|
||||
condition := &entity.Role{Name: g.Query("name")}
|
||||
rc.ResData = r.RoleApp.GetPageList(condition, ginx.GetPageParam(g), new([]entity.Role))
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import "fmt"
|
||||
|
||||
const (
|
||||
AppName = "mayfly-go"
|
||||
Version = "v1.4.3"
|
||||
Version = "v1.4.4"
|
||||
)
|
||||
|
||||
func GetAppInfo() string {
|
||||
|
||||
Reference in New Issue
Block a user